ffi-gdal 0.0.4 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -1
  3. data/Rakefile +12 -1
  4. data/TODO.md +11 -0
  5. data/ffi-gdal.gemspec +2 -2
  6. data/lib/ext/error_symbols.rb +59 -0
  7. data/lib/ext/float_ext.rb +15 -0
  8. data/lib/ext/narray_ext.rb +16 -0
  9. data/lib/ext/to_bool.rb +2 -0
  10. data/lib/ffi-gdal.rb +139 -4
  11. data/lib/ffi/{gdal/cpl_conv.rb → cpl/conv_h.rb} +2 -3
  12. data/lib/ffi/{gdal/cpl_error.rb → cpl/error_h.rb} +1 -25
  13. data/lib/ffi/cpl/minixml_h.rb +14 -0
  14. data/lib/ffi/{gdal/cpl_string.rb → cpl/string_h.rb} +0 -25
  15. data/lib/ffi/{gdal/cpl_vsi.rb → cpl/vsi_h.rb} +0 -0
  16. data/lib/ffi/cpl/xml_node.rb +13 -0
  17. data/lib/ffi/gdal.rb +57 -593
  18. data/lib/ffi/gdal/alg_h.rb +127 -0
  19. data/lib/ffi/gdal/gdal_grid_data_metrics_options.rb +14 -0
  20. data/lib/ffi/gdal/gdal_grid_inverse_distance_to_a_power_options.rb +19 -0
  21. data/lib/ffi/gdal/gdal_grid_moving_average_options.rb +14 -0
  22. data/lib/ffi/gdal/gdal_grid_nearest_neighbor_options.rb +13 -0
  23. data/lib/ffi/gdal/gdal_h.rb +683 -0
  24. data/lib/ffi/gdal/gdal_rpc_info.rb +27 -0
  25. data/lib/ffi/gdal/gdal_transformer_info.rb +14 -0
  26. data/lib/ffi/gdal/gdal_warp_options.rb +43 -0
  27. data/lib/ffi/gdal/grid_h.rb +51 -0
  28. data/lib/ffi/gdal/version.rb +1 -1
  29. data/lib/ffi/gdal/warper_h.rb +48 -0
  30. data/lib/ffi/ogr.rb +12 -0
  31. data/lib/ffi/ogr/api_h.rb +553 -0
  32. data/lib/ffi/ogr/core_h.rb +148 -0
  33. data/lib/ffi/ogr/featurestyle_h.rb +22 -0
  34. data/lib/ffi/ogr/geocoding_h.rb +21 -0
  35. data/lib/ffi/ogr/ogr_contour_writer_info.rb +14 -0
  36. data/lib/ffi/ogr/ogr_envelope.rb +12 -0
  37. data/lib/ffi/ogr/ogr_envelope_3d.rb +14 -0
  38. data/lib/ffi/ogr/ogr_field.rb +50 -0
  39. data/lib/ffi/ogr/ogr_style_param.rb +12 -0
  40. data/lib/ffi/ogr/ogr_style_value.rb +13 -0
  41. data/lib/ffi/ogr/srs_api_h.rb +325 -0
  42. data/lib/gdal/color_entry.rb +47 -0
  43. data/lib/gdal/color_entry_extensions.rb +30 -0
  44. data/lib/gdal/color_interpretation.rb +15 -0
  45. data/lib/gdal/color_table.rb +146 -0
  46. data/lib/gdal/color_table_extensions.rb +47 -0
  47. data/lib/gdal/color_table_types/cmyk.rb +25 -0
  48. data/lib/gdal/color_table_types/gray.rb +9 -0
  49. data/lib/gdal/color_table_types/hls.rb +21 -0
  50. data/lib/gdal/color_table_types/rgb.rb +25 -0
  51. data/lib/gdal/data_type.rb +38 -0
  52. data/lib/gdal/dataset.rb +437 -0
  53. data/lib/gdal/dataset_extensions.rb +496 -0
  54. data/lib/gdal/driver.rb +244 -0
  55. data/lib/gdal/driver_extensions.rb +56 -0
  56. data/lib/gdal/environment_methods.rb +43 -0
  57. data/lib/{ffi-gdal → gdal}/exceptions.rb +4 -1
  58. data/lib/gdal/geo_transform.rb +188 -0
  59. data/lib/gdal/geo_transform_extensions.rb +90 -0
  60. data/lib/gdal/logger.rb +7 -0
  61. data/lib/{ffi-gdal → gdal}/major_object.rb +15 -14
  62. data/lib/gdal/options.rb +49 -0
  63. data/lib/gdal/raster_attribute_table.rb +185 -0
  64. data/lib/gdal/raster_attribute_table_extensions.rb +40 -0
  65. data/lib/{ffi-gdal → gdal}/raster_band.rb +227 -99
  66. data/lib/gdal/raster_band_extensions.rb +198 -0
  67. data/lib/{ffi-gdal → gdal}/version_info.rb +8 -0
  68. data/lib/gdal/warp_operation.rb +96 -0
  69. data/lib/ogr/coordinate_transformation.rb +108 -0
  70. data/lib/ogr/data_source.rb +172 -0
  71. data/lib/ogr/data_source_extensions.rb +32 -0
  72. data/lib/ogr/driver.rb +119 -0
  73. data/lib/ogr/envelope.rb +80 -0
  74. data/lib/ogr/envelope_extensions.rb +92 -0
  75. data/lib/ogr/exceptions.rb +35 -0
  76. data/lib/ogr/feature.rb +212 -0
  77. data/lib/ogr/feature_definition.rb +120 -0
  78. data/lib/ogr/feature_definition_extensions.rb +36 -0
  79. data/lib/ogr/feature_extensions.rb +31 -0
  80. data/lib/ogr/field.rb +91 -0
  81. data/lib/ogr/field_extensions.rb +23 -0
  82. data/lib/ogr/geocoding_session.rb +84 -0
  83. data/lib/ogr/geometry.rb +617 -0
  84. data/lib/ogr/geometry_extensions.rb +60 -0
  85. data/lib/ogr/geometry_types/collection.rb +45 -0
  86. data/lib/ogr/geometry_types/curve.rb +120 -0
  87. data/lib/ogr/geometry_types/surface.rb +20 -0
  88. data/lib/ogr/layer.rb +226 -0
  89. data/lib/ogr/layer_extensions.rb +55 -0
  90. data/lib/ogr/line_string.rb +7 -0
  91. data/lib/ogr/linear_ring.rb +6 -0
  92. data/lib/ogr/multi_line_string.rb +9 -0
  93. data/lib/ogr/multi_point.rb +7 -0
  94. data/lib/ogr/multi_polygon.rb +14 -0
  95. data/lib/ogr/point.rb +89 -0
  96. data/lib/ogr/polygon.rb +9 -0
  97. data/lib/ogr/spatial_reference.rb +723 -0
  98. data/lib/ogr/spatial_reference_extensions.rb +32 -0
  99. data/lib/ogr/style_table.rb +17 -0
  100. data/lib/ogr/style_table_extensions.rb +16 -0
  101. data/spec/{ffi-gdal/integration → integration}/color_table_info_spec.rb +1 -1
  102. data/spec/{ffi-gdal/integration → integration}/dataset_info_spec.rb +0 -0
  103. data/spec/{ffi-gdal/integration → integration}/driver_info_spec.rb +1 -1
  104. data/spec/{ffi-gdal/integration → integration}/geo_transform_info_spec.rb +0 -0
  105. data/spec/{ffi-gdal/integration → integration}/raster_attribute_table_info_spec.rb +1 -1
  106. data/spec/{ffi-gdal/integration → integration}/raster_band_info_spec.rb +5 -5
  107. data/spec/spec_helper.rb +4 -1
  108. data/spec/support/shapefiles/states_21basic/states.prj +1 -0
  109. data/spec/support/shapefiles/states_21basic/states.sbn +0 -0
  110. data/spec/support/shapefiles/states_21basic/states.sbx +0 -0
  111. data/spec/support/shapefiles/states_21basic/states.shp +0 -0
  112. data/spec/support/worldfiles/SR_50M/SR_50M.VERSION.txt +1 -0
  113. data/spec/support/worldfiles/SR_50M/SR_50M.prj +1 -0
  114. data/spec/support/worldfiles/SR_50M/SR_50M.tfw +6 -0
  115. data/spec/{ext/cpl_error_symbols_spec.rb → unit/ext/error_symbols_spec.rb} +1 -1
  116. data/spec/unit/gdal/color_table_spec.rb +146 -0
  117. data/spec/unit/ogr/layer_spec.rb +97 -0
  118. data/spec/unit/ogr/linear_ring_spec.rb +111 -0
  119. data/spec/unit/ogr/point_spec.rb +321 -0
  120. data/spec/{ffi-gdal/unit → unit}/version_info_spec.rb +1 -1
  121. data/testing_gdal.rb +168 -0
  122. data/testing_gdalwarp.rb +91 -0
  123. data/testing_layer_to_layer.rb +35 -0
  124. data/testing_ndvi.rb +76 -0
  125. data/testing_nir.rb +77 -0
  126. data/testing_ogr.rb +63 -0
  127. metadata +167 -59
  128. data/lib/ext/cpl_error_symbols.rb +0 -37
  129. data/lib/ffi-gdal/color_table.rb +0 -59
  130. data/lib/ffi-gdal/dataset.rb +0 -359
  131. data/lib/ffi-gdal/driver.rb +0 -151
  132. data/lib/ffi-gdal/geo_transform.rb +0 -137
  133. data/lib/ffi-gdal/raster_attribute_table.rb +0 -78
  134. data/lib/ffi/gdal/ogr_api.rb +0 -21
  135. data/lib/ffi/gdal/ogr_core.rb +0 -195
  136. data/lib/ffi/gdal/ogr_srs_api.rb +0 -44
  137. data/meow.rb +0 -144
  138. data/rubby.rb +0 -224
