rgeo-dschee 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +29 -0
  3. data/ext/geos_c_impl/coordinates.c +65 -0
  4. data/ext/geos_c_impl/coordinates.h +2 -0
  5. data/ext/geos_c_impl/extconf.rb +43 -0
  6. data/ext/geos_c_impl/factory.c +995 -0
  7. data/ext/geos_c_impl/factory.h +238 -0
  8. data/ext/geos_c_impl/geometry.c +1093 -0
  9. data/ext/geos_c_impl/geometry.h +23 -0
  10. data/ext/geos_c_impl/geometry_collection.c +757 -0
  11. data/ext/geos_c_impl/geometry_collection.h +46 -0
  12. data/ext/geos_c_impl/line_string.c +675 -0
  13. data/ext/geos_c_impl/line_string.h +32 -0
  14. data/ext/geos_c_impl/main.c +40 -0
  15. data/ext/geos_c_impl/point.c +236 -0
  16. data/ext/geos_c_impl/point.h +30 -0
  17. data/ext/geos_c_impl/polygon.c +359 -0
  18. data/ext/geos_c_impl/polygon.h +43 -0
  19. data/ext/geos_c_impl/preface.h +38 -0
  20. data/ext/proj4_c_impl/extconf.rb +62 -0
  21. data/ext/proj4_c_impl/main.c +315 -0
  22. data/lib/rgeo.rb +89 -0
  23. data/lib/rgeo/cartesian.rb +25 -0
  24. data/lib/rgeo/cartesian/analysis.rb +77 -0
  25. data/lib/rgeo/cartesian/bounding_box.rb +398 -0
  26. data/lib/rgeo/cartesian/calculations.rb +113 -0
  27. data/lib/rgeo/cartesian/factory.rb +347 -0
  28. data/lib/rgeo/cartesian/feature_classes.rb +100 -0
  29. data/lib/rgeo/cartesian/feature_methods.rb +88 -0
  30. data/lib/rgeo/cartesian/interface.rb +135 -0
  31. data/lib/rgeo/coord_sys.rb +43 -0
  32. data/lib/rgeo/coord_sys/cs/entities.rb +1315 -0
  33. data/lib/rgeo/coord_sys/cs/factories.rb +148 -0
  34. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +272 -0
  35. data/lib/rgeo/coord_sys/proj4.rb +293 -0
  36. data/lib/rgeo/coord_sys/srs_database/interface.rb +115 -0
  37. data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +140 -0
  38. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +62 -0
  39. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +63 -0
  40. data/lib/rgeo/error.rb +27 -0
  41. data/lib/rgeo/feature.rb +54 -0
  42. data/lib/rgeo/feature/curve.rb +111 -0
  43. data/lib/rgeo/feature/factory.rb +278 -0
  44. data/lib/rgeo/feature/factory_generator.rb +96 -0
  45. data/lib/rgeo/feature/geometry.rb +624 -0
  46. data/lib/rgeo/feature/geometry_collection.rb +95 -0
  47. data/lib/rgeo/feature/line.rb +26 -0
  48. data/lib/rgeo/feature/line_string.rb +60 -0
  49. data/lib/rgeo/feature/linear_ring.rb +26 -0
  50. data/lib/rgeo/feature/mixins.rb +143 -0
  51. data/lib/rgeo/feature/multi_curve.rb +71 -0
  52. data/lib/rgeo/feature/multi_line_string.rb +26 -0
  53. data/lib/rgeo/feature/multi_point.rb +33 -0
  54. data/lib/rgeo/feature/multi_polygon.rb +57 -0
  55. data/lib/rgeo/feature/multi_surface.rb +73 -0
  56. data/lib/rgeo/feature/point.rb +84 -0
  57. data/lib/rgeo/feature/polygon.rb +97 -0
  58. data/lib/rgeo/feature/surface.rb +79 -0
  59. data/lib/rgeo/feature/types.rb +284 -0
  60. data/lib/rgeo/geographic.rb +40 -0
  61. data/lib/rgeo/geographic/factory.rb +450 -0
  62. data/lib/rgeo/geographic/interface.rb +489 -0
  63. data/lib/rgeo/geographic/proj4_projector.rb +58 -0
  64. data/lib/rgeo/geographic/projected_feature_classes.rb +107 -0
  65. data/lib/rgeo/geographic/projected_feature_methods.rb +212 -0
  66. data/lib/rgeo/geographic/projected_window.rb +383 -0
  67. data/lib/rgeo/geographic/simple_mercator_projector.rb +110 -0
  68. data/lib/rgeo/geographic/spherical_feature_classes.rb +100 -0
  69. data/lib/rgeo/geographic/spherical_feature_methods.rb +134 -0
  70. data/lib/rgeo/geographic/spherical_math.rb +188 -0
  71. data/lib/rgeo/geos.rb +89 -0
  72. data/lib/rgeo/geos/capi_factory.rb +470 -0
  73. data/lib/rgeo/geos/capi_feature_classes.rb +129 -0
  74. data/lib/rgeo/geos/ffi_factory.rb +592 -0
  75. data/lib/rgeo/geos/ffi_feature_classes.rb +83 -0
  76. data/lib/rgeo/geos/ffi_feature_methods.rb +574 -0
  77. data/lib/rgeo/geos/interface.rb +202 -0
  78. data/lib/rgeo/geos/utils.rb +74 -0
  79. data/lib/rgeo/geos/zm_factory.rb +405 -0
  80. data/lib/rgeo/geos/zm_feature_classes.rb +80 -0
  81. data/lib/rgeo/geos/zm_feature_methods.rb +344 -0
  82. data/lib/rgeo/impl_helper.rb +19 -0
  83. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +185 -0
  84. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +61 -0
  85. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +146 -0
  86. data/lib/rgeo/impl_helper/basic_point_methods.rb +104 -0
  87. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +87 -0
  88. data/lib/rgeo/impl_helper/math.rb +14 -0
  89. data/lib/rgeo/impl_helper/utils.rb +29 -0
  90. data/lib/rgeo/version.rb +3 -0
  91. data/lib/rgeo/wkrep.rb +37 -0
  92. data/lib/rgeo/wkrep/wkb_generator.rb +201 -0
  93. data/lib/rgeo/wkrep/wkb_parser.rb +251 -0
  94. data/lib/rgeo/wkrep/wkt_generator.rb +207 -0
  95. data/lib/rgeo/wkrep/wkt_parser.rb +415 -0
  96. data/lib/rgeo/yaml.rb +23 -0
  97. data/test/cartesian_analysis_test.rb +65 -0
  98. data/test/cartesian_bbox_test.rb +123 -0
  99. data/test/common/factory_tests.rb +78 -0
  100. data/test/common/geometry_collection_tests.rb +237 -0
  101. data/test/common/line_string_tests.rb +330 -0
  102. data/test/common/multi_line_string_tests.rb +182 -0
  103. data/test/common/multi_point_tests.rb +200 -0
  104. data/test/common/multi_polygon_tests.rb +191 -0
  105. data/test/common/point_tests.rb +370 -0
  106. data/test/common/polygon_tests.rb +261 -0
  107. data/test/coord_sys/ogc_cs_test.rb +342 -0
  108. data/test/coord_sys/proj4_srs_data_test.rb +41 -0
  109. data/test/coord_sys/proj4_test.rb +150 -0
  110. data/test/coord_sys/sr_org_test.rb +32 -0
  111. data/test/coord_sys/url_reader_test.rb +42 -0
  112. data/test/geos_capi/factory_test.rb +31 -0
  113. data/test/geos_capi/geometry_collection_test.rb +24 -0
  114. data/test/geos_capi/line_string_test.rb +24 -0
  115. data/test/geos_capi/misc_test.rb +116 -0
  116. data/test/geos_capi/multi_line_string_test.rb +24 -0
  117. data/test/geos_capi/multi_point_test.rb +24 -0
  118. data/test/geos_capi/multi_polygon_test.rb +39 -0
  119. data/test/geos_capi/parsing_unparsing_test.rb +40 -0
  120. data/test/geos_capi/point_test.rb +72 -0
  121. data/test/geos_capi/polygon_test.rb +154 -0
  122. data/test/geos_capi/zmfactory_test.rb +57 -0
  123. data/test/geos_ffi/factory_test.rb +31 -0
  124. data/test/geos_ffi/geometry_collection_test.rb +24 -0
  125. data/test/geos_ffi/line_string_test.rb +24 -0
  126. data/test/geos_ffi/misc_test.rb +63 -0
  127. data/test/geos_ffi/multi_line_string_test.rb +24 -0
  128. data/test/geos_ffi/multi_point_test.rb +24 -0
  129. data/test/geos_ffi/multi_polygon_test.rb +33 -0
  130. data/test/geos_ffi/parsing_unparsing_test.rb +41 -0
  131. data/test/geos_ffi/point_test.rb +77 -0
  132. data/test/geos_ffi/polygon_test.rb +46 -0
  133. data/test/geos_ffi/zmfactory_test.rb +58 -0
  134. data/test/mixins_test.rb +141 -0
  135. data/test/oneoff_test.rb +26 -0
  136. data/test/projected_geographic/factory_test.rb +25 -0
  137. data/test/projected_geographic/geometry_collection_test.rb +24 -0
  138. data/test/projected_geographic/line_string_test.rb +24 -0
  139. data/test/projected_geographic/multi_line_string_test.rb +26 -0
  140. data/test/projected_geographic/multi_point_test.rb +30 -0
  141. data/test/projected_geographic/multi_polygon_test.rb +25 -0
  142. data/test/projected_geographic/point_test.rb +51 -0
  143. data/test/projected_geographic/polygon_test.rb +24 -0
  144. data/test/simple_cartesian/calculations_test.rb +99 -0
  145. data/test/simple_cartesian/factory_test.rb +27 -0
  146. data/test/simple_cartesian/geometry_collection_test.rb +30 -0
  147. data/test/simple_cartesian/line_string_test.rb +31 -0
  148. data/test/simple_cartesian/multi_line_string_test.rb +28 -0
  149. data/test/simple_cartesian/multi_point_test.rb +31 -0
  150. data/test/simple_cartesian/multi_polygon_test.rb +31 -0
  151. data/test/simple_cartesian/point_test.rb +50 -0
  152. data/test/simple_cartesian/polygon_test.rb +28 -0
  153. data/test/simple_mercator/factory_test.rb +25 -0
  154. data/test/simple_mercator/geometry_collection_test.rb +24 -0
  155. data/test/simple_mercator/line_string_test.rb +24 -0
  156. data/test/simple_mercator/multi_line_string_test.rb +26 -0
  157. data/test/simple_mercator/multi_point_test.rb +29 -0
  158. data/test/simple_mercator/multi_polygon_test.rb +25 -0
  159. data/test/simple_mercator/point_test.rb +55 -0
  160. data/test/simple_mercator/polygon_test.rb +24 -0
  161. data/test/simple_mercator/window_test.rb +173 -0
  162. data/test/spherical_geographic/calculations_test.rb +167 -0
  163. data/test/spherical_geographic/factory_test.rb +27 -0
  164. data/test/spherical_geographic/geometry_collection_test.rb +31 -0
  165. data/test/spherical_geographic/line_string_test.rb +31 -0
  166. data/test/spherical_geographic/multi_line_string_test.rb +29 -0
  167. data/test/spherical_geographic/multi_point_test.rb +31 -0
  168. data/test/spherical_geographic/multi_polygon_test.rb +31 -0
  169. data/test/spherical_geographic/point_test.rb +78 -0
  170. data/test/spherical_geographic/polygon_test.rb +28 -0
  171. data/test/types_test.rb +42 -0
  172. data/test/wkrep/wkb_generator_test.rb +185 -0
  173. data/test/wkrep/wkb_parser_test.rb +293 -0
  174. data/test/wkrep/wkt_generator_test.rb +294 -0
  175. data/test/wkrep/wkt_parser_test.rb +412 -0
  176. metadata +386 -0
