//********************************************************************** // //<copyright> // //BBN Technologies, a Verizon Company //10 Moulton Street //Cambridge, MA 02138 //(617) 873-8000 // //Copyright (C) BBNT Solutions LLC. All rights reserved. // //</copyright> //********************************************************************** // //$Source: ///cvs/darwars/ambush/aar/src/com/bbn/ambush/mission/MissionHandler.java,v //$ //$RCSfile: OMGeo.java,v $ //$Revision: 1.6 $ //$Date: 2009/01/21 01:24:42 $ //$Author: dietrick $ // //********************************************************************** package com.bbn.openmap.geo; import java.awt.Point; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import java.util.ArrayList; import com.bbn.openmap.MoreMath; import com.bbn.openmap.omGraphics.OMGraphicAdapter; import com.bbn.openmap.omGraphics.OMPoint; import com.bbn.openmap.proj.GeoProj; import com.bbn.openmap.proj.Projection; import com.bbn.openmap.proj.coords.LatLonPoint; import com.bbn.openmap.util.Debug; /** * This is a class (or set of classes) that map GeoExtents to OMGraphics. They * can be used directly in a ExtentIndex and will render within OpenMap. This * class is not considered to be part of the omgeo.jar package because of its * dependencies on OpenMap, but resides in this package because of it's * knowledge of it. * * @author dietrick */ public abstract class OMGeo extends OMGraphicAdapter implements GeoExtent { protected GeoExtent extent; protected Object id = OMGeo.this; protected OMGeo() { setRenderType(RENDERTYPE_LATLON); } protected OMGeo(GeoExtent ge) { this(); setExtent(ge); } public GeoExtent getExtent() { return extent; } public void setExtent(GeoExtent ge) { extent = ge; } public BoundingCircle getBoundingCircle() { return getExtent().getBoundingCircle(); } public Object getID() { return id; } public void setID(Object id) { this.id = id; } public static class Pt extends OMGeo implements GeoPoint { protected int radius = OMPoint.DEFAULT_RADIUS; protected boolean isOval = true; public Pt(GeoPoint gp) { super(gp); } public Pt(Geo g) { super(new GeoPoint.Impl(g)); } public Pt(double lat, double lon, boolean isDegrees) { super(new GeoPoint.Impl(lat, lon, isDegrees)); } public Geo getGeo() { return ((GeoPoint) getExtent()).getPoint(); } public boolean generate(Projection proj) { setNeedToRegenerate(true); if (proj == null) { Debug.message("omgraphic", "GeoOMGraphic.Point: null projection in generate!"); return false; } Geo geo = getPoint(); double lat = geo.getLatitude(); double lon = geo.getLongitude(); if (!proj.isPlotable(lat, lon)) { setNeedToRegenerate(true);// HMMM not the best flag return false; } Point2D p1 = new Point2D.Double(); proj.forward(lat, lon, p1); double x1 = p1.getX() - radius; double y1 = p1.getY() - radius; double x2 = p1.getX() + radius; double y2 = p1.getY() + radius; if (isOval) { setShape(new GeneralPath(new Ellipse2D.Float((float) Math.min(x2, x1), (float) Math.min(y2, y1), (float) Math.abs(x2 - x1), (float) Math.abs(y2 - y1)))); } else { setShape(createBoxShape((int) Math.min(x2, x1), (int) Math.min(y2, y1), (int) Math.abs(x2 - x1), (int) Math.abs(y2 - y1))); } initLabelingDuringGenerate(); setLabelLocation(new Point((int) x2, (int) y1), proj); setNeedToRegenerate(false); return true; } public boolean isOval() { return isOval; } public void setOval(boolean isOval) { this.isOval = isOval; } public int getRadius() { return radius; } public void setRadius(int radius) { this.radius = radius; } public Geo getPoint() { return ((GeoPoint) getExtent()).getPoint(); } } public static class Line extends OMGeo implements GeoSegment { public Line(GeoSegment gs) { super(gs); } public Line(Geo[] gs) { super(new GeoSegment.Impl(gs)); } public Geo[] getGeoArray() { return ((GeoSegment) getExtent()).getSeg(); } public boolean generate(Projection proj) { setNeedToRegenerate(true); if (proj == null) { Debug.message("omgraphic", "GeoOMGraphic.Line: null projection in generate!"); return false; } // reset the internals initLabelingDuringGenerate(); double[] latlons = getSegArray(); ArrayList<float[]> lines = null; if (proj instanceof GeoProj) { lines = ((GeoProj) proj).forwardLine(new LatLonPoint.Double(latlons[0], latlons[1]), new LatLonPoint.Double(latlons[2], latlons[3]), lineType, -1); } else { lines = proj.forwardLine(new Point2D.Double(latlons[1], latlons[0]), new Point2D.Double(latlons[3], latlons[2])); } int size = lines.size(); float[][] xpoints = new float[(int) (size / 2)][0]; float[][] ypoints = new float[xpoints.length][0]; GeneralPath projectedShape = null; for (int i = 0, j = 0; i < size; i += 2, j++) { float[] xps = (float[]) lines.get(i); float[] yps = (float[]) lines.get(i + 1); xpoints[j] = xps; ypoints[j] = yps; GeneralPath gp = createShape(xps, yps, false); if (projectedShape == null) { projectedShape = gp; } else { projectedShape.append(gp, false); } } setShape(projectedShape); setLabelLocation(projectedShape, proj); setNeedToRegenerate(false); return true; } public Geo[] getSeg() { return ((GeoSegment) getExtent()).getSeg(); } public double[] getSegArray() { return ((GeoSegment) getExtent()).getSegArray(); } } public static class Polyline extends OMGeo implements GeoPath { public Polyline(GeoPath gp) { super(gp); } public Polyline(Geo[] gs) { super(new GeoPath.Impl(gs)); } public Polyline(GeoArray points) { super(new GeoPath.Impl(points)); } public GeoArray getPoints() { return ((GeoPath) getExtent()).getPoints(); } public boolean generate(Projection proj) { setNeedToRegenerate(true); boolean isPolygon = getExtent() instanceof GeoRegion; if (proj == null) { Debug.message("omgraphic", "GeoOMGraphic.Poly: null projection in generate!"); return false; } // answer the question now, saving calculation for future // calculations. The set method forces the calculation for // the query. // polygon/polyline project the polygon/polyline. // Vertices should already be in radians. // We might want to cache the latlon points retrieved from the // GeoArray at some point. ArrayList<float[]> vector; if (proj instanceof GeoProj) { vector = ((GeoProj) proj).forwardPoly(getPoints().toLLRadians(), lineType, -1, isPolygon); } else { vector = proj.forwardPoly(getPoints().toLLDegrees(), isPolygon); } int size = vector.size(); float[][] xpoints = new float[(int) (size / 2)][0]; float[][] ypoints = new float[xpoints.length][0]; for (int i = 0, j = 0; i < size; i += 2, j++) { xpoints[j] = (float[]) vector.get(i); ypoints[j] = (float[]) vector.get(i + 1); } initLabelingDuringGenerate(); size = xpoints.length; GeneralPath projectedShape = null; for (int i = 0; i < size; i++) { GeneralPath gp = createShape(xpoints[i], ypoints[i], isPolygon); projectedShape = appendShapeEdge(projectedShape, gp, false); } setShape(projectedShape); setLabelLocation(xpoints[0], ypoints[0], proj); setNeedToRegenerate(false); return true; } protected boolean isGeometryClosed(float[] rawllpts) { boolean geometryClosed = false; if (rawllpts != null) { int l = rawllpts.length; if (l > 4) { geometryClosed = (MoreMath.approximately_equal(rawllpts[0], rawllpts[l - 2]) && MoreMath.approximately_equal(rawllpts[1], rawllpts[l - 1])); } } return geometryClosed; } public boolean isSegmentNear(GeoSegment s, double epsilon) { return ((GeoPath) getExtent()).isSegmentNear(s, epsilon); } public int length() { return ((GeoPath) getExtent()).length(); } public PointIterator pointIterator() { return ((GeoPath) getExtent()).pointIterator(); } public SegmentIterator segmentIterator() { return ((GeoPath) getExtent()).segmentIterator(); } } public static class Polygon extends Polyline implements GeoRegion { public Polygon(GeoPath gp) { super(gp); } public Polygon(Geo[] gs) { super(new GeoRegion.Impl(gs)); } public Polygon(GeoArray points) { super(new GeoRegion.Impl(points)); } public boolean isPointInside(Geo point) { return ((GeoRegion) getExtent()).isPointInside(point); } } }