ffi-geos 0.5.0 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21720e245fc36802f809c92b874bc75906ba6994
4
- data.tar.gz: d819af55af7872bbd1ae042ec18f0b5409db4636
3
+ metadata.gz: 6bc526266d55420dc48080bdd5e692892c7dbb2a
4
+ data.tar.gz: f7677af86f57eb3d0a9be0b8b1755b3ddc423ffb
5
5
  SHA512:
6
- metadata.gz: c2fcc8382ee2256513cd1d71e81b00883b836e9a0265d4186e00820737feeb66d34a7db798e2c386846887b27e23fc324a2a89044d954f280321e86fb63eaedd
7
- data.tar.gz: 2d32149dac875f01b70aa1604e02b07d047871981d6410989e668d5a9cef3ff487e379d726e42cb32e83237591cf70b376309256a540cae0c19e033f82a5a08f
6
+ metadata.gz: 203cff10e29ac37807026ddc9a2d70965fe368df68ca2a03ea3fa74c28f5604ac86a03e33f5430461e0d0b109194bec66036c24d32058285ce6b03a6a815b33e
7
+ data.tar.gz: 35a98846b51df19ab97ccc39f610ee442b59a5f1c423b9b58870cda443d66476dff0dccad0340909a8906da1eacb86611eabbc287412ae0456f6bdcd8d92d4c8
@@ -5,7 +5,7 @@ rvm:
5
5
  - 2.0.0
6
6
  - 1.9.3
7
7
  - 1.8.7
8
- - rbx
8
+ - rbx-2
9
9
  before_install:
10
10
  - sudo apt-get update
11
11
  - sudo apt-get install libgeos-dev
@@ -9,10 +9,10 @@
9
9
 
10
10
  Ruby versions known to work:
11
11
 
12
- * Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0.0 x86_64, OSX 10.6.5+
13
- * Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0.0 i386, linux
14
- * Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0.0 x86_64, linux
15
- * JRuby 1.6, x86_64 OSX 10.6.5+
12
+ * Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0+ x86_64, OSX 10.6.5+
13
+ * Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0+ i386, linux
14
+ * Ruby MRI 1.8.7, 1.9.2, 1.9.3, 2.0+ x86_64, linux
15
+ * JRuby 1.6+, x86_64 OSX 10.6.5+
16
16
 
17
17
  === JRuby Notes
18
18
 
@@ -67,102 +67,16 @@ Ruby bindings along with the following enhancements and additions:
67
67
  copying in either a lenient or a strict sort of manner. See the documentation
68
68
  for Geos.srid_copy_policy= for details.
69
69
 
