rgeo 0.5.0 → 0.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f107cb048f69993a4599f85f76470ea2d5492eeb
4
- data.tar.gz: 89b9e3483a7a556030ab8977b3c243d89048cb63
3
+ metadata.gz: a348afadf3324ae7b79d3af50fc3574f02612e13
4
+ data.tar.gz: b1eabb80d8a0bca40f41d3243da8c7d3a5c73776
5
5
  SHA512:
6
- metadata.gz: a860309dc4140e31a78d6cf4b138a0fc2cdcf7f267c05875bf651aab03a5a17a400622c1d935ecfca8d3af00ed5d14bae02e46f48f039ed33bc6175fb0592a72
7
- data.tar.gz: 28a5fc931b6b50b34409e07dc8bfdcd53b2b5064c3a28d4cee39d5ff9ddd165c75e55983bc98f9de668c76e31e56388030d7399969b5e4d9fe5a47acf54ba365
6
+ metadata.gz: 4306a4bfd6ef26869bbace978ab2d7ee4c220f89c4d7dc8667724ae4361c1172ab114c2f35246be68cafdbaa8fcae6988f7ed52559bc7e607e2a11c9d9fda494
7
+ data.tar.gz: 41c1857a1594bb0240670e98ff9c797ae91d1c843d7c4a0f5962b67bedb93108b33d809771bd980feaeb297caeb95d5058a4332fe12ef6531fa539a30871987f
@@ -3,15 +3,18 @@
3
3
  # Makefile builder for GEOS wrapper
4
4
  #
5
5
  # -----------------------------------------------------------------------------
6
-
7
- if ::RUBY_DESCRIPTION =~ /^jruby\s/
8
-
6
+ def create_dummy_makefile
9
7
  ::File.open("Makefile", "w") { |f_| f_.write(".PHONY: install\ninstall:\n") }
8
+ end
10
9
 
10
+ if ::RUBY_DESCRIPTION =~ /^jruby\s/
11
+ create_dummy_makefile
11
12
  else
12
13
  require "mkmf"
13
14
 
14
- if geosconfig = (with_config("geos-config") || find_executable("geos-config"))
15
+ geosconfig = with_config("geos-config") || find_executable("geos-config")
16
+
17
+ if geosconfig
15
18
  puts "Using GEOS compile configuration from %s" [geosconfig]
16
19
  $INCFLAGS << " " << `#{geosconfig} --cflags`.strip
17
20
  geos_libs = `#{geosconfig} --clibs`.tr("\n", " ")
@@ -28,11 +31,13 @@ else
28
31
  have_func("rb_memhash", "ruby.h")
29
32
  end
30
33
 
31
- unless found_geos_
34
+ if found_geos_
35
+ create_makefile("rgeo/geos/geos_c_impl")
36
+ else
32
37
  puts "**** WARNING: Unable to find GEOS headers or libraries."
33
38
  puts "**** Ensure that 'geos-config' is in your PATH or provide that full path via --with-geos-config"
34
39
  puts "**** Compiling without GEOS support."
35
- end
36
40
 
37
- create_makefile("rgeo/geos/geos_c_impl")
41
+ create_dummy_makefile
42
+ end
38
43
  end
data/lib/rgeo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RGeo
2
- VERSION = "0.5.0".freeze
2
+ VERSION = "0.5.1".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgeo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma, Tee Parham
@@ -93,31 +93,8 @@ extensions:
93
93
  extra_rdoc_files: []
94
94
  files:
95
95
  - LICENSE.txt
96
- - ext/geos_c_impl/Makefile_2.2.3
97
- - ext/geos_c_impl/coordinates.c
98
- - ext/geos_c_impl/coordinates.h
99
96
  - ext/geos_c_impl/extconf.rb
100
- - ext/geos_c_impl/factory.c
101
- - ext/geos_c_impl/factory.h
102
- - ext/geos_c_impl/geometry.c
103
- - ext/geos_c_impl/geometry.h
104
- - ext/geos_c_impl/geometry_collection.c
105
- - ext/geos_c_impl/geometry_collection.h
106
- - ext/geos_c_impl/geos_c_impl_2.2.3.bundle
107
- - ext/geos_c_impl/line_string.c
108
- - ext/geos_c_impl/line_string.h
109
- - ext/geos_c_impl/main.c
110
- - ext/geos_c_impl/mkmf.log
111
- - ext/geos_c_impl/point.c
112
- - ext/geos_c_impl/point.h
113
- - ext/geos_c_impl/polygon.c
114
- - ext/geos_c_impl/polygon.h
115
- - ext/geos_c_impl/preface.h
116
- - ext/proj4_c_impl/Makefile_2.2.3
117
97
  - ext/proj4_c_impl/extconf.rb
118
- - ext/proj4_c_impl/main.c
119
- - ext/proj4_c_impl/mkmf.log
120
- - ext/proj4_c_impl/proj4_c_impl_2.2.3.bundle
121
98
  - lib/rgeo.rb
122
99
  - lib/rgeo/cartesian.rb
123
100
  - lib/rgeo/cartesian/analysis.rb
@@ -132,7 +109,6 @@ files:
132
109
  - lib/rgeo/coord_sys/cs/factories.rb
133
110
  - lib/rgeo/coord_sys/cs/wkt_parser.rb
134
111
  - lib/rgeo/coord_sys/proj4.rb
135
- - lib/rgeo/coord_sys/proj4_c_impl.bundle
136
112
  - lib/rgeo/coord_sys/srs_database/interface.rb
137
113
  - lib/rgeo/coord_sys/srs_database/proj4_data.rb
138
114
  - lib/rgeo/coord_sys/srs_database/sr_org.rb
@@ -174,7 +150,6 @@ files:
174
150
  - lib/rgeo/geos/ffi_factory.rb
175
151
  - lib/rgeo/geos/ffi_feature_classes.rb
176
152
  - lib/rgeo/geos/ffi_feature_methods.rb
177
- - lib/rgeo/geos/geos_c_impl.bundle
178
153
  - lib/rgeo/geos/interface.rb
179
154
  - lib/rgeo/geos/utils.rb
180
155
  - lib/rgeo/geos/zm_factory.rb
