Module: OGR::Geometry

Extended by:
ClassMethods
Includes:
EWKBIOExtensions, OGR::GeometryMixins::Extensions
Included in:
GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon, NoneGeometry, Point, Polygon, UnknownGeometry
Defined in:
lib/ogr/geometry.rb,
lib/ogr/extensions/geometry/wkb_record.rb,
lib/ogr/extensions/geometry/ewkb_record.rb,
lib/ogr/extensions/geometry/rttopo_extensions.rb,
lib/ogr/extensions/geometry/ewkb_io_extensions.rb

Defined Under Namespace

Modules: ClassMethods, EWKBIOExtensions, RttopoExtensions Classes: EWKBRecord, WKBRecord

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ClassMethods

create, create_from_gml, create_from_json, create_from_wkb, create_from_wkt, factory, merge_geometry_types, release

Methods included from EWKBIOExtensions

#to_ewkb

Methods included from OGR::GeometryMixins::Extensions

#!=, #collection?, #container?, #curve?, #invalid?, #surface?, #to_vector, #utm_zone

Instance Attribute Details

#c_pointerFFI::Pointer (readonly)



157
158
159
# File 'lib/ogr/geometry.rb', line 157

def c_pointer
  @c_pointer
end

Class Method Details

.included(base) ⇒ Object



147
148
149
150
# File 'lib/ogr/geometry.rb', line 147

def self.included(base)
  base.send(:include, GDAL::Logger)
  base.send(:extend, ClassMethods)
end

Instance Method Details

#boundaryOGR::Geometry



526
527
528
# 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) ⇒ OGR::Polygon

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



537
538
539
540
541
# 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

#centroidInteger



252
253
254
255
256
257
258
259
# 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

#cloneOGR::Geometry



166
167
168
169
170
# 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!Object

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



392
393
394
# File 'lib/ogr/geometry.rb', line 392

def close_rings!
  FFI::OGR::API.OGR_G_CloseRings(@c_pointer)
end

#contains?(geometry) ⇒ Boolean



329
330
331
332
# 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_hullOGR::Geometry



544
545
546
# File 'lib/ogr/geometry.rb', line 544

def convex_hull
  build_geometry { FFI::OGR::API.OGR_G_ConvexHull(@c_pointer) }
end

#coordinate_dimensionInteger

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



187
188
189
# File 'lib/ogr/geometry.rb', line 187

def coordinate_dimension
  FFI::OGR::API.OGR_G_GetCoordinateDimension(@c_pointer)
end

#coordinate_dimension=(new_coordinate_dimension) ⇒ Object



192
193
194
195
196
197
198
# 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

#crosses?(geometry) ⇒ Boolean



315
316
317
318
# 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!Object



159
160
161
162
163
# File 'lib/ogr/geometry.rb', line 159

def destroy!
  self.class.release(@c_pointer)

  @c_pointer = nil
end

#difference(geometry) ⇒ OGR::Geometry Also known as: -



408
409
410
411
412
413
# 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

#dimensionInteger



180
181
182
# File 'lib/ogr/geometry.rb', line 180

def dimension
  FFI::OGR::API.OGR_G_GetDimension(@c_pointer)
end

#disjoint?(geometry) ⇒ Boolean



302
303
304
305
# 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) ⇒ Float

The shortest distance between the two geometries.



429
430
431
# 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) ⇒ Object

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



273
274
275
276
277
# 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!Object

Clears all information from the geometry.



175
176
177
# File 'lib/ogr/geometry.rb', line 175

def empty!
  FFI::OGR::API.OGR_G_Empty(@c_pointer)
end

#empty?Boolean



342
343
344
# File 'lib/ogr/geometry.rb', line 342

def empty?
  FFI::OGR::API.OGR_G_IsEmpty(@c_pointer)
end

#envelopeOGR::Envelope



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# 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) ⇒ Boolean Also known as: ==



293
294
295
296
297
# 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

#flatten_to_2d!Object

Converts this geometry to a 2D geometry.



280
281
282
# File 'lib/ogr/geometry.rb', line 280

def flatten_to_2d!
  FFI::OGR::API.OGR_G_FlattenTo2D(@c_pointer)
end

#geometry_countInteger Also known as: count



239
240
241
# File 'lib/ogr/geometry.rb', line 239

def geometry_count
  FFI::OGR::API.OGR_G_GetGeometryCount(@c_pointer)
end

#import_from_wkb(wkb_data) ⇒ Object

Raises:



557
558
559
560
561
# 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) ⇒ Object

Raises:



584
585
586
587
588
589
590
591
592
# 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) ⇒ OGR::Geometry



376
377
378
379
380
# 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) ⇒ Boolean



286
287
288
289
# 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?Boolean



261
262
263
# File 'lib/ogr/geometry.rb', line 261

def is_2d?
  coordinate_dimension == 2
