private void adjustDateLineCrossingPoints() { ArrayList<LatLon> corners = new ArrayList<LatLon>(Arrays.asList(sw, se, nw, ne)); if (!LatLon.locationsCrossDateLine(corners)) return; double lonSign = 0; for (LatLon corner : corners) { if (Math.abs(corner.getLongitude().degrees) != 180) lonSign = Math.signum(corner.getLongitude().degrees); } if (lonSign == 0) return; if (Math.abs(sw.getLongitude().degrees) == 180 && Math.signum(sw.getLongitude().degrees) != lonSign) sw = new Position(sw.getLatitude(), sw.getLongitude().multiply(-1), sw.getElevation()); if (Math.abs(se.getLongitude().degrees) == 180 && Math.signum(se.getLongitude().degrees) != lonSign) se = new Position(se.getLatitude(), se.getLongitude().multiply(-1), se.getElevation()); if (Math.abs(nw.getLongitude().degrees) == 180 && Math.signum(nw.getLongitude().degrees) != lonSign) nw = new Position(nw.getLatitude(), nw.getLongitude().multiply(-1), nw.getElevation()); if (Math.abs(ne.getLongitude().degrees) == 180 && Math.signum(ne.getLongitude().degrees) != lonSign) ne = new Position(ne.getLatitude(), ne.getLongitude().multiply(-1), ne.getElevation()); }
protected void dragWholeShape(DragSelectEvent dragEvent, Movable dragObject) { View view = getWwd().getView(); EllipsoidalGlobe globe = (EllipsoidalGlobe) getWwd().getModel().getGlobe(); // Compute ref-point position in screen coordinates. Position refPos = dragObject.getReferencePosition(); if (refPos == null) return; 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 int determineAdjustmentSide(Movable dragObject, double factor) { if (dragObject instanceof SurfaceSector) { SurfaceSector quad = (SurfaceSector) dragObject; Sector s = quad.getSector(); // TODO: go over all sectors Position p = this.getWwd().getCurrentPosition(); if (p == null) { return NONE; } double dN = abs(s.getMaxLatitude().subtract(p.getLatitude()).degrees); double dS = abs(s.getMinLatitude().subtract(p.getLatitude()).degrees); double dW = abs(s.getMinLongitude().subtract(p.getLongitude()).degrees); double dE = abs(s.getMaxLongitude().subtract(p.getLongitude()).degrees); double sLat = factor * s.getDeltaLatDegrees(); double sLon = factor * s.getDeltaLonDegrees(); if (dN < sLat && dW < sLon) return NORTHWEST; if (dN < sLat && dE < sLon) return NORTHEAST; if (dS < sLat && dW < sLon) return SOUTHWEST; if (dS < sLat && dE < sLon) return SOUTHEAST; if (dN < sLat) return NORTH; if (dS < sLat) return SOUTH; if (dW < sLon) return WEST; if (dE < sLon) return EAST; } return NONE; }
private void fillPointsPanel() { int i = 0; for (Position pos : lineBuilder.getLine().getPositions()) { if (i == this.pointLabels.length) break; String las = String.format("Lat %7.4f\u00B0", pos.getLatitude().getDegrees()); String los = String.format("Lon %7.4f\u00B0", pos.getLongitude().getDegrees()); pointLabels[i++].setText(las + " " + los); } for (; i < this.pointLabels.length; i++) pointLabels[i++].setText(""); }
public void computeZone(DrawContext dc) { try { Position centerPos = ((OrbitView) dc.getView()).getCenterPosition(); if (centerPos != null) { if (centerPos.latitude.degrees <= UTM_MAX_LATITUDE && centerPos.latitude.degrees >= UTM_MIN_LATITUDE) { UTMCoord UTM = UTMCoord.fromLatLon( centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe()); this.zone = UTM.getZone(); } else this.zone = 0; } } catch (Exception ex) { this.zone = 0; } }
protected Sector resizeShape(Movable dragObject, int side) { if (dragObject instanceof SurfaceSector) { SurfaceSector quad = (SurfaceSector) dragObject; Sector s = quad.getSector(); // TODO: go over all sectors Position p = this.getWwd().getCurrentPosition(); if (p == null || this.getPreviousPosition() == null) { return null; } Angle dLat = p.getLatitude().subtract(this.getPreviousPosition().getLatitude()); Angle dLon = p.getLongitude().subtract(this.getPreviousPosition().getLongitude()); Angle newMinLat = s.getMinLatitude(); Angle newMinLon = s.getMinLongitude(); Angle newMaxLat = s.getMaxLatitude(); Angle newMaxLon = s.getMaxLongitude(); if (side == NORTH) { newMaxLat = s.getMaxLatitude().add(dLat); } else if (side == SOUTH) { newMinLat = s.getMinLatitude().add(dLat); } else if (side == EAST) { newMaxLon = s.getMaxLongitude().add(dLon); } else if (side == WEST) { newMinLon = s.getMinLongitude().add(dLon); } else if (side == NORTHWEST) { newMaxLat = s.getMaxLatitude().add(dLat); newMinLon = s.getMinLongitude().add(dLon); } else if (side == NORTHEAST) { newMaxLat = s.getMaxLatitude().add(dLat); newMaxLon = s.getMaxLongitude().add(dLon); } else if (side == SOUTHWEST) { newMinLat = s.getMinLatitude().add(dLat); newMinLon = s.getMinLongitude().add(dLon); } else if (side == SOUTHEAST) { newMinLat = s.getMinLatitude().add(dLat); newMaxLon = s.getMaxLongitude().add(dLon); } return new Sector(newMinLat, newMaxLat, newMinLon, newMaxLon); } return null; }
public void selectRenderables(DrawContext dc) { try { OrbitView view = (OrbitView) dc.getView(); // Compute easting and northing label offsets Double pixelSize = view.computePixelSizeAtDistance(view.getZoom()); Double eastingOffset = view.getViewport().width * pixelSize * offsetFactorX / 2; Double northingOffset = view.getViewport().height * pixelSize * offsetFactorY / 2; // Derive labels center pos from the view center Position centerPos = view.getCenterPosition(); double labelEasting; double labelNorthing; String labelHemisphere; if (this.zone > 0) { UTMCoord UTM = UTMCoord.fromLatLon(centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe()); labelEasting = UTM.getEasting() + eastingOffset; labelNorthing = UTM.getNorthing() + northingOffset; labelHemisphere = UTM.getHemisphere(); if (labelNorthing < 0) { labelNorthing = 10e6 + labelNorthing; labelHemisphere = AVKey.SOUTH; } } else { UPSCoord UPS = UPSCoord.fromLatLon(centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe()); labelEasting = UPS.getEasting() + eastingOffset; labelNorthing = UPS.getNorthing() + northingOffset; labelHemisphere = UPS.getHemisphere(); } Position labelPos; for (int i = 0; i < this.extremes.length; i++) { UTMExtremes levelExtremes = this.extremes[i]; double gridStep = Math.pow(10, i); double gridStepTimesTen = gridStep * 10; String graticuleType = getTypeFor((int) gridStep); if (levelExtremes.minX <= levelExtremes.maxX) { // Process easting scale labels for this level for (double easting = levelExtremes.minX; easting <= levelExtremes.maxX; easting += gridStep) { // Skip multiples of ten grid steps except for last (higher) level if (i == this.extremes.length - 1 || easting % gridStepTimesTen != 0) { try { labelPos = computePosition(this.zone, labelHemisphere, easting, labelNorthing); if (labelPos == null) continue; Angle lat = labelPos.getLatitude(); Angle lon = labelPos.getLongitude(); Vec4 surfacePoint = getSurfacePoint(dc, lat, lon); if (viewFrustum.contains(surfacePoint) && isPointInRange(dc, surfacePoint)) { String text = String.valueOf((int) (easting % this.scaleModulo)); GeographicText gt = new UserFacingText(text, new Position(lat, lon, 0)); gt.setPriority(gridStepTimesTen); addRenderable(gt, graticuleType); } } catch (IllegalArgumentException ignore) { } } } } if (!(levelExtremes.maxYHemisphere.equals(AVKey.SOUTH) && levelExtremes.maxY == 0)) { // Process northing scale labels for this level String currentHemisphere = levelExtremes.minYHemisphere; for (double northing = levelExtremes.minY; (northing <= levelExtremes.maxY) || !currentHemisphere.equals(levelExtremes.maxYHemisphere); northing += gridStep) { // Skip multiples of ten grid steps except for last (higher) level if (i == this.extremes.length - 1 || northing % gridStepTimesTen != 0) { try { labelPos = computePosition(this.zone, currentHemisphere, labelEasting, northing); if (labelPos == null) continue; Angle lat = labelPos.getLatitude(); Angle lon = labelPos.getLongitude(); Vec4 surfacePoint = getSurfacePoint(dc, lat, lon); if (viewFrustum.contains(surfacePoint) && isPointInRange(dc, surfacePoint)) { String text = String.valueOf((int) (northing % this.scaleModulo)); GeographicText gt = new UserFacingText(text, new Position(lat, lon, 0)); gt.setPriority(gridStepTimesTen); addRenderable(gt, graticuleType); } } catch (IllegalArgumentException ignore) { } if (!currentHemisphere.equals(levelExtremes.maxYHemisphere) && northing >= 10e6 - gridStep) { // Switch hemisphere currentHemisphere = levelExtremes.maxYHemisphere; northing = -gridStep; } } } } // end northing } // for levels } catch (IllegalArgumentException ignore) { } }
/** Create the graticule grid elements */ private void createUTMRenderables() { this.gridElements = new ArrayList<GridElement>(); ArrayList<Position> positions = new ArrayList<Position>(); // Generate meridians and zone labels int lon = -180; int zoneNumber = 1; int maxLat; for (int i = 0; i < 60; i++) { Angle longitude = Angle.fromDegrees(lon); // Meridian positions.clear(); positions.add(new Position(Angle.fromDegrees(-80), longitude, 10e3)); positions.add(new Position(Angle.fromDegrees(-60), longitude, 10e3)); positions.add(new Position(Angle.fromDegrees(-30), longitude, 10e3)); positions.add(new Position(Angle.ZERO, longitude, 10e3)); positions.add(new Position(Angle.fromDegrees(30), longitude, 10e3)); if (lon < 6 || lon > 36) { // 'regular' UTM meridians maxLat = 84; positions.add(new Position(Angle.fromDegrees(60), longitude, 10e3)); positions.add(new Position(Angle.fromDegrees(maxLat), longitude, 10e3)); } else { // Exceptions: shorter meridians around and north-east of Norway if (lon == 6) { maxLat = 56; positions.add(new Position(Angle.fromDegrees(maxLat), longitude, 10e3)); } else { maxLat = 72; positions.add(new Position(Angle.fromDegrees(60), longitude, 10e3)); positions.add(new Position(Angle.fromDegrees(maxLat), longitude, 10e3)); } } Object polyline = createLineRenderable(positions, Polyline.GREAT_CIRCLE); Sector sector = Sector.fromDegrees(-80, maxLat, lon, lon); this.gridElements.add(new GridElement(sector, polyline, GridElement.TYPE_LINE)); // Zone label GeographicText text = new UserFacingText(zoneNumber + "", Position.fromDegrees(0, lon + 3, 0)); sector = Sector.fromDegrees(-90, 90, lon + 3, lon + 3); this.gridElements.add(new GridElement(sector, text, GridElement.TYPE_LONGITUDE_LABEL)); // Increase longitude and zone number lon += 6; zoneNumber++; } // Generate special meridian segments for exceptions around and north-east of Norway for (int i = 0; i < 5; i++) { positions.clear(); lon = specialMeridians[i][0]; positions.add( new Position(Angle.fromDegrees(specialMeridians[i][1]), Angle.fromDegrees(lon), 10e3)); positions.add( new Position(Angle.fromDegrees(specialMeridians[i][2]), Angle.fromDegrees(lon), 10e3)); Object polyline = createLineRenderable(positions, Polyline.GREAT_CIRCLE); Sector sector = Sector.fromDegrees(specialMeridians[i][1], specialMeridians[i][2], lon, lon); this.gridElements.add(new GridElement(sector, polyline, GridElement.TYPE_LINE)); } // Generate parallels - no exceptions int lat = -80; for (int i = 0; i < 21; i++) { Angle latitude = Angle.fromDegrees(lat); for (int j = 0; j < 4; j++) { // Each prallel is divided into four 90 degrees segments positions.clear(); lon = -180 + j * 90; positions.add(new Position(latitude, Angle.fromDegrees(lon), 10e3)); positions.add(new Position(latitude, Angle.fromDegrees(lon + 30), 10e3)); positions.add(new Position(latitude, Angle.fromDegrees(lon + 60), 10e3)); positions.add(new Position(latitude, Angle.fromDegrees(lon + 90), 10e3)); Object polyline = createLineRenderable(positions, Polyline.LINEAR); Sector sector = Sector.fromDegrees(lat, lat, lon, lon + 90); this.gridElements.add(new GridElement(sector, polyline, GridElement.TYPE_LINE)); } // Latitude band label if (i < 20) { GeographicText text = new UserFacingText(latBands.charAt(i) + "", Position.fromDegrees(lat + 4, 0, 0)); Sector sector = Sector.fromDegrees(lat + 4, lat + 4, -180, 180); this.gridElements.add(new GridElement(sector, text, GridElement.TYPE_LATITUDE_LABEL)); } // Increase latitude lat += lat < 72 ? 8 : 12; } }
/** * Select the visible grid elements * * @param dc the current <code>DrawContext</code>. */ protected void selectRenderables(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } Sector vs = dc.getVisibleSector(); OrbitView view = (OrbitView) dc.getView(); // Compute labels offset from view center Position centerPos = view.getCenterPosition(); Double pixelSizeDegrees = Angle.fromRadians( view.computePixelSizeAtDistance(view.getZoom()) / dc.getGlobe().getEquatorialRadius()) .degrees; Double labelOffsetDegrees = pixelSizeDegrees * view.getViewport().getWidth() / 4; Position labelPos = Position.fromDegrees( centerPos.getLatitude().degrees - labelOffsetDegrees, centerPos.getLongitude().degrees - labelOffsetDegrees, 0); Double labelLatDegrees = labelPos.getLatitude().normalizedLatitude().degrees; labelLatDegrees = Math.min(Math.max(labelLatDegrees, -76), 78); labelPos = new Position( Angle.fromDegrees(labelLatDegrees), labelPos.getLongitude().normalizedLongitude(), 0); if (vs != null) { for (GridElement ge : this.gridElements) { if (ge.isInView(dc)) { if (ge.renderable instanceof GeographicText) { GeographicText gt = (GeographicText) ge.renderable; if (labelPos.getLatitude().degrees < 72 || "*32*34*36*".indexOf("*" + gt.getText() + "*") == -1) { // Adjust label position according to eye position Position pos = gt.getPosition(); if (ge.type.equals(GridElement.TYPE_LATITUDE_LABEL)) pos = Position.fromDegrees( pos.getLatitude().degrees, labelPos.getLongitude().degrees, pos.getElevation()); else if (ge.type.equals(GridElement.TYPE_LONGITUDE_LABEL)) pos = Position.fromDegrees( labelPos.getLatitude().degrees, pos.getLongitude().degrees, pos.getElevation()); gt.setPosition(pos); } } this.graticuleSupport.addRenderable(ge.renderable, GRATICULE_UTM); } } // System.out.println("Total elements: " + count + " visible sector: " + vs); } }
public AppFrame() { super(true, true, false); // Add detail hint slider panel this.getLayerPanel().add(makeDetailHintControlPanel(), BorderLayout.SOUTH); RenderableLayer layer = new RenderableLayer(); // Create and set an attribute bundle. ShapeAttributes attrs = new BasicShapeAttributes(); attrs.setInteriorMaterial(Material.YELLOW); attrs.setInteriorOpacity(0.7); attrs.setEnableLighting(true); attrs.setOutlineMaterial(Material.RED); attrs.setOutlineWidth(2d); attrs.setDrawInterior(true); attrs.setDrawOutline(false); // Create and set an attribute bundle. ShapeAttributes attrs2 = new BasicShapeAttributes(); attrs2.setInteriorMaterial(Material.PINK); attrs2.setInteriorOpacity(1); attrs2.setEnableLighting(true); attrs2.setOutlineMaterial(Material.WHITE); attrs2.setOutlineWidth(2d); attrs2.setDrawOutline(false); // ********* sample Wedges ******************* // Wedge with equal axes, ABSOLUTE altitude mode Wedge wedge3 = new Wedge(Position.fromDegrees(40, -120, 80000), Angle.POS90, 50000, 50000, 50000); wedge3.setAltitudeMode(WorldWind.ABSOLUTE); wedge3.setAttributes(attrs); wedge3.setVisible(true); wedge3.setValue(AVKey.DISPLAY_NAME, "Wedge with equal axes, ABSOLUTE altitude mode"); layer.addRenderable(wedge3); // Wedge with equal axes, RELATIVE_TO_GROUND Wedge wedge4 = new Wedge(Position.fromDegrees(37.5, -115, 50000), Angle.POS90, 50000, 50000, 50000); wedge4.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge4.setAttributes(attrs); wedge4.setVisible(true); wedge4.setValue( AVKey.DISPLAY_NAME, "Wedge with equal axes, RELATIVE_TO_GROUND altitude mode"); layer.addRenderable(wedge4); // Wedge with equal axes, CLAMP_TO_GROUND Wedge wedge5 = new Wedge(Position.fromDegrees(35, -110, 50000), Angle.POS90, 50000, 50000, 50000); wedge5.setAltitudeMode(WorldWind.CLAMP_TO_GROUND); wedge5.setAttributes(attrs); wedge5.setVisible(true); wedge5.setValue(AVKey.DISPLAY_NAME, "Wedge with equal axes, CLAMP_TO_GROUND altitude mode"); layer.addRenderable(wedge5); // Wedge with a texture, using Wedge(position, angle, height, radius) constructor Wedge wedge9 = new Wedge(Position.fromDegrees(0, -90, 600000), Angle.fromDegrees(225), 1200000, 600000); wedge9.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge9.setImageSources("gov/nasa/worldwindx/examples/images/500px-Checkerboard_pattern.png"); wedge9.setAttributes(attrs); wedge9.setVisible(true); wedge9.setValue(AVKey.DISPLAY_NAME, "Wedge with a texture"); layer.addRenderable(wedge9); // Scaled Wedge with default orientation Wedge wedge = new Wedge(Position.ZERO, Angle.fromDegrees(125), 500000, 500000, 500000); wedge.setAltitudeMode(WorldWind.ABSOLUTE); wedge.setAttributes(attrs); wedge.setVisible(true); wedge.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with default orientation"); layer.addRenderable(wedge); // Scaled Wedge with a pre-set orientation Wedge wedge2 = new Wedge( Position.fromDegrees(0, 30, 750000), Angle.POS90, 500000, 500000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge2.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge2.setAttributes(attrs2); wedge2.setVisible(true); wedge2.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with a pre-set orientation"); layer.addRenderable(wedge2); // Scaled Wedge with a pre-set orientation Wedge wedge6 = new Wedge( Position.fromDegrees(30, 30, 750000), Angle.POS90, 500000, 500000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge6.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge6.setImageSources("gov/nasa/worldwindx/examples/images/500px-Checkerboard_pattern.png"); wedge6.setAttributes(attrs2); wedge6.setVisible(true); wedge6.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with a pre-set orientation"); layer.addRenderable(wedge6); // Scaled Wedge with a pre-set orientation Wedge wedge7 = new Wedge( Position.fromDegrees(60, 30, 750000), Angle.POS90, 500000, 500000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge7.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge7.setAttributes(attrs2); wedge7.setVisible(true); wedge7.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with a pre-set orientation"); layer.addRenderable(wedge7); // Scaled, oriented Wedge in 3rd "quadrant" (-X, -Y, -Z) Wedge wedge8 = new Wedge( Position.fromDegrees(-45, -180, 750000), Angle.POS90, 500000, 1000000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge8.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge8.setAttributes(attrs2); wedge8.setVisible(true); wedge8.setValue( AVKey.DISPLAY_NAME, "Scaled, oriented Wedge with in the 3rd 'quadrant' (-X, -Y, -Z)"); layer.addRenderable(wedge8); // Add the layer to the model. insertBeforeCompass(getWwd(), layer); // Update layer panel this.getLayerPanel().update(this.getWwd()); }