rgeo 2.0.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -559,22 +559,6 @@ static VALUE method_multi_polygon_centroid(VALUE self)
559
559
  }
560
560
 
561
561
 
562
- static VALUE method_multi_polygon_point_on_surface(VALUE self)
563
- {
564
- VALUE result;
565
- RGeo_GeometryData* self_data;
566
- const GEOSGeometry* self_geom;
567
-
568
- result = Qnil;
569
- self_data = RGEO_GEOMETRY_DATA_PTR(self);
570
- self_geom = self_data->geom;
571
- if (self_geom) {
572
- result = rgeo_wrap_geos_geometry(self_data->factory, GEOSPointOnSurface_r(self_data->geos_context, self_geom), Qnil);
573
- }
574
- return result;
575
- }
576
-
577
-
578
562
  static VALUE cmethod_geometry_collection_create(VALUE module, VALUE factory, VALUE array)
579
563
  {
580
564
  return create_geometry_collection(module, GEOS_GEOMETRYCOLLECTION, factory, array);
@@ -648,7 +632,6 @@ void rgeo_init_geos_geometry_collection(RGeo_Globals* globals)
648
632
  rb_define_method(geos_multi_polygon_methods, "geometry_type", method_multi_polygon_geometry_type, 0);
649
633
  rb_define_method(geos_multi_polygon_methods, "area", method_multi_polygon_area, 0);
650
634
  rb_define_method(geos_multi_polygon_methods, "centroid", method_multi_polygon_centroid, 0);
651
- rb_define_method(geos_multi_polygon_methods, "point_on_surface", method_multi_polygon_point_on_surface, 0);
652
635
  rb_define_method(geos_multi_polygon_methods, "hash", method_multi_polygon_hash, 0);
653
636
  rb_define_method(geos_multi_polygon_methods, "coordinates", method_multi_polygon_coordinates, 0);
654
637
  }
@@ -2,7 +2,6 @@
2
2
  Main initializer for GEOS wrapper
3
3
  */
4
4
 
5
-
6
5
  #include "preface.h"
7
6
 
8
7
  #ifdef RGEO_GEOS_SUPPORTED
@@ -10,18 +9,20 @@
10
9
  #include <ruby.h>
11
10
  #include <geos_c.h>
12
11
 
12
+ #include "errors.h"
13
+
13
14
  #include "factory.h"
14
15
  #include "geometry.h"
15
16
  #include "point.h"
16
17
  #include "line_string.h"
17
18
  #include "polygon.h"
18
19
  #include "geometry_collection.h"
20
+ #include "analysis.h"
19
21
 
20
22
  #endif
21
23
 
22
24
  RGEO_BEGIN_C
23
25
 
24
-
25
26
  void Init_geos_c_impl()
26
27
  {
27
28
  #ifdef RGEO_GEOS_SUPPORTED
@@ -33,6 +34,8 @@ void Init_geos_c_impl()
33
34
  rgeo_init_geos_line_string(globals);
34
35
  rgeo_init_geos_polygon(globals);
35
36
  rgeo_init_geos_geometry_collection(globals);
37
+ rgeo_init_geos_analysis(globals);
38
+ rgeo_init_geos_errors();
36
39
  #endif
37
40
  }
38
41
 
@@ -21,6 +21,9 @@
21
21
  #ifdef HAVE_GEOSUNARYUNION_R
22
22
  #define RGEO_GEOS_SUPPORTS_UNARYUNION
23
23
  #endif
24
+ #ifdef HAVE_GEOSCOORDSEQ_ISCCW_R
25
+ #define RGEO_GEOS_SUPPORTS_ISCCW
26
+ #endif
24
27
  #ifdef HAVE_RB_MEMHASH
25
28
  #define RGEO_SUPPORTS_NEW_HASHING
26
29
  #endif
data/lib/rgeo.rb CHANGED
@@ -75,12 +75,12 @@
75
75
  # database, and based on the postgresql adapter. Available as the
76
76
  # activerecord-postgis-adapter gem.
77
77
 
78
- require "rgeo/version"
79
- require "rgeo/error"
80
- require "rgeo/feature"
81
- require "rgeo/coord_sys"
82
- require "rgeo/impl_helper"
83
- require "rgeo/wkrep"
84
- require "rgeo/geos"
85
- require "rgeo/cartesian"
86
- require "rgeo/geographic"
78
+ require_relative "rgeo/version"
79
+ require_relative "rgeo/error"
80
+ require_relative "rgeo/feature"
81
+ require_relative "rgeo/coord_sys"
82
+ require_relative "rgeo/impl_helper"
83
+ require_relative "rgeo/wkrep"
84
+ require_relative "rgeo/geos"
85
+ require_relative "rgeo/cartesian"
86
+ require_relative "rgeo/geographic"
@@ -6,10 +6,10 @@
6
6
  # the simple Cartesian implementation. It also provides a namespace
