GeoRuby 0.0.4 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|