georuby 2.3.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -9
- data/Rakefile +13 -14
- data/lib/geo_ruby/ewk.rb +2 -0
- data/lib/geo_ruby/{simple_features → ewk}/ewkb_parser.rb +206 -218
- data/lib/geo_ruby/ewk/ewkt_parser.rb +321 -0
- data/lib/geo_ruby/geojson.rb +27 -32
- data/lib/geo_ruby/georss.rb +88 -66
- data/lib/geo_ruby/gpx.rb +113 -1
- data/lib/geo_ruby/kml.rb +43 -31
- data/lib/geo_ruby/shp.rb +1 -0
- data/lib/geo_ruby/shp4r/dbf.rb +7 -3
- data/lib/geo_ruby/shp4r/shp.rb +297 -284
- data/lib/geo_ruby/simple_features.rb +2 -6
- data/lib/geo_ruby/simple_features/circle.rb +15 -13
- data/lib/geo_ruby/simple_features/envelope.rb +84 -77
- data/lib/geo_ruby/simple_features/geometry.rb +89 -69
- data/lib/geo_ruby/simple_features/geometry_collection.rb +46 -43
- data/lib/geo_ruby/simple_features/geometry_factory.rb +50 -47
- data/lib/geo_ruby/simple_features/helper.rb +14 -14
- data/lib/geo_ruby/simple_features/line_string.rb +94 -97
- data/lib/geo_ruby/simple_features/linear_ring.rb +4 -9
- data/lib/geo_ruby/simple_features/multi_line_string.rb +18 -21
- data/lib/geo_ruby/simple_features/multi_point.rb +18 -20
- data/lib/geo_ruby/simple_features/multi_polygon.rb +19 -25
- data/lib/geo_ruby/simple_features/point.rb +134 -128
- data/lib/geo_ruby/simple_features/polygon.rb +60 -59
- data/lib/geo_ruby/version.rb +1 -1
- data/spec/data/geojson/feature.json +9 -0
- data/spec/data/geojson/feature_collection.json +3 -4
- data/spec/geo_ruby/{simple_features → ewk}/ewkb_parser_spec.rb +56 -57
- data/spec/geo_ruby/{simple_features → ewk}/ewkt_parser_spec.rb +62 -63
- data/spec/geo_ruby/geojson_spec.rb +34 -17
- data/spec/geo_ruby/georss_spec.rb +76 -64
- data/spec/geo_ruby/{gpx4r/gpx_spec.rb → gpx_spec.rb} +25 -25
- data/spec/geo_ruby/kml_spec.rb +40 -36
- data/spec/geo_ruby/shp4r/shp_spec.rb +51 -51
- data/spec/geo_ruby/simple_features/circle_spec.rb +2 -2
- data/spec/geo_ruby/simple_features/envelope_spec.rb +8 -8
- data/spec/geo_ruby/simple_features/geometry_collection_spec.rb +26 -26
- data/spec/geo_ruby/simple_features/geometry_factory_spec.rb +5 -5
- data/spec/geo_ruby/simple_features/geometry_spec.rb +8 -8
- data/spec/geo_ruby/simple_features/line_string_spec.rb +102 -102
- data/spec/geo_ruby/simple_features/linear_ring_spec.rb +7 -7
- data/spec/geo_ruby/simple_features/multi_line_string_spec.rb +20 -20
- data/spec/geo_ruby/simple_features/multi_point_spec.rb +16 -16
- data/spec/geo_ruby/simple_features/multi_polygon_spec.rb +19 -19
- data/spec/geo_ruby/simple_features/point_spec.rb +180 -174
- data/spec/geo_ruby/simple_features/polygon_spec.rb +55 -56
- data/spec/geo_ruby_spec.rb +4 -4
- data/spec/spec_helper.rb +19 -13
- metadata +10 -9
- data/lib/geo_ruby/gpx4r/gpx.rb +0 -118
- data/lib/geo_ruby/simple_features/ewkt_parser.rb +0 -336
@@ -2,21 +2,21 @@ require 'geo_ruby/simple_features/geometry'
|
|
2
2
|
|
3
3
|
module GeoRuby
|
4
4
|
module SimpleFeatures
|
5
|
-
#Represents a collection of arbitrary geometries
|
5
|
+
# Represents a collection of arbitrary geometries
|
6
6
|
class GeometryCollection < Geometry
|
7
7
|
attr_reader :geometries
|
8
8
|
|
9
|
-
def initialize(srid = DEFAULT_SRID,with_z=false,with_m=false)
|
10
|
-
super(srid,with_z,with_m)
|
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
|
|
14
|
-
#Delegate the unknown methods to the geometries array
|
15
|
-
def method_missing(method_name
|
16
|
-
@geometries.send(method_name
|
14
|
+
# Delegate the unknown methods to the geometries array
|
15
|
+
def method_missing(method_name, *args, &b)
|
16
|
+
@geometries.send(method_name, *args, &b)
|
17
17
|
end
|
18
18
|
|
19
|
-
#Bounding box in 2D/3D. Returns an array of 2 points
|
19
|
+
# Bounding box in 2D/3D. Returns an array of 2 points
|
20
20
|
def bounding_box
|
21
21
|
max_x, min_x, max_y, min_y = -Float::MAX, Float::MAX, -Float::MAX, Float::MAX
|
22
22
|
if with_z
|
@@ -33,7 +33,7 @@ module GeoRuby
|
|
33
33
|
max_z = ne.z if ne.z > max_z
|
34
34
|
min_z = sw.z if sw.z < min_z
|
35
35
|
end
|
36
|
-
[Point.from_x_y_z(min_x,min_y,min_z),Point.from_x_y_z(max_x,max_y,max_z)]
|
36
|
+
[Point.from_x_y_z(min_x, min_y, min_z), Point.from_x_y_z(max_x, max_y, max_z)]
|
37
37
|
else
|
38
38
|
each do |geometry|
|
39
39
|
bbox = geometry.bounding_box
|
@@ -45,7 +45,7 @@ module GeoRuby
|
|
45
45
|
max_x = ne.x if ne.x > max_x
|
46
46
|
min_x = sw.x if sw.x < min_x
|
47
47
|
end
|
48
|
-
[Point.from_x_y(min_x,min_y),Point.from_x_y(max_x,max_y)]
|
48
|
+
[Point.from_x_y(min_x, min_y), Point.from_x_y(max_x, max_y)]
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -57,81 +57,84 @@ module GeoRuby
|
|
57
57
|
max_m = lrmr[1] if lrmr[1] > max_m
|
58
58
|
min_m = lrmr[0] if lrmr[0] < min_m
|
59
59
|
end
|
60
|
-
[min_m,max_m]
|
60
|
+
[min_m, max_m]
|
61
61
|
else
|
62
|
-
[0,0]
|
62
|
+
[0, 0]
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
#tests the equality of geometry collections
|
67
|
-
def ==(
|
68
|
-
if(
|
66
|
+
# tests the equality of geometry collections
|
67
|
+
def ==(other)
|
68
|
+
if (other.class != self.class)
|
69
69
|
false
|
70
|
-
elsif length !=
|
70
|
+
elsif length != other.length
|
71
71
|
false
|
72
72
|
else
|
73
|
-
index=0
|
74
|
-
while index<length
|
75
|
-
return false if self[index] !=
|
76
|
-
index+=1
|
73
|
+
index = 0
|
74
|
+
while index < length
|
75
|
+
return false if self[index] != other[index]
|
76
|
+
index += 1
|
77
77
|
end
|
78
78
|
true
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
#Binary representation of the collection
|
83
|
-
def binary_representation(allow_z=true,allow_m=true) #:nodoc:
|
84
|
-
rep = [length].pack(
|
85
|
-
#output the list of geometries without outputting the SRID first
|
86
|
-
|
82
|
+
# Binary representation of the collection
|
83
|
+
def binary_representation(allow_z = true, allow_m = true) #:nodoc:
|
84
|
+
rep = [length].pack('V')
|
85
|
+
# output the list of geometries without outputting the SRID first
|
86
|
+
# and with the same setting regarding Z and M
|
87
|
+
each { |geometry| rep << geometry.as_ewkb(false, allow_z, allow_m) }
|
87
88
|
rep
|
88
89
|
end
|
89
90
|
|
90
|
-
#WKB geometry type of the collection
|
91
|
+
# WKB geometry type of the collection
|
91
92
|
def binary_geometry_type #:nodoc:
|
92
93
|
7
|
93
94
|
end
|
94
95
|
|
95
|
-
#Text representation of a geometry collection
|
96
|
-
def text_representation(allow_z=true,allow_m=true) #:nodoc:
|
97
|
-
@geometries.collect
|
96
|
+
# Text representation of a geometry collection
|
97
|
+
def text_representation(allow_z = true, allow_m = true) #:nodoc:
|
98
|
+
@geometries.collect do |geometry|
|
99
|
+
geometry.as_ewkt(false, allow_z, allow_m)
|
100
|
+
end.join(',')
|
98
101
|
end
|
99
102
|
|
100
|
-
#WKT geometry type
|
103
|
+
# WKT geometry type
|
101
104
|
def text_geometry_type #:nodoc:
|
102
|
-
|
105
|
+
'GEOMETRYCOLLECTION'
|
103
106
|
end
|
104
107
|
|
105
|
-
def as_json(
|
106
|
-
{:
|
108
|
+
def as_json(_options = {})
|
109
|
+
{ type: 'GeometryCollection', geometries: geometries }
|
107
110
|
end
|
108
111
|
|
109
|
-
#georss simple representation : outputs only the first geometry of the collection
|
110
|
-
def georss_simple_representation(options)#:nodoc:
|
112
|
+
# georss simple representation : outputs only the first geometry of the collection
|
113
|
+
def georss_simple_representation(options) #:nodoc:
|
111
114
|
self[0].georss_simple_representation(options)
|
112
115
|
end
|
113
|
-
#georss w3c representation : outputs the first point of the outer ring
|
114
|
-
def georss_w3cgeo_representation(options)#:nodoc:
|
116
|
+
# georss w3c representation : outputs the first point of the outer ring
|
117
|
+
def georss_w3cgeo_representation(options) #:nodoc:
|
115
118
|
self[0].georss_w3cgeo_representation(options)
|
116
119
|
end
|
117
|
-
#georss gml representation : outputs only the first geometry of the collection
|
118
|
-
def georss_gml_representation(options)#:nodoc:
|
120
|
+
# georss gml representation : outputs only the first geometry of the collection
|
121
|
+
def georss_gml_representation(options) #:nodoc:
|
119
122
|
self[0].georss_gml_representation(options)
|
120
123
|
end
|
121
124
|
|
122
|
-
#outputs the geometry in kml format
|
125
|
+
# outputs the geometry in kml format
|
123
126
|
def kml_representation(options = {}) #:nodoc:
|
124
127
|
result = "<MultiGeometry#{options[:id_attr]}>\n"
|
125
|
-
options[:id_attr] =
|
128
|
+
options[:id_attr] = '' # the subgeometries do not have an ID
|
126
129
|
each do |geometry|
|
127
130
|
result += geometry.kml_representation(options)
|
128
131
|
end
|
129
132
|
result += "</MultiGeometry>\n"
|
130
133
|
end
|
131
134
|
|
132
|
-
#creates a new GeometryCollection from an array of geometries
|
133
|
-
def self.from_geometries(geometries,srid=DEFAULT_SRID,
|
134
|
-
geometry_collection = new(srid,
|
135
|
+
# creates a new GeometryCollection from an array of geometries
|
136
|
+
def self.from_geometries(geometries, srid = DEFAULT_SRID, z = false, m = false)
|
137
|
+
geometry_collection = new(srid, z, m)
|
135
138
|
geometry_collection.concat(geometries)
|
136
139
|
geometry_collection
|
137
140
|
end
|
@@ -1,78 +1,81 @@
|
|
1
|
-
require 'geo_ruby/simple_features/point'
|
2
|
-
require 'geo_ruby/simple_features/line_string'
|
3
|
-
require 'geo_ruby/simple_features/linear_ring'
|
4
|
-
require 'geo_ruby/simple_features/polygon'
|
5
|
-
require 'geo_ruby/simple_features/multi_point'
|
6
|
-
require 'geo_ruby/simple_features/multi_line_string'
|
7
|
-
require 'geo_ruby/simple_features/multi_polygon'
|
8
|
-
require 'geo_ruby/simple_features/geometry_collection'
|
9
|
-
|
10
|
-
|
11
1
|
module GeoRuby
|
12
2
|
module SimpleFeatures
|
13
|
-
#Creates a new geometry according to constructions
|
3
|
+
# Creates a new geometry according to constructions
|
4
|
+
# received from a parser, for example EWKBParser.
|
14
5
|
class GeometryFactory
|
15
|
-
#the built geometry
|
6
|
+
# the built geometry
|
16
7
|
attr_reader :geometry
|
17
8
|
|
18
9
|
def initialize
|
19
10
|
@geometry = nil
|
20
11
|
@geometry_stack = []
|
21
12
|
end
|
22
|
-
|
13
|
+
|
14
|
+
# resets the factory
|
23
15
|
def reset
|
24
16
|
@geometry = nil
|
25
17
|
@geometry_stack = []
|
26
18
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
|
20
|
+
# add a 2D point to the current geometry
|
21
|
+
def add_point_x_y(x, y)
|
22
|
+
@geometry_stack.last.set_x_y(x, y)
|
30
23
|
end
|
31
|
-
|
24
|
+
|
25
|
+
# add 2D points to the current geometry
|
32
26
|
def add_points_x_y(xy)
|
33
|
-
xy.each_slice(2) {|slice| add_point_x_y(*slice)}
|
27
|
+
xy.each_slice(2) { |slice| add_point_x_y(*slice) }
|
34
28
|
end
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
|
30
|
+
# add a 3D point to the current geometry
|
31
|
+
def add_point_x_y_z(x, y, z)
|
32
|
+
@geometry_stack.last.set_x_y_z(x, y, z)
|
38
33
|
end
|
39
|
-
|
34
|
+
|
35
|
+
# add 3D points to the current geometry
|
40
36
|
def add_points_x_y_z(xyz)
|
41
|
-
xyz.each_slice(3) {|slice| add_point_x_y_z(*slice)}
|
37
|
+
xyz.each_slice(3) { |slice| add_point_x_y_z(*slice) }
|
42
38
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
@geometry_stack.last.
|
39
|
+
|
40
|
+
# add a 2D point with M to the current geometry
|
41
|
+
def add_point_x_y_m(x, y, m)
|
42
|
+
@geometry_stack.last.set_x_y(x, y)
|
43
|
+
@geometry_stack.last.m = m
|
47
44
|
end
|
48
|
-
|
45
|
+
|
46
|
+
# add 2D points with M to the current geometry
|
49
47
|
def add_points_x_y_m(xym)
|
50
|
-
xym.each_slice(3) {|slice| add_point_x_y_m(*slice)}
|
48
|
+
xym.each_slice(3) { |slice| add_point_x_y_m(*slice) }
|
51
49
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
@geometry_stack.last.
|
50
|
+
|
51
|
+
# add a 3D point with M to the current geometry
|
52
|
+
def add_point_x_y_z_m(x, y, z, m)
|
53
|
+
@geometry_stack.last.set_x_y_z(x, y, z)
|
54
|
+
@geometry_stack.last.m = m
|
56
55
|
end
|
57
|
-
|
56
|
+
|
57
|
+
# add 3D points with M to the current geometry
|
58
58
|
def add_points_x_y_z_m(xyzm)
|
59
|
-
xyzm.each_slice(4) {|slice| add_point_x_y_z_m(*slice)}
|
59
|
+
xyzm.each_slice(4) { |slice| add_point_x_y_z_m(*slice) }
|
60
60
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
|
62
|
+
# begin a geometry of type +geometry_type+
|
63
|
+
def begin_geometry(geometry_type, srid = DEFAULT_SRID)
|
64
|
+
geometry = geometry_type.new(srid)
|
65
|
+
@geometry = geometry if @geometry.nil?
|
65
66
|
@geometry_stack << geometry
|
66
67
|
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
@geometry.
|
71
|
-
@geometry.
|
72
|
-
|
73
|
-
|
68
|
+
|
69
|
+
# terminates the current geometry
|
70
|
+
def end_geometry(with_z = false, with_m = false)
|
71
|
+
@geometry = @geometry_stack.pop
|
72
|
+
@geometry.with_z = with_z
|
73
|
+
@geometry.with_m = with_m
|
74
|
+
# add the newly defined geometry to its parent if there is one
|
75
|
+
@geometry_stack.last << geometry unless @geometry_stack.empty?
|
74
76
|
end
|
75
|
-
|
77
|
+
|
78
|
+
# abort a geometry
|
76
79
|
def abort_geometry
|
77
80
|
reset
|
78
81
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
module GeoRuby
|
2
2
|
module SimpleFeatures
|
3
|
-
#indicates the presence of Z coordinates in EWKB strings
|
4
|
-
Z_MASK=0x80000000
|
5
|
-
#indicates the presence of M coordinates in EWKB strings.
|
6
|
-
M_MASK=0x40000000
|
7
|
-
#indicate the presence of a SRID in EWKB strings.
|
8
|
-
SRID_MASK=0x20000000
|
9
|
-
#GeoRSS namespace
|
10
|
-
GEORSS_NS =
|
11
|
-
#GML Namespace
|
12
|
-
GML_NS =
|
13
|
-
#W3CGeo Namespace
|
14
|
-
W3CGEO_NS =
|
15
|
-
#KML Namespace
|
16
|
-
KML_NS =
|
3
|
+
# indicates the presence of Z coordinates in EWKB strings
|
4
|
+
Z_MASK = 0x80000000
|
5
|
+
# indicates the presence of M coordinates in EWKB strings.
|
6
|
+
M_MASK = 0x40000000
|
7
|
+
# indicate the presence of a SRID in EWKB strings.
|
8
|
+
SRID_MASK = 0x20000000
|
9
|
+
# GeoRSS namespace
|
10
|
+
GEORSS_NS = 'http://www.georss.org/georss'
|
11
|
+
# GML Namespace
|
12
|
+
GML_NS = 'http://www.opengis.net/gml'
|
13
|
+
# W3CGeo Namespace
|
14
|
+
W3CGEO_NS = 'http://www.w3.org/2003/01/geo/wgs84_pos#'
|
15
|
+
# KML Namespace
|
16
|
+
KML_NS = 'http://earth.google.com/kml/2.1'
|
17
17
|
end
|
18
18
|
end
|
@@ -1,44 +1,43 @@
|
|
1
|
-
require
|
1
|
+
require 'geo_ruby/simple_features/geometry'
|
2
2
|
|
3
3
|
module GeoRuby
|
4
4
|
module SimpleFeatures
|
5
|
-
#Represents a line string as an array of points (see Point).
|
5
|
+
# Represents a line string as an array of points (see Point).
|
6
6
|
class LineString < Geometry
|
7
|
-
#the list of points forming the line string
|
7
|
+
# the list of points forming the line string
|
8
8
|
attr_reader :points
|
9
9
|
|
10
|
-
def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
|
11
|
-
super(srid,with_z,with_m)
|
12
|
-
@points=[]
|
10
|
+
def initialize(srid = DEFAULT_SRID, with_z = false, with_m = false)
|
11
|
+
super(srid, with_z, with_m)
|
12
|
+
@points = []
|
13
13
|
end
|
14
14
|
|
15
|
-
#Delegate the unknown methods to the points array
|
16
|
-
def method_missing(method_name
|
17
|
-
@points.send(method_name
|
15
|
+
# Delegate the unknown methods to the points array
|
16
|
+
def method_missing(method_name, *args, &b)
|
17
|
+
@points.send(method_name, *args, &b)
|
18
18
|
end
|
19
19
|
|
20
|
-
#tests if the line string is closed
|
21
|
-
def
|
22
|
-
#a bit naive...
|
20
|
+
# tests if the line string is closed
|
21
|
+
def closed?
|
22
|
+
# a bit naive...
|
23
23
|
@points.first == @points.last
|
24
24
|
end
|
25
|
-
alias :closed? :is_closed
|
26
25
|
|
27
26
|
def clockwise?
|
28
27
|
tuples = @points.zip(
|
29
28
|
@points[1..-1] + [@points[0]],
|
30
29
|
@points[2..-1] + [@points[0], @points[1]])
|
31
|
-
tuples.map!{ |a,b,c| b.x * (c.y - a.y) }
|
32
|
-
sum = tuples.
|
33
|
-
|
30
|
+
tuples.map! { |a, b, c| b.x * (c.y - a.y) }
|
31
|
+
sum = tuples.reduce(0.0) { |a, e| a + e }
|
34
32
|
sum < 0.0
|
35
33
|
end
|
36
34
|
|
37
|
-
#Bounding box in 2D/3D. Returns an array of 2 points
|
35
|
+
# Bounding box in 2D/3D. Returns an array of 2 points
|
38
36
|
def bounding_box
|
39
|
-
max_x
|
40
|
-
|
41
|
-
|
37
|
+
max_x = max_y = -Float::MAX
|
38
|
+
min_x = min_y = Float::MAX
|
39
|
+
if with_z
|
40
|
+
max_z, min_z = -Float::MAX, Float::MAX
|
42
41
|
each do |point|
|
43
42
|
max_y = point.y if point.y > max_y
|
44
43
|
min_y = point.y if point.y < min_y
|
@@ -47,7 +46,7 @@ module GeoRuby
|
|
47
46
|
max_z = point.z if point.z > max_z
|
48
47
|
min_z = point.z if point.z < min_z
|
49
48
|
end
|
50
|
-
[Point.from_x_y_z(min_x,min_y,min_z),Point.from_x_y_z(max_x,max_y,max_z)]
|
49
|
+
[Point.from_x_y_z(min_x, min_y, min_z), Point.from_x_y_z(max_x, max_y, max_z)]
|
51
50
|
else
|
52
51
|
each do |point|
|
53
52
|
max_y = point.y if point.y > max_y
|
@@ -55,7 +54,7 @@ module GeoRuby
|
|
55
54
|
max_x = point.x if point.x > max_x
|
56
55
|
min_x = point.x if point.x < min_x
|
57
56
|
end
|
58
|
-
[Point.from_x_y(min_x,min_y),Point.from_x_y(max_x,max_y)]
|
57
|
+
[Point.from_x_y(min_x, min_y), Point.from_x_y(max_x, max_y)]
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
@@ -66,119 +65,123 @@ module GeoRuby
|
|
66
65
|
max_m = point.m if point.m.to_f > max_m
|
67
66
|
min_m = point.m if point.m.to_f < min_m
|
68
67
|
end
|
69
|
-
[min_m,max_m]
|
68
|
+
[min_m, max_m]
|
70
69
|
else
|
71
|
-
[0,0]
|
70
|
+
[0, 0]
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
75
|
-
|
76
|
-
def intersects?(
|
77
|
-
|
74
|
+
# call to native Geo intersect, return true or false
|
75
|
+
def intersects?(_other_line_string)
|
78
76
|
end
|
79
77
|
|
80
78
|
def spherical_distance
|
81
79
|
total = 0
|
82
|
-
@points.each_with_index do |p,i|
|
83
|
-
total += p.spherical_distance(@points[i+1]) if @points[i+1]
|
80
|
+
@points.each_with_index do |p, i|
|
81
|
+
total += p.spherical_distance(@points[i + 1]) if @points[i + 1]
|
84
82
|
end
|
85
83
|
total
|
86
84
|
end
|
87
85
|
|
88
86
|
def euclidian_distance
|
89
87
|
total = 0
|
90
|
-
@points.each_with_index do |p,i|
|
91
|
-
total += p.euclidian_distance(@points[i+1]) if @points[i+1]
|
88
|
+
@points.each_with_index do |p, i|
|
89
|
+
total += p.euclidian_distance(@points[i + 1]) if @points[i + 1]
|
92
90
|
end
|
93
91
|
total
|
94
92
|
end
|
95
93
|
|
96
|
-
#Tests the equality of line strings
|
97
|
-
def ==(
|
98
|
-
if
|
99
|
-
|
94
|
+
# Tests the equality of line strings
|
95
|
+
def ==(other)
|
96
|
+
if other.class != self.class ||
|
97
|
+
other.length != length
|
100
98
|
false
|
101
99
|
else
|
102
|
-
index=0
|
103
|
-
while index<length
|
104
|
-
return false if self[index] !=
|
105
|
-
index+=1
|
100
|
+
index = 0
|
101
|
+
while index < length
|
102
|
+
return false if self[index] != other[index]
|
103
|
+
index += 1
|
106
104
|
end
|
107
105
|
true
|
108
106
|
end
|
109
107
|
end
|
110
108
|
|
111
|
-
#Binary representation of a line string
|
112
|
-
def binary_representation(allow_z=true,allow_m=true) #:nodoc:
|
113
|
-
rep = [length].pack(
|
114
|
-
each {|point| rep << point.binary_representation(allow_z,allow_m) }
|
109
|
+
# Binary representation of a line string
|
110
|
+
def binary_representation(allow_z = true, allow_m = true) #:nodoc:
|
111
|
+
rep = [length].pack('V')
|
112
|
+
each { |point| rep << point.binary_representation(allow_z, allow_m) }
|
115
113
|
rep
|
116
114
|
end
|
117
115
|
|
118
|
-
#WKB geometry type
|
116
|
+
# WKB geometry type
|
119
117
|
def binary_geometry_type #:nodoc:
|
120
118
|
2
|
121
119
|
end
|
122
120
|
|
123
|
-
#Text representation of a line string
|
124
|
-
def text_representation(allow_z=true,allow_m=true) #:nodoc:
|
125
|
-
@points.collect{|point| point.text_representation(allow_z,allow_m) }.join(
|
121
|
+
# Text representation of a line string
|
122
|
+
def text_representation(allow_z = true, allow_m = true) #:nodoc:
|
123
|
+
@points.collect { |point| point.text_representation(allow_z, allow_m) }.join(',')
|
126
124
|
end
|
127
|
-
#WKT geometry type
|
125
|
+
# WKT geometry type
|
128
126
|
def text_geometry_type #:nodoc:
|
129
|
-
|
127
|
+
'LINESTRING'
|
130
128
|
end
|
131
129
|
|
132
|
-
#georss simple representation
|
130
|
+
# georss simple representation
|
133
131
|
def georss_simple_representation(options) #:nodoc:
|
134
|
-
georss_ns = options[:georss_ns] ||
|
132
|
+
georss_ns = options[:georss_ns] || 'georss'
|
135
133
|
geom_attr = options[:geom_attr]
|
136
|
-
"<#{georss_ns}:line#{geom_attr}
|
134
|
+
"<#{georss_ns}:line#{geom_attr}>#{georss_poslist}</#{georss_ns}:line>\n"
|
137
135
|
end
|
138
|
-
|
136
|
+
|
137
|
+
# georss w3c representation : outputs the first point of the line
|
139
138
|
def georss_w3cgeo_representation(options) #:nodoc:
|
140
|
-
w3cgeo_ns = options[:w3cgeo_ns] ||
|
141
|
-
"<#{w3cgeo_ns}:lat>#{self[0].y}</#{w3cgeo_ns}:lat>\n
|
139
|
+
w3cgeo_ns = options[:w3cgeo_ns] || 'geo'
|
140
|
+
"<#{w3cgeo_ns}:lat>#{self[0].y}</#{w3cgeo_ns}:lat>\n"\
|
141
|
+
"<#{w3cgeo_ns}:long>#{self[0].x}</#{w3cgeo_ns}:long>\n"
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
|
+
# georss gml representation
|
144
145
|
def georss_gml_representation(options) #:nodoc:
|
145
|
-
georss_ns = options[:georss_ns] ||
|
146
|
-
gml_ns = options[:gml_ns] ||
|
146
|
+
georss_ns = options[:georss_ns] || 'georss'
|
147
|
+
gml_ns = options[:gml_ns] || 'gml'
|
147
148
|
|
148
|
-
|
149
|
-
|
150
|
-
|
149
|
+
"<#{georss_ns}:where>\n<#{gml_ns}:LineString>\n<#{gml_ns}:posList>\n" \
|
150
|
+
"#{georss_poslist}\n</#{gml_ns}:posList>\n</#{gml_ns}:LineString>\n" \
|
151
|
+
"</#{georss_ns}:where>\n"
|
151
152
|
end
|
152
153
|
|
153
154
|
def georss_poslist #:nodoc:
|
154
|
-
map {|point| "#{point.y} #{point.x}"}.join(
|
155
|
+
map { |point| "#{point.y} #{point.x}" }.join(' ')
|
155
156
|
end
|
156
157
|
|
157
|
-
#outputs the geometry in kml format : options are <tt>:id</tt>,
|
158
|
-
|
159
|
-
#
|
158
|
+
# outputs the geometry in kml format : options are <tt>:id</tt>,
|
159
|
+
# <tt>:tesselate</tt>, <tt>:extrude</tt>, <tt>:altitude_mode</tt>.
|
160
|
+
# If the altitude_mode option is not present, the Z (if present) will not
|
161
|
+
# be output (since it won't be used by GE: clampToGround is the default)
|
160
162
|
def kml_representation(options = {}) #:nodoc:
|
161
163
|
result = "<LineString#{options[:id_attr]}>\n"
|
162
164
|
result += options[:geom_data] if options[:geom_data]
|
163
|
-
result +=
|
165
|
+
result += '<coordinates>'
|
164
166
|
result += kml_poslist(options)
|
165
167
|
result += "</coordinates>\n"
|
166
|
-
result
|
168
|
+
result + "</LineString>\n"
|
167
169
|
end
|
168
170
|
|
169
171
|
def kml_poslist(options) #:nodoc:
|
170
|
-
pos_list =
|
171
|
-
|
172
|
+
pos_list = \
|
173
|
+
if options[:allow_z]
|
174
|
+
map { |point| "#{point.x},#{point.y},#{options[:fixed_z] || point.z || 0}" }
|
172
175
|
else
|
173
|
-
map {|point| "#{point.x},#{point.y}" }
|
176
|
+
map { |point| "#{point.x},#{point.y}" }
|
174
177
|
end
|
175
|
-
pos_list.reverse! if
|
176
|
-
pos_list.join(
|
178
|
+
pos_list.reverse! if options[:reverse]
|
179
|
+
pos_list.join(' ')
|
177
180
|
end
|
178
181
|
|
179
182
|
# Simplify linestring (Douglas Peucker Algorithm)
|
180
183
|
# http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
|
181
|
-
def simplify(epsilon=1)
|
184
|
+
def simplify(epsilon = 1)
|
182
185
|
LineString.from_points(do_simplify(@points, epsilon))
|
183
186
|
end
|
184
187
|
|
@@ -188,40 +191,34 @@ module GeoRuby
|
|
188
191
|
d = list[i].orthogonal_distance(list[0], list[-1])
|
189
192
|
index, dmax = i, d if d > dmax
|
190
193
|
end
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
res1[0..-2] + res2[0..-1]
|
196
|
-
else
|
197
|
-
[list[0], list[-1]]
|
198
|
-
end
|
194
|
+
return [list[0], list[-1]] if dmax < epsilon
|
195
|
+
res1 = do_simplify(list[0..index], epsilon)
|
196
|
+
res2 = do_simplify(list[index..-1], epsilon)
|
197
|
+
res1[0..-2] + res2[0..-1]
|
199
198
|
end
|
200
199
|
|
201
200
|
def to_coordinates
|
202
|
-
points.map
|
201
|
+
points.map(&:to_coordinates)
|
203
202
|
end
|
204
203
|
|
205
|
-
def as_json(
|
206
|
-
{:
|
204
|
+
def as_json(_options = {})
|
205
|
+
{ type: 'LineString', coordinates: to_coordinates }
|
207
206
|
end
|
208
207
|
|
209
|
-
#Creates a new line string. Accept an array of points as argument
|
210
|
-
def self.from_points(points,srid=DEFAULT_SRID,
|
211
|
-
line_string = new(srid,
|
208
|
+
# Creates a new line string. Accept an array of points as argument
|
209
|
+
def self.from_points(points, srid = DEFAULT_SRID, z = false, m = false)
|
210
|
+
line_string = new(srid, z, m)
|
212
211
|
line_string.concat(points)
|
213
212
|
line_string
|
214
213
|
end
|
215
214
|
|
216
|
-
#Creates a new line string. Accept a sequence of points as argument
|
217
|
-
|
218
|
-
|
219
|
-
line_string
|
215
|
+
# Creates a new line string. Accept a sequence of points as argument:
|
216
|
+
# ((x,y)...(x,y))
|
217
|
+
def self.from_coordinates(points, srid = DEFAULT_SRID, z = false, m = false)
|
218
|
+
line_string = new(srid, z, m)
|
219
|
+
line_string.concat(points.map { |p| Point.from_coordinates(p, srid, z, m) })
|
220
220
|
line_string
|
221
221
|
end
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
end #SimpleFeatures
|
226
|
-
|
227
|
-
end #GeoRuby
|
222
|
+
end # LineString
|
223
|
+
end # SimpleFeatures
|
224
|
+
end # GeoRuby
|