Class: Geos::Geometry

Inherits:
Object
  • Object
show all
Includes:
Tools
Defined in:
lib/ffi-geos/geometry.rb

Direct Known Subclasses

GeometryCollection, LineString, Point, Polygon

Defined Under Namespace

Classes: CouldntNormalizeError

Constant Summary

Constants included from GeomTypes

Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION, Geos::GeomTypes::GEOS_LINEARRING, Geos::GeomTypes::GEOS_LINESTRING, Geos::GeomTypes::GEOS_MULTILINESTRING, Geos::GeomTypes::GEOS_MULTIPOINT, Geos::GeomTypes::GEOS_MULTIPOLYGON, Geos::GeomTypes::GEOS_POINT, Geos::GeomTypes::GEOS_POLYGON

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Tools

#bool_result, #bool_to_int, #cast_geometry_ptr, #check_enum_value, #check_geometry, #extract_options!, #pick_srid_according_to_policy, #pick_srid_from_geoms, #symbol_for_enum

Constructor Details

#initialize(ptr, options = {}) ⇒ Geometry

For internal use. Geometry objects should be created via WkbReader, WktReader and the various Geos.create_* methods.



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ffi-geos/geometry.rb', line 17

def initialize(ptr, options = {})
  options = {
    auto_free: true
  }.merge(options)

  @ptr = FFI::AutoPointer.new(
    ptr,
    self.class.method(:release)
  )

  @ptr.autorelease = !!options[:auto_free]
  @parent = options[:parent] if options[:parent]
end

Instance Attribute Details

#ptrObject (readonly)

Returns the value of attribute ptr.



7
8
9
# File 'lib/ffi-geos/geometry.rb', line 7

def ptr
  @ptr
end

Class Method Details

.release(ptr) ⇒ Object

:nodoc:



41
42
43
# File 'lib/ffi-geos/geometry.rb', line 41

def self.release(ptr) # :nodoc:
  FFIGeos.GEOSGeom_destroy_r(Geos.current_handle_pointer, ptr)
end

Instance Method Details

#==(other) ⇒ Object



448
449
450
451
452
# File 'lib/ffi-geos/geometry.rb', line 448

def ==(other)
  return eql?(other) if other.is_a?(Geos::Geometry)

  false
end

#areaObject



570
571
572
573
574
575
576
# File 'lib/ffi-geos/geometry.rb', line 570

def area
  return 0 if empty?

  double_ptr = FFI::MemoryPointer.new(:double)
  FFIGeos.GEOSArea_r(Geos.current_handle_pointer, ptr, double_ptr)
  double_ptr.read_double
end

#boundaryObject



213
214
215
# File 'lib/ffi-geos/geometry.rb', line 213

