schleyfox-rgeo 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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
data/Version ADDED
@@ -0,0 +1 @@
1
+ 0.2.5
@@ -0,0 +1,84 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Makefile builder for GEOS wrapper
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
+ if ::RUBY_DESCRIPTION =~ /^jruby\s/
38
+
39
+ ::File.open('Makefile', 'w'){ |f_| f_.write(".PHONY: install\ninstall:\n") }
40
+
41
+ else
42
+
43
+ require 'mkmf'
44
+
45
+ header_dirs_ =
46
+ [
47
+ '/usr/local/include',
48
+ '/usr/local/geos/include',
49
+ '/opt/local/include',
50
+ '/opt/geos/include',
51
+ '/opt/include',
52
+ ::Config::CONFIG['includedir'],
53
+ '/usr/include',
54
+ ]
55
+ lib_dirs_ =
56
+ [
57
+ '/usr/local/lib',
58
+ '/usr/local/geos/lib',
59
+ '/opt/local/lib',
60
+ '/opt/geos/lib',
61
+ '/opt/lib',
62
+ ::Config::CONFIG['libdir'],
63
+ '/usr/lib',
64
+ ]
65
+ header_dirs_.delete_if{ |path_| !::File.directory?(path_) }
66
+ lib_dirs_.delete_if{ |path_| !::File.directory?(path_) }
67
+
68
+ found_geos_ = false
69
+ header_dirs_, lib_dirs_ = dir_config('geos', header_dirs_, lib_dirs_)
70
+ if have_header('geos_c.h')
71
+ $libs << ' -lgeos -lgeos_c'
72
+ if have_func('initGEOS_r', 'geos_c.h')
73
+ found_geos_ = true
74
+ else
75
+ $libs.gsub!(' -lgeos -lgeos_c', '')
76
+ end
77
+ end
78
+ unless found_geos_
79
+ puts "**** WARNING: Unable to find GEOS headers or GEOS version is too old."
80
+ puts "**** Compiling without GEOS support."
81
+ end
82
+ create_makefile('rgeo/geos/geos_c_impl')
83
+
84
+ end
@@ -0,0 +1,468 @@
1
+ /*
2
+ -----------------------------------------------------------------------------
3
+
4
+ Factory and utility functions for GEOS wrapper
5
+
6
+ -----------------------------------------------------------------------------
7
+ Copyright 2010 Daniel Azuma
8
+
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ * Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+ * Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+ * Neither the name of the copyright holder, nor the names of any other
20
+ contributors to this software, may be used to endorse or promote products
21
+ derived from this software without specific prior written permission.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ POSSIBILITY OF SUCH DAMAGE.
34
+ -----------------------------------------------------------------------------
35
+ */
36
+
37
+
38
+ #include "preface.h"
39
+
40
+ #ifdef RGEO_GEOS_SUPPORTED
41
+
42
+ #include <ruby.h>
43
+ #include <geos_c.h>
44
+
45
+ #include "factory.h"
46
+ #include "geometry.h"
47
+ #include "point.h"
48
+ #include "line_string.h"
49
+ #include "polygon.h"
50
+ #include "geometry_collection.h"
51
+
52
+ RGEO_BEGIN_C
53
+
54
+
55
+ /**** RUBY AND GEOS CALLBACKS ****/
56
+
57
+
58
+ // NOP message handler. GEOS requires that a message handler be set
59
+ // for every context handle.
60
+
61
+ static void message_handler(const char* fmt, ...)
62
+ {
63
+ }
64
+
65
+
66
+ // Destroy function for factory data. We destroy any serialization
67
+ // objects that have been created for the factory, and then destroy
68
+ // the GEOS context, before freeing the factory data itself.
69
+
70
+ static void destroy_factory_func(RGeo_FactoryData* data)
71
+ {
72
+ GEOSContextHandle_t context = data->geos_context;
73
+ if (data->wkt_reader) {
74
+ GEOSWKTReader_destroy_r(context, data->wkt_reader);
75
+ }
76
+ if (data->wkb_reader) {
77
+ GEOSWKBReader_destroy_r(context, data->wkb_reader);
78
+ }
79
+ if (data->wkt_writer) {
80
+ GEOSWKTWriter_destroy_r(context, data->wkt_writer);
81
+ }
82
+ if (data->wkb_writer) {
83
+ GEOSWKBWriter_destroy_r(context, data->wkb_writer);
84
+ }
85
+ finishGEOS_r(context);
86
+ free(data);
87
+ }
88
+
89
+
90
+ // Destroy function for geometry data. We destroy the internal
91
+ // GEOS geometry (if present) before freeing the data itself.
92
+
93
+ static void destroy_geometry_func(RGeo_GeometryData* data)
94
+ {
95
+ if (data->geom) {
96
+ GEOSGeom_destroy_r(data->geos_context, data->geom);
97
+ }
98
+ free(data);
99
+ }
100
+
101
+
102
+ // Mark function for geometry data. This marks the factory and klasses
103
+ // held by the geometry so those don't get collected.
104
+
105
+ static void mark_geometry_func(RGeo_GeometryData* data)
106
+ {
107
+ if (!NIL_P(data->factory)) {
108
+ rb_gc_mark(data->factory);
109
+ }
110
+ if (!NIL_P(data->klasses)) {
111
+ rb_gc_mark(data->klasses);
112
+ }
113
+ }
114
+
115
+
116
+ // Destroy function for globals data. We don't need to destroy any
117
+ // auxiliary data for now...
118
+
119
+ static void destroy_globals_func(RGeo_Globals* data)
120
+ {
121
+ free(data);
122
+ }
123
+
124
+
125
+ // Mark function for globals data. This should mark any globals that
126
+ // need to be held through garbage collection (none at the moment.)
127
+
128
+ static void mark_globals_func(RGeo_Globals* data)
129
+ {
130
+ }
131
+
132
+
133
+ /**** RUBY METHOD DEFINITIONS ****/
134
+
135
+
136
+ static VALUE method_factory_srid(VALUE self)
137
+ {
138
+ return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->srid);
139
+ }
140
+
141
+
142
+ static VALUE method_factory_buffer_resolution(VALUE self)
143
+ {
144
+ return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->buffer_resolution);
145
+ }
146
+
147
+
148
+ static VALUE method_factory_flags(VALUE self)
149
+ {
150
+ return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->flags);
151
+ }
152
+
153
+
154
+ static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
155
+ {
156
+ Check_Type(str, T_STRING);
157
+ RGeo_FactoryData* self_data = RGEO_FACTORY_DATA_PTR(self);
158
+ GEOSContextHandle_t self_context = self_data->geos_context;
159
+ GEOSWKTReader* wkt_reader = self_data->wkt_reader;
160
+ if (!wkt_reader) {
161
+ wkt_reader = GEOSWKTReader_create_r(self_context);
162
+ self_data->wkt_reader = wkt_reader;
163
+ }
164
+ VALUE result = Qnil;
165
+ if (wkt_reader) {
166
+ GEOSGeometry* geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str));
167
+ if (geom) {
168
+ result = rgeo_wrap_geos_geometry(self, geom, Qnil);
169
+ }
170
+ }
171
+ return result;
172
+ }
173
+
174
+
175
+ static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
176
+ {
177
+ Check_Type(str, T_STRING);
178
+ RGeo_FactoryData* self_data = RGEO_FACTORY_DATA_PTR(self);
179
+ GEOSContextHandle_t self_context = self_data->geos_context;
180
+ GEOSWKBReader* wkb_reader = self_data->wkb_reader;
181
+ if (!wkb_reader) {
182
+ wkb_reader = GEOSWKBReader_create_r(self_context);
183
+ self_data->wkb_reader = wkb_reader;
184
+ }
185
+ VALUE result = Qnil;
186
+ if (wkb_reader) {
187
+ GEOSGeometry* geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
188
+ if (geom) {
189
+ result = rgeo_wrap_geos_geometry(self, geom, Qnil);
190
+ }
191
+ }
192
+ return result;
193
+ }
194
+
195
+
196
+ static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE buffer_resolution)
197
+ {
198
+ VALUE result = Qnil;
199
+ RGeo_FactoryData* data = ALLOC(RGeo_FactoryData);
200
+ if (data) {
201
+ GEOSContextHandle_t context = initGEOS_r(message_handler, message_handler);
202
+ if (context) {
203
+ VALUE wrapped_globals = rb_const_get_at(klass, rb_intern("INTERNAL_CGLOBALS"));
204
+ data->globals = (RGeo_Globals*)DATA_PTR(wrapped_globals);
205
+ data->geos_context = context;
206
+ data->flags = NUM2INT(flags);
207
+ data->srid = NUM2INT(srid);
208
+ data->buffer_resolution = NUM2INT(buffer_resolution);
209
+ data->wkt_reader = NULL;
210
+ data->wkb_reader = NULL;
211
+ data->wkt_writer = NULL;
212
+ data->wkb_writer = NULL;
213
+ result = Data_Wrap_Struct(klass, NULL, destroy_factory_func, data);
214
+ }
215
+ else {
216
+ free(data);
217
+ }
218
+ }
219
+ return result;
220
+ }
221
+
222
+
223
+ /**** INITIALIZATION FUNCTION ****/
224
+
225
+
226
+ RGeo_Globals* rgeo_init_geos_factory()
227
+ {
228
+ RGeo_Globals* globals = ALLOC(RGeo_Globals);
229
+ VALUE rgeo_module = rb_define_module("RGeo");
230
+ globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
231
+ globals->feature_module = rb_define_module_under(rgeo_module, "Feature");
232
+
233
+ // Add C methods to the factory.
234
+ VALUE geos_factory_class = rb_const_get_at(globals->geos_module, rb_intern("Factory"));
235
+ rb_define_method(geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
236
+ rb_define_method(geos_factory_class, "_parse_wkb_impl", method_factory_parse_wkb, 1);
237
+ rb_define_method(geos_factory_class, "_srid", method_factory_srid, 0);
238
+ rb_define_method(geos_factory_class, "_buffer_resolution", method_factory_buffer_resolution, 0);
239
+ rb_define_method(geos_factory_class, "_flags", method_factory_flags, 0);
240
+ rb_define_module_function(geos_factory_class, "_create", cmethod_factory_create, 3);
241
+
242
+ // Wrap the globals in a Ruby object and store it off so we have access
243
+ // to it later. Each factory instance will reference it internally.
244
+ VALUE wrapped_globals = Data_Wrap_Struct(rb_cObject, mark_globals_func, destroy_globals_func, globals);
245
+ rb_define_const(geos_factory_class, "INTERNAL_CGLOBALS", wrapped_globals);
246
+
247
+ return globals;
248
+ }
249
+
250
+
251
+ /**** OTHER PUBLIC FUNCTIONS ****/
252
+
253
+
254
+ VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
255
+ {
256
+ VALUE result = Qnil;
257
+ if (geom || !NIL_P(klass)) {
258
+ RGeo_FactoryData* factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
259
+ GEOSContextHandle_t factory_context = factory_data ? factory_data->geos_context : NULL;
260
+ VALUE klasses = Qnil;
261
+ if (TYPE(klass) != T_CLASS) {
262
+ RGeo_Globals* globals = factory_data->globals;
263
+ VALUE inferred_klass = Qnil;
264
+ char is_collection = 0;
265
+ switch (GEOSGeomTypeId_r(factory_context, geom)) {
266
+ case GEOS_POINT:
267
+ inferred_klass = globals->geos_point;
268
+ break;
269
+ case GEOS_LINESTRING:
270
+ inferred_klass = globals->geos_line_string;
271
+ break;
272
+ case GEOS_LINEARRING:
273
+ inferred_klass = globals->geos_linear_ring;
274
+ break;
275
+ case GEOS_POLYGON:
276
+ inferred_klass = globals->geos_polygon;
277
+ break;
278
+ case GEOS_MULTIPOINT:
279
+ inferred_klass = globals->geos_multi_point;
280
+ is_collection = 1;
281
+ break;
282
+ case GEOS_MULTILINESTRING:
283
+ inferred_klass = globals->geos_multi_line_string;
284
+ is_collection = 1;
285
+ break;
286
+ case GEOS_MULTIPOLYGON:
287
+ inferred_klass = globals->geos_multi_polygon;
288
+ is_collection = 1;
289
+ break;
290
+ case GEOS_GEOMETRYCOLLECTION:
291
+ inferred_klass = globals->geos_geometry_collection;
292
+ is_collection = 1;
293
+ break;
294
+ default:
295
+ inferred_klass = globals->geos_geometry;
296
+ break;
297
+ }
298
+ if (TYPE(klass) == T_ARRAY && is_collection) {
299
+ klasses = klass;
300
+ }
301
+ klass = inferred_klass;
302
+ }
303
+ RGeo_GeometryData* data = ALLOC(RGeo_GeometryData);
304
+ if (data) {
305
+ if (geom) {
306
+ GEOSSetSRID_r(factory_context, geom, factory_data->srid);
307
+ }
308
+ data->geom = geom;
309
+ data->geos_context = factory_context;
310
+ data->factory = factory;
311
+ data->klasses = klasses;
312
+ result = Data_Wrap_Struct(klass, mark_geometry_func, destroy_geometry_func, data);
313
+ }
314
+ }
315
+ return result;
316
+ }
317
+
318
+
319
+ VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass)
320
+ {
321
+ VALUE result = Qnil;
322
+ if (geom) {
323
+ GEOSGeometry* clone_geom = GEOSGeom_clone_r(RGEO_FACTORY_DATA_PTR(factory)->geos_context, geom);
324
+ if (clone_geom) {
325
+ result = rgeo_wrap_geos_geometry(factory, clone_geom, klass);
326
+ }
327
+ }
328
+ return result;
329
+ }
330
+
331
+
332
+ const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
333
+ {
334
+ VALUE object;
335
+ if (NIL_P(type) && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
336
+ object = obj;
337
+ }
338
+ else {
339
+ object = rb_funcall(RGEO_FACTORY_DATA_PTR(factory)->globals->feature_module, rb_intern("cast"), 3, obj, factory, type);
340
+ }
341
+ const GEOSGeometry* geom = NULL;
342
+ if (!NIL_P(object)) {
343
+ geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
344
+ }
345
+ return geom;
346
+ }
347
+
348
+
349
+ GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, VALUE type, VALUE* klasses)
350
+ {
351
+ if (klasses) {
352
+ *klasses = Qnil;
353
+ }
354
+ VALUE object = rb_funcall(RGEO_FACTORY_DATA_PTR(factory)->globals->feature_module, rb_intern("cast"), 5, obj, factory, type, ID2SYM(rb_intern("force_new")), ID2SYM(rb_intern("keep_subtype")));
355
+ GEOSGeometry* geom = NULL;
356
+ if (!NIL_P(object)) {
357
+ RGeo_GeometryData* object_data = RGEO_GEOMETRY_DATA_PTR(object);
358
+ geom = object_data->geom;
359
+ if (klasses) {
360
+ *klasses = object_data->klasses;
361
+ if (NIL_P(*klasses)) {
362
+ *klasses = CLASS_OF(object);
363
+ }
364
+ }
365
+ object_data->geom = NULL;
366
+ object_data->geos_context = NULL;
367
+ object_data->factory = Qnil;
368
+ object_data->klasses = Qnil;
369
+ }
370
+ return geom;
371
+ }
372
+
373
+
374
+ char rgeo_is_geos_object(VALUE obj)
375
+ {
376
+ return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? 1 : 0;
377
+ }
378
+
379
+
380
+ const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
381
+ {
382
+ return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom) : NULL;
383
+ }
384
+
385
+
386
+ VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
387
+ {
388
+ VALUE result = Qnil;
389
+ if (geom1 && geom2) {
390
+ const GEOSCoordSequence* cs1 = GEOSGeom_getCoordSeq_r(context, geom1);
391
+ const GEOSCoordSequence* cs2 = GEOSGeom_getCoordSeq_r(context, geom2);
392
+ if (cs1 && cs2) {
393
+ unsigned int len1 = 0;
394
+ unsigned int len2 = 0;
395
+ if (GEOSCoordSeq_getSize_r(context, cs1, &len1) && GEOSCoordSeq_getSize_r(context, cs2, &len2)) {
396
+ if (len1 == len2) {
397
+ result = Qtrue;
398
+ unsigned int i;
399
+ double val1, val2;
400
+ for (i=0; i<len1; ++i) {
401
+ if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) {
402
+ if (val1 == val2) {
403
+ if (GEOSCoordSeq_getY_r(context, cs1, i, &val1) && GEOSCoordSeq_getY_r(context, cs2, i, &val2)) {
404
+ if (val1 == val2) {
405
+ if (check_z) {
406
+ val1 = 0;
407
+ if (!GEOSCoordSeq_getZ_r(context, cs1, i, &val1)) {
408
+ result = Qnil;
409
+ break;
410
+ }
411
+ val2 = 0;
412
+ if (!GEOSCoordSeq_getZ_r(context, cs2, i, &val2)) {
413
+ result = Qnil;
414
+ break;
415
+ }
416
+ if (val1 != val2) {
417
+ result = Qfalse;
418
+ break;
419
+ }
420
+ }
421
+ }
422
+ else { // Y coords are different
423
+ result = Qfalse;
424
+ break;
425
+ }
426
+ }
427
+ else { // Failed to get Y coords
428
+ result = Qnil;
429
+ break;
430
+ }
431
+ }
432
+ else { // X coords are different
433
+ result = Qfalse;
434
+ break;
435
+ }
436
+ }
437
+ else { // Failed to get X coords
438
+ result = Qnil;
439
+ break;
440
+ }
441
+ } // Iteration over coords
442
+ }
443
+ else { // Lengths are different
444
+ result = Qfalse;
445
+ }
446
+ }
447
+ }
448
+ }
449
+ return result;
450
+ }
451
+
452
+
453
+ VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
454
+ {
455
+ VALUE result = Qnil;
456
+ if (rb_obj_class(obj1) != rb_obj_class(obj2)) {
457
+ result = Qfalse;
458
+ }
459
+ else {
460
+ result = rb_funcall(RGEO_GEOMETRY_DATA_PTR(obj1)->factory, rb_intern("eql?"), 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
461
+ }
462
+ return result;
463
+ }
464
+
465
+
466
+ RGEO_END_C
467
+
468
+ #endif