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 CHANGED
@@ -1,5 +1,5 @@
1
1
  =GeoRuby
2
- This is GeoRuby 0.0.4. It is intended as a holder for data returned from PostGIS queries. Therefore, 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).
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). Since EWKB and HexEWKB are respectively the canonical binary and ASCII representations of geometries in PostGIS, this functionality can prove useful.
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
- Just type :
21
+ To install the latest version, just type :
20
22
  gem install GeoRuby
21
23
 
22
24
  ===Changes since the last version
23
- Change of the default SRID when not specified
24
- Correction of a bug in the EWKT parsing for negative SRIDs
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
- @dimension=2
47
-
53
+
48
54
  if (@geometry_type & Z_MASK) != 0
49
- @dimension=3
55
+ @with_z=true
50
56
  @geometry_type = @geometry_type & ~Z_MASK
51
57
  end
52
58
  if (@geometry_type & M_MASK) != 0
53
- raise StandardError::new("For next version")
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 parent, we take the default srid
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 StandardError::new("Unknown geometry type")
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 @dimension == 3
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
- @factory.add_point_x_y(x,y)
137
+ m = @unpack_structure.read_double
138
+ @factory.add_point_x_y_m(x,y,m)
117
139
  end
118
- @factory.end_geometry
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 StandardError::new("Trailing data") if @position != @ewkb.length
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 StandardError::new("Truncated data") if packed_double.nil? or packed_double.length < 8
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 StandardError::new("Truncated data") if packed_uint.nil? or packed_uint.length < 4
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 StandardError::new("Truncated data") if packed_byte.nil? or packed_byte.length < 1
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 = scanner[1].to_i
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 parent, we take the default srid
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+)/) and @parse_options.has_key? scanner[1]
54
- to_call = scanner[1]
55
- if scanner.scan(/\((.*)\)/)
56
- @parse_options[to_call].call(scanner[1])
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 StandardError::new("Bad token : " + scanner.rest)
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(/(.*?),(?=[A-Z])/))
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
- while(scanner.scan(/\(([^\)]*)\),?/))
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
- if(coords.length == 2)
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
- @factory.add_point_x_y_z(*coords)
154
+ @with_m=true
155
+ @with_z=true
156
+ @factory.add_point_x_y_z_m(*coords)
132
157
  end
133
- @factory.end_geometry
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. It is not supported at present.
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
- #The argument +dimension+ forces the dimension of the output. The argument +with_srid+ indicates if the output must contain the SRID.
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 dimension == 3
37
+ if @with_z and allow_z
35
38
  type = type | Z_MASK
36
39
  end
37
- if(with_srid)
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
- ewkb << binary_representation(dimension)
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
- as_binary(dimension,with_srid).each_byte {|char| str << sprintf("%02x",char).upcase}
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 a EWKT string.
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 << text_representation(dimension) << ")"
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.from_hexewkb(hexewkb)
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(dimension=2)
70
+ def binary_representation(allow_z=true,allow_m=true)
70
71
  rep = [length].pack("V")
71
- each {|geometry| rep << geometry.as_binary(dimension,false) }
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(dimension=2)
80
- @geometries.collect{|geometry| geometry.as_text(dimension,false)}.join(",")
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(dimension=2)
76
+ def binary_representation(allow_z=true,allow_m=true)
76
77
  rep = [length].pack("V")
77
- each {|point| rep << point.binary_representation(dimension) }
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(dimension=2)
86
- @points.collect{|point| point.text_representation(dimension) }.join(",")
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.from_raw_point_sequence(points,srid=DEFAULT_SRID)
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.from_raw_point_sequence(points,srid=DEFAULT_SRID)
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