def boundary
  cast_geometry_ptr(FFIGeos.GEOSBoundary_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#buffer(width, options = nil) ⇒ Object

:call-seq:

buffer(width)
buffer(width, options)
buffer(width, buffer_params)
buffer(width, quad_segs)

Calls buffer on the Geometry. Options can be passed as either a BufferParams object, as an equivalent Hash or as a quad_segs value. Default values can be found in Geos::Constants::BUFFER_PARAM_DEFAULTS.

Note that when using versions of GEOS prior to 3.3.0, only the quad_segs option is recognized when using Geometry#buffer and other options are ignored.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/ffi-geos/geometry.rb', line 122

def buffer(width, options = nil)
  options ||= {}
  params = case options
    when Hash
      Geos::BufferParams.new(options)
    when Geos::BufferParams
      options
    when Numeric
      Geos::BufferParams.new(quad_segs: options)
    else
      raise ArgumentError, 'Expected Geos::BufferParams, a Hash or a Numeric'
  end

  cast_geometry_ptr(FFIGeos.GEOSBufferWithParams_r(Geos.current_handle_pointer, ptr, params.ptr, width), srid_copy: srid)
end

#build_areaObject

Added in GEOS 3.8+



697
698
699
# File 'lib/ffi-geos/geometry.rb', line 697

def build_area
  cast_geometry_ptr(FFIGeos.GEOSBuildArea_r(Geos.current_handle_pointer, ptr))
end

#centroidObject Also known as: center



285
286
287
# File 'lib/ffi-geos/geometry.rb', line 285

def centroid
  cast_geometry_ptr(FFIGeos.GEOSGetCentroid_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#clip_by_rect(xmin, ymin, xmax, ymax) ⇒ Object Also known as: clip_by_rectangle

Available in GEOS 3.5.0+.



279
280
281
# File 'lib/ffi-geos/geometry.rb', line 279

def clip_by_rect(xmin, ymin, xmax, ymax)
  cast_geometry_ptr(FFIGeos.GEOSClipByRect_r(Geos.current_handle_pointer, ptr, xmin, ymin, xmax, ymax))
end

#concave_hull(ratio: 0.0, allow_holes: false, length: nil) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
# File 'lib/ffi-geos/geometry.rb', line 166

def concave_hull(ratio: 0.0, allow_holes: false, length: nil)
  cast_geometry_ptr(
    case length
      when Numeric
        FFIGeos.GEOSConcaveHullByLength_r(Geos.current_handle_pointer, ptr, length, bool_to_int(allow_holes))
      else
        FFIGeos.GEOSConcaveHull_r(Geos.current_handle_pointer, ptr, ratio, bool_to_int(allow_holes))
    end,
    srid_copy: srid
  )
end

#concave_hull_of_polygons(length_ratio, tight: false, allow_holes: false) ⇒ Object



797
798
799
# File 'lib/ffi-geos/geometry.rb', line 797

def concave_hull_of_polygons(length_ratio, tight: false, allow_holes: false)
  cast_geometry_ptr(FFIGeos.GEOSConcaveHullOfPolygons_r(Geos.current_handle_pointer, ptr, length_ratio, bool_to_int(tight), bool_to_int(allow_holes)), srid_copy: srid)
end

#constrained_delaunay_triangulationObject



729
730
731
# File 'lib/ffi-geos/geometry.rb', line 729

def constrained_delaunay_triangulation
  cast_geometry_ptr(FFIGeos.GEOSConstrainedDelaunayTriangulation_r(Geos.current_handle_pointer, ptr))
end

#contains?(geom) ⇒ Boolean

Returns:

  • (Boolean)


388
389
390
391
# File 'lib/ffi-geos/geometry.rb', line 388

def contains?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSContains_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#convex_hullObject



161
162
163
# File 'lib/ffi-geos/geometry.rb', line 161

def convex_hull
  cast_geometry_ptr(FFIGeos.GEOSConvexHull_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#coord_seqObject



94
95
96
# File 'lib/ffi-geos/geometry.rb', line 94

def coord_seq
  CoordinateSequence.new(FFIGeos.GEOSGeom_getCoordSeq_r(Geos.current_handle_pointer, ptr), false, self)
end

#coverage_unionObject

Added in GEOS 3.8+



242
243
244
# File 'lib/ffi-geos/geometry.rb', line 242

def coverage_union
  cast_geometry_ptr(FFIGeos.GEOSCoverageUnion_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#covered_by?(geom) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


424
425
426
427
# File 'lib/ffi-geos/geometry.rb', line 424

def covered_by?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSCoveredBy_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#covers?(geom) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


402
403
404
405
# File 'lib/ffi-geos/geometry.rb', line 402

def covers?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSCovers_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#crosses?(geom) ⇒ Boolean

Returns:

  • (Boolean)


378
379
380
381
# File 'lib/ffi-geos/geometry.rb', line 378

def crosses?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSCrosses_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#delaunay_triangulation(*args) ⇒ Object

:call-seq:

 delaunay_triangulation(options = {})
 delaunay_triangulation(tolerance, options = {})

Options:

* :tolerance
* :only_edges


718
719
720
721
722
723
724
725
# File 'lib/ffi-geos/geometry.rb', line 718

def delaunay_triangulation(*args)
  options = extract_options!(args)

  tolerance = args.first || options[:tolerance] || 0.0
  only_edges = bool_to_int(options[:only_edges])

  cast_geometry_ptr(FFIGeos.GEOSDelaunayTriangulation_r(Geos.current_handle_pointer, ptr, tolerance, only_edges))
end

#densify(tolerance = 0.0) ⇒ Object



156
157
158
# File 'lib/ffi-geos/geometry.rb', line 156

def densify(tolerance = 0.0)
  cast_geometry_ptr(FFIGeos.GEOSDensify_r(Geos.current_handle_pointer, ptr, tolerance), srid_copy: srid)
end

#difference(geom, precision: nil) ⇒ Object



192
193
194
195
196
197
198
199
200
# File 'lib/ffi-geos/geometry.rb', line 192

def difference(geom, precision: nil)
  check_geometry(geom)

  if precision
    cast_geometry_ptr(FFIGeos.GEOSDifferencePrec_r(Geos.current_handle_pointer, ptr, geom.ptr, precision), srid_copy: pick_srid_from_geoms(srid, geom.srid))
  else
    cast_geometry_ptr(FFIGeos.GEOSDifference_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
  end
end

#dimensionsObject



82
83
84
# File 'lib/ffi-geos/geometry.rb', line 82

def dimensions
  FFIGeos.GEOSGeom_getDimensions_r(Geos.current_handle_pointer, ptr)
end

#disjoint?(geom) ⇒ Boolean

Returns:

  • (Boolean)


363
364
365
366
# File 'lib/ffi-geos/geometry.rb', line 363

def disjoint?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSDisjoint_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#disjoint_subset_unionObject

Added in GEOS 3.12+



249
250
251
# File 'lib/ffi-geos/geometry.rb', line 249

def disjoint_subset_union
  cast_geometry_ptr(FFIGeos.GEOSDisjointSubsetUnion_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#distance(geom) ⇒ Object



586
587
588
589
590
591
# File 'lib/ffi-geos/geometry.rb', line 586

def distance(geom)
  check_geometry(geom)
  double_ptr = FFI::MemoryPointer.new(:double)
  FFIGeos.GEOSDistance_r(Geos.current_handle_pointer, ptr, geom.ptr, double_ptr)
  double_ptr.read_double
end

#distance_indexed(geom) ⇒ Object Also known as: indexed_distance

Available in GEOS 3.7+.



595
596
597
598
599
600
# File 'lib/ffi-geos/geometry.rb', line 595

def distance_indexed(geom)
  check_geometry(geom)
  double_ptr = FFI::MemoryPointer.new(:double)
  FFIGeos.GEOSDistanceIndexed_r(Geos.current_handle_pointer, ptr, geom.ptr, double_ptr)
  double_ptr.read_double
end

#empty?Boolean

Returns:

  • (Boolean)


476
477
478
# File 'lib/ffi-geos/geometry.rb', line 476

def empty?
  bool_result(FFIGeos.GEOSisEmpty_r(Geos.current_handle_pointer, ptr))
end

#end_pointObject



566
567
568
# File 'lib/ffi-geos/geometry.rb', line 566

def end_point
  cast_geometry_ptr(FFIGeos.GEOSGeomGetEndPoint_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#envelopeObject



307
308
309
# File 'lib/ffi-geos/geometry.rb', line 307

def envelope
  cast_geometry_ptr(FFIGeos.GEOSEnvelope_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#eql?(other) ⇒ Boolean Also known as: equals?

Returns:

  • (Boolean)


442
443
444
445
# File 'lib/ffi-geos/geometry.rb', line 442

def eql?(other)
  check_geometry(other)
  bool_result(FFIGeos.GEOSEquals_r(Geos.current_handle_pointer, ptr, other.ptr))
end

#eql_almost?(other, decimal = 6) ⇒ Boolean Also known as: equals_almost?, almost_equals?

Returns:

  • (Boolean)


469
470
471
472
# File 'lib/ffi-geos/geometry.rb', line 469

def eql_almost?(other, decimal = 6)
  check_geometry(other)
  bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer, ptr, other.ptr, 0.5 * (10 ** -decimal)))
end

#eql_exact?(other, tolerance) ⇒ Boolean Also known as: equals_exact?, exactly_equals?

Returns:

  • (Boolean)


454
455
456
457
# File 'lib/ffi-geos/geometry.rb', line 454

def eql_exact?(other, tolerance)
  check_geometry(other)
  bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle_pointer, ptr, other.ptr, tolerance))
end

#eql_identical?(other) ⇒ Boolean Also known as: equals_identical?

Returns:

  • (Boolean)


462
463
464
465
# File 'lib/ffi-geos/geometry.rb', line 462

def eql_identical?(other)
  check_geometry(other)
  bool_result(FFIGeos.GEOSEqualsIdentical_r(Geos.current_handle_pointer, ptr, other.ptr))
end

#extract_unique_pointsObject Also known as: unique_points



358
359
360
# File 'lib/ffi-geos/geometry.rb', line 358

def extract_unique_points
  cast_geometry_ptr(FFIGeos.GEOSGeom_extractUniquePoints_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#frechet_distance(geom, densify_frac = nil) ⇒ Object



847
848
849
850
851
852
853
854
855
856
857
858
859
# File 'lib/ffi-geos/geometry.rb', line 847

def frechet_distance(geom, densify_frac = nil)
  check_geometry(geom)

  double_ptr = FFI::MemoryPointer.new(:double)

  if densify_frac
    FFIGeos.GEOSFrechetDistanceDensify_r(Geos.current_handle_pointer, ptr, geom.ptr, densify_frac, double_ptr)
  else
    FFIGeos.GEOSFrechetDistance_r(Geos.current_handle_pointer, ptr, geom.ptr, double_ptr)
  end

  double_ptr.read_double
end

#geom_typeObject

Returns the name of the Geometry type, i.e. “Point”, “Polygon”, etc.



46
47
48
# File 'lib/ffi-geos/geometry.rb', line 46

def geom_type
  FFIGeos.GEOSGeomType_r(Geos.current_handle_pointer, ptr)
end

#has_m?Boolean

Returns:

  • (Boolean)


525
526
527
# File 'lib/ffi-geos/geometry.rb', line 525

def has_m?
  bool_result(FFIGeos.GEOSHasM_r(Geos.current_handle_pointer, ptr))
end

#has_z?Boolean

Returns:

  • (Boolean)


520
521
522
# File 'lib/ffi-geos/geometry.rb', line 520

def has_z?
  bool_result(FFIGeos.GEOSHasZ_r(Geos.current_handle_pointer, ptr))
end

#hausdorff_distance(geom, densify_frac = nil) ⇒ Object



604
605
606
607
608
609
610
611
612
613
614
615
616
# File 'lib/ffi-geos/geometry.rb', line 604

def hausdorff_distance(geom, densify_frac = nil)
  check_geometry(geom)

  double_ptr = FFI::MemoryPointer.new(:double)

  if densify_frac
    FFIGeos.GEOSHausdorffDistanceDensify_r(Geos.current_handle_pointer, ptr, geom.ptr, densify_frac, double_ptr)
  else
    FFIGeos.GEOSHausdorffDistance_r(Geos.current_handle_pointer, ptr, geom.ptr, double_ptr)
  end

  double_ptr.read_double
end

#hilbert_code(extent, level) ⇒ Object



291
292
293
294
295
296
# File 'lib/ffi-geos/geometry.rb', line 291

def hilbert_code(extent, level)
  check_geometry(extent)
  code_ptr = FFI::MemoryPointer.new(:uint)
  FFIGeos.GEOSHilbertCode_r(Geos.current_handle_pointer, ptr, extent.ptr, level, code_ptr)
  code_ptr.read_uint
end

#initialize_copy(source) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/ffi-geos/geometry.rb', line 31

def initialize_copy(source)
  @ptr = FFI::AutoPointer.new(
    FFIGeos.GEOSGeom_clone_r(Geos.current_handle_pointer, source.ptr),
    self.class.method(:release)
  )

  # Copy over SRID since GEOS does not
  self.srid = source.srid
end

#interpolate(d, normalized = false) ⇒ Object



548
549
550
551
552
553
554
555
556
# File 'lib/ffi-geos/geometry.rb', line 548

def interpolate(d, normalized = false)
  ret = if normalized
    FFIGeos.GEOSInterpolateNormalized_r(Geos.current_handle_pointer, ptr, d)
  else
    FFIGeos.GEOSInterpolate_r(Geos.current_handle_pointer, ptr, d)
  end

  cast_geometry_ptr(ret, srid_copy: srid)
end

#interpolate_normalized(d) ⇒ Object



558
559
560
# File 'lib/ffi-geos/geometry.rb', line 558

def interpolate_normalized(d)
  interpolate(d, true)
end

#intersection(geom, precision: nil) ⇒ Object



98
99
100
101
102
103
104
105
106
# File 'lib/ffi-geos/geometry.rb', line 98

def intersection(geom, precision: nil)
  check_geometry(geom)

  if precision
    cast_geometry_ptr(FFIGeos.GEOSIntersectionPrec_r(Geos.current_handle_pointer, ptr, geom.ptr, precision), srid_copy: pick_srid_from_geoms(srid, geom.srid))
  else
    cast_geometry_ptr(FFIGeos.GEOSIntersection_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
  end
end

#intersects?(geom) ⇒ Boolean

Returns:

  • (Boolean)


373
374
375
376
# File 'lib/ffi-geos/geometry.rb', line 373

def intersects?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSIntersects_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#largest_empty_circle(precision, boundary: nil) ⇒ Object



829
830
831
# File 'lib/ffi-geos/geometry.rb', line 829

def largest_empty_circle(precision, boundary: nil)
  cast_geometry_ptr(FFIGeos.GEOSLargestEmptyCircle_r(Geos.current_handle_pointer, ptr, boundary ? boundary.ptr : nil, precision))
end

#lengthObject



578
579
580
581
582
583
584
# File 'lib/ffi-geos/geometry.rb', line 578

def length
  return 0 if empty?

  double_ptr = FFI::MemoryPointer.new(:double)
  FFIGeos.GEOSLength_r(Geos.current_handle_pointer, ptr, double_ptr)
  double_ptr.read_double
end

#line_mergeObject



333
334
335
# File 'lib/ffi-geos/geometry.rb', line 333

def line_merge
  cast_geometry_ptr(FFIGeos.GEOSLineMerge_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#line_merge_directedObject



338
339
340
# File 'lib/ffi-geos/geometry.rb', line 338

def line_merge_directed
  cast_geometry_ptr(FFIGeos.GEOSLineMergeDirected_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#line_substring(start_fraction, end_fraction) ⇒ Object

Added in GEOS 3.12+



345
346
347
# File 'lib/ffi-geos/geometry.rb', line 345

def line_substring(start_fraction, end_fraction)
  cast_geometry_ptr(FFIGeos.GEOSLineSubstring_r(Geos.current_handle_pointer, ptr, start_fraction, end_fraction), srid_copy: srid)
end

#make_validObject

Added in GEOS 3.8+



704
705
706
# File 'lib/ffi-geos/geometry.rb', line 704

def make_valid
  cast_geometry_ptr(FFIGeos.GEOSMakeValid_r(Geos.current_handle_pointer, ptr))
end

#maximum_inscribed_circle(precision) ⇒ Object



823
824
825
# File 'lib/ffi-geos/geometry.rb', line 823

def maximum_inscribed_circle(precision)
  cast_geometry_ptr(FFIGeos.GEOSMaximumInscribedCircle_r(Geos.current_handle_pointer, ptr, precision))
end

#minimum_bounding_circleObject

Added in GEOS 3.8+. Does not yet support the radius or center arguments.



302
303
304
# File 'lib/ffi-geos/geometry.rb', line 302

def minimum_bounding_circle
  cast_geometry_ptr(FFIGeos.GEOSMinimumBoundingCircle_r(Geos.current_handle_pointer, ptr, nil, nil), srid_copy: srid)
end

#minimum_clearanceObject



809
810
811
812
813
# File 'lib/ffi-geos/geometry.rb', line 809

def minimum_clearance
  double_ptr = FFI::MemoryPointer.new(:double)
  FFIGeos.GEOSMinimumClearance_r(Geos.current_handle_pointer, ptr, double_ptr)
  double_ptr.read_double
end

#minimum_clearance_lineObject



817
818
819
# File 'lib/ffi-geos/geometry.rb', line 817

def minimum_clearance_line
  cast_geometry_ptr(FFIGeos.GEOSMinimumClearanceLine_r(Geos.current_handle_pointer, ptr))
end

#minimum_rotated_rectangleObject



803
804
805
# File 'lib/ffi-geos/geometry.rb', line 803

def minimum_rotated_rectangle
  cast_geometry_ptr(FFIGeos.GEOSMinimumRotatedRectangle_r(Geos.current_handle_pointer, ptr))
end

#minimum_widthObject



835
836
837
# File 'lib/ffi-geos/geometry.rb', line 835

def minimum_width
  cast_geometry_ptr(FFIGeos.GEOSMinimumWidth_r(Geos.current_handle_pointer, ptr))
end

#nearest_points(geom) ⇒ Object

Available in GEOS 3.4+.



620
621
622
623
624
625
# File 'lib/ffi-geos/geometry.rb', line 620

def nearest_points(geom)
  check_geometry(geom)
  nearest_points_ptr = FFIGeos.GEOSNearestPoints_r(Geos.current_handle_pointer, ptr, geom.ptr)

  CoordinateSequence.new(nearest_points_ptr) unless nearest_points_ptr.null?
end

#nodeObject

Available in GEOS 3.3.4+



267
268
269
# File 'lib/ffi-geos/geometry.rb', line 267

def node
  cast_geometry_ptr(FFIGeos.GEOSNode_r(Geos.current_handle_pointer, ptr))
end

#normalize!Object Also known as: normalize



55
56
57
58
59
# File 'lib/ffi-geos/geometry.rb', line 55

def normalize!
  raise Geos::Geometry::CouldntNormalizeError, self.class if FFIGeos.GEOSNormalize_r(Geos.current_handle_pointer, ptr) == -1

  self
end

#num_coordinatesObject



90
91
92
# File 'lib/ffi-geos/geometry.rb', line 90

def num_coordinates
  FFIGeos.GEOSGetNumCoordinates_r(Geos.current_handle_pointer, ptr)
end

#num_geometriesObject



86
87
88
# File 'lib/ffi-geos/geometry.rb', line 86

def num_geometries
  FFIGeos.GEOSGetNumGeometries_r(Geos.current_handle_pointer, ptr)
end

#orient_polygons(exterior_cw = false) ⇒ Object



69
70
71
# File 'lib/ffi-geos/geometry.rb', line 69

def orient_polygons(exterior_cw = false)
  dup.orient_polygons!(exterior_cw)
end

#orient_polygons!(exterior_cw = false) ⇒ Object



63
64
65
66
67
# File 'lib/ffi-geos/geometry.rb', line 63

def orient_polygons!(exterior_cw = false)
  raise Geos::GEOSException, self.class if FFIGeos.GEOSOrientPolygons_r(Geos.current_handle_pointer, ptr, bool_to_int(exterior_cw)) == -1

  self
end

#overlaps?(geom) ⇒ Boolean

Returns:

  • (Boolean)


393
394
395
396
# File 'lib/ffi-geos/geometry.rb', line 393

def overlaps?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSOverlaps_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#point_on_surfaceObject Also known as: representative_point



272
273
274
# File 'lib/ffi-geos/geometry.rb', line 272

def point_on_surface
  cast_geometry_ptr(FFIGeos.GEOSPointOnSurface_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#polygon_hull_simplify(parameter, outer: false, mode: :vertex_ratio) ⇒ Object



180
181
182
183
184
185
186
187
188
189
# File 'lib/ffi-geos/geometry.rb', line 180

def polygon_hull_simplify(parameter, outer: false, mode: :vertex_ratio)
  check_enum_value(Geos::PolygonHullSimplifyModes, mode)

  case mode
    when :vertex_ratio
      cast_geometry_ptr(FFIGeos.GEOSPolygonHullSimplify_r(Geos.current_handle_pointer, ptr, bool_to_int(outer), parameter), srid_copy: srid)
    when :area_ratio
      cast_geometry_ptr(FFIGeos.GEOSPolygonHullSimplifyMode_r(Geos.current_handle_pointer, ptr, bool_to_int(outer), 2, parameter), srid_copy: srid)
  end
end

#polygonize(*geoms) ⇒ Object



666
667
668
669
670
671
672
673
674
675
676
# File 'lib/ffi-geos/geometry.rb', line 666

def polygonize(*geoms)
  geoms.each do |geom|
    raise ArgumentError unless geom.is_a?(Geos::Geometry)
  end

  ary = [ptr].concat(geoms.collect(&:ptr))
  ary_ptr = FFI::MemoryPointer.new(:pointer, ary.length)
  ary_ptr.write_array_of_pointer(ary)

  cast_geometry_ptr(FFIGeos.GEOSPolygonize_r(Geos.current_handle_pointer, ary_ptr, ary.length), srid_copy: srid).to_a
end

#polygonize_cut_edgesObject



688
689
690
691
692
693
# File 'lib/ffi-geos/geometry.rb', line 688

def polygonize_cut_edges
  ary = FFI::MemoryPointer.new(:pointer)
  ary.write_array_of_pointer([ptr])

  cast_geometry_ptr(FFIGeos.GEOSPolygonizer_getCutEdges_r(Geos.current_handle_pointer, ary, 1), srid_copy: srid).to_a
end

#polygonize_fullObject

Returns a Hash with the following structure:

{
  rings: [ ... ],
  cuts: [ ... ],
  dangles: [ ... ],
  invalid_rings: [ ... ]
}


647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
# File 'lib/ffi-geos/geometry.rb', line 647

def polygonize_full
  cuts = FFI::MemoryPointer.new(:pointer)
  dangles = FFI::MemoryPointer.new(:pointer)
  invalid_rings = FFI::MemoryPointer.new(:pointer)

  rings = cast_geometry_ptr(FFIGeos.GEOSPolygonize_full_r(Geos.current_handle_pointer, ptr, cuts, dangles, invalid_rings), srid_copy: srid)

  cuts = cast_geometry_ptr(cuts.read_pointer, srid_copy: srid)
  dangles = cast_geometry_ptr(dangles.read_pointer, srid_copy: srid)
  invalid_rings = cast_geometry_ptr(invalid_rings.read_pointer, srid_copy: srid)

  {
    rings: rings.to_a,
    cuts: cuts.to_a,
    dangles: dangles.to_a,
    invalid_rings: invalid_rings.to_a
  }
end

#polygonize_validObject

Added in GEOS 3.8+



680
681
682
683
684
685
# File 'lib/ffi-geos/geometry.rb', line 680

def polygonize_valid
  ary = FFI::MemoryPointer.new(:pointer)
  ary.write_array_of_pointer([ptr])

  cast_geometry_ptr(FFIGeos.GEOSPolygonize_valid_r(Geos.current_handle_pointer, ary, 1), srid_copy: srid)
end

#precisionObject



775
776
777
# File 'lib/ffi-geos/geometry.rb', line 775

def precision
  FFIGeos.GEOSGeom_getPrecision_r(Geos.current_handle_pointer, ptr)
end

#project(geom, normalized = false) ⇒ Object

Raises:

  • (TypeError)


533
534
535
536
537
538
539
540
541
# File 'lib/ffi-geos/geometry.rb', line 533

def project(geom, normalized = false)
  raise TypeError, 'Expected Geos::Point type' unless geom.is_a?(Geos::Point)

  if normalized
    FFIGeos.GEOSProjectNormalized_r(Geos.current_handle_pointer, ptr, geom.ptr)
  else
    FFIGeos.GEOSProject_r(Geos.current_handle_pointer, ptr, geom.ptr)
  end
end

#project_normalized(geom) ⇒ Object



543
544
545
# File 'lib/ffi-geos/geometry.rb', line 543

def project_normalized(geom)
  project(geom, true)
end

#relate(geom) ⇒ Object

Returns the Dimensionally Extended Nine-Intersection Model (DE-9IM) matrix of the geometries as a String.



313
314
315
316
# File 'lib/ffi-geos/geometry.rb', line 313

def relate(geom)
  check_geometry(geom)
  FFIGeos.GEOSRelate_r(Geos.current_handle_pointer, ptr, geom.ptr)
end

#relate_boundary_node_rule(geom, bnr = :mod2) ⇒ Object

Available in GEOS 3.3+.



326
327
328
329
330
# File 'lib/ffi-geos/geometry.rb', line 326

def relate_boundary_node_rule(geom, bnr = :mod2)
  check_geometry(geom)
  check_enum_value(Geos::RelateBoundaryNodeRules, bnr)
  FFIGeos.GEOSRelateBoundaryNodeRule_r(Geos.current_handle_pointer, ptr, geom.ptr, bnr)
end

#relate_pattern(geom, pattern) ⇒ Object

Checks the DE-9IM pattern against the geoms.



319
320
321
322
# File 'lib/ffi-geos/geometry.rb', line 319

def relate_pattern(geom, pattern)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSRelatePattern_r(Geos.current_handle_pointer, ptr, geom.ptr, pattern))
end

#reverseObject



841
842
843
# File 'lib/ffi-geos/geometry.rb', line 841

def reverse
  cast_geometry_ptr(FFIGeos.GEOSReverse_r(Geos.current_handle_pointer, ptr))
end

#ring?Boolean

Returns:

  • (Boolean)


516
517
518
# File 'lib/ffi-geos/geometry.rb', line 516

def ring?
  bool_result(FFIGeos.GEOSisRing_r(Geos.current_handle_pointer, ptr))
end

#shared_paths(geom) ⇒ Object



634
635
636
637
# File 'lib/ffi-geos/geometry.rb', line 634

def shared_paths(geom)
  check_geometry(geom)
  cast_geometry_ptr(FFIGeos.GEOSSharedPaths_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid)).to_a
end

#simple?Boolean

Returns:

  • (Boolean)


512
513
514
# File 'lib/ffi-geos/geometry.rb', line 512

def simple?
  bool_result(FFIGeos.GEOSisSimple_r(Geos.current_handle_pointer, ptr))
end

#simplify(tolerance) ⇒ Object



350
351
352
# File 'lib/ffi-geos/geometry.rb', line 350

def simplify(tolerance)
  cast_geometry_ptr(FFIGeos.GEOSSimplify_r(Geos.current_handle_pointer, ptr, tolerance), srid_copy: srid)
end

#snap(geom, tolerance) ⇒ Object Also known as: snap_to



628
629
630
631
# File 'lib/ffi-geos/geometry.rb', line 628

def snap(geom, tolerance)
  check_geometry(geom)
  cast_geometry_ptr(FFIGeos.GEOSSnap_r(Geos.current_handle_pointer, ptr, geom.ptr, tolerance), srid_copy: pick_srid_from_geoms(srid, geom.srid))
end

#sridObject



74
75
76
# File 'lib/ffi-geos/geometry.rb', line 74

def srid
  FFIGeos.GEOSGetSRID_r(Geos.current_handle_pointer, ptr)
end

#srid=(s) ⇒ Object



78
79
80
# File 'lib/ffi-geos/geometry.rb', line 78

def srid=(s)
  FFIGeos.GEOSSetSRID_r(Geos.current_handle_pointer, ptr, s)
end

#start_pointObject



562
563
564
# File 'lib/ffi-geos/geometry.rb', line 562

def start_point
  cast_geometry_ptr(FFIGeos.GEOSGeomGetStartPoint_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#sym_difference(geom, precision: nil) ⇒ Object Also known as: symmetric_difference



202
203
204
205
206
207
208
209
210
# File 'lib/ffi-geos/geometry.rb', line 202

def sym_difference(geom, precision: nil)
  check_geometry(geom)

  if precision
    cast_geometry_ptr(FFIGeos.GEOSSymDifferencePrec_r(Geos.current_handle_pointer, ptr, geom.ptr, precision), srid_copy: pick_srid_from_geoms(srid, geom.srid))
  else
    cast_geometry_ptr(FFIGeos.GEOSSymDifference_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
  end
end

#to_preparedObject



762
763
764
# File 'lib/ffi-geos/geometry.rb', line 762

def to_prepared
  Geos::PreparedGeometry.new(self)
end

#to_sObject



766
767
768
769
770
771
772
# File 'lib/ffi-geos/geometry.rb', line 766

def to_s
  writer = WktWriter.new
  wkt = writer.write(self)
  wkt = "#{wkt[0...120]} ... " if wkt.length > 120

  "#<Geos::#{geom_type}: #{wkt}>"
end

#topology_preserve_simplify(tolerance) ⇒ Object



354
355
356
# File 'lib/ffi-geos/geometry.rb', line 354

def topology_preserve_simplify(tolerance)
  cast_geometry_ptr(FFIGeos.GEOSTopologyPreserveSimplify_r(Geos.current_handle_pointer, ptr, tolerance), srid_copy: srid)
end

#touches?(geom) ⇒ Boolean

Returns:

  • (Boolean)


368
369
370
371
# File 'lib/ffi-geos/geometry.rb', line 368

def touches?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSTouches_r(Geos.current_handle_pointer, ptr, geom.ptr))
end

#type_idObject

Returns one of the values from Geos::GeomTypes.



51
52
53
# File 'lib/ffi-geos/geometry.rb', line 51

def type_id
  FFIGeos.GEOSGeomTypeId_r(Geos.current_handle_pointer, ptr)
end

#unary_union(precision = nil) ⇒ Object

Available in GEOS 3.3+



256
257
258
259
260
261
262
# File 'lib/ffi-geos/geometry.rb', line 256

def unary_union(precision = nil)
  if precision
    cast_geometry_ptr(FFIGeos.GEOSUnaryUnionPrec_r(Geos.current_handle_pointer, ptr, precision), srid_copy: srid)
  else
    cast_geometry_ptr(FFIGeos.GEOSUnaryUnion_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
  end
end

#union(geom = nil, precision: nil) ⇒ Object

Calling without a geom argument is equivalent to calling unary_union when using GEOS 3.3+ and is equivalent to calling union_cascaded in older versions.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/ffi-geos/geometry.rb', line 220

def union(geom = nil, precision: nil)
  if geom
    check_geometry(geom)

    if precision
      cast_geometry_ptr(FFIGeos.GEOSUnionPrec_r(Geos.current_handle_pointer, ptr, geom.ptr, precision), srid_copy: pick_srid_from_geoms(srid, geom.srid))
    else
      cast_geometry_ptr(FFIGeos.GEOSUnion_r(Geos.current_handle_pointer, ptr, geom.ptr), srid_copy: pick_srid_from_geoms(srid, geom.srid))
    end
  elsif respond_to?(:unary_union)
    unary_union
  else
    union_cascaded
  end
end

#union_cascadedObject



236
237
238
# File 'lib/ffi-geos/geometry.rb', line 236

def union_cascaded
  cast_geometry_ptr(FFIGeos.GEOSUnionCascaded_r(Geos.current_handle_pointer, ptr), srid_copy: srid)
end

#valid?Boolean

Returns:

  • (Boolean)


480
481
482
# File 'lib/ffi-geos/geometry.rb', line 480

def valid?
  bool_result(FFIGeos.GEOSisValid_r(Geos.current_handle_pointer, ptr))
end

#valid_detail(flags = 0) ⇒ Object

Returns a Hash containing the following structure on invalid geometries:

{
  detail: "String explaining the problem",
  location: Geos::Point # centered on the problem
}

If the Geometry is valid, returns nil.



497
498
499
500
501
502
503
504
505
506
507
508
509
510
# File 'lib/ffi-geos/geometry.rb', line 497

def valid_detail(flags = 0)
  detail = FFI::MemoryPointer.new(:pointer)
  location = FFI::MemoryPointer.new(:pointer)
  valid = bool_result(
    FFIGeos.GEOSisValidDetail_r(Geos.current_handle_pointer, ptr, flags, detail, location)
  )

  return if valid

  {
    detail: detail.read_pointer.read_string,
    location: cast_geometry_ptr(location.read_pointer, srid_copy: srid)
  }
end

#valid_reasonObject

Returns a String describing whether or not the Geometry is valid.



485
486
487
# File 'lib/ffi-geos/geometry.rb', line 485

def valid_reason
  FFIGeos.GEOSisValidReason_r(Geos.current_handle_pointer, ptr)
end

#voronoi_diagram(*args) ⇒ Object

Available in GEOS 3.5.0+

:call-seq:

 voronoi_diagram(options = {})
 voronoi_diagram(tolerance, options = {})

Options:

* :tolerance
* :envelope
* :only_edges


746
747
748
749
750
751
752
753
754
755
756
757
758
759
# File 'lib/ffi-geos/geometry.rb', line 746

def voronoi_diagram(*args)
  options = extract_options!(args)

  tolerance = args.first || options[:tolerance] || 0.0

  envelope_ptr = if options[:envelope]
    check_geometry(options[:envelope])
    options[:envelope].ptr
  end

  only_edges = bool_to_int(options[:only_edges])

  cast_geometry_ptr(FFIGeos.GEOSVoronoiDiagram_r(Geos.current_handle_pointer, ptr, envelope_ptr, tolerance, only_edges))
end

#with_precision(grid_size, options = {}) ⇒ Object



781
782
783
784
785
786
787
788
789
790
791
792
793
# File 'lib/ffi-geos/geometry.rb', line 781

def with_precision(grid_size, options = {})
  options = {
    no_topology: false,
    keep_collapsed: false
  }.merge(options)

  flags = options.reduce(0) do |memo, (key, value)|
    memo |= Geos::PrecisionOptions[key] if value
    memo
  end

  cast_geometry_ptr(FFIGeos.GEOSGeom_setPrecision_r(Geos.current_handle_pointer, ptr, grid_size, flags))
end

#within?(geom) ⇒ Boolean

Returns:

  • (Boolean)


383
384
385
386
# File 'lib/ffi-geos/geometry.rb', line 383

def within?(geom)
  check_geometry(geom)
  bool_result(FFIGeos.GEOSWithin_r(Geos.current_handle_pointer, ptr, geom.ptr))
end