diff --git a/lib/ffi-geos.rb b/lib/ffi-geos.rb index 231cf5c..ec2d45b 100644 --- a/lib/ffi-geos.rb +++ b/lib/ffi-geos.rb @@ -551,6 +551,11 @@ def self.geos_library_paths :pointer, :pointer, :pointer ], + GEOSLineSubstring_r: [ + # *geom, *handle, *geom, start_fraction, end_fraction + :pointer, :pointer, :pointer, :double, :double + ], + GEOSGeom_getXMin_r: [ # 0 on exception, *handle, (double *) value :int, :pointer, :pointer, :pointer diff --git a/lib/ffi-geos/geometry.rb b/lib/ffi-geos/geometry.rb index 084d0fb..675563b 100644 --- a/lib/ffi-geos/geometry.rb +++ b/lib/ffi-geos/geometry.rb @@ -280,6 +280,13 @@ def line_merge cast_geometry_ptr(FFIGeos.GEOSLineMerge_r(Geos.current_handle_pointer, ptr), srid_copy: srid) end + if FFIGeos.respond_to?(:GEOSLineSubstring_r) + # Added in GEOS 3.12+ + 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 + end + def simplify(tolerance) cast_geometry_ptr(FFIGeos.GEOSSimplify_r(Geos.current_handle_pointer, ptr, tolerance), srid_copy: srid) end diff --git a/test/geometry_tests.rb b/test/geometry_tests.rb index 34bada4..e23c8a7 100644 --- a/test/geometry_tests.rb +++ b/test/geometry_tests.rb @@ -562,7 +562,7 @@ def test_unary_union_with_precision end def test_disjoint_subset_union - skip unless ENV['FORCE_TESTS'] || Geos::FFIGeos.respond_to?(:GEOSDisjointSubsetUnion_r) + skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:disjoint_subset_union) simple_tester( :disjoint_subset_union, @@ -789,6 +789,70 @@ def test_line_merge ) end + def test_line_substring + skip unless ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:line_substring) + + simple_tester( + :line_substring, + 'LINESTRING (0 0, 1 1)', + 'LINESTRING (0 0, 2 2)', + 0, + 0.5 + ) + + simple_tester( + :line_substring, + 'MULTILINESTRING ((0 52.5, 0 100), (0 -5, 0 0))', + 'MULTILINESTRING((0 0, 0 100),(0 -5, 0 0))', + 0.5, + 1 + ) + + simple_tester( + :line_substring, + 'LINESTRING (1 1, 1 1)', + 'LINESTRING (0 0, 2 2)', + 0.5, + 0.5 + ) + + simple_tester( + :line_substring, + 'LINESTRING (1 1, 1 1)', + 'LINESTRING (0 0, 2 2)', + 0.5, + 0.5 + ) + + assert_raises(Geos::GEOSException, 'IllegalArgumentException: end fraction must be <= 1') do + simple_tester( + :line_substring, + '', + 'LINESTRING (0 0, 2 2)', + 0.5, + 1.5 + ) + end + + assert_raises(Geos::GEOSException, 'IllegalArgumentException: end fraction must be <= 1') do + simple_tester( + :line_substring, + '', + 'LINESTRING (0 0, 2 2)', + 0.5, + -0.1 + ) + end + + simple_tester( + :line_substring, + 'LINESTRING (0.5 0.5, 0 0)', + 'LINESTRING (0 0, 1 1)', + 0.5, + 0 + ) + end + def test_simplify simple_tester( :simplify,