@@ -0,0 +1,60 @@
1
+ require 'json'
2
+
3
+ module OGR
4
+ module GeometryExtensions
5
+
6
+ # @return [Hash]
7
+ def as_json
8
+ json = {
9
+ coordinate_dimension: coordinate_dimension,
10
+ count: count,
11
+ dimension: dimension,
12
+ is_empty: empty?,
13
+ is_ring: ring?,
14
+ is_simple: simple?,
15
+ is_valid: valid?,
16
+ name: name,
17
+ point_count: point_count,
18
+ spatial_reference: spatial_reference.as_json,
19
+ type: type_to_name,
20
+ wkb_size: wkb_size
21
+ }
22
+
23
+ json.merge!(area: area) if respond_to? :area
24
+ json.merge!(length: length) if respond_to? :length
25
+ json.merge!(points: points) if respond_to? :points
26
+
27
+ json
28
+ end
29
+
30
+ # @return [String]
31
+ def to_json
32
+ as_json.to_json
33
+ end
34
+
35
+ def collection?
36
+ false
37
+ end
38
+
39
+ def to_vector(file_name, driver, layer_name: 'vectorized_geometry', spatial_reference: nil)
40
+ driver = OGR::Driver.by_name(driver)
41
+
42
+ data_source = driver.create_data_source(file_name)
43
+ log "Creating layer #{layer_name}, type: #{type}"
44
+ layer = data_source.create_layer(layer_name, geometry_type: type,
45
+ spatial_reference: spatial_reference)
46
+
47
+ # field = Field.create('Name', :OFTString)
48
+ # field.width = 32
49
+
50
+ unless layer
51
+ raise OGR::InvalidLayer, "Unable to create layer '#{layer_name}'."
52
+ end
53
+
54
+ feature = layer.create_feature(layer_name)
55
+ feature.geometry = self
56
+
57
+ data_source
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,45 @@
1
+ module OGR
2
+ module GeometryTypes
3
+ module Collection
4
+ def collection?
5
+ true
6
+ end
7
+
8
+ # If this geometry is a container, this fetches the geometry at the
9
+ # sub_geometry_index.
10
+ #
11
+ # @param sub_geometry_index [Fixnum]
12
+ # @return [OGR::Geometry]
13
+ def geometry_at(sub_geometry_index)
14
+ build_geometry do |ptr|
15
+ FFI::GDAL.OGR_G_GetGeometryRef(ptr, sub_geometry_index)
16
+ end
17
+ end
18
+
19
+ # Build a ring from a bunch of arcs.
20
+ #
21
+ # @param tolerance [Float]
22
+ # @param auto_close [Boolean]
23
+ # @return [OGR::Geometry]
24
+ def polygon_from_edges(tolerance, auto_close)
25
+ best_effort = false
26
+ ogrerr_ptr = FFI::MemoryPointer.new(:pointer)
27
+
28
+ new_geometry_ptr = FFI::GDAL.OGRBuildPolygonFromEdges(@geometry_pointer,
29
+ best_effort,
30
+ auto_close,
31
+ tolerance,
32
+ ogrerr_ptr)
33
+
34
+ ogrerr_int = ogrerr_ptr.read_int
35
+ ogrerr = FFI::GDAL::OGRErr[ogrerr_int]
36
+
37
+ if ogrerr == :OGRERR_FAILURE
38
+ raise "Couldn't create polygon"
39
+ end
40
+
41
+ self.class._to_geometry_type(new_geometry_ptr)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,120 @@
1
+ module OGR
2
+ module GeometryTypes
3
+ module Curve
4
+
5
+ # @return [Float]
6
+ def x(point_number)
7
+ FFI::GDAL.OGR_G_GetX(@geometry_pointer, point_number)
8
+ end
9
+
10
+ # @return [Float]
11
+ def y(point_number)
12
+ FFI::GDAL.OGR_G_GetY(@geometry_pointer, point_number)
13
+ end
14
+
15
+ # @return [Float]
16
+ def z(point_number)
17
+ FFI::GDAL.OGR_G_GetZ(@geometry_pointer, point_number)
18
+ end
19
+
20
+ # @return [Array<Float, Float, Float>] [x, y] if 2d or [x, y, z] if 3d.
21
+ def point(number)
22
+ x_ptr = FFI::MemoryPointer.new(:double)
23
+ y_ptr = FFI::MemoryPointer.new(:double)
24
+ z_ptr = FFI::MemoryPointer.new(:double)
25
+
26
+ FFI::GDAL.OGR_G_GetPoint(@geometry_pointer, number, x_ptr, y_ptr, z_ptr)
27
+
28
+ if coordinate_dimension == 2
29
+ [x_ptr.read_double, y_ptr.read_double]
30
+ else
31
+ [x_ptr.read_double, y_ptr.read_double, z_ptr.read_double]
32
+ end
33
+ end
34
+
35
+ # Adds a point to a LineString or Point geometry.
36
+ #
37
+ # @param x [Float]
38
+ # @param y [Float]
39
+ # @param z [Float]
40
+ def add_point(x, y, z=0)
41
+ if coordinate_dimension == 3
42
+ FFI::GDAL.OGR_G_AddPoint(@geometry_pointer, x, y, z)
43
+ else
44
+ FFI::GDAL.OGR_G_AddPoint_2D(@geometry_pointer, x, y)
45
+ end
46
+ end
47
+
48
+ def set_point(index, x, y, z=0)
49
+ FFI::GDAL.OGR_G_SetPoint(@geometry_pointer, index, x, y, z)
50
+ end
51
+
52
+ # @return [Array<Array>] An array of (x, y) or (x, y, z) points.
53
+ def points
54
+ x_stride = 2
55
+ y_stride = 2
56
+ z_stride = coordinate_dimension == 3 ? 1 : 0
57
+
58
+ buffer_size = FFI::Type::DOUBLE.size * 2 * point_count
59
+
60
+ x_buffer = FFI::MemoryPointer.new(:buffer_out, buffer_size)
61
+ y_buffer = FFI::MemoryPointer.new(:buffer_out, buffer_size)
62
+
63
+ z_buffer = if coordinate_dimension == 3
64
+ z_size = FFI::Type::DOUBLE.size * point_count
65
+ FFI::MemoryPointer.new(:buffer_out, z_size)
66
+ else
67
+ nil
68
+ end
69
+
70
+ num_points = FFI::GDAL.OGR_G_GetPoints(@geometry_pointer,
71
+ x_buffer,
72
+ x_stride,
73
+ y_buffer,
74
+ y_stride,
75
+ z_buffer,
76
+ z_stride)
77
+
78
+ 0.upto(num_points - 1).map do |i|
79
+ point(i)
80
+ end
81
+ end
82
+
83
+ # @param geo_transform [GDAL::GeoTransform]
84
+ # @return [Array<Array>]
85
+ def pixels(geo_transform)
86
+ log "points count: #{point_count}"
87
+ points.map do |x_and_y|
88
+ result = geo_transform.world_to_pixel(*x_and_y)
89
+
90
+ [result[:x].to_i.abs, result[:y].to_i.abs]
91
+ end
92
+ end
93
+
94
+ # @param new_count [Fixnum]
95
+ def point_count=(new_count)
96
+ FFI::GDAL.OGR_G_SetPointCount(@geometry_pointer, new_count)
97
+ end
98
+
99
+ # Computes the length for this geometry. Computes area for Curve or
100
+ # MultiCurve objects.
101
+ #
102
+ # @return [Float] 0.0 for unsupported geometry types.
103
+ def length
104
+ FFI::GDAL.OGR_G_Length(@geometry_pointer)
105
+ end
106
+
107
+ def start_point
108
+ point(0)
109
+ end
110
+
111
+ def end_point
112
+ point(point_count - 1)
113
+ end
114
+
115
+ def closed?
116
+ start_point == end_point
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,20 @@
1
+ module OGR
2
+ module GeometryTypes
3
+ module Surface
4
+
5
+ # Computes area for a LinearRing, Polygon, or MultiPolygon.
6
+ #
7
+ # @return [Float] 0.0 for unsupported geometry types.
8
+ def area
9
+ FFI::GDAL.OGR_G_Area(@geometry_pointer)
10
+ end
11
+
12
+ # Returns a point that's guaranteed to lie on the surface.
13
+ #
14
+ # @return [OGR::Point]
15
+ def point_on_surface
16
+ build_geometry { |ptr| FFI::GDAL.OGR_G_PointOnSurface(ptr) }
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/ogr/layer.rb ADDED
@@ -0,0 +1,226 @@
1
+ require_relative '../ffi/ogr'
2
+ require_relative 'layer_extensions'
3
+ require_relative 'envelope'
4
+ require_relative 'geometry'
5
+ require_relative 'feature'
6
+ require_relative 'feature_definition'
7
+ require_relative 'spatial_reference'
8
+ require_relative 'style_table'
9
+
10
+ module OGR
11
+ class Layer
12
+ include GDAL::MajorObject
13
+ include LayerExtensions
14
+
15
+ def initialize(layer)
16
+ @ogr_layer_pointer = GDAL._pointer(OGR::Layer, layer)
17
+ @features = []
18
+ end
19
+
20
+ def c_pointer
21
+ @ogr_layer_pointer
22
+ end
23
+
24
+ # @return [String]
25
+ def name
26
+ FFI::GDAL.OGR_L_GetName(@ogr_layer_pointer)
27
+ end
28
+
29
+ # @return [Symbol] One of OGRwkbGeometryType.
30
+ def geometry_type
31
+ FFI::GDAL.OGR_L_GetGeomType(@ogr_layer_pointer)
32
+ end
33
+
34
+ # TODO: per the gdal docs: "The returned pointer is to an internally owned
35
+ # object, and should not be altered or deleted by the caller."
36
+ #
37
+ # @return [OGR::Geometry]
38
+ def spatial_filter
39
+ return @spatial_filter if @spatial_filter
40
+
41
+ filter_pointer = FFI::GDAL.OGR_L_GetSpatialFilter(@ogr_layer_pointer)
42
+ return nil if filter_pointer.null?
43
+
44
+ @spatial_filter = OGR::Geometry.new(filter_pointer)
45
+ end
46
+
47
+ # The number of features in this layer. If +force+ is false and it would be
48
+ # expensive to determine the feature count, -1 may be returned.
49
+ #
50
+ # @param force [Boolean] Force the calculation even if it's
51
+ # expensive.
52
+ # @return [Fixnum]
53
+ def feature_count(force=true)
54
+ FFI::GDAL.OGR_L_GetFeatureCount(@ogr_layer_pointer, force)
55
+ end
56
+
57
+ # @param index [Fixnum] The 0-based index of the feature to get. It should
58
+ # be <= +feature_count+, but not checking is done to ensure.
59
+ # @return [OGR::Feature, nil]
60
+ def feature(index)
61
+ @features.fetch(index) do
62
+ feature_pointer = FFI::GDAL.OGR_L_GetFeature(@ogr_layer_pointer, index)
63
+ return nil if feature_pointer.null?
64
+
65
+ feature = OGR::Feature.new(feature_pointer)
66
+ @features.insert(index, feature)
67
+
68
+ feature
69
+ end
70
+ end
71
+
72
+ # The next available feature in this layer. Only features matching the
73
+ # current spatial filter will be returned. Use +reset_reading+ to start at
74
+ # the beginning again.
75
+ #
76
+ # @return [OGR::Feature, nil]
77
+ def next_feature
78
+ feature_pointer = FFI::GDAL.OGR_L_GetNextFeature(@ogr_layer_pointer)
79
+ return nil if feature_pointer.null?
80
+
81
+ OGR::Feature.new(feature_pointer)
82
+ end
83
+
84
+ # @return [Fixnum]
85
+ def features_read
86
+ FFI::GDAL.OGR_L_GetFeaturesRead(@ogr_layer_pointer)
87
+ end
88
+
89
+ # Uses the already-defined FeatureDefinition to create then write a new feature
90
+ # to the layer.
91
+ #
92
+ # @return [OGR::Feature]
93
+ def create_feature
94
+ feature_def = feature_definition
95
+ feature = OGR::Feature.create(feature_def)
96
+ ogr_err = FFI::GDAL.OGR_L_CreateFeature(@ogr_layer_pointer, feature.c_pointer)
97
+ ogr_err.to_ruby
98
+
99
+ feature
100
+ end
101
+
102
+ # Deletes the feature from the layer.
103
+ #
104
+ # TODO: Use OGR_L_TestCapability before trying to delete.
105
+ # @return +true+ if successful, otherwise raises an OGR exception.
106
+ def delete_feature(feature_id)
107
+ ogr_err = FFI::GDAL.OGR_L_DeleteFeature(@ogr_layer_pointer, feature_id)
108
+
109
+ ogr_err.to_ruby
110
+ end
111
+
112
+ # Creates and writes a new field to the layer.
113
+ #
114
+ # @param name [String]
115
+ # @param type [FFI::GDAL::OGRFieldType]
116
+ # @param approx_ok [Boolean] If +true+ the field may be created in a slightly
117
+ # different form, depending on the limitations of the format driver.
118
+ # @return [OGR::Field]
119
+ def create_field(name, type, approx_ok=false)
120
+ field = OGR::Field.create(name, type)
121
+ ogr_err = FFI::GDAL.OGR_L_CreateField(@ogr_layer_pointer, field.c_pointer, approx_ok)
122
+ ogr_err.to_ruby
123
+
124
+ field
125
+ end
126
+
127
+ # @param field [OGR::Field, FFI::Pointer]
128
+ # @param approx_ok [Boolean] If +true+ the field may be created in a slightly
129
+ # different form, depending on the limitations of the format driver.
130
+ # @return +true+ if successful, otherwise raises an OGR exception.
131
+ def add_field(field, approx_ok=false)
132
+ field_ptr = GDAL._pointer(OGR::Field, field)
133
+ ogr_err = FFI::GDAL.OGR_L_CreateField(@ogr_layer_pointer, field_ptr, approx_ok)
134
+
135
+ ogr_err.to_ruby
136
+ end
137
+
138
+ # Deletes the field definition from the layer.
139
+ #
140
+ # TODO: Use OGR_L_TestCapability before trying to delete.
141
+ # @return +true+ if successful, otherwise raises an OGR exception.
142
+ def delete_field(field_id)
143
+ ogr_err = FFI::GDAL.OGR_L_DeleteField(@ogr_layer_pointer, field_id)
144
+
145
+ ogr_err.to_ruby
146
+ end
147
+
148
+ # # Creates and writes a new geometry to the layer.
149
+ # #
150
+ # # @return [OGR::GeometryField]
151
+ # def create_geometry_field(approx_ok=false)
152
+ # geometry_field_definition_ptr = FFI::MemoryPointer.new(:OGRGeomFieldDefnH)
153
+ # ogr_err = OGR_L_CreateGeomField(@ogr_layer_pointer, geometry_field_definition_ptr)
154
+ #
155
+ # OGR::GeometryFieldDefinition.new(geometry_field_definition_ptr)
156
+ # end
157
+
158
+ # Resets the sequential reading of features for this layer.
159
+ def reset_reading
160
+ FFI::GDAL.OGR_L_ResetReading(@ogr_layer_pointer)
161
+ end
162
+
163
+ # The schema information for this layer.
164
+ #
165
+ # @return [OGR::FeatureDefinition,nil]
166
+ def feature_definition
167
+ return @feature_definition if @feature_definition
168
+
169
+ feature_defn_pointer = FFI::GDAL.OGR_L_GetLayerDefn(@ogr_layer_pointer)
170
+ return nil if feature_defn_pointer.null?
171
+
172
+ @feature_definition = OGR::FeatureDefinition.new(feature_defn_pointer)
173
+ end
174
+
175
+ # @return [OGR::SpatialReference]
176
+ def spatial_reference
177
+ return @spatial_reference if @spatial_reference
178
+
179
+ spatial_ref_pointer = FFI::GDAL.OGR_L_GetSpatialRef(@ogr_layer_pointer)
180
+ return nil if spatial_ref_pointer.null?
181
+
182
+ @spatial_reference = OGR::SpatialReference.new(spatial_ref_pointer)
183
+ end
184
+
185
+ # @return [OGR::Envelope]
186
+ def extent(force=true)
187
+ return @envelope if @envelope
188
+
189
+ envelope = FFI::GDAL::OGREnvelope.new
190
+ FFI::GDAL.OGR_L_GetExtent(@ogr_layer_pointer, envelope, force)
191
+ return nil if envelope.null?
192
+
193
+ @envelope = OGR::Envelope.new(envelope)
194
+ end
195
+
196
+ # @return [OGR::Envelope]
197
+ def extent_by_geometry(geometry_field_index, force=true)
198
+ envelope = FFI::GDAL::OGREnvelope.new
199
+ FFI::GDAL.OGR_L_GetExtentEx(@ogr_layer_pointer, geometry_field_index, envelope, force)
200
+ return nil if envelope.null?
201
+
202
+ OGR::Envelope.new(envelope)
203
+ end
204
+
205
+ # The name of the underlying database column. '' if not supported.
206
+ # @return [String]
207
+ def fid_column
208
+ FFI::GDAL.OGR_L_GetFIDColumn(@ogr_layer_pointer)
209
+ end
210
+
211
+ # @return [String]
212
+ def geometry_column
213
+ FFI::GDAL.OGR_L_GetGeometryColumn(@ogr_layer_pointer)
214
+ end
215
+
216
+ # @return [OGR::StyleTable, nil]
217
+ def style_table
218
+ return @style_table if @style_table
219
+
220
+ style_table_pointer = FFI::GDAL.OGR_L_GetStyleTable(@ogr_layer_pointer)
221
+ return nil if style_table_pointer.null?
222
+
223
+ @style_table = OGR::StyleTable.new(style_table_pointer)
224
+ end
225
+ end
226
+ end