GeoRuby 0.0.4 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +10 -5
- data/lib/geo_ruby/simple_features/ewkb_parser.rb +39 -16
- data/lib/geo_ruby/simple_features/ewkt_parser.rb +50 -24
- data/lib/geo_ruby/simple_features/geometry.rb +45 -30
- data/lib/geo_ruby/simple_features/geometry_collection.rb +14 -8
- data/lib/geo_ruby/simple_features/geometry_factory.rb +14 -2
- data/lib/geo_ruby/simple_features/line_string.rb +15 -12
- data/lib/geo_ruby/simple_features/linear_ring.rb +7 -7
- data/lib/geo_ruby/simple_features/multi_line_string.rb +11 -8
- data/lib/geo_ruby/simple_features/multi_point.rb +11 -10
- data/lib/geo_ruby/simple_features/multi_polygon.rb +8 -9
- data/lib/geo_ruby/simple_features/point.rb +42 -27
- data/lib/geo_ruby/simple_features/polygon.rb +13 -11
- data/rakefile.rb +1 -1
- data/test/test_ewkb_parser.rb +85 -12
- data/test/test_ewkt_parser.rb +104 -14
- data/test/test_simple_features.rb +208 -77
- metadata +2 -2
data/README
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=GeoRuby
|
2
|
-
This is GeoRuby 0.
|
2
|
+
This is GeoRuby 0.1.1. It is intended as a holder for data returned from PostGIS and the Spatial Extensions of MySql. The data model roughly follows the OGC "Simple Features for SQL" specification (see http://www.opengis.org/docs/99-049.pdf), although without any kind of advanced functionalities (such as geometric operators or reprojections).
|
3
3
|
|
4
4
|
===Available data types
|
5
5
|
The following geometric data types are provided :
|
@@ -12,16 +12,21 @@ The following geometric data types are provided :
|
|
12
12
|
- Multi polygon
|
13
13
|
- Geometry collection
|
14
14
|
|
15
|
+
They can be in 2D, 3DZ, 3DM, and 4D.
|
16
|
+
|
15
17
|
===Input and output
|
16
|
-
These geometries can be input and output in WKB/EWKB/WKT/EWKT format (as well as the related HexWKB and HexEWKB formats).
|
18
|
+
These geometries can be input and output in WKB/EWKB/WKT/EWKT format (as well as the related HexWKB and HexEWKB formats). HexEWKB and EWKB are the default form under which geometric data is returned respectively from PostGIS and MySql.
|
17
19
|
|
18
20
|
===Installation
|
19
|
-
|
21
|
+
To install the latest version, just type :
|
20
22
|
gem install GeoRuby
|
21
23
|
|
22
24
|
===Changes since the last version
|
23
|
-
|
24
|
-
|
25
|
+
- Addition of support for M and Z dimension in the data types, as well as in the EWKB and EWKT parsers.
|
26
|
+
- When creating a geometry, the presence of a Z or M dimension must be indicated. By default, the geometry is created in 2D and with a SRID of -1.
|
27
|
+
- Suppression of +as_binary+, +as_hex_binary+ and +as_text+. They have been replaced with +as_ewkb+, +as_wkb+, +as_hex_ewkb+, +as_hex_wkb+, +as_ewkt+ and +as_wkt+.
|
28
|
+
- Suppression of the static creation methods +from_raw_point_sequence+ (for some geometric types) and +from_raw_point_sequences+ (for other), to build a geometry from a list of point coordinates. They have been replaced by a +from_coordinates+ for all types.
|
29
|
+
- The static geometry construction method +from_hexewkb+ has been replaced with +from_hex_ewkb+.
|
25
30
|
|
26
31
|
===License
|
27
32
|
GeoRuby is released under the MIT license.
|
@@ -9,6 +9,10 @@ require 'geo_ruby/simple_features/geometry_collection'
|
|
9
9
|
|
10
10
|
module GeoRuby
|
11
11
|
module SimpleFeatures
|
12
|
+
|
13
|
+
class EWKBFormatError < StandardError
|
14
|
+
end
|
15
|
+
|
12
16
|
#Parses EWKB strings and notifies of events (such as the beginning of the definition of geometry, the value of the SRID...) the factory passed as argument to the constructor.
|
13
17
|
#
|
14
18
|
#=Example
|
@@ -35,36 +39,41 @@ module GeoRuby
|
|
35
39
|
def parse(ewkb)
|
36
40
|
@factory.reset
|
37
41
|
@unpack_structure=UnpackStructure::new(ewkb)
|
42
|
+
@with_z = false
|
43
|
+
@with_m = false
|
38
44
|
parse_geometry
|
39
45
|
@unpack_structure.done
|
40
46
|
@srid=nil
|
41
47
|
end
|
48
|
+
|
42
49
|
private
|
43
50
|
def parse_geometry
|
44
51
|
@unpack_structure.endianness=@unpack_structure.read_byte
|
45
52
|
@geometry_type = @unpack_structure.read_uint
|
46
|
-
|
47
|
-
|
53
|
+
|
48
54
|
if (@geometry_type & Z_MASK) != 0
|
49
|
-
@
|
55
|
+
@with_z=true
|
50
56
|
@geometry_type = @geometry_type & ~Z_MASK
|
51
57
|
end
|
52
58
|
if (@geometry_type & M_MASK) != 0
|
53
|
-
|
59
|
+
@with_m=true
|
60
|
+
@geometry_type = @geometry_type & ~M_MASK
|
54
61
|
end
|
55
62
|
if (@geometry_type & SRID_MASK) != 0
|
56
63
|
@srid = @unpack_structure.read_uint
|
57
64
|
@geometry_type = @geometry_type & ~SRID_MASK
|
58
65
|
else
|
59
|
-
#to manage multi geometries : the srid is not present in sub_geometries, therefore we take the srid of the parent ; if it is the
|
66
|
+
#to manage multi geometries : the srid is not present in sub_geometries, therefore we take the srid of the parent ; if it is the root, we take the default srid
|
60
67
|
@srid= @srid || DEFAULT_SRID
|
61
68
|
end
|
69
|
+
|
62
70
|
if @parse_options.has_key? @geometry_type
|
63
71
|
@parse_options[@geometry_type].call
|
64
72
|
else
|
65
|
-
raise
|
73
|
+
raise EWKBFormatError::new("Unknown geometry type")
|
66
74
|
end
|
67
75
|
end
|
76
|
+
|
68
77
|
def parse_geometry_collection
|
69
78
|
parse_multi_geometries(GeometryCollection)
|
70
79
|
end
|
@@ -80,42 +89,56 @@ module GeoRuby
|
|
80
89
|
def parse_multi_point
|
81
90
|
parse_multi_geometries(MultiPoint)
|
82
91
|
end
|
92
|
+
|
83
93
|
def parse_multi_geometries(geometry_type)
|
84
94
|
@factory.begin_geometry(geometry_type,@srid)
|
85
95
|
num_geometries = @unpack_structure.read_uint
|
86
96
|
1.upto(num_geometries) { parse_geometry }
|
87
|
-
@factory.end_geometry
|
97
|
+
@factory.end_geometry(@with_z,@with_m)
|
88
98
|
end
|
99
|
+
|
89
100
|
def parse_polygon
|
90
101
|
@factory.begin_geometry(Polygon,@srid)
|
91
102
|
num_linear_rings = @unpack_structure.read_uint
|
92
103
|
1.upto(num_linear_rings) {parse_linear_ring}
|
93
|
-
@factory.end_geometry
|
104
|
+
@factory.end_geometry(@with_z,@with_m)
|
94
105
|
end
|
106
|
+
|
95
107
|
def parse_linear_ring
|
96
108
|
parse_point_list(LinearRing)
|
97
109
|
end
|
110
|
+
|
98
111
|
def parse_line_string
|
99
112
|
parse_point_list(LineString)
|
100
113
|
end
|
114
|
+
|
101
115
|
#used to parse line_strings and linear_rings
|
102
116
|
def parse_point_list(geometry_type)
|
103
117
|
@factory.begin_geometry(geometry_type,@srid)
|
104
118
|
num_points = @unpack_structure.read_uint
|
105
119
|
1.upto(num_points) {parse_point}
|
106
|
-
@factory.end_geometry
|
120
|
+
@factory.end_geometry(@with_z,@with_m)
|
107
121
|
end
|
122
|
+
|
108
123
|
def parse_point
|
109
124
|
@factory.begin_geometry(Point,@srid)
|
110
125
|
x = @unpack_structure.read_double
|
111
126
|
y = @unpack_structure.read_double
|
112
|
-
if @
|
127
|
+
if ! (@with_z or @with_m) #most common case probably
|
128
|
+
@factory.add_point_x_y(x,y)
|
129
|
+
elsif @with_m and @with_z
|
130
|
+
z = @unpack_structure.read_double
|
131
|
+
m = @unpack_structure.read_double
|
132
|
+
@factory.add_point_x_y_z_m(x,y,z,m)
|
133
|
+
elsif @with_z
|
113
134
|
z = @unpack_structure.read_double
|
114
135
|
@factory.add_point_x_y_z(x,y,z)
|
115
136
|
else
|
116
|
-
@
|
137
|
+
m = @unpack_structure.read_double
|
138
|
+
@factory.add_point_x_y_m(x,y,m)
|
117
139
|
end
|
118
|
-
|
140
|
+
|
141
|
+
@factory.end_geometry(@with_z,@with_m)
|
119
142
|
end
|
120
143
|
end
|
121
144
|
|
@@ -149,27 +172,27 @@ module GeoRuby
|
|
149
172
|
@ewkb=ewkb
|
150
173
|
end
|
151
174
|
def done
|
152
|
-
raise
|
175
|
+
raise EWKBFormatError::new("Trailing data") if @position != @ewkb.length
|
153
176
|
end
|
154
177
|
def read_double
|
155
178
|
i=@position
|
156
179
|
@position += 8
|
157
180
|
packed_double = @ewkb[i...@position]
|
158
|
-
raise
|
181
|
+
raise EWKBFormatError::new("Truncated data") if packed_double.nil? or packed_double.length < 8
|
159
182
|
packed_double.unpack(@double_mark)[0]
|
160
183
|
end
|
161
184
|
def read_uint
|
162
185
|
i=@position
|
163
186
|
@position += 4
|
164
187
|
packed_uint = @ewkb[i...@position]
|
165
|
-
raise
|
188
|
+
raise EWKBFormatError::new("Truncated data") if packed_uint.nil? or packed_uint.length < 4
|
166
189
|
packed_uint.unpack(@uint_mark)[0]
|
167
190
|
end
|
168
191
|
def read_byte
|
169
192
|
i = @position
|
170
193
|
@position += 1
|
171
194
|
packed_byte = @ewkb[i...@position]
|
172
|
-
raise
|
195
|
+
raise EWKBFormatError::new("Truncated data") if packed_byte.nil? or packed_byte.length < 1
|
173
196
|
packed_byte.unpack("C")[0]
|
174
197
|
end
|
175
198
|
def endianness=(byte_order)
|
@@ -11,6 +11,10 @@ require 'strscan'
|
|
11
11
|
|
12
12
|
module GeoRuby
|
13
13
|
module SimpleFeatures
|
14
|
+
|
15
|
+
class EWKTFormatError < StandardError
|
16
|
+
end
|
17
|
+
|
14
18
|
#Parses EWKT strings and notifies of events (such as the beginning of the definition of geometry, the value of the SRID...) the factory passed as argument to the constructor.
|
15
19
|
#
|
16
20
|
#=Example
|
@@ -36,6 +40,8 @@ module GeoRuby
|
|
36
40
|
#Parses the ewkt string passed as argument and notifies the factory of events
|
37
41
|
def parse(ewkt)
|
38
42
|
@factory.reset
|
43
|
+
@with_z=false
|
44
|
+
@with_m=false
|
39
45
|
parse_geometry(ewkt)
|
40
46
|
@srid=nil
|
41
47
|
end
|
@@ -44,61 +50,70 @@ module GeoRuby
|
|
44
50
|
def parse_geometry(ewkt)
|
45
51
|
scanner = StringScanner.new(ewkt)
|
46
52
|
if scanner.scan(/SRID=(-?\d+);/)
|
47
|
-
@srid
|
53
|
+
if @srid.nil?
|
54
|
+
@srid = scanner[1].to_i
|
55
|
+
else
|
56
|
+
#not the root geometry and repeat of the SRID : shouldn't happen
|
57
|
+
raise EWKTFormatError.new("SRID in internal geometry")
|
58
|
+
end
|
48
59
|
else
|
49
|
-
#to manage multi geometries : the srid is not present in sub_geometries, therefore we take the srid of the parent ; if it is the
|
60
|
+
#to manage multi geometries : the srid is not present in sub_geometries, therefore we take the srid of the parent ; if it is the root, we take the default srid
|
50
61
|
@srid= @srid || DEFAULT_SRID
|
51
62
|
end
|
52
63
|
|
53
|
-
if scanner.scan(/(\w+)/)
|
54
|
-
|
55
|
-
if
|
56
|
-
@
|
64
|
+
if scanner.scan(/(\w+)/)
|
65
|
+
geom_type = scanner[1]
|
66
|
+
if geom_type[-1] == ?M
|
67
|
+
@with_m=true
|
68
|
+
geom_type.chop! #remove the M
|
69
|
+
end
|
70
|
+
#change the parsing method : this one really is ugly...
|
71
|
+
if @parse_options.has_key?(geom_type) and scanner.scan(/^\((.*)\)$/)
|
72
|
+
@parse_options[geom_type].call(scanner[1])
|
57
73
|
else
|
58
|
-
raise
|
74
|
+
raise EWKTFormatError.new("Bad token")
|
59
75
|
end
|
60
|
-
else
|
61
|
-
raise StandardError::new("Unknown geometry type")
|
62
76
|
end
|
77
|
+
|
63
78
|
end
|
64
79
|
def parse_geometry_collection(string)
|
65
80
|
@factory.begin_geometry(GeometryCollection,@srid)
|
66
81
|
scanner = StringScanner.new(string)
|
67
|
-
while(scanner.scan(
|
82
|
+
while(scanner.scan(/\s*(.*?),\s*(?=[A-Z])/))
|
68
83
|
parse_geometry(scanner[1])
|
69
84
|
end
|
70
85
|
parse_geometry(scanner.rest)
|
71
|
-
@factory.end_geometry
|
86
|
+
@factory.end_geometry(@with_z,@with_m)
|
72
87
|
end
|
73
88
|
|
74
89
|
def parse_multi_polygon(string)
|
75
90
|
@factory.begin_geometry(MultiPolygon,@srid)
|
76
91
|
scanner = StringScanner.new(string)
|
77
|
-
while(scanner.scan(/\((\((.*?)\))\)
|
92
|
+
while(scanner.scan(/\s*\(\s*(\((.*?)\))\s*\)\s*,?/)) #beeeh
|
78
93
|
parse_polygon(scanner[1])
|
79
94
|
end
|
80
|
-
@factory.end_geometry
|
95
|
+
@factory.end_geometry(@with_z,@with_m)
|
81
96
|
end
|
82
97
|
|
83
98
|
def parse_multi_line_string(string)
|
84
99
|
@factory.begin_geometry(MultiLineString,@srid)
|
85
100
|
scanner = StringScanner.new(string)
|
86
|
-
|
101
|
+
|
102
|
+
while(scanner.scan(/\s*\(([^\)]*)\)\s*,?/))
|
87
103
|
parse_line_string(scanner[1])
|
88
104
|
end
|
89
|
-
@factory.end_geometry
|
105
|
+
@factory.end_geometry(@with_z,@with_m)
|
90
106
|
end
|
91
107
|
|
92
108
|
def parse_polygon(string)
|
93
109
|
@factory.begin_geometry(Polygon,@srid)
|
94
110
|
scanner = StringScanner.new(string)
|
95
|
-
while(scanner.scan(/\(([^\)]*)\)
|
111
|
+
while(scanner.scan(/\s*\(([^\)]*)\)\s*,?/))
|
96
112
|
parse_linear_ring(scanner[1])
|
97
113
|
end
|
98
|
-
@factory.end_geometry
|
114
|
+
@factory.end_geometry(@with_z,@with_m)
|
99
115
|
end
|
100
|
-
|
101
|
-
|
116
|
+
|
102
117
|
def parse_multi_point(string)
|
103
118
|
parse_point_list(MultiPoint,string)
|
104
119
|
end
|
@@ -108,14 +123,14 @@ module GeoRuby
|
|
108
123
|
def parse_line_string(string)
|
109
124
|
parse_point_list(LineString,string)
|
110
125
|
end
|
111
|
-
#used to parse line_strings and linear_rings
|
126
|
+
#used to parse line_strings and linear_rings and multi_points
|
112
127
|
def parse_point_list(geometry_type,string)
|
113
128
|
@factory.begin_geometry(geometry_type,@srid)
|
114
129
|
scanner = StringScanner.new(string)
|
115
130
|
while(scanner.scan(/([^,]*),?/))
|
116
131
|
parse_point(scanner[1])
|
117
132
|
end
|
118
|
-
@factory.end_geometry
|
133
|
+
@factory.end_geometry(@with_z,@with_m)
|
119
134
|
end
|
120
135
|
|
121
136
|
def parse_point(string)
|
@@ -125,12 +140,23 @@ module GeoRuby
|
|
125
140
|
while scanner.scan(/\s*([-+]?[\d.]+)\s*/)
|
126
141
|
coords << scanner[1].to_f
|
127
142
|
end
|
128
|
-
|
143
|
+
|
144
|
+
if coords.length == 2
|
129
145
|
@factory.add_point_x_y(*coords)
|
146
|
+
elsif coords.length == 3
|
147
|
+
if @with_m
|
148
|
+
@factory.add_point_x_y_m(*coords)
|
149
|
+
else
|
150
|
+
@with_z=true #we know if it is 3dz only when reading the first point
|
151
|
+
@factory.add_point_x_y_z(*coords)
|
152
|
+
end
|
130
153
|
else
|
131
|
-
@
|
154
|
+
@with_m=true
|
155
|
+
@with_z=true
|
156
|
+
@factory.add_point_x_y_z_m(*coords)
|
132
157
|
end
|
133
|
-
|
158
|
+
|
159
|
+
@factory.end_geometry(@with_z,@with_m)
|
134
160
|
end
|
135
161
|
end
|
136
162
|
|
@@ -4,7 +4,7 @@ module GeoRuby#:nodoc:
|
|
4
4
|
DEFAULT_SRID=-1
|
5
5
|
#indicates the presence of Z coordinates in EWKB strings
|
6
6
|
Z_MASK=0x80000000
|
7
|
-
#indicates the presence of M coordinates in EWKB strings.
|
7
|
+
#indicates the presence of M coordinates in EWKB strings.
|
8
8
|
M_MASK=0x40000000
|
9
9
|
#indicate the presence of a SRID in EWKB strings.
|
10
10
|
SRID_MASK=0x20000000
|
@@ -15,74 +15,89 @@ module GeoRuby#:nodoc:
|
|
15
15
|
class Geometry
|
16
16
|
#SRID of the geometry
|
17
17
|
attr_accessor :srid
|
18
|
+
#Flag indicating if the z ordinate of the geometry is meaningful
|
19
|
+
attr_accessor :with_z
|
20
|
+
#Flag indicating if the m ordinate of the geometry is meaningful
|
21
|
+
attr_accessor :with_m
|
18
22
|
|
19
|
-
def initialize(srid=DEFAULT_SRID)
|
23
|
+
def initialize(srid=DEFAULT_SRID,with_z=false,with_m=false)
|
20
24
|
@srid=srid
|
25
|
+
@with_z=with_z
|
26
|
+
@with_m=with_m
|
21
27
|
end
|
22
28
|
|
23
29
|
#Outputs the geometry as an EWKB string.
|
24
|
-
#
|
25
|
-
|
26
|
-
#
|
27
|
-
#WKB output can be obtained for any geometry by passing a +dimension+ of 2 and +with_srid+ set to false.
|
28
|
-
def as_binary(dimension=2,with_srid=true)
|
30
|
+
#The +allow_srid+, +allow_z+ and +allow_m+ arguments allow the output to include srid, z and m respectively if they are present in the geometry. If these arguments are set to false, srid, z and m are not included, even if they are present in the geometry. By default, the output string contains all the information in the object.
|
31
|
+
def as_ewkb(allow_srid=true,allow_z=true,allow_m=true)
|
29
32
|
ewkb="";
|
30
33
|
|
31
34
|
ewkb << 1.chr #little_endian by default
|
32
35
|
|
33
36
|
type= binary_geometry_type
|
34
|
-
if
|
37
|
+
if @with_z and allow_z
|
35
38
|
type = type | Z_MASK
|
36
39
|
end
|
37
|
-
if
|
40
|
+
if @with_m and allow_m
|
41
|
+
type = type | M_MASK
|
42
|
+
end
|
43
|
+
if @srid != DEFAULT_SRID and allow_srid
|
38
44
|
type = type | SRID_MASK
|
39
45
|
ewkb << [type,@srid].pack("VV")
|
40
46
|
else
|
41
47
|
ewkb << [type].pack("V")
|
42
48
|
end
|
43
|
-
|
49
|
+
|
50
|
+
ewkb << binary_representation(allow_z,allow_m)
|
51
|
+
end
|
52
|
+
|
53
|
+
#Outputs the geometry as a strict WKB string.
|
54
|
+
def as_wkb
|
55
|
+
as_ewkb(false,false,false)
|
44
56
|
end
|
57
|
+
|
45
58
|
#Outputs the geometry as a HexEWKB string. It is almost the same as a WKB string, except that each byte of a WKB string is replaced by its hexadecimal 2-character representation in a HexEWKB string.
|
46
|
-
|
47
|
-
#The argument +dimension+ forces the dimension of the output. The argument +with_srid+ indicates if the output must contain the SRID.
|
48
|
-
#
|
49
|
-
#HexWKB output can be obtained for any geometry by passing a +dimension+ of 2 and +with_srid+ set to false.
|
50
|
-
def as_hex_binary(dimension=2,with_srid=true)
|
59
|
+
def as_hex_ewkb(allow_srid=true,allow_z=true,allow_m=true)
|
51
60
|
str = ""
|
52
|
-
|
61
|
+
as_ewkb(allow_srid,allow_z,allow_m).each_byte {|char| str << sprintf("%02x",char).upcase}
|
53
62
|
str
|
54
63
|
end
|
64
|
+
#Outputs the geometry as a strict HexWKB string
|
65
|
+
def as_hex_wkb
|
66
|
+
as_hex_ewkb(false,false,false)
|
67
|
+
end
|
55
68
|
|
56
|
-
#Outputs the geometry as
|
57
|
-
|
58
|
-
|
59
|
-
#The argument +dimension+ forces the dimension of the output. The argument +with_srid+ indicates if the output must contain the SRID.
|
60
|
-
#
|
61
|
-
#WKT output can be obtained for any geometry by passing a +dimension+ of 2 and +with_srid+ set to false.
|
62
|
-
def as_text(dimension=2,with_srid=true)
|
63
|
-
if with_srid
|
69
|
+
#Outputs the geometry as an EWKT string.
|
70
|
+
def as_ewkt(allow_srid=true,allow_z=true,allow_m=true)
|
71
|
+
if @srid!=DEFAULT_SRID and allow_srid #the default SRID is not output like in PostGIS
|
64
72
|
ewkt="SRID=#{@srid};"
|
65
73
|
else
|
66
74
|
ewkt=""
|
67
75
|
end
|
68
|
-
ewkt << text_geometry_type
|
69
|
-
ewkt <<
|
76
|
+
ewkt << text_geometry_type
|
77
|
+
ewkt << "M" if @with_m and allow_m and (!@with_z or !allow_z) #to distinguish the M from the Z when there is actually no Z...
|
78
|
+
ewkt << "(" << text_representation(allow_z,allow_m) << ")"
|
70
79
|
end
|
71
|
-
|
80
|
+
|
81
|
+
#Outputs the geometry as strict WKT string.
|
82
|
+
def as_wkt
|
83
|
+
as_ewkt(false,false,false)
|
84
|
+
end
|
85
|
+
|
86
|
+
#Creates a geometry based on a EWKB string. The actual class returned depends of the content of the string passed as argument. Since WKB strings are a subset of EWKB, they are also valid.
|
72
87
|
def self.from_ewkb(ewkb)
|
73
88
|
factory = GeometryFactory::new
|
74
89
|
ewkb_parser= EWKBParser::new(factory)
|
75
90
|
ewkb_parser.parse(ewkb)
|
76
91
|
factory.geometry
|
77
92
|
end
|
78
|
-
|
79
|
-
def self.
|
93
|
+
#Creates a geometry based on a HexEWKB string
|
94
|
+
def self.from_hex_ewkb(hexewkb)
|
80
95
|
factory = GeometryFactory::new
|
81
96
|
hexewkb_parser= HexEWKBParser::new(factory)
|
82
97
|
hexewkb_parser.parse(hexewkb)
|
83
98
|
factory.geometry
|
84
99
|
end
|
85
|
-
|
100
|
+
#Creates a geometry based on a EWKT string. Since WKT strings are a subset of EWKT, they are also valid.
|
86
101
|
def self.from_ewkt(ewkt)
|
87
102
|
factory = GeometryFactory::new
|
88
103
|
ewkt_parser= EWKTParser::new(factory)
|
@@ -6,8 +6,8 @@ module GeoRuby
|
|
6
6
|
class GeometryCollection < Geometry
|
7
7
|
attr_reader :geometries
|
8
8
|
|
9
|
-
def initialize(srid = DEFAULT_SRID)
|
10
|
-
super(srid)
|
9
|
+
def initialize(srid = DEFAULT_SRID,with_z=false,with_m=false)
|
10
|
+
super(srid,with_z,with_m)
|
11
11
|
@geometries = []
|
12
12
|
end
|
13
13
|
#add a geometry to the collection
|
@@ -65,27 +65,33 @@ module GeoRuby
|
|
65
65
|
true
|
66
66
|
end
|
67
67
|
end
|
68
|
+
|
68
69
|
#Binary representation of the collection
|
69
|
-
def binary_representation(
|
70
|
+
def binary_representation(allow_z=true,allow_m=true)
|
70
71
|
rep = [length].pack("V")
|
71
|
-
|
72
|
+
#output the list of geometries without outputting the SRID first and with the same setting regarding Z and M
|
73
|
+
each {|geometry| rep << geometry.as_ewkb(false,allow_z,allow_m) }
|
72
74
|
rep
|
73
75
|
end
|
76
|
+
|
74
77
|
#WKB geometry type of the collection
|
75
78
|
def binary_geometry_type
|
76
79
|
7
|
77
80
|
end
|
81
|
+
|
78
82
|
#Text representation of a geometry collection
|
79
|
-
def text_representation(
|
80
|
-
@geometries.collect{|geometry| geometry.
|
83
|
+
def text_representation(allow_z=true,allow_m=true)
|
84
|
+
@geometries.collect{|geometry| geometry.as_ewkt(false,allow_z,allow_m)}.join(",")
|
81
85
|
end
|
86
|
+
|
82
87
|
#WKT geometry type
|
83
88
|
def text_geometry_type
|
84
89
|
"GEOMETRYCOLLECTION"
|
85
90
|
end
|
91
|
+
|
86
92
|
#creates a new GeometryCollection from an array of geometries
|
87
|
-
def self.from_geometries(geometries,srid=DEFAULT_SRID)
|
88
|
-
geometry_collection = GeometryCollection::new(srid)
|
93
|
+
def self.from_geometries(geometries,srid=DEFAULT_SRID,with_z=false,with_m=false)
|
94
|
+
geometry_collection = GeometryCollection::new(srid,with_z,with_m)
|
89
95
|
geometry_collection.concat(geometries)
|
90
96
|
geometry_collection
|
91
97
|
end
|
@@ -30,6 +30,16 @@ module GeoRuby
|
|
30
30
|
def add_point_x_y_z(x,y,z)
|
31
31
|
@geometry_stack.last.set_x_y_z(x,y,z)
|
32
32
|
end
|
33
|
+
#add a 2D point with M to the current geometry
|
34
|
+
def add_point_x_y_m(x,y,m)
|
35
|
+
@geometry_stack.last.set_x_y(x,y)
|
36
|
+
@geometry_stack.last.m=m
|
37
|
+
end
|
38
|
+
#add a 3D point with M to the current geometry
|
39
|
+
def add_point_x_y_z_m(x,y,z,m)
|
40
|
+
@geometry_stack.last.set_x_y_z(x,y,z)
|
41
|
+
@geometry_stack.last.m=m
|
42
|
+
end
|
33
43
|
#begin a geometry of type +geometry_type+
|
34
44
|
def begin_geometry(geometry_type,srid=DEFAULT_SRID)
|
35
45
|
geometry= geometry_type::new(srid)
|
@@ -37,8 +47,10 @@ module GeoRuby
|
|
37
47
|
@geometry_stack << geometry
|
38
48
|
end
|
39
49
|
#terminates the current geometry
|
40
|
-
def end_geometry
|
41
|
-
geometry=@geometry_stack.pop
|
50
|
+
def end_geometry(with_z=false,with_m=false)
|
51
|
+
@geometry=@geometry_stack.pop
|
52
|
+
@geometry.with_z=with_z
|
53
|
+
@geometry.with_m=with_m
|
42
54
|
#add the newly defined geometry to its parent if there is one
|
43
55
|
@geometry_stack.last << geometry if !@geometry_stack.empty?
|
44
56
|
end
|
@@ -7,8 +7,8 @@ module GeoRuby
|
|
7
7
|
#the list of points forming the line string
|
8
8
|
attr_reader :points
|
9
9
|
|
10
|
-
def initialize(srid= DEFAULT_SRID
|
11
|
-
super(srid)
|
10
|
+
def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
|
11
|
+
super(srid,with_z,with_m)
|
12
12
|
@points=[]
|
13
13
|
end
|
14
14
|
#tests if the line string is closed
|
@@ -56,6 +56,7 @@ module GeoRuby
|
|
56
56
|
def remove(*slice)
|
57
57
|
@points.slice(*slice)
|
58
58
|
end
|
59
|
+
|
59
60
|
#Tests the equality of line strings
|
60
61
|
def ==(other_line_string)
|
61
62
|
if(other_line_string.class != self.class or
|
@@ -70,20 +71,22 @@ module GeoRuby
|
|
70
71
|
true
|
71
72
|
end
|
72
73
|
end
|
73
|
-
|
74
|
+
|
74
75
|
#Binary representation of a line string
|
75
|
-
def binary_representation(
|
76
|
+
def binary_representation(allow_z=true,allow_m=true)
|
76
77
|
rep = [length].pack("V")
|
77
|
-
each {|point| rep << point.binary_representation(
|
78
|
+
each {|point| rep << point.binary_representation(allow_z,allow_m) }
|
78
79
|
rep
|
79
80
|
end
|
81
|
+
|
80
82
|
#WKB geometry type
|
81
83
|
def binary_geometry_type
|
82
84
|
2
|
83
85
|
end
|
86
|
+
|
84
87
|
#Text representation of a line string
|
85
|
-
def text_representation(
|
86
|
-
@points.collect{|point| point.text_representation(
|
88
|
+
def text_representation(allow_z=true,allow_m=true)
|
89
|
+
@points.collect{|point| point.text_representation(allow_z,allow_m) }.join(",")
|
87
90
|
end
|
88
91
|
#WKT geometry type
|
89
92
|
def text_geometry_type
|
@@ -91,16 +94,16 @@ module GeoRuby
|
|
91
94
|
end
|
92
95
|
|
93
96
|
#Creates a new line string. Accept an array of points as argument
|
94
|
-
def self.from_points(points,srid=DEFAULT_SRID)
|
95
|
-
line_string = LineString::new(srid)
|
97
|
+
def self.from_points(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
|
98
|
+
line_string = LineString::new(srid,with_z,with_m)
|
96
99
|
line_string.concat(points)
|
97
100
|
line_string
|
98
101
|
end
|
99
102
|
|
100
103
|
#Creates a new line string. Accept a sequence of points as argument : ((x,y)...(x,y))
|
101
|
-
def self.
|
102
|
-
line_string = LineString::new(srid)
|
103
|
-
line_string.concat( points.collect{|point_coords| Point.from_coordinates(point_coords,srid) } )
|
104
|
+
def self.from_coordinates(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
|
105
|
+
line_string = LineString::new(srid,with_z,with_m)
|
106
|
+
line_string.concat( points.collect{|point_coords| Point.from_coordinates(point_coords,srid,with_z,with_m) } )
|
104
107
|
line_string
|
105
108
|
end
|
106
109
|
|
@@ -4,21 +4,21 @@ module GeoRuby
|
|
4
4
|
module SimpleFeatures
|
5
5
|
#Represents a linear ring, which is a closed line string (see LineString). No check is performed to verify if the linear ring is really closed.
|
6
6
|
class LinearRing < LineString
|
7
|
-
def initialize(srid= DEFAULT_SRID)
|
8
|
-
super(srid)
|
7
|
+
def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
|
8
|
+
super(srid,with_z,with_m)
|
9
9
|
end
|
10
10
|
|
11
11
|
#creates a new linear ring from an array of points. The first and last points should be equal, although no check is performed here.
|
12
|
-
def self.from_points(points,srid=DEFAULT_SRID)
|
13
|
-
linear_ring = LinearRing::new(srid)
|
12
|
+
def self.from_points(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
|
13
|
+
linear_ring = LinearRing::new(srid,with_z,with_m)
|
14
14
|
linear_ring.concat(points)
|
15
15
|
linear_ring
|
16
16
|
end
|
17
17
|
|
18
18
|
#creates a new linear ring from a sequence of points : ((x,y)...(x,y)).
|
19
|
-
def self.
|
20
|
-
linear_ring = LinearRing::new(srid)
|
21
|
-
linear_ring.concat( points.collect{|point_coords| Point.from_coordinates(point_coords,srid)
|
19
|
+
def self.from_coordinates(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
|
20
|
+
linear_ring = LinearRing::new(srid,with_z,with_m)
|
21
|
+
linear_ring.concat( points.collect{|point_coords| Point.from_coordinates(point_coords,srid,with_z,with_m) } )
|
22
22
|
linear_ring
|
23
23
|
end
|
24
24
|
|