7
7
  # for Cartesian-specific analysis tools.
8
8
 
9
- require "rgeo/cartesian/calculations"
10
- require "rgeo/cartesian/feature_methods"
11
- require "rgeo/cartesian/feature_classes"
12
- require "rgeo/cartesian/factory"
13
- require "rgeo/cartesian/interface"
14
- require "rgeo/cartesian/bounding_box"
15
- require "rgeo/cartesian/analysis"
9
+ require_relative "cartesian/calculations"
10
+ require_relative "cartesian/feature_methods"
11
+ require_relative "cartesian/feature_classes"
12
+ require_relative "cartesian/factory"
13
+ require_relative "cartesian/interface"
14
+ require_relative "cartesian/bounding_box"
15
+ require_relative "cartesian/analysis"
@@ -13,6 +13,28 @@ module RGeo
13
13
 
14
14
  module Analysis
15
15
  class << self
16
+ # Check orientation of a ring, returns `true` if it is counter-clockwise
17
+ # and false otherwise.
18
+ #
19
+ # If the factory used is GEOS based, use the GEOS implementation to
20
+ # check that. Otherwise, this methods falls back to `ring_direction`.
21
+ #
22
+ # == Note
23
+ #
24
+ # This method does not ensure a correct result for an invalid geometry.
25
+ # You should make sure your ring is valid beforehand using `is_ring?`
26
+ # if you are using a LineString, or directly `valid?` for a
27
+ # `linear_ring?`.
28
+ # This will be subject to changes in v3.
29
+ def ccw?(ring)
30
+ if RGeo::Geos.is_capi_geos?(ring) && RGeo::Geos::Analysis.ccw_supported?
31
+ RGeo::Geos::Analysis.ccw?(ring)
32
+ else
33
+ RGeo::Cartesian::Analysis.ring_direction(ring) == 1
34
+ end
35
+ end
36
+ alias counter_clockwise? ccw?
37
+
16
38
  # Given a LineString, which must be a ring, determine whether the
17
39
  # ring proceeds clockwise or counterclockwise.
18
40
  # Returns 1 for counterclockwise, or -1 for clockwise.
@@ -6,12 +6,12 @@
6
6
  #
7
7
  # -----------------------------------------------------------------------------
8
8
 
9
- require "rgeo/coord_sys/cs/factories"
10
- require "rgeo/coord_sys/cs/entities"
11
- require "rgeo/coord_sys/cs/wkt_parser"
12
- require "rgeo/coord_sys/srs_database/entry"
13
- require "rgeo/coord_sys/srs_database/url_reader"
14
- require "rgeo/coord_sys/srs_database/sr_org"
9
+ require_relative "coord_sys/cs/factories"
10
+ require_relative "coord_sys/cs/entities"
11
+ require_relative "coord_sys/cs/wkt_parser"
12
+ require_relative "coord_sys/srs_database/entry"
13
+ require_relative "coord_sys/srs_database/url_reader"
14
+ require_relative "coord_sys/srs_database/sr_org"
15
15
 
16
16
  module RGeo
17
17
  # This module provides data structures and tools related to coordinate
data/lib/rgeo/error.rb CHANGED
@@ -14,6 +14,10 @@ module RGeo
14
14
  class RGeoError < RuntimeError
15
15
  end
16
16
 
17
+ # RGeo error specific to the GEOS implementation.
18
+ class GeosError < RGeoError
19
+ end
20
+
17
21
  # The specified geometry is invalid
18
22
  class InvalidGeometry < RGeoError
19
23
  end
data/lib/rgeo/feature.rb CHANGED
@@ -24,20 +24,20 @@
24
24
  # itself. The implementation should separately document any such
25
25
  # extensions that it may provide.
26
26
 
