ffi-gdal 1.0.0.beta5 → 1.0.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -3
  3. data/.rubocop.yml +7 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +1 -1
  6. data/History.md +143 -1
  7. data/README.md +5 -11
  8. data/Rakefile +2 -60
  9. data/TODO.md +10 -0
  10. data/examples/geometries.rb +4 -6
  11. data/examples/gridding.rb +99 -98
  12. data/examples/ogr_layer_to_layer.rb +0 -2
  13. data/examples/raster_erasing.rb +47 -0
  14. data/examples/remove_small_polygons.rb +62 -0
  15. data/examples/testing_gdal.rb +0 -3
  16. data/examples/warping.rb +140 -0
  17. data/ffi-gdal.gemspec +5 -2
  18. data/lib/ext/error_symbols.rb +1 -1
  19. data/lib/ext/ffi_library_function_checks.rb +3 -2
  20. data/lib/ext/float_ext.rb +2 -2
  21. data/lib/ext/narray_ext.rb +1 -1
  22. data/lib/ext/numeric_as_data_type.rb +1 -1
  23. data/lib/ext/to_bool.rb +2 -2
  24. data/lib/ffi/cpl/conv.rb +1 -3
  25. data/lib/ffi/cpl/error.rb +0 -3
  26. data/lib/ffi/cpl/minixml.rb +17 -21
  27. data/lib/ffi/cpl/progress.rb +27 -0
  28. data/lib/ffi/cpl/string.rb +0 -8
  29. data/lib/ffi/cpl/vsi.rb +0 -1
  30. data/lib/ffi/cpl/xml_node.rb +0 -1
  31. data/lib/ffi/cpl.rb +15 -0
  32. data/lib/ffi/gdal/alg.rb +72 -54
  33. data/lib/ffi/gdal/gdal.rb +669 -672
  34. data/lib/ffi/gdal/grid.rb +141 -24
  35. data/lib/ffi/gdal/grid_data_metrics_options.rb +1 -1
  36. data/lib/ffi/gdal/grid_moving_average_options.rb +1 -1
  37. data/lib/ffi/gdal/matching.rb +0 -2
  38. data/lib/ffi/gdal/transformer_info.rb +1 -1
  39. data/lib/ffi/gdal/version.rb +1 -1
  40. data/lib/ffi/gdal/vrt.rb +0 -2
  41. data/lib/ffi/gdal/warp_options.rb +12 -14
  42. data/lib/ffi/gdal/warper.rb +61 -6
  43. data/lib/ffi/gdal.rb +18 -3
  44. data/lib/ffi/ogr/api.rb +10 -21
  45. data/lib/ffi/ogr/core.rb +9 -12
  46. data/lib/ffi/ogr/featurestyle.rb +0 -5
  47. data/lib/ffi/ogr/geocoding.rb +0 -1
  48. data/lib/ffi/ogr/srs_api.rb +0 -4
  49. data/lib/ffi/ogr/style_value.rb +1 -2
  50. data/lib/ffi/ogr.rb +15 -12
  51. data/lib/ffi-gdal.rb +5 -3
  52. data/lib/gdal/color_entry.rb +1 -0
  53. data/lib/gdal/color_interpretation.rb +2 -2
  54. data/lib/gdal/color_table.rb +14 -14
  55. data/lib/gdal/color_table_mixins/extensions.rb +4 -4
  56. data/lib/gdal/cpl_error_handler.rb +12 -14
  57. data/lib/gdal/data_type.rb +13 -12
  58. data/lib/gdal/dataset.rb +170 -94
  59. data/lib/gdal/dataset_mixins/algorithm_methods.rb +47 -21
  60. data/lib/gdal/dataset_mixins/extensions.rb +32 -61
  61. data/lib/gdal/dataset_mixins/matching.rb +0 -2
  62. data/lib/gdal/dataset_mixins/warp_methods.rb +42 -0
  63. data/lib/gdal/driver.rb +62 -47
  64. data/lib/gdal/driver_mixins/extensions.rb +2 -7
  65. data/lib/gdal/environment_methods.rb +13 -10
  66. data/lib/gdal/exceptions.rb +24 -2
  67. data/lib/gdal/geo_transform.rb +10 -16
  68. data/lib/gdal/geo_transform_mixins/extensions.rb +58 -3
  69. data/lib/gdal/grid.rb +62 -109
  70. data/lib/gdal/{grid_types → grid_algorithms}/data_metrics_base.rb +1 -3
  71. data/lib/gdal/{grid_types → grid_algorithms}/inverse_distance_to_a_power.rb +2 -4
  72. data/lib/gdal/{grid_types → grid_algorithms}/metric_average_distance.rb +2 -2
  73. data/lib/gdal/{grid_types → grid_algorithms}/metric_average_distance_pts.rb +2 -2
  74. data/lib/gdal/{grid_types → grid_algorithms}/metric_count.rb +2 -2
  75. data/lib/gdal/{grid_types → grid_algorithms}/metric_maximum.rb +2 -2
  76. data/lib/gdal/{grid_types → grid_algorithms}/metric_minimum.rb +2 -2
  77. data/lib/gdal/{grid_types → grid_algorithms}/metric_range.rb +2 -2
  78. data/lib/gdal/{grid_types → grid_algorithms}/moving_average.rb +2 -4
  79. data/lib/gdal/{grid_types → grid_algorithms}/nearest_neighbor.rb +2 -4
  80. data/lib/gdal/grid_algorithms.rb +22 -0
  81. data/lib/gdal/gridder/point_extracting.rb +89 -0
  82. data/lib/gdal/gridder.rb +294 -0
  83. data/lib/gdal/gridder_options.rb +273 -0
  84. data/lib/gdal/internal_helpers.rb +132 -23
  85. data/lib/gdal/major_object.rb +13 -10
  86. data/lib/gdal/merger.rb +130 -0
  87. data/lib/gdal/options.rb +3 -2
  88. data/lib/gdal/raster_attribute_table.rb +74 -51
  89. data/lib/gdal/raster_attribute_table_mixins/extensions.rb +21 -3
  90. data/lib/gdal/raster_band.rb +139 -167
  91. data/lib/gdal/raster_band_classifier.rb +19 -18
  92. data/lib/gdal/raster_band_mixins/algorithm_extensions.rb +107 -0
  93. data/lib/gdal/raster_band_mixins/algorithm_methods.rb +79 -40
  94. data/lib/gdal/raster_band_mixins/coloring_extensions.rb +84 -0
  95. data/lib/gdal/raster_band_mixins/extensions.rb +34 -169
  96. data/lib/gdal/raster_band_mixins/io_extensions.rb +180 -0
  97. data/lib/gdal/rpc_info.rb +1 -2
  98. data/lib/gdal/transformer.rb +1 -6
  99. data/lib/gdal/transformers/approximate_transformer.rb +0 -4
  100. data/lib/gdal/transformers/base_general_image_projection_transformer.rb +0 -6
  101. data/lib/gdal/transformers/gcp_transformer.rb +2 -6
  102. data/lib/gdal/transformers/general_image_projection_transformer.rb +8 -7
  103. data/lib/gdal/transformers/general_image_projection_transformer2.rb +1 -1
  104. data/lib/gdal/transformers/geolocation_transformer.rb +0 -4
  105. data/lib/gdal/transformers/reprojection_transformer.rb +0 -8
  106. data/lib/gdal/transformers/rpc_transformer.rb +0 -4
  107. data/lib/gdal/transformers/tps_transformer.rb +1 -3
  108. data/lib/gdal/version_info.rb +7 -8
  109. data/lib/gdal/virtual_dataset.rb +2 -4
  110. data/lib/gdal/warp_operation.rb +17 -14
  111. data/lib/gdal/warp_options.rb +132 -0
  112. data/lib/gdal.rb +41 -2
  113. data/lib/ogr/coordinate_transformation.rb +79 -32
  114. data/lib/ogr/data_source.rb +17 -14
  115. data/lib/ogr/data_source_extensions.rb +1 -5
  116. data/lib/ogr/driver.rb +11 -14
  117. data/lib/ogr/envelope.rb +1 -1
  118. data/lib/ogr/envelope_extensions.rb +23 -6
  119. data/lib/ogr/error_handling.rb +3 -3
  120. data/lib/ogr/exceptions.rb +6 -0
  121. data/lib/ogr/feature.rb +25 -38
  122. data/lib/ogr/feature_definition.rb +6 -8
  123. data/lib/ogr/feature_definition_extensions.rb +2 -6
  124. data/lib/ogr/feature_extensions.rb +71 -41
  125. data/lib/ogr/field.rb +16 -15
  126. data/lib/ogr/field_definition.rb +4 -4
  127. data/lib/ogr/geocoder.rb +5 -5
  128. data/lib/ogr/geometries/geometry_collection.rb +4 -1
  129. data/lib/ogr/geometries/geometry_collection_25d.rb +12 -0
  130. data/lib/ogr/geometries/line_string.rb +30 -8
  131. data/lib/ogr/geometries/line_string_25d.rb +21 -0
  132. data/lib/ogr/geometries/linear_ring.rb +10 -1
  133. data/lib/ogr/geometries/multi_line_string.rb +2 -1
  134. data/lib/ogr/geometries/multi_line_string_25d.rb +13 -0
  135. data/lib/ogr/geometries/multi_point.rb +2 -1
  136. data/lib/ogr/geometries/multi_point_25d.rb +14 -0
  137. data/lib/ogr/geometries/multi_polygon.rb +3 -2
  138. data/lib/ogr/geometries/multi_polygon_25d.rb +13 -0
  139. data/lib/ogr/geometries/point.rb +20 -23
  140. data/lib/ogr/geometries/point_25d.rb +48 -0
  141. data/lib/ogr/geometries/polygon.rb +4 -1
  142. data/lib/ogr/geometries/polygon_25d.rb +14 -0
  143. data/lib/ogr/geometry.rb +125 -93
  144. data/lib/ogr/geometry_field_definition.rb +7 -5
  145. data/lib/ogr/geometry_mixins/container_mixins.rb +23 -0
  146. data/lib/ogr/geometry_mixins/extensions.rb +111 -0
  147. data/lib/ogr/geometry_types/container.rb +10 -3
  148. data/lib/ogr/geometry_types/curve.rb +68 -23
  149. data/lib/ogr/geometry_types/surface.rb +0 -9
  150. data/lib/ogr/internal_helpers.rb +3 -3
  151. data/lib/ogr/layer.rb +4 -5
  152. data/lib/ogr/layer_mixins/extensions.rb +242 -17
  153. data/lib/ogr/layer_mixins/ogr_feature_methods.rb +11 -11
  154. data/lib/ogr/layer_mixins/ogr_field_methods.rb +6 -11
  155. data/lib/ogr/layer_mixins/ogr_layer_method_methods.rb +18 -18
  156. data/lib/ogr/layer_mixins/ogr_query_filter_methods.rb +0 -2
  157. data/lib/ogr/layer_mixins/ogr_sql_methods.rb +1 -1
  158. data/lib/ogr/spatial_reference.rb +12 -37
  159. data/lib/ogr/spatial_reference_mixins/coordinate_system_getter_setters.rb +53 -55
  160. data/lib/ogr/spatial_reference_mixins/exporters.rb +18 -49
  161. data/lib/ogr/spatial_reference_mixins/parameter_getter_setters.rb +10 -29
  162. data/lib/ogr/style_table.rb +2 -2
  163. data/lib/ogr/style_table_extensions.rb +3 -1
  164. data/lib/ogr/style_tool.rb +8 -14
  165. data/lib/ogr.rb +39 -1
  166. data/spec/ffi-gdal_spec.rb +18 -1
  167. data/spec/integration/gdal/color_table_info_spec.rb +49 -33
  168. data/spec/integration/gdal/dataset_info_spec.rb +294 -45
  169. data/spec/integration/gdal/driver_info_spec.rb +139 -31
  170. data/spec/integration/gdal/geo_transform_info_spec.rb +197 -26
  171. data/spec/integration/gdal/gridder_spec.rb +329 -0
  172. data/spec/integration/gdal/raster_attribute_table_info_spec.rb +216 -11
  173. data/spec/integration/gdal/raster_band_algorithms_spec.rb +33 -0
  174. data/spec/integration/gdal/raster_band_info_spec.rb +240 -271
  175. data/spec/integration/ogr/layer_spec.rb +3 -1
  176. data/spec/spec_helper.rb +15 -6
  177. data/spec/support/images/osgeo/gdal/data/hfa/float-rle.img +0 -0
  178. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.lgo +31 -0
  179. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.tif +0 -0
  180. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.tif.msk +0 -0
  181. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.txt +10 -0
  182. data/spec/support/images/osgeo/geotiff/gdal_eg/cea.tif +0 -0
  183. data/spec/support/images/osgeo/geotiff/gdal_eg/cea.txt +84 -0
  184. data/spec/support/images/osgeo/geotiff/zi_imaging/image0.lgo +45 -0
  185. data/spec/support/images/osgeo/geotiff/zi_imaging/image0.tif +0 -0
  186. data/spec/support/integration_help.rb +32 -2
  187. data/spec/support/shared_examples/gdal/major_object_examples.rb +0 -6
  188. data/spec/support/shared_examples/ogr/a_geometry.rb +1 -1
  189. data/spec/unit/ffi/gdal_spec.rb +1 -1
  190. data/spec/unit/gdal/color_entry_spec.rb +1 -0
  191. data/spec/unit/gdal/color_interpretation_spec.rb +1 -0
  192. data/spec/unit/gdal/dataset_spec.rb +53 -2
  193. data/spec/unit/gdal/geo_transform_mixins/extensions_spec.rb +67 -0
  194. data/spec/unit/gdal/geo_transform_spec.rb +1 -1
  195. data/spec/unit/gdal/grid_spec.rb +83 -0
  196. data/spec/unit/gdal/gridder/point_extracting_spec.rb +99 -0
  197. data/spec/unit/gdal/gridder_options_spec.rb +183 -0
  198. data/spec/unit/gdal/gridder_spec.rb +140 -0
  199. data/spec/unit/gdal/internal_helpers_spec.rb +166 -2
  200. data/spec/unit/gdal/major_object_spec.rb +2 -0
  201. data/spec/unit/gdal/options_spec.rb +1 -0
  202. data/spec/unit/gdal/raster_band_classifier_spec.rb +70 -12
  203. data/spec/unit/gdal/raster_band_mixins/extensions_spec.rb +71 -0
  204. data/spec/unit/gdal/raster_band_mixins/io_extensions_spec.rb +133 -0
  205. data/spec/unit/gdal/raster_band_spec.rb +1 -0
  206. data/spec/unit/gdal/rpc_info_spec.rb +1 -0
  207. data/spec/unit/gdal/version_info_spec.rb +2 -0
  208. data/spec/unit/gdal/warp_operation_spec.rb +1 -0
  209. data/spec/unit/ogr/coordinate_transformation_spec.rb +102 -0
  210. data/spec/unit/ogr/data_source_spec.rb +12 -0
  211. data/spec/unit/ogr/feature_extensions_spec.rb +88 -0
  212. data/spec/unit/ogr/feature_spec.rb +30 -46
  213. data/spec/unit/ogr/geometries/geometry_collection_25d_spec.rb +23 -0
  214. data/spec/unit/ogr/geometries/geometry_collection_spec.rb +3 -3
  215. data/spec/unit/ogr/geometries/line_string_25d_spec.rb +23 -0
  216. data/spec/unit/ogr/geometries/line_string_spec.rb +2 -2
  217. data/spec/unit/ogr/geometries/linear_ring_spec.rb +2 -2
  218. data/spec/unit/ogr/geometries/multi_line_string_25d_spec.rb +23 -0
  219. data/spec/unit/ogr/geometries/multi_point_25d_spec.rb +23 -0
  220. data/spec/unit/ogr/geometries/multi_polygon_25d_spec.rb +23 -0
  221. data/spec/unit/ogr/geometries/point_25d_spec.rb +23 -0
  222. data/spec/unit/ogr/geometries/point_spec.rb +14 -24
  223. data/spec/unit/ogr/geometries/polygon_25d_spec.rb +23 -0
  224. data/spec/unit/ogr/geometries/polygon_spec.rb +1 -1
  225. data/spec/unit/ogr/geometry_field_definition_spec.rb +1 -1
  226. data/spec/unit/ogr/geometry_spec.rb +196 -30
  227. data/spec/unit/ogr/internal_helpers_spec.rb +20 -9
  228. data/spec/unit/ogr/layer_mixins/ogr_feature_methods_spec.rb +14 -6
  229. data/spec/unit/ogr/spatial_reference_mixins/exporters_spec.rb +9 -1
  230. data/spec/unit/ogr/spatial_reference_mixins/parameter_getter_setters_spec.rb +2 -1
  231. data/spec/unit/ogr/style_table_spec.rb +1 -1
  232. data/tmp/.keep +0 -0
  233. metadata +121 -19
  234. data/examples/points.txt +0 -127
  235. data/lib/gdal/grid_types.rb +0 -22
  236. data/lib/ogr/geometries/point_extensions.rb +0 -32
  237. data/lib/ogr/geometry_extensions.rb +0 -59
