jsts-rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (209) hide show
  1. checksums.yaml +8 -8
  2. data/lib/jsts-rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/javascript.util.js +33 -1
  4. data/vendor/assets/javascripts/jsts-original.js +164 -1573
  5. data/vendor/assets/javascripts/jsts.js +197 -0
  6. data/vendor/assets/javascripts/jsts/algorithm/Angle.js +387 -0
  7. data/vendor/assets/javascripts/jsts/algorithm/BoundaryNodeRule.js +67 -0
  8. data/vendor/assets/javascripts/jsts/algorithm/CGAlgorithms.js +596 -0
  9. data/vendor/assets/javascripts/jsts/algorithm/CentralEndpointIntersector.js +118 -0
  10. data/vendor/assets/javascripts/jsts/algorithm/CentroidArea.js +225 -0
  11. data/vendor/assets/javascripts/jsts/algorithm/CentroidLine.js +85 -0
  12. data/vendor/assets/javascripts/jsts/algorithm/CentroidPoint.js +77 -0
  13. data/vendor/assets/javascripts/jsts/algorithm/ConvexHull.js +409 -0
  14. data/vendor/assets/javascripts/jsts/algorithm/HCoordinate.js +234 -0
  15. data/vendor/assets/javascripts/jsts/algorithm/LineIntersector.js +502 -0
  16. data/vendor/assets/javascripts/jsts/algorithm/MCPointInRing.js +124 -0
  17. data/vendor/assets/javascripts/jsts/algorithm/PointLocator.js +247 -0
  18. data/vendor/assets/javascripts/jsts/algorithm/RayCrossingCounter.js +215 -0
  19. data/vendor/assets/javascripts/jsts/algorithm/RobustDeterminant.js +353 -0
  20. data/vendor/assets/javascripts/jsts/algorithm/RobustLineIntersector.js +477 -0
  21. data/vendor/assets/javascripts/jsts/algorithm/distance/DiscreteHausdorffDistance.js +228 -0
  22. data/vendor/assets/javascripts/jsts/algorithm/distance/DistanceToPoint.js +68 -0
  23. data/vendor/assets/javascripts/jsts/algorithm/distance/PointPairDistance.js +104 -0
  24. data/vendor/assets/javascripts/jsts/algorithm/locate/PointOnGeometryLocator.js +7 -0
  25. data/vendor/assets/javascripts/jsts/algorithm/locate/SimplePointInAreaLocator.js +102 -0
  26. data/vendor/assets/javascripts/jsts/geom/Coordinate.js +158 -0
  27. data/vendor/assets/javascripts/jsts/geom/CoordinateArrays.js +148 -0
  28. data/vendor/assets/javascripts/jsts/geom/CoordinateFilter.js +29 -0
  29. data/vendor/assets/javascripts/jsts/geom/CoordinateList.js +157 -0
  30. data/vendor/assets/javascripts/jsts/geom/CoordinateSequenceFilter.js +63 -0
  31. data/vendor/assets/javascripts/jsts/geom/Dimension.js +137 -0
  32. data/vendor/assets/javascripts/jsts/geom/Envelope.js +833 -0
  33. data/vendor/assets/javascripts/jsts/geom/Geometry.js +1535 -0
  34. data/vendor/assets/javascripts/jsts/geom/GeometryCollection.js +230 -0
  35. data/vendor/assets/javascripts/jsts/geom/GeometryComponentFilter.js +36 -0
  36. data/vendor/assets/javascripts/jsts/geom/GeometryFactory.js +263 -0
  37. data/vendor/assets/javascripts/jsts/geom/GeometryFilter.js +29 -0
  38. data/vendor/assets/javascripts/jsts/geom/IntersectionMatrix.js +650 -0
  39. data/vendor/assets/javascripts/jsts/geom/LineSegment.js +275 -0
  40. data/vendor/assets/javascripts/jsts/geom/LineString.js +299 -0
  41. data/vendor/assets/javascripts/jsts/geom/LinearRing.js +69 -0
  42. data/vendor/assets/javascripts/jsts/geom/Location.js +83 -0
  43. data/vendor/assets/javascripts/jsts/geom/MultiLineString.js +47 -0
  44. data/vendor/assets/javascripts/jsts/geom/MultiPoint.js +64 -0
  45. data/vendor/assets/javascripts/jsts/geom/MultiPolygon.js +64 -0
  46. data/vendor/assets/javascripts/jsts/geom/Point.js +197 -0
  47. data/vendor/assets/javascripts/jsts/geom/Polygon.js +263 -0
  48. data/vendor/assets/javascripts/jsts/geom/PrecisionModel.js +187 -0
  49. data/vendor/assets/javascripts/jsts/geom/Triangle.js +313 -0
  50. data/vendor/assets/javascripts/jsts/geom/util/GeometryCombiner.js +143 -0
  51. data/vendor/assets/javascripts/jsts/geom/util/GeometryExtracter.js +76 -0
  52. data/vendor/assets/javascripts/jsts/geom/util/GeometryTransformer.js +295 -0
  53. data/vendor/assets/javascripts/jsts/geom/util/LinearComponentExtracter.js +207 -0
  54. data/vendor/assets/javascripts/jsts/geom/util/PointExtracter.js +67 -0
  55. data/vendor/assets/javascripts/jsts/geom/util/PolygonExtracter.js +71 -0
  56. data/vendor/assets/javascripts/jsts/geomgraph/Depth.js +145 -0
  57. data/vendor/assets/javascripts/jsts/geomgraph/DirectedEdge.js +270 -0
  58. data/vendor/assets/javascripts/jsts/geomgraph/DirectedEdgeStar.js +388 -0
  59. data/vendor/assets/javascripts/jsts/geomgraph/Edge.js +291 -0
  60. data/vendor/assets/javascripts/jsts/geomgraph/EdgeEnd.js +188 -0
  61. data/vendor/assets/javascripts/jsts/geomgraph/EdgeEndStar.js +322 -0
  62. data/vendor/assets/javascripts/jsts/geomgraph/EdgeIntersection.js +122 -0
  63. data/vendor/assets/javascripts/jsts/geomgraph/EdgeIntersectionList.js +146 -0
  64. data/vendor/assets/javascripts/jsts/geomgraph/EdgeList.js +111 -0
  65. data/vendor/assets/javascripts/jsts/geomgraph/EdgeNodingValidator.js +76 -0
  66. data/vendor/assets/javascripts/jsts/geomgraph/EdgeRing.js +230 -0
  67. data/vendor/assets/javascripts/jsts/geomgraph/GeometryGraph.js +469 -0
  68. data/vendor/assets/javascripts/jsts/geomgraph/GraphComponent.js +181 -0
  69. data/vendor/assets/javascripts/jsts/geomgraph/Label.js +316 -0
  70. data/vendor/assets/javascripts/jsts/geomgraph/Node.js +105 -0
  71. data/vendor/assets/javascripts/jsts/geomgraph/NodeFactory.js +22 -0
  72. data/vendor/assets/javascripts/jsts/geomgraph/NodeMap.js +128 -0
  73. data/vendor/assets/javascripts/jsts/geomgraph/PlanarGraph.js +214 -0
  74. data/vendor/assets/javascripts/jsts/geomgraph/Position.js +63 -0
  75. data/vendor/assets/javascripts/jsts/geomgraph/Quadrant.js +143 -0
  76. data/vendor/assets/javascripts/jsts/geomgraph/TopologyLocation.js +251 -0
  77. data/vendor/assets/javascripts/jsts/geomgraph/index/EdgeSetIntersector.js +47 -0
  78. data/vendor/assets/javascripts/jsts/geomgraph/index/SegmentIntersector.js +298 -0
  79. data/vendor/assets/javascripts/jsts/geomgraph/index/SimpleEdgeSetIntersector.js +107 -0
  80. data/vendor/assets/javascripts/jsts/geomgraph/index/SimpleMCSweepLineIntersector.js +29 -0
  81. data/vendor/assets/javascripts/jsts/index/ArrayListVisitor.js +37 -0
  82. data/vendor/assets/javascripts/jsts/index/DoubleBits.js +132 -0
  83. data/vendor/assets/javascripts/jsts/index/IntervalSize.js +55 -0
  84. data/vendor/assets/javascripts/jsts/index/ItemVisitor.js +23 -0
  85. data/vendor/assets/javascripts/jsts/index/SpatialIndex.js +67 -0
  86. data/vendor/assets/javascripts/jsts/index/bintree/Bintree.js +224 -0
  87. data/vendor/assets/javascripts/jsts/index/bintree/Interval.js +160 -0
  88. data/vendor/assets/javascripts/jsts/index/bintree/Key.js +110 -0
  89. data/vendor/assets/javascripts/jsts/index/bintree/Node.js +204 -0
  90. data/vendor/assets/javascripts/jsts/index/bintree/NodeBase.js +220 -0
  91. data/vendor/assets/javascripts/jsts/index/bintree/Root.js +113 -0
  92. data/vendor/assets/javascripts/jsts/index/chain/MonotoneChain.js +244 -0
  93. data/vendor/assets/javascripts/jsts/index/chain/MonotoneChainBuilder.js +106 -0
  94. data/vendor/assets/javascripts/jsts/index/chain/MonotoneChainOverlapAction.js +56 -0
  95. data/vendor/assets/javascripts/jsts/index/chain/MonotoneChainSelectAction.js +44 -0
  96. data/vendor/assets/javascripts/jsts/index/kdtree/KdNode.js +171 -0
  97. data/vendor/assets/javascripts/jsts/index/kdtree/KdTree.js +218 -0
  98. data/vendor/assets/javascripts/jsts/index/quadtree/Key.js +134 -0
  99. data/vendor/assets/javascripts/jsts/index/quadtree/Node.js +220 -0
  100. data/vendor/assets/javascripts/jsts/index/quadtree/NodeBase.js +330 -0
  101. data/vendor/assets/javascripts/jsts/index/quadtree/Quadtree.js +228 -0
  102. data/vendor/assets/javascripts/jsts/index/quadtree/Root.js +105 -0
  103. data/vendor/assets/javascripts/jsts/index/strtree/AbstractNode.js +107 -0
  104. data/vendor/assets/javascripts/jsts/index/strtree/AbstractSTRtree.js +594 -0
  105. data/vendor/assets/javascripts/jsts/index/strtree/Boundable.js +37 -0
  106. data/vendor/assets/javascripts/jsts/index/strtree/BoundablePair.js +0 -0
  107. data/vendor/assets/javascripts/jsts/index/strtree/Interval.js +94 -0
  108. data/vendor/assets/javascripts/jsts/index/strtree/ItemBoundable.js +60 -0
  109. data/vendor/assets/javascripts/jsts/index/strtree/SIRtree.js +122 -0
  110. data/vendor/assets/javascripts/jsts/index/strtree/STRtree.js +450 -0
  111. data/vendor/assets/javascripts/jsts/io/GeoJSONParser.js +471 -0
  112. data/vendor/assets/javascripts/jsts/io/GeoJSONReader.js +58 -0
  113. data/vendor/assets/javascripts/jsts/io/GeoJSONWriter.js +38 -0
  114. data/vendor/assets/javascripts/jsts/io/OpenLayersParser.js +245 -0
  115. data/vendor/assets/javascripts/jsts/io/WKTParser.js +421 -0
  116. data/vendor/assets/javascripts/jsts/io/WKTReader.js +68 -0
  117. data/vendor/assets/javascripts/jsts/io/WKTWriter.js +61 -0
  118. data/vendor/assets/javascripts/jsts/noding/BasicSegmentString.js +87 -0
  119. data/vendor/assets/javascripts/jsts/noding/FastNodingValidator.js +127 -0
  120. data/vendor/assets/javascripts/jsts/noding/InteriorIntersectionFinder.js +171 -0
  121. data/vendor/assets/javascripts/jsts/noding/IntersectionAdder.js +198 -0
  122. data/vendor/assets/javascripts/jsts/noding/IntersectionFinderAdder.js +79 -0
  123. data/vendor/assets/javascripts/jsts/noding/MCIndexNoder.js +147 -0
  124. data/vendor/assets/javascripts/jsts/noding/NodableSegmentString.js +35 -0
  125. data/vendor/assets/javascripts/jsts/noding/NodedSegmentString.js +235 -0
  126. data/vendor/assets/javascripts/jsts/noding/Noder.js +41 -0
  127. data/vendor/assets/javascripts/jsts/noding/NodingValidator.js +5 -0
  128. data/vendor/assets/javascripts/jsts/noding/Octant.js +84 -0
  129. data/vendor/assets/javascripts/jsts/noding/OrientedCoordinateArray.js +94 -0
  130. data/vendor/assets/javascripts/jsts/noding/ScaledNoder.js +105 -0
  131. data/vendor/assets/javascripts/jsts/noding/SegmentIntersector.js +45 -0
  132. data/vendor/assets/javascripts/jsts/noding/SegmentNode.js +70 -0
  133. data/vendor/assets/javascripts/jsts/noding/SegmentNodeList.js +262 -0
  134. data/vendor/assets/javascripts/jsts/noding/SegmentPointComparator.js +78 -0
  135. data/vendor/assets/javascripts/jsts/noding/SegmentString.js +61 -0
  136. data/vendor/assets/javascripts/jsts/noding/SinglePassNoder.js +51 -0
  137. data/vendor/assets/javascripts/jsts/noding/snapround/HotPixel.js +271 -0
  138. data/vendor/assets/javascripts/jsts/noding/snapround/MCIndexPointSnapper.js +96 -0
  139. data/vendor/assets/javascripts/jsts/noding/snapround/MCIndexSnapRounder.js +147 -0
  140. data/vendor/assets/javascripts/jsts/operation/BoundaryOp.js +166 -0
  141. data/vendor/assets/javascripts/jsts/operation/GeometryGraphOperation.js +90 -0
  142. data/vendor/assets/javascripts/jsts/operation/IsSimpleOp.js +293 -0
  143. data/vendor/assets/javascripts/jsts/operation/buffer/BufferBuilder.js +317 -0
  144. data/vendor/assets/javascripts/jsts/operation/buffer/BufferInputLineSimplifier.js +294 -0
  145. data/vendor/assets/javascripts/jsts/operation/buffer/BufferOp.js +340 -0
  146. data/vendor/assets/javascripts/jsts/operation/buffer/BufferParameters.js +328 -0
  147. data/vendor/assets/javascripts/jsts/operation/buffer/BufferSubgraph.js +296 -0
  148. data/vendor/assets/javascripts/jsts/operation/buffer/OffsetCurveBuilder.js +369 -0
  149. data/vendor/assets/javascripts/jsts/operation/buffer/OffsetCurveSetBuilder.js +301 -0
  150. data/vendor/assets/javascripts/jsts/operation/buffer/OffsetSegmentGenerator.js +777 -0
  151. data/vendor/assets/javascripts/jsts/operation/buffer/OffsetSegmentString.js +109 -0
  152. data/vendor/assets/javascripts/jsts/operation/buffer/RightmostEdgeFinder.js +164 -0
  153. data/vendor/assets/javascripts/jsts/operation/buffer/SubgraphDepthLocater.js +220 -0
  154. data/vendor/assets/javascripts/jsts/operation/distance/ConnectedElementLocationFilter.js +67 -0
  155. data/vendor/assets/javascripts/jsts/operation/distance/DistanceOp.js +506 -0
  156. data/vendor/assets/javascripts/jsts/operation/distance/GeometryLocation.js +102 -0
  157. data/vendor/assets/javascripts/jsts/operation/overlay/LineBuilder.js +194 -0
  158. data/vendor/assets/javascripts/jsts/operation/overlay/MaximalEdgeRing.js +72 -0
  159. data/vendor/assets/javascripts/jsts/operation/overlay/MinimalEdgeRing.js +33 -0
  160. data/vendor/assets/javascripts/jsts/operation/overlay/OverlayNodeFactory.js +26 -0
  161. data/vendor/assets/javascripts/jsts/operation/overlay/OverlayOp.js +584 -0
  162. data/vendor/assets/javascripts/jsts/operation/overlay/PointBuilder.js +103 -0
  163. data/vendor/assets/javascripts/jsts/operation/overlay/PolygonBuilder.js +282 -0
  164. data/vendor/assets/javascripts/jsts/operation/overlay/snap/GeometrySnapper.js +228 -0
  165. data/vendor/assets/javascripts/jsts/operation/overlay/snap/LineStringSnapper.js +228 -0
  166. data/vendor/assets/javascripts/jsts/operation/overlay/snap/SnapIfNeededOverlayOp.js +85 -0
  167. data/vendor/assets/javascripts/jsts/operation/overlay/snap/SnapOverlayOp.js +134 -0
  168. data/vendor/assets/javascripts/jsts/operation/polygonize/EdgeRing.js +259 -0
  169. data/vendor/assets/javascripts/jsts/operation/polygonize/PolygonizeDirectedEdge.js +94 -0
  170. data/vendor/assets/javascripts/jsts/operation/polygonize/PolygonizeEdge.js +31 -0
  171. data/vendor/assets/javascripts/jsts/operation/polygonize/PolygonizeGraph.js +507 -0
  172. data/vendor/assets/javascripts/jsts/operation/polygonize/Polygonizer.js +259 -0
  173. data/vendor/assets/javascripts/jsts/operation/relate/EdgeEndBuilder.js +140 -0
  174. data/vendor/assets/javascripts/jsts/operation/relate/EdgeEndBundle.js +183 -0
  175. data/vendor/assets/javascripts/jsts/operation/relate/EdgeEndBundleStar.js +48 -0
  176. data/vendor/assets/javascripts/jsts/operation/relate/RelateComputer.js +444 -0
  177. data/vendor/assets/javascripts/jsts/operation/relate/RelateNode.js +46 -0
  178. data/vendor/assets/javascripts/jsts/operation/relate/RelateNodeFactory.js +25 -0
  179. data/vendor/assets/javascripts/jsts/operation/relate/RelateNodeGraph.js +118 -0
  180. data/vendor/assets/javascripts/jsts/operation/relate/RelateOp.js +75 -0
  181. data/vendor/assets/javascripts/jsts/operation/union/CascadedPolygonUnion.js +319 -0
  182. data/vendor/assets/javascripts/jsts/operation/union/PointGeometryUnion.js +118 -0
  183. data/vendor/assets/javascripts/jsts/operation/union/UnaryUnionOp.js +244 -0
  184. data/vendor/assets/javascripts/jsts/operation/union/UnionInteracting.js +156 -0
  185. data/vendor/assets/javascripts/jsts/operation/valid/ConnectedInteriorTester.js +259 -0
  186. data/vendor/assets/javascripts/jsts/operation/valid/ConsistentAreaTester.js +127 -0
  187. data/vendor/assets/javascripts/jsts/operation/valid/IndexedNestedRingTester.js +89 -0
  188. data/vendor/assets/javascripts/jsts/operation/valid/IsValidOp.js +619 -0
  189. data/vendor/assets/javascripts/jsts/operation/valid/TopologyValidationError.js +199 -0
  190. data/vendor/assets/javascripts/jsts/planargraph/DirectedEdge.js +232 -0
  191. data/vendor/assets/javascripts/jsts/planargraph/DirectedEdgeStar.js +168 -0
  192. data/vendor/assets/javascripts/jsts/planargraph/Edge.js +124 -0
  193. data/vendor/assets/javascripts/jsts/planargraph/GraphComponent.js +182 -0
  194. data/vendor/assets/javascripts/jsts/planargraph/Node.js +127 -0
  195. data/vendor/assets/javascripts/jsts/planargraph/NodeMap.js +76 -0
  196. data/vendor/assets/javascripts/jsts/planargraph/PlanarGraph.js +246 -0
  197. data/vendor/assets/javascripts/jsts/simplify/LineSegmentIndex.js +101 -0
  198. data/vendor/assets/javascripts/jsts/triangulate/DelaunayTriangulationBuilder.js +224 -0
  199. data/vendor/assets/javascripts/jsts/triangulate/IncrementalDelaunayTriangulator.js +111 -0
  200. data/vendor/assets/javascripts/jsts/triangulate/VoronoiDiagramBuilder.js +172 -0
  201. data/vendor/assets/javascripts/jsts/triangulate/quadedge/LastFoundQuadEdgeLocator.js +52 -0
  202. data/vendor/assets/javascripts/jsts/triangulate/quadedge/QuadEdge.js +437 -0
  203. data/vendor/assets/javascripts/jsts/triangulate/quadedge/QuadEdgeSubdivision.js +1064 -0
  204. data/vendor/assets/javascripts/jsts/triangulate/quadedge/TrianglePredicate.js +350 -0
  205. data/vendor/assets/javascripts/jsts/triangulate/quadedge/Vertex.js +496 -0
  206. data/vendor/assets/javascripts/jsts/util/Assert.js +80 -0
  207. data/vendor/assets/javascripts/jsts/util/AssertionFailedException.js +23 -0
  208. data/vendor/assets/javascripts/jsts/util/UniqueCoordinateArrayFilter.js +52 -0
  209. metadata +204 -1
@@ -0,0 +1,103 @@
1
+ /* Copyright (c) 2011 by The Authors.
2
+ * Published under the LGPL 2.1 license.
3
+ * See /license-notice.txt for the full text of the license notice.
4
+ * See /license.txt for the full text of the license.
5
+ */
6
+
7
+ (function() {
8
+
9
+ var ArrayList = javascript.util.ArrayList;
10
+
11
+ /**
12
+ * Constructs {@link Point}s from the nodes of an overlay graph.
13
+ */
14
+ var PointBuilder = function(op, geometryFactory, ptLocator) {
15
+ this.resultPointList = new ArrayList();
16
+
17
+ this.op = op;
18
+ this.geometryFactory = geometryFactory;
19
+ };
20
+
21
+ PointBuilder.prototype.op = null;
22
+ PointBuilder.prototype.geometryFactory = null;
23
+
24
+ PointBuilder.prototype.resultPointList = null;
25
+
26
+ /**
27
+ * Computes the Point geometries which will appear in the result, given the
28
+ * specified overlay operation.
29
+ *
30
+ * @return a list of the Points objects in the result.
31
+ */
32
+ PointBuilder.prototype.build = function(opCode) {
33
+ this.extractNonCoveredResultNodes(opCode);
34
+ /**
35
+ * It can happen that connected result nodes are still covered by result
36
+ * geometries, so must perform this filter. (For instance, this can happen
37
+ * during topology collapse).
38
+ */
39
+ return this.resultPointList;
40
+ };
41
+
42
+ /**
43
+ * Determines nodes which are in the result, and creates {@link Point}s for
44
+ * them.
45
+ *
46
+ * This method determines nodes which are candidates for the result via their
47
+ * labelling and their graph topology.
48
+ *
49
+ * @param opCode
50
+ * the overlay operation.
51
+ * @private
52
+ */
53
+ PointBuilder.prototype.extractNonCoveredResultNodes = function(opCode) {
54
+ // testing only
55
+ // if (true) return resultNodeList;
56
+
57
+ for (var nodeit = this.op.getGraph().getNodes().iterator(); nodeit
58
+ .hasNext();) {
59
+ var n = nodeit.next();
60
+
61
+ // filter out nodes which are known to be in the result
62
+ if (n.isInResult())
63
+ continue;
64
+ // if an incident edge is in the result, then the node coordinate is
65
+ // included already
66
+ if (n.isIncidentEdgeInResult())
67
+ continue;
68
+ if (n.getEdges().getDegree() === 0 || opCode === jsts.operation.overlay.OverlayOp.INTERSECTION) {
69
+
70
+ /**
71
+ * For nodes on edges, only INTERSECTION can result in edge nodes being
72
+ * included even if none of their incident edges are included
73
+ */
74
+ var label = n.getLabel();
75
+ if (jsts.operation.overlay.OverlayOp.isResultOfOp(label, opCode)) {
76
+ this.filterCoveredNodeToPoint(n);
77
+ }
78
+ }
79
+ }
80
+ };
81
+
82
+ /**
83
+ * Converts non-covered nodes to Point objects and adds them to the result.
84
+ *
85
+ * A node is covered if it is contained in another element Geometry with
86
+ * higher dimension (e.g. a node point might be contained in a polygon, in
87
+ * which case the point can be eliminated from the result).
88
+ *
89
+ * @param n
90
+ * the node to test.
91
+ * @private
92
+ */
93
+ PointBuilder.prototype.filterCoveredNodeToPoint = function(n) {
94
+ var coord = n.getCoordinate();
95
+ if (!this.op.isCoveredByLA(coord)) {
96
+ var pt = this.geometryFactory.createPoint(coord);
97
+ this.resultPointList.add(pt);
98
+ }
99
+ };
100
+
101
+ jsts.operation.overlay.PointBuilder = PointBuilder;
102
+
103
+ })();
@@ -0,0 +1,282 @@
1
+ /* Copyright (c) 2011 by The Authors.
2
+ * Published under the LGPL 2.1 license.
3
+ * See /license-notice.txt for the full text of the license notice.
4
+ * See /license.txt for the full text of the license.
5
+ */
6
+
7
+ /**
8
+ * Forms {@link Polygon}s out of a graph of {@link DirectedEdge}s. The edges
9
+ * to use are marked as being in the result Area.
10
+ * <p>
11
+ */
12
+ jsts.operation.overlay.PolygonBuilder = function(geometryFactory) {
13
+ this.shellList = [];
14
+ this.geometryFactory = geometryFactory;
15
+ };
16
+
17
+ /**
18
+ * @private
19
+ */
20
+ jsts.operation.overlay.PolygonBuilder.prototype.geometryFactory = null;
21
+
22
+ /**
23
+ * @private
24
+ */
25
+ jsts.operation.overlay.PolygonBuilder.prototype.shellList = null;
26
+
27
+
28
+ /**
29
+ * Add a complete graph. The graph is assumed to contain one or more polygons,
30
+ * possibly with holes.
31
+ *
32
+ * @param {jsts.geomgraph.PlanarGraph}
33
+ * graph
34
+ */
35
+ jsts.operation.overlay.PolygonBuilder.prototype.add = function(graph) {
36
+ if (arguments.length === 2) {
37
+ this.add2.apply(this, arguments);
38
+ return;
39
+ }
40
+
41
+ this.add2(graph.getEdgeEnds(), graph.getNodes());
42
+ };
43
+
44
+ /**
45
+ * Add a set of edges and nodes, which form a graph. The graph is assumed to
46
+ * contain one or more polygons, possibly with holes.
47
+ */
48
+ jsts.operation.overlay.PolygonBuilder.prototype.add2 = function(dirEdges, nodes) {
49
+ jsts.geomgraph.PlanarGraph.linkResultDirectedEdges(nodes);
50
+ var maxEdgeRings = this.buildMaximalEdgeRings(dirEdges);
51
+ var freeHoleList = [];
52
+ var edgeRings = this.buildMinimalEdgeRings(maxEdgeRings, this.shellList,
53
+ freeHoleList);
54
+ this.sortShellsAndHoles(edgeRings, this.shellList, freeHoleList);
55
+ this.placeFreeHoles(this.shellList, freeHoleList);
56
+ };
57
+
58
+ jsts.operation.overlay.PolygonBuilder.prototype.getPolygons = function() {
59
+ var resultPolyList = this.computePolygons(this.shellList);
60
+ return resultPolyList;
61
+ };
62
+
63
+
64
+ /**
65
+ * for all DirectedEdges in result, form them into MaximalEdgeRings
66
+ *
67
+ * @private
68
+ */
69
+ jsts.operation.overlay.PolygonBuilder.prototype.buildMaximalEdgeRings = function(
70
+ dirEdges) {
71
+ var maxEdgeRings = [];
72
+ for (var it = dirEdges.iterator(); it.hasNext(); ) {
73
+ var de = it.next();
74
+ if (de.isInResult() && de.getLabel().isArea()) {
75
+ // if this edge has not yet been processed
76
+ if (de.getEdgeRing() == null) {
77
+ var er = new jsts.operation.overlay.MaximalEdgeRing(de, this.geometryFactory);
78
+ maxEdgeRings.push(er);
79
+ er.setInResult();
80
+ // System.out.println("max node degree = " + er.getMaxDegree());
81
+ }
82
+ }
83
+ }
84
+ return maxEdgeRings;
85
+ };
86
+
87
+ /**
88
+ * @private
89
+ */
90
+ jsts.operation.overlay.PolygonBuilder.prototype.buildMinimalEdgeRings = function(
91
+ maxEdgeRings, shellList, freeHoleList) {
92
+ var edgeRings = [];
93
+ for (var i = 0; i < maxEdgeRings.length; i++) {
94
+ var er = maxEdgeRings[i];
95
+ if (er.getMaxNodeDegree() > 2) {
96
+ er.linkDirectedEdgesForMinimalEdgeRings();
97
+ var minEdgeRings = er.buildMinimalRings();
98
+ // at this point we can go ahead and attempt to place holes, if this
99
+ // EdgeRing is a polygon
100
+ var shell = this.findShell(minEdgeRings);
101
+ if (shell !== null) {
102
+ this.placePolygonHoles(shell, minEdgeRings);
103
+ shellList.push(shell);
104
+ } else {
105
+ freeHoleList = freeHoleList.concat(minEdgeRings);
106
+ }
107
+ } else {
108
+ edgeRings.push(er);
109
+ }
110
+ }
111
+ return edgeRings;
112
+ };
113
+
114
+ /**
115
+ * This method takes a list of MinimalEdgeRings derived from a MaximalEdgeRing,
116
+ * and tests whether they form a Polygon. This is the case if there is a single
117
+ * shell in the list. In this case the shell is returned. The other possibility
118
+ * is that they are a series of connected holes, in which case no shell is
119
+ * returned.
120
+ *
121
+ * @return {EdgeRing} the shell EdgeRing, if there is one or null, if all the
122
+ * rings are holes.
123
+ * @private
124
+ */
125
+ jsts.operation.overlay.PolygonBuilder.prototype.findShell = function(
126
+ minEdgeRings) {
127
+ var shellCount = 0;
128
+ var shell = null;
129
+ for (var i = 0; i < minEdgeRings.length; i++) {
130
+ var er = minEdgeRings[i];
131
+ if (!er.isHole()) {
132
+ shell = er;
133
+ shellCount++;
134
+ }
135
+ }
136
+ jsts.util.Assert.isTrue(shellCount <= 1, 'found two shells in MinimalEdgeRing list');
137
+ return shell;
138
+ };
139
+ /**
140
+ * This method assigns the holes for a Polygon (formed from a list of
141
+ * MinimalEdgeRings) to its shell. Determining the holes for a MinimalEdgeRing
142
+ * polygon serves two purposes:
143
+ * <ul>
144
+ * <li>it is faster than using a point-in-polygon check later on.
145
+ * <li>it ensures correctness, since if the PIP test was used the point chosen
146
+ * might lie on the shell, which might return an incorrect result from the PIP
147
+ * test
148
+ * </ul>
149
+ *
150
+ * @param {EdgeRing}
151
+ * shell
152
+ * @param {Array}
153
+ * minEdgeRings
154
+ * @private
155
+ */
156
+ jsts.operation.overlay.PolygonBuilder.prototype.placePolygonHoles = function(
157
+ shell, minEdgeRings) {
158
+ for (var i = 0; i < minEdgeRings.length; i++) {
159
+ var er = minEdgeRings[i];
160
+ if (er.isHole()) {
161
+ er.setShell(shell);
162
+ }
163
+ }
164
+ };
165
+ /**
166
+ * For all rings in the input list, determine whether the ring is a shell or a
167
+ * hole and add it to the appropriate list. Due to the way the DirectedEdges
168
+ * were linked, a ring is a shell if it is oriented CW, a hole otherwise.
169
+ *
170
+ * @private
171
+ */
172
+ jsts.operation.overlay.PolygonBuilder.prototype.sortShellsAndHoles = function(
173
+ edgeRings, shellList, freeHoleList) {
174
+ for (var i = 0; i < edgeRings.length; i++) {
175
+ var er = edgeRings[i];
176
+ if (er.isHole()) {
177
+ freeHoleList.push(er);
178
+ } else {
179
+ shellList.push(er);
180
+ }
181
+ }
182
+ };
183
+ /**
184
+ * This method determines finds a containing shell for all holes which have not
185
+ * yet been assigned to a shell. These "free" holes should all be <b>properly</b>
186
+ * contained in their parent shells, so it is safe to use the
187
+ * <code>findEdgeRingContaining</code> method. (This is the case because any
188
+ * holes which are NOT properly contained (i.e. are connected to their parent
189
+ * shell) would have formed part of a MaximalEdgeRing and been handled in a
190
+ * previous step).
191
+ *
192
+ * @throws TopologyException
193
+ * if a hole cannot be assigned to a shell
194
+ * @private
195
+ */
196
+ jsts.operation.overlay.PolygonBuilder.prototype.placeFreeHoles = function(
197
+ shellList, freeHoleList) {
198
+ for (var i = 0; i < freeHoleList.length; i++) {
199
+ var hole = freeHoleList[i];
200
+ // only place this hole if it doesn't yet have a shell
201
+ if (hole.getShell() == null) {
202
+ var shell = this.findEdgeRingContaining(hole, shellList);
203
+ if (shell === null)
204
+ throw new jsts.error.TopologyError('unable to assign hole to a shell',
205
+ hole.getCoordinate(0));
206
+ hole.setShell(shell);
207
+ }
208
+ }
209
+ };
210
+
211
+ /**
212
+ * Find the innermost enclosing shell EdgeRing containing the argument EdgeRing,
213
+ * if any. The innermost enclosing ring is the <i>smallest</i> enclosing ring.
214
+ * The algorithm used depends on the fact that: <br>
215
+ * ring A contains ring B iff envelope(ring A) contains envelope(ring B) <br>
216
+ * This routine is only safe to use if the chosen point of the hole is known to
217
+ * be properly contained in a shell (which is guaranteed to be the case if the
218
+ * hole does not touch its shell)
219
+ *
220
+ * @return containing EdgeRing, if there is one.
221
+ * @return null if no containing EdgeRing is found.
222
+ * @private
223
+ */
224
+ jsts.operation.overlay.PolygonBuilder.prototype.findEdgeRingContaining = function(
225
+ testEr, shellList) {
226
+ var testRing = testEr.getLinearRing();
227
+ var testEnv = testRing.getEnvelopeInternal();
228
+ var testPt = testRing.getCoordinateN(0);
229
+
230
+ var minShell = null;
231
+ var minEnv = null;
232
+ for (var i = 0; i < shellList.length; i++) {
233
+ var tryShell = shellList[i];
234
+ var tryRing = tryShell.getLinearRing();
235
+ var tryEnv = tryRing.getEnvelopeInternal();
236
+ if (minShell !== null)
237
+ minEnv = minShell.getLinearRing().getEnvelopeInternal();
238
+ var isContained = false;
239
+ if (tryEnv.contains(testEnv) &&
240
+ jsts.algorithm.CGAlgorithms.isPointInRing(testPt, tryRing
241
+ .getCoordinates()))
242
+ isContained = true;
243
+ // check if this new containing ring is smaller than the current minimum
244
+ // ring
245
+ if (isContained) {
246
+ if (minShell == null || minEnv.contains(tryEnv)) {
247
+ minShell = tryShell;
248
+ }
249
+ }
250
+ }
251
+ return minShell;
252
+ };
253
+
254
+ /**
255
+ * @private
256
+ */
257
+ jsts.operation.overlay.PolygonBuilder.prototype.computePolygons = function(
258
+ shellList) {
259
+ var resultPolyList = new javascript.util.ArrayList();
260
+ // add Polygons for all shells
261
+ for (var i = 0; i < shellList.length; i++) {
262
+ var er = shellList[i];
263
+ var poly = er.toPolygon(this.geometryFactory);
264
+ resultPolyList.add(poly);
265
+ }
266
+ return resultPolyList;
267
+ };
268
+
269
+ /**
270
+ * Checks the current set of shells (with their associated holes) to see if any
271
+ * of them contain the point.
272
+ *
273
+ * @return {boolean}
274
+ */
275
+ jsts.operation.overlay.PolygonBuilder.prototype.containsPoint = function(p) {
276
+ for (var i = 0; i < this.shellList.length; i++) {
277
+ var er = this.shellList[i];
278
+ if (er.containsPoint(p))
279
+ return true;
280
+ }
281
+ return false;
282
+ };
@@ -0,0 +1,228 @@
1
+ /* Copyright (c) 2011 by The Authors.
2
+ * Published under the LGPL 2.1 license.
3
+ * See /license-notice.txt for the full text of the license notice.
4
+ * See /license.txt for the full text of the license.
5
+ */
6
+
7
+ /**
8
+ * Port source:
9
+ * /jts/jts/java/src/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java
10
+ * Revision: 167
11
+ */
12
+
13
+ /**
14
+ * @requires jsts/operation/overlay/snap/LineStringSnapper.js
15
+ * @requires jsts/geom/PrecisionModel.js
16
+ * @requires jsts/geom/util/GeometryTransformer.js
17
+ */
18
+
19
+ /**
20
+ * Snaps the vertices and segments of a {@link Geometry} to another Geometry's
21
+ * vertices. A snap distance tolerance is used to control where snapping is
22
+ * performed. Snapping one geometry to another can improve robustness for
23
+ * overlay operations by eliminating nearly-coincident edges (which cause
24
+ * problems during noding and intersection calculation). Too much snapping can
25
+ * result in invalid topology beging created, so the number and location of
26
+ * snapped vertices is decided using heuristics to determine when it is safe to
27
+ * snap. This can result in some potential snaps being omitted, however.
28
+ */
29
+
30
+ (function() {
31
+
32
+ var LineStringSnapper = jsts.operation.overlay.snap.LineStringSnapper;
33
+ var PrecisionModel = jsts.geom.PrecisionModel;
34
+ var TreeSet = javascript.util.TreeSet;
35
+
36
+ /**
37
+ * @constructor
38
+ */
39
+ var SnapTransformer = function(snapTolerance, snapPts, isSelfSnap) {
40
+ this.snapTolerance = snapTolerance;
41
+ this.snapPts = snapPts;
42
+ this.isSelfSnap = isSelfSnap || false;
43
+ };
44
+
45
+ SnapTransformer.prototype = new jsts.geom.util.GeometryTransformer();
46
+
47
+ SnapTransformer.prototype.snapTolerance = null;
48
+ SnapTransformer.prototype.snapPts = null;
49
+ SnapTransformer.prototype.isSelfSnap = false;
50
+
51
+
52
+ SnapTransformer.prototype.transformCoordinates = function(coords, parent) {
53
+ var srcPts = coords;
54
+ var newPts = this.snapLine(srcPts, this.snapPts);
55
+ return newPts;
56
+ };
57
+
58
+ SnapTransformer.prototype.snapLine = function(srcPts, snapPts) {
59
+ var snapper = new LineStringSnapper(srcPts, this.snapTolerance);
60
+ snapper.setAllowSnappingToSourceVertices(this.isSelfSnap);
61
+ return snapper.snapTo(snapPts);
62
+ };
63
+
64
+ /**
65
+ * Creates a new snapper acting on the given geometry
66
+ *
67
+ * @param srcGeom
68
+ * the geometry to snap.
69
+ * @constructor
70
+ */
71
+ var GeometrySnapper = function(srcGeom) {
72
+ this.srcGeom = srcGeom;
73
+ };
74
+
75
+ GeometrySnapper.SNAP_PRECISION_FACTOR = 1e-9;
76
+
77
+ /**
78
+ * Estimates the snap tolerance for a Geometry, taking into account its
79
+ * precision model.
80
+ *
81
+ * @param g
82
+ * a Geometry.
83
+ * @return the estimated snap tolerance.
84
+ */
85
+ GeometrySnapper.computeOverlaySnapTolerance = function(g) {
86
+ if (arguments.length === 2) {
87
+ return GeometrySnapper.computeOverlaySnapTolerance2.apply(this, arguments);
88
+ }
89
+
90
+ var snapTolerance = this.computeSizeBasedSnapTolerance(g);
91
+
92
+ /**
93
+ * Overlay is carried out in the precision model of the two inputs. If this
94
+ * precision model is of type FIXED, then the snap tolerance must reflect
95
+ * the precision grid size. Specifically, the snap tolerance should be at
96
+ * least the distance from a corner of a precision grid cell to the centre
97
+ * point of the cell.
98
+ */
99
+ var pm = g.getPrecisionModel();
100
+ if (pm.getType() == PrecisionModel.FIXED) {
101
+ var fixedSnapTol = (1 / pm.getScale()) * 2 / 1.415;
102
+ if (fixedSnapTol > snapTolerance)
103
+ snapTolerance = fixedSnapTol;
104
+ }
105
+ return snapTolerance;
106
+ };
107
+
108
+ GeometrySnapper.computeSizeBasedSnapTolerance = function(g) {
109
+ var env = g.getEnvelopeInternal();
110
+ var minDimension = Math.min(env.getHeight(), env.getWidth());
111
+ var snapTol = minDimension * GeometrySnapper.SNAP_PRECISION_FACTOR;
112
+ return snapTol;
113
+ };
114
+
115
+ GeometrySnapper.computeOverlaySnapTolerance2 = function(g0, g1) {
116
+ return Math.min(this.computeOverlaySnapTolerance(g0), this
117
+ .computeOverlaySnapTolerance(g1));
118
+ };
119
+
120
+ /**
121
+ * Snaps two geometries together with a given tolerance.
122
+ *
123
+ * @param g0
124
+ * a geometry to snap.
125
+ * @param g1
126
+ * a geometry to snap.
127
+ * @param snapTolerance
128
+ * the tolerance to use.
129
+ * @return the snapped geometries.
130
+ */
131
+ GeometrySnapper.snap = function(g0, g1, snapTolerance) {
132
+ var snapGeom = [];
133
+ var snapper0 = new GeometrySnapper(g0);
134
+ snapGeom[0] = snapper0.snapTo(g1, snapTolerance);
135
+
136
+ /**
137
+ * Snap the second geometry to the snapped first geometry (this strategy
138
+ * minimizes the number of possible different points in the result)
139
+ */
140
+ var snapper1 = new GeometrySnapper(g1);
141
+ snapGeom[1] = snapper1.snapTo(snapGeom[0], snapTolerance);
142
+
143
+ return snapGeom;
144
+ };
145
+
146
+ GeometrySnapper.snapToSelf = function(g0, snapTolerance, cleanResult) {
147
+ var snapper0 = new GeometrySnapper(g0);
148
+ return snapper0.snapToSelf(snapTolerance, cleanResult);
149
+ };
150
+
151
+ /**
152
+ * @private
153
+ */
154
+ GeometrySnapper.prototype.srcGeom = null;
155
+
156
+ /**
157
+ * Snaps the vertices in the component {@link LineString}s of the source
158
+ * geometry to the vertices of the given snap geometry.
159
+ *
160
+ * @param snapGeom
161
+ * a geometry to snap the source to.
162
+ * @return a new snapped Geometry.
163
+ */
164
+ GeometrySnapper.prototype.snapTo = function(snapGeom, snapTolerance) {
165
+ var snapPts = this.extractTargetCoordinates(snapGeom);
166
+
167
+ var snapTrans = new SnapTransformer(snapTolerance, snapPts);
168
+ return snapTrans.transform(this.srcGeom);
169
+ };
170
+
171
+ /**
172
+ * Snaps the vertices in the component {@link LineString}s of the source
173
+ * geometry to the vertices of the given snap geometry.
174
+ *
175
+ * @param snapGeom
176
+ * a geometry to snap the source to.
177
+ * @return a new snapped Geometry.
178
+ */
179
+ GeometrySnapper.prototype.snapToSelf = function(snapTolerance, cleanResult) {
180
+ var snapPts = this.extractTargetCoordinates(srcGeom);
181
+
182
+ var snapTrans = new SnapTransformer(snapTolerance, snapPts, true);
183
+ var snappedGeom = snapTrans.transform(srcGeom);
184
+ var result = snappedGeom;
185
+ if (cleanResult && result instanceof Polygonal) {
186
+ // TODO: use better cleaning approach
187
+ result = snappedGeom.buffer(0);
188
+ }
189
+ return result;
190
+ };
191
+
192
+ GeometrySnapper.prototype.extractTargetCoordinates = function(g) {
193
+ // TODO: should do this more efficiently. Use CoordSeq filter to get points,
194
+ // KDTree for uniqueness & queries
195
+ var ptSet = new TreeSet();
196
+ var pts = g.getCoordinates();
197
+ for (var i = 0; i < pts.length; i++) {
198
+ ptSet.add(pts[i]);
199
+ }
200
+ return ptSet.toArray();
201
+ };
202
+
203
+ /**
204
+ * Computes the snap tolerance based on the input geometries.
205
+ *
206
+ * @param ringPts
207
+ * @return
208
+ */
209
+ GeometrySnapper.prototype.computeSnapTolerance = function(ringPts) {
210
+ var minSegLen = this.computeMinimumSegmentLength(ringPts);
211
+ // use a small percentage of this to be safe
212
+ var snapTol = minSegLen / 10;
213
+ return snapTol;
214
+ };
215
+
216
+ GeometrySnapper.prototype.computeMinimumSegmentLength = function(pts) {
217
+ var minSegLen = Number.MAX_VALUE;
218
+ for (var i = 0; i < pts.length - 1; i++) {
219
+ var segLen = pts[i].distance(pts[i + 1]);
220
+ if (segLen < minSegLen)
221
+ minSegLen = segLen;
222
+ }
223
+ return minSegLen;
224
+ };
225
+
226
+ jsts.operation.overlay.snap.GeometrySnapper = GeometrySnapper;
227
+
228
+ })();