@@ -1,260 +0,0 @@
1
-
2
- SHELL = /bin/sh
3
-
4
- # V=0 quiet, V=1 verbose. other values don't work.
5
- V = 0
6
- Q1 = $(V:1=)
7
- Q = $(Q1:0=@)
8
- ECHO1 = $(V:1=@:)
9
- ECHO = $(ECHO1:0=@echo)
10
- NULLCMD = :
11
-
12
- #### Start of system configuration section. ####
13
-
14
- srcdir = .
15
- topdir = /Users/tee/.rubies/ruby-2.2.3/include/ruby-2.2.0
16
- hdrdir = $(topdir)
17
- arch_hdrdir = /Users/tee/.rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-darwin14
18
- PATH_SEPARATOR = :
19
- VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
20
- prefix = $(DESTDIR)/Users/tee/.rubies/ruby-2.2.3
21
- rubysitearchprefix = $(rubylibprefix)/$(sitearch)
22
- rubyarchprefix = $(rubylibprefix)/$(arch)
23
- rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
24
- exec_prefix = $(prefix)
25
- vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
26
- sitearchhdrdir = $(sitehdrdir)/$(sitearch)
27
- rubyarchhdrdir = $(rubyhdrdir)/$(arch)
28
- vendorhdrdir = $(rubyhdrdir)/vendor_ruby
29
- sitehdrdir = $(rubyhdrdir)/site_ruby
30
- rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
31
- vendorarchdir = $(vendorlibdir)/$(sitearch)
32
- vendorlibdir = $(vendordir)/$(ruby_version)
33
- vendordir = $(rubylibprefix)/vendor_ruby
34
- sitearchdir = $(sitelibdir)/$(sitearch)
35
- sitelibdir = $(sitedir)/$(ruby_version)
36
- sitedir = $(rubylibprefix)/site_ruby
37
- rubyarchdir = $(rubylibdir)/$(arch)
38
- rubylibdir = $(rubylibprefix)/$(ruby_version)
39
- sitearchincludedir = $(includedir)/$(sitearch)
40
- archincludedir = $(includedir)/$(arch)
41
- sitearchlibdir = $(libdir)/$(sitearch)
42
- archlibdir = $(libdir)/$(arch)
43
- ridir = $(datarootdir)/$(RI_BASE_NAME)
44
- mandir = $(datarootdir)/man
45
- localedir = $(datarootdir)/locale
46
- libdir = $(exec_prefix)/lib
47
- psdir = $(docdir)
48
- pdfdir = $(docdir)
49
- dvidir = $(docdir)
50
- htmldir = $(docdir)
51
- infodir = $(datarootdir)/info
52
- docdir = $(datarootdir)/doc/$(PACKAGE)
53
- oldincludedir = $(DESTDIR)/usr/include
54
- includedir = $(prefix)/include
55
- localstatedir = $(prefix)/var
56
- sharedstatedir = $(prefix)/com
57
- sysconfdir = $(prefix)/etc
58
- datadir = $(datarootdir)
59
- datarootdir = $(prefix)/share
60
- libexecdir = $(exec_prefix)/libexec
61
- sbindir = $(exec_prefix)/sbin
62
- bindir = $(exec_prefix)/bin
63
- archdir = $(rubyarchdir)
64
-
65
-
66
- CC = clang
67
- CXX = clang++
68
- LIBRUBY = $(LIBRUBY_A)
69
- LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
70
- LIBRUBYARG_SHARED =
71
- LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation
72
- empty =
73
- OUTFLAG = -o $(empty)
74
- COUTFLAG = -o $(empty)
75
-
76
- RUBY_EXTCONF_H =
77
- cflags = $(optflags) $(debugflags) $(warnflags)
78
- optflags = -O3 -fno-fast-math
79
- debugflags = -ggdb3
80
- warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens
81
- CCDLFLAGS = -fno-common
82
- CFLAGS = $(CCDLFLAGS) -O3 -Wno-error=shorten-64-to-32 -pipe $(ARCH_FLAG)
83
- INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) -I/usr/local/Cellar/geos/3.5.0/include
84
- DEFS =
85
- CPPFLAGS = -DHAVE_GEOS_C_H -DHAVE_GEOSSETSRID_R -DHAVE_GEOSPREPAREDCONTAINS_R -DHAVE_GEOSPREPAREDDISJOINT_R -DHAVE_RB_MEMHASH -I/Users/tee/.rubies/ruby-2.2.3/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags)
86
- CXXFLAGS = $(CCDLFLAGS) $(cxxflags) $(ARCH_FLAG)
87
- ldflags = -L. -L/Users/tee/.rubies/ruby-2.2.3/lib -fstack-protector -L/usr/local/lib
88
- dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress
89
- ARCH_FLAG =
90
- DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
91
- LDSHARED = $(CC) -dynamic -bundle
92
- LDSHAREDXX = $(CXX) -dynamic -bundle
93
- AR = ar
94
- EXEEXT =
95
-
96
- RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
97
- RUBY_SO_NAME = ruby
98
- RUBYW_INSTALL_NAME =
99
- RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
100
- RUBYW_BASE_NAME = rubyw
101
- RUBY_BASE_NAME = ruby
102
-
103
- arch = x86_64-darwin14
104
- sitearch = $(arch)
105
- ruby_version = 2.2.0
106
- ruby = $(bindir)/$(RUBY_BASE_NAME)
107
- RUBY = $(ruby)
108
- ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
109
-
110
- RM = rm -f
111
- RM_RF = $(RUBY) -run -e rm -- -rf
112
- RMDIRS = rmdir -p
113
- MAKEDIRS = mkdir -p
114
- INSTALL = /usr/bin/install -c
115
- INSTALL_PROG = $(INSTALL) -m 0755
116
- INSTALL_DATA = $(INSTALL) -m 644
117
- COPY = cp
118
- TOUCH = exit >
119
-
120
- #### End of system configuration section. ####
121
-
122
- preload =
123
-
124
- libpath = . $(libdir)
125
- LIBPATH = -L. -L$(libdir)
126
- DEFFILE =
127
-
128
- CLEANFILES = mkmf.log
129
- DISTCLEANFILES =
130
- DISTCLEANDIRS =
131
-
132
- extout =
133
- extout_prefix =
134
- target_prefix = /rgeo/geos
135
- LOCAL_LIBS =
136
- LIBS = -L/usr/local/Cellar/geos/3.5.0/lib -lgeos_c -lpthread -lgmp -ldl -lobjc
137
- ORIG_SRCS = coordinates.c factory.c geometry.c geometry_collection.c line_string.c main.c point.c polygon.c
138
- SRCS = $(ORIG_SRCS)
139
- OBJS = coordinates.o factory.o geometry.o geometry_collection.o line_string.o main.o point.o polygon.o
140
- HDRS = $(srcdir)/coordinates.h $(srcdir)/factory.h $(srcdir)/geometry.h $(srcdir)/geometry_collection.h $(srcdir)/line_string.h $(srcdir)/point.h $(srcdir)/polygon.h $(srcdir)/preface.h
141
- TARGET = geos_c_impl
142
- TARGET_NAME = geos_c_impl
143
- TARGET_ENTRY = Init_$(TARGET_NAME)
144
- DLLIB = $(TARGET).bundle
145
- EXTSTATIC =
146
- STATIC_LIB =
147
-
148
- TIMESTAMP_DIR = .
149
- BINDIR = $(bindir)
150
- RUBYCOMMONDIR = $(sitedir)$(target_prefix)
151
- RUBYLIBDIR = $(sitelibdir)$(target_prefix)
152
- RUBYARCHDIR = $(sitearchdir)$(target_prefix)
153
- HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
154
- ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
155
-
156
- TARGET_SO = $(DLLIB)
157
- CLEANLIBS = $(TARGET).bundle
158
- CLEANOBJS = *.o *.bak
159
-
160
- all: $(DLLIB)
161
- static: $(STATIC_LIB)
162
- .PHONY: all install static install-so install-rb
163
- .PHONY: clean clean-so clean-static clean-rb
164
-
165
- clean-static::
166
- clean-rb-default::
167
- clean-rb::
168
- clean-so::
169
- clean: clean-so clean-static clean-rb-default clean-rb
170
- -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
171
-
172
- distclean-rb-default::
173
- distclean-rb::
174
- distclean-so::
175
- distclean-static::
176
- distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
177
- -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
178
- -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
179
- -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
180
-
181
- realclean: distclean
182
- install: install-so install-rb
183
-
184
- install-so: $(DLLIB) $(TIMESTAMP_DIR)/.RUBYARCHDIR.-.rgeo.-.geos.time
185
- $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
186
- clean-static::
187
- -$(Q)$(RM) $(STATIC_LIB)
188
- install-rb: pre-install-rb install-rb-default
189
- install-rb-default: pre-install-rb-default
190
- pre-install-rb: Makefile
191
- pre-install-rb-default: Makefile
192
- pre-install-rb-default:
193
- @$(NULLCMD)
194
- $(TIMESTAMP_DIR)/.RUBYARCHDIR.-.rgeo.-.geos.time:
195
- $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
196
- $(Q) $(TOUCH) $@
197
-
198
- site-install: site-install-so site-install-rb
199
- site-install-so: install-so
200
- site-install-rb: install-rb
201
-
202
- .SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
203
-
204
- .cc.o:
205
- $(ECHO) compiling $(<)
206
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
207
-
208
- .cc.S:
209
- $(ECHO) translating $(<)
210
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
211
-
212
- .mm.o:
213
- $(ECHO) compiling $(<)
214
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
215
-
216
- .mm.S:
217
- $(ECHO) translating $(<)
218
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
219
-
220
- .cxx.o:
221
- $(ECHO) compiling $(<)
222
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
223
-
224
- .cxx.S:
225
- $(ECHO) translating $(<)
226
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
227
-
228
- .cpp.o:
229
- $(ECHO) compiling $(<)
230
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
231
-
232
- .cpp.S:
233
- $(ECHO) translating $(<)
234
- $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $<
235
-
236
- .c.o:
237
- $(ECHO) compiling $(<)
238
- $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
239
-
240
- .c.S:
241
- $(ECHO) translating $(<)
242
- $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $<
243
-
244
- .m.o:
245
- $(ECHO) compiling $(<)
246
- $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
247
-
248
- .m.S:
249
- $(ECHO) translating $(<)
250
- $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $<
251
-
252
- $(DLLIB): $(OBJS) Makefile
253
- $(ECHO) linking shared-object rgeo/geos/$(DLLIB)
254
- -$(Q)$(RM) $(@)
255
- $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
256
- $(Q) $(POSTLINK)
257
-
258
-
259
-
260
- $(OBJS): $(HDRS) $(ruby_headers)
@@ -1,65 +0,0 @@
1
- #include <ruby.h>
2
- #include <geos_c.h>
3
-
4
-
5
- VALUE extract_points_from_coordinate_sequence(GEOSContextHandle_t context, const GEOSCoordSequence* coord_sequence, int zCoordinate)
6
- {
7
- VALUE result = Qnil;
8
- VALUE point;
9
- unsigned int count;
10
- unsigned int i;
11
- double val;
12
-
13
- if(GEOSCoordSeq_getSize_r(context, coord_sequence, &count)) {
14
- result = rb_ary_new2(count);
15
- for(i = 0; i < count; ++i) {
16
- if(zCoordinate) {
17
- point = rb_ary_new2(3);
18
- } else {
19
- point = rb_ary_new2(2);
20
- }
21
- GEOSCoordSeq_getX_r(context, coord_sequence, i, &val);
22
- rb_ary_push(point, rb_float_new(val));
23
- GEOSCoordSeq_getY_r(context, coord_sequence, i, &val);
24
- rb_ary_push(point, rb_float_new(val));
25
- if(zCoordinate) {
26
- GEOSCoordSeq_getZ_r(context, coord_sequence, i, &val);
27
- rb_ary_push(point, rb_float_new(val));
28
- }
29
- rb_ary_push(result, point);
30
- }
31
- }
32
-
33
- return result;
34
- }
35
-
36
- VALUE extract_points_from_polygon(GEOSContextHandle_t context, const GEOSGeometry* polygon, int zCoordinate)
37
- {
38
- VALUE result = Qnil;
39
-
40
- const GEOSGeometry* ring;
41
- const GEOSCoordSequence* coord_sequence;
42
- unsigned int interior_ring_count;
43
- unsigned int i;
44
-
45
- if (polygon) {
46
- ring = GEOSGetExteriorRing_r(context, polygon);
47
- coord_sequence = GEOSGeom_getCoordSeq_r(context, ring);
48
-
49
- if(coord_sequence) {
50
- interior_ring_count = GEOSGetNumInteriorRings_r(context, polygon);
51
- result = rb_ary_new2(interior_ring_count + 1); // exterior + inner rings
52
-
53
- rb_ary_push(result, extract_points_from_coordinate_sequence(context, coord_sequence, zCoordinate));
54
-
55
- for(i = 0; i < interior_ring_count; ++i) {
56
- ring = GEOSGetInteriorRingN_r(context, polygon, i);
57
- coord_sequence = GEOSGeom_getCoordSeq_r(context, ring);
58
- if(coord_sequence) {
59
- rb_ary_push(result, extract_points_from_coordinate_sequence(context, coord_sequence, zCoordinate));
60
- }
61
- }
62
- }
63
- }
64
- return result;
65
- }
@@ -1,2 +0,0 @@
1
- VALUE extract_points_from_coordinate_sequence(GEOSContextHandle_t context, const GEOSCoordSequence* coord_sequence, int zCoordinate);
2
- VALUE extract_points_from_polygon(GEOSContextHandle_t context, const GEOSGeometry* polygon, int zCoordinate);
@@ -1,995 +0,0 @@
1
- /*
2
- Factory and utility functions for GEOS wrapper
3
- */
4
-
5
-
6
- #include "preface.h"
7
-
8
- #ifdef RGEO_GEOS_SUPPORTED
9
-
10
- #include <ruby.h>
11
- #include <geos_c.h>
12
-
13
- #include "factory.h"
14
- #include "geometry.h"
15
- #include "point.h"
16
- #include "line_string.h"
17
- #include "polygon.h"
18
- #include "geometry_collection.h"
19
-
20
- RGEO_BEGIN_C
21
-
22
-
23
- /**** RUBY AND GEOS CALLBACKS ****/
24
-
25
-
26
- // NOP message handler. GEOS requires that a message handler be set
27
- // for every context handle.
28
-
29
- static void message_handler(const char* fmt, ...)
30
- {
31
- }
32
-
33
-
34
- // Destroy function for factory data. We destroy any serialization
35
- // objects that have been created for the factory, and then destroy
36
- // the GEOS context, before freeing the factory data itself.
37
-
38
- static void destroy_factory_func(RGeo_FactoryData* data)
39
- {
40
- GEOSContextHandle_t context;
41
-
42
- context = data->geos_context;
43
- if (data->wkt_reader) {
44
- GEOSWKTReader_destroy_r(context, data->wkt_reader);
45
- }
46
- if (data->wkb_reader) {
47
- GEOSWKBReader_destroy_r(context, data->wkb_reader);
48
- }
49
- if (data->wkt_writer) {
50
- GEOSWKTWriter_destroy_r(context, data->wkt_writer);
51
- }
52
- if (data->wkb_writer) {
53
- GEOSWKBWriter_destroy_r(context, data->wkb_writer);
54
- }
55
- if (data->psych_wkt_reader) {
56
- GEOSWKTReader_destroy_r(context, data->psych_wkt_reader);
57
- }
58
- if (data->marshal_wkb_reader) {
59
- GEOSWKBReader_destroy_r(context, data->marshal_wkb_reader);
60
- }
61
- if (data->psych_wkt_writer) {
62
- GEOSWKTWriter_destroy_r(context, data->psych_wkt_writer);
63
- }
64
- if (data->marshal_wkb_writer) {
65
- GEOSWKBWriter_destroy_r(context, data->marshal_wkb_writer);
66
- }
67
- finishGEOS_r(context);
68
- free(data);
69
- }
70
-
71
-
72
- // Destroy function for geometry data. We destroy the internal
73
- // GEOS geometry (if present) before freeing the data itself.
74
-
75
- static void destroy_geometry_func(RGeo_GeometryData* data)
76
- {
77
- const GEOSPreparedGeometry* prep;
78
-
79
- if (data->geom) {
80
- GEOSGeom_destroy_r(data->geos_context, data->geom);
81
- }
82
- prep = data->prep;
83
- if (prep && prep != (const GEOSPreparedGeometry*)1 && prep != (const GEOSPreparedGeometry*)2 &&
84
- prep != (const GEOSPreparedGeometry*)3)
85
- {
86
- GEOSPreparedGeom_destroy_r(data->geos_context, prep);
87
- }
88
- free(data);
89
- }
90
-
91
-
92
- // Mark function for factory data. This marks the wkt and wkb generator
93
- // handles so they don't get collected.
94
-
95
- static void mark_factory_func(RGeo_FactoryData* data)
96
- {
97
- if (!NIL_P(data->wkrep_wkt_generator)) {
98
- rb_gc_mark(data->wkrep_wkt_generator);
99
- }
100
- if (!NIL_P(data->wkrep_wkb_generator)) {
101
- rb_gc_mark(data->wkrep_wkb_generator);
102
- }
103
- if (!NIL_P(data->wkrep_wkt_parser)) {
104
- rb_gc_mark(data->wkrep_wkt_parser);
105
- }
106
- if (!NIL_P(data->wkrep_wkb_parser)) {
107
- rb_gc_mark(data->wkrep_wkb_parser);
108
- }
109
- if (!NIL_P(data->proj4_obj)) {
110
- rb_gc_mark(data->proj4_obj);
111
- }
112
- if (!NIL_P(data->coord_sys_obj)) {
113
- rb_gc_mark(data->coord_sys_obj);
114
- }
115
- }
116
-
117
-
118
- // Mark function for geometry data. This marks the factory and klasses
119
- // held by the geometry so those don't get collected.
120
-
121
- static void mark_geometry_func(RGeo_GeometryData* data)
122
- {
123
- if (!NIL_P(data->factory)) {
124
- rb_gc_mark(data->factory);
125
- }
126
- if (!NIL_P(data->klasses)) {
127
- rb_gc_mark(data->klasses);
128
- }
129
- }
130
-
131
-
132
- // Destroy function for globals data. We don't need to destroy any
133
- // auxiliary data for now...
134
-
135
- static void destroy_globals_func(RGeo_Globals* data)
136
- {
137
- free(data);
138
- }
139
-
140
-
141
- // Mark function for globals data. This should mark any globals that
142
- // need to be held through garbage collection (none at the moment.)
143
-
144
- static void mark_globals_func(RGeo_Globals* data)
145
- {
146
- }
147
-
148
-
149
- /**** RUBY METHOD DEFINITIONS ****/
150
-
151
-
152
- static VALUE method_factory_srid(VALUE self)
153
- {
154
- return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->srid);
155
- }
156
-
157
-
158
- static VALUE method_factory_buffer_resolution(VALUE self)
159
- {
160
- return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->buffer_resolution);
161
- }
162
-
163
-
164
- static VALUE method_factory_flags(VALUE self)
165
- {
166
- return INT2NUM(RGEO_FACTORY_DATA_PTR(self)->flags);
167
- }
168
-
169
-
170
- static VALUE method_factory_parse_wkt(VALUE self, VALUE str)
171
- {
172
- RGeo_FactoryData* self_data;
173
- GEOSContextHandle_t self_context;
174
- GEOSWKTReader* wkt_reader;
175
- VALUE result;
176
- GEOSGeometry* geom;
177
-
178
- Check_Type(str, T_STRING);
179
- self_data = RGEO_FACTORY_DATA_PTR(self);
180
- self_context = self_data->geos_context;
181
- wkt_reader = self_data->wkt_reader;
182
- if (!wkt_reader) {
183
- wkt_reader = GEOSWKTReader_create_r(self_context);
184
- self_data->wkt_reader = wkt_reader;
185
- }
186
- result = Qnil;
187
- if (wkt_reader) {
188
- geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str));
189
- if (geom) {
190
- result = rgeo_wrap_geos_geometry(self, geom, Qnil);
191
- }
192
- }
193
- return result;
194
- }
195
-
196
-
197
- static VALUE method_factory_parse_wkb(VALUE self, VALUE str)
198
- {
199
- RGeo_FactoryData* self_data;
200
- GEOSContextHandle_t self_context;
201
- GEOSWKBReader* wkb_reader;
202
- VALUE result;
203
- GEOSGeometry* geom;
204
-
205
- Check_Type(str, T_STRING);
206
- self_data = RGEO_FACTORY_DATA_PTR(self);
207
- self_context = self_data->geos_context;
208
- wkb_reader = self_data->wkb_reader;
209
- if (!wkb_reader) {
210
- wkb_reader = GEOSWKBReader_create_r(self_context);
211
- self_data->wkb_reader = wkb_reader;
212
- }
213
- result = Qnil;
214
- if (wkb_reader) {
215
- geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
216
- if (geom) {
217
- result = rgeo_wrap_geos_geometry(self, geom, Qnil);
218
- }
219
- }
220
- return result;
221
- }
222
-
223
-
224
- static VALUE method_factory_read_for_marshal(VALUE self, VALUE str)
225
- {
226
- RGeo_FactoryData* self_data;
227
- GEOSContextHandle_t self_context;
228
- GEOSWKBReader* wkb_reader;
229
- VALUE result;
230
- GEOSGeometry* geom;
231
-
232
- Check_Type(str, T_STRING);
233
- self_data = RGEO_FACTORY_DATA_PTR(self);
234
- self_context = self_data->geos_context;
235
- wkb_reader = self_data->marshal_wkb_reader;
236
- if (!wkb_reader) {
237
- wkb_reader = GEOSWKBReader_create_r(self_context);
238
- self_data->marshal_wkb_reader = wkb_reader;
239
- }
240
- result = Qnil;
241
- if (wkb_reader) {
242
- geom = GEOSWKBReader_read_r(self_context, wkb_reader, (unsigned char*)RSTRING_PTR(str), (size_t)RSTRING_LEN(str));
243
- if (geom) {
244
- result = rgeo_wrap_geos_geometry(self, geom, Qnil);
245
- }
246
- }
247
- return result;
248
- }
249
-
250
-
251
- static VALUE method_factory_read_for_psych(VALUE self, VALUE str)
252
- {
253
- RGeo_FactoryData* self_data;
254
- GEOSContextHandle_t self_context;
255
- GEOSWKTReader* wkt_reader;
256
- VALUE result;
257
- GEOSGeometry* geom;
258
-
259
- Check_Type(str, T_STRING);
260
- self_data = RGEO_FACTORY_DATA_PTR(self);
261
- self_context = self_data->geos_context;
262
- wkt_reader = self_data->psych_wkt_reader;
263
- if (!wkt_reader) {
264
- wkt_reader = GEOSWKTReader_create_r(self_context);
265
- self_data->psych_wkt_reader = wkt_reader;
266
- }
267
- result = Qnil;
268
- if (wkt_reader) {
269
- geom = GEOSWKTReader_read_r(self_context, wkt_reader, RSTRING_PTR(str));
270
- if (geom) {
271
- result = rgeo_wrap_geos_geometry(self, geom, Qnil);
272
- }
273
- }
274
- return result;
275
- }
276
-
277
-
278
- static VALUE method_factory_write_for_marshal(VALUE self, VALUE obj)
279
- {
280
- RGeo_FactoryData* self_data;
281
- GEOSContextHandle_t self_context;
282
- GEOSWKBWriter* wkb_writer;
283
- const GEOSGeometry* geom;
284
- VALUE result;
285
- char* str;
286
- size_t size;
287
- char has_3d;
288
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
289
- RGeo_Globals* globals;
290
- VALUE wkb_generator;
291
- #endif
292
-
293
- self_data = RGEO_FACTORY_DATA_PTR(self);
294
- self_context = self_data->geos_context;
295
- has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
296
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
297
- if (has_3d) {
298
- globals = self_data->globals;
299
- wkb_generator = globals->marshal_wkb_generator;
300
- if (NIL_P(wkb_generator)) {
301
- wkb_generator = rb_funcall(
302
- rb_const_get_at(globals->geos_module, rb_intern("Utils")),
303
- rb_intern("marshal_wkb_generator"), 0);
304
- globals->marshal_wkb_generator = wkb_generator;
305
- }
306
- return rb_funcall(wkb_generator, globals->id_generate, 1, obj);
307
- }
308
- #endif
309
- wkb_writer = self_data->marshal_wkb_writer;
310
- if (!wkb_writer) {
311
- wkb_writer = GEOSWKBWriter_create_r(self_context);
312
- if (has_3d) {
313
- GEOSWKBWriter_setOutputDimension_r(self_context, wkb_writer, 3);
314
- }
315
- self_data->marshal_wkb_writer = wkb_writer;
316
- }
317
- result = Qnil;
318
- if (wkb_writer) {
319
- geom = rgeo_get_geos_geometry_safe(obj);
320
- if (geom) {
321
- str = (char*)GEOSWKBWriter_write_r(self_context, wkb_writer, geom, &size);
322
- if (str) {
323
- result = rb_str_new(str, size);
324
- GEOSFree_r(self_context, str);
325
- }
326
- }
327
- }
328
- return result;
329
- }
330
-
331
-
332
- static VALUE method_factory_write_for_psych(VALUE self, VALUE obj)
333
- {
334
- RGeo_FactoryData* self_data;
335
- GEOSContextHandle_t self_context;
336
- GEOSWKTWriter* wkt_writer;
337
- const GEOSGeometry* geom;
338
- VALUE result;
339
- char* str;
340
- size_t size;
341
- char has_3d;
342
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
343
- RGeo_Globals* globals;
344
- VALUE wkt_generator;
345
- #endif
346
-
347
- self_data = RGEO_FACTORY_DATA_PTR(self);
348
- self_context = self_data->geos_context;
349
- has_3d = self_data->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M;
350
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
351
- if (has_3d) {
352
- globals = self_data->globals;
353
- wkt_generator = globals->psych_wkt_generator;
354
- if (NIL_P(wkt_generator)) {
355
- wkt_generator = rb_funcall(
356
- rb_const_get_at(globals->geos_module, rb_intern("Utils")),
357
- rb_intern("psych_wkt_generator"), 0);
358
- globals->psych_wkt_generator = wkt_generator;
359
- }
360
- return rb_funcall(wkt_generator, globals->id_generate, 1, obj);
361
- }
362
- #endif
363
- wkt_writer = self_data->psych_wkt_writer;
364
- if (!wkt_writer) {
365
- wkt_writer = GEOSWKTWriter_create_r(self_context);
366
- if (has_3d) {
367
- GEOSWKTWriter_setOutputDimension_r(self_context, wkt_writer, 3);
368
- }
369
- self_data->psych_wkt_writer = wkt_writer;
370
- }
371
- result = Qnil;
372
- if (wkt_writer) {
373
- geom = rgeo_get_geos_geometry_safe(obj);
374
- if (geom) {
375
- str = GEOSWKTWriter_write_r(self_context, wkt_writer, geom);
376
- if (str) {
377
- result = rb_str_new2(str);
378
- GEOSFree_r(self_context, str);
379
- }
380
- }
381
- }
382
- return result;
383
- }
384
-
385
-
386
- static VALUE cmethod_factory_geos_version(VALUE klass)
387
- {
388
- return rb_str_new2(GEOS_VERSION);
389
- }
390
-
391
-
392
- static VALUE cmethod_factory_create(VALUE klass, VALUE flags, VALUE srid, VALUE buffer_resolution,
393
- VALUE wkt_generator, VALUE wkb_generator, VALUE proj4_obj, VALUE coord_sys_obj)
394
- {
395
- VALUE result;
396
- RGeo_FactoryData* data;
397
- GEOSContextHandle_t context;
398
- VALUE wrapped_globals;
399
-
400
- result = Qnil;
401
- data = ALLOC(RGeo_FactoryData);
402
- if (data) {
403
- context = initGEOS_r(message_handler, message_handler);
404
- if (context) {
405
- wrapped_globals = rb_const_get_at(klass, rb_intern("INTERNAL_CGLOBALS"));
406
- data->globals = (RGeo_Globals*)DATA_PTR(wrapped_globals);
407
- data->geos_context = context;
408
- data->flags = NUM2INT(flags);
409
- data->srid = NUM2INT(srid);
410
- data->buffer_resolution = NUM2INT(buffer_resolution);
411
- data->wkt_reader = NULL;
412
- data->wkb_reader = NULL;
413
- data->wkt_writer = NULL;
414
- data->wkb_writer = NULL;
415
- data->psych_wkt_reader = NULL;
416
- data->marshal_wkb_reader = NULL;
417
- data->psych_wkt_writer = NULL;
418
- data->marshal_wkb_writer = NULL;
419
- data->wkrep_wkt_generator = wkt_generator;
420
- data->wkrep_wkb_generator = wkb_generator;
421
- data->wkrep_wkt_parser = Qnil;
422
- data->wkrep_wkb_parser = Qnil;
423
- data->proj4_obj = proj4_obj;
424
- data->coord_sys_obj = coord_sys_obj;
425
- result = Data_Wrap_Struct(klass, mark_factory_func, destroy_factory_func, data);
426
- }
427
- else {
428
- free(data);
429
- }
430
- }
431
- return result;
432
- }
433
-
434
-
435
- static VALUE alloc_factory(VALUE klass)
436
- {
437
- return cmethod_factory_create(klass, INT2NUM(0), INT2NUM(0), INT2NUM(0), Qnil, Qnil, Qnil, Qnil);
438
- }
439
-
440
-
441
- static VALUE method_factory_initialize_copy(VALUE self, VALUE orig)
442
- {
443
- RGeo_FactoryData* self_data;
444
- RGeo_FactoryData* orig_data;
445
- GEOSContextHandle_t context;
446
-
447
- // Clear out existing data
448
- self_data = RGEO_FACTORY_DATA_PTR(self);
449
- context = self_data->geos_context;
450
- if (self_data->wkt_reader) {
451
- GEOSWKTReader_destroy_r(context, self_data->wkt_reader);
452
- self_data->wkt_reader = NULL;
453
- }
454
- if (self_data->wkb_reader) {
455
- GEOSWKBReader_destroy_r(context, self_data->wkb_reader);
456
- self_data->wkb_reader = NULL;
457
- }
458
- if (self_data->wkt_writer) {
459
- GEOSWKTWriter_destroy_r(context, self_data->wkt_writer);
460
- self_data->wkt_writer = NULL;
461
- }
462
- if (self_data->wkb_writer) {
463
- GEOSWKBWriter_destroy_r(context, self_data->wkb_writer);
464
- self_data->wkb_writer = NULL;
465
- }
466
- if (self_data->psych_wkt_reader) {
467
- GEOSWKTReader_destroy_r(context, self_data->psych_wkt_reader);
468
- self_data->psych_wkt_reader = NULL;
469
- }
470
- if (self_data->marshal_wkb_reader) {
471
- GEOSWKBReader_destroy_r(context, self_data->marshal_wkb_reader);
472
- self_data->marshal_wkb_reader = NULL;
473
- }
474
- if (self_data->psych_wkt_writer) {
475
- GEOSWKTWriter_destroy_r(context, self_data->psych_wkt_writer);
476
- self_data->psych_wkt_writer = NULL;
477
- }
478
- if (self_data->marshal_wkb_writer) {
479
- GEOSWKBWriter_destroy_r(context, self_data->marshal_wkb_writer);
480
- self_data->marshal_wkb_writer = NULL;
481
- }
482
- self_data->wkrep_wkt_generator = Qnil;
483
- self_data->wkrep_wkb_generator = Qnil;
484
- self_data->wkrep_wkt_parser = Qnil;
485
- self_data->wkrep_wkb_parser = Qnil;
486
- self_data->proj4_obj = Qnil;
487
- self_data->coord_sys_obj = Qnil;
488
-
489
- // Copy new data from original object
490
- if (TYPE(orig) == T_DATA && RDATA(orig)->dfree == (RUBY_DATA_FUNC)destroy_factory_func) {
491
- orig_data = RGEO_FACTORY_DATA_PTR(orig);
492
- self_data->flags = orig_data->flags;
493
- self_data->srid = orig_data->srid;
494
- self_data->buffer_resolution = orig_data->buffer_resolution;
495
- self_data->wkrep_wkt_generator = orig_data->wkrep_wkt_generator;
496
- self_data->wkrep_wkb_generator = orig_data->wkrep_wkb_generator;
497
- self_data->wkrep_wkt_parser = orig_data->wkrep_wkt_parser;
498
- self_data->wkrep_wkb_parser = orig_data->wkrep_wkb_parser;
499
- self_data->proj4_obj = orig_data->proj4_obj;
500
- self_data->coord_sys_obj = orig_data->coord_sys_obj;
501
- }
502
- return self;
503
- }
504
-
505
-
506
- static VALUE method_set_wkrep_parsers(VALUE self, VALUE wkt_parser, VALUE wkb_parser)
507
- {
508
- RGeo_FactoryData* self_data;
509
-
510
- self_data = RGEO_FACTORY_DATA_PTR(self);
511
- self_data->wkrep_wkt_parser = wkt_parser;
512
- self_data->wkrep_wkb_parser = wkb_parser;
513
-
514
- return self;
515
- }
516
-
517
-
518
- static VALUE method_get_proj4(VALUE self)
519
- {
520
- return RGEO_FACTORY_DATA_PTR(self)->proj4_obj;
521
- }
522
-
523
-
524
- static VALUE method_get_coord_sys(VALUE self)
525
- {
526
- return RGEO_FACTORY_DATA_PTR(self)->coord_sys_obj;
527
- }
528
-
529
-
530
- static VALUE method_get_wkt_generator(VALUE self)
531
- {
532
- return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkt_generator;
533
- }
534
-
535
-
536
- static VALUE method_get_wkb_generator(VALUE self)
537
- {
538
- return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkb_generator;
539
- }
540
-
541
-
542
- static VALUE method_get_wkt_parser(VALUE self)
543
- {
544
- return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkt_parser;
545
- }
546
-
547
-
548
- static VALUE method_get_wkb_parser(VALUE self)
549
- {
550
- return RGEO_FACTORY_DATA_PTR(self)->wkrep_wkb_parser;
551
- }
552
-
553
-
554
- static VALUE alloc_geometry(VALUE klass)
555
- {
556
- return rgeo_wrap_geos_geometry(Qnil, NULL, klass);
557
- }
558
-
559
-
560
- /**** INITIALIZATION FUNCTION ****/
561
-
562
-
563
- RGeo_Globals* rgeo_init_geos_factory()
564
- {
565
- RGeo_Globals* globals;
566
- VALUE rgeo_module;
567
- VALUE geos_factory_class;
568
- VALUE wrapped_globals;
569
- VALUE feature_module;
570
-
571
- globals = ALLOC(RGeo_Globals);
572
-
573
- // Cache some modules so we don't have to look them up by name every time
574
- rgeo_module = rb_define_module("RGeo");
575
- feature_module = rb_define_module_under(rgeo_module, "Feature");
576
- globals->feature_module = feature_module;
577
- globals->geos_module = rb_define_module_under(rgeo_module, "Geos");
578
- globals->feature_geometry = rb_const_get_at(feature_module, rb_intern("Geometry"));
579
- globals->feature_point = rb_const_get_at(feature_module, rb_intern("Point"));
580
- globals->feature_line_string = rb_const_get_at(feature_module, rb_intern("LineString"));
581
- globals->feature_linear_ring = rb_const_get_at(feature_module, rb_intern("LinearRing"));
582
- globals->feature_line = rb_const_get_at(feature_module, rb_intern("Line"));
583
- globals->feature_polygon = rb_const_get_at(feature_module, rb_intern("Polygon"));
584
- globals->feature_geometry_collection = rb_const_get_at(feature_module, rb_intern("GeometryCollection"));
585
- globals->feature_multi_point = rb_const_get_at(feature_module, rb_intern("MultiPoint"));
586
- globals->feature_multi_line_string = rb_const_get_at(feature_module, rb_intern("MultiLineString"));
587
- globals->feature_multi_polygon = rb_const_get_at(feature_module, rb_intern("MultiPolygon"));
588
-
589
- // Cache some commonly used names
590
- globals->id_cast = rb_intern("cast");
591
- globals->id_eql = rb_intern("eql?");
592
- globals->id_generate = rb_intern("generate");
593
- globals->id_enum_for = rb_intern("enum_for");
594
- globals->id_hash = rb_intern("hash");
595
- globals->sym_force_new = ID2SYM(rb_intern("force_new"));
596
- globals->sym_keep_subtype = ID2SYM(rb_intern("keep_subtype"));
597
- #ifndef RGEO_GEOS_SUPPORTS_SETOUTPUTDIMENSION
598
- globals->psych_wkt_generator = Qnil;
599
- globals->marshal_wkb_generator = Qnil;
600
- #endif
601
-
602
- // Add C methods to the factory.
603
- geos_factory_class = rb_define_class_under(globals->geos_module, "CAPIFactory", rb_cObject);
604
- rb_define_alloc_func(geos_factory_class, alloc_factory);
605
- rb_define_method(geos_factory_class, "initialize_copy", method_factory_initialize_copy, 1);
606
- rb_define_method(geos_factory_class, "_parse_wkt_impl", method_factory_parse_wkt, 1);
607
- rb_define_method(geos_factory_class, "_parse_wkb_impl", method_factory_parse_wkb, 1);
608
- rb_define_method(geos_factory_class, "_srid", method_factory_srid, 0);
609
- rb_define_method(geos_factory_class, "_buffer_resolution", method_factory_buffer_resolution, 0);
610
- rb_define_method(geos_factory_class, "_flags", method_factory_flags, 0);
611
- rb_define_method(geos_factory_class, "_set_wkrep_parsers", method_set_wkrep_parsers, 2);
612
- rb_define_method(geos_factory_class, "_proj4", method_get_proj4, 0);
613
- rb_define_method(geos_factory_class, "_coord_sys", method_get_coord_sys, 0);
614
- rb_define_method(geos_factory_class, "_wkt_generator", method_get_wkt_generator, 0);
615
- rb_define_method(geos_factory_class, "_wkb_generator", method_get_wkb_generator, 0);
616
- rb_define_method(geos_factory_class, "_wkt_parser", method_get_wkt_parser, 0);
617
- rb_define_method(geos_factory_class, "_wkb_parser", method_get_wkb_parser, 0);
618
- rb_define_method(geos_factory_class, "_read_for_marshal", method_factory_read_for_marshal, 1);
619
- rb_define_method(geos_factory_class, "_write_for_marshal", method_factory_write_for_marshal, 1);
620
- rb_define_method(geos_factory_class, "_read_for_psych", method_factory_read_for_psych, 1);
621
- rb_define_method(geos_factory_class, "_write_for_psych", method_factory_write_for_psych, 1);
622
- rb_define_module_function(geos_factory_class, "_create", cmethod_factory_create, 7);
623
- rb_define_module_function(geos_factory_class, "_geos_version", cmethod_factory_geos_version, 0);
624
-
625
- // Pre-define implementation classes and set up allocation methods
626
- globals->geos_geometry = rb_define_class_under(globals->geos_module, "CAPIGeometryImpl", rb_cObject);
627
- rb_define_alloc_func(globals->geos_geometry, alloc_geometry);
628
- globals->geos_point = rb_define_class_under(globals->geos_module, "CAPIPointImpl", rb_cObject);
629
- rb_define_alloc_func(globals->geos_point, alloc_geometry);
630
- globals->geos_line_string = rb_define_class_under(globals->geos_module, "CAPILineStringImpl", rb_cObject);
631
- rb_define_alloc_func(globals->geos_line_string, alloc_geometry);
632
- globals->geos_linear_ring = rb_define_class_under(globals->geos_module, "CAPILinearRingImpl", rb_cObject);
633
- rb_define_alloc_func(globals->geos_linear_ring, alloc_geometry);
634
- globals->geos_line = rb_define_class_under(globals->geos_module, "CAPILineImpl", rb_cObject);
635
- rb_define_alloc_func(globals->geos_line, alloc_geometry);
636
- globals->geos_polygon = rb_define_class_under(globals->geos_module, "CAPIPolygonImpl", rb_cObject);
637
- rb_define_alloc_func(globals->geos_polygon, alloc_geometry);
638
- globals->geos_geometry_collection = rb_define_class_under(globals->geos_module, "CAPIGeometryCollectionImpl", rb_cObject);
639
- rb_define_alloc_func(globals->geos_geometry_collection, alloc_geometry);
640
- globals->geos_multi_point = rb_define_class_under(globals->geos_module, "CAPIMultiPointImpl", rb_cObject);
641
- rb_define_alloc_func(globals->geos_multi_point, alloc_geometry);
642
- globals->geos_multi_line_string = rb_define_class_under(globals->geos_module, "CAPIMultiLineStringImpl", rb_cObject);
643
- rb_define_alloc_func(globals->geos_multi_line_string, alloc_geometry);
644
- globals->geos_multi_polygon = rb_define_class_under(globals->geos_module, "CAPIMultiPolygonImpl", rb_cObject);
645
- rb_define_alloc_func(globals->geos_multi_polygon, alloc_geometry);
646
-
647
- // Wrap the globals in a Ruby object and store it off so we have access
648
- // to it later. Each factory instance will reference it internally.
649
- wrapped_globals = Data_Wrap_Struct(rb_cObject, mark_globals_func, destroy_globals_func, globals);
650
- rb_define_const(geos_factory_class, "INTERNAL_CGLOBALS", wrapped_globals);
651
-
652
- return globals;
653
- }
654
-
655
-
656
- /**** OTHER PUBLIC FUNCTIONS ****/
657
-
658
-
659
- VALUE rgeo_wrap_geos_geometry(VALUE factory, GEOSGeometry* geom, VALUE klass)
660
- {
661
- VALUE result;
662
- RGeo_FactoryData* factory_data;
663
- GEOSContextHandle_t factory_context;
664
- VALUE klasses;
665
- RGeo_Globals* globals;
666
- VALUE inferred_klass;
667
- char is_collection;
668
- RGeo_GeometryData* data;
669
-
670
- result = Qnil;
671
- if (geom || !NIL_P(klass)) {
672
- factory_data = NIL_P(factory) ? NULL : RGEO_FACTORY_DATA_PTR(factory);
673
- factory_context = factory_data ? factory_data->geos_context : NULL;
674
- globals = factory_data ? factory_data->globals : NULL;
675
-
676
- // We don't allow "empty" points, so replace such objects with
677
- // an empty collection.
678
- if (geom && factory) {
679
- if (GEOSGeomTypeId_r(factory_context, geom) == GEOS_POINT && GEOSGetNumCoordinates_r(factory_context, geom) == 0) {
680
- GEOSGeom_destroy_r(factory_context, geom);
681
- geom = GEOSGeom_createCollection_r(factory_context, GEOS_GEOMETRYCOLLECTION, NULL, 0);
682
- klass = globals->geos_geometry_collection;
683
- }
684
- }
685
-
686
- klasses = Qnil;
687
- if (TYPE(klass) != T_CLASS) {
688
- inferred_klass = Qnil;
689
- is_collection = 0;
690
- switch (GEOSGeomTypeId_r(factory_context, geom)) {
691
- case GEOS_POINT:
692
- inferred_klass = globals->geos_point;
693
- break;
694
- case GEOS_LINESTRING:
695
- inferred_klass = globals->geos_line_string;
696
- break;
697
- case GEOS_LINEARRING:
698
- inferred_klass = globals->geos_linear_ring;
699
- break;
700
- case GEOS_POLYGON:
701
- inferred_klass = globals->geos_polygon;
702
- break;
703
- case GEOS_MULTIPOINT:
704
- inferred_klass = globals->geos_multi_point;
705
- is_collection = 1;
706
- break;
707
- case GEOS_MULTILINESTRING:
708
- inferred_klass = globals->geos_multi_line_string;
709
- is_collection = 1;
710
- break;
711
- case GEOS_MULTIPOLYGON:
712
- inferred_klass = globals->geos_multi_polygon;
713
- is_collection = 1;
714
- break;
715
- case GEOS_GEOMETRYCOLLECTION:
716
- inferred_klass = globals->geos_geometry_collection;
717
- is_collection = 1;
718
- break;
719
- default:
720
- inferred_klass = globals->geos_geometry;
721
- break;
722
- }
723
- if (TYPE(klass) == T_ARRAY && is_collection) {
724
- klasses = klass;
725
- }
726
- klass = inferred_klass;
727
- }
728
- data = ALLOC(RGeo_GeometryData);
729
- if (data) {
730
- if (geom) {
731
- GEOSSetSRID_r(factory_context, geom, factory_data->srid);
732
- }
733
- data->geos_context = factory_context;
734
- data->geom = geom;
735
- data->prep = factory_data && ((factory_data->flags & RGEO_FACTORYFLAGS_PREPARE_HEURISTIC) != 0) ?
736
- (GEOSPreparedGeometry*)1 : NULL;
737
- data->factory = factory;
738
- data->klasses = klasses;
739
- result = Data_Wrap_Struct(klass, mark_geometry_func, destroy_geometry_func, data);
740
- }
741
- }
742
- return result;
743
- }
744
-
745
-
746
- VALUE rgeo_wrap_geos_geometry_clone(VALUE factory, const GEOSGeometry* geom, VALUE klass)
747
- {
748
- VALUE result;
749
- GEOSGeometry* clone_geom;
750
-
751
- result = Qnil;
752
- if (geom) {
753
- clone_geom = GEOSGeom_clone_r(RGEO_FACTORY_DATA_PTR(factory)->geos_context, geom);
754
- if (clone_geom) {
755
- result = rgeo_wrap_geos_geometry(factory, clone_geom, klass);
756
- }
757
- }
758
- return result;
759
- }
760
-
761
-
762
- const GEOSGeometry* rgeo_convert_to_geos_geometry(VALUE factory, VALUE obj, VALUE type)
763
- {
764
- VALUE object;
765
- const GEOSGeometry* geom;
766
- RGeo_Globals* globals;
767
-
768
- if (NIL_P(type) && TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func && RGEO_GEOMETRY_DATA_PTR(obj)->factory == factory) {
769
- object = obj;
770
- }
771
- else {
772
- globals = RGEO_FACTORY_DATA_PTR(factory)->globals;
773
- object = rb_funcall(globals->feature_module, globals->id_cast, 3, obj, factory, type);
774
- }
775
- geom = NULL;
776
- if (!NIL_P(object)) {
777
- geom = RGEO_GEOMETRY_DATA_PTR(object)->geom;
778
- }
779
- return geom;
780
- }
781
-
782
-
783
- GEOSGeometry* rgeo_convert_to_detached_geos_geometry(VALUE obj, VALUE factory, VALUE type, VALUE* klasses)
784
- {
785
- VALUE object;
786
- GEOSGeometry* geom;
787
- RGeo_GeometryData* object_data;
788
- const GEOSPreparedGeometry* prep;
789
- RGeo_Globals* globals;
790
-
791
- if (klasses) {
792
- *klasses = Qnil;
793
- }
794
- globals = RGEO_FACTORY_DATA_PTR(factory)->globals;
795
- object = rb_funcall(globals->feature_module, globals->id_cast, 5, obj, factory, type, globals->sym_force_new, globals->sym_keep_subtype);
796
- geom = NULL;
797
- if (!NIL_P(object)) {
798
- object_data = RGEO_GEOMETRY_DATA_PTR(object);
799
- geom = object_data->geom;
800
- if (klasses) {
801
- *klasses = object_data->klasses;
802
- if (NIL_P(*klasses)) {
803
- *klasses = CLASS_OF(object);
804
- }
805
- }
806
- prep = object_data->prep;
807
- if (prep && prep != (GEOSPreparedGeometry*)1 && prep != (GEOSPreparedGeometry*)2) {
808
- GEOSPreparedGeom_destroy_r(object_data->geos_context, prep);
809
- }
810
- object_data->geos_context = NULL;
811
- object_data->geom = NULL;
812
- object_data->prep = NULL;
813
- object_data->factory = Qnil;
814
- object_data->klasses = Qnil;
815
- }
816
- return geom;
817
- }
818
-
819
-
820
- char rgeo_is_geos_object(VALUE obj)
821
- {
822
- return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? 1 : 0;
823
- }
824
-
825
-
826
- const GEOSGeometry* rgeo_get_geos_geometry_safe(VALUE obj)
827
- {
828
- return (TYPE(obj) == T_DATA && RDATA(obj)->dfree == (RUBY_DATA_FUNC)destroy_geometry_func) ? (const GEOSGeometry*)(RGEO_GEOMETRY_DATA_PTR(obj)->geom) : NULL;
829
- }
830
-
831
-
832
- VALUE rgeo_geos_coordseqs_eql(GEOSContextHandle_t context, const GEOSGeometry* geom1, const GEOSGeometry* geom2, char check_z)
833
- {
834
- VALUE result;
835
- const GEOSCoordSequence* cs1;
836
- const GEOSCoordSequence* cs2;
837
- unsigned int len1;
838
- unsigned int len2;
839
- unsigned int i;
840
- double val1, val2;
841
-
842
- result = Qnil;
843
- if (geom1 && geom2) {
844
- cs1 = GEOSGeom_getCoordSeq_r(context, geom1);
845
- cs2 = GEOSGeom_getCoordSeq_r(context, geom2);
846
- if (cs1 && cs2) {
847
- len1 = 0;
848
- len2 = 0;
849
- if (GEOSCoordSeq_getSize_r(context, cs1, &len1) && GEOSCoordSeq_getSize_r(context, cs2, &len2)) {
850
- if (len1 == len2) {
851
- result = Qtrue;
852
- for (i=0; i<len1; ++i) {
853
- if (GEOSCoordSeq_getX_r(context, cs1, i, &val1) && GEOSCoordSeq_getX_r(context, cs2, i, &val2)) {
854
- if (val1 == val2) {
855
- if (GEOSCoordSeq_getY_r(context, cs1, i, &val1) && GEOSCoordSeq_getY_r(context, cs2, i, &val2)) {
856
- if (val1 == val2) {
857
- if (check_z) {
858
- val1 = 0;
859
- if (!GEOSCoordSeq_getZ_r(context, cs1, i, &val1)) {
860
- result = Qnil;
861
- break;
862
- }
863
- val2 = 0;
864
- if (!GEOSCoordSeq_getZ_r(context, cs2, i, &val2)) {
865
- result = Qnil;
866
- break;
867
- }
868
- if (val1 != val2) {
869
- result = Qfalse;
870
- break;
871
- }
872
- }
873
- }
874
- else { // Y coords are different
875
- result = Qfalse;
876
- break;
877
- }
878
- }
879
- else { // Failed to get Y coords
880
- result = Qnil;
881
- break;
882
- }
883
- }
884
- else { // X coords are different
885
- result = Qfalse;
886
- break;
887
- }
888
- }
889
- else { // Failed to get X coords
890
- result = Qnil;
891
- break;
892
- }
893
- } // Iteration over coords
894
- }
895
- else { // Lengths are different
896
- result = Qfalse;
897
- }
898
- }
899
- }
900
- }
901
- return result;
902
- }
903
-
904
-
905
- VALUE rgeo_geos_klasses_and_factories_eql(VALUE obj1, VALUE obj2)
906
- {
907
- VALUE result;
908
- VALUE factory;
909
-
910
- result = Qnil;
911
- if (rb_obj_class(obj1) != rb_obj_class(obj2)) {
912
- result = Qfalse;
913
- }
914
- else {
915
- factory = RGEO_GEOMETRY_DATA_PTR(obj1)->factory;
916
- result = rb_funcall(factory, RGEO_FACTORY_DATA_PTR(factory)->globals->id_eql, 1, RGEO_GEOMETRY_DATA_PTR(obj2)->factory);
917
- }
918
- return result;
919
- }
920
-
921
-
922
- typedef struct {
923
- st_index_t seed_hash;
924
- double x;
925
- double y;
926
- double z;
927
- } RGeo_Coordseq_Hash_Struct;
928
-
929
- st_index_t rgeo_geos_coordseq_hash(GEOSContextHandle_t context, const GEOSGeometry* geom, st_index_t hash)
930
- {
931
- const GEOSCoordSequence* cs;
932
- unsigned int len;
933
- unsigned int i;
934
- RGeo_Coordseq_Hash_Struct hash_struct;
935
-
936
- if (geom) {
937
- cs = GEOSGeom_getCoordSeq_r(context, geom);
938
- if (cs) {
939
- if (GEOSCoordSeq_getSize_r(context, cs, &len)) {
940
- for (i=0; i<len; ++i) {
941
- if (GEOSCoordSeq_getX_r(context, cs, i, &hash_struct.x)) {
942
- if (GEOSCoordSeq_getY_r(context, cs, i, &hash_struct.y)) {
943
- if (!GEOSCoordSeq_getY_r(context, cs, i, &hash_struct.z)) {
944
- hash_struct.z = 0;
945
- }
946
- hash_struct.seed_hash = hash;
947
- hash = rb_memhash(&hash_struct, sizeof(RGeo_Coordseq_Hash_Struct));
948
- }
949
- }
950
- }
951
- }
952
- }
953
- }
954
- return hash;
955
- }
956
-
957
-
958
- typedef struct {
959
- st_index_t seed_hash;
960
- st_index_t h1;
961
- st_index_t h2;
962
- } RGeo_Objbase_Hash_Struct;
963
-
964
- st_index_t rgeo_geos_objbase_hash(VALUE factory, VALUE type_module, st_index_t hash)
965
- {
966
- ID hash_method;
967
- RGeo_Objbase_Hash_Struct hash_struct;
968
-
969
- hash_method = RGEO_FACTORY_DATA_PTR(factory)->globals->id_hash;
970
- hash_struct.seed_hash = hash;
971
- hash_struct.h1 = FIX2LONG(rb_funcall(factory, hash_method, 0));
972
- hash_struct.h2 = FIX2LONG(rb_funcall(type_module, hash_method, 0));
973
- return rb_memhash(&hash_struct, sizeof(RGeo_Objbase_Hash_Struct));
974
- }
975
-
976
-
977
- st_index_t rgeo_internal_memhash(const void* ptr, long len)
978
- {
979
- const char* bytes;
980
- st_index_t hval;
981
- long i;
982
-
983
- bytes = (const char*)ptr;
984
- hval = 0x811c9dc5;
985
- for (i=0; i<len; ++i) {
986
- hval ^= (unsigned int)(*bytes++);
987
- hval *= 0x01000193;
988
- }
989
- return hval;
990
- }
991
-
992
-
993
- RGEO_END_C
994
-
995
- #endif