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.
- data/History.rdoc +199 -0
- data/README.rdoc +172 -0
- data/Spatial_Programming_With_RGeo.rdoc +440 -0
- data/Version +1 -0
- data/ext/geos_c_impl/extconf.rb +84 -0
- data/ext/geos_c_impl/factory.c +468 -0
- data/ext/geos_c_impl/factory.h +224 -0
- data/ext/geos_c_impl/geometry.c +705 -0
- data/ext/geos_c_impl/geometry.h +55 -0
- data/ext/geos_c_impl/geometry_collection.c +482 -0
- data/ext/geos_c_impl/geometry_collection.h +69 -0
- data/ext/geos_c_impl/line_string.c +509 -0
- data/ext/geos_c_impl/line_string.h +64 -0
- data/ext/geos_c_impl/main.c +70 -0
- data/ext/geos_c_impl/point.c +193 -0
- data/ext/geos_c_impl/point.h +62 -0
- data/ext/geos_c_impl/polygon.c +265 -0
- data/ext/geos_c_impl/polygon.h +66 -0
- data/ext/geos_c_impl/preface.h +50 -0
- data/ext/proj4_c_impl/extconf.rb +88 -0
- data/ext/proj4_c_impl/main.c +271 -0
- data/lib/rgeo.rb +124 -0
- data/lib/rgeo/cartesian.rb +60 -0
- data/lib/rgeo/cartesian/analysis.rb +118 -0
- data/lib/rgeo/cartesian/bounding_box.rb +337 -0
- data/lib/rgeo/cartesian/calculations.rb +161 -0
- data/lib/rgeo/cartesian/factory.rb +209 -0
- data/lib/rgeo/cartesian/feature_classes.rb +173 -0
- data/lib/rgeo/cartesian/feature_methods.rb +106 -0
- data/lib/rgeo/cartesian/interface.rb +150 -0
- data/lib/rgeo/coord_sys.rb +79 -0
- data/lib/rgeo/coord_sys/cs/entities.rb +1524 -0
- data/lib/rgeo/coord_sys/cs/factories.rb +208 -0
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +308 -0
- data/lib/rgeo/coord_sys/proj4.rb +312 -0
- data/lib/rgeo/coord_sys/srs_database/active_record_table.rb +194 -0
- data/lib/rgeo/coord_sys/srs_database/interface.rb +165 -0
- data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +188 -0
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +108 -0
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +108 -0
- data/lib/rgeo/error.rb +63 -0
- data/lib/rgeo/feature.rb +88 -0
- data/lib/rgeo/feature/curve.rb +156 -0
- data/lib/rgeo/feature/factory.rb +332 -0
- data/lib/rgeo/feature/factory_generator.rb +138 -0
- data/lib/rgeo/feature/geometry.rb +614 -0
- data/lib/rgeo/feature/geometry_collection.rb +129 -0
- data/lib/rgeo/feature/line.rb +66 -0
- data/lib/rgeo/feature/line_string.rb +102 -0
- data/lib/rgeo/feature/linear_ring.rb +66 -0
- data/lib/rgeo/feature/multi_curve.rb +113 -0
- data/lib/rgeo/feature/multi_line_string.rb +66 -0
- data/lib/rgeo/feature/multi_point.rb +73 -0
- data/lib/rgeo/feature/multi_polygon.rb +97 -0
- data/lib/rgeo/feature/multi_surface.rb +116 -0
- data/lib/rgeo/feature/point.rb +120 -0
- data/lib/rgeo/feature/polygon.rb +141 -0
- data/lib/rgeo/feature/surface.rb +122 -0
- data/lib/rgeo/feature/types.rb +305 -0
- data/lib/rgeo/geographic.rb +75 -0
- data/lib/rgeo/geographic/factory.rb +287 -0
- data/lib/rgeo/geographic/interface.rb +410 -0
- data/lib/rgeo/geographic/proj4_projector.rb +98 -0
- data/lib/rgeo/geographic/projected_feature_classes.rb +213 -0
- data/lib/rgeo/geographic/projected_feature_methods.rb +228 -0
- data/lib/rgeo/geographic/projected_window.rb +467 -0
- data/lib/rgeo/geographic/simple_mercator_projector.rb +157 -0
- data/lib/rgeo/geographic/spherical_feature_classes.rb +212 -0
- data/lib/rgeo/geographic/spherical_feature_methods.rb +97 -0
- data/lib/rgeo/geographic/spherical_math.rb +206 -0
- data/lib/rgeo/geos.rb +72 -0
- data/lib/rgeo/geos/factory.rb +301 -0
- data/lib/rgeo/geos/impl_additions.rb +76 -0
- data/lib/rgeo/geos/interface.rb +139 -0
- data/lib/rgeo/geos/zm_factory.rb +275 -0
- data/lib/rgeo/geos/zm_impl.rb +432 -0
- data/lib/rgeo/impl_helper.rb +53 -0
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +235 -0
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +85 -0
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +197 -0
- data/lib/rgeo/impl_helper/basic_point_methods.rb +138 -0
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +121 -0
- data/lib/rgeo/impl_helper/math.rb +50 -0
- data/lib/rgeo/version.rb +52 -0
- data/lib/rgeo/wkrep.rb +72 -0
- data/lib/rgeo/wkrep/wkb_generator.rb +267 -0
- data/lib/rgeo/wkrep/wkb_parser.rb +315 -0
- data/lib/rgeo/wkrep/wkt_generator.rb +275 -0
- data/lib/rgeo/wkrep/wkt_parser.rb +496 -0
- data/test/common/geometry_collection_tests.rb +238 -0
- data/test/common/line_string_tests.rb +324 -0
- data/test/common/multi_line_string_tests.rb +209 -0
- data/test/common/multi_point_tests.rb +201 -0
- data/test/common/multi_polygon_tests.rb +208 -0
- data/test/common/point_tests.rb +331 -0
- data/test/common/polygon_tests.rb +232 -0
- data/test/coord_sys/tc_active_record_table.rb +102 -0
- data/test/coord_sys/tc_ogc_cs.rb +356 -0
- data/test/coord_sys/tc_proj4.rb +138 -0
- data/test/coord_sys/tc_proj4_srs_data.rb +76 -0
- data/test/coord_sys/tc_sr_org.rb +70 -0
- data/test/coord_sys/tc_url_reader.rb +82 -0
- data/test/geos/tc_factory.rb +91 -0
- data/test/geos/tc_geometry_collection.rb +62 -0
- data/test/geos/tc_line_string.rb +62 -0
- data/test/geos/tc_misc.rb +72 -0
- data/test/geos/tc_multi_line_string.rb +62 -0
- data/test/geos/tc_multi_point.rb +62 -0
- data/test/geos/tc_multi_polygon.rb +63 -0
- data/test/geos/tc_point.rb +86 -0
- data/test/geos/tc_polygon.rb +86 -0
- data/test/geos/tc_zmfactory.rb +85 -0
- data/test/projected_geographic/tc_geometry_collection.rb +62 -0
- data/test/projected_geographic/tc_line_string.rb +62 -0
- data/test/projected_geographic/tc_multi_line_string.rb +62 -0
- data/test/projected_geographic/tc_multi_point.rb +62 -0
- data/test/projected_geographic/tc_multi_polygon.rb +63 -0
- data/test/projected_geographic/tc_point.rb +93 -0
- data/test/projected_geographic/tc_polygon.rb +62 -0
- data/test/simple_cartesian/tc_calculations.rb +145 -0
- data/test/simple_cartesian/tc_geometry_collection.rb +69 -0
- data/test/simple_cartesian/tc_line_string.rb +70 -0
- data/test/simple_cartesian/tc_multi_line_string.rb +67 -0
- data/test/simple_cartesian/tc_multi_point.rb +67 -0
- data/test/simple_cartesian/tc_multi_polygon.rb +70 -0
- data/test/simple_cartesian/tc_point.rb +91 -0
- data/test/simple_cartesian/tc_polygon.rb +67 -0
- data/test/simple_mercator/tc_geometry_collection.rb +62 -0
- data/test/simple_mercator/tc_line_string.rb +62 -0
- data/test/simple_mercator/tc_multi_line_string.rb +62 -0
- data/test/simple_mercator/tc_multi_point.rb +62 -0
- data/test/simple_mercator/tc_multi_polygon.rb +63 -0
- data/test/simple_mercator/tc_point.rb +93 -0
- data/test/simple_mercator/tc_polygon.rb +62 -0
- data/test/simple_mercator/tc_window.rb +219 -0
- data/test/spherical_geographic/tc_calculations.rb +203 -0
- data/test/spherical_geographic/tc_geometry_collection.rb +70 -0
- data/test/spherical_geographic/tc_line_string.rb +70 -0
- data/test/spherical_geographic/tc_multi_line_string.rb +67 -0
- data/test/spherical_geographic/tc_multi_point.rb +67 -0
- data/test/spherical_geographic/tc_multi_polygon.rb +70 -0
- data/test/spherical_geographic/tc_point.rb +100 -0
- data/test/spherical_geographic/tc_polygon.rb +67 -0
- data/test/tc_cartesian_analysis.rb +107 -0
- data/test/tc_oneoff.rb +63 -0
- data/test/wkrep/tc_wkb_generator.rb +249 -0
- data/test/wkrep/tc_wkb_parser.rb +353 -0
- data/test/wkrep/tc_wkt_generator.rb +362 -0
- data/test/wkrep/tc_wkt_parser.rb +480 -0
- 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
|