@@ -0,0 +1,33 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # MultiPoint feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Feature
9
+ # == SFS 1.1 Description
10
+ #
11
+ # A MultiPoint is a 0-dimensional GeometryCollection. The elements of
12
+ # a MultiPoint are restricted to Points. The Points are not connected
13
+ # or ordered.
14
+ #
15
+ # A MultiPoint is simple if no two Points in the MultiPoint are equal
16
+ # (have identical coordinate values).
17
+ #
18
+ # The boundary of a MultiPoint is the empty set.
19
+ #
20
+ # == Notes
21
+ #
22
+ # MultiPoint is defined as a module and is provided primarily
23
+ # for the sake of documentation. Implementations need not necessarily
24
+ # include this module itself. Therefore, you should not depend on the
25
+ # kind_of? method to check type. Instead, use the provided check_type
26
+ # class method (or === operator) defined in the Type module.
27
+
28
+ module MultiPoint
29
+ include GeometryCollection
30
+ extend Type
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # MultiPolygon feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Feature
9
+ # == SFS 1.1 Description
10
+ #
11
+ # A MultiPolygon is a MultiSurface whose elements are Polygons.
12
+ #
13
+ # The assertions for MultiPolygons are as follows.
14
+ #
15
+ # a) The interiors of 2 Polygons that are elements of a MultiPolygon
16
+ # may not intersect.
17
+ #
18
+ # b) The boundaries of any 2 Polygons that are elements of a
19
+ # MultiPolygon may not "cross" and may touch at only a finite number
20
+ # of Points. NOTE: Crossing is prevented by assertion (a) above.
21
+ #
22
+ # c) A MultiPolygon is defined as topologically closed.
23
+ #
24
+ # d) A MultiPolygon may not have cut lines, spikes or punctures, a
25
+ # MultiPolygon is a regular closed Point set:
26
+ #
27
+ # e) The interior of a MultiPolygon with more than 1 Polygon is not
28
+ # connected, the number of connected components of the interior of a
29
+ # MultiPolygon is equal to the number of Polygons in the MultiPolygon.
30
+ #
31
+ # The boundary of a MultiPolygon is a set of closed Curves
32
+ # (LineStrings) corresponding to the boundaries of its element
33
+ # Polygons. Each Curve in the boundary of the MultiPolygon is in the
34
+ # boundary of exactly 1 element Polygon, and every Curve in the
35
+ # boundary of an element Polygon is in the boundary of the
36
+ # MultiPolygon.
37
+ #
38
+ # NOTE: The subclass of Surface named Polyhedral Surface is a faceted
39
+ # Surface whose facets are Polygons. A Polyhedral Surface is not a
40
+ # MultiPolygon because it violates the rule for MultiPolygons that the
41
+ # boundaries of the element Polygons intersect only at a finite number
42
+ # of Points.
43
+ #
44
+ # == Notes
45
+ #
46
+ # MultiPolygon is defined as a module and is provided primarily
47
+ # for the sake of documentation. Implementations need not necessarily
48
+ # include this module itself. Therefore, you should not depend on the
49
+ # kind_of? method to check type. Instead, use the provided check_type
50
+ # class method (or === operator) defined in the Type module.
51
+
52
+ module MultiPolygon
53
+ include MultiSurface
54
+ extend Type
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,73 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # MultiSurface feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Feature
9
+ # == SFS 1.1 Description
10
+ #
11
+ # A MultiSurface is a 2-dimensional GeometryCollection whose elements
12
+ # are Surfaces. The interiors of any two Surfaces in a MultiSurface may
13
+ # not intersect. The boundaries of any two elements in a MultiSurface
14
+ # may intersect, at most, at a finite number of Points.
15
+ #
16
+ # MultiSurface is a non-instantiable class in this International
17
+ # Standard. It defines a set of methods for its subclasses and is
18
+ # included for reasons of extensibility. The instantiable subclass of
19
+ # MultiSurface is MultiPolygon, corresponding to a collection of
20
+ # Polygons.
21
+ #
22
+ # == Notes
23
+ #
24
+ # MultiSurface is defined as a module and is provided primarily
25
+ # for the sake of documentation. Implementations need not necessarily
26
+ # include this module itself. Therefore, you should not depend on the
27
+ # kind_of? method to check type. Instead, use the provided check_type
28
+ # class method (or === operator) defined in the Type module.
29
+
30
+ module MultiSurface
31
+ include GeometryCollection
32
+ extend Type
33
+
34
+ # === SFS 1.1 Description
35
+ #
36
+ # The area of this MultiSurface, as measured in the spatial reference
37
+ # system of this MultiSurface.
38
+ #
39
+ # === Notes
40
+ #
41
+ # Returns a floating-point scalar value.
42
+
43
+ def area
44
+ raise Error::UnsupportedOperation, "Method MultiSurface#area not defined."
45
+ end
46
+
47
+ # === SFS 1.1 Description
48
+ #
49
+ # The mathematical centroid for this MultiSurface as a Point. The
50
+ # result is not guaranteed to be on this MultiSurface.
51
+ #
52
+ # === Notes
53
+ #
54
+ # Returns an object that supports the Point interface.
55
+
56
+ def centroid
57
+ raise Error::UnsupportedOperation, "Method MultiSurface#centroid not defined."
58
+ end
59
+
60
+ # === SFS 1.1 Description
61
+ #
62
+ # A Point guaranteed to be on this MultiSurface.
63
+ #
64
+ # === Notes
65
+ #
66
+ # Returns an object that supports the Point interface.
67
+
68
+ def point_on_surface
69
+ raise Error::UnsupportedOperation, "Method MultiSurface#point_on_surface not defined."
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,84 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Point feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Feature
9
+ # == SFS 1.1 Description
10
+ #
11
+ # A Point is a 0-dimensional geometric object and represents a single
12
+ # location in coordinate space. A Point has an x-coordinate value and
13
+ # a y-coordinate value.
14
+ #
15
+ # The boundary of a Point is the empty set.
16
+ #
17
+ # == Notes
18
+ #
19
+ # Point is defined as a module and is provided primarily
20
+ # for the sake of documentation. Implementations need not necessarily
21
+ # include this module itself. Therefore, you should not depend on the
22
+ # kind_of? method to check type. Instead, use the provided check_type
23
+ # class method (or === operator) defined in the Type module.
24
+ #
25
+ # Some implementations may support higher dimensional points.
26
+ #
27
+ # Some libraries, such as GEOS, support "empty" points. Such objects
28
+ # might be returned as, for example, the centroid of an empty
29
+ # MultiPolygon. The SFS does not clearly define or even acknowledge
30
+ # the existence of such a type, so RGeo will currently generally
31
+ # replace them with empty GeometryCollection objects. Therefore,
32
+ # currently, every RGeo Point object represents an actual location
33
+ # with real coordinates.
34
+
35
+ module Point
36
+ include Geometry
37
+ extend Type
38
+
39
+ # === SFS 1.1 Description
40
+ #
41
+ # The x-coordinate value for this Point.
42
+ #
43
+ # === Notes
44
+ #
45
+ # Returns a floating-point scalar value.
46
+
47
+ def x
48
+ raise Error::UnsupportedOperation, "Method Point#x not defined."
49
+ end
50
+
51
+ # === SFS 1.1 Description
52
+ #
53
+ # The y-coordinate value for this Point.
54
+ #
55
+ # === Notes
56
+ #
57
+ # Returns a floating-point scalar value.
58
+
59
+ def y
60
+ raise Error::UnsupportedOperation, "Method Point#y not defined."
61
+ end
62
+
63
+ # Returns the z-coordinate for this Point as a floating-point
64
+ # scalar value.
65
+ #
66
+ # This method may not be available if the point's factory does
67
+ # not support Z coordinates.
68
+
69
+ def z
70
+ raise Error::UnsupportedOperation, "Method Point#z not defined."
71
+ end
72
+
73
+ # Returns the m-coordinate for this Point as a floating-point
74
+ # scalar value.
75
+ #
76
+ # This method may not be available if the point's factory does
77
+ # not support M coordinates.
78
+
79
+ def m
80
+ raise Error::UnsupportedOperation, "Method Point#m not defined."
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,97 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Polygon feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Feature
9
+ # == SFS 1.1 Description
10
+ #
11
+ # A Polygon is a planar Surface defined by 1 exterior boundary and 0 or
12
+ # more interior boundaries. Each interior boundary defines a hole in
13
+ # the Polygon.
14
+ #
15
+ # The assertions for Polygons (the rules that define valid Polygons)
16
+ # are as follows:
17
+ #
18
+ # (a) Polygons are topologically closed;
19
+ #
20
+ # (b) The boundary of a Polygon consists of a set of LinearRings that
21
+ # make up its exterior and interior boundaries;
22
+ #
23
+ # (c) No two Rings in the boundary cross and the Rings in the boundary
24
+ # of a Polygon may intersect at a Point but only as a tangent;
25
+ #
26
+ # (d) A Polygon may not have cut lines, spikes or punctures;
27
+ #
28
+ # (e) The interior of every Polygon is a connected point set;
29
+ #
30
+ # (f) The exterior of a Polygon with 1 or more holes is not connected.
31
+ # Each hole defines a connected component of the exterior.
32
+ #
33
+ # In the above assertions, interior, closure and exterior have the
34
+ # standard topological definitions. The combination of (a) and (c) make
35
+ # a Polygon a regular closed Point set.
36
+ #
37
+ # Polygons are simple geometric objects.
38
+ #
39
+ # == Notes
40
+ #
41
+ # Polygon is defined as a module and is provided primarily
42
+ # for the sake of documentation. Implementations need not necessarily
43
+ # include this module itself. Therefore, you should not depend on the
44
+ # kind_of? method to check type. Instead, use the provided check_type
45
+ # class method (or === operator) defined in the Type module.
46
+
47
+ module Polygon
48
+ include Surface
49
+ extend Type
50
+
51
+ # === SFS 1.1 Description
52
+ #
53
+ # Returns the exterior ring of this Polygon.
54
+ #
55
+ # === Notes
56
+ #
57
+ # Returns an object that supports the LinearRing interface.
58
+
59
+ def exterior_ring
60
+ raise Error::UnsupportedOperation, "Method Polygon#exterior_ring not defined."
61
+ end
62
+
63
+ # === SFS 1.1 Description
64
+ #
65
+ # Returns the number of interiorRings in this Polygon.
66
+ #
67
+ # === Notes
68
+ #
69
+ # Returns an integer.
70
+
71
+ def num_interior_rings
72
+ raise Error::UnsupportedOperation, "Method Polygon#num_interior_rings not defined."
73
+ end
74
+
75
+ # === SFS 1.1 Description
76
+ #
77
+ # Returns the Nth interiorRing for this Polygon as a LineString.
78
+ #
79
+ # === Notes
80
+ #
81
+ # Returns an object that supports the LinearRing interface, or nil
82
+ # if the given N is out of range. N is zero-based.
83
+ # Does not support negative indexes.
84
+
85
+ def interior_ring_n(_n_)
86
+ raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined."
87
+ end
88
+
89
+ # Returns the interior rings as a (possibly empty) array of objects
90
+ # that support the LinearRing interface.
91
+
92
+ def interior_rings
93
+ raise Error::UnsupportedOperation, "Method Polygon#interior_rings not defined."
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,79 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Surface feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Feature
9
+ # == SFS 1.1 Description
10
+ #
11
+ # A Surface is a 2-dimensional geometric object.
12
+ #
13
+ # A simple Surface consists of a single "patch" that is associated with
14
+ # one "exterior boundary" and 0 or more "interior" boundaries. Simple
15
+ # Surfaces in 3-dimensional space are isomorphic to planar Surfaces.
16
+ # Polyhedral Surfaces are formed by "stitching" together simple
17
+ # Surfaces along their boundaries, polyhedral Surfaces in 3-dimensional
18
+ # space may not be planar as a whole.
19
+ #
20
+ # The boundary of a simple Surface is the set of closed Curves
21
+ # corresponding to its "exterior" and "interior" boundaries.
22
+ #
23
+ # The only instantiable subclass of Surface defined in this
24
+ # specification, Polygon, is a simple Surface that is planar.
25
+ #
26
+ # == Notes
27
+ #
28
+ # Surface is defined as a module and is provided primarily
29
+ # for the sake of documentation. Implementations need not necessarily
30
+ # include this module itself. Therefore, you should not depend on the
31
+ # kind_of? method to check type. Instead, use the provided check_type
32
+ # class method (or === operator) defined in the Type module.
33
+ #
34
+ # Some implementations may support higher dimensional points.
35
+
36
+ module Surface
37
+ include Geometry
38
+ extend Type
39
+
40
+ # === SFS 1.1 Description
41
+ #
42
+ # The area of this Surface, as measured in the spatial reference
43
+ # system of this Surface.
44
+ #
45
+ # === Notes
46
+ #
47
+ # Returns a floating-point scalar value.
48
+
49
+ def area
50
+ raise Error::UnsupportedOperation, "Method Surface#area not defined."
51
+ end
52
+
53
+ # === SFS 1.1 Description
54
+ #
55
+ # The mathematical centroid for this Surface as a Point. The result
56
+ # is not guaranteed to be on this Surface.
57
+ #
58
+ # === Notes
59
+ #
60
+ # Returns an object that supports the Point interface.
61
+
62
+ def centroid
63
+ raise Error::UnsupportedOperation, "Method Surface#centroid not defined."
64
+ end
65
+
66
+ # === SFS 1.1 Description
67
+ #
68
+ # A Point guaranteed to be on this Surface.
69
+ #
70
+ # === Notes
71
+ #
72
+ # Returns an object that supports the Point interface.
73
+
74
+ def point_on_surface
75
+ raise Error::UnsupportedOperation, "Method Surface#point_on_surface not defined."
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,284 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Feature type management and casting
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Feature
9
+ # All geometry implementations MUST include this submodule.
10
+ # This serves as a marker that may be used to test an object for
11
+ # feature-ness.
12
+
13
+ module Instance
14
+ end
15
+
16
+ # This module provides the API for geometry type objects. Technically
17
+ # these objects are modules (such as ::RGeo::Feature::Point), but as
18
+ # objects they respond to the methods documented here.
19
+ #
20
+ # For example, you may determine whether a feature object is a
21
+ # point by calling:
22
+ #
23
+ # ::RGeo::Feature::Point.check_type(object)
24
+ #
25
+ # A corresponding === operator is provided so you can use the type
26
+ # modules in a case-when clause:
27
+ #
28
+ # case object
29
+ # when ::RGeo::Feature::Point
30
+ # # do stuff here...
31
+ #
32
+ # However, a feature object may not actually include the point module
33
+ # itself; hence, the following will *not* work:
34
+ #
35
+ # object.is_a?(::RGeo::Feature::Point) # DON'T DO THIS-- DOES NOT WORK
36
+ #
37
+ # You may obtain the type of a feature object by calling its
38
+ # geometry_type method. You may then use the methods in this module to
39
+ # interrogate that type.
40
+ #
41
+ # # supppose object is a Point
42
+ # type = object.geometry_type # ::RGeo::Feature::Point
43
+ # type.type_name # "Point"
44
+ # type.supertype # ::RGeo::Feature::Geometry
45
+ #
46
+ # You may also use the presence of this module to determine whether
47
+ # a particular object is a feature type:
48
+ #
49
+ # ::RGeo::Feature::Type === object.geometry_type # true
50
+
51
+ module Type
52
+ # Deprecated alias for RGeo::Feature::Instance
53
+ Instance = Feature::Instance
54
+
55
+ # Returns true if the given object is this type or a subtype
56
+ # thereof, or if it is a feature object whose geometry_type is
57
+ # this type or a subtype thereof.
58
+ #
59
+ # Note that feature objects need not actually include this module.
60
+ # Therefore, the is_a? method will generally not work.
61
+
62
+ def check_type(rhs_)
63
+ rhs_ = rhs_.geometry_type if rhs_.is_a?(Feature::Instance)
64
+ rhs_.is_a?(Type) && (rhs_ == self || rhs_.include?(self))
65
+ end
66
+ alias_method :===, :check_type
67
+
68
+ # Returns true if this type is the same type or a subtype of the
69
+ # given type.
70
+
71
+ def subtype_of?(type_)
72
+ self == type_ || self.include?(type_)
73
+ end
74
+
75
+ # Returns the supertype of this type. The supertype of Geometry
76
+ # is nil.
77
+
78
+ def supertype
79
+ @supertype
80
+ end
81
+
82
+ # Iterates over the known immediate subtypes of this type.
83
+
84
+ def each_immediate_subtype(&block_)
85
+ @subtypes.each(&block_) if defined?(@subtypes) && @subtypes
86
+ end
87
+
88
+ # Returns the OpenGIS type name of this type. For example:
89
+ #
90
+ # ::RGeo::Feature::Point.type_name # "Point"
91
+
92
+ def type_name
93
+ name.sub("RGeo::Feature::", "")
94
+ end
95
+ alias_method :to_s, :type_name
96
+
97
+ def _add_subtype(type_) # :nodoc:
98
+ (@subtypes ||= []) << type_
99
+ end
100
+
101
+ def self.extended(type_) # :nodoc:
102
+ supertype_ = type_.included_modules.find { |m_| m_.is_a?(self) }
103
+ type_.instance_variable_set(:@supertype, supertype_)
104
+ supertype_._add_subtype(type_) if supertype_
105
+ end
106
+ end
107
+
108
+ class << self
109
+ # Cast the given object according to the given parameters, if
110
+ # possible, and return the resulting object. If the requested cast
111
+ # is not possible, nil is returned.
112
+ #
113
+ # Parameters may be provided as a hash, or as separate arguments.
114
+ # Hash keys are as follows:
115
+ #
116
+ # [<tt>:factory</tt>]
117
+ # Set the factory to the given factory. If this argument is not
118
+ # given, the original object's factory is kept.
119
+ # [<tt>:type</tt>]
120
+ # Cast to the given type, which must be a module in the
121
+ # RGeo::Feature namespace. If this argument is not given, the
122
+ # result keeps the same type as the original.
123
+ # [<tt>:project</tt>]
124
+ # If this is set to true, and both the original and new factories
125
+ # support proj4 projections, then the cast will also cause the
126
+ # coordinates to be transformed between those two projections.
127
+ # If set to false, the coordinates are not modified. Default is
128
+ # false.
129
+ # [<tt>:keep_subtype</tt>]
130
+ # Value must be a boolean indicating whether to keep the subtype
131
+ # of the original. If set to false, casting to a particular type
132
+ # always casts strictly to that type, even if the old type is a
133
+ # subtype of the new type. If set to true, the cast retains the
134
+ # subtype in that case. For example, casting a LinearRing to a
135
+ # LineString will normally yield a LineString, even though
136
+ # LinearRing is already a more specific subtype. If you set this
137
+ # value to true, the casted object will remain a LinearRing.
138
+ # Default is false.
139
+ # [<tt>:force_new</tt>]
140
+ # Always return a newly-created object, even if neither the type
141
+ # nor factory is modified. Normally, if this is set to false, and
142
+ # a cast is not set to modify either the factory or type, the
143
+ # original object itself is returned. Setting this flag to true
144
+ # causes cast to return a clone in that case. Default is false.
145
+ #
146
+ # You may also pass the new factory, the new type, and the flags
147
+ # as separate arguments. In this case, the flag names must be
148
+ # passed as symbols, and their effect is the same as setting their
149
+ # values to true. You can even combine separate arguments and hash
150
+ # arguments. For example, the following three calls are equivalent:
151
+ #
152
+ # RGeo::Feature.cast(geom, :type => RGeo::Feature::Point, :project => true)
153
+ # RGeo::Feature.cast(geom, RGeo::Feature::Point, :project => true)
154
+ # RGeo::Feature.cast(geom, RGeo::Feature::Point, :project)
155
+ #
156
+ # RGeo provides a default casting algorithm. Individual feature
157
+ # implementation factories may override this and customize the
158
+ # casting behavior by defining the override_cast method. See
159
+ # ::RGeo::Feature::Factory#override_cast for more details.
160
+
161
+ def cast(obj_, *params_)
162
+ # Interpret params
163
+ factory_ = obj_.factory
164
+ type_ = obj_.geometry_type
165
+ opts_ = {}
166
+ params_.each do |param_|
167
+ case param_
168
+ when Factory::Instance
169
+ opts_[:factory] = param_
170
+ when Type
171
+ opts_[:type] = param_
172
+ when ::Symbol
173
+ opts_[param_] = true
174
+ when ::Hash
175
+ opts_.merge!(param_)
176
+ end
177
+ end
178
+ force_new_ = opts_[:force_new]
179
+ keep_subtype_ = opts_[:keep_subtype]
180
+ project_ = opts_[:project]
181
+ nfactory_ = opts_.delete(:factory) || factory_
182
+ ntype_ = opts_.delete(:type) || type_
183
+
184
+ # Let the factory override
185
+ if nfactory_.respond_to?(:override_cast)
186
+ override_ = nfactory_.override_cast(obj_, ntype_, opts_)
187
+ return override_ unless override_ == false
188
+ end
189
+
190
+ # Default algorithm
191
+ ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
192
+ if ntype_ == type_
193
+ # Types are the same
194
+ if nfactory_ == factory_
195
+ force_new_ ? obj_.dup : obj_
196
+ else
197
+ if type_ == Point
198
+ proj_ = nproj_ = nil
199
+ if project_
200
+ proj_ = factory_.proj4
201
+ nproj_ = nfactory_.proj4
202
+ end
203
+ hasz_ = factory_.property(:has_z_coordinate)
204
+ nhasz_ = nfactory_.property(:has_z_coordinate)
205
+ if proj_ && nproj_
206
+ coords_ = CoordSys::Proj4.transform_coords(proj_, nproj_, obj_.x, obj_.y, hasz_ ? obj_.z : nil)
207
+ coords_ << (hasz_ ? obj_.z : 0.0) if nhasz_ && coords_.size < 3
208
+ else
209
+ coords_ = [obj_.x, obj_.y]
210
+ coords_ << (hasz_ ? obj_.z : 0.0) if nhasz_
211
+ end
212
+ coords_ << (factory_.property(:has_m_coordinate) ? obj_.m : 0.0) if nfactory_.property(:has_m_coordinate)
213
+ nfactory_.point(*coords_)
214
+ elsif type_ == Line
215
+ nfactory_.line(cast(obj_.start_point, nfactory_, opts_), cast(obj_.end_point, nfactory_, opts_))
216
+ elsif type_ == LinearRing
217
+ nfactory_.linear_ring(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
218
+ elsif type_ == LineString
219
+ nfactory_.line_string(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
220
+ elsif type_ == Polygon
221
+ nfactory_.polygon(cast(obj_.exterior_ring, nfactory_, opts_),
222
+ obj_.interior_rings.map { |r_| cast(r_, nfactory_, opts_) })
223
+ elsif type_ == MultiPoint
224
+ nfactory_.multi_point(obj_.map { |g_| cast(g_, nfactory_, opts_) })
225
+ elsif type_ == MultiLineString
226
+ nfactory_.multi_line_string(obj_.map { |g_| cast(g_, nfactory_, opts_) })
227
+ elsif type_ == MultiPolygon
228
+ nfactory_.multi_polygon(obj_.map { |g_| cast(g_, nfactory_, opts_) })
229
+ elsif type_ == GeometryCollection
230
+ nfactory_.collection(obj_.map { |g_| cast(g_, nfactory_, opts_) })
231
+ end
232
+ end
233
+ else
234
+ # Types are different
235
+ if ntype_ == Point && (type_ == MultiPoint || type_ == GeometryCollection) ||
236
+ (ntype_ == Line || ntype_ == LineString || ntype_ == LinearRing) && (type_ == MultiLineString || type_ == GeometryCollection) ||
237
+ ntype_ == Polygon && (type_ == MultiPolygon || type_ == GeometryCollection)
238
+ if obj_.num_geometries == 1
239
+ cast(obj_.geometry_n(0), nfactory_, ntype_, opts_)
240
+ end
241
+ elsif ntype_ == Point
242
+ nil
243
+ elsif ntype_ == Line
244
+ if type_ == LineString && obj_.num_points == 2
245
+ nfactory_.line(cast(obj_.point_n(0), nfactory_, opts_), cast(obj_.point_n(1), nfactory_, opts_))
246
+ end
247
+ elsif ntype_ == LinearRing
248
+ if type_ == LineString
249
+ nfactory_.linear_ring(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
250
+ end
251
+ elsif ntype_ == LineString
252
+ if type_ == Line || type_ == LinearRing
253
+ nfactory_.line_string(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
254
+ end
255
+ elsif ntype_ == MultiPoint
256
+ if type_ == Point
257
+ nfactory_.multi_point([cast(obj_, nfactory_, opts_)])
258
+ elsif type_ == GeometryCollection
259
+ nfactory_.multi_point(obj_.map { |p_| cast(p_, nfactory_, opts_) })
260
+ end
261
+ elsif ntype_ == MultiLineString
262
+ if type_ == Line || type_ == LinearRing || type_ == LineString
263
+ nfactory_.multi_line_string([cast(obj_, nfactory_, opts_)])
264
+ elsif type_ == GeometryCollection
265
+ nfactory_.multi_line_string(obj_.map { |p_| cast(p_, nfactory_, opts_) })
266
+ end
267
+ elsif ntype_ == MultiPolygon
268
+ if type_ == Polygon
269
+ nfactory_.multi_polygon([cast(obj_, nfactory_, opts_)])
270
+ elsif type_ == GeometryCollection
271
+ nfactory_.multi_polygon(obj_.map { |p_| cast(p_, nfactory_, opts_) })
272
+ end
273
+ elsif ntype_ == GeometryCollection
274
+ if type_ == MultiPoint || type_ == MultiLineString || type_ == MultiPolygon
275
+ nfactory_.collection(obj_.map { |p_| cast(p_, nfactory_, opts_) })
276
+ else
277
+ nfactory_.collection([cast(obj_, nfactory_, opts_)])
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end