@@ -35,6 +35,9 @@ module OGR
35
35
  class InvalidFieldDefinition < StandardError
36
36
  end
37
37
 
38
+ class InvalidFieldName < StandardError
39
+ end
40
+
38
41
  class InvalidGeometry < StandardError
39
42
  end
40
43
 
@@ -70,6 +73,9 @@ module OGR
70
73
  end
71
74
  end
72
75
 
76
+ class UnsupportedFieldType < StandardError
77
+ end
78
+
73
79
  class UnsupportedGeometryType < StandardError
74
80
  end
75
81
 
data/lib/ogr/feature.rb CHANGED
@@ -1,8 +1,7 @@
1
- require_relative '../ffi/ogr'
2
- require_relative 'feature_extensions'
3
- require_relative 'feature_definition'
4
- require_relative 'field_definition'
5
1
  require 'date'
2
+ require_relative '../ogr'
3
+ require_relative '../gdal'
4
+ require_relative 'feature_extensions'
6
5
 
7
6
  module OGR
8
7
  class Feature
@@ -19,14 +18,11 @@ module OGR
19
18
  FFI::OGR::API.OGR_F_Create(fd_or_pointer.c_pointer)
20
19
  else
21
20
  fd_or_pointer
22
- end
21
+ end
23
22
 
