placenamelayer.java

来自「world wind java sdk 源码」· Java 代码 · 共 1,493 行 · 第 1/4 页

JAVA
1,493
字号

        View view = dc.getView();
        Position eyePos = view.getEyePosition();
        if (eyePos == null)
            return false;

        Angle lat = clampAngle(eyePos.getLatitude(), sector.getMinLatitude(), sector.getMaxLatitude());
        Angle lon = clampAngle(eyePos.getLongitude(), sector.getMinLongitude(), sector.getMaxLongitude());
        Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d);
        double distSquared = dc.getView().getEyePoint().distanceToSquared3(p);
        //noinspection RedundantIfStatement
        if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared)
            return false;

        return true;
    }

    private static boolean isTileVisible(DrawContext dc, Tile tile, double minDistanceSquared,
        double maxDistanceSquared)
    {
        if (!tile.getSector().intersects(dc.getVisibleSector()))
            return false;

        View view = dc.getView();
        Position eyePos = view.getEyePosition();
        if (eyePos == null)
            return false;

        Angle lat = clampAngle(eyePos.getLatitude(), tile.getSector().getMinLatitude(),
            tile.getSector().getMaxLatitude());
        Angle lon = clampAngle(eyePos.getLongitude(), tile.getSector().getMinLongitude(),
            tile.getSector().getMaxLongitude());
        Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d);
        double distSquared = dc.getView().getEyePoint().distanceToSquared3(p);
        //noinspection RedundantIfStatement
        if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared)
            return false;

        return true;
    }

    private static boolean isNameVisible(DrawContext dc, PlaceNameService service, Position namePosition)
    {
        double elevation = dc.getVerticalExaggeration() * namePosition.getElevation();
        Vec4 namePoint = dc.getGlobe().computePointFromPosition(namePosition.getLatitude(),
            namePosition.getLongitude(), elevation);
        Vec4 eyeVec = dc.getView().getEyePoint();

        double dist = eyeVec.distanceTo3(namePoint);
        return dist >= service.getMinDisplayDistance() && dist <= service.getMaxDisplayDistance();
    }

    private static Angle clampAngle(Angle a, Angle min, Angle max)
    {
        double degrees = a.degrees;
        double minDegrees = min.degrees;
        double maxDegrees = max.degrees;
        return Angle.fromDegrees(degrees < minDegrees ? minDegrees : (degrees > maxDegrees ? maxDegrees : degrees));
    }

    // ============== Image Reading and Downloading ======================= //
    // ============== Image Reading and Downloading ======================= //
    // ============== Image Reading and Downloading ======================= //

    private void requestTile(DrawContext dc, Tile tile)
    {
        Vec4 centroid = tile.getCentroidPoint(dc.getGlobe());
        if (this.getReferencePoint() != null)
            tile.setPriority(centroid.distanceTo3(this.getReferencePoint()));

        RequestTask task = new RequestTask(tile, this);
        this.getRequestQ().add(task);
    }

    private void sendRequests()
    {
        Runnable task = this.requestQ.poll();
        while (task != null)
        {
            if (!WorldWind.getTaskService().isFull())
            {
                WorldWind.getTaskService().addTask(task);
            }
            task = this.requestQ.poll();
        }
    }

    private static class RequestTask implements Runnable, Comparable<RequestTask>
    {
        private final PlaceNameLayer layer;
        private final Tile tile;

        RequestTask(Tile tile, PlaceNameLayer layer)
        {
            this.layer = layer;
            this.tile = tile;
        }

        public void run()
        {
            if (this.tile.isTileInMemoryWithData())
                return;

            final java.net.URL tileURL = WorldWind.getDataFileStore().findFile(tile.getFileCachePath(), false);
            if (tileURL != null)
            {
                if (this.layer.loadTile(this.tile, tileURL))
                {
                    tile.getPlaceNameService().unmarkResourceAbsent(tile.getPlaceNameService().getTileNumber(
                        tile.row,
                        tile.column));
                    this.layer.firePropertyChange(AVKey.LAYER, null, this);
                    return;
                }
                else
                {
                    // Assume that something's wrong with the file and delete it.
                    WorldWind.getDataFileStore().removeFile(tileURL);
                    tile.getPlaceNameService().markResourceAbsent(tile.getPlaceNameService().getTileNumber(tile.row,
                        tile.column));
                    String message = Logging.getMessage("generic.DeletedCorruptDataFile", tileURL);
                    Logging.logger().fine(message);
                }
            }

            this.layer.downloadTile(this.tile);
        }

        /**
         * @param that the task to compare
         * @return -1 if <code>this</code> less than <code>that</code>, 1 if greater than, 0 if equal
         * @throws IllegalArgumentException if <code>that</code> is null
         */
        public int compareTo(RequestTask that)
        {
            if (that == null)
            {
                String msg = Logging.getMessage("nullValue.RequestTaskIsNull");
                Logging.logger().severe(msg);
                throw new IllegalArgumentException(msg);
            }
            return this.tile.getPriority() == that.tile.getPriority() ? 0 :
                this.tile.getPriority() < that.tile.getPriority() ? -1 : 1;
        }

        public boolean equals(Object o)
        {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;

            final RequestTask that = (RequestTask) o;

            // Don't include layer in comparison so that requests are shared among layers
            return !(tile != null ? !tile.equals(that.tile) : that.tile != null);
        }

        public int hashCode()
        {
            return (tile != null ? tile.hashCode() : 0);
        }

        public String toString()
        {
            return this.tile.toString();
        }
    }

    private boolean loadTile(Tile tile, java.net.URL url)
    {
        if (WWIO.isFileOutOfDate(url, this.placeNameServiceSet.getExpiryTime()))
        {
            // The file has expired. Delete it then request download of newer.
            WorldWind.getDataFileStore().removeFile(url);
            String message = Logging.getMessage("generic.DataFileExpired", url);
            Logging.logger().fine(message);
            return false;
        }

        PlaceNameChunk tileData;
        synchronized (this.fileLock)
        {
            tileData = readTileData(tile, url);
        }

        if (tileData == null)
            return false;

        tile.setDataChunk(tileData);
        WorldWind.getMemoryCache(Tile.class.getName()).add(tile.getHashInt(), tile);
        return true;
    }

    private static PlaceNameChunk readTileData(Tile tile, java.net.URL url)
    {
        java.io.InputStream is = null;

        try
        {
            String path = url.getFile();
            path = path.replaceAll("%20", " "); // TODO: find a better way to get a path usable by FileInputStream

            java.io.FileInputStream fis = new java.io.FileInputStream(path);
            java.io.BufferedInputStream buf = new java.io.BufferedInputStream(fis);
            is = new java.util.zip.GZIPInputStream(buf);

            GMLPlaceNameSAXHandler handler = new GMLPlaceNameSAXHandler();
            javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().parse(is, handler);
            return handler.createPlaceNameChunk(tile.getPlaceNameService());
        }
        catch (Exception e)
        {
            //todo log actual error 
            Logging.logger().log(Level.FINE,
                    Logging.getMessage("layers.PlaceNameLayer.ExceptionAttemptingToReadFile", url.toString()), e);
        }
        finally
        {
            try
            {
                if (is != null)
                    is.close();
            }
            catch (java.io.IOException e)
            {
                Logging.logger().log(Level.FINE,
                        Logging.getMessage("layers.PlaceNameLayer.ExceptionAttemptingToReadFile", url.toString()), e);
            }
        }

        return null;
    }

    private static CharBuffer newCharBuffer(int numElements)
    {
        ByteBuffer bb = ByteBuffer.allocateDirect((Character.SIZE / 8) * numElements);
        bb.order(ByteOrder.nativeOrder());
        return bb.asCharBuffer();
    }

    private static class GMLPlaceNameSAXHandler extends org.xml.sax.helpers.DefaultHandler
    {
        static final String GML_FEATURE_MEMBER = "gml:featureMember";
        static final String TOPP_FULL_NAME_ND = "topp:full_name_nd";
        static final String TOPP_LATITUDE = "topp:latitude";
        static final String TOPP_LONGITUDE = "topp:longitude";
        final LinkedList<String> internedQNameStack = new LinkedList<String>();
        boolean inBeginEndPair = false;
        StringBuilder latBuffer = new StringBuilder();
        StringBuilder lonBuffer = new StringBuilder();

        StringBuilder textArray = new StringBuilder();
        int[] textIndexArray = new int[16];
        double[] latlonArray = new double[16];
        int numEntries = 0;

        GMLPlaceNameSAXHandler()
        {
        }

        PlaceNameChunk createPlaceNameChunk(PlaceNameService service)
        {
            int numChars = this.textArray.length();
            CharBuffer textBuffer = newCharBuffer(numChars);
            textBuffer.put(this.textArray.toString());
            textBuffer.rewind();
            return new PlaceNameChunk(service, textBuffer, this.textIndexArray, this.latlonArray, this.numEntries);
        }

        void beginEntry()
        {
            int textIndex = this.textArray.length();
            this.textIndexArray = append(this.textIndexArray, this.numEntries, textIndex);
            this.inBeginEndPair = true;
        }

        void endEntry()
        {
            double lat = this.parseDouble(this.latBuffer);
            double lon = this.parseDouble(this.lonBuffer);
            int numLatLon = 2 * this.numEntries;
            this.latlonArray = this.append(this.latlonArray, numLatLon, lat);
            numLatLon++;
            this.latlonArray = this.append(this.latlonArray, numLatLon, lon);

            this.latBuffer.delete(0, this.latBuffer.length());
            this.lonBuffer.delete(0, this.lonBuffer.length());
            this.inBeginEndPair = false;
            this.numEntries++;
        }

        double parseDouble(StringBuilder sb)
        {
            double value = 0;
            try
            {
                value = Double.parseDouble(sb.toString());
            }
            catch (NumberFormatException e)
            {
                Logging.logger().log(Level.FINE,
                        Logging.getMessage("layers.PlaceNameLayer.ExceptionAttemptingToReadFile", ""), e);
            }
            return value;
        }

        int[] append(int[] array, int index, int value)
        {
            if (index >= array.length)
                array = this.resizeArray(array);
            array[index] = value;
            return array;
        }

        int[] resizeArray(int[] oldArray)
        {
            int newSize = 2 * oldArray.length;
            int[] newArray = new int[newSize];
            System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
            return newArray;
        }

        double[] append(double[] array, int index, double value)
        {
            if (index >= array.length)
                array = this.resizeArray(array);
            array[index] = value;
            return array;
        }

        double[] resizeArray(double[] oldArray)
        {
            int newSize = 2 * oldArray.length;
            double[] newArray = new double[newSize];
            System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
            return newArray;
        }

        @SuppressWarnings({"StringEquality"})
        public void characters(char ch[], int start, int length)
        {
            if (!this.inBeginEndPair)
                return;

            // Top of QName stack is an interned string,
            // so we can use pointer comparison.
            String internedTopQName = this.internedQNameStack.getFirst();

            StringBuilder sb = null;
            if (TOPP_LATITUDE == internedTopQName)
                sb = this.latBuffer;
            else if (TOPP_LONGITUDE == internedTopQName)
                sb = this.lonBuffer;
            else if (TOPP_FULL_NAME_ND == internedTopQName)
                sb = this.textArray;

            if (sb != null)
                sb.append(ch, start, length);
        }

        public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes attributes)
        {
            // Don't validate uri, localName or attributes because they aren't used.
            // Intern the qName string so we can use pointer comparison.
            String internedQName = qName.intern();
            //noinspection StringEquality
            if (GML_FEATURE_MEMBER == internedQName)
                this.beginEntry();
            this.internedQNameStack.addFirst(internedQName);
        }

        public void endElement(String uri, String localName, String qName)
        {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?