cloudceiling.java

来自「world wind java sdk 源码」· Java 代码 · 共 508 行 · 第 1/2 页

JAVA
508
字号
        // Start cap
        if (this.centerPositions.size() > 1)
            heading = LatLon.greatCircleAzimuth(this.centerPositions.get(cpn), this.centerPositions.get(cpn + 1));
        this.extentPositions.addAll(computeArcPositions(globe, this.centerPositions.get(cpn),
            heading.addDegrees(90), heading.addDegrees(270), this.radius));
        // Follow path one way
        while (cpn < this.centerPositions.size() - 1)
        {
            Angle previousHeading = heading;
            heading = LatLon.greatCircleAzimuth(this.centerPositions.get(cpn), this.centerPositions.get(cpn + 1));
            Angle nextHeading = heading;
            if (cpn < this.centerPositions.size() - 2)
                nextHeading = LatLon.greatCircleAzimuth(this.centerPositions.get(cpn + 1), this.centerPositions.get(cpn + 2));
            this.extentPositions.addAll(computeLinePositions(globe, this.centerPositions.get(cpn),
                this.centerPositions.get(cpn + 1), previousHeading, heading, nextHeading, radius));
            cpn++;
        }
        // End cap - turn around
        heading = normalizedHeading(heading.addDegrees(180));
        cpn = this.centerPositions.size() - 1;
        this.extentPositions.addAll(computeArcPositions(globe, this.centerPositions.get(cpn),
            heading.addDegrees(90), heading.addDegrees(270), this.radius));
        // Follow path the other way
        while (cpn > 0)
        {
            Angle previousHeading = heading;
            heading = LatLon.greatCircleAzimuth(this.centerPositions.get(cpn), this.centerPositions.get(cpn - 1));
            Angle nextHeading = heading;
            if (cpn > 1)
                nextHeading = LatLon.greatCircleAzimuth(this.centerPositions.get(cpn - 1), this.centerPositions.get(cpn - 2));
            this.extentPositions.addAll(computeLinePositions(globe, this.centerPositions.get(cpn),
                this.centerPositions.get(cpn - 1), previousHeading, heading, nextHeading, radius));
            cpn--;
        }
        // Close polygon
        this.extentPositions.add(this.extentPositions.get(0));
    }

    private static ArrayList<LatLon> computeArcPositions(Globe globe, LatLon center, Angle start, Angle end, double radius)
    {
        start = normalizedHeading(start);
        end = normalizedHeading(end);
        end = end.degrees > start.degrees ? end : end.addDegrees(360);
        ArrayList<LatLon> positions = new ArrayList<LatLon>();
        Angle radiusAngle = Angle.fromRadians(radius / globe.getRadiusAt(center));
        //positions.add(LatLon.greatCircleEndPosition(center, start, radiusAngle)); // Skip first pos
        positions.add(LatLon.greatCircleEndPosition(center, Angle.midAngle(start, end), radiusAngle));
        positions.add(LatLon.greatCircleEndPosition(center, end, radiusAngle));
        return positions;
    }

    private static ArrayList<LatLon> computeLinePositions(Globe globe, LatLon p1, LatLon p2, Angle previousHeading,
        Angle heading, Angle nextHeading, double radius)
    {
        ArrayList<LatLon> positions = new ArrayList<LatLon>();
        Angle radiusAngle = Angle.fromRadians(radius / globe.getRadiusAt(p1));
        // Skip first pos
//        if (isClockwiseHeadingChange(previousHeading, heading))
//            positions.add(LatLon.greatCircleEndPosition(p1, heading.subtractDegrees(90), radiusAngle));
//        else
//            positions.add(LatLon.greatCircleEndPosition(p1,
//                computeMidHeading(previousHeading, heading).subtractDegrees(90), radiusAngle));

        if (isClockwiseHeadingChange(heading, nextHeading))
        {
            positions.add(LatLon.greatCircleEndPosition(p2, heading.subtractDegrees(90), radiusAngle));
            if (!heading.equals(nextHeading))
                positions.addAll(computeArcPositions(globe, p2, heading.subtractDegrees(90),
                    nextHeading.subtractDegrees(90), radius));
        }
        else
            positions.add(LatLon.greatCircleEndPosition(p2,
                computeMidHeading(heading, nextHeading).subtractDegrees(90), radiusAngle));

        return positions;
    }

    private static boolean isClockwiseHeadingChange(Angle from, Angle to)
    {
        double a1 = normalizedHeading(from).degrees;
        double a2 = normalizedHeading(to).degrees;
        return (a2 > a1 && a2 - a1 < 180);
    }

    private static Angle computeMidHeading(Angle a1, Angle a2)
    {
        a1 = normalizedHeading(a1);
        a2 = normalizedHeading(a2);
        if (a1.degrees < a2.degrees && a2.degrees - a1.degrees > 180)
            a1 = a1.addDegrees(360);
        else if (a2.degrees < a1.degrees && a1.degrees - a2.degrees > 180)
            a2 = a2.addDegrees(360);
        return Angle.midAngle(a1, a2);
    }

    private static Angle normalizedHeading(Angle heading)
    {
        double a = heading.degrees % 360;
        while (a < 0)
            a += 360;
        return Angle.fromDegrees(a);
    }

    public String getRestorableState()
    {
        RestorableSupport restorableSupport = RestorableSupport.newRestorableSupport();
        // Creating a new RestorableSupport failed. RestorableSupport logged the problem, so just return null.
        if (restorableSupport == null)
            return null;

        restorableSupport.addStateValueAsString("name", this.name);
        
        if (this.color != null)
        {
            String encodedColor = RestorableSupport.encodeColor(this.color);
            if (encodedColor != null)
                restorableSupport.addStateValueAsString("color", encodedColor);
        }

        if (this.centerPositions != null)
        {
            // Create the base "positions" state object.
            RestorableSupport.StateObject positionsStateObj = restorableSupport.addStateObject("positions");
            if (positionsStateObj != null)
            {
                for (LatLon p : this.centerPositions)
                {
                    // Save each position only if all parts (latitude, longitude) can be saved.
                    if (p != null && p.getLatitude() != null && p.getLongitude() != null)
                    {
                        // Create a nested "position" element underneath the base "positions".
                        RestorableSupport.StateObject pStateObj =
                            restorableSupport.addStateObject(positionsStateObj, "position");
                        if (pStateObj != null)
                        {
                            restorableSupport.addStateValueAsDouble(pStateObj, "latitudeDegrees",
                                p.getLatitude().degrees);
                            restorableSupport.addStateValueAsDouble(pStateObj, "longitudeDegrees",
                                p.getLongitude().degrees);
                        }
                    }
                }
            }
        }

        restorableSupport.addStateValueAsString("elevationUnit", this.elevationUnit);
        restorableSupport.addStateValueAsString("deltaMode", this.deltaMode);
        restorableSupport.addStateValueAsDouble("elevationDelta", this.elevationDelta);
        restorableSupport.addStateValueAsDouble("elevationBase", this.elevationBase);
        restorableSupport.addStateValueAsDouble("radius", this.radius);
        restorableSupport.addStateValueAsBoolean("enabled", this.enabled);
        restorableSupport.addStateValueAsBoolean("showExtent", this.showExtent);

        return restorableSupport.getStateAsXml();
    }

    public void restoreState(String stateInXml)
    {
        if (stateInXml == null)
        {
            String message = Logging.getMessage("nullValue.StringIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        RestorableSupport restorableSupport;
        try
        {
            restorableSupport = RestorableSupport.parse(stateInXml);
        }
        catch (Exception e)
        {
            // Parsing the document specified by stateInXml failed.
            String message = Logging.getMessage("generic.ExceptionAttemptingToParseStateXml", stateInXml);
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message, e);
        }

        String colorState = restorableSupport.getStateValueAsString("color");
        if (colorState != null)
        {
            Color color = RestorableSupport.decodeColor(colorState);
            if (color != null)
                setColor(color);
        }

        // Get the base "positions" state object.
        RestorableSupport.StateObject positionsStateObj = restorableSupport.getStateObject("positions");
        if (positionsStateObj != null)
        {
            ArrayList<LatLon> newPositions = new ArrayList<LatLon>();
            // Get the nested "position" states beneath the base "positions".
            RestorableSupport.StateObject[] positionStateArray =
                restorableSupport.getAllStateObjects(positionsStateObj, "position");
            if (positionStateArray != null && positionStateArray.length != 0)
            {
                for (RestorableSupport.StateObject pStateObj : positionStateArray)
                {
                    if (pStateObj != null)
                    {
                        // Restore each position only if all parts are available.
                        Double latitudeState = restorableSupport.getStateValueAsDouble(pStateObj, "latitudeDegrees");
                        Double longitudeState = restorableSupport.getStateValueAsDouble(pStateObj, "longitudeDegrees");
                        if (latitudeState != null && longitudeState != null)
                            newPositions.add(LatLon.fromDegrees(latitudeState, longitudeState));
                    }
                }
            }

            // Even if there are no actual positions specified, we set positions as an empty list.
            // An empty set of positions is still a valid state.
            this.centerPositions = newPositions;
        }

        String nameState = restorableSupport.getStateValueAsString("name");
        if (nameState != null)
            this.name = nameState;

        String elevationUnitState = restorableSupport.getStateValueAsString("elevationUnit");
        if (elevationUnitState != null)
            this.elevationUnit = elevationUnitState;

        String deltaModeState = restorableSupport.getStateValueAsString("deltaMode");
        if (deltaModeState != null)
            this.deltaMode = deltaModeState;

        Double elevationDeltaState = restorableSupport.getStateValueAsDouble("elevationDelta");
        if (elevationDeltaState != null)
            this.elevationDelta = elevationDeltaState;

        Double elevationBaseState = restorableSupport.getStateValueAsDouble("elevationBase");
        if (elevationBaseState != null)
            this.elevationBase = elevationBaseState;

        Double radiusState = restorableSupport.getStateValueAsDouble("radius");
        if (radiusState != null)
            this.radius = radiusState;

        Boolean enabledState = restorableSupport.getStateValueAsBoolean("enabled");
        if (enabledState != null)
            setEnabled(enabledState);

        Boolean showExtentState = restorableSupport.getStateValueAsBoolean("showExtent");
        if (showExtentState != null)
            this.showExtent = showExtentState;


        this.updateElevations();
        this.updateExtent();

    }

}

⌨️ 快捷键说明

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