24
23
  if !@c_pointer.is_a?(FFI::Pointer) || @c_pointer.null?
25
- fail OGR::InvalidFeature, "Unable to create Feature with #{fd_or_pointer}"
24
+ raise OGR::InvalidFeature, "Unable to create Feature with #{fd_or_pointer}"
26
25
  end
27
-
28
- close_me = -> { destroy! }
29
- ObjectSpace.define_finalizer self, close_me
30
26
  end
31
27
 
32
28
  def destroy!
@@ -40,16 +36,18 @@ module OGR
40
36
  # @raise [OGR::Failure] If, for some reason, the clone fails.
41
37
  def clone
42
38
  feature_ptr = FFI::OGR::API.OGR_F_Clone(@c_pointer)
43
- fail OGR::Failure, 'Unable to clone feature' if feature_ptr.nil?
39
+ raise OGR::Failure, 'Unable to clone feature' if feature_ptr.nil?
44
40
 
45
41
  OGR::Feature.new(feature_ptr)
46
42
  end
47
43
 
48
44
  # Dumps the feature out to the file in human-readable form.
49
45
  #
50
- # @param file_name [String]
51
- def dump_readable(file_name)
52
- FFI::OGR::API.OGR_F_DumpReadable(@c_pointer, file_name)
46
+ # @param file_path [String]
47
+ def dump_readable(file_path = nil)
48
+ file_ptr = file_path ? FFI::CPL::Conv.CPLOpenShared(file_path, 'w', false) : nil
49
+ FFI::OGR::API.OGR_F_DumpReadable(@c_pointer, file_ptr)
50
+ FFI::CPL::Conv.CPLCloseShared(file_ptr) if file_ptr
53
51
  end
