01: package com.vividsolutions.jts.operation.overlay.validate;
02:
03: import java.util.*;
04: import com.vividsolutions.jts.geom.*;
05: import com.vividsolutions.jts.geom.util.*;
06:
07: /**
08: * Generates points offset by a given distance
09: * from both sides of the midpoint of
10: * all segments in a {@link Geometry}.
11: * Can be used to generate probe points for
12: * determining whether a polygonal overlay result
13: * is incorrect.
14: *
15: * @author Martin Davis
16: * @version 1.7
17: */
18: public class OffsetPointGenerator {
19: private double offsetDistance;
20: private Geometry g;
21: private List offsetPts;
22:
23: public OffsetPointGenerator(Geometry g, double offsetDistance) {
24: this .g = g;
25: this .offsetDistance = offsetDistance;
26: }
27:
28: /**
29: * Gets the computed offset points.
30: *
31: * @return List<Coordinate>
32: */
33: public List getPoints() {
34: offsetPts = new ArrayList();
35: List lines = LinearComponentExtracter.getLines(g);
36: for (Iterator i = lines.iterator(); i.hasNext();) {
37: LineString line = (LineString) i.next();
38: extractPoints(line);
39: }
40: //System.out.println(toMultiPoint(offsetPts));
41: return offsetPts;
42: }
43:
44: private void extractPoints(LineString line) {
45: Coordinate[] pts = line.getCoordinates();
46: for (int i = 0; i < pts.length - 1; i++) {
47: computeOffsetPoints(pts[i], pts[i + 1]);
48: }
49: }
50:
51: /**
52: * Generates the two points which are offset from the
53: * midpoint of the segment <tt>(p0, p1)</tt> by the
54: * <tt>offsetDistance</tt>.
55: *
56: * @param p0 the first point of the segment to offset from
57: * @param p1 the second point of the segment to offset from
58: */
59: private void computeOffsetPoints(Coordinate p0, Coordinate p1) {
60: double dx = p1.x - p0.x;
61: double dy = p1.y - p0.y;
62: double len = Math.sqrt(dx * dx + dy * dy);
63: // u is the vector that is the length of the offset, in the direction of the segment
64: double ux = offsetDistance * dx / len;
65: double uy = offsetDistance * dy / len;
66:
67: double midX = (p1.x + p0.x) / 2;
68: double midY = (p1.y + p0.y) / 2;
69:
70: Coordinate offsetLeft = new Coordinate(midX - uy, midY + ux);
71: Coordinate offsetRight = new Coordinate(midX + uy, midY - ux);
72:
73: offsetPts.add(offsetLeft);
74: offsetPts.add(offsetRight);
75: }
76:
77: }
|