Package org.geoforge.worldwind.builder.editor

Source Code of org.geoforge.worldwind.builder.editor.GfrEditorObjShpPlnCls

/* Copyright (C) 2001, 2011 United States Government as represented by
the Administrator of the National Aeronautics and Space Administration.
All Rights Reserved.
*/
package org.geoforge.worldwind.builder.editor;

import gov.nasa.worldwind.View;
import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Line;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.render.DrawContext;
import gov.nasa.worldwind.render.ExtrudedPolygon;
import gov.nasa.worldwind.render.airspaces.editor.AirspaceEditorUtil;
import gov.nasa.worldwind.terrain.Terrain;
import java.awt.Point;
import java.util.ArrayList;
import org.geoforge.worldwind.builder.marker.GfrMrkMoveAbs;
import org.geoforge.worldwind.builder.marker.GfrMrkMoveHoriz;

/**
* @author bantchao
*
* Based on WWD's ExtrudedPolygonEditor.java
* excluded inner-classes
*/
public class GfrEditorObjShpPlnCls extends GfrEditorObjShpPlnAbs
{
    public GfrEditorObjShpPlnCls()
    {
        super();
    }

    @Override
    protected void _assembleVertexControlPoints_(DrawContext dc)
    {
        Terrain terrain = dc.getTerrain();
        ExtrudedPolygon pol = (ExtrudedPolygon) super._pol_;

        Position refPos = pol.getReferencePosition();
        Vec4 refPoint = terrain.getSurfacePoint(refPos.getLatitude(), refPos.getLongitude(), 0);

        int altitudeMode = pol.getAltitudeMode();
        double height = pol.getHeight();

        Vec4 vaa = null;
        double vaaLength = 0; // used to compute independent length of each cap vertex
        double vaLength = 0;

        int i = 0;
        for (LatLon location : pol.getOuterBoundary())
        {
            Vec4 vert;

            // Compute the top/cap point.
            if (altitudeMode == WorldWind.CONSTANT || !(location instanceof Position))
            {
                if (vaa == null)
                {
                    // Compute the vector lengths of the top and bottom points at the reference position.
                    vaa = refPoint.multiply3(height / refPoint.getLength3());
                    vaaLength = vaa.getLength3();
                    vaLength = refPoint.getLength3();
                }

                // Compute the bottom point, which is on the terrain.
                vert = terrain.getSurfacePoint(location.getLatitude(), location.getLongitude(), 0);

                double delta = vaLength - vert.dot3(refPoint) / vaLength;
                vert = vert.add3(vaa.multiply3(1d + delta / vaaLength));
            }
            else if (altitudeMode == WorldWind.RELATIVE_TO_GROUND)
            {
                vert = terrain.getSurfacePoint(location.getLatitude(), location.getLongitude(),
                    ((Position) location).getAltitude());
            }
            else // WorldWind.ABSOLUTE
            {
                vert = terrain.getGlobe().computePointFromPosition(location.getLatitude(), location.getLongitude(),
                    ((Position) location).getAltitude() * terrain.getVerticalExaggeration());
            }

            Position vertexPosition = super._wwd.getModel().getGlobe().computePositionFromPoint(vert);
          
           
            GfrMrkMoveHoriz pnt = new GfrMrkMoveHoriz(vertexPosition, vert,
                super._bmaControlVertex, i);

            super._lstMarkerControlPoints.add(pnt);
           
            i++;
        }
    }   

    //*************************************************************
    // ***************** Polygon manipulation *********************
    //*************************************************************

   

    @Override
    protected void moveControlPoint(GfrMrkMoveHoriz controlPoint, Point lastMousePoint, Point moveToPoint)
    {
        View view = super._wwd.getView();
        Globe globe = super._wwd.getModel().getGlobe();

        Position refPos = controlPoint.getPosition();
        if (refPos == null)
            return;

        Line ray = view.computeRayFromScreenPoint(moveToPoint.getX(), moveToPoint.getY());
        Line previousRay = view.computeRayFromScreenPoint(lastMousePoint.getX(), lastMousePoint.getY());

        Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(super._wwd, refPos.getElevation(), ray);
        Vec4 previousVec = AirspaceEditorUtil.intersectGlobeAt(super._wwd, refPos.getElevation(), previousRay);

        if (vec == null || previousVec == null)
        {
            return;
        }

        Position pos = globe.computePositionFromPoint(vec);
        Position previousPos = globe.computePositionFromPoint(previousVec);
        LatLon change = pos.subtract(previousPos);

        java.util.List<LatLon> boundary = new ArrayList<LatLon>();
        for (LatLon ll : ((ExtrudedPolygon) super._pol_).getOuterBoundary())
        {
            boundary.add(ll);
        }

        boundary.set(controlPoint.getIndex(), new Position(pos.add(change), refPos.getAltitude()));

        // ExtrudedPolygon ensures that the last boundary position is the same as the first. Remove the last point
        // before setting the boundary.
        boundary.remove(boundary.size() - 1);

        ((ExtrudedPolygon) super._pol_).setOuterBoundary(boundary);
    }