54
52
 
55
53
  # Overwrites the contents of this feature from the geometry and attributes
@@ -61,7 +59,7 @@ module OGR
61
59
  # @param with_map [Array<Fixnum>]
62
60
  # TODO: Implement +with_map+
63
61
  def set_from!(_other_feature, _be_forgiving = false, with_map: nil)
64
- fail NotImplementedError, 'with_map: is not yet supported' if with_map
62
+ raise NotImplementedError, 'with_map: is not yet supported' if with_map
65
63
 
66
64
  ogr_err = FFI::OGR::API.OGR_F_SetFrom(@c_pointer, other_feature_ptr)
67
65
 
@@ -133,23 +131,17 @@ module OGR
133
131
  end
134
132
 
135
133
  # @param index [Fixnum]
136
- # @param value [FFI::OGR::Field]
137
- def set_field_raw(index, value)
138
- raw_field_ptr = FFI::MemoryPointer.new(value)
139
- usable_raw_field = FFI::OGR::Field.new(raw_field_ptr)
140
-
141
- unless valid_raw_field?(index, usable_raw_field)
142
- fail TypeError,
143
- "Raw field is not of required field type: #{field_definition(index).type}"
144
- end
134
+ # @param field [OGR::Field]
135
+ def set_field_raw(index, field)
136
+ usable_raw_field = field.c_struct
145
137
 
146
- FFI::OGR::API.OGR_F_SetFieldRaw(@c_pointer, index, value)
138
+ FFI::OGR::API.OGR_F_SetFieldRaw(@c_pointer, index, usable_raw_field)
147
139
  end
148
140
 
149
141
  # @param index [Fixnum]
150
142
  # @param value [String]
151
143
  def set_field_binary(index, value)
152
- fail TypeError, 'value must be a binary string' unless value.is_a? String
144
+ raise TypeError, 'value must be a binary string' unless value.is_a? String
153
145
 
154
146
  value_ptr = FFI::MemoryPointer.new(:uchar, value.length)
155
147
  value_ptr.put_bytes(0, value)
@@ -232,7 +224,7 @@ module OGR
232
224
  # @return [OGR::Geometry]
233
225
  def steal_geometry
234
226
  geometry_ptr = FFI::OGR::API.OGR_F_StealGeometry(@c_pointer)
235
- fail OGR::Failure, 'Unable to steal geometry.' if geometry_ptr.nil?
227
+ raise OGR::Failure, 'Unable to steal geometry.' if geometry_ptr.nil?
236
228
 
237
229
  OGR::Geometry.factory(geometry_ptr)
238
230
  end
@@ -284,30 +276,25 @@ module OGR
284
276
  geometry_ptr = FFI::OGR::API.OGR_F_GetGeomFieldRef(@c_pointer, index)
285
277
  return nil if geometry_ptr.nil? || geometry_ptr.null?
286
278
 
287
- geometry = OGR::Geometry.factory(geometry_ptr)
288
- geometry.read_only = true
289
-
290
- geometry
279
+ OGR::Geometry.factory(geometry_ptr)
291
280
  end
292
281
 
293
282
  # @param index [Fixnum]
294
283
  # @param geometry [OGR::Geometry]
295
284
  def set_geometry_field(index, geometry)
296
285
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
297
- fail OGR::InvalidGeometry if geometry_ptr.nil?
286
+ raise OGR::InvalidGeometry if geometry_ptr.nil?
298
287
 
