schleyfox-rgeo 0.2.5

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 (150) hide show
  1. data/History.rdoc +199 -0
  2. data/README.rdoc +172 -0
  3. data/Spatial_Programming_With_RGeo.rdoc +440 -0
  4. data/Version +1 -0
  5. data/ext/geos_c_impl/extconf.rb +84 -0
  6. data/ext/geos_c_impl/factory.c +468 -0
  7. data/ext/geos_c_impl/factory.h +224 -0
  8. data/ext/geos_c_impl/geometry.c +705 -0
  9. data/ext/geos_c_impl/geometry.h +55 -0
  10. data/ext/geos_c_impl/geometry_collection.c +482 -0
  11. data/ext/geos_c_impl/geometry_collection.h +69 -0
  12. data/ext/geos_c_impl/line_string.c +509 -0
  13. data/ext/geos_c_impl/line_string.h +64 -0
  14. data/ext/geos_c_impl/main.c +70 -0
  15. data/ext/geos_c_impl/point.c +193 -0
  16. data/ext/geos_c_impl/point.h +62 -0
  17. data/ext/geos_c_impl/polygon.c +265 -0
  18. data/ext/geos_c_impl/polygon.h +66 -0
  19. data/ext/geos_c_impl/preface.h +50 -0
  20. data/ext/proj4_c_impl/extconf.rb +88 -0
  21. data/ext/proj4_c_impl/main.c +271 -0
  22. data/lib/rgeo.rb +124 -0
  23. data/lib/rgeo/cartesian.rb +60 -0
  24. data/lib/rgeo/cartesian/analysis.rb +118 -0
  25. data/lib/rgeo/cartesian/bounding_box.rb +337 -0
  26. data/lib/rgeo/cartesian/calculations.rb +161 -0
  27. data/lib/rgeo/cartesian/factory.rb +209 -0
  28. data/lib/rgeo/cartesian/feature_classes.rb +173 -0
  29. data/lib/rgeo/cartesian/feature_methods.rb +106 -0
  30. data/lib/rgeo/cartesian/interface.rb +150 -0
  31. data/lib/rgeo/coord_sys.rb +79 -0
  32. data/lib/rgeo/coord_sys/cs/entities.rb +1524 -0
  33. data/lib/rgeo/coord_sys/cs/factories.rb +208 -0
  34. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +308 -0
  35. data/lib/rgeo/coord_sys/proj4.rb +312 -0
  36. data/lib/rgeo/coord_sys/srs_database/active_record_table.rb +194 -0
  37. data/lib/rgeo/coord_sys/srs_database/interface.rb +165 -0
  38. data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +188 -0
  39. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +108 -0
  40. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +108 -0
  41. data/lib/rgeo/error.rb +63 -0
  42. data/lib/rgeo/feature.rb +88 -0
  43. data/lib/rgeo/feature/curve.rb +156 -0
  44. data/lib/rgeo/feature/factory.rb +332 -0
  45. data/lib/rgeo/feature/factory_generator.rb +138 -0
  46. data/lib/rgeo/feature/geometry.rb +614 -0
  47. data/lib/rgeo/feature/geometry_collection.rb +129 -0
  48. data/lib/rgeo/feature/line.rb +66 -0
  49. data/lib/rgeo/feature/line_string.rb +102 -0
  50. data/lib/rgeo/feature/linear_ring.rb +66 -0
  51. data/lib/rgeo/feature/multi_curve.rb +113 -0
  52. data/lib/rgeo/feature/multi_line_string.rb +66 -0
  53. data/lib/rgeo/feature/multi_point.rb +73 -0
  54. data/lib/rgeo/feature/multi_polygon.rb +97 -0
  55. data/lib/rgeo/feature/multi_surface.rb +116 -0
  56. data/lib/rgeo/feature/point.rb +120 -0
  57. data/lib/rgeo/feature/polygon.rb +141 -0
  58. data/lib/rgeo/feature/surface.rb +122 -0
  59. data/lib/rgeo/feature/types.rb +305 -0
  60. data/lib/rgeo/geographic.rb +75 -0
  61. data/lib/rgeo/geographic/factory.rb +287 -0
  62. data/lib/rgeo/geographic/interface.rb +410 -0
  63. data/lib/rgeo/geographic/proj4_projector.rb +98 -0
  64. data/lib/rgeo/geographic/projected_feature_classes.rb +213 -0
  65. data/lib/rgeo/geographic/projected_feature_methods.rb +228 -0
  66. data/lib/rgeo/geographic/projected_window.rb +467 -0
  67. data/lib/rgeo/geographic/simple_mercator_projector.rb +157 -0
  68. data/lib/rgeo/geographic/spherical_feature_classes.rb +212 -0
  69. data/lib/rgeo/geographic/spherical_feature_methods.rb +97 -0
  70. data/lib/rgeo/geographic/spherical_math.rb +206 -0
  71. data/lib/rgeo/geos.rb +72 -0
  72. data/lib/rgeo/geos/factory.rb +301 -0
  73. data/lib/rgeo/geos/impl_additions.rb +76 -0
  74. data/lib/rgeo/geos/interface.rb +139 -0
  75. data/lib/rgeo/geos/zm_factory.rb +275 -0
  76. data/lib/rgeo/geos/zm_impl.rb +432 -0
  77. data/lib/rgeo/impl_helper.rb +53 -0
  78. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +235 -0
  79. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +85 -0
  80. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +197 -0
  81. data/lib/rgeo/impl_helper/basic_point_methods.rb +138 -0
  82. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +121 -0
  83. data/lib/rgeo/impl_helper/math.rb +50 -0
  84. data/lib/rgeo/version.rb +52 -0
  85. data/lib/rgeo/wkrep.rb +72 -0
  86. data/lib/rgeo/wkrep/wkb_generator.rb +267 -0
  87. data/lib/rgeo/wkrep/wkb_parser.rb +315 -0
  88. data/lib/rgeo/wkrep/wkt_generator.rb +275 -0
  89. data/lib/rgeo/wkrep/wkt_parser.rb +496 -0
  90. data/test/common/geometry_collection_tests.rb +238 -0
  91. data/test/common/line_string_tests.rb +324 -0
  92. data/test/common/multi_line_string_tests.rb +209 -0
  93. data/test/common/multi_point_tests.rb +201 -0
  94. data/test/common/multi_polygon_tests.rb +208 -0
  95. data/test/common/point_tests.rb +331 -0
  96. data/test/common/polygon_tests.rb +232 -0
  97. data/test/coord_sys/tc_active_record_table.rb +102 -0
  98. data/test/coord_sys/tc_ogc_cs.rb +356 -0
  99. data/test/coord_sys/tc_proj4.rb +138 -0
  100. data/test/coord_sys/tc_proj4_srs_data.rb +76 -0
  101. data/test/coord_sys/tc_sr_org.rb +70 -0
  102. data/test/coord_sys/tc_url_reader.rb +82 -0
  103. data/test/geos/tc_factory.rb +91 -0
  104. data/test/geos/tc_geometry_collection.rb +62 -0
  105. data/test/geos/tc_line_string.rb +62 -0
  106. data/test/geos/tc_misc.rb +72 -0
  107. data/test/geos/tc_multi_line_string.rb +62 -0
  108. data/test/geos/tc_multi_point.rb +62 -0
  109. data/test/geos/tc_multi_polygon.rb +63 -0
  110. data/test/geos/tc_point.rb +86 -0
  111. data/test/geos/tc_polygon.rb +86 -0
  112. data/test/geos/tc_zmfactory.rb +85 -0
  113. data/test/projected_geographic/tc_geometry_collection.rb +62 -0
  114. data/test/projected_geographic/tc_line_string.rb +62 -0
  115. data/test/projected_geographic/tc_multi_line_string.rb +62 -0
  116. data/test/projected_geographic/tc_multi_point.rb +62 -0
  117. data/test/projected_geographic/tc_multi_polygon.rb +63 -0
  118. data/test/projected_geographic/tc_point.rb +93 -0
  119. data/test/projected_geographic/tc_polygon.rb +62 -0
  120. data/test/simple_cartesian/tc_calculations.rb +145 -0
  121. data/test/simple_cartesian/tc_geometry_collection.rb +69 -0
  122. data/test/simple_cartesian/tc_line_string.rb +70 -0
  123. data/test/simple_cartesian/tc_multi_line_string.rb +67 -0
  124. data/test/simple_cartesian/tc_multi_point.rb +67 -0
  125. data/test/simple_cartesian/tc_multi_polygon.rb +70 -0
  126. data/test/simple_cartesian/tc_point.rb +91 -0
  127. data/test/simple_cartesian/tc_polygon.rb +67 -0
  128. data/test/simple_mercator/tc_geometry_collection.rb +62 -0
  129. data/test/simple_mercator/tc_line_string.rb +62 -0
  130. data/test/simple_mercator/tc_multi_line_string.rb +62 -0
  131. data/test/simple_mercator/tc_multi_point.rb +62 -0
  132. data/test/simple_mercator/tc_multi_polygon.rb +63 -0
  133. data/test/simple_mercator/tc_point.rb +93 -0
  134. data/test/simple_mercator/tc_polygon.rb +62 -0
  135. data/test/simple_mercator/tc_window.rb +219 -0
  136. data/test/spherical_geographic/tc_calculations.rb +203 -0
  137. data/test/spherical_geographic/tc_geometry_collection.rb +70 -0
  138. data/test/spherical_geographic/tc_line_string.rb +70 -0
  139. data/test/spherical_geographic/tc_multi_line_string.rb +67 -0
  140. data/test/spherical_geographic/tc_multi_point.rb +67 -0
  141. data/test/spherical_geographic/tc_multi_polygon.rb +70 -0
  142. data/test/spherical_geographic/tc_point.rb +100 -0
  143. data/test/spherical_geographic/tc_polygon.rb +67 -0
  144. data/test/tc_cartesian_analysis.rb +107 -0
  145. data/test/tc_oneoff.rb +63 -0
  146. data/test/wkrep/tc_wkb_generator.rb +249 -0
  147. data/test/wkrep/tc_wkb_parser.rb +353 -0
  148. data/test/wkrep/tc_wkt_generator.rb +362 -0
  149. data/test/wkrep/tc_wkt_parser.rb +480 -0
  150. metadata +267 -0