70
- === Geos
71
-
72
- * Many new Geos.create_* methods, such as Geos.create_linear_ring, etc.
73
-
74
- * Geos.srid_copy_policy, srid_copy_policy=, srid_copy_policy_default and
75
- srid_copy_policy_default=.
76
-
77
- === Geos::Geometry
78
-
79
- * Geos::almost_equals?
80
- * Geos::coord_seq
81
- * Geos::covered_by?
82
- * Geos::covers?
83
- * Geos::delaunay_triangulation
84
- * Geos::end_point
85
- * Geos::eql_almost?
86
- * Geos::equals?
87
- * Geos::equals_almost?
88
- * Geos::equals_exact?
89
- * Geos::exactly_equals?
90
- * Geos::extract_unique_points - Geos::Geometry#unique_points
91
- * Geos::hausdorff_distance
92
- * Geos::interpolate
93
- * Geos::interpolate_normalized
94
- * Geos::nearest_points
95
- * Geos::node
96
- * Geos::normalize!
97
- * Geos::num_coordinates
98
- * Geos::polygonize
99
- * Geos::polygonize_cut_edges
100
- * Geos::polygonize_full
101
- * Geos::project
102
- * Geos::project_normalized
103
- * Geos::relate_boundary_node_rule
104
- * Geos::representative_point
105
- * Geos::shared_paths
106
- * Geos::snap
107
- * Geos::snap_to
108
- * Geos::start_point
109
- * Geos::symmetric_difference
110
- * Geos::to_prepared
111
- * Geos::unary_union
112
- * Geos::union_cascaded - Geos::Geometry#union can also be called
113
- without a geometry argument to produce the same effect.
114
- * Geos::unique_points - Geos::Geometry#extract_unique_points
115
- * Geos::valid_detail
116
- * Geos::valid_reason
117
-
118
- === Geos::LineString and Geos::LinearRing
119
-
120
- * Geos::LineString#[]
121
- * Geos::LineString#closed?
122
- * Geos::LineString#each
123
- * Geos::LineString#num_points
124
- * Geos::LineString#offset_curve
125
- * Geos::LineString#point_n
126
- * Geos::LineString#slice
127
- * Geos::LinearRing#to_line_string
128
- * Geos::LinearRing#to_polygon
129
-
130
- === Geos::WktWriter
131
-
132
- * Geos::WktWriter#old_3d
133
- * Geos::WktWriter#old_3d=
134
- * Geos::WktWriter#output_dimensions
135
- * Geos::WktWriter#output_dimensions=
136
- * Geos::WktWriter#rounding_precision
137
- * Geos::WktWriter#rounding_precision=
138
- * Geos::WktWriter#trim
139
- * Geos::WktWriter#trim=
140
-
141
- === Geos::CoordinateSequence
142
-
143
- * Geos::CoordinateSequence#has_z?
144
- * Geos::CoordinateSequence#to_line_string
145
- * Geos::CoordinateSequence#to_linear_ring
146
- * Geos::CoordinateSequence#to_point
147
- * Geos::CoordinateSequence#to_polygon
148
-
149
- === Geos::Polygon
150
-
151
- * Geos::Polygon#interior_ring
152
- * Geos::Polygon#interior_rings
153
-
154
- === Geos::Utils
155
-
156
- * Geos::Utils.orientation_index
157
- * Geos::Utils.relate_match
158
-
159
- === Geos::Interrupt
160
-
161
- * Geos::Interrupt.available?
162
- * Geos::Interrupt.register
163
- * Geos::Interrupt.request
164
- * Geos::Interrupt.cancel
165
- * Geos::Interrupt.clear
70
+ * There are many, many new methods added all over the place. Pretty much the
71
+ entire GEOS C API is represented in ffi-geos along with all sorts of useful
72
+ convenience methods and geometry conversion and manipulation methods.
73
+
74
+ * *NEW IN ffi-geos 1.0.0* -- all errors thrown by ffi-geos are now instances of
75
+ `Geos::Error` or subclasses thereof. `Geos::Error` itself is a descendant
76
+ of `RuntimeError` as is the case with the native Geos extension. This means
77
+ that code like `rescue RuntimeError` should still work but you can now
78
+ further capture more precise error types by capturing errors like
79
+ `Geos::Error`, `Geos::ParseError`, etc.
166
80
 
167
81
  == Thanks
168
82
 
@@ -1023,7 +1023,7 @@ module Geos
1023
1023
  end
1024
1024
 
1025
1025
  def error_handler(*args)
1026
- raise RuntimeError.new(args[0] % args[1])
1026
+ raise Geos::GEOSException.new(args[0] % args[1])
1027
1027
  end
1028
1028
  end
1029
1029
 
@@ -1110,7 +1110,7 @@ module Geos
1110
1110
  create_empty_collection
1111
1111
  create_empty_linear_ring
1112
1112
  }.each do |m|
1113
- self.class_eval <<-EOF
1113
+ self.class_eval(<<-EOF, __FILE__, __LINE__ + 1)
1114
1114
  def #{m}(*args)
1115
1115
  Geos::Utils.#{m}(*args)
1116
1116
  end
@@ -1178,12 +1178,27 @@ module Geos
1178
1178
  ].freeze
1179
1179
  end
1180
1180
 
1181
- class MixedSRIDsError < RuntimeError
1181
+ class Error < ::RuntimeError
1182
+ end
1183
+
1184
+ class GEOSException < Error
1185
+ end
1186
+
1187
+ class IndexBoundsError < Error
1188
+ def initialize(*)
1189
+ super("Index out of bounds")
1190
+ end
1191
+ end
1192
+
1193
+ class MixedSRIDsError < Error
1182
1194
  def initialize(srid_a, srid_b)