299
- ogr_err =
300
- # FFI::OGR::API.OGR_F_SetGeomFieldDirectly(@c_pointer, index, geometry_ptr)
301
- FFI::OGR::API.OGR_F_SetGeomField(@c_pointer, index, geometry_ptr)
288
+ ogr_err = FFI::OGR::API.OGR_F_SetGeomField(@c_pointer, index, geometry_ptr)
302
289
 
303
290
  ogr_err.handle_result
304
291
  end
305
292
 
306
293
  # @return [Boolean]
307
- def equal?(other_feature)
308
- FFI::OGR::API.OGR_F_Equal(@c_pointer, c_pointer_from(other_feature))
294
+ def equal?(other)
295
+ FFI::OGR::API.OGR_F_Equal(@c_pointer, c_pointer_from(other))
309
296
  end
310
- alias_method :equals?, :equal?
297
+ alias equals? equal?
311
298
 
312
299
  # @param index [Fixnum]
313
300
  # @return [Fixnum]
@@ -442,7 +429,7 @@ module OGR
442
429
  # @param new_style_table [OGR::StyleTable]
443
430
  def style_table=(new_style_table)
444
431
  new_style_table_ptr = GDAL._pointer(OGR::StyleTable, new_style_table)
445
- fail OGR::InvalidStyleTable unless new_style_table_ptr
432
+ raise OGR::InvalidStyleTable unless new_style_table_ptr
446
433
 
447
434
  FFI::OGR::API.OGR_F_SetStyleTableDirectly(@c_pointer, new_style_table_ptr)
448
435
  end
@@ -1,7 +1,5 @@
1
- require_relative '../ffi/ogr'
1
+ require_relative '../ogr'
2
2
  require_relative 'feature_definition_extensions'
3
- require_relative 'field_definition'
4
- require_relative 'geometry_field_definition'
5
3
 
6
4
  module OGR
7
5
  class FeatureDefinition
@@ -22,15 +20,15 @@ module OGR
22
20
  end
23
21
 
24
22
  if !@c_pointer.is_a?(FFI::Pointer) || @c_pointer.null?
25
- fail OGR::InvalidFeatureDefinition, "Unable to create #{self.class.name} from #{name_or_pointer}"
23
+ raise OGR::InvalidFeatureDefinition, "Unable to create #{self.class.name} from #{name_or_pointer}"
26
24
  end
27
-
28
- close_me = -> { FFI::OGR::API.OGR_FD_Destroy(@c_pointer) }
29
- ObjectSpace.define_finalizer self, close_me
30
25
  end
31
26
 
32
27
  def release!
28
+ return unless @c_pointer
29
+
33
30
  FFI::OGR::API.OGR_FD_Release(@c_pointer)
31
+ @c_pointer = nil
34
32
  end
35
33
 
36
34
  # @return [String]
@@ -58,7 +56,7 @@ module OGR
58
56
  field_definition_ptr = GDAL._pointer(OGR::FieldDefinition, field_definition)
59
57
 
60
58
  if field_definition_ptr.nil?
61
- fail OGR::InvalidFieldDefinition, "Unable to add OGR::FieldDefinition: '#{field_definition}'"
59
+ raise OGR::InvalidFieldDefinition, "Unable to add OGR::FieldDefinition: '#{field_definition}'"
62
60
  end
63
61
 
64
62
  FFI::OGR::API.OGR_FD_AddFieldDefn(@c_pointer, field_definition_ptr)
@@ -6,18 +6,14 @@ module OGR
6
6
  def field_definitions
7
7
  return [] if field_count.zero?
8
8
 
9
- field_count.times.map do |i|
10
- field_definition(i)
11
- end
9
+ Array.new(field_count) { |i| field_definition(i) }
12
10
  end
13
11
 
14
12
  # @return [Array<OGR::GeometryFieldDefinition>]
15
13
  def geometry_field_definitions
16
14
  return [] if geometry_field_count.zero?
17
15
 
18
- geometry_field_count.times.map do |i|
19
- geometry_field_definition(i)
20
- end
16
+ Array.new(geometry_field_count) { |i| geometry_field_definition(i) }
21
17
  end
22
18
 
23
19
  # @param name [String]
@@ -2,62 +2,92 @@ require 'json'
2
2
 
3
3
  module OGR
4
4
  module FeatureExtensions
5
+ # Retrieves the value for each field and yields it.
6
+ #
7
+ # @return [Enumerator]
8
+ # @yieldparam [Number, String, Array]
9
+ def each_field
10
+ return enum_for(:each_field) unless block_given?
11
+
12
+ field_count.times do |i|
13
+ yield field(i)
14
+ end
15
+ end
16
+
5
17
  # @return [Array] Uses each FieldDefinition to determine the field type at
6
18
  # each index and returns maps the field as that value type.
7
19
  def fields
