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: package com.vividsolutions.jump.plugin.edit;
033:
034: import java.util.*;
035: import com.vividsolutions.jump.feature.*;
036: import com.vividsolutions.jump.geom.*;
037: import com.vividsolutions.jts.geom.*;
038: import com.vividsolutions.jts.geom.LineSegment;
039: import com.vividsolutions.jump.util.CoordinateArrays;
040: import com.vividsolutions.jump.task.*;
041:
042: /**
043: * Extracts the unique segments from a FeatureCollection.
044: *
045: * Replace UniqueSegmentExtracter, adding the capability to return segments
046: * occuring between minOccur and maxOccur times in the dataset.
047: * Now, this class can do the same as FeatureSegmentCounter in JCS and should replace it
048: * [Michael Michaud 2007-05-15]
049: *
050: * @author Martin Davis / Michael Michaud
051: * @version 1.1
052: */
053: public class SegmentsExtracter {
054: private static final GeometryFactory factory = new GeometryFactory();
055:
056: private Set segmentSet = new TreeSet();
057: // Segments are added to a TreeMap (LineSegment is Comparable)
058: private Map segmentMap = new TreeMap();
059: // private LineSegment querySegment = new LineSegment();
060: private boolean countZeroLengthSegments = true;
061: private TaskMonitor monitor;
062: private Geometry fence = null;
063:
064: // private LineSegmentEnvelopeIntersector lineEnvInt;
065:
066: public SegmentsExtracter() {
067: }
068:
069: /**
070: * Creates a new counter.
071: *
072: * @param monitor
073: */
074: public SegmentsExtracter(TaskMonitor monitor) {
075: this .monitor = monitor;
076: }
077:
078: /*
079: public void setFence(Geometry fence)
080: {
081: this.fence = fence;
082: //lineEnvInt = new LineSegmentEnvelopeIntersector();
083: }
084: */
085:
086: public void add(FeatureCollection fc) {
087: monitor.allowCancellationRequests();
088: int totalFeatures = fc.size();
089: int j = 0;
090: for (Iterator i = fc.iterator(); i.hasNext()
091: && !monitor.isCancelRequested();) {
092: Feature feature = (Feature) i.next();
093: j++;
094: monitor.report(j, totalFeatures, "features");
095: add(feature);
096: }
097: }
098:
099: public void add(Feature f) {
100: Geometry g = f.getGeometry();
101: // skip if using fence and feature is not in fence
102: if (fence != null && !g.intersects(fence))
103: return;
104:
105: List coordArrays = CoordinateArrays.toCoordinateArrays(g, true);
106: for (Iterator i = coordArrays.iterator(); i.hasNext();) {
107: Coordinate[] coord = (Coordinate[]) i.next();
108: for (int j = 0; j < coord.length - 1; j++) {
109: // skip if using fence AND seg is not in fence
110: /*
111: if (fence != null) {
112: LineString segLine = factory.createLineString(new Coordinate[] { coord[j], coord[j + 1] });
113: if (! fence.intersects(segLine))
114: continue;
115: }
116: */
117: add(coord[j], coord[j + 1]);
118: }
119: }
120: }
121:
122: public void add(Coordinate p0, Coordinate p1) {
123: // check for zero-length segment
124: boolean isZeroLength = p0.equals(p1);
125: if (!countZeroLengthSegments && isZeroLength)
126: return;
127:
128: LineSegment lineseg = new LineSegment(p0, p1);
129: lineseg.normalize();
130:
131: SegmentCount count = (SegmentCount) segmentMap.get(lineseg);
132: if (count == null) {
133: segmentMap.put(lineseg, new SegmentCount(1));
134: } else {
135: count.increment();
136: }
137:
138: //segmentSet.add(lineseg);
139: }
140:
141: public Collection getSegments() {
142: return segmentMap.keySet();
143: }
144:
145: public Collection getSegments(int minOccurs, int maxOccurs) {
146: List segmentList = new ArrayList();
147: for (Iterator it = segmentMap.entrySet().iterator(); it
148: .hasNext();) {
149: Map.Entry entry = (Map.Entry) it.next();
150: LineSegment ls = (LineSegment) entry.getKey();
151: int count = ((SegmentCount) entry.getValue()).getCount();
152: if (count >= minOccurs && count <= maxOccurs) {
153: segmentList.add(ls);
154: }
155: }
156: return segmentList;
157: }
158:
159: public class SegmentCount {
160: private int count = 0;
161:
162: public SegmentCount(int value) {
163: this .count = value;
164: }
165:
166: public int getCount() {
167: return count;
168: }
169:
170: public void increment() {
171: count++;
172: }
173: }
174:
175: }
|