module OGR::Geometry

Attributes

c_pointer[R]

@return [FFI::Pointer]

Public Class Methods

included(base) click to toggle source
# File lib/ogr/geometry.rb, line 147
def self.included(base)
  base.send(:include, GDAL::Logger)
  base.send(:extend, ClassMethods)
end

Public Instance Methods

-(geometry)
Alias for: difference
==(geometry)
Alias for: equals?
boundary() click to toggle source

@return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 526
def boundary
  build_geometry { FFI::OGR::API.OGR_G_Boundary(@c_pointer) }
end
buffer(distance, quad_segments = 30) click to toggle source

Computes the buffer of the geometry by building a new geometry that contains the buffer region around the geometry that this was called on.

@param distance [Float] The buffer distance to be applied. @param quad_segments [Integer] The number of segments to use to approximate

a 90 degree (quadrant) of curvature.

@return [OGR::Polygon]

# File lib/ogr/geometry.rb, line 537
def buffer(distance, quad_segments = 30)
  build_geometry do
    FFI::OGR::API.OGR_G_Buffer(@c_pointer, distance, quad_segments)
  end
end
centroid() click to toggle source

@return [Integer]

# File lib/ogr/geometry.rb, line 252
def centroid
  point = is_3d? ? OGR::Point25D.new : OGR::Point.new

  ogr_err = FFI::OGR::API.OGR_G_Centroid(@c_pointer, point.c_pointer)
  return if point.c_pointer.null? || ogr_err.positive?

  point
end
clone() click to toggle source

@return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 166
def clone
  new_geometry_ptr = FFI::OGR::API.OGR_G_Clone(@c_pointer)

  OGR::Geometry.factory(new_geometry_ptr)
end
close_rings!() click to toggle source

If this or any contained geometries has polygon rings that aren’t closed, this closes them by adding the starting point at the end.

# File lib/ogr/geometry.rb, line 392
def close_rings!
  FFI::OGR::API.OGR_G_CloseRings(@c_pointer)
