Class: GeoRuby::SimpleFeatures::LineString

Inherits:
Geometry
  • Object
show all
Defined in:
lib/geo_ruby/simple_features/line_string.rb

Overview

Represents a line string as an array of points (see Point).

Direct Known Subclasses

LinearRing

Instance Attribute Summary collapse

Attributes inherited from Geometry

#srid, #with_m, #with_z

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Geometry

#as_ewkb, #as_ewkt, #as_georss, #as_hex_ewkb, #as_hex_wkb, #as_kml, #as_wkb, #as_wkt, #envelope, from_ewkb, from_ewkt, from_geojson, from_georss, from_georss_with_tags, from_hex_ewkb, from_kml

Constructor Details

#initialize(srid = DEFAULT_SRID, with_z = false, with_m = false) ⇒ LineString

Returns a new instance of LineString.



10
11
12
13
# File 'lib/geo_ruby/simple_features/line_string.rb', line 10

def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
  super(srid,with_z,with_m)
  @points=[]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &b) ⇒ Object

Delegate the unknown methods to the points array



16
17
18
# File 'lib/geo_ruby/simple_features/line_string.rb', line 16

def method_missing(method_name,*args,&b)
  @points.send(method_name,*args,&b)
end

Instance Attribute Details

#pointsObject (readonly)

the list of points forming the line string



8
9
10
# File 'lib/geo_ruby/simple_features/line_string.rb', line 8

def points
  @points
end

Class Method Details

.from_coordinates(points, srid = DEFAULT_SRID, with_z = false, with_m = false) ⇒ Object

Creates a new line string. Accept a sequence of points as argument : ((x,y)…(x,y))



225
226
227
228
229
# File 'lib/geo_ruby/simple_features/line_string.rb', line 225

