geojson 1.0.0
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.rdoc +28 -0
- data/geojson.gemspec +8 -0
- data/lib/geojson.rb +146 -0
- data/test/geojson_test.rb +76 -0
- metadata +70 -0
data/README.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
h1. What is GeoJSON?
|
2
|
+
|
3
|
+
GeoJSON is a JSON representation of Simple Feature geometries defined by Open Geospatial Consortium (OGC). Simple features is a standard for representing geographic objects. You can read the GeoJSON spec at: "http://geojson.org/geojson-spec.html":http://geojson.org/geojson-spec.html
|
4
|
+
|
5
|
+
h1. Using GeoJSON
|
6
|
+
|
7
|
+
h2. Prerequisits
|
8
|
+
|
9
|
+
This GeoJSON is an extension to the GeoRuby gem.
|
10
|
+
|
11
|
+
<pre>
|
12
|
+
<code>
|
13
|
+
gem install nofxx-georuby
|
14
|
+
git clone git@github.com:sabman/geojson.git
|
15
|
+
cd geojson
|
16
|
+
|
17
|
+
irb
|
18
|
+
require 'geo_ruby'
|
19
|
+
require 'geojson'
|
20
|
+
geojson = '{ "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }'
|
21
|
+
# read geometry
|
22
|
+
geom = Geometry.from_geojson(geojson)
|
23
|
+
# write geometry
|
24
|
+
geom.to_json
|
25
|
+
</code>
|
26
|
+
</pre>
|
27
|
+
|
28
|
+
You can see the "tests":http://github.com/sabman/geojson/blob/master/tests/test_geojson.rb for more examples
|
data/geojson.gemspec
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "geojson"
|
3
|
+
s.version = "1.0.0"
|
4
|
+
s.description = "This GeoJSON is an extension to the GeoRuby gem"
|
5
|
+
s.summary = "more info at http://github.com/sabman/geojson"
|
6
|
+
s.author = "Shoaib Burq"
|
7
|
+
s.files = Dir["{lib/**/*.rb,README.rdoc,test/**/*.rb,Rakefile,*.gemspec}"]
|
8
|
+
end
|
data/lib/geojson.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2008 Primin Kalberer, Sourcepole AG
|
3
|
+
#
|
4
|
+
# This file was part of Mapfish server
|
5
|
+
# modified by Shoaib Burq
|
6
|
+
# - added 3D support
|
7
|
+
# - refactored the when switch for duplication
|
8
|
+
#
|
9
|
+
# MapFish Server is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# MapFish Server is distributed in the hope that if will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU Less General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have recenived a copy of the GNU Lesser General Public License
|
20
|
+
# along with MapFish server. If not, see <http://gnu.org/licenses/>.
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'geo_ruby'
|
24
|
+
require 'json/pure'
|
25
|
+
include GeoRuby::SimpleFeatures
|
26
|
+
|
27
|
+
module GeoRuby
|
28
|
+
module SimpleFeatures
|
29
|
+
class Geometry
|
30
|
+
def self.from_geojson(data, srid=DEFAULT_SRID)
|
31
|
+
data ||= {}
|
32
|
+
if data.is_a?(String)
|
33
|
+
require 'active_support'
|
34
|
+
data = ActiveSupport::JSON::decode(data)
|
35
|
+
end
|
36
|
+
coords = data['coordinates'] || data[:coordinates]
|
37
|
+
data_type = data['type'] || data[:type]
|
38
|
+
case data_type
|
39
|
+
when 'Point','LineString','Polygon','MultiPoint','MultiLineString','MultiPolygon'
|
40
|
+
Kernel.const_get(data_type).from_coordinates(coords, srid)
|
41
|
+
when 'GeometryCollection'
|
42
|
+
geometriesJson = data['geometries'] || data[:geometries]
|
43
|
+
geometries = geometriesJson.collect{|geom| from_geojson(geom)}
|
44
|
+
GeometryCollection.from_geometries(geometries, srid)
|
45
|
+
when 'Feature'
|
46
|
+
geometryJson = data['geometry'] || data[:geometry]
|
47
|
+
properties = data['properties'] || data[:properties]
|
48
|
+
id = data['id'] || data[:id]
|
49
|
+
Feature.new(from_geojson(geometryJson), properties, id)
|
50
|
+
when 'FeatureCollection'
|
51
|
+
features = data['features'] || data[:features]
|
52
|
+
FeatureCollection.new(features.collect { |feature| from_geojson(feature) })
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
class Point
|
57
|
+
def to_json(options = {})
|
58
|
+
{ :type => "Point",
|
59
|
+
:coordinates => (with_z ? [self.x, self.y, self.z] : [self.x, self.y])
|
60
|
+
}.to_json(options)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
class LineString
|
64
|
+
def to_json(options = {})
|
65
|
+
coords = self.points.collect { |point| with_z ? [point.x, point.y, point.z] : [point.x, point.y] }
|
66
|
+
{:type => "LineString", :coordinates => coords}.to_json(options)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
class Polygon
|
70
|
+
def to_json(options = {})
|
71
|
+
coords = self.collect{|ring| ring.points.collect{|point| with_z ? [point.x, point.y, point.z] : [point.x, point.y] } }
|
72
|
+
{:type => "Polygon", :coordinates => coords }.to_json(options)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
class MultiPoint
|
76
|
+
def to_json(options = {})
|
77
|
+
coords = self.geometries.collect {|geom| with_z ? [geom.x, geom.y, geom.z] : [geom.x, geom.y]}
|
78
|
+
{:type => "MultiPoint", :coordinates => coords}.to_json(options)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
class MultiLineString
|
82
|
+
def to_json(options = {})
|
83
|
+
coords = self.geometries.collect {|geom| geom.points.collect {|point| with_z ? [point.x, point.y, point.z]:[point.x, point.y] }}
|
84
|
+
{:type => "MultiLineString", :coordinates => coords}.to_json(options)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
class MultiPolygon
|
88
|
+
def to_json(options = {})
|
89
|
+
coords = self.geometries.collect{|poly| poly.collect{|ring| ring.points.collect{|point| with_z ? [point.x, point.y, point.z]:[point.x, point.y] }}}
|
90
|
+
{:type => "MultiPolygon", :coordinates => coords}.to_json(options)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
class GeometryCollection
|
94
|
+
def to_json(options = {})
|
95
|
+
{:type => "GeometryCollection", :geometries => self.geometries}.to_json(options)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Feature
|
100
|
+
attr_accessor :geometry
|
101
|
+
attr_accessor :properties
|
102
|
+
attr_accessor :id
|
103
|
+
|
104
|
+
def initialize(geometry, properties={}, id=nil)
|
105
|
+
@geometry=geometry
|
106
|
+
@properties=properties
|
107
|
+
@id=id
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_json(options = {})
|
111
|
+
result = {:type => "Feature",
|
112
|
+
:geometry => @geometry,
|
113
|
+
:properties => @properties}
|
114
|
+
result[:id] = @id if @id != nil
|
115
|
+
return result.to_json(options)
|
116
|
+
end
|
117
|
+
|
118
|
+
def ==(other)
|
119
|
+
if other.class != self.class
|
120
|
+
false
|
121
|
+
else
|
122
|
+
@geometry==other.geometry and @properties==other.properties and @id==other.id
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class FeatureCollection
|
128
|
+
attr_accessor :features
|
129
|
+
def initialize(features=[])
|
130
|
+
@features=features
|
131
|
+
end
|
132
|
+
|
133
|
+
def to_json(options={})
|
134
|
+
{:type => "FeatureCollection", :features => @features}.to_json(options)
|
135
|
+
end
|
136
|
+
|
137
|
+
def ==(other)
|
138
|
+
if other.class != self.class
|
139
|
+
false
|
140
|
+
else
|
141
|
+
@features==other.features
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'json'
|
4
|
+
require 'geojson'
|
5
|
+
require 'active_support'
|
6
|
+
|
7
|
+
class GeojsonTest < Test::Unit::TestCase
|
8
|
+
include GeoRuby::SimpleFeatures
|
9
|
+
include ActiveSupport
|
10
|
+
|
11
|
+
def check_geom(geojson, expected)
|
12
|
+
geom=Geometry.from_geojson(geojson)
|
13
|
+
assert_equal(expected, geom)
|
14
|
+
assert_equal(geojson.gsub(/\s/, ""), geom.to_json.gsub(/\s/, ""))
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_point_from_hash
|
18
|
+
geom=Geometry.from_geojson(JSON::decode('{ "type": "Point", "coordinates": [100.0, 0.0] }'))
|
19
|
+
assert_equal(Point.from_coordinates([100.0, 0.0]), geom)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_point
|
23
|
+
check_geom('{ "type": "Point", "coordinates": [100.0, 0.0] }',
|
24
|
+
Point.from_coordinates([100.0, 0.0]))
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_linestring
|
28
|
+
check_geom('{ "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }',
|
29
|
+
LineString.from_coordinates([ [100.0, 0.0], [101.0, 1.0] ]))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_polygon_no_hole
|
33
|
+
check_geom('{ "type": "Polygon", "coordinates": [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ] }',
|
34
|
+
Polygon.from_coordinates([ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ] ]))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_polygon_with_hole
|
38
|
+
check_geom('{ "type": "Polygon", "coordinates": [ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ], [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ] ] }',
|
39
|
+
Polygon.from_coordinates([ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ], [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ] ]))
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_multi_point
|
43
|
+
check_geom('{ "type": "MultiPoint", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }',
|
44
|
+
MultiPoint.from_coordinates([ [100.0, 0.0], [101.0, 1.0] ]))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_multi_linestring
|
48
|
+
check_geom('{ "type": "MultiLineString", "coordinates": [ [ [100.0, 0.0], [101.0, 1.0] ], [ [102.0, 2.0], [103.0, 3.0] ] ] }',
|
49
|
+
MultiLineString.from_coordinates([ [ [100.0, 0.0], [101.0, 1.0] ], [ [102.0, 2.0], [103.0, 3.0] ] ]))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_multi_polygon_no_hole
|
53
|
+
check_geom('{ "type": "MultiPolygon", "coordinates": [ [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] ] }',
|
54
|
+
MultiPolygon.from_coordinates([ [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] ]))
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_geometry_collection
|
58
|
+
check_geom('{ "type": "GeometryCollection", "geometries": [ { "type": "Point", "coordinates": [100.0, 0.0] }, { "type": "LineString", "coordinates": [ [101.0, 0.0], [102.0, 1.0] ] } ] }', GeometryCollection.from_geometries([Point.from_coordinates([100.0, 0.0]),
|
59
|
+
LineString.from_coordinates([ [101.0, 0.0], [102.0, 1.0] ])]))
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_feature
|
63
|
+
check_geom('{ "type": "Feature", "geometry": {"type": "Point", "coordinates": [102.0, 0.5]}, "properties": {"prop0": "value0"} }',
|
64
|
+
Feature.new(Point.from_coordinates([102.0, 0.5]), {"prop0"=>"value0"}))
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_feature_collection
|
68
|
+
check_geom('{ "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates":[102.0, 0.5]}, "id": "toto", "properties": {"prop0": "value0"}}, {"type": "Feature", "geometry": {"type": "LineString", "coordinates": [[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]]}, "properties": {"prop0": "value0", "prop1": 0.0}}]}',
|
69
|
+
FeatureCollection.new([
|
70
|
+
Feature.new(Point.from_coordinates([102.0, 0.5]), {"prop0"=>"value0"}, "toto"),
|
71
|
+
Feature.new(LineString.from_coordinates([ [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] ]), {"prop0"=>"value0", "prop1"=>0.0})
|
72
|
+
])
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: geojson
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Shoaib Burq
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-01 00:00:00 -03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: This GeoJSON is an extension to the GeoRuby gem
|
23
|
+
email:
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- lib/geojson.rb
|
32
|
+
- README.rdoc
|
33
|
+
- test/geojson_test.rb
|
34
|
+
- geojson.gemspec
|
35
|
+
has_rdoc: true
|
36
|
+
homepage:
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
hash: 3
|
50
|
+
segments:
|
51
|
+
- 0
|
52
|
+
version: "0"
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.7
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: more info at http://github.com/sabman/geojson
|
69
|
+
test_files: []
|
70
|
+
|