    @Override
    protected void setHeightPolyline(Point previousMousePoint, Point mousePoint)
    {
        // Find the closest points between the rays through each screen point, and the ray from the control point
        // and in the direction of the globe's surface normal. Compute the elevation difference between these two
        // points, and use that as the change in polygon height.

        Position referencePos = this._pol_.getReferencePosition();
       
        if (referencePos == null)
            return;

        Vec4 referencePoint = super._wwd.getModel().getGlobe().computePointFromPosition(referencePos);

        Vec4 surfaceNormal = super._wwd.getModel().getGlobe().computeSurfaceNormalAtLocation(referencePos.getLatitude(),
            referencePos.getLongitude());
        Line verticalRay = new Line(referencePoint, surfaceNormal);
        Line screenRay = super._wwd.getView().computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
        Line previousScreenRay = super._wwd.getView().computeRayFromScreenPoint(previousMousePoint.getX(),
            previousMousePoint.getY());

        Vec4 pointOnLine = AirspaceEditorUtil.nearestPointOnLine(verticalRay, screenRay);
        Vec4 previousPointOnLine = AirspaceEditorUtil.nearestPointOnLine(verticalRay, previousScreenRay);

        Position pos = super._wwd.getModel().getGlobe().computePositionFromPoint(pointOnLine);
        Position previousPos = super._wwd.getModel().getGlobe().computePositionFromPoint(previousPointOnLine);
        double elevationChange = pos.getElevation() - previousPos.getElevation();

        java.util.List<Position> boundary = new ArrayList<Position>();
       
        for (LatLon ll : ((ExtrudedPolygon) super._pol_).getOuterBoundary())
        {
            boundary.add(new Position(ll, ((Position) ll).getElevation() + elevationChange));
        }

        ((ExtrudedPolygon) super._pol_).setOuterBoundary(boundary);
    }

    /**
     * Add a vertex to the polygon's outer boundary.
     *
     * @param _pntMouse the point at which the mouse was clicked. The new vertex will be placed as near as possible to
     *                   this point, at the elevation of the polygon.
     */
    @Override
    protected void addVertex(Point mousePoint)
    {
       
        // Try to find the edge that is closest to a ray passing through the screen point. We're trying to determine
        // the user's intent as to which edge a new two control points should be added to.

        Line ray = super._wwd.getView().computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
        Vec4 pickPoint = super._intersectPolygonAltitudeAt(ray);

        double nearestDistance = Double.MAX_VALUE;
        int newVertexIndex = 0;

        // Loop through the control points and determine which edge is closest to the pick point
        for (int i = 0; i < this._lstMarkerControlPoints.size(); i++)
        {
            GfrMrkMoveAbs thisMarker = (GfrMrkMoveAbs) this._lstMarkerControlPoints.get(i);
            GfrMrkMoveAbs nextMarker = (GfrMrkMoveAbs) this._lstMarkerControlPoints.get(
                (i + 1) % this._lstMarkerControlPoints.size());

            Vec4 pointOnEdge = AirspaceEditorUtil.nearestPointOnSegment(thisMarker.getPoint(), nextMarker.getPoint(), pickPoint);
            if (!AirspaceEditorUtil.isPointBehindLineOrigin(ray, pointOnEdge))
            {
                double d = pointOnEdge.distanceTo3(pickPoint);
                if (d < nearestDistance)
                {
                    newVertexIndex = i + 1;
                    nearestDistance = d;
                }
            }
        }

        Position newPosition = super._wwd.getModel().getGlobe().computePositionFromPoint(pickPoint);

        // Copy the outer boundary list
        ArrayList<Position> positionList = new ArrayList<Position>(this._lstMarkerControlPoints.size());
        for (LatLon position : ((ExtrudedPolygon) super._pol_).getOuterBoundary())
        {
            positionList.add((Position) position);
        }

        // Add the new vertex
        positionList.add(newVertexIndex, newPosition);

        ((ExtrudedPolygon) super._pol_).setOuterBoundary(positionList);
    }

    /**
     * Remove a vertex from the polygon.
     *
     * @param vertexToRemove the vertex to remove.
     */
    @Override
    protected boolean removeVertex(GfrMrkMoveHoriz vertexToRemove)
    {
       
        if (this._lstMarkerControlPoints.size() == 5) // 3 edges + 1 double point + 1 for height control
        {
            System.out.println("this._lstMarkerControlPoints.size() == 5, preventing remove");
            return false;
        }
       
        ExtrudedPolygon polygon = (ExtrudedPolygon) super._pol_;
        ArrayList<LatLon> locations = new ArrayList<LatLon>(this._lstMarkerControlPoints.size() - 1);

        for (LatLon latLon : polygon.getOuterBoundary())
        {
            locations.add(latLon);
        }
       
        locations.remove(vertexToRemove.getIndex());

        polygon.setOuterBoundary(locations);
        return true;
    }
}

TOP

Related Classes of org.geoforge.worldwind.builder.editor.GfrEditorObjShpPlnCls

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.