def self.from_coordinates(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
  line_string = new(srid,with_z,with_m)
  line_string.concat( points.map {|p| Point.from_coordinates(p,srid,with_z,with_m) } )
  line_string
end

.from_points(points, srid = DEFAULT_SRID, with_z = false, with_m = false) ⇒ Object

Creates a new line string. Accept an array of points as argument



218
219
220
221
222
# File 'lib/geo_ruby/simple_features/line_string.rb', line 218

def self.from_points(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
  line_string = new(srid,with_z,with_m)
  line_string.concat(points)
  line_string
end

Instance Method Details

#==(other_line_string) ⇒ Object

Tests the equality of line strings



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/geo_ruby/simple_features/line_string.rb', line 97

def ==(other_line_string)
  if(other_line_string.class != self.class or
       other_line_string.length != self.length)
    false
  else
    index=0
    while index<length
      return false if self[index] != other_line_string[index]
      index+=1
    end
    true
  end
end

#as_json(options = {}) ⇒ Object



205
206
207
208
# File 'lib/geo_ruby/simple_features/line_string.rb', line 205

def as_json(options = {})
  {:type => 'LineString',
   :coordinates => self.to_coordinates}
end

#binary_geometry_typeObject

WKB geometry type



119
120
121
# File 'lib/geo_ruby/simple_features/line_string.rb', line 119

def binary_geometry_type #:nodoc:
  2
end

#binary_representation(allow_z = true, allow_m = true) ⇒ Object

Binary representation of a line string



112
113
114
115
116
# File 'lib/geo_ruby/simple_features/line_string.rb', line 112

def binary_representation(allow_z=true,allow_m=true) #:nodoc:
  rep = [length].pack("V")
  each {|point| rep << point.binary_representation(allow_z,allow_m) }
  rep
end

#bounding_boxObject

Bounding box in 2D/3D. Returns an array of 2 points



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/geo_ruby/simple_features/line_string.rb', line 38

def bounding_box
  max_x, min_x, max_y, min_y = -Float::MAX, Float::MAX, -Float::MAX, Float::MAX
  if(with_z)
    max_z, min_z = -Float::MAX,Float::MAX
    each do |point|
      max_y = point.y if point.y > max_y
      min_y = point.y if point.y < min_y
      max_x = point.x if point.x > max_x
      min_x = point.x if point.x < min_x
      max_z = point.z if point.z > max_z
      min_z = point.z if point.z < min_z
    end
    [Point.from_x_y_z(min_x,min_y,min_z),Point.from_x_y_z(max_x,max_y,max_z)]
  else
    each do |point|
      max_y = point.y if point.y > max_y
      min_y = point.y if point.y < min_y
      max_x = point.x if point.x > max_x
      min_x = point.x if point.x < min_x
    end
    [Point.from_x_y(min_x,min_y),Point.from_x_y(max_x,max_y)]
  end
end

#clockwise?Boolean

Returns:

  • (Boolean)


27
28
29
30
31
32
33
34
35
# File 'lib/geo_ruby/simple_features/line_string.rb', line 27

def clockwise?
  tuples = @points.zip(
    @points[1..-1] + [@points[0]],
    @points[2..-1] + [@points[0], @points[1]])
  tuples.map!{ |a,b,c| b.x * (c.y - a.y)  }
  sum = tuples.inject(0.0){ |sum, elem| sum+elem }

  sum < 0.0
end

#do_simplify(list, epsilon) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/geo_ruby/simple_features/line_string.rb', line 185

def do_simplify(list, epsilon)
  index = dmax = 0
  2.upto(list.length - 1) do |i|
    d = list[i].orthogonal_distance(list[0], list[-1])
    index, dmax = i, d if d > dmax
  end

  if dmax >= epsilon
    res1 = do_simplify(list[0..index], epsilon)
    res2 = do_simplify(list[index..-1], epsilon)
    res1[0..-2] + res2[0..-1]
  else
    [list[0], list[-1]]
  end
end

#euclidian_distanceObject



88
89
90
91
92
93
94
# File 'lib/geo_ruby/simple_features/line_string.rb', line 88

def euclidian_distance
  total = 0
  @points.each_with_index do |p,i|
    total += p.euclidian_distance(@points[i+1]) if @points[i+1]
  end
  total
end

#georss_gml_representation(options) ⇒ Object

georss gml representation



144
145
146
147
148
149
150
151
# File 'lib/geo_ruby/simple_features/line_string.rb', line 144

def georss_gml_representation(options) #:nodoc:
  georss_ns = options[:georss_ns] || "georss"
  gml_ns = options[:gml_ns] || "gml"

  result = "<#{georss_ns}:where>\n<#{gml_ns}:LineString>\n<#{gml_ns}:posList>\n"
  result += georss_poslist
  result += "\n</#{gml_ns}:posList>\n</#{gml_ns}:LineString>\n</#{georss_ns}:where>\n"
end

#georss_poslistObject

:nodoc:



153
154
155
# File 'lib/geo_ruby/simple_features/line_string.rb', line 153

def georss_poslist #:nodoc:
  map {|point| "#{point.y} #{point.x}"}.join(" ")
end

#georss_simple_representation(options) ⇒ Object

georss simple representation



133
134
135
136
137
# File 'lib/geo_ruby/simple_features/line_string.rb', line 133

def georss_simple_representation(options) #:nodoc:
  georss_ns = options[:georss_ns] || "georss"
  geom_attr = options[:geom_attr]
  "<#{georss_ns}:line#{geom_attr}>" + georss_poslist + "</#{georss_ns}:line>\n"
end

#georss_w3cgeo_representation(options) ⇒ Object

georss w3c representation : outputs the first point of the line



139
140
141
142
# File 'lib/geo_ruby/simple_features/line_string.rb', line 139

def georss_w3cgeo_representation(options) #:nodoc:
  w3cgeo_ns = options[:w3cgeo_ns] || "geo"
  "<#{w3cgeo_ns}:lat>#{self[0].y}</#{w3cgeo_ns}:lat>\n<#{w3cgeo_ns}:long>#{self[0].x}</#{w3cgeo_ns}:long>\n"
end

#intersects?(other_line_string) ⇒ Boolean

call to native Geo intersect, return true or false

Returns:

  • (Boolean)


76
77
78
# File 'lib/geo_ruby/simple_features/line_string.rb', line 76

def intersects?(other_line_string)

end

#is_closedObject Also known as: closed?

tests if the line string is closed



21
22
23
24
# File 'lib/geo_ruby/simple_features/line_string.rb', line 21

def is_closed
  #a bit naive...
  @points.first == @points.last
end

#kml_poslist(options) ⇒ Object

:nodoc:



169
170
171
172
173
174
175
176
177
# File 'lib/geo_ruby/simple_features/line_string.rb', line 169

def kml_poslist(options) #:nodoc:
  pos_list = if options[:allow_z]
     map {|point| "#{point.x},#{point.y},#{options[:fixed_z] || point.z || 0}" }
  else
    map {|point| "#{point.x},#{point.y}" }
  end
  pos_list.reverse! if(options[:reverse])
  pos_list.join(" ")
end

#kml_representation(options = {}) ⇒ Object

outputs the geometry in kml format : options are :id, :tesselate, :extrude, :altitude_mode. If the altitude_mode option is not present, the Z (if present) will not be output (since it won’t be used by GE anyway: clampToGround is the default)



160
161
162
163
164
165
166
167
# File 'lib/geo_ruby/simple_features/line_string.rb', line 160

def kml_representation(options = {}) #:nodoc:
  result = "<LineString#{options[:id_attr]}>\n"
  result += options[:geom_data] if options[:geom_data]
  result += "<coordinates>"
  result += kml_poslist(options)
  result += "</coordinates>\n"
  result += "</LineString>\n"
end

#m_rangeObject



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/geo_ruby/simple_features/line_string.rb', line 62

def m_range
  if with_m
    max_m, min_m = -Float::MAX, Float::MAX
    each do |point|
      max_m = point.m if point.m.to_f > max_m
      min_m = point.m if point.m.to_f < min_m
    end
    [min_m,max_m]
  else
    [0,0]
  end
end

#simplify(epsilon = 1) ⇒ Object

Simplify linestring (Douglas Peucker Algorithm) en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm



181
182
183
# File 'lib/geo_ruby/simple_features/line_string.rb', line 181

def simplify(epsilon=1)
  LineString.from_points(do_simplify(@points, epsilon))
end

#spherical_distanceObject



80
81
82
83
84
85
86
# File 'lib/geo_ruby/simple_features/line_string.rb', line 80

def spherical_distance
  total = 0
  @points.each_with_index do |p,i|
    total += p.spherical_distance(@points[i+1]) if @points[i+1]
  end
  total
end

#text_geometry_typeObject

WKT geometry type



128
129
130
# File 'lib/geo_ruby/simple_features/line_string.rb', line 128

def text_geometry_type #:nodoc:
  "LINESTRING"
end

#text_representation(allow_z = true, allow_m = true) ⇒ Object

Text representation of a line string



124
125
126
# File 'lib/geo_ruby/simple_features/line_string.rb', line 124

def text_representation(allow_z=true,allow_m=true) #:nodoc:
  @points.collect{|point| point.text_representation(allow_z,allow_m) }.join(",")
end

#to_coordinatesObject



201
202
203
# File 'lib/geo_ruby/simple_features/line_string.rb', line 201

def to_coordinates
  points.map{|p| p.to_coordinates }
end

#to_json(options = {}) ⇒ Object Also known as: as_geojson

simple geojson representation TODO add CRS / SRID support?



212
213
214
# File 'lib/geo_ruby/simple_features/line_string.rb', line 212

def to_json(options = {})
  as_json(options).to_json(options)
end