rgeo-dschee 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
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