end

#is_3d?Boolean



265
266
267
# File 'lib/ogr/geometry.rb', line 265

def is_3d?
  coordinate_dimension == 3
end

#nameString



230
231
232
233
234
235
236
# 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) ⇒ Boolean



336
337
338
339
# 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_countInteger



245
246
247
248
249
# 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_surfaceOGR::Point

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



551
552
553
# File 'lib/ogr/geometry.rb', line 551

def point_on_surface
  build_geometry { FFI::OGR::API.OGR_G_PointOnSurface(@c_pointer) }
end

#polygonizeOGR::Geometry

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



402
403
404
# File 'lib/ogr/geometry.rb', line 402

def polygonize
  build_geometry { FFI::OGR::API.OGR_G_Polygonize(@c_pointer) }
end

#ring?Boolean

TRUE if the geometry has no points, otherwise FALSE.



366
367
368
369
370
371
372
# 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) ⇒ OGR::Geometry

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



519
520
521
522
523
# File 'lib/ogr/geometry.rb', line 519

def segmentize!(max_length)
  FFI::OGR::API.OGR_G_Segmentize(@c_pointer, max_length)

  self
end

#simple?Boolean

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.



359
360
361
# File 'lib/ogr/geometry.rb', line 359

def simple?
  FFI::OGR::API.OGR_G_IsSimple(@c_pointer)
end

#simplify(distance_tolerance, preserve_topology: false) ⇒ OGR::Geometry

Computes and returns a new, simplified geometry.



505
506
507
508
509
510
511
512
513
# 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_referenceOGR::SpatialReference

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



437
438
439
440
441
442
# 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) ⇒ Object

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



448
449
450
451
452
453
454
# 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) ⇒ OGR::Geometry



418
419
420
421
422
423
# 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_jsonString



647
648
649
650
651
652
# 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) ⇒ String

Options Hash (**options):

  • :coordinate_precision (String)

    Maximum number of figures after decimal separate to write in coordinates.

  • :significant_figures (String)

    Maximum number of significant figures.



660
661
662
663
664
665
666
# 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) ⇒ String

This geometry expressed as GML in GML basic data types.

Options Hash (**options):

  • :format (String)

    “GML3” is really the only “option” here, since without passing this in, GDAL defaults to “GML2.1.2” (as of 1.8.0).

  • :gml3_linestring_element (String)

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

  • :gml3_longsrs (String)

    Defaults to “YES”, which prefixes the EPSG authority with “urn:ogc:def:crs:EPSG::”. If “NO”, the EPSG authority is prefixed with “EPSG:”.

  • :gmlid (String)

    Use this to write a gml:id attribute at the top level of the geometry.



628
629
630
631
632
633
634
# 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_wktString

Raises:



606
607
608
609
610
611
612
# 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) ⇒ String



639
640
641
642
643
644
# 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_stringOGR::Geometry

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



672
673
674
# 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) ⇒ OGR::LinearRing

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



680
681
682
683
684
685
686
687
688
689
690
691
692
693
# 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_stringOGR::Geometry

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



715
716
717
# 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_pointOGR::Geometry

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



707
708
709
# 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_polygonOGR::MultiPolygon

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



723
724
725
# File 'lib/ogr/geometry.rb', line 723

def to_multi_polygon
  build_geometry { FFI::OGR::API.OGR_G_ForceToMultiPolygon(@c_pointer) }
end

#to_polygonOGR::Geometry

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



699
700
701
# 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) ⇒ String

Raises:



572
573
574
575
576
577
578
579
580
# 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_wktString

Raises:



596
597
598
599
600
601
602
# 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) ⇒ Boolean



309
310
311
# 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) ⇒ Object

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.

Raises:



467
468
469
470
471
472
473
474
475
476
# 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) ⇒ Object

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.

Raises:



491
492
493
494
495
496
497
498
# 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

#typeFFI::OGR::API::WKBGeometryType



220
221
222
# File 'lib/ogr/geometry.rb', line 220

def type
  FFI::OGR::API.OGR_G_GetGeometryType(@c_pointer)
end

#type_to_nameString



225
226
227
# File 'lib/ogr/geometry.rb', line 225

def type_to_name
  self.class.type_to_name(type)
end

#union(other_geometry) ⇒ OGR::Geometry



384
385
386
387
388
# 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?Boolean



347
348
349
350
351
# File 'lib/ogr/geometry.rb', line 347

def valid?
  FFI::OGR::API.OGR_G_IsValid(@c_pointer)
rescue GDAL::Error
  false
end

#within?(geometry) ⇒ Boolean



322
323
324
325
# 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_sizeInteger

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



566
567
568
# File 'lib/ogr/geometry.rb', line 566

def wkb_size
  FFI::OGR::API.OGR_G_WkbSize(@c_pointer)
end