rgeo-dschee 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +29 -0
- data/ext/geos_c_impl/coordinates.c +65 -0
- data/ext/geos_c_impl/coordinates.h +2 -0
- data/ext/geos_c_impl/extconf.rb +43 -0
- data/ext/geos_c_impl/factory.c +995 -0
- data/ext/geos_c_impl/factory.h +238 -0
- data/ext/geos_c_impl/geometry.c +1093 -0
- data/ext/geos_c_impl/geometry.h +23 -0
- data/ext/geos_c_impl/geometry_collection.c +757 -0
- data/ext/geos_c_impl/geometry_collection.h +46 -0
- data/ext/geos_c_impl/line_string.c +675 -0
- data/ext/geos_c_impl/line_string.h +32 -0
- data/ext/geos_c_impl/main.c +40 -0
- data/ext/geos_c_impl/point.c +236 -0
- data/ext/geos_c_impl/point.h +30 -0
- data/ext/geos_c_impl/polygon.c +359 -0
- data/ext/geos_c_impl/polygon.h +43 -0
- data/ext/geos_c_impl/preface.h +38 -0
- data/ext/proj4_c_impl/extconf.rb +62 -0
- data/ext/proj4_c_impl/main.c +315 -0
- data/lib/rgeo.rb +89 -0
- data/lib/rgeo/cartesian.rb +25 -0
- data/lib/rgeo/cartesian/analysis.rb +77 -0
- data/lib/rgeo/cartesian/bounding_box.rb +398 -0
- data/lib/rgeo/cartesian/calculations.rb +113 -0
- data/lib/rgeo/cartesian/factory.rb +347 -0
- data/lib/rgeo/cartesian/feature_classes.rb +100 -0
- data/lib/rgeo/cartesian/feature_methods.rb +88 -0
- data/lib/rgeo/cartesian/interface.rb +135 -0
- data/lib/rgeo/coord_sys.rb +43 -0
- data/lib/rgeo/coord_sys/cs/entities.rb +1315 -0
- data/lib/rgeo/coord_sys/cs/factories.rb +148 -0
- data/lib/rgeo/coord_sys/cs/wkt_parser.rb +272 -0
- data/lib/rgeo/coord_sys/proj4.rb +293 -0
- data/lib/rgeo/coord_sys/srs_database/interface.rb +115 -0
- data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +140 -0
- data/lib/rgeo/coord_sys/srs_database/sr_org.rb +62 -0
- data/lib/rgeo/coord_sys/srs_database/url_reader.rb +63 -0
- data/lib/rgeo/error.rb +27 -0
- data/lib/rgeo/feature.rb +54 -0
- data/lib/rgeo/feature/curve.rb +111 -0
- data/lib/rgeo/feature/factory.rb +278 -0
- data/lib/rgeo/feature/factory_generator.rb +96 -0
- data/lib/rgeo/feature/geometry.rb +624 -0
- data/lib/rgeo/feature/geometry_collection.rb +95 -0
- data/lib/rgeo/feature/line.rb +26 -0
- data/lib/rgeo/feature/line_string.rb +60 -0
- data/lib/rgeo/feature/linear_ring.rb +26 -0
- data/lib/rgeo/feature/mixins.rb +143 -0
- data/lib/rgeo/feature/multi_curve.rb +71 -0
- data/lib/rgeo/feature/multi_line_string.rb +26 -0
- data/lib/rgeo/feature/multi_point.rb +33 -0
- data/lib/rgeo/feature/multi_polygon.rb +57 -0
- data/lib/rgeo/feature/multi_surface.rb +73 -0
- data/lib/rgeo/feature/point.rb +84 -0
- data/lib/rgeo/feature/polygon.rb +97 -0
- data/lib/rgeo/feature/surface.rb +79 -0
- data/lib/rgeo/feature/types.rb +284 -0
- data/lib/rgeo/geographic.rb +40 -0
- data/lib/rgeo/geographic/factory.rb +450 -0
- data/lib/rgeo/geographic/interface.rb +489 -0
- data/lib/rgeo/geographic/proj4_projector.rb +58 -0
- data/lib/rgeo/geographic/projected_feature_classes.rb +107 -0
- data/lib/rgeo/geographic/projected_feature_methods.rb +212 -0
- data/lib/rgeo/geographic/projected_window.rb +383 -0
- data/lib/rgeo/geographic/simple_mercator_projector.rb +110 -0
- data/lib/rgeo/geographic/spherical_feature_classes.rb +100 -0
- data/lib/rgeo/geographic/spherical_feature_methods.rb +134 -0
- data/lib/rgeo/geographic/spherical_math.rb +188 -0
- data/lib/rgeo/geos.rb +89 -0
- data/lib/rgeo/geos/capi_factory.rb +470 -0
- data/lib/rgeo/geos/capi_feature_classes.rb +129 -0
- data/lib/rgeo/geos/ffi_factory.rb +592 -0
- data/lib/rgeo/geos/ffi_feature_classes.rb +83 -0
- data/lib/rgeo/geos/ffi_feature_methods.rb +574 -0
- data/lib/rgeo/geos/interface.rb +202 -0
- data/lib/rgeo/geos/utils.rb +74 -0
- data/lib/rgeo/geos/zm_factory.rb +405 -0
- data/lib/rgeo/geos/zm_feature_classes.rb +80 -0
- data/lib/rgeo/geos/zm_feature_methods.rb +344 -0
- data/lib/rgeo/impl_helper.rb +19 -0
- data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +185 -0
- data/lib/rgeo/impl_helper/basic_geometry_methods.rb +61 -0
- data/lib/rgeo/impl_helper/basic_line_string_methods.rb +146 -0
- data/lib/rgeo/impl_helper/basic_point_methods.rb +104 -0
- data/lib/rgeo/impl_helper/basic_polygon_methods.rb +87 -0
- data/lib/rgeo/impl_helper/math.rb +14 -0
- data/lib/rgeo/impl_helper/utils.rb +29 -0
- data/lib/rgeo/version.rb +3 -0
- data/lib/rgeo/wkrep.rb +37 -0
- data/lib/rgeo/wkrep/wkb_generator.rb +201 -0
- data/lib/rgeo/wkrep/wkb_parser.rb +251 -0
- data/lib/rgeo/wkrep/wkt_generator.rb +207 -0
- data/lib/rgeo/wkrep/wkt_parser.rb +415 -0
- data/lib/rgeo/yaml.rb +23 -0
- data/test/cartesian_analysis_test.rb +65 -0
- data/test/cartesian_bbox_test.rb +123 -0
- data/test/common/factory_tests.rb +78 -0
- data/test/common/geometry_collection_tests.rb +237 -0
- data/test/common/line_string_tests.rb +330 -0
- data/test/common/multi_line_string_tests.rb +182 -0
- data/test/common/multi_point_tests.rb +200 -0
- data/test/common/multi_polygon_tests.rb +191 -0
- data/test/common/point_tests.rb +370 -0
- data/test/common/polygon_tests.rb +261 -0
- data/test/coord_sys/ogc_cs_test.rb +342 -0
- data/test/coord_sys/proj4_srs_data_test.rb +41 -0
- data/test/coord_sys/proj4_test.rb +150 -0
- data/test/coord_sys/sr_org_test.rb +32 -0
- data/test/coord_sys/url_reader_test.rb +42 -0
- data/test/geos_capi/factory_test.rb +31 -0
- data/test/geos_capi/geometry_collection_test.rb +24 -0
- data/test/geos_capi/line_string_test.rb +24 -0
- data/test/geos_capi/misc_test.rb +116 -0
- data/test/geos_capi/multi_line_string_test.rb +24 -0
- data/test/geos_capi/multi_point_test.rb +24 -0
- data/test/geos_capi/multi_polygon_test.rb +39 -0
- data/test/geos_capi/parsing_unparsing_test.rb +40 -0
- data/test/geos_capi/point_test.rb +72 -0
- data/test/geos_capi/polygon_test.rb +154 -0
- data/test/geos_capi/zmfactory_test.rb +57 -0
- data/test/geos_ffi/factory_test.rb +31 -0
- data/test/geos_ffi/geometry_collection_test.rb +24 -0
- data/test/geos_ffi/line_string_test.rb +24 -0
- data/test/geos_ffi/misc_test.rb +63 -0
- data/test/geos_ffi/multi_line_string_test.rb +24 -0
- data/test/geos_ffi/multi_point_test.rb +24 -0
- data/test/geos_ffi/multi_polygon_test.rb +33 -0
- data/test/geos_ffi/parsing_unparsing_test.rb +41 -0
- data/test/geos_ffi/point_test.rb +77 -0
- data/test/geos_ffi/polygon_test.rb +46 -0
- data/test/geos_ffi/zmfactory_test.rb +58 -0
- data/test/mixins_test.rb +141 -0
- data/test/oneoff_test.rb +26 -0
- data/test/projected_geographic/factory_test.rb +25 -0
- data/test/projected_geographic/geometry_collection_test.rb +24 -0
- data/test/projected_geographic/line_string_test.rb +24 -0
- data/test/projected_geographic/multi_line_string_test.rb +26 -0
- data/test/projected_geographic/multi_point_test.rb +30 -0
- data/test/projected_geographic/multi_polygon_test.rb +25 -0
- data/test/projected_geographic/point_test.rb +51 -0
- data/test/projected_geographic/polygon_test.rb +24 -0
- data/test/simple_cartesian/calculations_test.rb +99 -0
- data/test/simple_cartesian/factory_test.rb +27 -0
- data/test/simple_cartesian/geometry_collection_test.rb +30 -0
- data/test/simple_cartesian/line_string_test.rb +31 -0
- data/test/simple_cartesian/multi_line_string_test.rb +28 -0
- data/test/simple_cartesian/multi_point_test.rb +31 -0
- data/test/simple_cartesian/multi_polygon_test.rb +31 -0
- data/test/simple_cartesian/point_test.rb +50 -0
- data/test/simple_cartesian/polygon_test.rb +28 -0
- data/test/simple_mercator/factory_test.rb +25 -0
- data/test/simple_mercator/geometry_collection_test.rb +24 -0
- data/test/simple_mercator/line_string_test.rb +24 -0
- data/test/simple_mercator/multi_line_string_test.rb +26 -0
- data/test/simple_mercator/multi_point_test.rb +29 -0
- data/test/simple_mercator/multi_polygon_test.rb +25 -0
- data/test/simple_mercator/point_test.rb +55 -0
- data/test/simple_mercator/polygon_test.rb +24 -0
- data/test/simple_mercator/window_test.rb +173 -0
- data/test/spherical_geographic/calculations_test.rb +167 -0
- data/test/spherical_geographic/factory_test.rb +27 -0
- data/test/spherical_geographic/geometry_collection_test.rb +31 -0
- data/test/spherical_geographic/line_string_test.rb +31 -0
- data/test/spherical_geographic/multi_line_string_test.rb +29 -0
- data/test/spherical_geographic/multi_point_test.rb +31 -0
- data/test/spherical_geographic/multi_polygon_test.rb +31 -0
- data/test/spherical_geographic/point_test.rb +78 -0
- data/test/spherical_geographic/polygon_test.rb +28 -0
- data/test/types_test.rb +42 -0
- data/test/wkrep/wkb_generator_test.rb +185 -0
- data/test/wkrep/wkb_parser_test.rb +293 -0
- data/test/wkrep/wkt_generator_test.rb +294 -0
- data/test/wkrep/wkt_parser_test.rb +412 -0
- metadata +386 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# MultiPoint feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module RGeo
|
8
|
+
module Feature
|
9
|
+
# == SFS 1.1 Description
|
10
|
+
#
|
11
|
+
# A MultiPoint is a 0-dimensional GeometryCollection. The elements of
|
12
|
+
# a MultiPoint are restricted to Points. The Points are not connected
|
13
|
+
# or ordered.
|
14
|
+
#
|
15
|
+
# A MultiPoint is simple if no two Points in the MultiPoint are equal
|
16
|
+
# (have identical coordinate values).
|
17
|
+
#
|
18
|
+
# The boundary of a MultiPoint is the empty set.
|
19
|
+
#
|
20
|
+
# == Notes
|
21
|
+
#
|
22
|
+
# MultiPoint is defined as a module and is provided primarily
|
23
|
+
# for the sake of documentation. Implementations need not necessarily
|
24
|
+
# include this module itself. Therefore, you should not depend on the
|
25
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
26
|
+
# class method (or === operator) defined in the Type module.
|
27
|
+
|
28
|
+
module MultiPoint
|
29
|
+
include GeometryCollection
|
30
|
+
extend Type
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# MultiPolygon feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module RGeo
|
8
|
+
module Feature
|
9
|
+
# == SFS 1.1 Description
|
10
|
+
#
|
11
|
+
# A MultiPolygon is a MultiSurface whose elements are Polygons.
|
12
|
+
#
|
13
|
+
# The assertions for MultiPolygons are as follows.
|
14
|
+
#
|
15
|
+
# a) The interiors of 2 Polygons that are elements of a MultiPolygon
|
16
|
+
# may not intersect.
|
17
|
+
#
|
18
|
+
# b) The boundaries of any 2 Polygons that are elements of a
|
19
|
+
# MultiPolygon may not "cross" and may touch at only a finite number
|
20
|
+
# of Points. NOTE: Crossing is prevented by assertion (a) above.
|
21
|
+
#
|
22
|
+
# c) A MultiPolygon is defined as topologically closed.
|
23
|
+
#
|
24
|
+
# d) A MultiPolygon may not have cut lines, spikes or punctures, a
|
25
|
+
# MultiPolygon is a regular closed Point set:
|
26
|
+
#
|
27
|
+
# e) The interior of a MultiPolygon with more than 1 Polygon is not
|
28
|
+
# connected, the number of connected components of the interior of a
|
29
|
+
# MultiPolygon is equal to the number of Polygons in the MultiPolygon.
|
30
|
+
#
|
31
|
+
# The boundary of a MultiPolygon is a set of closed Curves
|
32
|
+
# (LineStrings) corresponding to the boundaries of its element
|
33
|
+
# Polygons. Each Curve in the boundary of the MultiPolygon is in the
|
34
|
+
# boundary of exactly 1 element Polygon, and every Curve in the
|
35
|
+
# boundary of an element Polygon is in the boundary of the
|
36
|
+
# MultiPolygon.
|
37
|
+
#
|
38
|
+
# NOTE: The subclass of Surface named Polyhedral Surface is a faceted
|
39
|
+
# Surface whose facets are Polygons. A Polyhedral Surface is not a
|
40
|
+
# MultiPolygon because it violates the rule for MultiPolygons that the
|
41
|
+
# boundaries of the element Polygons intersect only at a finite number
|
42
|
+
# of Points.
|
43
|
+
#
|
44
|
+
# == Notes
|
45
|
+
#
|
46
|
+
# MultiPolygon is defined as a module and is provided primarily
|
47
|
+
# for the sake of documentation. Implementations need not necessarily
|
48
|
+
# include this module itself. Therefore, you should not depend on the
|
49
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
50
|
+
# class method (or === operator) defined in the Type module.
|
51
|
+
|
52
|
+
module MultiPolygon
|
53
|
+
include MultiSurface
|
54
|
+
extend Type
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# MultiSurface feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module RGeo
|
8
|
+
module Feature
|
9
|
+
# == SFS 1.1 Description
|
10
|
+
#
|
11
|
+
# A MultiSurface is a 2-dimensional GeometryCollection whose elements
|
12
|
+
# are Surfaces. The interiors of any two Surfaces in a MultiSurface may
|
13
|
+
# not intersect. The boundaries of any two elements in a MultiSurface
|
14
|
+
# may intersect, at most, at a finite number of Points.
|
15
|
+
#
|
16
|
+
# MultiSurface is a non-instantiable class in this International
|
17
|
+
# Standard. It defines a set of methods for its subclasses and is
|
18
|
+
# included for reasons of extensibility. The instantiable subclass of
|
19
|
+
# MultiSurface is MultiPolygon, corresponding to a collection of
|
20
|
+
# Polygons.
|
21
|
+
#
|
22
|
+
# == Notes
|
23
|
+
#
|
24
|
+
# MultiSurface is defined as a module and is provided primarily
|
25
|
+
# for the sake of documentation. Implementations need not necessarily
|
26
|
+
# include this module itself. Therefore, you should not depend on the
|
27
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
28
|
+
# class method (or === operator) defined in the Type module.
|
29
|
+
|
30
|
+
module MultiSurface
|
31
|
+
include GeometryCollection
|
32
|
+
extend Type
|
33
|
+
|
34
|
+
# === SFS 1.1 Description
|
35
|
+
#
|
36
|
+
# The area of this MultiSurface, as measured in the spatial reference
|
37
|
+
# system of this MultiSurface.
|
38
|
+
#
|
39
|
+
# === Notes
|
40
|
+
#
|
41
|
+
# Returns a floating-point scalar value.
|
42
|
+
|
43
|
+
def area
|
44
|
+
raise Error::UnsupportedOperation, "Method MultiSurface#area not defined."
|
45
|
+
end
|
46
|
+
|
47
|
+
# === SFS 1.1 Description
|
48
|
+
#
|
49
|
+
# The mathematical centroid for this MultiSurface as a Point. The
|
50
|
+
# result is not guaranteed to be on this MultiSurface.
|
51
|
+
#
|
52
|
+
# === Notes
|
53
|
+
#
|
54
|
+
# Returns an object that supports the Point interface.
|
55
|
+
|
56
|
+
def centroid
|
57
|
+
raise Error::UnsupportedOperation, "Method MultiSurface#centroid not defined."
|
58
|
+
end
|
59
|
+
|
60
|
+
# === SFS 1.1 Description
|
61
|
+
#
|
62
|
+
# A Point guaranteed to be on this MultiSurface.
|
63
|
+
#
|
64
|
+
# === Notes
|
65
|
+
#
|
66
|
+
# Returns an object that supports the Point interface.
|
67
|
+
|
68
|
+
def point_on_surface
|
69
|
+
raise Error::UnsupportedOperation, "Method MultiSurface#point_on_surface not defined."
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Point feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module RGeo
|
8
|
+
module Feature
|
9
|
+
# == SFS 1.1 Description
|
10
|
+
#
|
11
|
+
# A Point is a 0-dimensional geometric object and represents a single
|
12
|
+
# location in coordinate space. A Point has an x-coordinate value and
|
13
|
+
# a y-coordinate value.
|
14
|
+
#
|
15
|
+
# The boundary of a Point is the empty set.
|
16
|
+
#
|
17
|
+
# == Notes
|
18
|
+
#
|
19
|
+
# Point is defined as a module and is provided primarily
|
20
|
+
# for the sake of documentation. Implementations need not necessarily
|
21
|
+
# include this module itself. Therefore, you should not depend on the
|
22
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
23
|
+
# class method (or === operator) defined in the Type module.
|
24
|
+
#
|
25
|
+
# Some implementations may support higher dimensional points.
|
26
|
+
#
|
27
|
+
# Some libraries, such as GEOS, support "empty" points. Such objects
|
28
|
+
# might be returned as, for example, the centroid of an empty
|
29
|
+
# MultiPolygon. The SFS does not clearly define or even acknowledge
|
30
|
+
# the existence of such a type, so RGeo will currently generally
|
31
|
+
# replace them with empty GeometryCollection objects. Therefore,
|
32
|
+
# currently, every RGeo Point object represents an actual location
|
33
|
+
# with real coordinates.
|
34
|
+
|
35
|
+
module Point
|
36
|
+
include Geometry
|
37
|
+
extend Type
|
38
|
+
|
39
|
+
# === SFS 1.1 Description
|
40
|
+
#
|
41
|
+
# The x-coordinate value for this Point.
|
42
|
+
#
|
43
|
+
# === Notes
|
44
|
+
#
|
45
|
+
# Returns a floating-point scalar value.
|
46
|
+
|
47
|
+
def x
|
48
|
+
raise Error::UnsupportedOperation, "Method Point#x not defined."
|
49
|
+
end
|
50
|
+
|
51
|
+
# === SFS 1.1 Description
|
52
|
+
#
|
53
|
+
# The y-coordinate value for this Point.
|
54
|
+
#
|
55
|
+
# === Notes
|
56
|
+
#
|
57
|
+
# Returns a floating-point scalar value.
|
58
|
+
|
59
|
+
def y
|
60
|
+
raise Error::UnsupportedOperation, "Method Point#y not defined."
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the z-coordinate for this Point as a floating-point
|
64
|
+
# scalar value.
|
65
|
+
#
|
66
|
+
# This method may not be available if the point's factory does
|
67
|
+
# not support Z coordinates.
|
68
|
+
|
69
|
+
def z
|
70
|
+
raise Error::UnsupportedOperation, "Method Point#z not defined."
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns the m-coordinate for this Point as a floating-point
|
74
|
+
# scalar value.
|
75
|
+
#
|
76
|
+
# This method may not be available if the point's factory does
|
77
|
+
# not support M coordinates.
|
78
|
+
|
79
|
+
def m
|
80
|
+
raise Error::UnsupportedOperation, "Method Point#m not defined."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Polygon feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module RGeo
|
8
|
+
module Feature
|
9
|
+
# == SFS 1.1 Description
|
10
|
+
#
|
11
|
+
# A Polygon is a planar Surface defined by 1 exterior boundary and 0 or
|
12
|
+
# more interior boundaries. Each interior boundary defines a hole in
|
13
|
+
# the Polygon.
|
14
|
+
#
|
15
|
+
# The assertions for Polygons (the rules that define valid Polygons)
|
16
|
+
# are as follows:
|
17
|
+
#
|
18
|
+
# (a) Polygons are topologically closed;
|
19
|
+
#
|
20
|
+
# (b) The boundary of a Polygon consists of a set of LinearRings that
|
21
|
+
# make up its exterior and interior boundaries;
|
22
|
+
#
|
23
|
+
# (c) No two Rings in the boundary cross and the Rings in the boundary
|
24
|
+
# of a Polygon may intersect at a Point but only as a tangent;
|
25
|
+
#
|
26
|
+
# (d) A Polygon may not have cut lines, spikes or punctures;
|
27
|
+
#
|
28
|
+
# (e) The interior of every Polygon is a connected point set;
|
29
|
+
#
|
30
|
+
# (f) The exterior of a Polygon with 1 or more holes is not connected.
|
31
|
+
# Each hole defines a connected component of the exterior.
|
32
|
+
#
|
33
|
+
# In the above assertions, interior, closure and exterior have the
|
34
|
+
# standard topological definitions. The combination of (a) and (c) make
|
35
|
+
# a Polygon a regular closed Point set.
|
36
|
+
#
|
37
|
+
# Polygons are simple geometric objects.
|
38
|
+
#
|
39
|
+
# == Notes
|
40
|
+
#
|
41
|
+
# Polygon is defined as a module and is provided primarily
|
42
|
+
# for the sake of documentation. Implementations need not necessarily
|
43
|
+
# include this module itself. Therefore, you should not depend on the
|
44
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
45
|
+
# class method (or === operator) defined in the Type module.
|
46
|
+
|
47
|
+
module Polygon
|
48
|
+
include Surface
|
49
|
+
extend Type
|
50
|
+
|
51
|
+
# === SFS 1.1 Description
|
52
|
+
#
|
53
|
+
# Returns the exterior ring of this Polygon.
|
54
|
+
#
|
55
|
+
# === Notes
|
56
|
+
#
|
57
|
+
# Returns an object that supports the LinearRing interface.
|
58
|
+
|
59
|
+
def exterior_ring
|
60
|
+
raise Error::UnsupportedOperation, "Method Polygon#exterior_ring not defined."
|
61
|
+
end
|
62
|
+
|
63
|
+
# === SFS 1.1 Description
|
64
|
+
#
|
65
|
+
# Returns the number of interiorRings in this Polygon.
|
66
|
+
#
|
67
|
+
# === Notes
|
68
|
+
#
|
69
|
+
# Returns an integer.
|
70
|
+
|
71
|
+
def num_interior_rings
|
72
|
+
raise Error::UnsupportedOperation, "Method Polygon#num_interior_rings not defined."
|
73
|
+
end
|
74
|
+
|
75
|
+
# === SFS 1.1 Description
|
76
|
+
#
|
77
|
+
# Returns the Nth interiorRing for this Polygon as a LineString.
|
78
|
+
#
|
79
|
+
# === Notes
|
80
|
+
#
|
81
|
+
# Returns an object that supports the LinearRing interface, or nil
|
82
|
+
# if the given N is out of range. N is zero-based.
|
83
|
+
# Does not support negative indexes.
|
84
|
+
|
85
|
+
def interior_ring_n(_n_)
|
86
|
+
raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined."
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns the interior rings as a (possibly empty) array of objects
|
90
|
+
# that support the LinearRing interface.
|
91
|
+
|
92
|
+
def interior_rings
|
93
|
+
raise Error::UnsupportedOperation, "Method Polygon#interior_rings not defined."
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Surface feature interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module RGeo
|
8
|
+
module Feature
|
9
|
+
# == SFS 1.1 Description
|
10
|
+
#
|
11
|
+
# A Surface is a 2-dimensional geometric object.
|
12
|
+
#
|
13
|
+
# A simple Surface consists of a single "patch" that is associated with
|
14
|
+
# one "exterior boundary" and 0 or more "interior" boundaries. Simple
|
15
|
+
# Surfaces in 3-dimensional space are isomorphic to planar Surfaces.
|
16
|
+
# Polyhedral Surfaces are formed by "stitching" together simple
|
17
|
+
# Surfaces along their boundaries, polyhedral Surfaces in 3-dimensional
|
18
|
+
# space may not be planar as a whole.
|
19
|
+
#
|
20
|
+
# The boundary of a simple Surface is the set of closed Curves
|
21
|
+
# corresponding to its "exterior" and "interior" boundaries.
|
22
|
+
#
|
23
|
+
# The only instantiable subclass of Surface defined in this
|
24
|
+
# specification, Polygon, is a simple Surface that is planar.
|
25
|
+
#
|
26
|
+
# == Notes
|
27
|
+
#
|
28
|
+
# Surface is defined as a module and is provided primarily
|
29
|
+
# for the sake of documentation. Implementations need not necessarily
|
30
|
+
# include this module itself. Therefore, you should not depend on the
|
31
|
+
# kind_of? method to check type. Instead, use the provided check_type
|
32
|
+
# class method (or === operator) defined in the Type module.
|
33
|
+
#
|
34
|
+
# Some implementations may support higher dimensional points.
|
35
|
+
|
36
|
+
module Surface
|
37
|
+
include Geometry
|
38
|
+
extend Type
|
39
|
+
|
40
|
+
# === SFS 1.1 Description
|
41
|
+
#
|
42
|
+
# The area of this Surface, as measured in the spatial reference
|
43
|
+
# system of this Surface.
|
44
|
+
#
|
45
|
+
# === Notes
|
46
|
+
#
|
47
|
+
# Returns a floating-point scalar value.
|
48
|
+
|
49
|
+
def area
|
50
|
+
raise Error::UnsupportedOperation, "Method Surface#area not defined."
|
51
|
+
end
|
52
|
+
|
53
|
+
# === SFS 1.1 Description
|
54
|
+
#
|
55
|
+
# The mathematical centroid for this Surface as a Point. The result
|
56
|
+
# is not guaranteed to be on this Surface.
|
57
|
+
#
|
58
|
+
# === Notes
|
59
|
+
#
|
60
|
+
# Returns an object that supports the Point interface.
|
61
|
+
|
62
|
+
def centroid
|
63
|
+
raise Error::UnsupportedOperation, "Method Surface#centroid not defined."
|
64
|
+
end
|
65
|
+
|
66
|
+
# === SFS 1.1 Description
|
67
|
+
#
|
68
|
+
# A Point guaranteed to be on this Surface.
|
69
|
+
#
|
70
|
+
# === Notes
|
71
|
+
#
|
72
|
+
# Returns an object that supports the Point interface.
|
73
|
+
|
74
|
+
def point_on_surface
|
75
|
+
raise Error::UnsupportedOperation, "Method Surface#point_on_surface not defined."
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Feature type management and casting
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module RGeo
|
8
|
+
module Feature
|
9
|
+
# All geometry implementations MUST include this submodule.
|
10
|
+
# This serves as a marker that may be used to test an object for
|
11
|
+
# feature-ness.
|
12
|
+
|
13
|
+
module Instance
|
14
|
+
end
|
15
|
+
|
16
|
+
# This module provides the API for geometry type objects. Technically
|
17
|
+
# these objects are modules (such as ::RGeo::Feature::Point), but as
|
18
|
+
# objects they respond to the methods documented here.
|
19
|
+
#
|
20
|
+
# For example, you may determine whether a feature object is a
|
21
|
+
# point by calling:
|
22
|
+
#
|
23
|
+
# ::RGeo::Feature::Point.check_type(object)
|
24
|
+
#
|
25
|
+
# A corresponding === operator is provided so you can use the type
|
26
|
+
# modules in a case-when clause:
|
27
|
+
#
|
28
|
+
# case object
|
29
|
+
# when ::RGeo::Feature::Point
|
30
|
+
# # do stuff here...
|
31
|
+
#
|
32
|
+
# However, a feature object may not actually include the point module
|
33
|
+
# itself; hence, the following will *not* work:
|
34
|
+
#
|
35
|
+
# object.is_a?(::RGeo::Feature::Point) # DON'T DO THIS-- DOES NOT WORK
|
36
|
+
#
|
37
|
+
# You may obtain the type of a feature object by calling its
|
38
|
+
# geometry_type method. You may then use the methods in this module to
|
39
|
+
# interrogate that type.
|
40
|
+
#
|
41
|
+
# # supppose object is a Point
|
42
|
+
# type = object.geometry_type # ::RGeo::Feature::Point
|
43
|
+
# type.type_name # "Point"
|
44
|
+
# type.supertype # ::RGeo::Feature::Geometry
|
45
|
+
#
|
46
|
+
# You may also use the presence of this module to determine whether
|
47
|
+
# a particular object is a feature type:
|
48
|
+
#
|
49
|
+
# ::RGeo::Feature::Type === object.geometry_type # true
|
50
|
+
|
51
|
+
module Type
|
52
|
+
# Deprecated alias for RGeo::Feature::Instance
|
53
|
+
Instance = Feature::Instance
|
54
|
+
|
55
|
+
# Returns true if the given object is this type or a subtype
|
56
|
+
# thereof, or if it is a feature object whose geometry_type is
|
57
|
+
# this type or a subtype thereof.
|
58
|
+
#
|
59
|
+
# Note that feature objects need not actually include this module.
|
60
|
+
# Therefore, the is_a? method will generally not work.
|
61
|
+
|
62
|
+
def check_type(rhs_)
|
63
|
+
rhs_ = rhs_.geometry_type if rhs_.is_a?(Feature::Instance)
|
64
|
+
rhs_.is_a?(Type) && (rhs_ == self || rhs_.include?(self))
|
65
|
+
end
|
66
|
+
alias_method :===, :check_type
|
67
|
+
|
68
|
+
# Returns true if this type is the same type or a subtype of the
|
69
|
+
# given type.
|
70
|
+
|
71
|
+
def subtype_of?(type_)
|
72
|
+
self == type_ || self.include?(type_)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the supertype of this type. The supertype of Geometry
|
76
|
+
# is nil.
|
77
|
+
|
78
|
+
def supertype
|
79
|
+
@supertype
|
80
|
+
end
|
81
|
+
|
82
|
+
# Iterates over the known immediate subtypes of this type.
|
83
|
+
|
84
|
+
def each_immediate_subtype(&block_)
|
85
|
+
@subtypes.each(&block_) if defined?(@subtypes) && @subtypes
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the OpenGIS type name of this type. For example:
|
89
|
+
#
|
90
|
+
# ::RGeo::Feature::Point.type_name # "Point"
|
91
|
+
|
92
|
+
def type_name
|
93
|
+
name.sub("RGeo::Feature::", "")
|
94
|
+
end
|
95
|
+
alias_method :to_s, :type_name
|
96
|
+
|
97
|
+
def _add_subtype(type_) # :nodoc:
|
98
|
+
(@subtypes ||= []) << type_
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.extended(type_) # :nodoc:
|
102
|
+
supertype_ = type_.included_modules.find { |m_| m_.is_a?(self) }
|
103
|
+
type_.instance_variable_set(:@supertype, supertype_)
|
104
|
+
supertype_._add_subtype(type_) if supertype_
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class << self
|
109
|
+
# Cast the given object according to the given parameters, if
|
110
|
+
# possible, and return the resulting object. If the requested cast
|
111
|
+
# is not possible, nil is returned.
|
112
|
+
#
|
113
|
+
# Parameters may be provided as a hash, or as separate arguments.
|
114
|
+
# Hash keys are as follows:
|
115
|
+
#
|
116
|
+
# [<tt>:factory</tt>]
|
117
|
+
# Set the factory to the given factory. If this argument is not
|
118
|
+
# given, the original object's factory is kept.
|
119
|
+
# [<tt>:type</tt>]
|
120
|
+
# Cast to the given type, which must be a module in the
|
121
|
+
# RGeo::Feature namespace. If this argument is not given, the
|
122
|
+
# result keeps the same type as the original.
|
123
|
+
# [<tt>:project</tt>]
|
124
|
+
# If this is set to true, and both the original and new factories
|
125
|
+
# support proj4 projections, then the cast will also cause the
|
126
|
+
# coordinates to be transformed between those two projections.
|
127
|
+
# If set to false, the coordinates are not modified. Default is
|
128
|
+
# false.
|
129
|
+
# [<tt>:keep_subtype</tt>]
|
130
|
+
# Value must be a boolean indicating whether to keep the subtype
|
131
|
+
# of the original. If set to false, casting to a particular type
|
132
|
+
# always casts strictly to that type, even if the old type is a
|
133
|
+
# subtype of the new type. If set to true, the cast retains the
|
134
|
+
# subtype in that case. For example, casting a LinearRing to a
|
135
|
+
# LineString will normally yield a LineString, even though
|
136
|
+
# LinearRing is already a more specific subtype. If you set this
|
137
|
+
# value to true, the casted object will remain a LinearRing.
|
138
|
+
# Default is false.
|
139
|
+
# [<tt>:force_new</tt>]
|
140
|
+
# Always return a newly-created object, even if neither the type
|
141
|
+
# nor factory is modified. Normally, if this is set to false, and
|
142
|
+
# a cast is not set to modify either the factory or type, the
|
143
|
+
# original object itself is returned. Setting this flag to true
|
144
|
+
# causes cast to return a clone in that case. Default is false.
|
145
|
+
#
|
146
|
+
# You may also pass the new factory, the new type, and the flags
|
147
|
+
# as separate arguments. In this case, the flag names must be
|
148
|
+
# passed as symbols, and their effect is the same as setting their
|
149
|
+
# values to true. You can even combine separate arguments and hash
|
150
|
+
# arguments. For example, the following three calls are equivalent:
|
151
|
+
#
|
152
|
+
# RGeo::Feature.cast(geom, :type => RGeo::Feature::Point, :project => true)
|
153
|
+
# RGeo::Feature.cast(geom, RGeo::Feature::Point, :project => true)
|
154
|
+
# RGeo::Feature.cast(geom, RGeo::Feature::Point, :project)
|
155
|
+
#
|
156
|
+
# RGeo provides a default casting algorithm. Individual feature
|
157
|
+
# implementation factories may override this and customize the
|
158
|
+
# casting behavior by defining the override_cast method. See
|
159
|
+
# ::RGeo::Feature::Factory#override_cast for more details.
|
160
|
+
|
161
|
+
def cast(obj_, *params_)
|
162
|
+
# Interpret params
|
163
|
+
factory_ = obj_.factory
|
164
|
+
type_ = obj_.geometry_type
|
165
|
+
opts_ = {}
|
166
|
+
params_.each do |param_|
|
167
|
+
case param_
|
168
|
+
when Factory::Instance
|
169
|
+
opts_[:factory] = param_
|
170
|
+
when Type
|
171
|
+
opts_[:type] = param_
|
172
|
+
when ::Symbol
|
173
|
+
opts_[param_] = true
|
174
|
+
when ::Hash
|
175
|
+
opts_.merge!(param_)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
force_new_ = opts_[:force_new]
|
179
|
+
keep_subtype_ = opts_[:keep_subtype]
|
180
|
+
project_ = opts_[:project]
|
181
|
+
nfactory_ = opts_.delete(:factory) || factory_
|
182
|
+
ntype_ = opts_.delete(:type) || type_
|
183
|
+
|
184
|
+
# Let the factory override
|
185
|
+
if nfactory_.respond_to?(:override_cast)
|
186
|
+
override_ = nfactory_.override_cast(obj_, ntype_, opts_)
|
187
|
+
return override_ unless override_ == false
|
188
|
+
end
|
189
|
+
|
190
|
+
# Default algorithm
|
191
|
+
ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
|
192
|
+
if ntype_ == type_
|
193
|
+
# Types are the same
|
194
|
+
if nfactory_ == factory_
|
195
|
+
force_new_ ? obj_.dup : obj_
|
196
|
+
else
|
197
|
+
if type_ == Point
|
198
|
+
proj_ = nproj_ = nil
|
199
|
+
if project_
|
200
|
+
proj_ = factory_.proj4
|
201
|
+
nproj_ = nfactory_.proj4
|
202
|
+
end
|
203
|
+
hasz_ = factory_.property(:has_z_coordinate)
|
204
|
+
nhasz_ = nfactory_.property(:has_z_coordinate)
|
205
|
+
if proj_ && nproj_
|
206
|
+
coords_ = CoordSys::Proj4.transform_coords(proj_, nproj_, obj_.x, obj_.y, hasz_ ? obj_.z : nil)
|
207
|
+
coords_ << (hasz_ ? obj_.z : 0.0) if nhasz_ && coords_.size < 3
|
208
|
+
else
|
209
|
+
coords_ = [obj_.x, obj_.y]
|
210
|
+
coords_ << (hasz_ ? obj_.z : 0.0) if nhasz_
|
211
|
+
end
|
212
|
+
coords_ << (factory_.property(:has_m_coordinate) ? obj_.m : 0.0) if nfactory_.property(:has_m_coordinate)
|
213
|
+
nfactory_.point(*coords_)
|
214
|
+
elsif type_ == Line
|
215
|
+
nfactory_.line(cast(obj_.start_point, nfactory_, opts_), cast(obj_.end_point, nfactory_, opts_))
|
216
|
+
elsif type_ == LinearRing
|
217
|
+
nfactory_.linear_ring(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
|
218
|
+
elsif type_ == LineString
|
219
|
+
nfactory_.line_string(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
|
220
|
+
elsif type_ == Polygon
|
221
|
+
nfactory_.polygon(cast(obj_.exterior_ring, nfactory_, opts_),
|
222
|
+
obj_.interior_rings.map { |r_| cast(r_, nfactory_, opts_) })
|
223
|
+
elsif type_ == MultiPoint
|
224
|
+
nfactory_.multi_point(obj_.map { |g_| cast(g_, nfactory_, opts_) })
|
225
|
+
elsif type_ == MultiLineString
|
226
|
+
nfactory_.multi_line_string(obj_.map { |g_| cast(g_, nfactory_, opts_) })
|
227
|
+
elsif type_ == MultiPolygon
|
228
|
+
nfactory_.multi_polygon(obj_.map { |g_| cast(g_, nfactory_, opts_) })
|
229
|
+
elsif type_ == GeometryCollection
|
230
|
+
nfactory_.collection(obj_.map { |g_| cast(g_, nfactory_, opts_) })
|
231
|
+
end
|
232
|
+
end
|
233
|
+
else
|
234
|
+
# Types are different
|
235
|
+
if ntype_ == Point && (type_ == MultiPoint || type_ == GeometryCollection) ||
|
236
|
+
(ntype_ == Line || ntype_ == LineString || ntype_ == LinearRing) && (type_ == MultiLineString || type_ == GeometryCollection) ||
|
237
|
+
ntype_ == Polygon && (type_ == MultiPolygon || type_ == GeometryCollection)
|
238
|
+
if obj_.num_geometries == 1
|
239
|
+
cast(obj_.geometry_n(0), nfactory_, ntype_, opts_)
|
240
|
+
end
|
241
|
+
elsif ntype_ == Point
|
242
|
+
nil
|
243
|
+
elsif ntype_ == Line
|
244
|
+
if type_ == LineString && obj_.num_points == 2
|
245
|
+
nfactory_.line(cast(obj_.point_n(0), nfactory_, opts_), cast(obj_.point_n(1), nfactory_, opts_))
|
246
|
+
end
|
247
|
+
elsif ntype_ == LinearRing
|
248
|
+
if type_ == LineString
|
249
|
+
nfactory_.linear_ring(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
|
250
|
+
end
|
251
|
+
elsif ntype_ == LineString
|
252
|
+
if type_ == Line || type_ == LinearRing
|
253
|
+
nfactory_.line_string(obj_.points.map { |p_| cast(p_, nfactory_, opts_) })
|
254
|
+
end
|
255
|
+
elsif ntype_ == MultiPoint
|
256
|
+
if type_ == Point
|
257
|
+
nfactory_.multi_point([cast(obj_, nfactory_, opts_)])
|
258
|
+
elsif type_ == GeometryCollection
|
259
|
+
nfactory_.multi_point(obj_.map { |p_| cast(p_, nfactory_, opts_) })
|
260
|
+
end
|
261
|
+
elsif ntype_ == MultiLineString
|
262
|
+
if type_ == Line || type_ == LinearRing || type_ == LineString
|
263
|
+
nfactory_.multi_line_string([cast(obj_, nfactory_, opts_)])
|
264
|
+
elsif type_ == GeometryCollection
|
265
|
+
nfactory_.multi_line_string(obj_.map { |p_| cast(p_, nfactory_, opts_) })
|
266
|
+
end
|
267
|
+
elsif ntype_ == MultiPolygon
|
268
|
+
if type_ == Polygon
|
269
|
+
nfactory_.multi_polygon([cast(obj_, nfactory_, opts_)])
|
270
|
+
elsif type_ == GeometryCollection
|
271
|
+
nfactory_.multi_polygon(obj_.map { |p_| cast(p_, nfactory_, opts_) })
|
272
|
+
end
|
273
|
+
elsif ntype_ == GeometryCollection
|
274
|
+
if type_ == MultiPoint || type_ == MultiLineString || type_ == MultiPolygon
|
275
|
+
nfactory_.collection(obj_.map { |p_| cast(p_, nfactory_, opts_) })
|
276
|
+
else
|
277
|
+
nfactory_.collection([cast(obj_, nfactory_, opts_)])
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|