From f299589ddd7e3926a66f1f39176f1ebc016821c0 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Tue, 5 Mar 2024 15:22:56 +0000 Subject: [PATCH] Add tests and documentation for 'interpolate_linestring' --- README.rst | 27 ++++ php_geospatial.stub.php | 4 +- php_geospatial_arginfo.h | 16 +- tests/interpolate-line-string-001.phpt | 200 +++++++++++++++++++++++++ tests/interpolate-line-string-002.phpt | 59 ++++++++ tests/interpolate-line-string-003.phpt | 90 +++++++++++ 6 files changed, 386 insertions(+), 10 deletions(-) create mode 100644 tests/interpolate-line-string-001.phpt create mode 100644 tests/interpolate-line-string-002.phpt create mode 100644 tests/interpolate-line-string-003.phpt diff --git a/README.rst b/README.rst index 7ea21eb..2e4488c 100644 --- a/README.rst +++ b/README.rst @@ -189,6 +189,33 @@ you would use:: var_dump(fraction_along_gc_line($point1, $point2, 0.25)); +Interpolating a GeoJSONLineString +--------------------------------- + +The ``interpolate_linestring`` functions takes a GeoJSONLineString. If the +Pythagorean distance in degrees between two points in the line than the +``epsilon`` value, it inserts a new point every ``epsilon / distance`` +fraction of the Great Circle Line. + +Given the Linestring:: + + $lineString = [ + 'type' => 'Linestring', + 'coordinates' => [ + [ 5, 10 ], + [ 15, 10 ], + [ 0, -50 ], + ] + ]; + +The following will return an array with 26 elements:: + + var_dump(interpolate_linestring($lineString, 3)); + +Five for the first pair, at fractions ``0.0``, ``0.3``, ``0.6``, ``0.9`` and +``1.0``, and then two times, each another ``0.0485`` fraction along the Great +Circle Line for the second pair. + Geohashing ---------- diff --git a/php_geospatial.stub.php b/php_geospatial.stub.php index 957cc73..c33f5e7 100644 --- a/php_geospatial.stub.php +++ b/php_geospatial.stub.php @@ -38,11 +38,11 @@ function haversine(array $from, array $to, float $radius = GEO_EARTH_RADIUS): fl function vincenty(array $from, array $to, float $reference_ellipsoid = GEO_WGS84): float {} function fraction_along_gc_line(array $from, array $to, float $fraction): array {} +function interpolate_linestring(array $line, float $epsilon): array {} + function initial_bearing(array $from, array $to): float {} function rdp_simplify(array $points, float $epsilon): array {} -function interpolate_linestring(array $line, float $epsilon): array {} - function geohash_encode(array $point, int $precision = 12): string {} function geohash_decode(string $geohash): array {} diff --git a/php_geospatial_arginfo.h b/php_geospatial_arginfo.h index ae1fa40..5a85169 100644 --- a/php_geospatial_arginfo.h +++ b/php_geospatial_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 52022e47a6841ea20db60c2c92eba319cfc6c563 */ + * Stub hash: 0fadd3390095e7624d9586206523e5352d345729 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dms_to_decimal, 0, 3, IS_DOUBLE, 0) ZEND_ARG_TYPE_INFO(0, degrees, IS_DOUBLE, 0) @@ -58,6 +58,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_fraction_along_gc_line, 0, 3, IS ZEND_ARG_TYPE_INFO(0, fraction, IS_DOUBLE, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_interpolate_linestring, 0, 2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, line, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, epsilon, IS_DOUBLE, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_initial_bearing, 0, 2, IS_DOUBLE, 0) ZEND_ARG_TYPE_INFO(0, from, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, to, IS_ARRAY, 0) @@ -68,11 +73,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rdp_simplify, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, epsilon, IS_DOUBLE, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_interpolate_linestring, 0, 2, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, line, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, epsilon, IS_DOUBLE, 0) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_geohash_encode, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, point, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, precision, IS_LONG, 0, "12") @@ -92,9 +92,9 @@ ZEND_FUNCTION(transform_datum); ZEND_FUNCTION(haversine); ZEND_FUNCTION(vincenty); ZEND_FUNCTION(fraction_along_gc_line); +ZEND_FUNCTION(interpolate_linestring); ZEND_FUNCTION(initial_bearing); ZEND_FUNCTION(rdp_simplify); -ZEND_FUNCTION(interpolate_linestring); ZEND_FUNCTION(geohash_encode); ZEND_FUNCTION(geohash_decode); @@ -109,9 +109,9 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(haversine, arginfo_haversine) ZEND_FE(vincenty, arginfo_vincenty) ZEND_FE(fraction_along_gc_line, arginfo_fraction_along_gc_line) + ZEND_FE(interpolate_linestring, arginfo_interpolate_linestring) ZEND_FE(initial_bearing, arginfo_initial_bearing) ZEND_FE(rdp_simplify, arginfo_rdp_simplify) - ZEND_FE(interpolate_linestring, arginfo_interpolate_linestring) ZEND_FE(geohash_encode, arginfo_geohash_encode) ZEND_FE(geohash_decode, arginfo_geohash_decode) ZEND_FE_END diff --git a/tests/interpolate-line-string-001.phpt b/tests/interpolate-line-string-001.phpt new file mode 100644 index 0000000..50292f3 --- /dev/null +++ b/tests/interpolate-line-string-001.phpt @@ -0,0 +1,200 @@ +--TEST-- +Test for "interpolate_linestring" #1 +--FILE-- + 'Linestring', + 'coordinates' => [ + [ 5, 10 ], + [ 15, 10 ], + [ 0, -50 ], + ] +]; + +var_dump(interpolate_linestring($lineString, 3)); +?> +--EXPECTF-- +array(26) { + [0]=> + array(2) { + [0]=> + float(5) + [1]=> + float(10) + } + [1]=> + array(2) { + [0]=> + float(7.9998706635703245) + [1]=> + float(10.03143197167244) + } + [2]=> + array(2) { + [0]=> + float(11.000073920872426) + [1]=> + float(10.035925156338873) + } + [3]=> + array(2) { + [0]=> + float(14.000110773799255) + [1]=> + float(10.013466491669567) + } + [4]=> + array(2) { + [0]=> + float(14.999999999999998) + [1]=> + float(10) + } + [5]=> + array(2) { + [0]=> + float(14.431497984318062) + [1]=> + float(7.0743500242581225) + } + [6]=> + array(2) { + [0]=> + float(13.87016260996529) + [1]=> + float(4.148019326790382) + } + [7]=> + array(2) { + [0]=> + float(13.312974140472463) + [1]=> + float(1.221294808989993) + } + [8]=> + array(2) { + [0]=> + float(12.756998952507347) + [1]=> + float(-1.7055449208364544) + } + [9]=> + array(2) { + [0]=> + float(12.199328445763877) + [1]=> + float(-4.632223663590317) + } + [10]=> + array(2) { + [0]=> + float(11.63701903368877) + [1]=> + float(-7.55846185163128) + } + [11]=> + array(2) { + [0]=> + float(11.067030621797189) + [1]=> + float(-10.483970622513857) + } + [12]=> + array(2) { + [0]=> + float(10.486160869758637) + [1]=> + float(-13.408445478413974) + } + [13]=> + array(2) { + [0]=> + float(9.890972221197222) + [1]=> + float(-16.331559233911236) + } + [14]=> + array(2) { + [0]=> + float(9.277708136408956) + [1]=> + float(-19.252953899216553) + } + [15]=> + array(2) { + [0]=> + float(8.642194115015831) + [1]=> + float(-22.172231059691807) + } + [16]=> + array(2) { + [0]=> + float(7.979717846837639) + [1]=> + float(-25.08894018486976) + } + [17]=> + array(2) { + [0]=> + float(7.284881023816488) + [1]=> + float(-28.002564114424196) + } + [18]=> + array(2) { + [0]=> + float(6.55141274516024) + [1]=> + float(-30.91250069881375) + } + [19]=> + array(2) { + [0]=> + float(5.771930687062061) + [1]=> + float(-33.81803917851203) + } + [20]=> + array(2) { + [0]=> + float(4.937630724808758) + [1]=> + float(-36.718329304916004) + } + [21]=> + array(2) { + [0]=> + float(4.037877612215368) + [1]=> + float(-39.61234033808264) + } + [22]=> + array(2) { + [0]=> + float(3.059657259010722) + [1]=> + float(-42.49880573947054) + } + [23]=> + array(2) { + [0]=> + float(1.9868328958488306) + [1]=> + float(-45.37614734526896) + } + [24]=> + array(2) { + [0]=> + float(0.7991194226357126) + [1]=> + float(-48.2423696103279) + } + [25]=> + array(2) { + [0]=> + float(0) + [1]=> + float(-50) + } +} diff --git a/tests/interpolate-line-string-002.phpt b/tests/interpolate-line-string-002.phpt new file mode 100644 index 0000000..6cfafc1 --- /dev/null +++ b/tests/interpolate-line-string-002.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test for "interpolate_linestring" #2 +--FILE-- + 'Linestring', + 'coordinates' => [ + [ 0, 0 ], + [ 90, 0 ], + ] +]; + +var_dump(interpolate_linestring($lineString, 20)); +?> +--EXPECTF-- +array(6) { + [0]=> + array(2) { + [0]=> + float(0) + [1]=> + float(0) + } + [1]=> + array(2) { + [0]=> + float(19.999999999999996) + [1]=> + float(0) + } + [2]=> + array(2) { + [0]=> + float(40.00000000000001) + [1]=> + float(0) + } + [3]=> + array(2) { + [0]=> + float(59.99999999999999) + [1]=> + float(0) + } + [4]=> + array(2) { + [0]=> + float(80) + [1]=> + float(0) + } + [5]=> + array(2) { + [0]=> + float(90) + [1]=> + float(0) + } +} diff --git a/tests/interpolate-line-string-003.phpt b/tests/interpolate-line-string-003.phpt new file mode 100644 index 0000000..2e3f690 --- /dev/null +++ b/tests/interpolate-line-string-003.phpt @@ -0,0 +1,90 @@ +--TEST-- +Test for "interpolate_linestring" #3 +--FILE-- + 'Linestring', + 'coordinates' => [ + [ 0, 50 ], + [ 90, 50 ], + ] +]; + +var_dump(interpolate_linestring($lineString, 20)); +var_dump(interpolate_linestring($lineString, 40)); +?> +--EXPECTF-- +array(6) { + [0]=> + array(2) { + [0]=> + float(0) + [1]=> + float(50) + } + [1]=> + array(2) { + [0]=> + float(17.264525298083225) + [1]=> + float(56.16396630005119) + } + [2]=> + array(2) { + [0]=> + float(39.12863273409221) + [1]=> + float(59.18552765040588) + } + [3]=> + array(2) { + [0]=> + float(62.26466104551454) + [1]=> + float(58.14617677212717) + } + [4]=> + array(2) { + [0]=> + float(81.99106566784195) + [1]=> + float(53.39333006084351) + } + [5]=> + array(2) { + [0]=> + float(90) + [1]=> + float(50) + } +} +array(4) { + [0]=> + array(2) { + [0]=> + float(0) + [1]=> + float(50) + } + [1]=> + array(2) { + [0]=> + float(39.12863273409221) + [1]=> + float(59.18552765040588) + } + [2]=> + array(2) { + [0]=> + float(81.99106566784195) + [1]=> + float(53.39333006084351) + } + [3]=> + array(2) { + [0]=> + float(90) + [1]=> + float(50) + } +}