rgeo 0.1.10
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/History.rdoc +22 -0
- data/README.rdoc +124 -0
- data/Version +1 -0
- data/ext/geos_c_impl/extconf.rb +72 -0
- data/ext/geos_c_impl/factory.c +468 -0
- data/ext/geos_c_impl/factory.h +217 -0
- data/ext/geos_c_impl/geometry.c +644 -0
- data/ext/geos_c_impl/geometry.h +65 -0
- data/ext/geos_c_impl/geometry_collection.c +580 -0
- data/ext/geos_c_impl/geometry_collection.h +79 -0
- data/ext/geos_c_impl/globals.h +58 -0
- data/ext/geos_c_impl/line_string.c +468 -0
- data/ext/geos_c_impl/line_string.h +74 -0
- data/ext/geos_c_impl/main.c +65 -0
- data/ext/geos_c_impl/point.c +201 -0
- data/ext/geos_c_impl/point.h +77 -0
- data/ext/geos_c_impl/polygon.c +259 -0
- data/ext/geos_c_impl/polygon.h +76 -0
- data/ext/geos_c_impl/preface.h +42 -0
- data/lib/rgeo.rb +68 -0
- data/lib/rgeo/errors.rb +59 -0
- data/lib/rgeo/features.rb +89 -0
- data/lib/rgeo/features/curve.rb +155 -0
- data/lib/rgeo/features/factory.rb +191 -0
- data/lib/rgeo/features/geometry.rb +560 -0
- data/lib/rgeo/features/geometry_collection.rb +118 -0
- data/lib/rgeo/features/line.rb +65 -0
- data/lib/rgeo/features/line_string.rb +101 -0
- data/lib/rgeo/features/linear_ring.rb +65 -0
- data/lib/rgeo/features/multi_curve.rb +112 -0
- data/lib/rgeo/features/multi_line_string.rb +65 -0
- data/lib/rgeo/features/multi_point.rb +72 -0
- data/lib/rgeo/features/multi_polygon.rb +96 -0
- data/lib/rgeo/features/multi_surface.rb +115 -0
- data/lib/rgeo/features/point.rb +97 -0
- data/lib/rgeo/features/polygon.rb +141 -0
- data/lib/rgeo/features/surface.rb +121 -0
- data/lib/rgeo/geo_json.rb +58 -0
- data/lib/rgeo/geo_json/coder.rb +305 -0
- data/lib/rgeo/geo_json/entities.rb +284 -0
- data/lib/rgeo/geo_json/interface.rb +95 -0
- data/lib/rgeo/geography.rb +75 -0
- data/lib/rgeo/geography/common/geometry_collection_methods.rb +206 -0
- data/lib/rgeo/geography/common/geometry_methods.rb +92 -0
- data/lib/rgeo/geography/common/helper.rb +102 -0
- data/lib/rgeo/geography/common/line_string_methods.rb +187 -0
- data/lib/rgeo/geography/common/point_methods.rb +149 -0
- data/lib/rgeo/geography/common/polygon_methods.rb +122 -0
- data/lib/rgeo/geography/factories.rb +136 -0
- data/lib/rgeo/geography/factory.rb +246 -0
- data/lib/rgeo/geography/projected_window.rb +467 -0
- data/lib/rgeo/geography/simple_mercator/feature_classes.rb +320 -0
- data/lib/rgeo/geography/simple_mercator/feature_methods.rb +291 -0
- data/lib/rgeo/geography/simple_mercator/projector.rb +116 -0
- data/lib/rgeo/geography/simple_spherical/calculations.rb +70 -0
- data/lib/rgeo/geography/simple_spherical/geometry_collection_impl.rb +66 -0
- data/lib/rgeo/geography/simple_spherical/geometry_methods.rb +59 -0
- data/lib/rgeo/geography/simple_spherical/line_string_impl.rb +104 -0
- data/lib/rgeo/geography/simple_spherical/multi_line_string_impl.rb +67 -0
- data/lib/rgeo/geography/simple_spherical/multi_point_impl.rb +67 -0
- data/lib/rgeo/geography/simple_spherical/multi_polygon_impl.rb +67 -0
- data/lib/rgeo/geography/simple_spherical/point_impl.rb +85 -0
- data/lib/rgeo/geography/simple_spherical/polygon_impl.rb +66 -0
- data/lib/rgeo/geos.rb +72 -0
- data/lib/rgeo/geos/factory.rb +260 -0
- data/lib/rgeo/geos/impl_additions.rb +57 -0
- data/lib/rgeo/geos/interface.rb +74 -0
- data/lib/rgeo/version.rb +52 -0
- data/tests/geos/tc_factory.rb +91 -0
- data/tests/geos/tc_geometry_collection.rb +226 -0
- data/tests/geos/tc_line_string.rb +310 -0
- data/tests/geos/tc_misc.rb +72 -0
- data/tests/geos/tc_multi_line_string.rb +211 -0
- data/tests/geos/tc_multi_point.rb +202 -0
- data/tests/geos/tc_multi_polygon.rb +210 -0
- data/tests/geos/tc_point.rb +305 -0
- data/tests/geos/tc_polygon.rb +240 -0
- data/tests/simple_mercator/tc_point.rb +303 -0
- data/tests/simple_mercator/tc_window.rb +219 -0
- data/tests/tc_geojson.rb +230 -0
- data/tests/tc_oneoff.rb +61 -0
- metadata +162 -0
@@ -0,0 +1,141 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Polygon feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
module Features
|
40
|
+
|
41
|
+
|
42
|
+
# == SFS 1.1 Description
|
43
|
+
#
|
44
|
+
# A Polygon is a planar Surface defined by 1 exterior boundary and 0 or
|
45
|
+
# more interior boundaries. Each interior boundary defines a hole in
|
46
|
+
# the Polygon.
|
47
|
+
#
|
48
|
+
# The assertions for Polygons (the rules that define valid Polygons)
|
49
|
+
# are as follows:
|
50
|
+
#
|
51
|
+
# (a) Polygons are topologically closed;
|
52
|
+
#
|
53
|
+
# (b) The boundary of a Polygon consists of a set of LinearRings that
|
54
|
+
# make up its exterior and interior boundaries;
|
55
|
+
#
|
56
|
+
# (c) No two Rings in the boundary cross and the Rings in the boundary
|
57
|
+
# of a Polygon may intersect at a Point but only as a tangent;
|
58
|
+
#
|
59
|
+
# (d) A Polygon may not have cut lines, spikes or punctures;
|
60
|
+
#
|
61
|
+
# (e) The interior of every Polygon is a connected point set;
|
62
|
+
#
|
63
|
+
# (f) The exterior of a Polygon with 1 or more holes is not connected.
|
64
|
+
# Each hole defines a connected component of the exterior.
|
65
|
+
#
|
66
|
+
# In the above assertions, interior, closure and exterior have the
|
67
|
+
# standard topological definitions. The combination of (a) and (c) make
|
68
|
+
# a Polygon a regular closed Point set.
|
69
|
+
#
|
70
|
+
# Polygons are simple geometric objects.
|
71
|
+
#
|
72
|
+
# == Notes
|
73
|
+
#
|
74
|
+
# Polygon is defined as a module and is provided primarily
|
75
|
+
# for the sake of documentation. Implementations need not necessarily
|
76
|
+
# include this module itself. Therefore, you should not depend on the
|
77
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
78
|
+
# class method. A corresponding === operator is also provided to
|
79
|
+
# to support case-when constructs.
|
80
|
+
|
81
|
+
module Polygon
|
82
|
+
|
83
|
+
include Surface
|
84
|
+
include ::Enumerable
|
85
|
+
|
86
|
+
|
87
|
+
# === SFS 1.1 Description
|
88
|
+
#
|
89
|
+
# Returns the exterior ring of this Polygon.
|
90
|
+
#
|
91
|
+
# === Notes
|
92
|
+
#
|
93
|
+
# Returns an object that supports the LinearRing interface.
|
94
|
+
|
95
|
+
def exterior_ring
|
96
|
+
raise Errors::MethodUnimplemented
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# === SFS 1.1 Description
|
101
|
+
#
|
102
|
+
# Returns the number of interiorRings in this Polygon.
|
103
|
+
#
|
104
|
+
# === Notes
|
105
|
+
#
|
106
|
+
# Returns an integer.
|
107
|
+
|
108
|
+
def num_interior_rings
|
109
|
+
raise Errors::MethodUnimplemented
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# === SFS 1.1 Description
|
114
|
+
#
|
115
|
+
# Returns the Nth interiorRing for this Polygon as a LineString.
|
116
|
+
#
|
117
|
+
# === Notes
|
118
|
+
#
|
119
|
+
# Returns an object that supports the LineString interface, or nil
|
120
|
+
# if the given n is out of range.
|
121
|
+
|
122
|
+
def interior_ring_n(n_)
|
123
|
+
raise Errors::MethodUnimplemented
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# Returns the interior rings as a (possibly empty) array of objects
|
128
|
+
# that support the LinearRing interface.
|
129
|
+
|
130
|
+
def interior_rings
|
131
|
+
raise Errors::MethodUnimplemented
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Surface feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
module Features
|
40
|
+
|
41
|
+
|
42
|
+
# == SFS 1.1 Description
|
43
|
+
#
|
44
|
+
# A Surface is a 2-dimensional geometric object.
|
45
|
+
#
|
46
|
+
# A simple Surface consists of a single "patch" that is associated with
|
47
|
+
# one "exterior boundary" and 0 or more "interior" boundaries. Simple
|
48
|
+
# Surfaces in 3-dimensional space are isomorphic to planar Surfaces.
|
49
|
+
# Polyhedral Surfaces are formed by "stitching" together simple
|
50
|
+
# Surfaces along their boundaries, polyhedral Surfaces in 3-dimensional
|
51
|
+
# space may not be planar as a whole.
|
52
|
+
#
|
53
|
+
# The boundary of a simple Surface is the set of closed Curves
|
54
|
+
# corresponding to its "exterior" and "interior" boundaries.
|
55
|
+
#
|
56
|
+
# The only instantiable subclass of Surface defined in this
|
57
|
+
# specification, Polygon, is a simple Surface that is planar.
|
58
|
+
#
|
59
|
+
# == Notes
|
60
|
+
#
|
61
|
+
# Surface is defined as a module and is provided primarily
|
62
|
+
# for the sake of documentation. Implementations need not necessarily
|
63
|
+
# include this module itself. Therefore, you should not depend on the
|
64
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
65
|
+
# class method. A corresponding === operator is also provided to
|
66
|
+
# to support case-when constructs.
|
67
|
+
#
|
68
|
+
# Some implementations may support higher dimensional points.
|
69
|
+
|
70
|
+
module Surface
|
71
|
+
|
72
|
+
include Geometry
|
73
|
+
|
74
|
+
|
75
|
+
# === SFS 1.1 Description
|
76
|
+
#
|
77
|
+
# The area of this Surface, as measured in the spatial reference
|
78
|
+
# system of this Surface.
|
79
|
+
#
|
80
|
+
# === Notes
|
81
|
+
#
|
82
|
+
# Returns a floating-point scalar value.
|
83
|
+
|
84
|
+
def area
|
85
|
+
raise Errors::MethodUnimplemented
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# === SFS 1.1 Description
|
90
|
+
#
|
91
|
+
# The mathematical centroid for this Surface as a Point. The result
|
92
|
+
# is not guaranteed to be on this Surface.
|
93
|
+
#
|
94
|
+
# === Notes
|
95
|
+
#
|
96
|
+
# Returns an object that supports the Point interface.
|
97
|
+
|
98
|
+
def centroid
|
99
|
+
raise Errors::MethodUnimplemented
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
# === SFS 1.1 Description
|
104
|
+
#
|
105
|
+
# A Point guaranteed to be on this Surface.
|
106
|
+
#
|
107
|
+
# === Notes
|
108
|
+
#
|
109
|
+
# Returns an object that supports the Point interface.
|
110
|
+
|
111
|
+
def point_on_surface
|
112
|
+
raise Errors::MethodUnimplemented
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# GeoJSON implementation for RGeo
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
|
40
|
+
# This is a namespace for a set of tools that provide GeoJSON encoding.
|
41
|
+
# See http://geojson.org/ for more information about this specification.
|
42
|
+
|
43
|
+
module GeoJSON
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# Dependency source files.
|
51
|
+
paths_ = [
|
52
|
+
'features',
|
53
|
+
'geo_json/entities',
|
54
|
+
'geo_json/coder',
|
55
|
+
'geo_json/interface',
|
56
|
+
]
|
57
|
+
|
58
|
+
paths_.each{ |path_| require "rgeo/#{path_}" }
|
@@ -0,0 +1,305 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# GeoJSON encoder object
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
require 'json'
|
38
|
+
|
39
|
+
|
40
|
+
module RGeo
|
41
|
+
|
42
|
+
module GeoJSON
|
43
|
+
|
44
|
+
|
45
|
+
# This object encapsulates encoding and decoding settings (principally
|
46
|
+
# the RGeo::Features::Factory and the RGeo::GeoJSON::EntityFactory to
|
47
|
+
# be used) so that you can encode and decode without specifying those
|
48
|
+
# settings every time.
|
49
|
+
|
50
|
+
class Coder
|
51
|
+
|
52
|
+
|
53
|
+
# Create a new coder settings object. The geo factory is passed as
|
54
|
+
# a required argument. The entity factory is optional. To provide
|
55
|
+
# one, pass an option with key <tt>:entity_factory</tt>. It defaults
|
56
|
+
# to the default RGeo::GeoJSON::EntityFactory, which generates
|
57
|
+
# objects of type RGeo::GeoJSON::Feature or RGeo::GeoJSON::FeatureCollection.
|
58
|
+
|
59
|
+
def initialize(geo_factory_, opts_={})
|
60
|
+
@geo_factory = geo_factory_
|
61
|
+
@entity_factory = opts_[:entity_factory] || EntityFactory.instance
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Encode the given object as GeoJSON. The object may be one of the
|
66
|
+
# geometry objects specified in RGeo::Features, or an appropriate
|
67
|
+
# GeoJSON wrapper entity supported by this coder's entity factory.
|
68
|
+
|
69
|
+
def encode(object_)
|
70
|
+
if @entity_factory.is_feature_collection?(object_)
|
71
|
+
{
|
72
|
+
'type' => 'FeatureCollection',
|
73
|
+
'features' => @entity_factory.map_feature_collection(object_){ |f_| _encode_feature(f_) },
|
74
|
+
}
|
75
|
+
elsif @entity_factory.is_feature?(object_)
|
76
|
+
_encode_feature(object_)
|
77
|
+
else
|
78
|
+
_encode_geometry(object_)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# Decode an object from GeoJSON. The input may be a JSON hash, a
|
84
|
+
# String, or an IO object from which to read the JSON string.
|
85
|
+
|
86
|
+
def decode(input_)
|
87
|
+
if input_.kind_of?(::IO)
|
88
|
+
input_ = input_.read rescue nil
|
89
|
+
end
|
90
|
+
if input_.kind_of?(::String)
|
91
|
+
input_ = ::JSON.parse(input_) rescue nil
|
92
|
+
end
|
93
|
+
unless input_.kind_of?(::Hash)
|
94
|
+
return nil
|
95
|
+
end
|
96
|
+
case input_['type']
|
97
|
+
when 'FeatureCollection'
|
98
|
+
features_ = input_['features']
|
99
|
+
features_ = [] unless features_.kind_of?(::Array)
|
100
|
+
decoded_features_ = []
|
101
|
+
features_.each do |f_|
|
102
|
+
if f_['type'] == 'Feature'
|
103
|
+
decoded_features_ << _decode_feature(f_)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
@entity_factory.feature_collection(decoded_features_)
|
107
|
+
when 'Feature'
|
108
|
+
_decode_feature(input_)
|
109
|
+
else
|
110
|
+
_decode_geometry(input_)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# Returns the RGeo::Features::Factory used to generate geometry objects.
|
116
|
+
|
117
|
+
def geo_factory
|
118
|
+
@geo_factory
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
# Returns the RGeo::GeoJSON::EntityFactory used to generate GeoJSON
|
123
|
+
# wrapper entities.
|
124
|
+
|
125
|
+
def entity_factory
|
126
|
+
@entity_factory
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
def _encode_feature(object_) # :nodoc:
|
131
|
+
json_ = {
|
132
|
+
'type' => 'Feature',
|
133
|
+
'geometry' => _encode_geometry(@entity_factory.get_feature_geometry(object_)),
|
134
|
+
'properties' => @entity_factory.get_feature_properties(object_).dup,
|
135
|
+
}
|
136
|
+
id_ = @entity_factory.get_feature_id(object_)
|
137
|
+
json_['id'] = id_ if id_
|
138
|
+
json_
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
def _encode_geometry(object_) # :nodoc:
|
143
|
+
case object_
|
144
|
+
when Features::Point
|
145
|
+
{
|
146
|
+
'type' => 'Point',
|
147
|
+
'coordinates' => [object_.x, object_.y],
|
148
|
+
}
|
149
|
+
when Features::LineString
|
150
|
+
{
|
151
|
+
'type' => 'LineString',
|
152
|
+
'coordinates' => object_.points.map{ |p_| [p_.x, p_.y] },
|
153
|
+
}
|
154
|
+
when Features::Polygon
|
155
|
+
{
|
156
|
+
'type' => 'Polygon',
|
157
|
+
'coordinates' => [object_.exterior_ring.points.map{ |p_| [p_.x, p_.y] }] + object_.interior_rings.map{ |r_| r_.points.map{ |p_| [p_.x, p_.y] } }
|
158
|
+
}
|
159
|
+
when Features::MultiPoint
|
160
|
+
{
|
161
|
+
'type' => 'MultiPoint',
|
162
|
+
'coordinates' => object_.map{ |p_| [p_.x, p_.y] },
|
163
|
+
}
|
164
|
+
when Features::MultiLineString
|
165
|
+
{
|
166
|
+
'type' => 'MultiLineString',
|
167
|
+
'coordinates' => object_.map{ |ls_| ls_.points.map{ |p_| [p_.x, p_.y] } },
|
168
|
+
}
|
169
|
+
when Features::MultiPolygon
|
170
|
+
{
|
171
|
+
'type' => 'MultiPolygon',
|
172
|
+
'coordinates' => object_.map{ |poly_| [poly_.exterior_ring.points.map{ |p_| [p_.x, p_.y] }] + poly_.interior_rings.map{ |r_| r_.points.map{ |p_| [p_.x, p_.y] } } },
|
173
|
+
}
|
174
|
+
when Features::GeometryCollection
|
175
|
+
{
|
176
|
+
'type' => 'GeometryCollection',
|
177
|
+
'geometries' => object_.map{ |geom_| _encode_geometry(geom_) },
|
178
|
+
}
|
179
|
+
else
|
180
|
+
nil
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
def _decode_feature(input_) # :nodoc:
|
186
|
+
geometry_ = _decode_geometry(input_['geometry'])
|
187
|
+
if geometry_
|
188
|
+
@entity_factory.feature(geometry_, input_['id'], input_['properties'])
|
189
|
+
else
|
190
|
+
nil
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
def _decode_geometry(input_) # :nodoc:
|
196
|
+
case input_['type']
|
197
|
+
when 'GeometryCollection'
|
198
|
+
_decode_geometry_collection(input_)
|
199
|
+
when 'Point'
|
200
|
+
_decode_point_coords(input_['coordinates'])
|
201
|
+
when 'LineString'
|
202
|
+
_decode_line_string_coords(input_['coordinates'])
|
203
|
+
when 'Polygon'
|
204
|
+
_decode_polygon_coords(input_['coordinates'])
|
205
|
+
when 'MultiPoint'
|
206
|
+
_decode_multi_point_coords(input_['coordinates'])
|
207
|
+
when 'MultiLineString'
|
208
|
+
_decode_multi_line_string_coords(input_['coordinates'])
|
209
|
+
when 'MultiPolygon'
|
210
|
+
_decode_multi_polygon_coords(input_['coordinates'])
|
211
|
+
else
|
212
|
+
nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
def _decode_geometry_collection(input_) # :nodoc:
|
218
|
+
geometries_ = input_['geometries']
|
219
|
+
geometries_ = [] unless geometries_.kind_of?(::Array)
|
220
|
+
decoded_geometries_ = []
|
221
|
+
geometries_.each do |g_|
|
222
|
+
g_ = _decode_geometry(g_)
|
223
|
+
decoded_geometries_ << g_ if g_
|
224
|
+
end
|
225
|
+
@geo_factory.collection(decoded_geometries_)
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
def _decode_point_coords(point_coords_) # :nodoc:
|
230
|
+
return nil unless point_coords_.kind_of?(::Array)
|
231
|
+
@geo_factory.point(point_coords_[0].to_f, point_coords_[1].to_f) rescue nil
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
def _decode_line_string_coords(line_coords_) # :nodoc:
|
236
|
+
return nil unless line_coords_.kind_of?(::Array)
|
237
|
+
points_ = []
|
238
|
+
line_coords_.each do |point_coords_|
|
239
|
+
point_ = _decode_point_coords(point_coords_)
|
240
|
+
points_ << point_ if point_
|
241
|
+
end
|
242
|
+
@geo_factory.line_string(points_)
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
def _decode_polygon_coords(poly_coords_) # :nodoc:
|
247
|
+
return nil unless poly_coords_.kind_of?(::Array)
|
248
|
+
rings_ = []
|
249
|
+
poly_coords_.each do |ring_coords_|
|
250
|
+
return nil unless ring_coords_.kind_of?(::Array)
|
251
|
+
points_ = []
|
252
|
+
ring_coords_.each do |point_coords_|
|
253
|
+
point_ = _decode_point_coords(point_coords_)
|
254
|
+
points_ << point_ if point_
|
255
|
+
end
|
256
|
+
ring_ = @geo_factory.linear_ring(points_)
|
257
|
+
rings_ << ring_ if ring_
|
258
|
+
end
|
259
|
+
if rings_.size == 0
|
260
|
+
nil
|
261
|
+
else
|
262
|
+
@geo_factory.polygon(rings_[0], rings_[1..-1])
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
def _decode_multi_point_coords(multi_point_coords_) # :nodoc:
|
268
|
+
return nil unless multi_point_coords_.kind_of?(::Array)
|
269
|
+
points_ = []
|
270
|
+
multi_point_coords_.each do |point_coords_|
|
271
|
+
point_ = _decode_point_coords(point_coords_)
|
272
|
+
points_ << point_ if point_
|
273
|
+
end
|
274
|
+
@geo_factory.multi_point(points_)
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
def _decode_multi_line_string_coords(multi_line_coords_) # :nodoc:
|
279
|
+
return nil unless multi_line_coords_.kind_of?(::Array)
|
280
|
+
lines_ = []
|
281
|
+
multi_line_coords_.each do |line_coords_|
|
282
|
+
line_ = _decode_line_string_coords(line_coords_)
|
283
|
+
lines_ << line_ if line_
|
284
|
+
end
|
285
|
+
@geo_factory.multi_line_string(lines_)
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
def _decode_multi_polygon_coords(multi_polygon_coords_) # :nodoc:
|
290
|
+
return nil unless multi_polygon_coords_.kind_of?(::Array)
|
291
|
+
polygons_ = []
|
292
|
+
multi_polygon_coords_.each do |poly_coords_|
|
293
|
+
poly_ = _decode_polygon_coords(poly_coords_)
|
294
|
+
polygons_ << poly_ if poly_
|
295
|
+
end
|
296
|
+
@geo_factory.multi_polygon(polygons_)
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|