1183
1195
  super("Operation on mixed SRIDs (#{srid_a} vs. #{srid_b})")
1184
1196
  end
1185
1197
  end
1186
1198
 
1199
+ class ParseError < Error
1200
+ end
1201
+
1187
1202
  include GeomTypes
1188
1203
  include VersionConstants
1189
1204
  end
@@ -4,7 +4,7 @@ module Geos
4
4
 
5
5
  # A CoordinateSequence is a list of coordinates in a Geometry.
6
6
  class CoordinateSequence
7
- class ParseError < ArgumentError
7
+ class ParseError < Geos::ParseError
8
8
  end
9
9
 
10
10
  class CoordinateAccessor
@@ -262,7 +262,7 @@ module Geos
262
262
 
263
263
  def check_bounds(idx) #:nodoc:
264
264
  if idx < 0 || idx >= self.length
265
- raise RuntimeError.new("Index out of bounds")
265
+ raise Geos::IndexBoundsError.new("Index out of bounds")
266
266
  end
267
267
  end
268
268
 
@@ -6,6 +6,12 @@ module Geos
6
6
 
7
7
  attr_reader :ptr
8
8
 
9
+ class CouldntNormalizeError < Geos::Error
10
+ def initialize(klass)
11
+ super("Couldn't normalize #{klass}")
12
+ end
13
+ end
14
+
9
15
  # For internal use. Geometry objects should be created via WkbReader,
10
16
  # WktReader and the various Geos.create_* methods.
11
17
  def initialize(ptr, options = {})
@@ -48,7 +54,7 @@ module Geos
48
54
 
49
55
  def normalize!
50
56
  if FFIGeos.GEOSNormalize_r(Geos.current_handle, self.ptr) == -1
51
- raise RuntimeError.new("Couldn't normalize #{self.class}")
57
+ raise Geos::Geometry::CouldntNormalizeError.new(self.class)
52
58
  end
53
59
 
54
60
  self
@@ -12,10 +12,10 @@ module Geos
12
12
  # Registers an interrupt method or block that may be called during
13
13
  # certain operations such as Geos::Geometry#buffer. During these
14
14
  # blocks you can interrupt the current operation using
15
- # Geos.request_interrupt and cancel that interrupt request using
16
- # Geos.clear_interrupt.
15
+ # Geos::Interrupt.request and cancel that interrupt request using
16
+ # Geos::Interrupt.clear.
17
17
  #
18
- # The return value for Geos.register_interrupt is a reference to the
18
+ # The return value for Geos::Interrupt.register is a reference to the
19
19
  # previously registered callback, allowing you to chain interrupt
20
20
  # calls together by calling #call on the previously registered callback.
21
21
  #
@@ -25,9 +25,9 @@ module Geos
25
25
  # up in unexpected ways while interrupts are firing.
26
26
  def register(method_or_block = nil, &block)
27
27
  if method_or_block.nil? && !block_given?
28
- raise ArgumentError.new("Expected either a method or a block for Geos.register_interrupt")
28
+ raise ArgumentError.new("Expected either a method or a block for Geos::Interrupt.register")
29
29
  elsif !method_or_block.nil? && block_given?
30
- raise ArgumentError.new("Cannot use both a method and a block for Geos.register_interrupt")
30
+ raise ArgumentError.new("Cannot use both a method and a block for Geos::Interrupt.register")
31
31
  else
32
32
  retval = @current_interrupt_callback
33
33
 
@@ -44,7 +44,7 @@ module Geos
44
44
  end
45
45
 
46
46
  # Interrupt the current operation. This method should generally be
47
- # called from within a callback registered with Geos.register_interrupt
47
+ # called from within a callback registered with Geos::Interrupt.register
48
48
  # but can be called at any time to interrupt the next interruptable
49
49
  # operation.
50
50
  def request