8
- field_count.times.map do |i|
9
- case field_definition(i).type
10
- when :OFTInteger then field_as_integer(i)
11
- when :OFTIntegerList then field_as_integer_list(i)
12
- when :OFTReal then field_as_double(i)
13
- when :OFTRealList then field_as_double_list(i)
14
- when :OFTString then field_as_string(i)
15
- when :OFTStringList then field_as_string_list(i)
16
- when :OFTWideString then field_as_string(i)
17
- when :OFTWideStringList then field_as_string_list(i)
18
- when :OFTBinary then field_as_binary(i)
19
- when :OFTDate, :OFTTime, :OFTDateTime then field_as_date_time(i)
20
- when :OFTInteger64 then field_as_integer(i)
21
- when :OFTInteger64List then field_as_integer_lsit(i)
22
- when :OFTMaxType then field_as_date_time(i)
23
- else fail "not sure about field type: #{fd.type}"
24
- end
20
+ each_field.to_a
21
+ end
22
+
23
+ # Retrieves a field using +index+, but uses its type from the associated
24
+ # {OGR::FieldDefinition} to determine it's core type to return as. This
25
+ # saves from having to find out the type then call the associated
26
+ # +field_as_[type]+ method if you just want the data in it's originally
27
+ # intended form.
28
+ #
29
+ # @param index [Fixnum] Index of the field to retrieve the data for.
30
+ # @return [Number, String, Array]
31
+ # @raise [OGR::UnsupportedFieldType] if the associated FieldDefinition's
32
+ # type has not yet been mapped here (to know how to return the value).
33
+ def field(index)
34
+ field_type = field_definition(index).type
35
+
36
+ case field_type
37
+ when :OFTInteger then field_as_integer(index)
38
+ when :OFTIntegerList then field_as_integer_list(index)
39
+ when :OFTReal then field_as_double(index)
40
+ when :OFTRealList then field_as_double_list(index)
41
+ when :OFTString then field_as_string(index)
42
+ when :OFTStringList then field_as_string_list(index)
43
+ when :OFTWideString then field_as_string(index)
44
+ when :OFTWideStringList then field_as_string_list(index)
45
+ when :OFTBinary then field_as_binary(index)
46
+ when :OFTDate, :OFTTime, :OFTDateTime then field_as_date_time(index)
47
+ when :OFTInteger64 then field_as_integer(index)
48
+ when :OFTInteger64List then field_as_integer_lsit(index)
49
+ when :OFTMaxType then field_as_date_time(index)
50
+ else raise OGR::UnsupportedFieldType,
51
+ "Don't know how to fetch field for field type: #{field_type}"
25
52
  end
26
53
  end
27
54
 
28
- # @return [Array<OGR::Geometry>]
29
- def geometry_fields
30
- geometry_field_count.times.map do |i|
31
- geometry_field(i)
55
+ # @return [Enumerator]
56
+ # @yieldparam [OGR::GeometryFieldDefinition]
57
+ def each_geometry_field_definition
58
+ return enum_for(:each_geometry_field_definition) unless block_given?
59
+
60
+ geometry_field_count.times do |i|
61
+ yield geometry_field_definition(i)
32
62
  end
33
63
  end
34
64
 
35
- # TODO: this seems really wonky...
36
- def valid_raw_field?(index, raw_field)
37
- field_def = field_definition(index)
65
+ # @return [Array<OGR::GeometryFieldDefinition>]
66
+ def geometry_field_definitions
67
+ each_geometry_field_definition.to_a
68
+ end
69
+
70
+ # @return [Enumerator]
71
+ # @yieldparam [OGR::Geometry]
72
+ def each_geometry_field
73
+ return enum_for(:each_geometry_field) unless block_given?
38
74
 
39
- case field_def.type
40
- when :OFTInteger then !raw_field[:integer].nil?
41
- when :OFTIntegerList then !raw_field[:integer_list].nil?
42
- when :OFTInteger64 then !raw_field[:integer64].nil?
43
- when :OFTInteger64List then !raw_field[:integer64_list].nil?
44
- when :OFTReal then !raw_field[:real].nil?
45
- when :OFTRealList then !raw_field[:real_list].nil?
46
- when :OFTString then !raw_field[:string].nil?
47
- when :OFTStringList then !raw_field[:string_list].nil?
48
- when :OFTBinary then !raw_field[:binary].nil?
49
- when :OFTDate then !raw_field[:date].nil?
50
- else
51
- fail OGR::Failure, "Not sure how to set raw type: #{field_def.type}"
75
+ geometry_field_count.times do |i|
76
+ yield geometry_field(i)
52
77
  end
53
78
  end
54
79
 
80
+ # @return [Array<OGR::Geometry>]
81
+ def geometry_fields
82
+ each_geometry_field.to_a
83
+ end
84
+
55
85
  # @return [Hash]
56
86
  def as_json(options = nil)
57
- fields_with_nested_json = fields.map do |f|
87
+ fields_with_nested_json = fields.map.with_index do |f, i|
58
88
  {
59
- field_definition: f[:field_definition].as_json(options),
60
- value_as_string: f[:value_as_string]
89
+ field_definition: field_definition(i).as_json(options),
90
+ value: f
61
91
  }
62
92
  end
63
93
 
@@ -68,7 +98,7 @@ module OGR
68
98
  fields: fields_with_nested_json,
69
99
  geometry: geometry ? geometry.as_json(options) : nil,
70
100
  geometry_field_count: geometry_field_count,
71
- geometry_field_definitions: geometry_field_definitions.map(&:as_json),
101
+ geometry_field_definition: each_geometry_field_definition.map { |gfd| gfd.as_json(options) },
72
102
  style_string: style_string,
73
103
  style_table: style_table ? style_table.as_json(options) : nil
74
104
  }
data/lib/ogr/field.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'date'
2
+ require_relative '../ogr'
2
3
 
3
4
  module OGR
4
5
  class Field
@@ -19,7 +20,7 @@ module OGR
19
20
  def integer
20
21
  @c_struct[:integer]
21
22
  end
22
- alias_method :to_i, :integer
23
+ alias to_i integer
23
24
 
24
25
  # @param new_int [Fixnum]
25
26
  def integer=(new_int)
@@ -40,7 +41,7 @@ module OGR
40
41
  def real
41
42
  @c_struct[:real]
42
43
  end
43
- alias_method :to_f, :real
44
+ alias to_f real
44
45
 
45
46
  # @param new_real [Float]
46
47
  def real=(new_real)
@@ -68,7 +69,7 @@ module OGR
68
69
 
69
70
  # @param new_integer_list [Array<Fixnum>]
70
71
  def integer_list=(new_integer_list)
71
- list_ptr = FFI::MemoryPointer.new(:int, new_integer_list.size)
72
+ list_ptr = FFI::MemoryPointer.new(:int, new_integer_list.length)
72
73
  list_ptr.write_array_of_int(new_integer_list)
73
74
 
74
75
  il = FFI::OGR::FieldTypes::IntegerList.new
@@ -85,7 +86,7 @@ module OGR
85
86
 
86
87
  il[:list].read_array_of_int64(il[:count])
87
88
  end
88
- alias_method :to_bignum, :integer64_list
89
+ alias to_bignum integer64_list
89
90
 
