// **********************************************************************
//
//<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: GeoIntersectionLayer.java,v $
//$Revision: 1.1.2.4 $
//$Date: 2007/02/13 20:00:55 $
//$Author: dietrick $
//
//**********************************************************************
package com.bbn.openmap.layer.test;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;
import com.bbn.openmap.LatLonPoint;
import com.bbn.openmap.dataAccess.shape.DbfTableModel;
import com.bbn.openmap.dataAccess.shape.EsriGraphicList;
import com.bbn.openmap.event.MapMouseEvent;
import com.bbn.openmap.geo.BoundaryCrossing;
import com.bbn.openmap.geo.BoundingCircle;
import com.bbn.openmap.geo.ExtentIndex;
import com.bbn.openmap.geo.ExtentIndexImpl;
import com.bbn.openmap.geo.Geo;
import com.bbn.openmap.geo.GeoPath;
import com.bbn.openmap.geo.GeoPoint;
import com.bbn.openmap.geo.GeoRegion;
import com.bbn.openmap.geo.GeoSegment;
import com.bbn.openmap.geo.Intersection;
import com.bbn.openmap.layer.editor.EditorLayer;
import com.bbn.openmap.omGraphics.DrawingAttributes;
import com.bbn.openmap.omGraphics.OMAction;
import com.bbn.openmap.omGraphics.OMColor;
import com.bbn.openmap.omGraphics.OMGraphic;
import com.bbn.openmap.omGraphics.OMGraphicList;
import com.bbn.openmap.omGraphics.OMLine;
import com.bbn.openmap.omGraphics.OMPoint;
import com.bbn.openmap.omGraphics.OMPoly;
import com.bbn.openmap.omGraphics.OMRaster;
import com.bbn.openmap.omGraphics.OMTextLabeler;
import com.bbn.openmap.omGraphics.SinkGraphic;
import com.bbn.openmap.proj.Mercator;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.util.ArgParser;
import com.bbn.openmap.util.Debug;
import com.bbn.openmap.util.FileUtils;
import com.bbn.openmap.util.PaletteHelper;
import com.bbn.openmap.util.PropUtils;
/**
* This layer demonstrates the use of the com.bbn.openmap.geo package to do
* intersection calculations in lat/lon space. It allows you to load shape files
* for sample data sets, and then draw lines, polygons and points on the map to
* as test cases for intersections on the sample data sets. The ToolPanel will
* hold controls for choosing what kind of things to draw, and how they should
* be rendered. The palette for this layer controls the sample data sets,
* letting you add and remove data files and change their colors.
* <P>
*
* If you draw a line, polyline or point, the shapes in the data sets that
* intersect with them will be rendered in the 'select' colors. If you draw a
* closed polygon with a fill color, the data set shapes inside the polygon will
* also be selected. The palette has controls for showing the actual points of
* intersection for paths and their sample data regions. There is also an option
* to allow mouse clicks on a data set region to create an image over the
* bounding rectangle for that region, checking the Geo point intersection
* algorithm against the Java 2D algorithm for the shape in projected pixel
* space. An all-green image is good, pixels where the algorithms differ will be
* red.
* <P>
*
* The properties for this layer are:
*
* <pre>
* geo.class=com.bbn.openmap.layer.test.GeoIntersectionLayer
* geo.prettyName=GEO Intersections
* geo.editor=com.bbn.openmap.layer.editor.DrawingEditorTool
* geo.showAttributes=true
* geo.loaders=lines polys points
* geo.mouseModes=Gestures
* geo.lines.class=com.bbn.openmap.tools.drawing.OMLineLoader
* geo.polys.class=com.bbn.openmap.tools.drawing.OMPolyLoader
* geo.points.class=com.bbn.openmap.tools.drawing.OMPointLoader
* geo.shapeFileList=geocounties geolakes geocountries
* geo.geocounties=/data/shape/usa/counties.shp
* geo.geolakes=/data/shape/world/lakes.shp
* geo.geocountries=/data/shape/world/cntry02/cntry02.shp
* # Colors for regular, unselected data shapes
* geo.fillColor=FF333399
* geo.selectColor=ffff9900
* geo.mattingColor=ffff9900
* # Colors for data shapes intersected by drawn shapes
* geo.selected.fillColor=FFFFFF00
* geo.selected.selectColor=ffff9900
* geo.selected.mattingColor=ffff9900
* </pre>
*
* @author dietrick
*/
public class GeoIntersectionLayer extends EditorLayer implements
PropertyChangeListener {
/** This list holds the OMGraphics that have been drawn. */
protected OMGraphicList drawnList = new OMGraphicList();
/** This list holds the EsriGraphicLists from the Shape files. */
protected OMGraphicList fileDataList = new OMGraphicList();
/**
* This list holds the BoundaryCrossings and the image masks created from
* Intersection queries.
*/
protected OMGraphicList intersectionResultList = new OMGraphicList();
/** The RegionIndex organizing the Shape OMGraphics for searching. */
protected ExtentIndexImpl regionIndex = null;
protected DrawingAttributes shapeDA = new DrawingAttributes();
protected DrawingAttributes shapeDASelected = new DrawingAttributes();
public final static String ShapeFileListProperty = "shapeFileList";
public final static String ShapeFileProperty = "shapeFile";
public final static String ShowCrossingPointsProperty = "showCrossingPoints";
public final static String PointCheckProperty = "pointCheck";
public final static String SHAPE_FILE_NAME_ATTRIBUTE = "SHAPE_FILE_NAME";
public final static String SHAPE_VISIBILITY_CONTROL_ATTRIBUTE = "SHAPE_VISIBILITY_CONTROL";
public final static String SHAPE_CONTROL_ATTRIBUTE = "SHAPE_CONTROL";
protected boolean showCrossingPoints = false;
protected boolean createPointCheck = false;
public static boolean DEBUG = false;
/**
*
*/
public GeoIntersectionLayer() {
super();
DEBUG = Debug.debugging("geo");
shapeDA.getPropertyChangeSupport().addPropertyChangeListener(this);
}
public void setProperties(String prefix, Properties props) {
super.setProperties(prefix, props);
shapeDA.setProperties(prefix, props);
prefix = PropUtils.getScopedPropertyPrefix(prefix);
shapeDASelected.setProperties(prefix + "selected", props);
Vector v = PropUtils.parseSpacedMarkers(props.getProperty(prefix
+ ShapeFileListProperty));
for (Iterator it = v.iterator(); it.hasNext();) {
String markerName = (String) it.next();
String shapeFileName = props.getProperty(prefix + markerName);
if (shapeFileName != null) {
File sf = new File(shapeFileName);
if (sf.exists()) {
addShapeFile(sf);
}
}
}
}
public OMGraphicList prepare() {
OMGraphicList list = getList();
if (list == null) {
list = new OMGraphicList();
// If there isn't any data loaded, ask the user for a
// file.
if (fileDataList.size() == 0) {
addShapeFileFromUser();
}
} else {
list.clear();
}
// If we created any pixel intersection images before, time to
// get rid of them.
calculateIntersectionsWithDrawnList();
list.add(intersectionResultList);
list.add(drawnList);
if (DEBUG)
Debug.output("GeoIntersectLayer(" + getName()
+ "): Adding lines to main list");
list.add(fileDataList);
if (DEBUG)
Debug.output("GeoIntersectLayer(" + getName()
+ "): Adding shapes to main list");
list.generate(getProjection());
if (DEBUG)
Debug.output("GeoIntersectLayer(" + getName()
+ "): Projected main list, returning");
return list;
}
public void calculateIntersectionsWithDrawnList() {
intersectionResultList.clear();
ExtentIndex rIndex = getRegionIndex(true);
for (Iterator it = drawnList.iterator(); it.hasNext();) {
OMGraphic omg = (OMGraphic) it.next();
if (omg instanceof OMLine
|| (omg instanceof OMPoly && !((OMPoly) omg).isPolygon())) {
if (DEBUG) {
Debug.output("GeoIntersectLayer(" + getName()
+ "): Checking line against RegionIndex");
}
GeoPath path = getPathFromOMGraphic(omg);
Iterator intrsctns = null;
Iterator crssngs = null;
if (showCrossingPoints) {
BoundaryCrossing.Collector results = BoundaryCrossing.getCrossings(path,
rIndex);
intrsctns = results.iterator();
crssngs = results.getCrossings();
} else {
intrsctns = Intersection.intersect(path, rIndex);
}
while (intrsctns.hasNext()) {
OMPolyRegion ompr = (OMPolyRegion) intrsctns.next();
setRegionAsSelected(ompr);
if (DEBUG) {
Debug.output("GeoIntersectLayer(" + getName()
+ "): Set Poly for hit");
}
}
int num = 0;
while (crssngs != null && crssngs.hasNext()) {
BoundaryCrossing bc = (BoundaryCrossing) crssngs.next();
Geo geo = bc.getGeo();
OMPoint pgeo = new OMPoint((float) geo.getLatitude(), (float) geo.getLongitude());
pgeo.setFillPaint(Color.WHITE);
pgeo.putAttribute(OMGraphic.LABEL,
new OMTextLabeler(Integer.toString(num++)));
intersectionResultList.add(pgeo);
}
} else if (omg instanceof OMPoly) {
for (Iterator hits = Intersection.intersect(new OMPolyRegion((OMPoly) omg),
rIndex); hits.hasNext();) {
setRegionAsSelected((OMPolyRegion) hits.next());
if (DEBUG) {
Debug.output("GeoIntersectLayer(" + getName()
+ "): Set Poly for hit");
}
}
} else if (omg instanceof OMPoint) {
OMPoint omp = (OMPoint) omg;
for (Iterator hits = Intersection.intersect(new GeoPoint.Impl(omp.getLat(), omp.getLon()),
rIndex); hits.hasNext();) {
setRegionAsSelected((OMPolyRegion) hits.next());
if (DEBUG) {
Debug.output("GeoIntersectLayer(" + getName()
+ "): Set Poly for hit");
}
}
}
}
}
protected void setRegionAsSelected(OMPolyRegion ompr) {
shapeDASelected.setTo(ompr.poly);
}
protected GeoPath getPathFromOMGraphic(OMGraphic omg) {
GeoPath path = null;
if (omg instanceof OMLine) {
path = getPath((OMLine) omg);
} else if (omg instanceof OMPoly) {
path = getPath((OMPoly) omg);
}
return path;
}
protected GeoPath getPath(OMLine oml) {
return new GeoPath.Impl(oml.getLL());
}
protected GeoPath getPath(OMPoly omp) {
return new GeoPath.Impl(omp.getLatLonArray(), false);
}
/**
* Query the user for a shape file, and add the contents to the region list
* or line list if a valid file is selected.
*/
public void addShapeFileFromUser() {
String shpFileName = FileUtils.getFilePathToOpenFromUser("Pick Shape File",
new FileFilter() {
public boolean accept(File f) {
return f.isDirectory() || f.getName().endsWith("shp");
}
public String getDescription() {
return "ESRI Shape (.shp) file";
}
});
if (shpFileName != null) {
addShapeFile(new File(shpFileName));
}
}
/**
* Add the data from a shape file to the region list or edge list, depending
* on the content type.
*
* @param shpFile
*/
public void addShapeFile(File shpFile) {
if (shpFile != null) {
try {
String shpFilePath = shpFile.getAbsolutePath();
String shpFileName = shpFile.getName();
DrawingAttributes da = new DrawingAttributes();
da.setSelectPaint(new Color(200, 100, 100, 200));
EsriGraphicList shapeList = EsriGraphicList.getEsriGraphicList(shpFile.toURL(),
da,
DbfTableModel.getDbfTableModel(new File(shpFilePath.replaceAll(".shp",
".dbf")).toURL()));
if (DEBUG)
Debug.output("GeoIntersectLayer(" + getName()
+ "): Adding shapes from " + shpFileName);
JCheckBox visibilityControl = new JCheckBox("Show", true);
visibilityControl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
setShapeListVisibilityForCheckbox();
repaint();
}
});
JButton removeButton = new JButton("Remove");
removeButton.addActionListener(new RemoveShapesActionListener(fileDataList, shapeList));
JLabel label = new JLabel(shpFileName, JLabel.LEFT);
JPanel panel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
panel.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
c.weightx = 1.0;
c.insets = new Insets(2, 2, 2, 2);
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
gridbag.setConstraints(label, c);
panel.add(label);
c.weightx = 0;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
gridbag.setConstraints(visibilityControl, c);
panel.add(visibilityControl);
gridbag.setConstraints(removeButton, c);
panel.add(removeButton);
shapeList.putAttribute(SHAPE_FILE_NAME_ATTRIBUTE, shpFileName);
shapeList.putAttribute(SHAPE_VISIBILITY_CONTROL_ATTRIBUTE,
visibilityControl);
shapeList.putAttribute(SHAPE_CONTROL_ATTRIBUTE, panel);
int type = shapeList.getType();
if (type != EsriGraphicList.SHAPE_TYPE_POLYGON
&& type != EsriGraphicList.SHAPE_TYPE_POLYLINE) {
fireRequestMessage("The type of shapes contained in the file\n"
+ shpFileName
+ "\nisn't handled by this layer. Choose a file that\ncontains lines or polygons.");
return;
}
fileDataList.add(shapeList);
rebuildFileListControl();
if (getProjection() != null) {
doPrepare();
}
} catch (MalformedURLException murle) {
}
}
}
protected void setShapeListVisibilityForCheckbox() {
for (Iterator it = fileDataList.iterator(); it.hasNext();) {
Object obj = it.next();
if (obj instanceof OMGraphicList) {
OMGraphicList omgl = (OMGraphicList) obj;
obj = omgl.getAttribute(SHAPE_VISIBILITY_CONTROL_ATTRIBUTE);
if (obj != null) {
omgl.setVisible(((JCheckBox) obj).isSelected());
}
}
}
}
public ExtentIndex getRegionIndex(boolean resetRegionSelection) {
if (regionIndex == null) {
regionIndex = new ExtentIndexImpl();
}
if (resetRegionSelection) {
for (Iterator reset = regionIndex.iterator(); reset.hasNext();) {
shapeDA.setTo(((OMPolyRegion) reset.next()).poly);
}
if (DEBUG)
Debug.output("GeoIntersectLayer(" + getName()
+ "): Reset region fills");
}
return regionIndex;
}
protected void addToRegionIndex(OMPoly p, ExtentIndex regionIndex) {
if (regionIndex.addExtent(new OMPolyRegion(p)) && DEBUG) {
Debug.output("GeoIntersectLayer(" + getName()
+ "): Added poly region to RegionIndex");
}
}
protected void addToRegionIndex(OMGraphicList omgl, ExtentIndex regionIndex) {
for (Iterator it = omgl.iterator(); it.hasNext();) {
Object someObj = it.next();
if (someObj instanceof OMPoly) {
addToRegionIndex((OMPoly) someObj, regionIndex);
} else {
addToRegionIndex((OMGraphicList) someObj, regionIndex);
}
}
}
public void drawingComplete(OMGraphic omg, OMAction action) {
releaseProxyMouseMode();
if ((omg instanceof OMLine || omg instanceof OMPoly || omg instanceof OMPoint)
&& drawnList != null) {
drawnList.doAction(omg, action);
deselect(drawnList);
doPrepare();
} else {
Debug.error("GeoIntersectLayer(" + getName() + "): received "
+ omg + " and " + action + " with no list ready");
}
// This is important!!
if (editorTool != null) {
editorTool.drawingComplete(omg, action);
}
}
public OMGraphicList getDrawnIntersectorList() {
return drawnList;
}
public boolean receivesMapEvents() {
return false;
}
public boolean mouseOver(MapMouseEvent mme) {
if (regionIndex != null) {
LatLonPoint llp = mme.getLatLon();
GeoPoint geop = new GeoPoint.Impl(llp.getLatitude(), llp.getLongitude());
for (Iterator hits = Intersection.intersect(geop, regionIndex); hits.hasNext();) {
OMPolyRegion ompr = (OMPolyRegion) hits.next();
ompr.poly.select();
ompr.poly.generate(getProjection());
}
repaint();
}
return true;
}
public boolean isHighlightable(OMGraphic omg) {
return createPointCheck
|| (drawnList != null && drawnList.contains(omg));
}
public String getToolTipTextFor(OMGraphic omg) {
if (drawnList != null && drawnList.contains(omg)) {
return super.getToolTipTextFor(omg);
} else if (createPointCheck) {
return "Click to create point test image mask";
}
return null;
}
public void highlight(OMGraphic omg) {
omg.setMatted(true);
super.highlight(omg);
}
public void unhighlight(OMGraphic omg) {
omg.setMatted(false);
super.unhighlight(omg);
}
public boolean isSelectable(OMGraphic omg) {
return createPointCheck
|| (drawnList != null && drawnList.contains(omg));
}
public void select(OMGraphicList omgl) {
for (Iterator it = omgl.iterator(); it.hasNext();) {
OMGraphic omg = (OMGraphic) it.next();
if (drawnList != null && drawnList.contains(omg)) {
super.select(omgl);
} else if (createPointCheck) {
intersectionResultList.add(getPointIntersectionImage(omg));
}
}
repaint();
}
public void deselect(OMGraphicList omgl) {
intersectionResultList.clear();
repaint();
}
public OMGraphic getPointIntersectionImage(OMGraphic omg) {
Shape s = omg.getShape();
Projection p = getProjection();
if (s != null && p != null && omg instanceof OMPoly) {
Rectangle r = s.getBounds();
double x = r.getX();
double y = r.getY();
double h = r.getHeight();
double w = r.getWidth();
float[] rawll = ((OMPoly) omg).getLatLonArray();
LatLonPoint llHolder = new LatLonPoint();
Geo g = new Geo(0, 0);
int[] pix = new int[(int) (h * w)];
for (double j = 0; j < h; j++) {
for (double i = 0; i < w; i++) {
boolean inShape = s.contains(i + x, j + y);
p.inverse((int) (i + x), (int) (j + y), llHolder);
g.initialize(llHolder.getLatitude(), llHolder.getLongitude());
boolean inGeo = Intersection.isPointInPolygon(g,
rawll,
false);
int val = 0;
if (inShape == inGeo) {
val = 0x6200FF00;
} else {
val = 0x62ff0000;
}
pix[(int) (w * j + i)] = val;
}
}
OMRaster omr = new OMRaster((int) x, (int) y, (int) w, (int) h, pix);
omr.setSelectPaint(OMColor.clear);
// omr.setSelected(true);
omr.generate(p);
return omr;
}
return SinkGraphic.getSharedInstance();
}
protected JPanel getFileListControl() {
if (fileListControl == null) {
fileListControl = PaletteHelper.createHorizontalPanel("Shape Files Being Used for Intersections");
}
return fileListControl;
}
public void rebuildFileListControl() {
JPanel p = getFileListControl();
p.setBackground(Color.white);
Color light = Color.white;
Color dark = Color.LIGHT_GRAY;
Color current = dark;
p.removeAll();
GridBagLayout gridbag = new GridBagLayout();
p.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.gridx = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
getRegionIndex(false).clear();
for (Iterator it = fileDataList.iterator(); it.hasNext();) {
Object obj = it.next();
if (obj instanceof EsriGraphicList) {
EsriGraphicList shapeList = (EsriGraphicList) obj;
JPanel control = (JPanel) shapeList.getAttribute(SHAPE_CONTROL_ATTRIBUTE);
if (control != null) {
control.setBackground(current);
Component[] comps = control.getComponents();
for (int i = 0; i < comps.length; i++) {
comps[i].setBackground(current);
}
if (current == dark)
current = light;
else
current = dark;
gridbag.setConstraints(control, c);
p.add(control);
}
addToRegionIndex(shapeList, getRegionIndex(false));
}
}
if (fileDataList.size() == 0) {
JLabel label = new JLabel("No Shape Files Loaded", JButton.CENTER);
c.anchor = GridBagConstraints.CENTER;
gridbag.setConstraints(label, c);
p.add(label);
}
c.fill = GridBagConstraints.BOTH;
c.weighty = 1;
JLabel filler = new JLabel("");
gridbag.setConstraints(filler, c);
p.add(filler);
p.revalidate();
}
JPanel fileListControl;
JPanel panel = null;
JCheckBox showCrossingsButton;
JCheckBox pointCheckButton;
public Component getGUI() {
if (panel == null) {
panel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
panel.setLayout(gridbag);
c.gridx = GridBagConstraints.REMAINDER;
c.weightx = 1.0;
c.insets = new Insets(1, 5, 1, 5);
c.fill = GridBagConstraints.HORIZONTAL;
JPanel daPanel1 = PaletteHelper.createHorizontalPanel("Paint Settings for Shapes");
daPanel1.add(shapeDA.getGUI());
JPanel daPanel2 = PaletteHelper.createHorizontalPanel("Paint Settings for Intersected Shapes");
daPanel2.add(shapeDASelected.getGUI());
gridbag.setConstraints(daPanel1, c);
gridbag.setConstraints(daPanel2, c);
panel.add(daPanel1);
panel.add(daPanel2);
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
JPanel tablePanel = getFileListControl();
gridbag.setConstraints(tablePanel, c);
panel.add(tablePanel);
JPanel checkPanel = new JPanel();
GridBagLayout gb = new GridBagLayout();
checkPanel.setLayout(gb);
GridBagConstraints c2 = new GridBagConstraints();
c2.anchor = GridBagConstraints.WEST;
c2.gridx = GridBagConstraints.REMAINDER;
showCrossingsButton = new JCheckBox("Show Crossing Points", showCrossingPoints);
showCrossingsButton.setToolTipText("<html>Show ordered points where drawn lines cross Shapes.");
showCrossingsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
setShowCrossingPoints(((JCheckBox) ae.getSource()).isSelected());
doPrepare();
}
});
gb.setConstraints(showCrossingsButton, c2);
checkPanel.add(showCrossingsButton);
pointCheckButton = new JCheckBox("Click Creates Image Mask", showCrossingPoints);
pointCheckButton.setToolTipText("<html>When clicking on Shape, create image mask that shows Geo point<br>intersection vs. Java 2D. Green is good.");
pointCheckButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
setCreatePointCheck(((JCheckBox) ae.getSource()).isSelected());
doPrepare();
}
});
gb.setConstraints(pointCheckButton, c2);
checkPanel.add(pointCheckButton);
c.weightx = 0;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
gridbag.setConstraints(checkPanel, c);
panel.add(checkPanel);
JButton addButton = new JButton("Add Shape File...");
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
addShapeFileFromUser();
}
});
c.insets = new Insets(5, 5, 5, 5);
gridbag.setConstraints(addButton, c);
panel.add(addButton);
}
return panel;
}
public static class OMPolyRegion extends GeoRegion.Impl {
public OMPoly poly;
public OMPolyRegion(OMPoly omp) {
super(omp.getLatLonArray(), false);
poly = omp;
}
public Object getID() {
return GeoIntersectionLayer.OMPolyRegion.this;
}
}
public static class OMLineSegment implements GeoSegment {
Geo[] geos;
float[] segArray;
public OMLineSegment(OMLine oml) {
segArray = oml.getLL();
geos = new Geo[2];
geos[0] = new Geo(segArray[0], segArray[1]);
geos[1] = new Geo(segArray[2], segArray[3]);
}
/*
* (non-Javadoc)
*
* @see com.bbn.openmap.geo.GeoSegment#getSeg()
*/
public Geo[] getSeg() {
return geos;
}
/*
* (non-Javadoc)
*
* @see com.bbn.openmap.geo.GeoSegment#getSegArray()
*/
public float[] getSegArray() {
return segArray;
}
/*
* (non-Javadoc)
*
* @see com.bbn.openmap.geo.GeoExtent#getID()
*/
public Object getID() {
return this;
}
public BoundingCircle getBoundingCircle() {
return new BoundingCircle.Impl(getSeg());
}
}
protected class RemoveShapesActionListener implements ActionListener {
protected OMGraphicList mainDataList;
protected OMGraphicList toBeRemoved;
public RemoveShapesActionListener(OMGraphicList mdl, OMGraphicList tbr) {
mainDataList = mdl;
toBeRemoved = tbr;
}
public void actionPerformed(ActionEvent ae) {
mainDataList.remove(toBeRemoved);
rebuildFileListControl();
GeoIntersectionLayer.this.doPrepare();
}
}
public boolean isShowCrossingPoints() {
return showCrossingPoints;
}
public void setShowCrossingPoints(boolean showCrossingPoints) {
this.showCrossingPoints = showCrossingPoints;
}
public void propertyChange(PropertyChangeEvent evt) {
shapeDA.setTo(fileDataList);
repaint();
}
public DrawingAttributes getShapeDA() {
return shapeDA;
}
public void setShapeDA(DrawingAttributes shapeDA) {
this.shapeDA = shapeDA;
}
public DrawingAttributes getShapeDASelected() {
return shapeDASelected;
}
public void setShapeDASelected(DrawingAttributes shapeDASelected) {
this.shapeDASelected = shapeDASelected;
}
public boolean isCreatePointCheck() {
return createPointCheck;
}
public void setCreatePointCheck(boolean createPointCheck) {
this.createPointCheck = createPointCheck;
}
public void runGeoTests(int numIterations, int numToSkipAtStart) {
Projection proj = new Mercator(new LatLonPoint(35f, -90f), 100000000, 800, 800);
double[] results = new double[7];
for (int i = 0; i < numIterations; i++) {
boolean countThisIteration = (i >= numToSkipAtStart);
long startTime = System.currentTimeMillis();
setProjection(proj.makeClone());
calculateIntersectionsWithDrawnList();
long endTime = System.currentTimeMillis();
if (countThisIteration) {
results[0] += endTime - startTime;
}
OMGraphic omg = new OMLine(20f, -125f, 30f, -70f, OMGraphic.LINETYPE_GREATCIRCLE);
getDrawnIntersectorList().add(omg);
startTime = System.currentTimeMillis();
calculateIntersectionsWithDrawnList();
endTime = System.currentTimeMillis();
if (countThisIteration) {
results[1] += endTime - startTime;
}
setShowCrossingPoints(true);
startTime = System.currentTimeMillis();
calculateIntersectionsWithDrawnList();
endTime = System.currentTimeMillis();
if (countThisIteration) {
results[2] += endTime - startTime;
}
getDrawnIntersectorList().clear();
setShowCrossingPoints(false);
float[] coords = new float[] { 33.4f, -77.2f, 34f, -79.5f, 35f,
-90f, 40f, -100f, 45f, -101f, 50f, -83.2f, 35f, -65.7f,
-34f, -70.5f, 33.4f, -77.2f };
omg = new OMPoly(coords, OMPoly.DECIMAL_DEGREES, OMGraphic.LINETYPE_GREATCIRCLE);
getDrawnIntersectorList().add(omg);
startTime = System.currentTimeMillis();
calculateIntersectionsWithDrawnList();
endTime = System.currentTimeMillis();
if (countThisIteration) {
results[3] += endTime - startTime;
}
setShowCrossingPoints(true);
startTime = System.currentTimeMillis();
calculateIntersectionsWithDrawnList();
endTime = System.currentTimeMillis();
if (countThisIteration) {
results[4] += endTime - startTime;
}
omg.setFillPaint(Color.red);
setShowCrossingPoints(false);
startTime = System.currentTimeMillis();
calculateIntersectionsWithDrawnList();
endTime = System.currentTimeMillis();
if (countThisIteration) {
results[5] += endTime - startTime;
}
setShowCrossingPoints(true);
startTime = System.currentTimeMillis();
calculateIntersectionsWithDrawnList();
endTime = System.currentTimeMillis();
if (countThisIteration) {
results[6] += endTime - startTime;
}
System.out.print(".");
System.out.flush();
}
double numIterationsCounted = numIterations - numToSkipAtStart;
Debug.output("For " + numIterationsCounted + " iterations");
Debug.output(" avg time to calculate without Intersection: "
+ (results[0] / numIterationsCounted) + " ms");
Debug.output(" avg time to calculate with Intersection line: "
+ (results[1] / numIterationsCounted) + " ms");
Debug.output(" avg time to calculate with Intersection line with crossing points: "
+ (results[2] / numIterationsCounted) + " ms");
Debug.output(" avg time to calculate with Intersection poly: "
+ (results[3] / numIterationsCounted) + " ms");
Debug.output(" avg time to calculate with Intersection poly with crossing points: "
+ (results[4] / numIterationsCounted) + " ms");
Debug.output(" avg time to calculate with Intersection Containment poly: "
+ (results[5] / numIterationsCounted) + " ms");
Debug.output(" avg time to calculate with Intersection Containment poly and crossing points: "
+ (results[6] / numIterationsCounted) + " ms");
}
public static void main(String[] argv) {
Debug.init();
ArgParser argp = new ArgParser("GeoIntersectionLayer");
argp.add("shape", "Shape file to use for GeoRegions in index.", 1);
argp.parse(argv);
String[] files = argp.getArgValues("shape");
if (files != null && files.length > 0 && files[0].endsWith(".shp")) {
File file = new File(files[0]);
GeoIntersectionLayer gil = new GeoIntersectionLayer();
Debug.output("Loading shape file: " + file.getName());
long startTime = System.currentTimeMillis();
gil.addShapeFile(file);
long endTime = System.currentTimeMillis();
Debug.output(" time to load file: " + (endTime - startTime) + " ms");
gil.runGeoTests(25, 3);
} else {
argp.printUsage();
System.exit(0);
}
}
}