001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.workbench.ui.plugin.analysis;
034:
035: import java.util.*;
036: import com.vividsolutions.jts.algorithm.*;
037: import com.vividsolutions.jts.geom.*;
038: import com.vividsolutions.jts.simplify.*;
039: import com.vividsolutions.jts.operation.linemerge.*;
040: import com.vividsolutions.jts.operation.polygonize.*;
041: import com.vividsolutions.jump.I18N;
042:
043: /**
044: * A function object for {@link Geometry} functions (which return a Geometry).
045: * Provides metadata about the function.
046: *
047: * @author Martin Davis
048: * @version 1.0
049: */
050: public abstract class GeometryFunction {
051: // [sstein, 16.07.2006] due to language setting problems loaded in corresponding class
052: /*
053: private static final String METHOD_INTERSECTION = I18N.get("ui.plugin.analysis.GeometryFunction.intersection");
054: private static final String METHOD_UNION = I18N.get("ui.plugin.analysis.GeometryFunction.union");
055: private static final String METHOD_DIFFERENCE_AB = I18N.get("ui.plugin.analysis.GeometryFunction.difference-a-b");
056: private static final String METHOD_DIFFERENCE_BA = I18N.get("ui.plugin.analysis.GeometryFunction.difference-b-a");
057: private static final String METHOD_SYMDIFF = I18N.get("ui.plugin.analysis.GeometryFunction.symetric-difference");
058: private static final String METHOD_CENTROID_A = I18N.get("ui.plugin.analysis.GeometryFunction.centroid-of-a");
059: static final String METHOD_BUFFER = I18N.get("ui.plugin.analysis.GeometryFunction.buffer");
060:
061: private static final String sFunction = I18N.get("ui.plugin.analysis.GeometryFunctionPlugIn.function");
062: */
063: private static GeometryFunction[] method = {
064: new IntersectionFunction(), new UnionFunction(),
065: new DifferenceABFunction(), new DifferenceBAFunction(),
066: new SymDifferenceFunction(), new CentroidFunction(),
067: new InteriorPointFunction(), new BufferFunction(),
068: new SimplifyFunction(), new SimplifyTopologyFunction(),
069: new ConvexHullFunction(), new BoundaryFunction(),
070: new EnvelopeFunction(), new LineMergeFunction(),
071: new LineSequenceFunction(), new PolygonizeFunction(),
072: new ReverseLinestringFunction() };
073:
074: public static List getNames() {
075: List methodNames = new ArrayList();
076: for (int i = 0; i < method.length; i++) {
077: methodNames.add(method[i].name);
078: }
079: return methodNames;
080: }
081:
082: public static List getNames(Collection functions) {
083: List names = new ArrayList();
084: for (Iterator i = functions.iterator(); i.hasNext();) {
085: GeometryFunction func = (GeometryFunction) i.next();
086: names.add(func.name);
087: }
088: return names;
089: }
090:
091: public static GeometryFunction getFunction(String name) {
092: for (int i = 0; i < method.length; i++) {
093: if (method[i].name.equals(name))
094: return method[i];
095: }
096: return null;
097: }
098:
099: public static GeometryFunction getFunction(Collection functions,
100: String name) {
101: for (Iterator i = functions.iterator(); i.hasNext();) {
102: GeometryFunction func = (GeometryFunction) i.next();
103: if (func.name.equals(name))
104: return func;
105: }
106: return null;
107: }
108:
109: public static GeometryFunction[] getFunctions() {
110: return method;
111: }
112:
113: private String name;
114: private int nArguments;
115: private int nParams;
116: private boolean isAggregate = false; // not yet used
117: private String description;
118:
119: public String getName() {
120: return name;
121: }
122:
123: public int getGeometryArgumentCount() {
124: return nArguments;
125: }
126:
127: public int getParameterCount() {
128: return nParams;
129: }
130:
131: public GeometryFunction(String name, int nArgs, int nParams) {
132: this (
133: name,
134: nArgs,
135: nParams,
136: name
137: + " "
138: + I18N
139: .get("ui.plugin.analysis.GeometryFunctionPlugIn.function"));
140: }
141:
142: public GeometryFunction(String name, int nArgs, int nParams,
143: String description) {
144: this .name = name;
145: this .nArguments = nArgs;
146: this .nParams = nParams;
147: this .description = description;
148: }
149:
150: public String getDescription() {
151: return description;
152: }
153:
154: /**
155: * Exectute the function on the geometry(s) in the geom array.
156: * The function can expect that the correct number of geometry arguments
157: * is present in the array.
158: * Integer parameters must be passed as doubles.
159: * If no result can be computed for some reason, null should be returned
160: * to indicate this to the caller.
161: * Exceptions may be thrown and must be handled by the caller.
162: *
163: * @param geom the geometry arguments
164: * @param param any non-geometric arguments.
165: * @return the geometry result, or null if no result could be computed.
166: */
167: public abstract Geometry execute(Geometry[] geom, double[] param);
168:
169: public String toString() {
170: return name;
171: }
172:
173: //====================================================
174:
175: private static class IntersectionFunction extends GeometryFunction {
176: public IntersectionFunction() {
177: super (
178: I18N
179: .get("ui.plugin.analysis.GeometryFunction.intersection"),
180: 2, 0);
181: }
182:
183: public Geometry execute(Geometry[] geom, double[] param) {
184: return geom[0].intersection(geom[1]);
185: }
186: }
187:
188: private static class UnionFunction extends GeometryFunction {
189: public UnionFunction() {
190: super (
191: I18N
192: .get("ui.plugin.analysis.GeometryFunction.union"),
193: 2, 0);
194: }
195:
196: public Geometry execute(Geometry[] geom, double[] param) {
197: return geom[0].union(geom[1]);
198: }
199: }
200:
201: private static class DifferenceABFunction extends GeometryFunction {
202: public DifferenceABFunction() {
203: super (
204: I18N
205: .get("ui.plugin.analysis.GeometryFunction.difference-a-b"),
206: 2, 0);
207: }
208:
209: public Geometry execute(Geometry[] geom, double[] param) {
210: return geom[0].difference(geom[1]);
211: }
212: }
213:
214: private static class DifferenceBAFunction extends GeometryFunction {
215: public DifferenceBAFunction() {
216: super (
217: I18N
218: .get("ui.plugin.analysis.GeometryFunction.difference-b-a"),
219: 2, 0);
220: }
221:
222: public Geometry execute(Geometry[] geom, double[] param) {
223: return geom[1].difference(geom[0]);
224: }
225: }
226:
227: private static class SymDifferenceFunction extends GeometryFunction {
228: public SymDifferenceFunction() {
229: super (
230: I18N
231: .get("ui.plugin.analysis.GeometryFunction.symetric-difference"),
232: 2, 0);
233: }
234:
235: public Geometry execute(Geometry[] geom, double[] param) {
236: return geom[0].symDifference(geom[1]);
237: }
238: }
239:
240: private static class CentroidFunction extends GeometryFunction {
241: public CentroidFunction() {
242: super (
243: I18N
244: .get("ui.plugin.analysis.GeometryFunction.centroid-of-a"),
245: 1, 0);
246: }
247:
248: public Geometry execute(Geometry[] geom, double[] param) {
249: return geom[0].getCentroid();
250: }
251: }
252:
253: private static class InteriorPointFunction extends GeometryFunction {
254: public InteriorPointFunction() {
255: super ("Interior Point", 1, 0);
256: }
257:
258: public Geometry execute(Geometry[] geom, double[] param) {
259: return geom[0].getInteriorPoint();
260: }
261: }
262:
263: private static class BufferFunction extends GeometryFunction {
264: public BufferFunction() {
265: super (I18N
266: .get("ui.plugin.analysis.GeometryFunction.buffer"),
267: 1, 1);
268: }
269:
270: public Geometry execute(Geometry[] geom, double[] param) {
271: return geom[0].buffer(param[0]);
272: }
273: }
274:
275: private static class SimplifyFunction extends GeometryFunction {
276: public SimplifyFunction() {
277: super (
278: I18N
279: .get("ui.plugin.analysis.GeometryFunction.Simplify-(D-P)"),
280: 1,
281: 1,
282: I18N
283: .get("ui.plugin.analysis.GeometryFunction.Simplifies-a-geometry-using-the-Douglas-Peucker-algorithm"));
284: }
285:
286: public Geometry execute(Geometry[] geom, double[] param) {
287: return DouglasPeuckerSimplifier.simplify(geom[0], param[0]);
288: }
289: }
290:
291: private static class SimplifyTopologyFunction extends
292: GeometryFunction {
293: public SimplifyTopologyFunction() {
294: super (
295: I18N
296: .get("ui.plugin.analysis.GeometryFunction.Simplify-(preserve-topology)"),
297: 1, 1);
298: }
299:
300: public Geometry execute(Geometry[] geom, double[] param) {
301: return TopologyPreservingSimplifier.simplify(geom[0],
302: param[0]);
303: }
304: }
305:
306: private static class ConvexHullFunction extends GeometryFunction {
307: public ConvexHullFunction() {
308: super (
309: I18N
310: .get("ui.plugin.analysis.GeometryFunction.Convex-Hull"),
311: 1, 0);
312: }
313:
314: public Geometry execute(Geometry[] geom, double[] param) {
315: ConvexHull hull = new ConvexHull(geom[0]);
316: return hull.getConvexHull();
317: }
318: }
319:
320: private static class BoundaryFunction extends GeometryFunction {
321: public BoundaryFunction() {
322: super (
323: I18N
324: .get("ui.plugin.analysis.GeometryFunction.Boundary"),
325: 1, 0);
326: }
327:
328: public Geometry execute(Geometry[] geom, double[] param) {
329: return geom[0].getBoundary();
330: }
331: }
332:
333: private static class EnvelopeFunction extends GeometryFunction {
334: public EnvelopeFunction() {
335: super (
336: I18N
337: .get("ui.plugin.analysis.GeometryFunction.Envelope"),
338: 1, 0);
339: }
340:
341: public Geometry execute(Geometry[] geom, double[] param) {
342: return geom[0].getEnvelope();
343: }
344: }
345:
346: private static class LineMergeFunction extends GeometryFunction {
347: public LineMergeFunction() {
348: super (
349: I18N
350: .get("ui.plugin.analysis.GeometryFunction.Line-Merge"),
351: 1, 0);
352: }
353:
354: public Geometry execute(Geometry[] geom, double[] param) {
355: LineMerger merger = new LineMerger();
356: merger.add(geom[0]);
357: Collection lines = merger.getMergedLineStrings();
358: return geom[0].getFactory().buildGeometry(lines);
359: }
360: }
361:
362: private static class LineSequenceFunction extends GeometryFunction {
363: public LineSequenceFunction() {
364: super (
365: I18N
366: .get("ui.plugin.analysis.GeometryFunction.Line-Sequence"),
367: 1, 0);
368: }
369:
370: public Geometry execute(Geometry[] geom, double[] param) {
371: LineSequencer sequencer = new LineSequencer();
372: sequencer.add(geom[0]);
373: return sequencer.getSequencedLineStrings();
374: }
375: }
376:
377: private static class PolygonizeFunction extends GeometryFunction {
378: public PolygonizeFunction() {
379: super (
380: I18N
381: .get("ui.plugin.analysis.GeometryFunction.Polygonize"),
382: 1, 0);
383: }
384:
385: public Geometry execute(Geometry[] geom, double[] param) {
386: Polygonizer polygonizer = new Polygonizer();
387: polygonizer.add(geom[0]);
388: Collection polyColl = polygonizer.getPolygons();
389: Geometry[] polys = GeometryFactory
390: .toGeometryArray(polyColl);
391: return geom[0].getFactory().createGeometryCollection(polys);
392: }
393: }
394:
395: /**
396: * added 3. March 2007
397: * @author finstef
398: *
399: */
400: private static class ReverseLinestringFunction extends
401: GeometryFunction {
402: public ReverseLinestringFunction() {
403: super (
404: I18N
405: .get("ui.plugin.analysis.GeometryFunction.Reverse-Line-Direction"),
406: 1, 0);
407: }
408:
409: public Geometry execute(Geometry[] geom, double[] param) {
410: if (geom[0] instanceof LineString) {
411: Coordinate[] a = geom[0].getCoordinates();
412: CoordinateArrays.reverse(a);
413: Geometry invLine = new GeometryFactory()
414: .createLineString(a);
415: return invLine;
416: } else if (geom[0] instanceof Polygon) {
417: Polygon p = (Polygon) geom[0];
418: Coordinate[] outer = p.getExteriorRing()
419: .getCoordinates();
420: CoordinateArrays.reverse(outer);
421: LinearRing outLine = new GeometryFactory()
422: .createLinearRing(outer);
423: //-- do so as well for inner rings
424: LinearRing[] innerR = null;
425: if (p.getNumInteriorRing() > 0) {
426: innerR = new LinearRing[p.getNumInteriorRing()];
427: for (int i = 0; i < p.getNumInteriorRing(); i++) {
428: Coordinate[] inner = p.getInteriorRingN(i)
429: .getCoordinates();
430: CoordinateArrays.reverse(inner);
431: innerR[i] = new GeometryFactory()
432: .createLinearRing(inner);
433: }
434: }
435: Polygon pout = new GeometryFactory().createPolygon(
436: outLine, innerR);
437: return pout;
438: } else {
439: return geom[0];
440: }
441: }
442: }
443: }
|