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
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