@@ -0,0 +1,141 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Polygon feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ module RGeo
38
+
39
+ module Feature
40
+
41
+
42
+ # == SFS 1.1 Description
43
+ #
44
+ # A Polygon is a planar Surface defined by 1 exterior boundary and 0 or
45
+ # more interior boundaries. Each interior boundary defines a hole in
46
+ # the Polygon.
47
+ #
48
+ # The assertions for Polygons (the rules that define valid Polygons)
49
+ # are as follows:
50
+ #
51
+ # (a) Polygons are topologically closed;
52
+ #
53
+ # (b) The boundary of a Polygon consists of a set of LinearRings that
54
+ # make up its exterior and interior boundaries;
55
+ #
56
+ # (c) No two Rings in the boundary cross and the Rings in the boundary
57
+ # of a Polygon may intersect at a Point but only as a tangent;
58
+ #
59
+ # (d) A Polygon may not have cut lines, spikes or punctures;
60
+ #
61
+ # (e) The interior of every Polygon is a connected point set;
62
+ #
63
+ # (f) The exterior of a Polygon with 1 or more holes is not connected.
64
+ # Each hole defines a connected component of the exterior.
65
+ #
66
+ # In the above assertions, interior, closure and exterior have the
67
+ # standard topological definitions. The combination of (a) and (c) make
68
+ # a Polygon a regular closed Point set.
69
+ #
70
+ # Polygons are simple geometric objects.
71
+ #
72
+ # == Notes
73
+ #
74
+ # Polygon is defined as a module and is provided primarily
75
+ # for the sake of documentation. Implementations need not necessarily
76
+ # include this module itself. Therefore, you should not depend on the
77
+ # kind_of? method to check type. Instead, use the provided check_type
78
+ # class method (or === operator) defined in the Type module.
79
+
80
+ module Polygon
81
+
82
+ extend Type
83
+
84
+ include Surface
85
+ include ::Enumerable
86
+
87
+
88
+ # === SFS 1.1 Description
89
+ #
90
+ # Returns the exterior ring of this Polygon.
91
+ #
92
+ # === Notes
93
+ #
94
+ # Returns an object that supports the LinearRing interface.
95
+
96
+ def exterior_ring
97
+ raise Error::UnsupportedOperation, "Method Polygon#exterior_ring not defined."
98
+ end
99
+
100
+
101
+ # === SFS 1.1 Description
102
+ #
103
+ # Returns the number of interiorRings in this Polygon.
104
+ #
105
+ # === Notes
106
+ #
107
+ # Returns an integer.
108
+
109
+ def num_interior_rings
110
+ raise Error::UnsupportedOperation, "Method Polygon#num_interior_rings not defined."
111
+ end
112
+
113
+
114
+ # === SFS 1.1 Description
115
+ #
116
+ # Returns the Nth interiorRing for this Polygon as a LineString.
117
+ #
118
+ # === Notes
119
+ #
120
+ # Returns an object that supports the LinearRing interface, or nil
121
+ # if the given n is out of range.
122
+
123
+ def interior_ring_n(n_)
124
+ raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined."
125
+ end
126
+
127
+
128
+ # Returns the interior rings as a (possibly empty) array of objects
129
+ # that support the LinearRing interface.
130
+
131
+ def interior_rings
132
+ raise Error::UnsupportedOperation, "Method Polygon#interior_rings not defined."
133
+ end
134
+
135
+
136
+ end
137
+
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,122 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Surface feature interface
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ module RGeo
38
+
39
+ module Feature
40
+
41
+
42
+ # == SFS 1.1 Description
43
+ #
44
+ # A Surface is a 2-dimensional geometric object.
45
+ #
46
+ # A simple Surface consists of a single "patch" that is associated with
47
+ # one "exterior boundary" and 0 or more "interior" boundaries. Simple
48
+ # Surfaces in 3-dimensional space are isomorphic to planar Surfaces.
49
+ # Polyhedral Surfaces are formed by "stitching" together simple
50
+ # Surfaces along their boundaries, polyhedral Surfaces in 3-dimensional
51
+ # space may not be planar as a whole.
52
+ #
53
+ # The boundary of a simple Surface is the set of closed Curves
54
+ # corresponding to its "exterior" and "interior" boundaries.
55
+ #
56
+ # The only instantiable subclass of Surface defined in this
57
+ # specification, Polygon, is a simple Surface that is planar.
58
+ #
59
+ # == Notes
60
+ #
61
+ # Surface is defined as a module and is provided primarily
62
+ # for the sake of documentation. Implementations need not necessarily
63
+ # include this module itself. Therefore, you should not depend on the
64
+ # kind_of? method to check type. Instead, use the provided check_type
65
+ # class method (or === operator) defined in the Type module.
66
+ #
67
+ # Some implementations may support higher dimensional points.
68
+
69
+ module Surface
70
+
71
+ extend Type
72
+
73
+ include Geometry
74
+
75
+
76
+ # === SFS 1.1 Description
77
+ #
78
+ # The area of this Surface, as measured in the spatial reference
79
+ # system of this Surface.
80
+ #
81
+ # === Notes
82
+ #
83
+ # Returns a floating-point scalar value.
84
+
85
+ def area
86
+ raise Error::UnsupportedOperation, "Method Surface#area not defined."
87
+ end
88
+
89
+
90
+ # === SFS 1.1 Description
91
+ #
92
+ # The mathematical centroid for this Surface as a Point. The result
93
+ # is not guaranteed to be on this Surface.
94
+ #
95
+ # === Notes
96
+ #
97
+ # Returns an object that supports the Point interface.
98
+
99
+ def centroid
100
+ raise Error::UnsupportedOperation, "Method Surface#centroid not defined."
101
+ end
102
+
103
+
104
+ # === SFS 1.1 Description
105
+ #
106
+ # A Point guaranteed to be on this Surface.
107
+ #
108
+ # === Notes
109
+ #
110
+ # Returns an object that supports the Point interface.
111
+
112
+ def point_on_surface
113
+ raise Error::UnsupportedOperation, "Method Surface#point_on_surface not defined."
114
+ end
115
+
116
+
117
+ end
118
+
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,305 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Feature type management and casting
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ module RGeo
38
+
39
+ module Feature
40
+
41
+
42
+ # All geometry implementations MUST include this submodule.
43
+ # This serves as a marker that may be used to test an object for
44
+ # feature-ness.
45
+
46
+ module Instance
47
+ end
48
+
49
+
50
+ # These methods are available as module methods (not instance methods)
51
+ # of the various feature types.
52
+ # For example, you may determine whether a feature object is a
53
+ # point by calling:
54
+ #
55
+ # ::RGeo::Feature::Point.check_type(object)
56
+ #
57
+ # A corresponding === operator is provided so you can use the type
58
+ # modules in a case-when clause.
59
+ #
60
+ # You may also use the presence of this module to determine whether
61
+ # a particular object is a feature type:
62
+ #
63
+ # object.kind_of?(::RGeo::Feature::Type)
64
+
65
+ module Type
66
+
67
+
68
+ # Deprecated alias for RGeo::Feature::Instance
69
+ Instance = Feature::Instance
70
+
71
+
72
+ # Returns true if the given object is this type or a subtype
73
+ # thereof, or if it is a feature object whose geometry_type is
74
+ # this type or a subtype thereof.
75
+ #
76
+ # Note that feature objects need not actually include this module.
77
+
78
+ def check_type(rhs_)
79
+ rhs_ = rhs_.geometry_type if rhs_.kind_of?(Feature::Instance)
80
+ rhs_.kind_of?(Type) && (rhs_ == self || rhs_.include?(self))
81
+ end
82
+ alias_method :===, :check_type
83
+
84
+
85
+ # Returns true if this type is the same type or a subtype of the
86
+ # given type.
87
+
88
+ def subtype_of?(type_)
89
+ self == type_ || self.include?(type_)
90
+ end
91
+
92
+
93
+ # Returns the OpenGIS type name of this type.
94
+
95
+ def type_name
96
+ self.name.sub('RGeo::Feature::', '')
97
+ end
98
+
99
+
100
+ end
101
+
102
+
103
+ class << self
104
+
105
+
106
+ # Cast the given object according to the given parameters, if
107
+ # possible, and return the resulting object. If the requested cast
108
+ # is not possible, nil is returned.
109
+ #
110
+ # Parameters may be provided as a hash, or as separate arguments.
111
+ # Hash keys are as follows:
112
+ #
113
+ # [<tt>:factory</tt>]
114
+ # Set the factory to the given factory. If this argument is not
115
+ # given, the original object's factory is kept.
116
+ # [<tt>:type</tt>]
117
+ # Cast to the given type, which must be a module in the
118
+ # RGeo::Feature namespace. If this argument is not given, the
119
+ # result keeps the same type as the original.
120
+ # [<tt>:project</tt>]
121
+ # If this is set to true, and both the original and new factories
122
+ # support proj4 projections, then the cast will also cause the
123
+ # coordinates to be transformed between those two projections.
124
+ # If set to false, the coordinates are not modified. Default is
125
+ # false.
126
+ # [<tt>:keep_subtype</tt>]
127
+ # Value must be a boolean indicating whether to keep the subtype
128
+ # of the original. If set to false, casting to a particular type
129
+ # always casts strictly to that type, even if the old type is a
130
+ # subtype of the new type. If set to true, the cast retains the
131
+ # subtype in that case. For example, casting a LinearRing to a
132
+ # LineString will normally yield a LineString, even though
133
+ # LinearRing is already a more specific subtype. If you set this
134
+ # value to true, the casted object will remain a LinearRing.
135
+ # Default is false.
136
+ # [<tt>:force_new</tt>]
137
+ # Always return a newly-created object, even if neither the type
138
+ # nor factory is modified. Normally, if this is set to false, and
139
+ # a cast is not set to modify either the factory or type, the
140
+ # original object itself is returned. Setting this flag to true
141
+ # causes cast to return a clone in that case. Default is false.
142
+ #
143
+ # You may also pass the new factory, the new type, and the flags
144
+ # as separate arguments. In this case, the flag names must be
145
+ # passed as symbols, and their effect is the same as setting their
146
+ # values to true. You can even combine separate arguments and hash
147
+ # arguments. For example, the following three calls are equivalent:
148
+ #
149
+ # Feature.cast(geom, :type => Feature::Point, :project => true)
150
+ # Feature.cast(geom, Feature::Point, :project => true)
151
+ # Feature.cast(geom, Feature::Point, :project)
152
+ #
153
+ # RGeo provides a default casting algorithm. Individual feature
154
+ # implementation factories may override this and customize the
155
+ # casting behavior by defining the override_cast method. See
156
+ # ::RGeo::Feature::Factory#override_cast for more details.
157
+
158
+ def cast(obj_, *params_)
159
+ # Interpret params
160
+ factory_ = obj_.factory
161
+ type_ = obj_.geometry_type
162
+ opts_ = {}
163
+ params_.each do |param_|
164
+ case param_
165
+ when Factory::Instance
166
+ opts_[:factory] = param_
167
+ when Type
168
+ opts_[:type] = param_
169
+ when ::Symbol
170
+ opts_[param_] = true
171
+ when ::Hash
172
+ opts_.merge!(param_)
173
+ end
174
+ end
175
+ force_new_ = opts_[:force_new]
176
+ keep_subtype_ = opts_[:keep_subtype]
177
+ project_ = opts_[:project]
178
+ nfactory_ = opts_.delete(:factory) || factory_
179
+ ntype_ = opts_.delete(:type) || type_
180
+
181
+ # Let the factory override
182
+ if nfactory_.respond_to?(:override_cast)
183
+ override_ = nfactory_.override_cast(obj_, ntype_, opts_)
184
+ return override_ unless override_ == false
185
+ end
186
+
187
+ # Default algorithm
188
+ ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
189
+ if ntype_ == type_
190
+ # Types are the same
191
+ if nfactory_ == factory_
192
+ force_new_ ? obj_.dup : obj_
193
+ else
194
+ if type_ == Point
195
+ proj_ = nproj_ = nil
196
+ if project_
197
+ proj_ = factory_.proj4
198
+ nproj_ = nfactory_.proj4
199
+ end
200
+ hasz_ = factory_.property(:has_z_coordinate)
201
+ nhasz_ = nfactory_.property(:has_z_coordinate)
202
+ if proj_ && nproj_
203
+ coords_ = CoordSys::Proj4.transform_coords(proj_, nproj_, obj_.x, obj_.y, hasz_ ? obj_.z : nil)
204
+ coords_ << (hasz_ ? obj_.z : 0.0) if nhasz_ && coords_.size < 3
205
+ else
206
+ coords_ = [obj_.x, obj_.y]
207
+ coords_ << (hasz_ ? obj_.z : 0.0) if nhasz_
208
+ end
209
+ coords_ << (factory_.property(:has_m_coordinate) ? obj_.m : 0.0) if nfactory_.property(:has_m_coordinate)
210
+ nfactory_.point(*coords_)
211
+ elsif type_ == Line
212
+ nfactory_.line(cast(obj_.start_point, nfactory_, opts_), cast(obj_.end_point, nfactory_, opts_))
213
+ elsif type_ == LinearRing
214
+ nfactory_.linear_ring(obj_.points.map{ |p_| cast(p_, nfactory_, opts_) })
215
+ elsif type_ == LineString
216
+ nfactory_.line_string(obj_.points.map{ |p_| cast(p_, nfactory_, opts_) })
217
+ elsif type_ == Polygon
218
+ nfactory_.polygon(cast(obj_.exterior_ring, nfactory_, opts_),
219
+ obj_.interior_rings.map{ |r_| cast(r_, nfactory_, opts_) })
220
+ elsif type_ == MultiPoint
221
+ nfactory_.multi_point(obj_.map{ |g_| cast(g_, nfactory_, opts_) })
222
+ elsif type_ == MultiLineString
223
+ nfactory_.multi_line_string(obj_.map{ |g_| cast(g_, nfactory_, opts_) })
224
+ elsif type_ == MultiPolygon
225
+ nfactory_.multi_polygon(obj_.map{ |g_| cast(g_, nfactory_, opts_) })
226
+ elsif type_ == GeometryCollection
227
+ nfactory_.collection(obj_.map{ |g_| cast(g_, nfactory_, opts_) })
228
+ else
229
+ nil
230
+ end
231
+ end
232
+ else
233
+ # Types are different
234
+ if ntype_ == Point && (type_ == MultiPoint || type_ == GeometryCollection) ||
235
+ (ntype_ == Line || ntype_ == LineString || ntype_ == LinearRing) && (type_ == MultiLineString || type_ == GeometryCollection) ||
236
+ ntype_ == Polygon && (type_ == MultiPolygon || type_ == GeometryCollection)
237
+ then
238
+ if obj_.num_geometries == 1
239
+ cast(obj_.geometry_n(0), nfactory_, ntype_, opts_)
240
+ else
241
+ nil
242
+ end
243
+ elsif ntype_ == Point
244
+ nil
245
+ elsif ntype_ == Line
246
+ if type_ == LineString && obj_.num_points == 2
247
+ nfactory_.line(cast(obj_.point_n(0), nfactory_, opts_), cast(obj_.point_n(1), nfactory_, opts_))
248
+ else
249
+ nil
250
+ end
251
+ elsif ntype_ == LinearRing
252
+ if type_ == LineString
253
+ nfactory_.linear_ring(obj_.points.map{ |p_| cast(p_, nfactory_, opts_) })
254
+ else
255
+ nil
256
+ end
257
+ elsif ntype_ == LineString
258
+ if type_ == Line || type_ == LinearRing
259
+ nfactory_.line_string(obj_.points.map{ |p_| cast(p_, nfactory_, opts_) })
260
+ else
261
+ nil
262
+ end
263
+ elsif ntype_ == MultiPoint
264
+ if type_ == Point
265
+ nfactory_.multi_point([cast(obj_, nfactory_, opts_)])
266
+ elsif type_ == GeometryCollection
267
+ nfactory_.multi_point(obj_.map{ |g_| cast(p_, nfactory_, opts_) })
268
+ else
269
+ nil
270
+ end
271
+ elsif ntype_ == MultiLineString
272
+ if type_ == Line || type_ == LinearRing || type_ == LineString
273
+ nfactory_.multi_line_string([cast(obj_, nfactory_, opts_)])
274
+ elsif type_ == GeometryCollection
275
+ nfactory_.multi_line_string(obj_.map{ |g_| cast(p_, nfactory_, opts_) })
276
+ else
277
+ nil
278
+ end
279
+ elsif ntype_ == MultiPolygon
280
+ if type_ == Polygon
281
+ nfactory_.multi_polygon([cast(obj_, nfactory_, opts_)])
282
+ elsif type_ == GeometryCollection
283
+ nfactory_.multi_polygon(obj_.map{ |g_| cast(p_, nfactory_, opts_) })
284
+ else
285
+ nil
286
+ end
287
+ elsif ntype_ == GeometryCollection
288
+ if type_ == MultiPoint || type_ == MultiLineString || type_ == MultiPolygon
289
+ nfactory_.collection(obj_.map{ |g_| cast(p_, nfactory_, opts_) })
290
+ else
291
+ nfactory_.collection([cast(obj_, nfactory_, opts_)])
292
+ end
293
+ else
294
+ nil
295
+ end
296
+ end
297
+ end
298
+
299
+
300
+ end
301
+
302
+
303
+ end
304
+
305
+ end