schleyfox-rgeo 0.2.5
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 +199 -0
- data/README.rdoc +172 -0
- data/Spatial_Programming_With_RGeo.rdoc +440 -0
- data/Version +1 -0
- data/ext/geos_c_impl/extconf.rb +84 -0
- data/ext/geos_c_impl/factory.c +468 -0
- data/ext/geos_c_impl/factory.h +224 -0
- data/ext/geos_c_impl/geometry.c +705 -0
- data/ext/geos_c_impl/geometry.h +55 -0
- data/ext/geos_c_impl/geometry_collection.c +482 -0
- data/ext/geos_c_impl/geometry_collection.h +69 -0
- data/ext/geos_c_impl/line_string.c +509 -0
- data/ext/geos_c_impl/line_string.h +64 -0
- data/ext/geos_c_impl/main.c +70 -0
- data/ext/geos_c_impl/point.c +193 -0
- data/ext/geos_c_impl/point.h +62 -0
- data/ext/geos_c_impl/polygon.c +265 -0
- data/ext/geos_c_impl/polygon.h +66 -0
- data/ext/geos_c_impl/preface.h +50 -0
- data/ext/proj4_c_impl/extconf.rb +88 -0
- data/ext/proj4_c_impl/main.c +271 -0
- data/lib/rgeo.rb +124 -0
- data/lib/rgeo/cartesian.rb +60 -0
- data/lib/rgeo/cartesian/analysis.rb +118 -0
- data/lib/rgeo/cartesian/bounding_box.rb +337 -0
- data/lib/rgeo/cartesian/calculations.rb +161 -0
- data/lib/rgeo/cartesian/factory.rb +209 -0
- data/lib/rgeo/cartesian/feature_classes.rb +173 -0
- data/lib/rgeo/cartesian/feature_methods.rb +106 -0
- data/lib/rgeo/cartesian/interface.rb +150 -0
- data/lib/rgeo/coord_sys.rb +79 -0
- data/lib/rgeo/coord_sys/cs/entities.rb +1524 -0
- data/lib/rgeo/coord_sys/cs/factories.rb +208 -0
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +308 -0
- data/lib/rgeo/coord_sys/proj4.rb +312 -0
- data/lib/rgeo/coord_sys/srs_database/active_record_table.rb +194 -0
- data/lib/rgeo/coord_sys/srs_database/interface.rb +165 -0
- data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +188 -0
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +108 -0
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +108 -0
- data/lib/rgeo/error.rb +63 -0
- data/lib/rgeo/feature.rb +88 -0
- data/lib/rgeo/feature/curve.rb +156 -0
- data/lib/rgeo/feature/factory.rb +332 -0
- data/lib/rgeo/feature/factory_generator.rb +138 -0
- data/lib/rgeo/feature/geometry.rb +614 -0
- data/lib/rgeo/feature/geometry_collection.rb +129 -0
- data/lib/rgeo/feature/line.rb +66 -0
- data/lib/rgeo/feature/line_string.rb +102 -0
- data/lib/rgeo/feature/linear_ring.rb +66 -0
- data/lib/rgeo/feature/multi_curve.rb +113 -0
- data/lib/rgeo/feature/multi_line_string.rb +66 -0
- data/lib/rgeo/feature/multi_point.rb +73 -0
- data/lib/rgeo/feature/multi_polygon.rb +97 -0
- data/lib/rgeo/feature/multi_surface.rb +116 -0
- data/lib/rgeo/feature/point.rb +120 -0
- data/lib/rgeo/feature/polygon.rb +141 -0
- data/lib/rgeo/feature/surface.rb +122 -0
- data/lib/rgeo/feature/types.rb +305 -0
- data/lib/rgeo/geographic.rb +75 -0
- data/lib/rgeo/geographic/factory.rb +287 -0
- data/lib/rgeo/geographic/interface.rb +410 -0
- data/lib/rgeo/geographic/proj4_projector.rb +98 -0
- data/lib/rgeo/geographic/projected_feature_classes.rb +213 -0
- data/lib/rgeo/geographic/projected_feature_methods.rb +228 -0
- data/lib/rgeo/geographic/projected_window.rb +467 -0
- data/lib/rgeo/geographic/simple_mercator_projector.rb +157 -0
- data/lib/rgeo/geographic/spherical_feature_classes.rb +212 -0
- data/lib/rgeo/geographic/spherical_feature_methods.rb +97 -0
- data/lib/rgeo/geographic/spherical_math.rb +206 -0
- data/lib/rgeo/geos.rb +72 -0
- data/lib/rgeo/geos/factory.rb +301 -0
- data/lib/rgeo/geos/impl_additions.rb +76 -0
- data/lib/rgeo/geos/interface.rb +139 -0
- data/lib/rgeo/geos/zm_factory.rb +275 -0
- data/lib/rgeo/geos/zm_impl.rb +432 -0
- data/lib/rgeo/impl_helper.rb +53 -0
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +235 -0
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +85 -0
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +197 -0
- data/lib/rgeo/impl_helper/basic_point_methods.rb +138 -0
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +121 -0
- data/lib/rgeo/impl_helper/math.rb +50 -0
- data/lib/rgeo/version.rb +52 -0
- data/lib/rgeo/wkrep.rb +72 -0
- data/lib/rgeo/wkrep/wkb_generator.rb +267 -0
- data/lib/rgeo/wkrep/wkb_parser.rb +315 -0
- data/lib/rgeo/wkrep/wkt_generator.rb +275 -0
- data/lib/rgeo/wkrep/wkt_parser.rb +496 -0
- data/test/common/geometry_collection_tests.rb +238 -0
- data/test/common/line_string_tests.rb +324 -0
- data/test/common/multi_line_string_tests.rb +209 -0
- data/test/common/multi_point_tests.rb +201 -0
- data/test/common/multi_polygon_tests.rb +208 -0
- data/test/common/point_tests.rb +331 -0
- data/test/common/polygon_tests.rb +232 -0
- data/test/coord_sys/tc_active_record_table.rb +102 -0
- data/test/coord_sys/tc_ogc_cs.rb +356 -0
- data/test/coord_sys/tc_proj4.rb +138 -0
- data/test/coord_sys/tc_proj4_srs_data.rb +76 -0
- data/test/coord_sys/tc_sr_org.rb +70 -0
- data/test/coord_sys/tc_url_reader.rb +82 -0
- data/test/geos/tc_factory.rb +91 -0
- data/test/geos/tc_geometry_collection.rb +62 -0
- data/test/geos/tc_line_string.rb +62 -0
- data/test/geos/tc_misc.rb +72 -0
- data/test/geos/tc_multi_line_string.rb +62 -0
- data/test/geos/tc_multi_point.rb +62 -0
- data/test/geos/tc_multi_polygon.rb +63 -0
- data/test/geos/tc_point.rb +86 -0
- data/test/geos/tc_polygon.rb +86 -0
- data/test/geos/tc_zmfactory.rb +85 -0
- data/test/projected_geographic/tc_geometry_collection.rb +62 -0
- data/test/projected_geographic/tc_line_string.rb +62 -0
- data/test/projected_geographic/tc_multi_line_string.rb +62 -0
- data/test/projected_geographic/tc_multi_point.rb +62 -0
- data/test/projected_geographic/tc_multi_polygon.rb +63 -0
- data/test/projected_geographic/tc_point.rb +93 -0
- data/test/projected_geographic/tc_polygon.rb +62 -0
- data/test/simple_cartesian/tc_calculations.rb +145 -0
- data/test/simple_cartesian/tc_geometry_collection.rb +69 -0
- data/test/simple_cartesian/tc_line_string.rb +70 -0
- data/test/simple_cartesian/tc_multi_line_string.rb +67 -0
- data/test/simple_cartesian/tc_multi_point.rb +67 -0
- data/test/simple_cartesian/tc_multi_polygon.rb +70 -0
- data/test/simple_cartesian/tc_point.rb +91 -0
- data/test/simple_cartesian/tc_polygon.rb +67 -0
- data/test/simple_mercator/tc_geometry_collection.rb +62 -0
- data/test/simple_mercator/tc_line_string.rb +62 -0
- data/test/simple_mercator/tc_multi_line_string.rb +62 -0
- data/test/simple_mercator/tc_multi_point.rb +62 -0
- data/test/simple_mercator/tc_multi_polygon.rb +63 -0
- data/test/simple_mercator/tc_point.rb +93 -0
- data/test/simple_mercator/tc_polygon.rb +62 -0
- data/test/simple_mercator/tc_window.rb +219 -0
- data/test/spherical_geographic/tc_calculations.rb +203 -0
- data/test/spherical_geographic/tc_geometry_collection.rb +70 -0
- data/test/spherical_geographic/tc_line_string.rb +70 -0
- data/test/spherical_geographic/tc_multi_line_string.rb +67 -0
- data/test/spherical_geographic/tc_multi_point.rb +67 -0
- data/test/spherical_geographic/tc_multi_polygon.rb +70 -0
- data/test/spherical_geographic/tc_point.rb +100 -0
- data/test/spherical_geographic/tc_polygon.rb +67 -0
- data/test/tc_cartesian_analysis.rb +107 -0
- data/test/tc_oneoff.rb +63 -0
- data/test/wkrep/tc_wkb_generator.rb +249 -0
- data/test/wkrep/tc_wkb_parser.rb +353 -0
- data/test/wkrep/tc_wkt_generator.rb +362 -0
- data/test/wkrep/tc_wkt_parser.rb +480 -0
- metadata +267 -0
data/lib/rgeo.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# RGeo main file
|
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
|
+
# RGeo is a spatial data library for Ruby. It focuses on the storage and
|
38
|
+
# manipulation of spatial data types such as points, lines, and polygons.
|
39
|
+
#
|
40
|
+
# RGeo comprises a number of modules. The "rgeo" gem provides a suite of
|
41
|
+
# standard modules. Additional optional modules are provided by separate
|
42
|
+
# gems with names of the form "<tt>rgeo-*</tt>".
|
43
|
+
#
|
44
|
+
# === Standard modules
|
45
|
+
#
|
46
|
+
# These are the standard modules provided by the "rgeo" gem.
|
47
|
+
#
|
48
|
+
# * RGeo::Feature contains interface specifications for spatial
|
49
|
+
# objects implemented by RGeo. These interfaces closely follow the OGC
|
50
|
+
# Simple Features Specifiation (SFS). This module forms the core of RGeo.
|
51
|
+
#
|
52
|
+
# * RGeo::CoordSys contains classes for representing spatial
|
53
|
+
# reference systems and coordinate transformations. For example, it
|
54
|
+
# includes a wrapper for the Proj4 library, supporting many geographic
|
55
|
+
# projections.
|
56
|
+
#
|
57
|
+
# * RGeo::Cartesian is a gateway for geometric data implementations
|
58
|
+
# that operate in Caresian (flat) coordinate systems. It also provides a
|
59
|
+
# basic pure ruby Cartesian implementation. This implementation does not
|
60
|
+
# cover all the geometric analysis operations defined by the SFS, but it
|
61
|
+
# does not require an external C library and is often sufficient for
|
62
|
+
# basic applications.
|
63
|
+
#
|
64
|
+
# * RGeo::Geos is another Cartesian implementation that wraps the
|
65
|
+
# GEOS library to provide a full, high-performance implementation of
|
66
|
+
# Cartesian geometry that includes every operation defined in the SFS.
|
67
|
+
# It requires GEOS 3.2 or later.
|
68
|
+
#
|
69
|
+
# * RGeo::Geographic contains spatial implementations that operate
|
70
|
+
# in latitude-longitude coordinates and are well-suited for geographic
|
71
|
+
# location based applications. Geographic spatial objects may also be
|
72
|
+
# linked to projections.
|
73
|
+
#
|
74
|
+
# * RGeo::WKRep contains tools for reading and writing spatial
|
75
|
+
# data in the OGC Well-Known Text (WKT) and Well-Known Binary (WKB)
|
76
|
+
# representations. It also supports common variants such as the PostGIS
|
77
|
+
# EWKT and EWKB representations.
|
78
|
+
#
|
79
|
+
# === Optional Modules
|
80
|
+
#
|
81
|
+
# Here is a partial list of optional modules available as separate gems.
|
82
|
+
#
|
83
|
+
# * <b>rgeo-geojson</b> provides the RGeo::GeoJSON module, containing
|
84
|
+
# tools for GeoJSON encoding and decoding of spatial objects.
|
85
|
+
#
|
86
|
+
# * <b>rgeo-shapefile</b> provides the RGeo::Shapefile module, containing
|
87
|
+
# tools for reading ESRI shapefiles.
|
88
|
+
#
|
89
|
+
# * <b>rgeo-activerecord</b> provides the RGeo::ActiveRecord module,
|
90
|
+
# containing some ActiveRecord extensions for spatial databases, and a
|
91
|
+
# set of common tools for ActiveRecord spatial database adapters.
|
92
|
+
#
|
93
|
+
# Several ActiveRecord adapters use RGeo. These include:
|
94
|
+
#
|
95
|
+
# * <b>mysqlspatial</b>, an adapter for MySQL spatial extensions based on
|
96
|
+
# the mysql adapter. Available as the activerecord-mysqlspatial-adapter
|
97
|
+
# gem.
|
98
|
+
#
|
99
|
+
# * <b>mysql2spatial</b>, an adapter for MySQL spatial extensions based on
|
100
|
+
# the mysql2 adapter. Available as the activerecord-mysql2spatial-adapter
|
101
|
+
# gem.
|
102
|
+
#
|
103
|
+
# * <b>spatialite</b>, an adapter for the SpatiaLite extension to the
|
104
|
+
# Sqlite3 database, and based on the sqlite3 adapter. Available as the
|
105
|
+
# activerecord-spatialite-adapter gem.
|
106
|
+
#
|
107
|
+
# * <b>postgis</b>, an adapter for the PostGIS extension to the PostgreSQL
|
108
|
+
# database, and based on the postgresql adapter. Available as the
|
109
|
+
# activerecord-postgis-adapter gem.
|
110
|
+
|
111
|
+
module RGeo
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# Core modules
|
116
|
+
require 'rgeo/version'
|
117
|
+
require 'rgeo/error'
|
118
|
+
require 'rgeo/feature'
|
119
|
+
require 'rgeo/coord_sys'
|
120
|
+
require 'rgeo/impl_helper'
|
121
|
+
require 'rgeo/wkrep'
|
122
|
+
require 'rgeo/geos'
|
123
|
+
require 'rgeo/cartesian'
|
124
|
+
require 'rgeo/geographic'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Cartesian features 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
|
+
# The Cartesian module is a gateway to implementations that use the
|
41
|
+
# Cartesian (i.e. flat) coordinate system. It provides convenient
|
42
|
+
# access to Cartesian factories such as the Geos implementation and
|
43
|
+
# the simple Cartesian implementation. It also provides a namespace
|
44
|
+
# for Cartesian-specific analysis tools.
|
45
|
+
|
46
|
+
module Cartesian
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Implementation files.
|
54
|
+
require 'rgeo/cartesian/calculations'
|
55
|
+
require 'rgeo/cartesian/feature_methods'
|
56
|
+
require 'rgeo/cartesian/feature_classes'
|
57
|
+
require 'rgeo/cartesian/factory'
|
58
|
+
require 'rgeo/cartesian/interface'
|
59
|
+
require 'rgeo/cartesian/bounding_box'
|
60
|
+
require 'rgeo/cartesian/analysis'
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Cartesian toplevel 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 Cartesian
|
40
|
+
|
41
|
+
|
42
|
+
# This provides includes some spatial analysis algorithms supporting
|
43
|
+
# Cartesian data.
|
44
|
+
|
45
|
+
module Analysis
|
46
|
+
|
47
|
+
class << self
|
48
|
+
|
49
|
+
|
50
|
+
# Given a LineString, which must be a ring, determine whether the
|
51
|
+
# ring proceeds clockwise or counterclockwise.
|
52
|
+
# Returns 1 for counterclockwise, or -1 for clockwise.
|
53
|
+
#
|
54
|
+
# Returns 0 if the ring is empty.
|
55
|
+
# The return value is undefined if the object is not a ring, or
|
56
|
+
# is not in a Cartesian coordinate system.
|
57
|
+
|
58
|
+
def ring_direction(ring_)
|
59
|
+
size_ = ring_.num_points - 1
|
60
|
+
return 0 if size_ == 0
|
61
|
+
|
62
|
+
# Extract unit-length segments from the ring.
|
63
|
+
segs_ = []
|
64
|
+
size_.times do |i_|
|
65
|
+
p0_ = ring_.point_n(i_)
|
66
|
+
p1_ = ring_.point_n(i_+1)
|
67
|
+
x_ = p1_.x - p0_.x
|
68
|
+
y_ = p1_.y - p0_.y
|
69
|
+
r_ = ::Math.sqrt(x_*x_ + y_*y_)
|
70
|
+
if r_ > 0.0
|
71
|
+
segs_ << x_/r_ << y_/r_
|
72
|
+
end
|
73
|
+
end
|
74
|
+
segs_ << segs_[0] << segs_[1]
|
75
|
+
|
76
|
+
# Extract angles from the segments by subtracting the segments.
|
77
|
+
# Note angles are represented as cos/sin pairs so we don't
|
78
|
+
# have to calculate any trig functions.
|
79
|
+
angs_ = []
|
80
|
+
size_.times do |i_|
|
81
|
+
x0_, y0_, x1_, y1_ = segs_[i_*2,4]
|
82
|
+
angs_ << x0_*x1_ + y0_*y1_ << x0_*y1_ - x1_*y0_
|
83
|
+
end
|
84
|
+
|
85
|
+
# Now add the angles and count revolutions.
|
86
|
+
# Again, our running sum is represented as a cos/sin pair.
|
87
|
+
revolutions_ = 0
|
88
|
+
sin_ = 0.0
|
89
|
+
cos_ = 1.0
|
90
|
+
angs_.each_slice(2) do |(x_, y_)|
|
91
|
+
ready_ = y_ > 0.0 && sin_ > 0.0 || y_ < 0.0 && sin_ < 0.0
|
92
|
+
if y_ != 0.0
|
93
|
+
s_ = sin_*x_ + cos_*y_
|
94
|
+
c_ = cos_*x_ - sin_*y_
|
95
|
+
r_ = ::Math.sqrt(s_*s_ + c_*c_)
|
96
|
+
sin_ = s_ / r_
|
97
|
+
cos_ = c_ / r_
|
98
|
+
end
|
99
|
+
if ready_
|
100
|
+
if y_ > 0.0 && sin_ <= 0.0
|
101
|
+
revolutions_ += 1
|
102
|
+
elsif y_ < 0.0 && sin_ >= 0.0
|
103
|
+
revolutions_ -= 1
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
revolutions_
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,337 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Cartesian toplevel 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 Cartesian
|
40
|
+
|
41
|
+
|
42
|
+
# This is a bounding box for Cartesian data.
|
43
|
+
# The simple cartesian implementation uses this internally to compute
|
44
|
+
# envelopes. You may also use it directly to compute and represent
|
45
|
+
# bounding boxes.
|
46
|
+
#
|
47
|
+
# A bounding box is a set of ranges in each dimension: X, Y, as well
|
48
|
+
# as Z and M if supported. You can compute a bounding box for one or
|
49
|
+
# more geometry objects by creating a new bounding box object, and
|
50
|
+
# adding the geometries to it. You may then query it for the bounds,
|
51
|
+
# or use it to determine whether it encloses other geometries or
|
52
|
+
# bounding boxes.
|
53
|
+
|
54
|
+
class BoundingBox
|
55
|
+
|
56
|
+
|
57
|
+
# Create a new empty bounding box with the given factory.
|
58
|
+
#
|
59
|
+
# The factory defines the coordinate system for the bounding box,
|
60
|
+
# and also defines whether it should track Z and M coordinates.
|
61
|
+
# All geometries will be cast to this factory when added to this
|
62
|
+
# bounding box, and any generated envelope geometry will have this
|
63
|
+
# as its factory.
|
64
|
+
#
|
65
|
+
# Options include:
|
66
|
+
#
|
67
|
+
# [<tt>:ignore_z</tt>]
|
68
|
+
# If true, ignore z coordinates even if the factory supports them.
|
69
|
+
# Default is false.
|
70
|
+
# [<tt>:ignore_m</tt>]
|
71
|
+
# If true, ignore m coordinates even if the factory supports them.
|
72
|
+
# Default is false.
|
73
|
+
|
74
|
+
def initialize(factory_, opts_={})
|
75
|
+
@factory = factory_
|
76
|
+
@has_z = !opts_[:ignore_z] && factory_.property(:has_z_coordinate) ? true : false
|
77
|
+
@has_m = !opts_[:ignore_m] && factory_.property(:has_m_coordinate) ? true : false
|
78
|
+
@min_x = @max_x = @min_y = @max_y = @min_z = @max_z = @min_m = @max_m = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def eql?(rhs_) # :nodoc:
|
83
|
+
rhs_.is_a?(BoundingBox) && @factory == rhs_.factory &&
|
84
|
+
@min_x == rhs_.min_x && @max_x == rhs_.max_x &&
|
85
|
+
@min_y == rhs_.min_y && @max_y == rhs_.max_y &&
|
86
|
+
@min_z == rhs_.min_z && @max_z == rhs_.max_z &&
|
87
|
+
@min_m == rhs_.min_m && @max_m == rhs_.max_m
|
88
|
+
end
|
89
|
+
alias_method :==, :eql?
|
90
|
+
|
91
|
+
|
92
|
+
# Returns the bounding box's factory.
|
93
|
+
|
94
|
+
def factory
|
95
|
+
@factory
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# Returns true if this bounding box is still empty.
|
100
|
+
|
101
|
+
def empty?
|
102
|
+
@min_x.nil?
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# Returns true if this bounding box tracks Z coordinates.
|
107
|
+
|
108
|
+
def has_z
|
109
|
+
@has_z
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# Returns true if this bounding box tracks M coordinates.
|
114
|
+
|
115
|
+
def has_m
|
116
|
+
@has_m
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# Returns the minimum X, or nil if this bounding box is empty.
|
121
|
+
|
122
|
+
def min_x
|
123
|
+
@min_x
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# Returns the maximum X, or nil if this bounding box is empty.
|
128
|
+
|
129
|
+
def max_x
|
130
|
+
@max_x
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# Returns the minimum Y, or nil if this bounding box is empty.
|
135
|
+
|
136
|
+
def min_y
|
137
|
+
@min_y
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# Returns the maximum Y, or nil if this bounding box is empty.
|
142
|
+
|
143
|
+
def max_y
|
144
|
+
@max_y
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
# Returns the minimum Z, or nil if this bounding box is empty.
|
149
|
+
|
150
|
+
def min_z
|
151
|
+
@min_z
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
# Returns the maximum Z, or nil if this bounding box is empty.
|
156
|
+
|
157
|
+
def max_z
|
158
|
+
@max_z
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
# Returns the minimum M, or nil if this bounding box is empty.
|
163
|
+
|
164
|
+
def min_m
|
165
|
+
@min_m
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
# Returns the maximum M, or nil if this bounding box is empty.
|
170
|
+
|
171
|
+
def max_m
|
172
|
+
@max_m
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
# Returns a point representing the minimum extent in all dimensions,
|
177
|
+
# or nil if this bounding box is empty.
|
178
|
+
|
179
|
+
def min_point
|
180
|
+
if @min_x
|
181
|
+
extras_ = []
|
182
|
+
extras_ << @min_z if @has_z
|
183
|
+
extras_ << @min_m if @has_m
|
184
|
+
@factory.point(@min_x, @min_y, *extras_)
|
185
|
+
else
|
186
|
+
nil
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
# Returns a point representing the maximum extent in all dimensions,
|
192
|
+
# or nil if this bounding box is empty.
|
193
|
+
|
194
|
+
def max_point
|
195
|
+
if @min_x
|
196
|
+
extras_ = []
|
197
|
+
extras_ << @max_z if @has_z
|
198
|
+
extras_ << @max_m if @has_m
|
199
|
+
@factory.point(@max_x, @max_y, *extras_)
|
200
|
+
else
|
201
|
+
nil
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
# Adjusts the extents of this bounding box to encomass the given
|
207
|
+
# object, which may be a geometry or another bounding box.
|
208
|
+
# Returns self.
|
209
|
+
|
210
|
+
def add(geometry_)
|
211
|
+
case geometry_
|
212
|
+
when BoundingBox
|
213
|
+
add(geometry_.min_point)
|
214
|
+
add(geometry_.max_point)
|
215
|
+
when Feature::Geometry
|
216
|
+
if geometry_.factory == @factory
|
217
|
+
_add_geometry(geometry_)
|
218
|
+
else
|
219
|
+
_add_geometry(Factory.cast(geometry_, @factory))
|
220
|
+
end
|
221
|
+
end
|
222
|
+
self
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
# Converts this bounding box to an envelope polygon.
|
227
|
+
# Returns the empty collection if this bounding box is empty.
|
228
|
+
|
229
|
+
def to_geometry
|
230
|
+
if @min_x
|
231
|
+
extras_ = []
|
232
|
+
extras_ << @min_z if @has_z
|
233
|
+
extras_ << @min_m if @has_m
|
234
|
+
point_min_ = @factory.point(@min_x, @min_y, *extras_)
|
235
|
+
if @min_x == @max_x && @min_y == @max_y
|
236
|
+
point_min_
|
237
|
+
else
|
238
|
+
extras_ = []
|
239
|
+
extras_ << @max_z if @has_z
|
240
|
+
extras_ << @max_m if @has_m
|
241
|
+
point_max_ = @factory.point(@max_x, @max_y, *extras_)
|
242
|
+
if @min_x == @max_x || @min_y == @max_y
|
243
|
+
@factory.line(point_min_, point_max_)
|
244
|
+
else
|
245
|
+
@factory.polygon(@factory.linear_ring(point_min_, @factory.point(@max_x, @min_y, *extras_), point_max_, @factory.point(@min_x, @max_y, *extras_), point_min_))
|
246
|
+
end
|
247
|
+
end
|
248
|
+
else
|
249
|
+
@factory.collection([])
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
# Returns true if this bounding box contains the given object,
|
255
|
+
# which may be a geometry or another bounding box.
|
256
|
+
#
|
257
|
+
# Supports these options:
|
258
|
+
#
|
259
|
+
# <tt>:ignore_z</tt>
|
260
|
+
# Ignore the Z coordinate when testing, even if both objects
|
261
|
+
# have Z. Default is false.
|
262
|
+
# <tt>:ignore_m</tt>
|
263
|
+
# Ignore the M coordinate when testing, even if both objects
|
264
|
+
# have M. Default is false.
|
265
|
+
|
266
|
+
def contains?(rhs_, opts_={})
|
267
|
+
if Feature::Geometry === rhs_
|
268
|
+
contains?(BoundingBox.new(@factory).add(rhs_))
|
269
|
+
elsif rhs_.empty?
|
270
|
+
true
|
271
|
+
elsif empty?
|
272
|
+
false
|
273
|
+
elsif @min_x > rhs_.min_x || @max_x < rhs_.max_x || @min_y > rhs_.min_y || @max_y < rhs_.max_y
|
274
|
+
false
|
275
|
+
elsif @has_m && rhs_.has_m && !opts_[:ignore_m] && (@min_m > rhs_.min_m || @max_m < rhs_.max_m)
|
276
|
+
false
|
277
|
+
elsif @has_z && rhs_.has_z && !opts_[:ignore_z] && (@min_z > rhs_.min_z || @max_z < rhs_.max_z)
|
278
|
+
false
|
279
|
+
else
|
280
|
+
true
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
|
285
|
+
def _add_geometry(geometry_) # :nodoc:
|
286
|
+
case geometry_
|
287
|
+
when Feature::Point
|
288
|
+
_add_point(geometry_)
|
289
|
+
when Feature::LineString
|
290
|
+
geometry_.points.each{ |p_| _add_point(p_) }
|
291
|
+
when Feature::Polygon
|
292
|
+
geometry_.exterior_ring.points.each{ |p_| _add_point(p_) }
|
293
|
+
when Feature::MultiPoint
|
294
|
+
geometry_.each{ |p_| _add_point(p_) }
|
295
|
+
when Feature::MultiLineString
|
296
|
+
geometry_.each{ |line_| line_.points.each{ |p_| _add_point(p_) } }
|
297
|
+
when Feature::MultiPolygon
|
298
|
+
geometry_.each{ |poly_| poly_.exterior_ring.points.each{ |p_| _add_point(p_) } }
|
299
|
+
when Feature::GeometryCollection
|
300
|
+
geometry_.each{ |g_| _add_geometry(g_) }
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
|
305
|
+
def _add_point(point_) # :nodoc:
|
306
|
+
if @min_x
|
307
|
+
x_ = point_.x
|
308
|
+
@min_x = x_ if x_ < @min_x
|
309
|
+
@max_x = x_ if x_ > @max_x
|
310
|
+
y_ = point_.y
|
311
|
+
@min_y = y_ if y_ < @min_y
|
312
|
+
@max_y = y_ if y_ > @max_y
|
313
|
+
if @has_z
|
314
|
+
z_ = point_.z
|
315
|
+
@min_z = z_ if z_ < @min_z
|
316
|
+
@max_z = z_ if z_ > @max_z
|
317
|
+
end
|
318
|
+
if @has_m
|
319
|
+
m_ = point_.m
|
320
|
+
@min_m = m_ if m_ < @min_m
|
321
|
+
@max_m = m_ if m_ > @max_m
|
322
|
+
end
|
323
|
+
else
|
324
|
+
@min_x = @max_x = point_.x
|
325
|
+
@min_y = @max_y = point_.y
|
326
|
+
@min_z = @max_z = point_.z if @has_z
|
327
|
+
@min_m = @max_m = point_.m if @has_m
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|