rgeo 2.0.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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