jsl-GeoRuby 1.3.3

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.
Files changed (43) hide show
  1. data/MIT-LICENSE +7 -0
  2. data/README +83 -0
  3. data/georuby.gemspec +37 -0
  4. data/lib/geo_ruby.rb +16 -0
  5. data/lib/geo_ruby/shp4r/dbf.rb +180 -0
  6. data/lib/geo_ruby/shp4r/shp.rb +701 -0
  7. data/lib/geo_ruby/simple_features/envelope.rb +134 -0
  8. data/lib/geo_ruby/simple_features/ewkb_parser.rb +216 -0
  9. data/lib/geo_ruby/simple_features/ewkt_parser.rb +336 -0
  10. data/lib/geo_ruby/simple_features/geometry.rb +225 -0
  11. data/lib/geo_ruby/simple_features/geometry_collection.rb +136 -0
  12. data/lib/geo_ruby/simple_features/geometry_factory.rb +81 -0
  13. data/lib/geo_ruby/simple_features/georss_parser.rb +135 -0
  14. data/lib/geo_ruby/simple_features/helper.rb +18 -0
  15. data/lib/geo_ruby/simple_features/line_string.rb +166 -0
  16. data/lib/geo_ruby/simple_features/linear_ring.rb +12 -0
  17. data/lib/geo_ruby/simple_features/multi_line_string.rb +39 -0
  18. data/lib/geo_ruby/simple_features/multi_point.rb +41 -0
  19. data/lib/geo_ruby/simple_features/multi_polygon.rb +38 -0
  20. data/lib/geo_ruby/simple_features/point.rb +236 -0
  21. data/lib/geo_ruby/simple_features/polygon.rb +150 -0
  22. data/rakefile.rb +44 -0
  23. data/test/data/multipoint.dbf +0 -0
  24. data/test/data/multipoint.shp +0 -0
  25. data/test/data/multipoint.shx +0 -0
  26. data/test/data/point.dbf +0 -0
  27. data/test/data/point.shp +0 -0
  28. data/test/data/point.shx +0 -0
  29. data/test/data/polygon.dbf +0 -0
  30. data/test/data/polygon.shp +0 -0
  31. data/test/data/polygon.shx +0 -0
  32. data/test/data/polyline.dbf +0 -0
  33. data/test/data/polyline.shp +0 -0
  34. data/test/data/polyline.shx +0 -0
  35. data/test/test_ewkb_parser.rb +171 -0
  36. data/test/test_ewkt_parser.rb +193 -0
  37. data/test/test_georss_kml.rb +231 -0
  38. data/test/test_shp.rb +76 -0
  39. data/test/test_shp_write.rb +150 -0
  40. data/test/test_simple_features.rb +506 -0
  41. data/tools/db.yml +6 -0
  42. data/tools/shp2sql.rb +92 -0
  43. metadata +95 -0
