rgeo 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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