27
- require "rgeo/feature/factory"
28
- require "rgeo/feature/types"
29
- require "rgeo/feature/geometry"
30
- require "rgeo/feature/point"
31
- require "rgeo/feature/curve"
32
- require "rgeo/feature/line_string"
33
- require "rgeo/feature/linear_ring"
34
- require "rgeo/feature/line"
35
- require "rgeo/feature/surface"
36
- require "rgeo/feature/polygon"
37
- require "rgeo/feature/geometry_collection"
38
- require "rgeo/feature/multi_point"
39
- require "rgeo/feature/multi_curve"
40
- require "rgeo/feature/multi_line_string"
41
- require "rgeo/feature/multi_surface"
42
- require "rgeo/feature/multi_polygon"
43
- require "rgeo/feature/factory_generator"
27
+ require_relative "feature/factory"
28
+ require_relative "feature/types"
29
+ require_relative "feature/geometry"
30
+ require_relative "feature/point"
31
+ require_relative "feature/curve"
32
+ require_relative "feature/line_string"
33
+ require_relative "feature/linear_ring"
34
+ require_relative "feature/line"
35
+ require_relative "feature/surface"
36
+ require_relative "feature/polygon"
37
+ require_relative "feature/geometry_collection"
38
+ require_relative "feature/multi_point"
39
+ require_relative "feature/multi_curve"
40
+ require_relative "feature/multi_line_string"
41
+ require_relative "feature/multi_surface"
42
+ require_relative "feature/multi_polygon"
43
+ require_relative "feature/factory_generator"
@@ -23,6 +23,16 @@ module RGeo
23
23
  module LinearRing
24
24
  include LineString
25
25
  extend Type
26
+
27
+ # Returns +true+ if the ring is oriented in a counter clockwise direction
28
+ # otherwise returns +false+.
29
+ #
30
+ # == Notes
31
+ #
32
+ # Not a standard SFS method for linear rings, but added for convenience.
33
+ def ccw?
34
+ raise Error::UnsupportedOperation, "Method LinearRing#ccw? not defined."
35
+ end
26
36
  end
27
37
  end
28
38
  end
@@ -18,13 +18,13 @@
18
18
  # See the various class methods of Geographic for more information on
19
19
  # the behaviors of the factories they generate.
20
20
 
21
- require "rgeo/geographic/factory"
22
- require "rgeo/geographic/projected_window"
23
- require "rgeo/geographic/interface"
24
- require "rgeo/geographic/spherical_math"
25
- require "rgeo/geographic/spherical_feature_methods"
26
- require "rgeo/geographic/spherical_feature_classes"
27
- require "rgeo/geographic/proj4_projector"
28
- require "rgeo/geographic/simple_mercator_projector"
29
- require "rgeo/geographic/projected_feature_methods"
30
- require "rgeo/geographic/projected_feature_classes"
21
+ require_relative "geographic/factory"
22
+ require_relative "geographic/projected_window"
23
+ require_relative "geographic/interface"
24
+ require_relative "geographic/spherical_math"
25
+ require_relative "geographic/spherical_feature_methods"
26
+ require_relative "geographic/spherical_feature_classes"
27
+ require_relative "geographic/proj4_projector"
28
+ require_relative "geographic/simple_mercator_projector"
29
+ require_relative "geographic/projected_feature_methods"
30
+ require_relative "geographic/projected_feature_classes"
@@ -110,6 +110,10 @@ module RGeo
110
110
  def sym_difference(rhs)
111
111
  factory.unproject(projection.sym_difference(Feature.cast(rhs, factory).projection))
112
112
  end
113
+
114
+ def point_on_surface
115
+ factory.unproject(projection.point_on_surface)
116
+ end
113
117
  end
114
118
 
115
119
  module ProjectedPointMethods # :nodoc:
@@ -125,7 +129,7 @@ module RGeo
125
129
  if @x >= -180.0 && @x < 180.0
126
130
  self
127
131
  else
128
- PointImpl.new(@factory, canonical_x, @y)
132
+ ProjectedPointImpl.new(@factory, canonical_x, @y)
129
133
  end
130
134
  end
131
135
 
@@ -170,10 +174,6 @@ module RGeo
170
174
  def centroid
171
175
  factory.unproject(projection.centroid)
172
176
  end
173
-
174
- def point_on_surface
175
- factory.unproject(projection.point_on_surface)
176
- end
177
177
  end
178
178
 
179
179
  module ProjectedPolygonMethods # :nodoc:
@@ -47,6 +47,7 @@ module RGeo
47
47
  include ImplHelper::BasicGeometryMethods
48
48
  include ImplHelper::BasicPolygonMethods
49
49
  include SphericalGeometryMethods
50
+ include SphericalPolygonMethods
50
51
  end
51
52
 
52
53
  class SphericalGeometryCollectionImpl # :nodoc:
@@ -130,5 +130,28 @@ module RGeo
130
130
  inject(0.0) { |sum, geom| sum + geom.length }
131
131
  end
132
132
  end
133
+
134
+ module SphericalPolygonMethods # :nodoc:
135
+ def centroid
136
+ return super unless num_interior_rings == 0
137
+
138
+ centroid_lat = 0.0
139
+ centroid_lng = 0.0
140
+ signed_area = 0.0
141
+
142
+ exterior_ring.points.each_cons(2) do |p0, p1|
143
+ area = (p0.x * p1.y) - (p1.x * p0.y)
144
+ signed_area += area
145
+ centroid_lat += (p0.x + p1.x) * area
146
+ centroid_lng += (p0.y + p1.y) * area
147
+ end
148
+
149
+ signed_area *= 0.5
150
+ centroid_lat /= (6.0 * signed_area)
151
+ centroid_lng /= (6.0 * signed_area)
152
+
153
+ RGeo::Geographic.spherical_factory.point(centroid_lat, centroid_lng)
154
+ end
155
+ end
133
156
  end
