rgeo 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.rdoc +11 -3
- data/Spatial_Programming_With_RGeo.rdoc +8 -8
- data/Version +1 -1
- data/ext/geos_c_impl/factory.c +20 -3
- data/ext/geos_c_impl/factory.h +2 -0
- data/ext/geos_c_impl/geometry.c +31 -19
- data/lib/rgeo/cartesian/factory.rb +32 -3
- data/lib/rgeo/cartesian/interface.rb +22 -2
- data/lib/rgeo/feature/factory.rb +1 -1
- data/lib/rgeo/feature/factory_generator.rb +1 -1
- data/lib/rgeo/feature/types.rb +3 -3
- data/lib/rgeo/geographic/factory.rb +31 -2
- data/lib/rgeo/geographic/interface.rb +68 -5
- data/lib/rgeo/geographic/proj4_projector.rb +8 -1
- data/lib/rgeo/geos.rb +1 -1
- data/lib/rgeo/geos/factory.rb +69 -4
- data/lib/rgeo/geos/impl_additions.rb +1 -1
- data/lib/rgeo/geos/interface.rb +31 -0
- data/lib/rgeo/geos/zm_factory.rb +33 -2
- data/lib/rgeo/geos/zm_impl.rb +3 -3
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +2 -2
- data/lib/rgeo/wkrep/wkb_generator.rb +1 -24
- data/lib/rgeo/wkrep/wkb_parser.rb +32 -43
- data/lib/rgeo/wkrep/wkt_generator.rb +21 -43
- data/lib/rgeo/wkrep/wkt_parser.rb +10 -41
- data/test/common/point_tests.rb +7 -1
- data/test/geos/tc_parsing_unparsing.rb +80 -0
- data/test/wkrep/tc_wkb_parser.rb +44 -37
- data/test/wkrep/tc_wkt_generator.rb +25 -25
- data/test/wkrep/tc_wkt_parser.rb +1 -3
- metadata +4 -2
@@ -82,7 +82,14 @@ module RGeo
|
|
82
82
|
|
83
83
|
|
84
84
|
def create_from_proj4(geography_factory_, proj4_, opts_={})
|
85
|
-
projection_factory_ = Cartesian.preferred_factory(:proj4 => proj4_,
|
85
|
+
projection_factory_ = Cartesian.preferred_factory(:proj4 => proj4_,
|
86
|
+
:coord_sys => opts_[:coord_sys], :srid => opts_[:srid],
|
87
|
+
:buffer_resolution => opts_[:buffer_resolution],
|
88
|
+
:lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions],
|
89
|
+
:has_z_coordinate => opts_[:has_z_coordinate],
|
90
|
+
:has_m_coordinate => opts_[:has_m_coordinate],
|
91
|
+
:wkt_parser => opts_[:wkt_parser], :wkt_generator => opts_[:wkt_generator],
|
92
|
+
:wkb_parser => opts_[:wkb_parser], :wkb_generator => opts_[:wkb_generator])
|
86
93
|
new(geography_factory_, projection_factory_)
|
87
94
|
end
|
88
95
|
|
data/lib/rgeo/geos.rb
CHANGED
@@ -51,7 +51,7 @@ module RGeo
|
|
51
51
|
# therefore not documented.
|
52
52
|
#
|
53
53
|
# To use the Geos implementation, first obtain a factory using the
|
54
|
-
# ::RGeo::Geos
|
54
|
+
# ::RGeo::Geos.factory method. You may then call any of the standard
|
55
55
|
# factory methods on the resulting object.
|
56
56
|
|
57
57
|
module Geos
|
data/lib/rgeo/geos/factory.rb
CHANGED
@@ -53,10 +53,13 @@ module RGeo
|
|
53
53
|
# Create a new factory. Returns nil if the GEOS implementation is
|
54
54
|
# not supported.
|
55
55
|
#
|
56
|
-
# See ::RGeo::Geos
|
56
|
+
# See ::RGeo::Geos.factory for a list of supported options.
|
57
57
|
|
58
58
|
def create(opts_={})
|
59
|
+
# Make sure GEOS is available
|
59
60
|
return nil unless respond_to?(:_create)
|
61
|
+
|
62
|
+
# Get flags to pass to the C extension
|
60
63
|
flags_ = 0
|
61
64
|
flags_ |= 1 if opts_[:lenient_multi_polygon_assertions]
|
62
65
|
flags_ |= 2 if opts_[:has_z_coordinate]
|
@@ -64,8 +67,32 @@ module RGeo
|
|
64
67
|
if flags_ & 6 == 6
|
65
68
|
raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
|
66
69
|
end
|
70
|
+
|
71
|
+
# Buffer resolution
|
67
72
|
buffer_resolution_ = opts_[:buffer_resolution].to_i
|
68
73
|
buffer_resolution_ = 1 if buffer_resolution_ < 1
|
74
|
+
|
75
|
+
# Interpret the generator options
|
76
|
+
wkt_generator_ = opts_[:wkt_generator]
|
77
|
+
case wkt_generator_
|
78
|
+
when :geos
|
79
|
+
wkt_generator_ = nil
|
80
|
+
when ::Hash
|
81
|
+
wkt_generator_ = WKRep::WKTGenerator.new(wkt_generator_)
|
82
|
+
else
|
83
|
+
wkt_generator_ = WKRep::WKTGenerator.new(:convert_case => :upper)
|
84
|
+
end
|
85
|
+
wkb_generator_ = opts_[:wkb_generator]
|
86
|
+
case wkb_generator_
|
87
|
+
when :geos
|
88
|
+
wkb_generator_ = nil
|
89
|
+
when ::Hash
|
90
|
+
wkb_generator_ = WKRep::WKBGenerator.new(wkb_generator_)
|
91
|
+
else
|
92
|
+
wkb_generator_ = WKRep::WKBGenerator.new
|
93
|
+
end
|
94
|
+
|
95
|
+
# Coordinate system (srid, proj4, and coord_sys)
|
69
96
|
srid_ = opts_[:srid]
|
70
97
|
proj4_ = opts_[:proj4]
|
71
98
|
if CoordSys::Proj4.supported?
|
@@ -87,9 +114,39 @@ module RGeo
|
|
87
114
|
end
|
88
115
|
end
|
89
116
|
srid_ ||= coord_sys_.authority_code if coord_sys_
|
90
|
-
|
117
|
+
|
118
|
+
# Create the factory and set instance variables
|
119
|
+
result_ = _create(flags_, srid_.to_i, buffer_resolution_, wkt_generator_, wkb_generator_)
|
120
|
+
|
121
|
+
# Interpret parser options
|
122
|
+
wkt_parser_ = opts_[:wkt_parser]
|
123
|
+
case wkt_parser_
|
124
|
+
when :geos
|
125
|
+
wkt_parser_ = nil
|
126
|
+
when ::Hash
|
127
|
+
wkt_parser_ = WKRep::WKTParser.new(result_, wkt_parser_)
|
128
|
+
else
|
129
|
+
wkt_parser_ = WKRep::WKTParser.new(result_)
|
130
|
+
end
|
131
|
+
wkb_parser_ = opts_[:wkb_parser]
|
132
|
+
case wkb_parser_
|
133
|
+
when :geos
|
134
|
+
wkb_parser_ = nil
|
135
|
+
when ::Hash
|
136
|
+
wkb_parser_ = WKRep::WKBParser.new(result_, wkb_parser_)
|
137
|
+
else
|
138
|
+
wkb_parser_ = WKRep::WKBParser.new(result_)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Set instance variables
|
91
142
|
result_.instance_variable_set(:@proj4, proj4_)
|
92
143
|
result_.instance_variable_set(:@coord_sys, coord_sys_)
|
144
|
+
result_.instance_variable_set(:@wkt_parser, wkt_parser_)
|
145
|
+
result_.instance_variable_set(:@wkb_parser, wkb_parser_)
|
146
|
+
result_.instance_variable_set(:@wkt_generator, wkt_generator_)
|
147
|
+
result_.instance_variable_set(:@wkb_generator, wkb_generator_)
|
148
|
+
|
149
|
+
# Return the result
|
93
150
|
result_
|
94
151
|
end
|
95
152
|
alias_method :new, :create
|
@@ -152,14 +209,22 @@ module RGeo
|
|
152
209
|
# See ::RGeo::Feature::Factory#parse_wkt
|
153
210
|
|
154
211
|
def parse_wkt(str_)
|
155
|
-
|
212
|
+
if @wkt_parser
|
213
|
+
@wkt_parser.parse(str_)
|
214
|
+
else
|
215
|
+
_parse_wkt_impl(str_)
|
216
|
+
end
|
156
217
|
end
|
157
218
|
|
158
219
|
|
159
220
|
# See ::RGeo::Feature::Factory#parse_wkb
|
160
221
|
|
161
222
|
def parse_wkb(str_)
|
162
|
-
|
223
|
+
if @wkb_parser
|
224
|
+
@wkb_parser.parse(str_)
|
225
|
+
else
|
226
|
+
_parse_wkb_impl(str_)
|
227
|
+
end
|
163
228
|
end
|
164
229
|
|
165
230
|
|
data/lib/rgeo/geos/interface.rb
CHANGED
@@ -105,6 +105,37 @@ module RGeo
|
|
105
105
|
# Support <tt>z_coordinate</tt>. Default is false.
|
106
106
|
# [<tt>:has_m_coordinate</tt>]
|
107
107
|
# Support <tt>m_coordinate</tt>. Default is false.
|
108
|
+
# [<tt>:wkt_parser</tt>]
|
109
|
+
# Configure the parser for WKT. You may either pass a hash of
|
110
|
+
# configuration parameters for WKRep::WKTParser.new, or the
|
111
|
+
# special value <tt>:geos</tt>, indicating to use the native
|
112
|
+
# GEOS parser. Default is the empty hash, indicating the default
|
113
|
+
# configuration for WKRep::WKTParser.
|
114
|
+
# Note that the special <tt>:geos</tt> value is not supported for
|
115
|
+
# ZM factories, since GEOS currently can't handle ZM natively.
|
116
|
+
# [<tt>:wkb_parser</tt>]
|
117
|
+
# Configure the parser for WKB. You may either pass a hash of
|
118
|
+
# configuration parameters for WKRep::WKBParser.new, or the
|
119
|
+
# special value <tt>:geos</tt>, indicating to use the native
|
120
|
+
# GEOS parser. Default is the empty hash, indicating the default
|
121
|
+
# configuration for WKRep::WKBParser.
|
122
|
+
# Note that the special <tt>:geos</tt> value is not supported for
|
123
|
+
# ZM factories, since GEOS currently can't handle ZM natively.
|
124
|
+
# [<tt>:wkt_generator</tt>]
|
125
|
+
# Configure the generator for WKT. You may either pass a hash of
|
126
|
+
# configuration parameters for WKRep::WKTGenerator.new, or the
|
127
|
+
# special value <tt>:geos</tt>, indicating to use the native
|
128
|
+
# GEOS generator. Default is <tt>{:convert_case => :upper}</tt>.
|
129
|
+
# Note that the special <tt>:geos</tt> value is not supported for
|
130
|
+
# ZM factories, since GEOS currently can't handle ZM natively.
|
131
|
+
# [<tt>:wkb_generator</tt>]
|
132
|
+
# Configure the generator for WKB. You may either pass a hash of
|
133
|
+
# configuration parameters for WKRep::WKBGenerator.new, or the
|
134
|
+
# special value <tt>:geos</tt>, indicating to use the native
|
135
|
+
# GEOS generator. Default is the empty hash, indicating the
|
136
|
+
# default configuration for WKRep::WKBGenerator.
|
137
|
+
# Note that the special <tt>:geos</tt> value is not supported for
|
138
|
+
# ZM factories, since GEOS currently can't handle ZM natively.
|
108
139
|
|
109
140
|
def factory(opts_={})
|
110
141
|
if supported?
|
data/lib/rgeo/geos/zm_factory.rb
CHANGED
@@ -76,10 +76,41 @@ module RGeo
|
|
76
76
|
config_ = {
|
77
77
|
:lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions],
|
78
78
|
:buffer_resolution => opts_[:buffer_resolution],
|
79
|
+
:wkt_generator => opts_[:wkt_generator], :wkt_parser => opts_[:wkt_parser],
|
80
|
+
:wkb_generator => opts_[:wkb_generator], :wkb_parser => opts_[:wkb_parser],
|
79
81
|
:srid => srid_.to_i, :proj4 => proj4_, :coord_sys => coord_sys_,
|
80
82
|
}
|
81
83
|
@zfactory = Factory.create(config_.merge(:has_z_coordinate => true))
|
82
84
|
@mfactory = Factory.create(config_.merge(:has_m_coordinate => true))
|
85
|
+
|
86
|
+
wkt_generator_ = opts_[:wkt_generator]
|
87
|
+
case wkt_generator_
|
88
|
+
when ::Hash
|
89
|
+
@wkt_generator = WKRep::WKTGenerator.new(wkt_generator_)
|
90
|
+
else
|
91
|
+
@wkt_generator = WKRep::WKTGenerator.new(:convert_case => :upper)
|
92
|
+
end
|
93
|
+
wkb_generator_ = opts_[:wkb_generator]
|
94
|
+
case wkb_generator_
|
95
|
+
when ::Hash
|
96
|
+
@wkb_generator = WKRep::WKBGenerator.new(wkb_generator_)
|
97
|
+
else
|
98
|
+
@wkb_generator = WKRep::WKBGenerator.new
|
99
|
+
end
|
100
|
+
wkt_parser_ = opts_[:wkt_parser]
|
101
|
+
case wkt_parser_
|
102
|
+
when ::Hash
|
103
|
+
@wkt_parser = WKRep::WKTParser.new(self, wkt_parser_)
|
104
|
+
else
|
105
|
+
@wkt_parser = WKRep::WKTParser.new(self)
|
106
|
+
end
|
107
|
+
wkb_parser_ = opts_[:wkb_parser]
|
108
|
+
case wkb_parser_
|
109
|
+
when ::Hash
|
110
|
+
@wkb_parser = WKRep::WKBParser.new(self, wkb_parser_)
|
111
|
+
else
|
112
|
+
@wkb_parser = WKRep::WKBParser.new(self)
|
113
|
+
end
|
83
114
|
end
|
84
115
|
|
85
116
|
|
@@ -142,14 +173,14 @@ module RGeo
|
|
142
173
|
# See ::RGeo::Feature::Factory#parse_wkt
|
143
174
|
|
144
175
|
def parse_wkt(str_)
|
145
|
-
|
176
|
+
@wkt_parser.parse(str_)
|
146
177
|
end
|
147
178
|
|
148
179
|
|
149
180
|
# See ::RGeo::Feature::Factory#parse_wkb
|
150
181
|
|
151
182
|
def parse_wkb(str_)
|
152
|
-
|
183
|
+
@wkb_parser.parse(str_)
|
153
184
|
end
|
154
185
|
|
155
186
|
|
data/lib/rgeo/geos/zm_impl.rb
CHANGED
@@ -101,12 +101,12 @@ module RGeo
|
|
101
101
|
|
102
102
|
|
103
103
|
def as_text
|
104
|
-
|
104
|
+
@factory.instance_variable_get(:@wkt_generator).generate(self)
|
105
105
|
end
|
106
106
|
|
107
107
|
|
108
108
|
def as_binary
|
109
|
-
|
109
|
+
@factory.instance_variable_get(:@wkb_generator).generate(self)
|
110
110
|
end
|
111
111
|
|
112
112
|
|
@@ -415,7 +415,7 @@ module RGeo
|
|
415
415
|
Feature::MultiPoint => ZMGeometryCollectionImpl,
|
416
416
|
Feature::MultiLineString => ZMMultiLineStringImpl,
|
417
417
|
Feature::MultiPolygon => ZMMultiPolygonImpl,
|
418
|
-
}
|
418
|
+
}.freeze
|
419
419
|
|
420
420
|
|
421
421
|
def self.create(factory_, zgeometry_, mgeometry_)
|
@@ -68,12 +68,12 @@ module RGeo
|
|
68
68
|
|
69
69
|
|
70
70
|
def as_text
|
71
|
-
|
71
|
+
@factory.instance_variable_get(:@wkt_generator).generate(self)
|
72
72
|
end
|
73
73
|
|
74
74
|
|
75
75
|
def as_binary
|
76
|
-
|
76
|
+
@factory.instance_variable_get(:@wkb_generator).generate(self)
|
77
77
|
end
|
78
78
|
|
79
79
|
|
@@ -85,7 +85,7 @@ module RGeo
|
|
85
85
|
Feature::MultiLineString => 5,
|
86
86
|
Feature::MultiPolygon => 6,
|
87
87
|
Feature::GeometryCollection => 7,
|
88
|
-
}
|
88
|
+
}.freeze
|
89
89
|
# :startdoc:
|
90
90
|
|
91
91
|
|
@@ -105,46 +105,23 @@ module RGeo
|
|
105
105
|
@type_format
|
106
106
|
end
|
107
107
|
|
108
|
-
# Sets the format for type codes. See WKBGenerator for details.
|
109
|
-
def type_format=(value_)
|
110
|
-
@type_format = value_
|
111
|
-
end
|
112
|
-
|
113
108
|
# Returns whether SRID is embedded. See WKBGenerator for details.
|
114
109
|
def emit_ewkb_srid?
|
115
110
|
@emit_ewkb_srid
|
116
111
|
end
|
117
112
|
|
118
|
-
# Sets whether SRID is embedded. Available only when the type_format
|
119
|
-
# is <tt>:ewkb</tt>. See WKBGenerator for details.
|
120
|
-
def emit_ewkb_srid=(value_)
|
121
|
-
@emit_ewkb_srid = @type_format == :ewkb && value_
|
122
|
-
end
|
123
|
-
|
124
113
|
# Returns whether output is converted to hex.
|
125
114
|
# See WKBGenerator for details.
|
126
115
|
def hex_format?
|
127
116
|
@hex_format
|
128
117
|
end
|
129
118
|
|
130
|
-
# Sets whether output is converted to hex.
|
131
|
-
# See WKBGenerator for details.
|
132
|
-
def hex_format=(value_)
|
133
|
-
@hex_format = value_ ? true : false
|
134
|
-
end
|
135
|
-
|
136
119
|
# Returns whether output is little-endian (NDR).
|
137
120
|
# See WKBGenerator for details.
|
138
121
|
def little_endian?
|
139
122
|
@little_endian
|
140
123
|
end
|
141
124
|
|
142
|
-
# Sets whether output is little-endian (NDR).
|
143
|
-
# See WKBGenerator for details.
|
144
|
-
def little_endian=(value_)
|
145
|
-
@little_endian = value_ ? true : false
|
146
|
-
end
|
147
|
-
|
148
125
|
|
149
126
|
# Generate and return the WKB format for the given geometry object,
|
150
127
|
# according to the current settings.
|
@@ -81,7 +81,16 @@ module RGeo
|
|
81
81
|
# documentation for the options that can be passed.
|
82
82
|
|
83
83
|
def initialize(factory_generator_=nil, opts_={})
|
84
|
-
|
84
|
+
if factory_generator_.kind_of?(Feature::Factory::Instance)
|
85
|
+
@factory_generator = Feature::FactoryGenerator.single(factory_generator_)
|
86
|
+
@exact_factory = factory_generator_
|
87
|
+
elsif factory_generator_.respond_to?(:call)
|
88
|
+
@factory_generator = factory_generator_
|
89
|
+
@exact_factory = nil
|
90
|
+
else
|
91
|
+
@factory_generator = Cartesian.method(:preferred_factory)
|
92
|
+
@exact_factory = nil
|
93
|
+
end
|
85
94
|
@support_ewkb = opts_[:support_ewkb] ? true : false
|
86
95
|
@support_wkb12 = opts_[:support_wkb12] ? true : false
|
87
96
|
@ignore_extra_bytes = opts_[:ignore_extra_bytes] ? true : false
|
@@ -100,70 +109,41 @@ module RGeo
|
|
100
109
|
@exact_factory
|
101
110
|
end
|
102
111
|
|
103
|
-
# Sets the factory_generator. See WKBParser for details.
|
104
|
-
def factory_generator=(value_)
|
105
|
-
if value_.kind_of?(Feature::Factory::Instance)
|
106
|
-
@factory_generator = Feature::FactoryGenerator.single(value_)
|
107
|
-
@exact_factory = value_
|
108
|
-
elsif value_.respond_to?(:call)
|
109
|
-
@factory_generator = value_
|
110
|
-
@exact_factory = nil
|
111
|
-
else
|
112
|
-
@factory_generator = Cartesian.method(:preferred_factory)
|
113
|
-
@exact_factory = nil
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
# Sets the factory_generator to the given block.
|
118
|
-
# See WKBParser for details.
|
119
|
-
def to_generate_factory(&block_)
|
120
|
-
@factory_generator = block_
|
121
|
-
end
|
122
|
-
|
123
112
|
# Returns true if this parser supports EWKB.
|
124
113
|
# See WKBParser for details.
|
125
114
|
def support_ewkb?
|
126
115
|
@support_ewkb
|
127
116
|
end
|
128
117
|
|
129
|
-
# Sets the the support_ewkb flag. See WKBParser for details.
|
130
|
-
def support_ewkb=(value_)
|
131
|
-
@support_ewkb = value_ ? true : false
|
132
|
-
end
|
133
|
-
|
134
118
|
# Returns true if this parser supports SFS 1.2 extensions.
|
135
119
|
# See WKBParser for details.
|
136
120
|
def support_wkb12?
|
137
121
|
@support_wkb12
|
138
122
|
end
|
139
123
|
|
140
|
-
# Sets the the support_wkb12 flag. See WKBParser for details.
|
141
|
-
def support_wkb12=(value_)
|
142
|
-
@support_wkb12 = value_ ? true : false
|
143
|
-
end
|
144
|
-
|
145
124
|
# Returns true if this parser ignores extra bytes.
|
146
125
|
# See WKBParser for details.
|
147
126
|
def ignore_extra_bytes?
|
148
127
|
@ignore_extra_bytes
|
149
128
|
end
|
150
129
|
|
151
|
-
#
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# Parse the given hex string, and return a geometry object.
|
158
|
-
|
159
|
-
def parse_hex(str_)
|
160
|
-
parse([str_].pack('H*'))
|
130
|
+
# Returns true if this parser can auto-detect hex.
|
131
|
+
# See WKBParser for details.
|
132
|
+
def auto_detect_hex?
|
133
|
+
@auto_detect_hex
|
161
134
|
end
|
162
135
|
|
163
136
|
|
164
|
-
# Parse the given binary data, and return a
|
137
|
+
# Parse the given binary data or hexadecimal string, and return a
|
138
|
+
# geometry object.
|
139
|
+
#
|
140
|
+
# The #parse_hex method is a synonym, present for historical
|
141
|
+
# reasons but deprecated. Use #parse instead.
|
165
142
|
|
166
143
|
def parse(data_)
|
144
|
+
if data_[0,1] =~ /[0-9a-fA-F]/
|
145
|
+
data_ = [data_].pack('H*')
|
146
|
+
end
|
167
147
|
@cur_has_z = nil
|
168
148
|
@cur_has_m = nil
|
169
149
|
@cur_srid = nil
|
@@ -183,10 +163,19 @@ module RGeo
|
|
183
163
|
end
|
184
164
|
obj_
|
185
165
|
end
|
166
|
+
alias_method :parse_hex, :parse
|
186
167
|
|
187
168
|
|
188
169
|
def _parse_object(contained_) # :nodoc:
|
189
|
-
|
170
|
+
endian_value_ = _get_byte
|
171
|
+
case endian_value_
|
172
|
+
when 0
|
173
|
+
little_endian_ = false
|
174
|
+
when 1
|
175
|
+
little_endian_ = true
|
176
|
+
else
|
177
|
+
raise Error::ParseError, "Bad endian byte value: #{endian_value_}"
|
178
|
+
end
|
190
179
|
type_code_ = _get_integer(little_endian_)
|
191
180
|
has_z_ = false
|
192
181
|
has_m_ = false
|