@@ -53,7 +53,7 @@ module Geos
53
53
 
54
54
  # Cancel a request to interrupt the current operation. This method
55
55
  # should be called from within a callback registered with
56
- # Geos.register_interrupt but can be called at any time all the same.
56
+ # Geos::Interrupt.register but can be called at any time all the same.
57
57
  def cancel
58
58
  FFIGeos.GEOS_interruptCancel
59
59
  end
@@ -29,7 +29,7 @@ module Geos
29
29
 
30
30
  def point_n(n)
31
31
  if n < 0 || n >= self.num_points
32
- raise RuntimeError.new("Index out of bounds")
32
+ raise Geos::IndexBoundsError.new
33
33
  else
34
34
  cast_geometry_ptr(
35
35
  FFIGeos.GEOSGeomGetPointN_r(Geos.current_handle, self.ptr, n), {
@@ -68,5 +68,20 @@ module Geos
68
68
  bool_result(FFIGeos.GEOSisClosed_r(Geos.current_handle, self.ptr))
69
69
  end
70
70
  end
71
+
72
+ def to_linear_ring
73
+ if self.closed?
74
+ Geos.create_linear_ring(self.coord_seq, :srid => pick_srid_according_to_policy(self.srid))
75
+ else
76
+ self_cs = self.coord_seq.to_a
77
+ self_cs.push(self_cs[0])
78
+
79
+ Geos.create_linear_ring(self_cs, :srid => pick_srid_according_to_policy(self.srid))
80
+ end
81
+ end
82
+
83
+ def to_polygon
84
+ self.to_linear_ring.to_polygon
85
+ end
71
86
  end
72
87
  end
@@ -69,7 +69,7 @@ module Geos
69
69
  envelope
70
70
  topology_preserve_simplify
71
71
  }.each do |method|
72
- self.class_eval(<<-EOF)
72
+ self.class_eval(<<-EOF, __FILE__, __LINE__ + 1)
73
73
  def #{method}(*args)
74
74
  self.dup.tap { |ret|
75
75
  ret.srid = pick_srid_according_to_policy(ret.srid)
@@ -8,7 +8,7 @@ module Geos
8
8
 
9
9
  def interior_ring_n(n)
10
10
  if n < 0 || n >= self.num_interior_rings
11
- raise RuntimeError.new("Index out of bounds")
11
+ raise Geos::IndexBoundsError.new
12
12
  else
13
13
  cast_geometry_ptr(
14
14
  FFIGeos.GEOSGetInteriorRingN_r(Geos.current_handle, self.ptr, n), {
@@ -9,6 +9,12 @@ module Geos
9
9
 
10
10
  undef :clone, :dup
11
11
 
12
+ class AlreadyBuiltError < Geos::Error
13
+ def initialize(*)
14
+ super("STRtree has already been built")
15
+ end
16
+ end
17
+
12
18
  # :call-seq:
13
19
  # new(capacity)
14
20
  # new(geoms_and_objects)
@@ -71,7 +77,7 @@ module Geos
71
77
 
72
78
  def insert(geom, item)
73
79
  if self.built?
74
- raise RuntimeError.new("STRtree has already been built")
80
+ raise AlreadyBuiltError.new
75
81
  else
76
82
  check_geometry(geom)
77
83
 
@@ -1,6 +1,24 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Geos
4
+ class NullPointerError < Geos::Error
5
+ def initialize(*)
6
+ super("Tried to create a Geometry from a NULL pointer!")
7
+ end
8
+ end
9
+
10
+ class InvalidGeometryTypeError < Geos::Error
11
+ def initialize(*)
12
+ super("Invalid geometry type")
13
+ end
14
+ end
15
+
16
+ class UnexpectedBooleanResultError < Geos::Error
17
+ def initialize(result)
18
+ super("Unexpected boolean result: #{result}")
19
+ end
20
+ end
21
+
4
22
  module Tools
5
23
  include GeomTypes
6
24
 
@@ -10,7 +28,7 @@ module Geos
10
28
  }.merge(options)
11
29
 
12
30
  if geom_ptr.null?
13
- raise RuntimeError.new("Tried to create a Geometry from a NULL pointer!")
31
+ raise Geos::NullPointerError.new
14
32
  end
15
33
 
16
34
  klass = case FFIGeos.GEOSGeomTypeId_r(Geos.current_handle, geom_ptr)
@@ -31,7 +49,7 @@ module Geos
31
49
  when GEOS_GEOMETRYCOLLECTION
32
50
  GeometryCollection
33
51
  else
34
- raise RuntimeError.new("Invalid geometry type")
52
+ raise Geos::InvalidGeometryTypeError.new
35
53
  end
36
54
 
37
55
  klass.new(geom_ptr, options).tap { |ret|
@@ -76,14 +94,14 @@ module Geos
76
94
  end
77
95
  end
78
96
 
79
- def bool_result(r)
80
- case r
97
+ def bool_result(result)
98
+ case result
81
99
  when 1
82
100
  true
83
101
  when 0
84
102
  false
85
103
  else
86
- raise RuntimeError.new("Unexpected boolean result: #{r}")
104
+ raise Geos::UnexpectedBooleanResultError.new(result)
87
105
  end
88
106
  end
89
107
 
@@ -100,6 +118,14 @@ module Geos
100
118
  end
101
119
  end
102
120
 
121
+ def extract_options!(args)
122
+ if args.last.is_a?(Hash)
123
+ args.pop
124
+ else
125
+ {}
126
+ end
127
+ end
128
+
103
129
  class << self
104
130
  include Geos::Tools
105
131
  end
@@ -28,11 +28,7 @@ module Geos
28
28
  end
29
29
 
30
30
  def create_point(*args)
31
- options = if args.last.is_a?(Hash)
32
- args.pop
33
- else
34
- {}
35
- end
31
+ options = extract_options!(args)
36
32
 
37
33
  if args.length == 1
38
34
  cs = args.first
@@ -47,7 +43,7 @@ module Geos
47
43
  end
48
44
 
49
45
  if cs.length != 1
50
- raise RuntimeError.new("IllegalArgumentException: Point coordinate list must contain a single element")
46
+ raise ArgumentError.new("IllegalArgumentException: Point coordinate list must contain a single element")
51
47
  end
52
48
 
53
49
  cs_dup = cs.dup
@@ -62,7 +58,7 @@ module Geos
62
58
  cs = cs_from_cs_or_geom(cs)
63
59
 
64
60
  if cs.length <= 1 && cs.length != 0
65
- raise RuntimeError.new("IllegalArgumentException: point array must contain 0 or >1 elements")
61
+ raise ArgumentError.new("IllegalArgumentException: point array must contain 0 or >1 elements")
66
62
  end
67
63
 
68
64
  cs_dup = cs.dup
@@ -77,7 +73,7 @@ module Geos
77
73
  cs = cs_from_cs_or_geom(cs)
78
74
 
79
75
  if cs.length <= 1 && cs.length != 0
80
- raise RuntimeError.new("IllegalArgumentException: point array must contain 0 or >1 elements")
76
+ raise ArgumentError.new("IllegalArgumentException: point array must contain 0 or >1 elements")
81
77
  end
82
78
 
83
79
  cs.ptr.autorelease = false
@@ -88,11 +84,7 @@ module Geos
88
84
  end
89
85
 
90
86
  def create_polygon(outer, *args)
91
- options = if args.last.is_a?(Hash)
92
- args.pop
93
- else
94
- {}
95
- end
87
+ options = extract_options!(args)
96
88
 
97
89
  inner_dups = Array(args).flatten.collect { |i|
98
90
  force_to_linear_ring(i) or
@@ -174,11 +166,7 @@ module Geos
174
166
  Geos::Geometry
175
167
  end
176
168
 
177
- options = if args.last.is_a?(Hash)
178
- args.pop
179
- else
180
- {}
181
- end
169
+ options = extract_options!(args)
182
170
 
183
171
  geoms = Array(args).flatten.tap { |i|
184
172
  if i.detect { |g| !g.is_a?(klass) }