@@ -0,0 +1,18 @@
1
+ module GeoRuby
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 = "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
+ end
18
+ end
@@ -0,0 +1,166 @@
1
+ require "geo_ruby/simple_features/geometry"
2
+
3
+ module GeoRuby
4
+ module SimpleFeatures
5
+ #Represents a line string as an array of points (see Point).
6
+ class LineString < Geometry
7
+ #the list of points forming the line string
8
+ attr_reader :points
9
+
10
+ def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
11
+ super(srid,with_z,with_m)
12
+ @points=[]
13
+ end
14
+
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
+ end
19
+
20
+ #tests if the line string is closed
21
+ def is_closed
22
+ #a bit naive...
23
+ @points.first == @points.last
24
+ end
25
+
26
+ #Bounding box in 2D/3D. Returns an array of 2 points
27
+ def bounding_box
28
+ max_x, min_x, max_y, min_y = -Float::MAX, Float::MAX, -Float::MAX, Float::MAX
29
+ if(with_z)
30
+ max_z, min_z = -Float::MAX,Float::MAX
31
+ each do |point|
32
+ max_y = point.y if point.y > max_y
33
+ min_y = point.y if point.y < min_y
34
+ max_x = point.x if point.x > max_x
35
+ min_x = point.x if point.x < min_x
36
+ max_z = point.z if point.z > max_z
37
+ min_z = point.z if point.z < min_z
38
+ end
39
+ [Point.from_x_y_z(min_x,min_y,min_z),Point.from_x_y_z(max_x,max_y,max_z)]
40
+ else
41
+ each do |point|
42
+ max_y = point.y if point.y > max_y
43
+ min_y = point.y if point.y < min_y
44
+ max_x = point.x if point.x > max_x
45
+ min_x = point.x if point.x < min_x
46
+ end
47
+ [Point.from_x_y(min_x,min_y),Point.from_x_y(max_x,max_y)]
48
+ end
49
+ end
50
+
51
+ def m_range
52
+ if with_m
53
+ max_m, min_m = -Float::MAX, Float::MAX
54
+ each do |point|
55
+ max_m = point.m if point.m > max_m
56
+ min_m = point.m if point.m < min_m
57
+ end
58
+ [min_m,max_m]
59
+ else
60
+ [0,0]
61
+ end
62
+ end
63
+
64
+ #Tests the equality of line strings
65
+ def ==(other_line_string)
66
+ if(other_line_string.class != self.class or
67
+ other_line_string.length != self.length)
68
+ false
69
+ else
70
+ index=0
71
+ while index<length
72
+ return false if self[index] != other_line_string[index]
73
+ index+=1
74
+ end
75
+ true
76
+ end
77
+ end
78
+
79
+ #Binary representation of a line string
80
+ def binary_representation(allow_z=true,allow_m=true) #:nodoc:
81
+ rep = [length].pack("V")
82
+ each {|point| rep << point.binary_representation(allow_z,allow_m) }
83
+ rep
84
+ end
85
+
86
+ #WKB geometry type
87
+ def binary_geometry_type #:nodoc:
88
+ 2
89
+ end
90
+
91
+ #Text representation of a line string
92
+ def text_representation(allow_z=true,allow_m=true) #:nodoc:
93
+ @points.collect{|point| point.text_representation(allow_z,allow_m) }.join(",")
94
+ end
95
+ #WKT geometry type
96
+ def text_geometry_type #:nodoc:
97
+ "LINESTRING"
98
+ end
99
+
100
+ #georss simple representation
101
+ def georss_simple_representation(options) #:nodoc:
102
+ georss_ns = options[:georss_ns] || "georss"
103
+ geom_attr = options[:geom_attr]
104
+ "<#{georss_ns}:line#{geom_attr}>" + georss_poslist + "</#{georss_ns}:line>\n"
105
+ end
106
+ #georss w3c representation : outputs the first point of the line
107
+ def georss_w3cgeo_representation(options) #:nodoc:
108
+ w3cgeo_ns = options[:w3cgeo_ns] || "geo"
109
+ "<#{w3cgeo_ns}:lat>#{self[0].y}</#{w3cgeo_ns}:lat>\n<#{w3cgeo_ns}:long>#{self[0].x}</#{w3cgeo_ns}:long>\n"
110
+ end
111
+ #georss gml representation
112
+ def georss_gml_representation(options) #:nodoc:
113
+ georss_ns = options[:georss_ns] || "georss"
114
+ gml_ns = options[:gml_ns] || "gml"
115
+
116
+ result = "<#{georss_ns}:where>\n<#{gml_ns}:LineString>\n<#{gml_ns}:posList>\n"
117
+ result += georss_poslist
118
+ result += "\n</#{gml_ns}:posList>\n</#{gml_ns}:LineString>\n</#{georss_ns}:where>\n"
119
+ end
120
+
121
+ def georss_poslist #:nodoc:
122
+ map {|point| "#{point.y} #{point.x}"}.join(" ")
123
+ end
124
+
125
+ #outputs the geometry in kml format : options are <tt>:id</tt>, <tt>:tesselate</tt>, <tt>:extrude</tt>,
126
+ #<tt>:altitude_mode</tt>. If the altitude_mode option is not present, the Z (if present) will not be output (since
127
+ #it won't be used by GE anyway: clampToGround is the default)
128
+ def kml_representation(options = {}) #:nodoc:
129
+ result = "<LineString#{options[:id_attr]}>\n"
130
+ result += options[:geom_data] if options[:geom_data]
131
+ result += "<coordinates>"
132
+ result += kml_poslist(options)
133
+ result += "</coordinates>\n"
134
+ result += "</LineString>\n"
135
+ end
136
+
137
+ def kml_poslist(options) #:nodoc:
138
+ pos_list = if options[:allow_z]
139
+ map {|point| "#{point.x},#{point.y},#{options[:fixed_z] || point.z || 0}" }
140
+ else
141
+ map {|point| "#{point.x},#{point.y}" }
142
+ end
143
+ if(options[:reverse])
144
+ pos_list.reverse.join(" ")
145
+ else
146
+ pos_list.join(" ")
147
+ end
148
+ end
149
+
150
+ #Creates a new line string. Accept an array of points as argument
151
+ def self.from_points(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
152
+ line_string = new(srid,with_z,with_m)
153
+ line_string.concat(points)
154
+ line_string
155
+ end
156
+
157
+ #Creates a new line string. Accept a sequence of points as argument : ((x,y)...(x,y))
158
+ def self.from_coordinates(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
159
+ line_string = new(srid,with_z,with_m)
160
+ line_string.concat( points.collect{|point_coords| Point.from_coordinates(point_coords,srid,with_z,with_m) } )
161
+ line_string
162
+ end
163
+
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,12 @@
1
+ require 'geo_ruby/simple_features/line_string'
2
+
3
+ module GeoRuby
4
+ module SimpleFeatures
5
+ #Represents a linear ring, which is a closed line string (see LineString). Currently, no check is performed to verify if the linear ring is really closed.
6
+ class LinearRing < LineString
7
+ def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
8
+ super(srid,with_z,with_m)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,39 @@
1
+ require 'geo_ruby/simple_features/geometry_collection'
2
+
3
+ module GeoRuby
4
+ module SimpleFeatures
5
+ #Represents a group of line strings (see LineString).
6
+ class MultiLineString < GeometryCollection
7
+ def initialize(srid = DEFAULT_SRID,with_z=false,with_m=false)
8
+ super(srid)
9
+ end
10
+
11
+ def binary_geometry_type #:nodoc:
12
+ 5
13
+ end
14
+
15
+ #Text representation of a multi line string
16
+ def text_representation(allow_z=true,allow_m=true) #:nodoc:
17
+ @geometries.collect{|line_string| "(" + line_string.text_representation(allow_z,allow_m) + ")" }.join(",")
18
+ end
19
+ #WKT geometry type
20
+ def text_geometry_type #:nodoc:
21
+ "MULTILINESTRING"
22
+ end
23
+
24
+ #Creates a new multi line string from an array of line strings
25
+ def self.from_line_strings(line_strings,srid=DEFAULT_SRID,with_z=false,with_m=false)
26
+ multi_line_string = new(srid,with_z,with_m)
27
+ multi_line_string.concat(line_strings)
28
+ multi_line_string
29
+ end
30
+
31
+ #Creates a new multi line string from sequences of points : (((x,y)...(x,y)),((x,y)...(x,y)))
32
+ def self.from_coordinates(point_sequences,srid=DEFAULT_SRID,with_z=false,with_m=false)
33
+ multi_line_string = new(srid,with_z,with_m)
34
+ multi_line_string.concat(point_sequences.collect {|points| LineString.from_coordinates(points,srid,with_z,with_m) })
35
+ multi_line_string
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,41 @@
1
+ require 'geo_ruby/simple_features/geometry_collection'
2
+
3
+ module GeoRuby
4
+ module SimpleFeatures
5
+ #Represents a group of points (see Point).
6
+ class MultiPoint < GeometryCollection
7
+
8
+ def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
9
+ super(srid,with_z,with_m)
10
+ end
11
+
12
+ def binary_geometry_type #:nodoc:
13
+ 4
14
+ end
15
+
16
+ #Text representation of a MultiPoint
17
+ def text_representation(allow_z=true,allow_m=true) #:nodoc:
18
+ "(" + @geometries.collect{|point| point.text_representation(allow_z,allow_m)}.join("),(") + ")"
19
+ end
20
+ #WKT geoemtry type
21
+ def text_geometry_type #:nodoc:
22
+ "MULTIPOINT"
23
+ end
24
+
25
+ #Creates a new multi point from an array of points
26
+ def self.from_points(points,srid= DEFAULT_SRID,with_z=false,with_m=false)
27
+ multi_point= new(srid,with_z,with_m)
28
+ multi_point.concat(points)
29
+ multi_point
30
+ end
31
+
32
+ #Creates a new multi point from a list of point coordinates : ((x,y)...(x,y))
33
+ def self.from_coordinates(points,srid= DEFAULT_SRID,with_z=false,with_m=false)
34
+ multi_point= new(srid,with_z,with_m)
35
+ multi_point.concat(points.collect {|point| Point.from_coordinates(point,srid,with_z,with_m)})
36
+ multi_point
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,38 @@
1
+ require 'geo_ruby/simple_features/geometry_collection'
2
+
3
+
4
+ module GeoRuby
5
+ module SimpleFeatures
6
+ #Represents a group of polygons (see Polygon).
7
+ class MultiPolygon < GeometryCollection
8
+ def initialize(srid = DEFAULT_SRID,with_z=false,with_m=false)
9
+ super(srid)
10
+ end
11
+
12
+ def binary_geometry_type #:nodoc:
13
+ 6
14
+ end
15
+ #Text representation of a MultiPolygon
16
+ def text_representation(allow_z=true,allow_m=true) #:nodoc:
17
+ @geometries.collect{|polygon| "(" + polygon.text_representation(allow_z,allow_m) + ")"}.join(",")
18
+ end
19
+ #WKT geometry type
20
+ def text_geometry_type #:nodoc:
21
+ "MULTIPOLYGON"
22
+ end
23
+
24
+ #Creates a multi polygon from an array of polygons
25
+ def self.from_polygons(polygons,srid=DEFAULT_SRID,with_z=false,with_m=false)
26
+ multi_polygon = new(srid,with_z,with_m)
27
+ multi_polygon.concat(polygons)
28
+ multi_polygon
29
+ end
30
+ #Creates a multi polygon from sequences of points : ((((x,y)...(x,y)),((x,y)...(x,y)),((x,y)...(x,y)))
31
+ def self.from_coordinates(point_sequence_sequences,srid= DEFAULT_SRID,with_z=false,with_m=false)
32
+ multi_polygon = new(srid,with_z,with_m)
33
+ multi_polygon.concat( point_sequence_sequences.collect {|point_sequences| Polygon.from_coordinates(point_sequences,srid,with_z,with_m) } )
34
+ multi_polygon
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,236 @@
1
+ require "geo_ruby/simple_features/geometry"
2
+
3
+ module GeoRuby
4
+ module SimpleFeatures
5
+ #Represents a point. It is in 3D if the Z coordinate is not +nil+.
6
+ class Point < Geometry
7
+
8
+ attr_accessor :x,:y,:z,:m
9
+ #if you prefer calling the coordinates lat and lon (or lng, for GeoKit compatibility)
10
+ alias :lon :x
11
+ alias :lng :x
12
+ alias :lat :y
13
+
14
+ def initialize(srid=DEFAULT_SRID,with_z=false,with_m=false)
15
+ super(srid,with_z,with_m)
16
+ @x=0.0
17
+ @y=0.0
18
+ @z=0.0 #default value : meaningful if with_z
19
+ @m=0.0 #default value : meaningful if with_m
20
+ end
21
+ #sets all coordinates in one call. Use the +m+ accessor to set the m.
22
+ def set_x_y_z(x,y,z)
23
+ @x=x
24
+ @y=y
25
+ @z=z
26
+ self
27
+ end
28
+ alias :set_lon_lat_z :set_x_y_z
29
+
30
+ #sets all coordinates of a 2D point in one call
31
+ def set_x_y(x,y)
32
+ @x=x
33
+ @y=y
34
+ self
35
+ end
36
+ alias :set_lon_lat :set_x_y
37
+
38
+ #Return the distance between the 2D points (ie taking care only of the x and y coordinates), assuming the points are in projected coordinates. Euclidian distance in whatever unit the x and y ordinates are.
39
+ def euclidian_distance(point)
40
+ Math.sqrt((point.x - x)**2 + (point.y - y)**2)
41
+ end
42
+
43
+ #Returns the sperical distance in m, with a radius of 6471000m, with the haversine law. Assumes x is the lon and y the lat, in degrees (Changed in version 1.1). The user has to make sure using this distance makes sense (ie she should be in latlon coordinates)
44
+ def spherical_distance(point,radius=6370997.0)
45
+ deg_to_rad = 0.0174532925199433
46
+
47
+ radlat_from = lat * deg_to_rad
48
+ radlat_to = point.lat * deg_to_rad
49
+
50
+ dlat = (point.lat - lat) * deg_to_rad
51
+ dlon = (point.lon - lon) * deg_to_rad
52
+
53
+ a = Math.sin(dlat/2)**2 + Math.cos(radlat_from) * Math.cos(radlat_to) * Math.sin(dlon/2)**2
54
+ c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
55
+ radius * c
56
+ end
57
+
58
+ #Ellipsoidal distance in m using Vincenty's formula. Lifted entirely from Chris Veness's code at http://www.movable-type.co.uk/scripts/LatLongVincenty.html and adapted for Ruby. Assumes the x and y are the lon and lat in degrees.
59
+ #a is the semi-major axis (equatorial radius) of the ellipsoid
60
+ #b is the semi-minor axis (polar radius) of the ellipsoid
61
+ #Their values by default are set to the ones of the WGS84 ellipsoid
62
+ def ellipsoidal_distance(point, a = 6378137.0, b = 6356752.3142)
63
+ deg_to_rad = 0.0174532925199433
64
+
65
+ f = (a-b) / a
66
+ l = (point.lon - lon) * deg_to_rad
67
+
68
+ u1 = Math.atan((1-f) * Math.tan(lat * deg_to_rad ))
69
+ u2 = Math.atan((1-f) * Math.tan(point.lat * deg_to_rad))
70
+ sinU1 = Math.sin(u1)
71
+ cosU1 = Math.cos(u1)
72
+ sinU2 = Math.sin(u2)
73
+ cosU2 = Math.cos(u2)
74
+
75
+ lambda = l
76
+ lambdaP = 2 * Math::PI
77
+ iterLimit = 20
78
+
79
+ while (lambda-lambdaP).abs > 1e-12 && --iterLimit>0
80
+ sinLambda = Math.sin(lambda)
81
+ cosLambda = Math.cos(lambda)
82
+ sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) + (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda))
83
+
84
+ return 0 if sinSigma == 0 #coincident points
85
+
86
+ cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda
87
+ sigma = Math.atan2(sinSigma, cosSigma)
88
+ sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma
89
+ cosSqAlpha = 1 - sinAlpha*sinAlpha
90
+ cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha
91
+
92
+ cos2SigmaM = 0 if (cos2SigmaM.nan?) #equatorial line: cosSqAlpha=0
93
+
94
+ c = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha))
95
+ lambdaP = lambda
96
+ lambda = l + (1-c) * f * sinAlpha * (sigma + c * sinSigma * (cos2SigmaM + c * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)))
97
+ end
98
+ return NaN if iterLimit==0 #formula failed to converge
99
+
100
+ uSq = cosSqAlpha * (a*a - b*b) / (b*b)
101
+ a_bis = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)))
102
+ b_bis = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)))
103
+ deltaSigma = b_bis * sinSigma*(cos2SigmaM + b_bis/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)- b_bis/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)))
104
+
105
+ b*a_bis*(sigma-deltaSigma)
106
+ end
107
+
108
+
109
+ #Bounding box in 2D/3D. Returns an array of 2 points
110
+ def bounding_box
111
+ unless with_z
112
+ [Point.from_x_y(@x,@y),Point.from_x_y(@x,@y)]
113
+ else
114
+ [Point.from_x_y_z(@x,@y,@z),Point.from_x_y_z(@x,@y,@z)]
115
+ end
116
+ end
117
+
118
+ def m_range
119
+ [@m,@m]
120
+ end
121
+
122
+ #tests the equality of the position of points + m
123
+ def ==(other_point)
124
+ if other_point.class != self.class
125
+ false
126
+ else
127
+ @x == other_point.x and @y == other_point.y and @z == other_point.z and @m == other_point.m
128
+ end
129
+ end
130
+
131
+ #binary representation of a point. It lacks some headers to be a valid EWKB representation.
132
+ def binary_representation(allow_z=true,allow_m=true) #:nodoc:
133
+ bin_rep = [@x,@y].pack("EE")
134
+ bin_rep += [@z].pack("E") if @with_z and allow_z #Default value so no crash
135
+ bin_rep += [@m].pack("E") if @with_m and allow_m #idem
136
+ bin_rep
137
+ end
138
+ #WKB geometry type of a point
139
+ def binary_geometry_type#:nodoc:
140
+ 1
141
+ end
142
+
143
+ #text representation of a point
144
+ def text_representation(allow_z=true,allow_m=true) #:nodoc:
145
+ tex_rep = "#{@x} #{@y}"
146
+ tex_rep += " #{@z}" if @with_z and allow_z
147
+ tex_rep += " #{@m}" if @with_m and allow_m
148
+ tex_rep
149
+ end
150
+ #WKT geometry type of a point
151
+ def text_geometry_type #:nodoc:
152
+ "POINT"
153
+ end
154
+
155
+ #georss simple representation
156
+ def georss_simple_representation(options) #:nodoc:
157
+ georss_ns = options[:georss_ns] || "georss"
158
+ geom_attr = options[:geom_attr]
159
+ "<#{georss_ns}:point#{geom_attr}>#{y} #{x}</#{georss_ns}:point>\n"
160
+ end
161
+ #georss w3c representation
162
+ def georss_w3cgeo_representation(options) #:nodoc:
163
+ w3cgeo_ns = options[:w3cgeo_ns] || "geo"
164
+ "<#{w3cgeo_ns}:lat>#{y}</#{w3cgeo_ns}:lat>\n<#{w3cgeo_ns}:long>#{x}</#{w3cgeo_ns}:long>\n"
165
+ end
166
+ #georss gml representation
167
+ def georss_gml_representation(options) #:nodoc:
168
+ georss_ns = options[:georss_ns] || "georss"
169
+ gml_ns = options[:gml_ns] || "gml"
170
+ result = "<#{georss_ns}:where>\n<#{gml_ns}:Point>\n<#{gml_ns}:pos>"
171
+ result += "#{y} #{x}"
172
+ result += "</#{gml_ns}:pos>\n</#{gml_ns}:Point>\n</#{georss_ns}:where>\n"
173
+ end
174
+
175
+ #outputs the geometry in kml format : options are <tt>:id</tt>, <tt>:tesselate</tt>, <tt>:extrude</tt>,
176
+ #<tt>:altitude_mode</tt>. If the altitude_mode option is not present, the Z (if present) will not be output (since
177
+ #it won't be used by GE anyway: clampToGround is the default)
178
+ def kml_representation(options = {}) #:nodoc:
179
+ result = "<Point#{options[:id_attr]}>\n"
180
+ result += options[:geom_data] if options[:geom_data]
181
+ result += "<coordinates>#{x},#{y}"
182
+ result += ",#{options[:fixed_z] || z ||0}" if options[:allow_z]
183
+ result += "</coordinates>\n"
184
+ result += "</Point>\n"
185
+ end
186
+
187
+ #creates a point from an array of coordinates
188
+ def self.from_coordinates(coords,srid=DEFAULT_SRID,with_z=false,with_m=false)
189
+ if ! (with_z or with_m)
190
+ from_x_y(coords[0],coords[1],srid)
191
+ elsif with_z and with_m
192
+ from_x_y_z_m(coords[0],coords[1],coords[2],coords[3],srid)
193
+ elsif with_z
194
+ from_x_y_z(coords[0],coords[1],coords[2],srid)
195
+ else
196
+ from_x_y_m(coords[0],coords[1],coords[2],srid)
197
+ end
198
+ end
199
+
200
+ #creates a point from the X and Y coordinates
201
+ def self.from_x_y(x,y,srid=DEFAULT_SRID)
202
+ point= new(srid)
203
+ point.set_x_y(x,y)
204
+ end
205
+
206
+ #creates a point from the X, Y and Z coordinates
207
+ def self.from_x_y_z(x,y,z,srid=DEFAULT_SRID)
208
+ point= new(srid,true)
209
+ point.set_x_y_z(x,y,z)
210
+ end
211
+
212
+
213
+ #creates a point from the X, Y and M coordinates
214
+ def self.from_x_y_m(x,y,m,srid=DEFAULT_SRID)
215
+ point= new(srid,false,true)
216
+ point.m=m
217
+ point.set_x_y(x,y)
218
+ end
219
+
220
+ #creates a point from the X, Y, Z and M coordinates
221
+ def self.from_x_y_z_m(x,y,z,m,srid=DEFAULT_SRID)
222
+ point= new(srid,true,true)
223
+ point.m=m
224
+ point.set_x_y_z(x,y,z)
225
+ end
226
+
227
+ #aliasing the constructors in case you want to use lat/lon instead of y/x
228
+ class << self
229
+ alias :from_lon_lat :from_x_y
230
+ alias :from_lon_lat_z :from_x_y_z
231
+ alias :from_lon_lat_m :from_x_y_m
232
+ alias :from_lon_lat_z_m :from_x_y_z_m
233
+ end
234
+ end
235
+ end
236
+ end