134
157
  end
data/lib/rgeo/geos.rb CHANGED
@@ -21,24 +21,24 @@
21
21
 
22
22
  module RGeo
23
23
  module Geos
24
- require "rgeo/geos/utils"
25
- require "rgeo/geos/interface"
24
+ require_relative "geos/utils"
25
+ require_relative "geos/interface"
26
26
  begin
27
- require "rgeo/geos/geos_c_impl"
27
+ require_relative "geos/geos_c_impl"
28
28
  rescue LoadError
29
29
  # continue
30
30
  end
31
31
  CAPI_SUPPORTED = RGeo::Geos.const_defined?(:CAPIGeometryMethods)
32
32
  if CAPI_SUPPORTED
33
- require "rgeo/geos/capi_feature_classes"
34
- require "rgeo/geos/capi_factory"
33
+ require_relative "geos/capi_feature_classes"
34
+ require_relative "geos/capi_factory"
35
35
  end
36
- require "rgeo/geos/ffi_feature_methods"
37
- require "rgeo/geos/ffi_feature_classes"
38
- require "rgeo/geos/ffi_factory"
39
- require "rgeo/geos/zm_feature_methods"
40
- require "rgeo/geos/zm_feature_classes"
41
- require "rgeo/geos/zm_factory"
36
+ require_relative "geos/ffi_feature_methods"
37
+ require_relative "geos/ffi_feature_classes"
38
+ require_relative "geos/ffi_factory"
39
+ require_relative "geos/zm_feature_methods"
40
+ require_relative "geos/zm_feature_classes"
41
+ require_relative "geos/zm_factory"
42
42
 
43
43
  # Determine ffi support.
44
44
  begin
@@ -63,15 +63,13 @@ module RGeo
63
63
  self.preferred_native_interface = :ffi
64
64
  end
65
65
 
66
- # There is some trouble with END_CAP in GEOS
67
- # In docs CAP_ROUND = 1, but it's work properly with 0
68
- CAP_ROUND = 0
69
- CAP_FLAT = 1
70
- CAP_SQUARE = 2
66
+ CAP_ROUND = 1
67
+ CAP_FLAT = 2
68
+ CAP_SQUARE = 3
71
69
 
72
- JOIN_ROUND = 0
73
- JOIN_MITRE = 1
74
- JOIN_BEVEL = 2
70
+ JOIN_ROUND = 1
71
+ JOIN_MITRE = 2
72
+ JOIN_BEVEL = 3
75
73
  end
76
74
  end
77
75
 
@@ -297,7 +297,11 @@ module RGeo
297
297
  if (wkb_parser_ = _wkb_parser)
298
298
  wkb_parser_.parse(str_)
299
299
  else
300
- _parse_wkb_impl(str_)
300
+ if str_[0] == "\x00" || str_[0] == "\x01"
301
+ _parse_wkb_impl(str_)
302
+ else
303
+ _parse_wkb_impl([str_].pack('H*'))
304
+ end
301
305
  end
302
306
  end
303
307
 
@@ -72,6 +72,10 @@ module RGeo
72
72
  include CAPIGeometryMethods
73
73
  include CAPILineStringMethods
74
74
  include CAPILinearRingMethods
75
+
76
+ def ccw?
77
+ RGeo::Cartesian::Analysis.ccw?(self)
78
+ end
75
79
  end
76
80
 
77
81
  class CAPILineImpl # :nodoc:
@@ -266,6 +266,10 @@ module RGeo
266
266
  fg
267
267
  end
268
268
 
269
+ def point_on_surface
270
+ @factory.wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
271
+ end
272
+
269
273
  private
270
274
 
271
275
  def request_prepared
@@ -389,6 +393,10 @@ module RGeo
389
393
  def geometry_type
390
394
  Feature::LinearRing
391
395
  end
396
+
397
+ def ccw?
398
+ RGeo::Cartesian::Analysis.ccw?(self)
399
+ end
392
400
  end
393
401
 
394
402
  module FFILineMethods # :nodoc:
@@ -571,10 +579,6 @@ module RGeo
571
579
  @factory.wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
572
580
  end
573
581
 
574
- def point_on_surface
575
- @factory.wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
576
- end
577
-
578
582
  def coordinates
579
583
  each.map(&:coordinates)
580
584
  end