📄 surfaceimageeditor.java
字号:
/* Copyright (C) 2001, 2008 United States Government as represented bythe Administrator of the National Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.render;import gov.nasa.worldwind.*;import gov.nasa.worldwind.event.*;import gov.nasa.worldwind.geom.*;import gov.nasa.worldwind.globes.Globe;import gov.nasa.worldwind.layers.*;import gov.nasa.worldwind.pick.PickedObject;import gov.nasa.worldwind.render.markers.*;import gov.nasa.worldwind.terrain.SectorGeometryList;import gov.nasa.worldwind.util.Logging;import java.awt.*;import java.util.ArrayList;/** * @author dcollins * @version $Id: SurfaceImageEditor.java 9685 2009-03-26 17:02:02Z dcollins $ */public class SurfaceImageEditor implements SelectListener{ protected static final int NONE = 0; protected static final int MOVING = 1; protected static final int SIZING = 2; protected final WorldWindow wwd; protected SurfaceImage shape; protected MarkerLayer controlPointLayer; protected boolean armed; protected boolean active; protected int activeOperation = NONE; protected Position previousPosition = null; protected static class ControlPointMarker extends BasicMarker { private int index; public ControlPointMarker(Position position, MarkerAttributes attrs, int index) { super(position, attrs); this.index = index; } public int getIndex() { return this.index; } } public SurfaceImageEditor(WorldWindow wwd, SurfaceImage shape) { if (wwd == null) { String msg = Logging.getMessage("nullValue.WorldWindow"); Logging.logger().log(java.util.logging.Level.FINE, msg); throw new IllegalArgumentException(msg); } if (shape == null) { String msg = Logging.getMessage("nullValue.Shape"); Logging.logger().log(java.util.logging.Level.FINE, msg); throw new IllegalArgumentException(msg); } this.wwd = wwd; this.shape = shape; this.controlPointLayer = new MarkerLayer(); } public WorldWindow getWwd() { return this.wwd; } public SurfaceImage getSurfaceImage() { return this.shape; } public boolean isArmed() { return this.armed; } public void setArmed(boolean armed) { if (!this.armed && armed) { this.enable(); } else if (this.armed && !armed) { this.disable(); } this.armed = armed; } protected void enable() { LayerList layers = this.wwd.getModel().getLayers(); if (!layers.contains(this.controlPointLayer)) layers.add(this.controlPointLayer); if (!this.controlPointLayer.isEnabled()) this.controlPointLayer.setEnabled(true); this.updateAffordances(); this.wwd.addSelectListener(this); } protected void disable() { LayerList layers = this.wwd.getModel().getLayers(); layers.remove(this.controlPointLayer); wwd.removeSelectListener(this); } public void selected(SelectEvent event) { if (event == null) { String msg = Logging.getMessage("nullValue.EventIsNull"); Logging.logger().log(java.util.logging.Level.FINE, msg); throw new IllegalArgumentException(msg); } if (event.getTopObject() != null && !(event.getTopObject() == this.shape || event.getTopPickedObject().getParentLayer() == this.controlPointLayer)) { ((Component) this.wwd).setCursor(null); return; } if (event.getEventAction().equals(SelectEvent.DRAG_END)) { this.active = false; this.activeOperation = NONE; this.previousPosition = null; } else if (event.getEventAction().equals(SelectEvent.ROLLOVER)) { if (!(this.wwd instanceof Component)) return; if (event.getTopObject() == null || event.getTopPickedObject().isTerrain()) { ((Component) this.wwd).setCursor(null); return; } Cursor cursor; if (event.getTopObject() instanceof SurfaceImage) cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); else if (event.getTopObject() instanceof Marker) cursor = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR); else cursor = null; ((Component) this.wwd).setCursor(cursor); } else if (event.getEventAction().equals(SelectEvent.LEFT_PRESS)) { this.active = true; this.previousPosition = this.wwd.getCurrentPosition(); } else if (event.getEventAction().equals(SelectEvent.DRAG)) { if (!this.active) return; DragSelectEvent dragEvent = (DragSelectEvent) event; Object topObject = dragEvent.getTopObject(); if (topObject == null) return; if (topObject == this.shape || this.activeOperation == MOVING) { this.activeOperation = MOVING; this.dragWholeShape(dragEvent, topObject); this.updateAffordances(); } else if (dragEvent.getTopPickedObject().getParentLayer() == this.controlPointLayer || this.activeOperation == SIZING) { this.activeOperation = SIZING; this.resizeShape(topObject); this.updateAffordances(); } } } protected void dragWholeShape(DragSelectEvent dragEvent, Object topObject) { if (!(topObject instanceof Movable)) return; Movable dragObject = (Movable) topObject; View view = wwd.getView(); Globe globe = wwd.getModel().getGlobe(); // Compute ref-point position in screen coordinates. Since the SufaceShape is implicitly follows the surface // geometry, we will override the reference elevation with the current surface elevation. This will improve // cursor tracking in areas where the elevations are far from zero. Position refPos = dragObject.getReferencePosition(); double refElevation = this.computeSurfaceElevation(wwd, refPos); refPos = new Position(refPos, refElevation); Vec4 refPoint = globe.computePointFromPosition(refPos); Vec4 screenRefPoint = view.project(refPoint); // Compute screen-coord delta since last event. int dx = dragEvent.getPickPoint().x - dragEvent.getPreviousPickPoint().x; int dy = dragEvent.getPickPoint().y - dragEvent.getPreviousPickPoint().y; // Find intersection of screen coord ref-point with globe. double x = screenRefPoint.x + dx; double y = dragEvent.getMouseEvent().getComponent().getSize().height - screenRefPoint.y + dy - 1; Line ray = view.computeRayFromScreenPoint(x, y); Intersection inters[] = globe.intersect(ray, refPos.getElevation()); if (inters != null) { // Intersection with globe. Move reference point to the intersection point. Position p = globe.computePositionFromPoint(inters[0].getIntersectionPoint()); dragObject.moveTo(p); } } protected void resizeShape(Object topObject) { if (!(topObject instanceof ControlPointMarker)) return; // If the terrain beneath the control point is null, then the user is attempting to drag the handle off the // globe. This is not a valid state for SurfaceImage, so we will ignore this action but keep the drag operation // in effect. PickedObject terrainObject = this.wwd.getObjectsAtCurrentPosition().getTerrainObject(); if (terrainObject == null) return; Position p = terrainObject.getPosition(); Angle dLat = p.getLatitude().subtract(this.previousPosition.getLatitude()); Angle dLon = p.getLongitude().subtract(this.previousPosition.getLongitude()); LatLon delta = new LatLon(dLat, dLon); this.previousPosition = p; java.util.List<LatLon> corners = new ArrayList<LatLon>(this.shape.getCorners()); ControlPointMarker marker = (ControlPointMarker) topObject; corners.set(marker.getIndex(), corners.get(marker.getIndex()).add(delta)); this.shape.setCorners(corners); } protected void updateAffordances() { java.util.List<LatLon> corners = this.shape.getCorners(); double d = LatLon.getAverageDistance(corners).radians * wwd.getModel().getGlobe().getRadius(); MarkerAttributes markerAttrs = new BasicMarkerAttributes(Material.BLUE, BasicMarkerShape.SPHERE, 0.7, 10, 0.1, d / 30); ArrayList<LatLon> handlePositions = new ArrayList<LatLon>(8); for (LatLon corner : corners) { handlePositions.add(corner); } ArrayList<Marker> handles = new ArrayList<Marker>(handlePositions.size()); for (int i = 0; i < handlePositions.size(); i++) { handles.add(new ControlPointMarker(new Position(handlePositions.get(i), 0), markerAttrs, i)); } this.controlPointLayer.setOverrideMarkerElevation(true); this.controlPointLayer.setElevation(0); this.controlPointLayer.setKeepSeparated(false); this.controlPointLayer.setMarkers(handles); } protected double computeSurfaceElevation(WorldWindow wwd, LatLon latLon) { SectorGeometryList sgl = wwd.getSceneController().getTerrain(); if (sgl != null) { Vec4 point = sgl.getSurfacePoint(latLon.getLatitude(), latLon.getLongitude(), 0.0); if (point != null) { Position pos = wwd.getModel().getGlobe().computePositionFromPoint(point); return pos.getElevation(); } } return wwd.getModel().getGlobe().getElevation(latLon.getLatitude(), latLon.getLongitude()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -