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,619 @@
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
+ * Implements the algorithms required to compute the <code>isValid()</code>
9
+ * method for {@link Geometry}s. See the documentation for the various geometry
10
+ * types for a specification of validity.
11
+ *
12
+ * @version 1.7
13
+ * @constructor
14
+ */
15
+
16
+ jsts.operation.valid.IsValidOp = function(parentGeometry) {
17
+ this.parentGeometry = parentGeometry;
18
+ this.isSelfTouchingRingFormingHoleValid = false;
19
+ this.validErr = null;
20
+ };
21
+
22
+ /**
23
+ * Tests whether a {@link Geometry} is valid.
24
+ *
25
+ * @param geom
26
+ * the Geometry to test.
27
+ * @return true if the geometry is valid.
28
+ */
29
+ jsts.operation.valid.IsValidOp.isValid = function(arg) {
30
+ if (arguments[0] instanceof jsts.geom.Coordinate) {
31
+ if (isNaN(arg.x)) {
32
+ return false;
33
+ }
34
+ if (!isFinite(arg.x) && !isNaN(arg.x)) {
35
+ return false;
36
+ }
37
+ if (isNaN(arg.y)) {
38
+ return false;
39
+ }
40
+ if (!isFinite(arg.y) && !isNaN(arg.y)) {
41
+ return false;
42
+ }
43
+ return true;
44
+ } else {
45
+ var isValidOp = new jsts.operation.valid.IsValidOp(arg);
46
+ return isValidOp.isValid();
47
+ }
48
+ };
49
+
50
+ /**
51
+ * Find a point from the list of testCoords that is NOT a node in the edge for
52
+ * the list of searchCoords
53
+ *
54
+ * @return the point found, or <code>null</code> if none found.
55
+ */
56
+ jsts.operation.valid.IsValidOp.findPtNotNode = function(testCoords, searchRing,
57
+ graph) {
58
+ // find edge corresponding to searchRing.
59
+ var searchEdge = graph.findEdge(searchRing);
60
+ // find a point in the testCoords which is not a node of the searchRing
61
+ var eiList = searchEdge.getEdgeIntersectionList();
62
+ // somewhat inefficient - is there a better way? (Use a node map, for
63
+ // instance?)
64
+ for (var i = 0; i < testCoords.length; i++) {
65
+ var pt = testCoords[i];
66
+ if (!eiList.isIntersection(pt)) {
67
+ return pt;
68
+ }
69
+ }
70
+ return null;
71
+ };
72
+
73
+ /**
74
+ * Sets whether polygons using <b>Self-Touching Rings</b> to form holes are
75
+ * reported as valid. If this flag is set, the following Self-Touching
76
+ * conditions are treated as being valid:
77
+ * <ul>
78
+ * <li>the shell ring self-touches to create a hole touching the shell
79
+ * <li>a hole ring self-touches to create two holes touching at a point
80
+ * </ul>
81
+ * <p>
82
+ * The default (following the OGC SFS standard) is that this condition is <b>not</b>
83
+ * valid (<code>false</code>).
84
+ * <p>
85
+ * This does not affect whether Self-Touching Rings disconnecting the polygon
86
+ * interior are considered valid (these are considered to be <b>invalid</b>
87
+ * under the SFS, and many other spatial models as well). This includes
88
+ * "bow-tie" shells, which self-touch at a single point causing the interior to
89
+ * be disconnected, and "C-shaped" holes which self-touch at a single point
90
+ * causing an island to be formed.
91
+ *
92
+ * @param isValid
93
+ * states whether geometry with this condition is valid.
94
+ */
95
+ jsts.operation.valid.IsValidOp.prototype.setSelfTouchingRingFormingHoleValid = function(
96
+ isValid) {
97
+ this.isSelfTouchingRingFormingHoleValid = isValid;
98
+ };
99
+
100
+ jsts.operation.valid.IsValidOp.prototype.isValid = function() {
101
+ this.checkValid(this.parentGeometry);
102
+ return this.validErr == null;
103
+ };
104
+
105
+ jsts.operation.valid.IsValidOp.prototype.getValidationError = function() {
106
+ this.checkValid(this.parentGeometry);
107
+ return this.validErr;
108
+ };
109
+
110
+ jsts.operation.valid.IsValidOp.prototype.checkValid = function(g) {
111
+ this.validErr = null;
112
+
113
+ // empty geometries are always valid!
114
+ if (g.isEmpty()) {
115
+ return;
116
+ }
117
+
118
+ if (g instanceof jsts.geom.Point) {
119
+ this.checkValidPoint(g);
120
+ } else if (g instanceof jsts.geom.MultiPoint) {
121
+ this.checkValidMultiPoint(g);
122
+ // LineString also handles LinearRings
123
+ } else if (g instanceof jsts.geom.LinearRing) {
124
+ this.checkValidLinearRing(g);
125
+ } else if (g instanceof jsts.geom.LineString) {
126
+ this.checkValidLineString(g);
127
+ } else if (g instanceof jsts.geom.Polygon) {
128
+ this.checkValidPolygon(g);
129
+ } else if (g instanceof jsts.geom.MultiPolygon) {
130
+ this.checkValidMultiPolygon(g);
131
+ } else if (g instanceof jsts.geom.GeometryCollection) {
132
+ this.checkValidGeometryCollection(g);
133
+ } else {
134
+ throw g.constructor;
135
+ }
136
+ };
137
+
138
+ /**
139
+ * Checks validity of a Point.
140
+ */
141
+ jsts.operation.valid.IsValidOp.prototype.checkValidPoint = function(g) {
142
+ this.checkInvalidCoordinates(g.getCoordinates());
143
+ };
144
+ /**
145
+ * Checks validity of a MultiPoint.
146
+ */
147
+ jsts.operation.valid.IsValidOp.prototype.checkValidMultiPoint = function(g) {
148
+ this.checkInvalidCoordinates(g.getCoordinates());
149
+ };
150
+
151
+ /**
152
+ * Checks validity of a LineString. Almost anything goes for linestrings!
153
+ */
154
+ jsts.operation.valid.IsValidOp.prototype.checkValidLineString = function(g) {
155
+ this.checkInvalidCoordinates(g.getCoordinates());
156
+ if (this.validErr != null) {
157
+ return;
158
+ }
159
+ var graph = new jsts.geomgraph.GeometryGraph(0, g);
160
+ this.checkTooFewPoints(graph);
161
+ };
162
+ /**
163
+ * Checks validity of a LinearRing.
164
+ */
165
+ jsts.operation.valid.IsValidOp.prototype.checkValidLinearRing = function(g) {
166
+ this.checkInvalidCoordinates(g.getCoordinates());
167
+ if (this.validErr != null) {
168
+ return;
169
+ }
170
+ this.checkClosedRing(g);
171
+ if (this.validErr != null) {
172
+ return;
173
+ }
174
+ var graph = new jsts.geomgraph.GeometryGraph(0, g);
175
+ this.checkTooFewPoints(graph);
176
+ if (this.validErr != null) {
177
+ return;
178
+ }
179
+ var li = new jsts.algorithm.RobustLineIntersector();
180
+ graph.computeSelfNodes(li, true);
181
+ this.checkNoSelfIntersectingRings(graph);
182
+ };
183
+
184
+ /**
185
+ * Checks the validity of a polygon. Sets the validErr flag.
186
+ */
187
+ jsts.operation.valid.IsValidOp.prototype.checkValidPolygon = function(g) {
188
+ this.checkInvalidCoordinates(g);
189
+ if (this.validErr != null) {
190
+ return;
191
+ }
192
+ this.checkClosedRings(g);
193
+ if (this.validErr != null) {
194
+ return;
195
+ }
196
+
197
+ var graph = new jsts.geomgraph.GeometryGraph(0, g);
198
+
199
+ this.checkTooFewPoints(graph);
200
+ if (this.validErr != null) {
201
+ return;
202
+ }
203
+ this.checkConsistentArea(graph);
204
+ if (this.validErr != null) {
205
+ return;
206
+ }
207
+
208
+ if (!this.isSelfTouchingRingFormingHoleValid) {
209
+ this.checkNoSelfIntersectingRings(graph);
210
+ if (this.validErr != null) {
211
+ return;
212
+ }
213
+ }
214
+ this.checkHolesInShell(g, graph);
215
+ if (this.validErr != null) {
216
+ return;
217
+ }
218
+ // SLOWcheckHolesNotNested(g);
219
+ this.checkHolesNotNested(g, graph);
220
+ if (this.validErr != null) {
221
+ return;
222
+ }
223
+ this.checkConnectedInteriors(graph);
224
+ };
225
+
226
+ jsts.operation.valid.IsValidOp.prototype.checkValidMultiPolygon = function(g) {
227
+ var il = g.getNumGeometries();
228
+ for (var i = 0; i < il; i++) {
229
+ var p = g.getGeometryN(i);
230
+ this.checkInvalidCoordinates(p);
231
+ if (this.validErr != null) {
232
+ return;
233
+ }
234
+ this.checkClosedRings(p);
235
+ if (this.validErr != null) {
236
+ return;
237
+ }
238
+ }
239
+ // Add this
240
+ var graph = new jsts.geomgraph.GeometryGraph(0, g);
241
+
242
+ this.checkTooFewPoints(graph);
243
+ if (this.validErr != null) {
244
+ return;
245
+ }
246
+ this.checkConsistentArea(graph);
247
+ if (this.validErr != null) {
248
+ return;
249
+ }
250
+ if (!this.isSelfTouchingRingFormingHoleValid) {
251
+ this.checkNoSelfIntersectingRings(graph);
252
+ if (this.validErr != null) {
253
+ return;
254
+ }
255
+ }
256
+ for (var i = 0; i < g.getNumGeometries(); i++) {
257
+ var p = g.getGeometryN(i);
258
+ this.checkHolesInShell(p, graph);
259
+ if (this.validErr != null) {
260
+ return;
261
+ }
262
+ }
263
+ for (var i = 0; i < g.getNumGeometries(); i++) {
264
+ var p = g.getGeometryN(i);
265
+ this.checkHolesNotNested(p, graph);
266
+ if (this.validErr != null) {
267
+ return;
268
+ }
269
+ }
270
+ this.checkShellsNotNested(g, graph);
271
+ if (this.validErr != null) {
272
+ return;
273
+ }
274
+ this.checkConnectedInteriors(graph);
275
+ };
276
+
277
+ jsts.operation.valid.IsValidOp.prototype.checkValidGeometryCollection = function(
278
+ gc) {
279
+ for (var i = 0; i < gc.getNumGeometries(); i++) {
280
+ var g = gc.getGeometryN(i);
281
+ this.checkValid(g);
282
+ if (this.validErr != null) {
283
+ return;
284
+ }
285
+ }
286
+ };
287
+
288
+ jsts.operation.valid.IsValidOp.prototype.checkInvalidCoordinates = function(
289
+ arg) {
290
+ if (arg instanceof jsts.geom.Polygon) {
291
+ var poly = arg;
292
+ this.checkInvalidCoordinates(poly.getExteriorRing().getCoordinates());
293
+ if (this.validErr != null) {
294
+ return;
295
+ }
296
+ for (var i = 0; i < poly.getNumInteriorRing(); i++) {
297
+ this.checkInvalidCoordinates(poly.getInteriorRingN(i).getCoordinates());
298
+ if (this.validErr != null) {
299
+ return;
300
+ }
301
+ }
302
+ } else {
303
+ var coords = arg;
304
+ for (var i = 0; i < coords.length; i++) {
305
+ if (!jsts.operation.valid.IsValidOp.isValid(coords[i])) {
306
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
307
+ jsts.operation.valid.TopologyValidationError.INVALID_COORDINATE,
308
+ coords[i]);
309
+ return;
310
+ }
311
+ }
312
+ }
313
+ };
314
+
315
+ jsts.operation.valid.IsValidOp.prototype.checkClosedRings = function(poly) {
316
+ // checkClosedRing((LinearRing) poly.getExteriorRing());
317
+ this.checkClosedRing(poly.getExteriorRing());
318
+ if (this.validErr != null) {
319
+ return;
320
+ }
321
+ for (var i = 0; i < poly.getNumInteriorRing(); i++) {
322
+ // checkClosedRing((LinearRing) poly.getInteriorRingN(i));
323
+ this.checkClosedRing(poly.getInteriorRingN(i));
324
+ if (this.validErr != null) {
325
+ return;
326
+ }
327
+ }
328
+ };
329
+
330
+ jsts.operation.valid.IsValidOp.prototype.checkClosedRing = function(ring) {
331
+ if (!ring.isClosed()) {
332
+ var pt = null;
333
+ if (ring.getNumPoints() >= 1) {
334
+ pt = ring.getCoordinateN(0);
335
+ }
336
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
337
+ jsts.operation.valid.TopologyValidationError.RING_NOT_CLOSED, pt);
338
+ }
339
+ };
340
+
341
+ jsts.operation.valid.IsValidOp.prototype.checkTooFewPoints = function(graph) {
342
+ if (graph.hasTooFewPoints) {
343
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
344
+ jsts.operation.valid.TopologyValidationError.TOO_FEW_POINTS, graph
345
+ .getInvalidPoint());
346
+ return;
347
+ }
348
+ };
349
+
350
+ /**
351
+ * Checks that the arrangement of edges in a polygonal geometry graph forms a
352
+ * consistent area.
353
+ *
354
+ * @param graph
355
+ *
356
+ * @see ConsistentAreaTester
357
+ */
358
+ jsts.operation.valid.IsValidOp.prototype.checkConsistentArea = function(graph) {
359
+ var cat = new jsts.operation.valid.ConsistentAreaTester(graph);
360
+ var isValidArea = cat.isNodeConsistentArea();
361
+ if (!isValidArea) {
362
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
363
+ jsts.operation.valid.TopologyValidationError.SELF_INTERSECTION, cat
364
+ .getInvalidPoint());
365
+ return;
366
+ }
367
+ if (cat.hasDuplicateRings()) {
368
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
369
+ jsts.operation.valid.TopologyValidationError.DUPLICATE_RINGS, cat
370
+ .getInvalidPoint());
371
+ }
372
+ };
373
+
374
+ /**
375
+ * Check that there is no ring which self-intersects (except of course at its
376
+ * endpoints). This is required by OGC topology rules (but not by other models
377
+ * such as ESRI SDE, which allow inverted shells and exverted holes).
378
+ *
379
+ * @param graph
380
+ * the topology graph of the geometry.
381
+ */
382
+ jsts.operation.valid.IsValidOp.prototype.checkNoSelfIntersectingRings = function(
383
+ graph) {
384
+ for (var i = graph.getEdgeIterator(); i.hasNext();) {
385
+ var e = i.next();
386
+ this.checkNoSelfIntersectingRing(e.getEdgeIntersectionList());
387
+ if (this.validErr != null) {
388
+ return;
389
+ }
390
+ }
391
+ };
392
+
393
+ /**
394
+ * Check that a ring does not self-intersect, except at its endpoints. Algorithm
395
+ * is to count the number of times each node along edge occurs. If any occur
396
+ * more than once, that must be a self-intersection.
397
+ */
398
+ jsts.operation.valid.IsValidOp.prototype.checkNoSelfIntersectingRing = function(
399
+ eiList) {
400
+ var nodeSet = [];
401
+ var isFirst = true;
402
+ for (var i = eiList.iterator(); i.hasNext();) {
403
+ var ei = i.next();
404
+ if (isFirst) {
405
+ isFirst = false;
406
+ continue;
407
+ }
408
+ if (nodeSet.indexOf(ei.coord) >= 0) {
409
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
410
+ jsts.operation.valid.TopologyValidationError.RING_SELF_INTERSECTION,
411
+ ei.coord);
412
+ return;
413
+ } else {
414
+ nodeSet.push(ei.coord);
415
+ }
416
+ }
417
+ };
418
+
419
+ /**
420
+ * Tests that each hole is inside the polygon shell. This routine assumes that
421
+ * the holes have previously been tested to ensure that all vertices lie on the
422
+ * shell oon the same side of it (i.e that the hole rings do not cross the shell
423
+ * ring). In other words, this test is only correct if the ConsistentArea test
424
+ * is passed first. Given this, a simple point-in-polygon test of a single point
425
+ * in the hole can be used, provided the point is chosen such that it does not
426
+ * lie on the shell.
427
+ *
428
+ * @param p
429
+ * the polygon to be tested for hole inclusion.
430
+ * @param graph
431
+ * a GeometryGraph incorporating the polygon.
432
+ */
433
+ jsts.operation.valid.IsValidOp.prototype.checkHolesInShell = function(p, graph) {
434
+ var shell = p.getExteriorRing();
435
+
436
+ // PointInRing pir = new SimplePointInRing(shell);
437
+ // PointInRing pir = new SIRtreePointInRing(shell);
438
+
439
+ var pir = new jsts.algorithm.MCPointInRing(shell);
440
+
441
+ for (var i = 0; i < p.getNumInteriorRing(); i++) {
442
+
443
+ var hole = p.getInteriorRingN(i); // Cast?
444
+ var holePt = jsts.operation.valid.IsValidOp.findPtNotNode(hole.getCoordinates(), shell, graph);
445
+ /**
446
+ * If no non-node hole vertex can be found, the hole must split the polygon
447
+ * into disconnected interiors. This will be caught by a subsequent check.
448
+ */
449
+ if (holePt == null) {
450
+ return;
451
+ }
452
+
453
+ var outside = !pir.isInside(holePt);
454
+ if (outside) {
455
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
456
+ jsts.operation.valid.TopologyValidationError.HOLE_OUTSIDE_SHELL,
457
+ holePt);
458
+ return;
459
+ }
460
+ }
461
+ };
462
+
463
+ /**
464
+ * Tests that no hole is nested inside another hole. This routine assumes that
465
+ * the holes are disjoint. To ensure this, holes have previously been tested to
466
+ * ensure that:
467
+ * <ul>
468
+ * <li>they do not partially overlap (checked by
469
+ * <code>checkRelateConsistency</code>)
470
+ * <li>they are not identical (checked by <code>checkRelateConsistency</code>)
471
+ * </ul>
472
+ */
473
+ jsts.operation.valid.IsValidOp.prototype.checkHolesNotNested = function(p,
474
+ graph) {
475
+ var nestedTester = new jsts.operation.valid.IndexedNestedRingTester(graph);
476
+ // SimpleNestedRingTester nestedTester = new SimpleNestedRingTester(arg[0]);
477
+ // SweeplineNestedRingTester nestedTester = new
478
+ // SweeplineNestedRingTester(arg[0]);
479
+
480
+ for (var i = 0; i < p.getNumInteriorRing(); i++) {
481
+ var innerHole = p.getInteriorRingN(i);
482
+ nestedTester.add(innerHole);
483
+ }
484
+ var isNonNested = nestedTester.isNonNested();
485
+ if (!isNonNested) {
486
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
487
+ jsts.operation.valid.TopologyValidationError.NESTED_HOLES, nestedTester
488
+ .getNestedPoint());
489
+ }
490
+ };
491
+
492
+ /**
493
+ * Tests that no element polygon is wholly in the interior of another element
494
+ * polygon.
495
+ * <p>
496
+ * Preconditions:
497
+ * <ul>
498
+ * <li>shells do not partially overlap
499
+ * <li>shells do not touch along an edge
500
+ * <li>no duplicate rings exist
501
+ * </ul>
502
+ * This routine relies on the fact that while polygon shells may touch at one or
503
+ * more vertices, they cannot touch at ALL vertices.
504
+ */
505
+ jsts.operation.valid.IsValidOp.prototype.checkShellsNotNested = function(mp,
506
+ graph) {
507
+ for (var i = 0; i < mp.getNumGeometries(); i++) {
508
+ var p = mp.getGeometryN(i);
509
+ var shell = p.getExteriorRing();
510
+ for (var j = 0; j < mp.getNumGeometries(); j++) {
511
+ if (i == j) {
512
+ continue;
513
+ }
514
+ var p2 = mp.getGeometryN(j);
515
+ this.checkShellNotNested(shell, p2, graph);
516
+ if (this.validErr != null) {
517
+ return;
518
+ }
519
+ }
520
+ }
521
+ };
522
+
523
+ /**
524
+ * Check if a shell is incorrectly nested within a polygon. This is the case if
525
+ * the shell is inside the polygon shell, but not inside a polygon hole. (If the
526
+ * shell is inside a polygon hole, the nesting is valid.)
527
+ * <p>
528
+ * The algorithm used relies on the fact that the rings must be properly
529
+ * contained. E.g. they cannot partially overlap (this has been previously
530
+ * checked by <code>checkRelateConsistency</code> )
531
+ */
532
+ jsts.operation.valid.IsValidOp.prototype.checkShellNotNested = function(shell,
533
+ p, graph) {
534
+ var shellPts = shell.getCoordinates();
535
+ // test if shell is inside polygon shell
536
+ var polyShell = p.getExteriorRing();
537
+ var polyPts = polyShell.getCoordinates();
538
+ var shellPt = jsts.operation.valid.IsValidOp.findPtNotNode(shellPts, polyShell, graph);
539
+ // if no point could be found, we can assume that the shell is outside the
540
+ // polygon
541
+ if (shellPt == null) {
542
+ return;
543
+ }
544
+ var insidePolyShell = jsts.algorithm.CGAlgorithms.isPointInRing(shellPt, polyPts);
545
+ if (!insidePolyShell) {
546
+ return;
547
+ }
548
+
549
+ // if no holes, this is an error!
550
+ if (p.getNumInteriorRing() <= 0) {
551
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
552
+ jsts.operation.valid.TopologyValidationError.NESTED_SHELLS, shellPt);
553
+ return;
554
+ }
555
+
556
+ /**
557
+ * Check if the shell is inside one of the holes. This is the case if one of
558
+ * the calls to checkShellInsideHole returns a null coordinate. Otherwise, the
559
+ * shell is not properly contained in a hole, which is an error.
560
+ */
561
+ var badNestedPt = null;
562
+ for (var i = 0; i < p.getNumInteriorRing(); i++) {
563
+ var hole = p.getInteriorRingN(i);
564
+ badNestedPt = this.checkShellInsideHole(shell, hole, graph);
565
+ if (badNestedPt == null) {
566
+ return;
567
+ }
568
+ }
569
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
570
+ jsts.operation.valid.TopologyValidationError.NESTED_SHELLS, badNestedPt);
571
+ };
572
+
573
+ /**
574
+ * This routine checks to see if a shell is properly contained in a hole. It
575
+ * assumes that the edges of the shell and hole do not properly intersect.
576
+ *
577
+ * @return <code>null</code> if the shell is properly contained, or a
578
+ * Coordinate which is not inside the hole if it is not.
579
+ *
580
+ */
581
+ jsts.operation.valid.IsValidOp.prototype.checkShellInsideHole = function(shell,
582
+ hole, graph) {
583
+ var shellPts = shell.getCoordinates();
584
+ var holePts = hole.getCoordinates();
585
+ // TODO: improve performance of this - by sorting pointlists for instance?
586
+ var shellPt = jsts.operation.valid.IsValidOp.findPtNotNode(shellPts, hole, graph);
587
+ // if point is on shell but not hole, check that the shell is inside the
588
+ // hole
589
+ if (shellPt != null) {
590
+ var insideHole = jsts.algorithm.CGAlgorithms.isPointInRing(shellPt, holePts);
591
+ if (!insideHole) {
592
+ return shellPt;
593
+ }
594
+ }
595
+ var holePt = jsts.operation.valid.IsValidOp.findPtNotNode(holePts, shell, graph);
596
+ // if point is on hole but not shell, check that the hole is outside the
597
+ // shell
598
+ if (holePt != null) {
599
+ var insideShell = jsts.algorithm.CGAlgorithms.isPointInRing(holePt, shellPts);
600
+ if (insideShell) {
601
+ return holePt;
602
+ }
603
+ return null;
604
+ }
605
+ jsts.util.Assert
606
+ .shouldNeverReachHere('points in shell and hole appear to be equal');
607
+ return null;
608
+ };
609
+
610
+ jsts.operation.valid.IsValidOp.prototype.checkConnectedInteriors = function(
611
+ graph) {
612
+ var cit = new jsts.operation.valid.ConnectedInteriorTester(graph);
613
+ if (!cit.isInteriorsConnected()) {
614
+ this.validErr = new jsts.operation.valid.TopologyValidationError(
615
+ jsts.operation.valid.TopologyValidationError.DISCONNECTED_INTERIOR, cit
616
+ .getCoordinate());
617
+ }
618
+
619
+ };