end
contains?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 329
def contains?(geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
  FFI::OGR::API.OGR_G_Contains(@c_pointer, geometry_ptr)
end
convex_hull() click to toggle source

@return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 544
def convex_hull
  build_geometry { FFI::OGR::API.OGR_G_ConvexHull(@c_pointer) }
end
coordinate_dimension() click to toggle source

The dimension of coordinates in this geometry (i.e. 2d vs 3d).

@return [Integer] 2 or 3, but 0 in the case of an empty point.

# File lib/ogr/geometry.rb, line 187
def coordinate_dimension
  FFI::OGR::API.OGR_G_GetCoordinateDimension(@c_pointer)
end
coordinate_dimension=(new_coordinate_dimension) click to toggle source

@param new_coordinate_dimension [Integer]

# File lib/ogr/geometry.rb, line 192
def coordinate_dimension=(new_coordinate_dimension)
  unless [2, 3].include?(new_coordinate_dimension)
    raise "Can't set coordinate to #{new_coordinate_dimension}.  Must be 2 or 3."
  end

  FFI::OGR::API.OGR_G_SetCoordinateDimension(@c_pointer, new_coordinate_dimension)
end
count()
Alias for: geometry_count
crosses?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 315
def crosses?(geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
  FFI::OGR::API.OGR_G_Crosses(@c_pointer, geometry_ptr)
end
destroy!() click to toggle source
# File lib/ogr/geometry.rb, line 159
def destroy!
  self.class.release(@c_pointer)

  @c_pointer = nil
end
difference(geometry) click to toggle source

@param geometry [OGR::Geometry] @return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 408
def difference(geometry)
  new_geometry_ptr = FFI::OGR::API.OGR_G_Difference(@c_pointer, geometry.c_pointer)
  return if new_geometry_ptr.null?

  self.class.factory(new_geometry_ptr)
end
Also aliased as: -
dimension() click to toggle source

@return [Integer] 0 for points, 1 for lines, 2 for surfaces.

# File lib/ogr/geometry.rb, line 180
def dimension
  FFI::OGR::API.OGR_G_GetDimension(@c_pointer)
end
disjoint?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 302
def disjoint?(geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
  FFI::OGR::API.OGR_G_Disjoint(@c_pointer, geometry_ptr)
end
distance_to(geometry) click to toggle source

The shortest distance between the two geometries.

@param geometry [OGR::Geometry] @return [Float] -1 if an error occurs.

# File lib/ogr/geometry.rb, line 429
def distance_to(geometry)
  FFI::OGR::API.OGR_G_Distance(@c_pointer, geometry.c_pointer)
end
dump_readable(file_path = nil, prefix: nil) click to toggle source

Dump as WKT to the given file_path; dumps to STDOUT if none is given.

@param file_path [String] The text file to write to. @param prefix [String] The prefix to put on each line of output.

# File lib/ogr/geometry.rb, line 273
def dump_readable(file_path = nil, prefix: nil)
  file_ptr = file_path ? FFI::CPL::Conv.CPLOpenShared(file_path, "w", false) : nil
  FFI::OGR::API.OGR_G_DumpReadable(@c_pointer, file_ptr, prefix)
  FFI::CPL::Conv.CPLCloseShared(file_ptr) if file_ptr
end
empty!() click to toggle source

Clears all information from the geometry.

@return nil

# File lib/ogr/geometry.rb, line 175
def empty!
  FFI::OGR::API.OGR_G_Empty(@c_pointer)
end
empty?() click to toggle source

@return [Boolean]

# File lib/ogr/geometry.rb, line 342
def empty?
  FFI::OGR::API.OGR_G_IsEmpty(@c_pointer)
end
envelope() click to toggle source

@return [OGR::Envelope]

# File lib/ogr/geometry.rb, line 201
def envelope
  case coordinate_dimension
  when 2
    envelope = FFI::OGR::Envelope.new
    FFI::OGR::API.OGR_G_GetEnvelope(@c_pointer, envelope)
  when 3
    envelope = FFI::OGR::Envelope3D.new
    FFI::OGR::API.OGR_G_GetEnvelope3D(@c_pointer, envelope)
  when 0 then return nil
  else
    raise "Unknown envelope dimension."
  end

  return if envelope.null?

  OGR::Envelope.new(envelope)
end
equals?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 293
def equals?(geometry)
  return false unless geometry.is_a? OGR::Geometry

  FFI::OGR::API.OGR_G_Equals(@c_pointer, geometry.c_pointer)
end
Also aliased as: ==
flatten_to_2d!() click to toggle source

Converts this geometry to a 2D geometry.

# File lib/ogr/geometry.rb, line 280
def flatten_to_2d!
  FFI::OGR::API.OGR_G_FlattenTo2D(@c_pointer)
end
geometry_count() click to toggle source

@return [Integer]

# File lib/ogr/geometry.rb, line 239
def geometry_count
  FFI::OGR::API.OGR_G_GetGeometryCount(@c_pointer)
end
Also aliased as: count
import_from_wkb(wkb_data) click to toggle source

@param wkb_data [String] Binary WKB data. @raise [OGR::Failure]

# File lib/ogr/geometry.rb, line 557
def import_from_wkb(wkb_data)
  OGR::ErrorHandling.handle_ogr_err("Unable to import geometry from WKB") do
    FFI::OGR::API.OGR_G_ImportFromWkb(@c_pointer, wkb_data, wkb_data.length)
  end
end
import_from_wkt(wkt_data) click to toggle source

@param wkt_data [String] @raise [OGR::Failure]

# File lib/ogr/geometry.rb, line 584
def import_from_wkt(wkt_data)
  wkt_data_pointer = FFI::MemoryPointer.from_string(wkt_data)
  wkt_pointer_pointer = FFI::MemoryPointer.new(:pointer)
  wkt_pointer_pointer.write_pointer(wkt_data_pointer)

  OGR::ErrorHandling.handle_ogr_err("Unable to import from WKT: #{wkt_data}") do
    FFI::OGR::API.OGR_G_ImportFromWkt(@c_pointer, wkt_pointer_pointer)
  end
end
intersection(other_geometry) click to toggle source

@param other_geometry [OGR::Geometry] @return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 376
def intersection(other_geometry)
  build_geometry do
    FFI::OGR::API.OGR_G_Intersection(@c_pointer, other_geometry.c_pointer)
  end
end
intersects?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 286
def intersects?(geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
  FFI::OGR::API.OGR_G_Intersects(@c_pointer, geometry_ptr)
end
is_2d?() click to toggle source
# File lib/ogr/geometry.rb, line 261
def is_2d?
  coordinate_dimension == 2
end
is_3d?() click to toggle source
# File lib/ogr/geometry.rb, line 265
def is_3d?
  coordinate_dimension == 3
end
name() click to toggle source

@return [String]

# File lib/ogr/geometry.rb, line 230
def name
  # The returned pointer is to a static internal string and should not be modified or freed.
  name, ptr = FFI::OGR::API.OGR_G_GetGeometryName(@c_pointer)
  ptr.autorelease = false

  name
end
overlaps?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 336
def overlaps?(geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
  FFI::OGR::API.OGR_G_Overlaps(@c_pointer, geometry_ptr)
end
point_count() click to toggle source

@return [Integer]

# File lib/ogr/geometry.rb, line 245
def point_count
  return 0 if empty?

  FFI::OGR::API.OGR_G_GetPointCount(@c_pointer)
end
point_on_surface() click to toggle source

Returns a point that’s guaranteed to lie on the surface.

@return [OGR::Point]

# File lib/ogr/geometry.rb, line 551
def point_on_surface
  build_geometry { FFI::OGR::API.OGR_G_PointOnSurface(@c_pointer) }
end
polygonize() click to toggle source

Creates a polygon from a set of sparse edges. The newly created geometry will contain a collection of reassembled Polygons.

@return [OGR::Geometry] nil if the current geometry isn’t a

MultiLineString or if it's impossible to reassemble due to topological
inconsistencies.
# File lib/ogr/geometry.rb, line 402
def polygonize
  build_geometry { FFI::OGR::API.OGR_G_Polygonize(@c_pointer) }
end
ring?() click to toggle source

TRUE if the geometry has no points, otherwise FALSE.

@return [Boolean]

# File lib/ogr/geometry.rb, line 366
def ring?
  FFI::OGR::API.OGR_G_IsRing(@c_pointer)
rescue GDAL::Error => e
  return false if e.message.include? "IllegalArgumentException"

  raise
end
segmentize!(max_length) click to toggle source

Modify the geometry so that it has no segments longer than max_length.

@param max_length [Float] @return [OGR::Geometry] Returns self that’s been segmentized.

# File lib/ogr/geometry.rb, line 519
def segmentize!(max_length)
  FFI::OGR::API.OGR_G_Segmentize(@c_pointer, max_length)

  self
end
simple?() click to toggle source

Returns TRUE if the geometry has no anomalous geometric points, such as self intersection or self tangency. The description of each instantiable geometric class will include the specific conditions that cause an instance of that class to be classified as not simple.

@return [Boolean]

# File lib/ogr/geometry.rb, line 359
def simple?
  FFI::OGR::API.OGR_G_IsSimple(@c_pointer)
end
simplify(distance_tolerance, preserve_topology: false) click to toggle source

Computes and returns a new, simplified geometry.

@param distance_tolerance [Float] @param preserve_topology [Boolean] @return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 505
def simplify(distance_tolerance, preserve_topology: false)
  build_geometry do
    if preserve_topology
      FFI::OGR::API.OGR_G_SimplifyPreserveTopology(@c_pointer, distance_tolerance)
    else
      FFI::OGR::API.OGR_G_Simplify(@c_pointer, distance_tolerance)
    end
  end
end
spatial_reference() click to toggle source

NOTE: The returned object may be shared with many geometries, and should thus not be modified.

@return [OGR::SpatialReference]

# File lib/ogr/geometry.rb, line 437
def spatial_reference
  spatial_ref_ptr = FFI::OGR::API.OGR_G_GetSpatialReference(@c_pointer)
  return if spatial_ref_ptr.null?

  OGR::SpatialReference.new(spatial_ref_ptr)
end
spatial_reference=(new_spatial_ref) click to toggle source

Assigns a spatial reference to this geometry. Any existing spatial reference is replaced, but this does not reproject the geometry.

@param new_spatial_ref [OGR::SpatialReference, FFI::Pointer]

# File lib/ogr/geometry.rb, line 448
def spatial_reference=(new_spatial_ref)
  #  Note that assigning a spatial reference increments the reference count
  #  on the OGRSpatialReference, but does not copy it.
  new_spatial_ref_ptr = GDAL._pointer(OGR::SpatialReference, new_spatial_ref, autorelease: false)

  FFI::OGR::API.OGR_G_AssignSpatialReference(@c_pointer, new_spatial_ref_ptr)
end
symmetric_difference(geometry) click to toggle source

@param geometry [OGR::Geometry] @return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 418
def symmetric_difference(geometry)
  new_geometry_ptr = FFI::OGR::API.OGR_G_SymDifference(@c_pointer, geometry.c_pointer)
  return if new_geometry_ptr.null?

  self.class.factory(new_geometry_ptr)
end
to_geo_json() click to toggle source

@return [String]

# File lib/ogr/geometry.rb, line 647
def to_geo_json
  json, ptr = FFI::OGR::API.OGR_G_ExportToJson(@c_pointer)
  FFI::CPL::VSI.VSIFree(ptr)

  json
end
to_geo_json_ex(**options) click to toggle source

@param [Hash] options @option options [String] :coordinate_precision Maximum number of figures

after decimal separate to write in coordinates.

@option options [String] :significant_figures Maximum number of

significant figures.

@return [String]

# File lib/ogr/geometry.rb, line 660
def to_geo_json_ex(**options)
  options_ptr = GDAL::Options.pointer(options)
  json, ptr = FFI::OGR::API.OGR_G_ExportToJsonEx(@c_pointer, options_ptr)
  FFI::CPL::VSI.VSIFree(ptr)

  json
end
to_gml(**options) click to toggle source

This geometry expressed as GML in GML basic data types.

@param [Hash] options @option options [String] :format “GML3” is really the only “option” here,

since without passing this in, GDAL defaults to "GML2.1.2" (as of 1.8.0).

@option options [String] :gml3_linestring_element “curve” is the only

option here, which only pertains a) to LineString geometries, and b)
when +:format+ is set to GML3.

@option options [String] :gml3_longsrs Defaults to “YES”, which prefixes

the EPSG authority with "urn:ogc:def:crs:EPSG::".  If "NO", the EPSG
authority is prefixed with "EPSG:".

@option options [String] :gmlid Use this to write a gml:id attribute at

the top level of the geometry.

@return [String]

# File lib/ogr/geometry.rb, line 628
def to_gml(**options)
  options_ptr = GDAL::Options.pointer(options)
  gml, ptr = FFI::OGR::API.OGR_G_ExportToGMLEx(@c_pointer, options_ptr)
  FFI::CPL::VSI.VSIFree(ptr)

  gml
end
to_iso_wkt() click to toggle source

@return [String] @raise [OGR::Failure]

# File lib/ogr/geometry.rb, line 606
def to_iso_wkt
  GDAL._cpl_read_and_free_string do |output_ptr|
    OGR::ErrorHandling.handle_ogr_err("Unable to export to WKT") do
      FFI::OGR::API.OGR_G_ExportToIsoWkt(@c_pointer, output_ptr)
    end
  end
end
to_kml(altitude_mode = nil) click to toggle source

@param altitude_mode [String] Value to write in the altitudeMode

element.

@return [String]

# File lib/ogr/geometry.rb, line 639
def to_kml(altitude_mode = nil)
  kml, ptr = FFI::OGR::API.OGR_G_ExportToKML(@c_pointer, altitude_mode)
  FFI::CPL::VSI.VSIFree(ptr)

  kml
end
to_line_string() click to toggle source

Converts the current geometry to a LineString geometry. The returned object is a new OGR::Geometry instance.

@return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 672
def to_line_string
  build_geometry { FFI::OGR::API.OGR_G_ForceToLineString(clone.c_pointer) }
end
to_linear_ring(close_rings: false) click to toggle source

Since GDAL doesn’t provide converting to a LinearRing, this is a hackish method for doing so.

@return [OGR::LinearRing]

# File lib/ogr/geometry.rb, line 680
def to_linear_ring(close_rings: false)
  line_string = to_line_string

  return line_string unless line_string.is_a?(OGR::LineString)

  linear_ring = OGR::LinearRing.new

  linear_ring.spatial_reference = line_string.spatial_reference.clone if line_string.spatial_reference

  linear_ring.import_from_wkt(line_string.to_wkt.tr("LINESTRING", "LINEARRING"))
  linear_ring.close_rings! if close_rings

  linear_ring
end
to_multi_line_string() click to toggle source

Converts the current geometry to a MultiLineString geometry. The returned object is a new OGR::Geometry instance.

@return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 715
def to_multi_line_string
  build_geometry { FFI::OGR::API.OGR_G_ForceToMultiLineString(clone.c_pointer) }
end
to_multi_point() click to toggle source

Converts the current geometry to a MultiPoint geometry. The returned object is a new OGR::Geometry instance.

@return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 707
def to_multi_point
  build_geometry { FFI::OGR::API.OGR_G_ForceToMultiPoint(clone.c_pointer) }
end
to_multi_polygon() click to toggle source

Converts the current geometry to a MultiPolygon geometry. The returned object is a new OGR::Geometry instance.

@return [OGR::MultiPolygon]

# File lib/ogr/geometry.rb, line 723
def to_multi_polygon
  build_geometry { FFI::OGR::API.OGR_G_ForceToMultiPolygon(@c_pointer) }
end
to_polygon() click to toggle source

Converts the current geometry to a Polygon geometry. The returned object is a new OGR::Geometry instance.

@return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 699
def to_polygon
  build_geometry { FFI::OGR::API.OGR_G_ForceToPolygon(clone.c_pointer) }
end
to_wkb(byte_order = :wkbXDR) click to toggle source

@return [String] @raise [OGR::Failure]

# File lib/ogr/geometry.rb, line 572
def to_wkb(byte_order = :wkbXDR)
  output = FFI::MemoryPointer.new(:uchar, wkb_size)

  OGR::ErrorHandling.handle_ogr_err("Unable to export geometry to WKB (using byte order #{byte_order})") do
    FFI::OGR::API.OGR_G_ExportToWkb(@c_pointer, byte_order, output)
  end

  output.read_bytes(wkb_size)
end
to_wkt() click to toggle source

@return [String] @raise [OGR::Failure]

# File lib/ogr/geometry.rb, line 596
def to_wkt
  GDAL._cpl_read_and_free_string do |output_ptr|
    OGR::ErrorHandling.handle_ogr_err("Unable to export to WKT") do
      FFI::OGR::API.OGR_G_ExportToWkt(@c_pointer, output_ptr)
    end
  end
end
touches?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 309
def touches?(geometry)
  FFI::OGR::API.OGR_G_Touches(@c_pointer, geometry.c_pointer)
end
transform!(coordinate_transformation) click to toggle source

Transforms the coordinates of this geometry in its current spatial reference system to a new spatial reference system. Normally this means reprojecting the vectors, but it could also include datum shifts, and changes of units.

Note that this doesn’t require the geometry to have an existing spatial reference system.

@param coordinate_transformation [OGR::CoordinateTransformation,

FFI::Pointer]

@raise [OGR::Failure]

# File lib/ogr/geometry.rb, line 467
def transform!(coordinate_transformation)
  coord_trans_ptr = GDAL._pointer(OGR::CoordinateTransformation,
                                  coordinate_transformation)

  return if coord_trans_ptr.nil? || coord_trans_ptr.null?

  OGR::ErrorHandling.handle_ogr_err("Unable to transform geometry") do
    FFI::OGR::API.OGR_G_Transform(@c_pointer, coord_trans_ptr)
  end
end
transform_to!(new_spatial_ref) click to toggle source

Similar to #transform, but this only works if the geometry already has an assigned spatial reference system and is transformable to the target coordinate system.

Because this function requires internal creation and initialization of an OGRCoordinateTransformation object it is significantly more expensive to use this function to transform many geometries than it is to create the OGRCoordinateTransformation in advance, and call transform() with that transformation. This function exists primarily for convenience when only transforming a single geometry.

@param new_spatial_ref [OGR::SpatialReference, FFI::Pointer] @raise [OGR::Failure]

# File lib/ogr/geometry.rb, line 491
def transform_to!(new_spatial_ref)
  new_spatial_ref_ptr = GDAL._pointer(OGR::SpatialReference, new_spatial_ref, autorelease: false)
  return if new_spatial_ref_ptr.null?

  OGR::ErrorHandling.handle_ogr_err("Unable to transform geometry") do
    FFI::OGR::API.OGR_G_TransformTo(@c_pointer, new_spatial_ref_ptr)
  end
end
type() click to toggle source

@return [FFI::OGR::API::WKBGeometryType]

# File lib/ogr/geometry.rb, line 220
def type
  FFI::OGR::API.OGR_G_GetGeometryType(@c_pointer)
end
type_to_name() click to toggle source

@return [String]

# File lib/ogr/geometry.rb, line 225
def type_to_name
  self.class.type_to_name(type)
end
union(other_geometry) click to toggle source

@param other_geometry [OGR::Geometry] @return [OGR::Geometry]

# File lib/ogr/geometry.rb, line 384
def union(other_geometry)
  build_geometry do
    FFI::OGR::API.OGR_G_Union(@c_pointer, other_geometry.c_pointer)
  end
end
valid?() click to toggle source

@return [Boolean]

# File lib/ogr/geometry.rb, line 347
def valid?
  FFI::OGR::API.OGR_G_IsValid(@c_pointer)
rescue GDAL::Error
  false
end
within?(geometry) click to toggle source

@param geometry [OGR::Geometry, FFI::Pointer] @return [Boolean]

# File lib/ogr/geometry.rb, line 322
def within?(geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
  FFI::OGR::API.OGR_G_Within(@c_pointer, geometry_ptr)
end
wkb_size() click to toggle source

The exact number of bytes required to hold the WKB of this object.

@return [Integer]

# File lib/ogr/geometry.rb, line 566
def wkb_size
  FFI::OGR::API.OGR_G_WkbSize(@c_pointer)
end

Private Instance Methods

build_geometry() { || ... } click to toggle source
# File lib/ogr/geometry.rb, line 740
def build_geometry
  new_geometry_ptr = yield
  return if new_geometry_ptr.nil? || new_geometry_ptr.null? || new_geometry_ptr == @c_pointer

  OGR::Geometry.factory(new_geometry_ptr)
end
initialize_from_pointer(geometry_ptr) click to toggle source

@param geometry_ptr [OGR::Geometry, FFI::Pointer]

# File lib/ogr/geometry.rb, line 730
def initialize_from_pointer(geometry_ptr)
  raise OGR::InvalidHandle, "Must initialize with a valid pointer: #{geometry_ptr}" if geometry_ptr.nil?

  pointer = GDAL._pointer(OGR::Geometry, geometry_ptr, autorelease: false)

  raise OGR::InvalidHandle, "Must initialize with a valid pointer: #{geometry_ptr}" if pointer.null?

  @c_pointer = pointer
end