/*
* The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
* for visualizing and manipulating spatial features with geometry and attributes.
*
* Copyright (C) 2003 Vivid Solutions
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
package com.vividsolutions.jump.workbench.ui.plugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import com.vividsolutions.jts.algorithm.PointLocator;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.WKTWriter;
import com.vividsolutions.jump.I18N;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.io.FUTURE_JTS_WKTWriter;
import com.vividsolutions.jump.util.Fmt;
import com.vividsolutions.jump.workbench.model.FenceLayerFinder;
import com.vividsolutions.jump.workbench.model.Layer;
import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
import com.vividsolutions.jump.workbench.plugin.PlugInContext;
import com.vividsolutions.jump.workbench.ui.GUIUtil;
import com.vividsolutions.jump.workbench.ui.TextFrame;
public class VerticesInFencePlugIn extends AbstractPlugIn {
private FUTURE_JTS_WKTWriter wktWriter = new FUTURE_JTS_WKTWriter();
private GeometryFactory factory = new GeometryFactory();
public VerticesInFencePlugIn() {}
public boolean execute(PlugInContext context) throws Exception {
reportNothingToUndoYet(context);
TextFrame textFrame = new TextFrame(context.getWorkbenchFrame());
textFrame.setTitle(I18N.get("ui.plugin.VerticesInFencePlugIn.vertices-in-fence"));
textFrame.clear();
textFrame.setText(description(context));
textFrame.setSize(550, 300);
context.getWorkbenchFrame().addInternalFrame(textFrame);
return true;
}
private String description(PlugInContext context) {
FenceLayerFinder fenceLayerFinder = new FenceLayerFinder(context);
StringBuffer description = new StringBuffer();
description.append("<html><body>");
for (Iterator i = context.getLayerManager().iterator(); i.hasNext();) {
Layer layer = (Layer) i.next();
if (!layer.isVisible()) {
continue;
}
if (layer == fenceLayerFinder.getLayer()) {
continue;
}
description.append(description(layer, context));
}
description.append("</body></html>");
return description.toString();
}
public static Collection verticesInFence(
Collection geometries,
Geometry fence,
boolean skipClosingVertex) {
ArrayList verticesInFence = new ArrayList();
for (Iterator i = geometries.iterator(); i.hasNext();) {
Geometry geometry = (Geometry) i.next();
verticesInFence.addAll(
verticesInFence(geometry, fence, skipClosingVertex).getCoordinates());
}
return verticesInFence;
}
/**
* @param skipClosingVertex whether to ignore the duplicate point that closes off a
* LinearRing or Polygon
*/
public static VerticesInFence verticesInFence(
Geometry geometry,
final Geometry fence,
final boolean skipClosingVertex) {
final ArrayList coordinates = new ArrayList();
final ArrayList indices = new ArrayList();
//PointLocator is non-re-entrant. Therefore, create a new instance for each fence.
//[Jon Aquino]
final PointLocator pointLocator = new PointLocator();
final IntWrapper index = new IntWrapper(-1);
geometry.apply(new GeometryComponentFilter() {
public void filter(Geometry geometry) {
if (geometry instanceof GeometryCollection
|| geometry instanceof Polygon) {
//Wait for the elements to be passed into the filter [Jon Aquino]
return;
}
Coordinate[] component = geometry.getCoordinates();
for (int j = 0; j < component.length; j++) {
index.value++;
if (skipClosingVertex
&& (component.length > 1)
&& (j == (component.length - 1))
&& component[j].equals(component[0])) {
continue;
}
if (pointLocator.locate(component[j], fence) == Location.EXTERIOR) {
continue;
}
coordinates.add(component[j]);
indices.add(new Integer(index.value));
}
}
});
return new VerticesInFence() {
public List getCoordinates() {
return coordinates;
}
public int getIndex(int i) {
return ((Integer) indices.get(i)).intValue();
}
};
}
/**
*@return an empty String if the layer has no coordinates in the fence
*/
private String description(Layer layer, PlugInContext context) {
boolean foundVertices = false;
String description =
"<Table width=100%><tr><td colspan=2 valign=top><i>"+I18N.get("ui.plugin.VerticesInFencePlugIn.layer")+" </i><font color='#3300cc'><b>"
+ layer.getName()
+ "</b></font></td></tr>";
String bgcolor = "darkgrey";
for (Iterator i =
layer
.getFeatureCollectionWrapper()
.query(context.getLayerViewPanel().getFence().getEnvelopeInternal())
.iterator();
i.hasNext();
) {
Feature feature = (Feature) i.next();
VerticesInFence verticesInFence =
verticesInFence(
feature.getGeometry(),
context.getLayerViewPanel().getFence(),
true);
if (verticesInFence.getCoordinates().isEmpty()) {
continue;
}
if (bgcolor.equals("#faebd7")) {
bgcolor = "darkgrey";
} else {
bgcolor = "#faebd7";
}
foundVertices = true;
//<<TODO:DEFECT>> Get platform-specific newline rather than "\n" [Jon Aquino]
description
+= ("<tr bgcolor="
+ bgcolor
+ "><td width=10% valign=top><font size='-1'><i>"+I18N.get("ui.plugin.VerticesInFencePlugIn.feature-id")+" </i></font><font size='-1' color='#3300cc'><b>"
+ feature.getID()
+ "</b></font><td>");
description += description(verticesInFence, feature.getGeometry());
description += "</td></tr>";
}
description += "</table>";
return foundVertices ? description : "";
}
private WKTDisplayHelper helper = new WKTDisplayHelper();
private String description(VerticesInFence verticesInFence, Geometry geometry) {
StringBuffer description = new StringBuffer();
//<<TODO:FEATURE>> Perhaps we should change these \n's to the line separators
//specific to the current platform. Then the user could copy the text and
//paste it to any editor without any funny symbols potentially appearing. [Jon Aquino]
description.append("<pre>");
for (int i = 0; i < verticesInFence.getCoordinates().size(); i++) {
description.append(
GUIUtil.escapeHTML(
"["
+ Fmt.fmt(
helper.annotation(
geometry,
(Coordinate) verticesInFence.getCoordinates().get(i)),
10)
+ "] "
+ wktWriter.write(
factory.createPoint(
(Coordinate) verticesInFence.getCoordinates().get(i)))
+ "\n",
false,
false));
}
description.append("</pre>");
return description.toString();
}
public static interface VerticesInFence {
public List getCoordinates();
public int getIndex(int i);
}
private static class IntWrapper {
public int value;
public IntWrapper(int value) {
this.value = value;
}
}
public static void main(String[] args) {
new WKTWriter();
((Geometry)(new Object())).toString();
}
}