90
91
  # @param new_integer64_list [Array<Bignum>]
91
92
  def integer64_list=(new_integer64_list)
@@ -98,7 +99,7 @@ module OGR
98
99
 
99
100
  @c_struct[:integer64_list] = il
100
101
  end
101
- alias_method :bignum_list=, :integer64_list=
102
+ alias bignum_list= integer64_list=
102
103
 
103
104
  # @return [Array<Float>]
104
105
  def real_list
@@ -107,7 +108,7 @@ module OGR
107
108
 
108
109
  rl[:list].read_array_of_double(rl[:count])
109
110
  end
110
- alias_method :float_list, :real_list
111
+ alias float_list real_list
111
112
 
112
113
  # @param new_real_list [Array<Float>]
113
114
  def real_list=(new_real_list)
@@ -120,7 +121,7 @@ module OGR
120
121
 
121
122
  @c_struct[:real_list] = rl
122
123
  end
123
- alias_method :float_list=, :real_list=
124
+ alias float_list= real_list=
124
125
 
125
126
  # @return [Array<String>]
126
127
  def string_list
@@ -194,16 +195,16 @@ module OGR
194
195
 
195
196
  # @param new_date [Date, Time, DateTime]
196
197
  def date=(new_date)
197
- time = new_date.to_time
198
- zone = OGR._format_time_zone_for_ogr(time.zone)
198
+ # All of Date's Time methods are private. Using #send to accomdate Date.
199
+ zone = OGR._format_time_zone_for_ogr(new_date.send(:zone))
199
200
 
200
201
  date = FFI::OGR::FieldTypes::Date.new
201
- date[:year] = time.year
202
- date[:month] = time.month
203
- date[:day] = time.day
204
- date[:hour] = time.hour
205
- date[:minute] = time.min
206
- date[:second] = time.sec
202
+ date[:year] = new_date.year
203
+ date[:month] = new_date.month
204
+ date[:day] = new_date.day
205
+ date[:hour] = new_date.hour
206
+ date[:minute] = new_date.send(:min)
207
+ date[:second] = new_date.send(:sec) + (new_date.to_time.usec / 1_000_000.to_f)
207
208
  date[:tz_flag] = zone
208
209
 
209
210
  @c_struct[:date] = date
@@ -1,4 +1,4 @@
1
- require_relative '../ffi/ogr'
1
+ require_relative '../ogr'
2
2
  require_relative 'field_definition_extensions'
3
3
 
4
4
  module OGR
@@ -18,13 +18,13 @@ module OGR
18
18
  end
19
19
 
20
20
  unless @c_pointer.is_a?(FFI::Pointer) && !@c_pointer.null?
21
- fail OGR::InvalidFieldDefinition, "Unable to create #{self.class.name} from #{name_or_pointer}"
21
+ raise OGR::InvalidFieldDefinition, "Unable to create #{self.class.name} from #{name_or_pointer}"
22
22
  end
23
-
24
- ObjectSpace.define_finalizer(self, -> { destroy! })
25
23
  end
26
24
 
27
25
  def destroy!
26
+ return unless @c_pointer
27
+
28
28
  FFI::OGR::API.OGR_Fld_Destroy(@c_pointer)
29
29
  @c_pointer = nil
30
30
  end
data/lib/ogr/geocoder.rb CHANGED
@@ -1,4 +1,4 @@
1
- require_relative 'layer'
1
+ require_relative '../ogr'
2
2
 
3
3
  module OGR
4
4
  # Geocode things! http://www.gdal.org/ogr__geocoding_8h.html
@@ -34,13 +34,13 @@ module OGR
34
34
 
35
35
  options_ptr = GDAL::Options.pointer(converted_options)
36
36
 
37
- @c_pointer = FFI::GDAL.OGRGeocodeCreateSession(options_ptr)
37
+ @c_pointer = FFI::GDAL::GDAL.OGRGeocodeCreateSession(options_ptr)
38
38
  end
39
39
 
40
40
  def destroy!
41
41
  return unless @c_pointer
42
42
 
43
- FFI::GDAL.OGRGeocodeDestroySession(@c_pointer)
43
+ FFI::GDAL::GDAL.OGRGeocodeDestroySession(@c_pointer)
44
44
  @c_pointer = nil
45
45
  end
46
46
 
@@ -59,7 +59,7 @@ module OGR
59
59
  def geocode(query, **options)
60
60
  options_ptr = GDAL::Options.pointer(options)
61
61
  layer_ptr =
62
- FFI::GDAL.OGRGeocode(@c_pointer, query, nil, options_ptr)
62
+ FFI::GDAL::GDAL.OGRGeocode(@c_pointer, query, nil, options_ptr)
63
63
  return nil if layer_ptr.null?
64
64
 
65
65
  OGR::Layer.new(layer_ptr)
@@ -76,7 +76,7 @@ module OGR
76
76
  def reverse_geocode(lon, lat, **options)
77
77
  options_ptr = GDAL::Options.pointer(options)
78
78
  layer_ptr =
79
- FFI::GDAL.OGRGeocodeReverse(@c_pointer, lon, lat, options_ptr)
79
+ FFI::GDAL::GDAL.OGRGeocodeReverse(@c_pointer, lon, lat, options_ptr)
80
80
  return nil if layer_ptr.null?
81
81
 
82
82
  OGR::Layer.new(layer_ptr)
@@ -1,13 +1,16 @@
1
1
  require_relative '../geometry_types/container'
2
+ require_relative '../geometry_types/surface'
2
3
 
3
4
  module OGR
4
5
  class GeometryCollection
5
6
  include OGR::Geometry
6
7
  include GeometryTypes::Container
8
+ include GeometryTypes::Surface
7
9
 
8
- def initialize(geometry_ptr = nil)
10
+ def initialize(geometry_ptr = nil, spatial_reference: nil)
9
11
  geometry_ptr ||= OGR::Geometry.create(:wkbGeometryCollection)
10
12
  initialize_from_pointer(geometry_ptr)
