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