ffi-geos 0.5.0 → 1.0.0

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