13
+ self.spatial_reference = spatial_reference if spatial_reference
11
14
  end
12
15
  end
13
16
  end
@@ -0,0 +1,12 @@
1
+ require_relative 'geometry_collection'
2
+
3
+ module OGR
4
+ # NOTE: {{#type}} will return :wkbGeometryCollection (read: 2D instead of
5
+ # 2.5D) until a Z value is set.
6
+ class GeometryCollection25D < GeometryCollection
7
+ def initialize(geometry_ptr = nil, spatial_reference: nil)
8
+ geometry_ptr ||= OGR::Geometry.create(:wkbGeometryCollection25D)
9
+ super(geometry_ptr, spatial_reference: spatial_reference)
10
+ end
11
+ end
12
+ end
@@ -5,13 +5,9 @@ module OGR
5
5
  include OGR::Geometry
6
6
  include GeometryTypes::Curve
7
7
 
8
- def self.approximate_arc_angles(center_x, center_y,
9
- z,
10
- primary_radius, secondary_radius,
11
- rotation,
12
- start_angle, end_angle,
13
- max_angle_step_size_degrees = 0)
14
- geometry_ptr = FFI::GDAL.OGR_G_ApproximateArcAngles(
8
+ def self.approximate_arc_angles(center_x, center_y, z, primary_radius, secondary_radius,
9
+ rotation, start_angle, end_angle, max_angle_step_size_degrees = 0)
10
+ geometry_ptr = FFI::GDAL::GDAL.OGR_G_ApproximateArcAngles(
15
11
  center_x,
16
12
  center_y,
17
13
  z,
@@ -27,9 +23,35 @@ module OGR
27
23
  new(geometry_ptr)
28
24
  end
29
25
 
30
- def initialize(geometry_ptr = nil)
26
+ def initialize(geometry_ptr = nil, spatial_reference: nil)
31
27
  geometry_ptr ||= OGR::Geometry.create(:wkbLineString)
32
28
  initialize_from_pointer(geometry_ptr)
29
+ self.spatial_reference = spatial_reference if spatial_reference
30
+ end
31
+
32
+ # Adds a point to a LineString or Point geometry.
33
+ #
34
+ # @param x [Float]
35
+ # @param y [Float]
36
+ # @param z [Float]
37
+ def add_point(x, y, z = nil)
38
+ if z
39
+ FFI::OGR::API.OGR_G_AddPoint(@c_pointer, x, y, z)
40
+ else
41
+ FFI::OGR::API.OGR_G_AddPoint_2D(@c_pointer, x, y)
42
+ end
43
+ end
44
+
45
+ # Wrapper for {#add_point} to allow passing in an {OGR::Point} instead of
46
+ # individual coordinates.
47
+ #
48
+ # @param point [OGR::Point]
49
+ def add_geometry(point)
50
+ if point.is_3d?
51
+ add_point(point.x, point.y, point.z)
52
+ else
53
+ add_point(point.x, point.y)
54
+ end
33
55
  end
34
56
  end
35
57
  end
@@ -0,0 +1,21 @@
1
+ require_relative 'line_string'
2
+
3
+ module OGR
4
+ # NOTE: {{#type}} will return :wkbLineString (read: 2D instead of 2.5D) until
5
+ # a Z value is set.
6
+ class LineString25D < LineString
7
+ def initialize(geometry_ptr = nil, spatial_reference: nil)
8
+ geometry_ptr ||= OGR::Geometry.create(:wkbLineString25D)
9
+ super(geometry_ptr, spatial_reference: spatial_reference)
10
+ end
11
+
12
+ # Adds a point to a LineString or Point geometry.
13
+ #
14
+ # @param x [Float]
15
+ # @param y [Float]
16
+ # @param z [Float]
17
+ def add_point(x, y, z)
18
+ super(x, y, z)
19
+ end
20
+ end
21
+ end
@@ -3,9 +3,18 @@ require_relative 'line_string'
3
3
  module OGR
4
4
  class LinearRing < LineString
5
5
  # @param [FFI::Pointer] geometry_ptr
6
- def initialize(geometry_ptr = nil)
6
+ def initialize(geometry_ptr = nil, spatial_reference: nil)
7
7
  geometry_ptr ||= OGR::Geometry.create(:wkbLinearRing)
8
8
  initialize_from_pointer(geometry_ptr)
9
+ self.spatial_reference = spatial_reference if spatial_reference
10
+ end
11
+
12
+ def to_line_string
13
+ line_string = OGR::LineString.new
14
+ line_string.spatial_reference = spatial_reference if spatial_reference
15
+ line_string.import_from_wkt(to_wkt.sub('LINEARRING', 'LINESTRING'))
16
+
17
+ line_string
9
18
  end
10
19
  end
11
20
  end
@@ -8,9 +8,10 @@ module OGR
8
8
  include GeometryTypes::Container
9
9
 
10
10
  # @param [FFI::Pointer] geometry_ptr
11
- def initialize(geometry_ptr = nil)
11
+ def initialize(geometry_ptr = nil, spatial_reference: nil)
12
12
  geometry_ptr ||= OGR::Geometry.create(:wkbMultiLineString)
13
13
  initialize_from_pointer(geometry_ptr)
14
+ self.spatial_reference = spatial_reference if spatial_reference
14
15
  end
15
16
  end
16
17
  end
@@ -0,0 +1,13 @@
1
+ require_relative 'multi_line_string'
2
+
3
+ module OGR
4
+ # NOTE: {{#type}} will return :wkbMultiLineString (read: 2D instead of 2.5D)
5
+ # until a Z value is set.
6
+ class MultiLineString25D < MultiLineString
7
+ # @param [FFI::Pointer] geometry_ptr
8
+ def initialize(geometry_ptr = nil, spatial_reference: nil)
9
+ geometry_ptr ||= OGR::Geometry.create(:wkbMultiLineString25D)
10
+ super(geometry_ptr, spatial_reference: spatial_reference)
11
+ end
12
+ end
13
+ end