From b5d0797544d509f59cca3314e865f6a7177db865 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Fri, 29 Nov 2013 15:42:24 +0000 Subject: [PATCH 1/3] Fixed uninitialised variables in case the ellipsoids weren't set. --- geospatial.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/geospatial.c b/geospatial.c index e01c39d..0542726 100644 --- a/geospatial.c +++ b/geospatial.c @@ -385,13 +385,14 @@ PHP_FUNCTION(decimal_to_dms) } /* }}} */ -/* {{{ proto helmert(double x, double y, double z [, long from_reference_ellipsoid, long to_reference_ellipsoid]) - * Convert polar ones (latitude, longitude) tp cartesian co-ordiantes (x, y, z) */ +/* {{{ proto array helmert(double x, double y, double z [, long from_reference_ellipsoid, long to_reference_ellipsoid]) + * Convert cartesian co-ordinates between reference elipsoids */ PHP_FUNCTION(helmert) { double x, y, z; geo_cartesian point; - long from_reference_ellipsoid, to_reference_ellipsoid; + long from_reference_ellipsoid = 0, to_reference_ellipsoid = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddd|ll", &x, &y, &z, &from_reference_ellipsoid, &to_reference_ellipsoid) == FAILURE) { return; } From 63e50296a6200702a985bf2a04b0750733d38224 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Fri, 29 Nov 2013 16:17:21 +0000 Subject: [PATCH 2/3] Use geojson for in- and output coordinate pairs Also fix prototypes where necessary. --- geospatial.c | 35 ++++++++++------- tests/Greenwich.phpt | 38 ++++++++++++------- tests/JodrellBank.phpt | 22 +++++++---- tests/OSGB36_to_WGS84.phpt | 11 +++--- tests/WGS84_to_OSGB36.phpt | 13 ++++--- ...geospatial_haversine_london_edinburgh.phpt | 10 ++++- .../geospatial_haversine_polar_distance.phpt | 10 ++++- tests/haversine.phpt | 15 +++++--- tests/helmert.phpt | 4 +- 9 files changed, 104 insertions(+), 54 deletions(-) diff --git a/geospatial.c b/geospatial.c index 0542726..d9cd6b8 100644 --- a/geospatial.c +++ b/geospatial.c @@ -328,7 +328,7 @@ geo_lat_long cartesian_to_polar(double x, double y, double z, geo_ellipsoid eli) return polar; } -/* {{{ proto dms_to_decimal(double degrees, double minutes, double seconds [,string direction]) +/* {{{ proto double dms_to_decimal(double degrees, double minutes, double seconds [,string direction]) * Convert degrees, minutes & seconds values to decimal degrees */ PHP_FUNCTION(dms_to_decimal) { @@ -353,7 +353,7 @@ PHP_FUNCTION(dms_to_decimal) } /* }}} */ -/* {{{ proto decimal_to_dms(double decimal, string coordinate) +/* {{{ proto array decimal_to_dms(double decimal, string coordinate) * Convert decimal degrees value to whole degrees and minutes and decimal seconds */ PHP_FUNCTION(decimal_to_dms) { @@ -406,7 +406,7 @@ PHP_FUNCTION(helmert) } /* }}} */ -/* {{{ proto polar_to_cartesian(double latitude, double longitude[, long reference_ellipsoid]) +/* {{{ proto array polar_to_cartesian(double latitude, double longitude[, long reference_ellipsoid]) * Convert polar ones (latitude, longitude) tp cartesian co-ordiantes (x, y, z) */ PHP_FUNCTION(polar_to_cartesian) { @@ -427,8 +427,8 @@ PHP_FUNCTION(polar_to_cartesian) } /* }}} */ -/* {{{ proto cartesian_to_polar(double x, double y, double z [, long reference_ellipsoid]) - * Convert cartesian co-ordiantes (x, y, z) to polar ones (latitude, longitude) */ +/* {{{ proto array cartesian_to_polar(double x, double y, double z [, long reference_ellipsoid]) + * Convert cartesian co-ordinates (x, y, z) to polar ones (latitude, longitude) */ PHP_FUNCTION(cartesian_to_polar) { double x, y, z; @@ -449,44 +449,53 @@ PHP_FUNCTION(cartesian_to_polar) /* }}} */ -/* {{{ proto transform_datum(double latitude, double longitude, long from_reference_ellipsoid, long to_reference_ellipsoid) - * Unified function to transform projection of geo-cordinates between datums */ +/* {{{ proto GeoJSONPoint transform_datum(GeoJSONPoint coordinates, long from_reference_ellipsoid, long to_reference_ellipsoid) + * Unified function to transform projection of geo-coordinates between datums */ PHP_FUNCTION(transform_datum) { double latitude, longitude; + zval *geojson; long from_reference_ellipsoid, to_reference_ellipsoid; geo_cartesian point, converted_point; geo_lat_long polar; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddll", &latitude, &longitude, &from_reference_ellipsoid, &to_reference_ellipsoid) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "all", &geojson, &from_reference_ellipsoid, &to_reference_ellipsoid) == FAILURE) { return; } + geojson_point_to_lon_lat(geojson, &longitude, &latitude); + geo_ellipsoid eli_from = get_ellipsoid(from_reference_ellipsoid); geo_ellipsoid eli_to = get_ellipsoid(to_reference_ellipsoid); point = polar_to_cartesian(latitude, longitude, eli_from); geo_helmert_constants helmert_constants = get_helmert_constants(from_reference_ellipsoid, to_reference_ellipsoid); converted_point = helmert(point.x, point.y, point.z, helmert_constants); polar = cartesian_to_polar(converted_point.x, converted_point.y, converted_point.z, eli_to); - +/* array_init(return_value); add_assoc_double(return_value, "lat", polar.latitude); add_assoc_double(return_value, "long", polar.longitude); add_assoc_double(return_value, "height", polar.height); +*/ + retval_point_from_coordinates(return_value, polar.longitude, polar.latitude); } /* }}} */ -/* {{{ proto haversine(double fromLat, double fromLong, double toLat, double toLong [, double radius ]) +/* {{{ proto double haversine(GeoJSONPoint from, GeoJSONPoint to [, double radius ]) * Calculates the greater circle distance between the two lattitude/longitude pairs */ PHP_FUNCTION(haversine) { - double from_lat, from_long, to_lat, to_long; double radius = GEO_EARTH_RADIUS; + zval *from_geojson, *to_geojson; + double from_lat, from_long, to_lat, to_long; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd|d", &from_lat, &from_long, &to_lat, &to_long, &radius) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa|d", &from_geojson, &to_geojson, &radius) == FAILURE) { return; } + geojson_point_to_lon_lat(from_geojson, &from_long, &from_lat); + geojson_point_to_lon_lat(to_geojson, &to_long, &to_lat); + RETURN_DOUBLE(php_geo_haversine(from_lat * GEO_DEG_TO_RAD, from_long * GEO_DEG_TO_RAD, to_lat * GEO_DEG_TO_RAD, to_long * GEO_DEG_TO_RAD) * radius); } /* }}} */ @@ -509,7 +518,7 @@ void php_geo_fraction_along_gc_line(double from_lat, double from_long, double to *res_long = atan2(y, x); } -/* {{{ proto GeoJSON fraction_along_gc_line(GeoJSONPoint from, GeoJSONPoint to, double fraction [, double radius ]) +/* {{{ proto GeoJSONPoint fraction_along_gc_line(GeoJSONPoint from, GeoJSONPoint to, double fraction [, double radius ]) * Calculates a lat/long pair at a fraction (0-1) of the distance along a GC line */ PHP_FUNCTION(fraction_along_gc_line) { diff --git a/tests/Greenwich.phpt b/tests/Greenwich.phpt index 980d41e..b232221 100644 --- a/tests/Greenwich.phpt +++ b/tests/Greenwich.phpt @@ -1,31 +1,41 @@ --TEST-- -WGS84 to OSGB36 for Grennwich Observertory +WGS84 to OSGB36 for Greenwich Observertory --FILE-- 'Point', 'coordinates' => array( $long, $lat ) ); -$airyLong = $polar['long']; -$wgs84Long = $long; +$polar = transform_datum($from, GEO_WGS84, GEO_AIRY_1830); -$diferenceWGS84 = haversine($lat, $long, $lat, 0); -$diferenceAiry = haversine($polar['lat'], $polar['long'], $polar['lat'], 0); +$diferenceWGS84 = haversine( + $from, + array('type' => 'Point', 'coordinates' => array( 0, $lat ) ) +); + +$diferenceAiry = haversine( + $polar, + array('type' => 'Point', 'coordinates' => array( 0, $polar['coordinates'][1] ) ) +); //lat long of merdian in Airy 1830 ideally long of 0 var_dump($polar); //distance in m of difference from lat long and meridian echo round($diferenceWGS84 * 1000, 8),PHP_EOL; echo round($diferenceAiry * 1000, 8),PHP_EOL; +?> --EXPECT-- -array(3) { - ["lat"]=> - float(51.477400823311) - ["long"]=> - float(0.00013627354767069) - ["height"]=> - float(-21.205192557536) +array(2) { + ["type"]=> + string(5) "Point" + ["coordinates"]=> + array(2) { + [0]=> + float(0.00013627354767069) + [1]=> + float(51.477400823311) + } } 102.84185171 -9.44816796 \ No newline at end of file +9.44816796 diff --git a/tests/JodrellBank.phpt b/tests/JodrellBank.phpt index b40f8ea..84a1974 100644 --- a/tests/JodrellBank.phpt +++ b/tests/JodrellBank.phpt @@ -6,12 +6,20 @@ WGS84 to OSGB36 $lat = dms_to_decimal(53, 14, 10.5); $long = dms_to_decimal(-2, 18, 25.7); -$polar = transform_datum($lat, $long, GEO_WGS84, GEO_AIRY_1830); +$from = array('type' => 'Point', 'coordinates' => array( $long, $lat ) ); -echo round($polar['lat'] ,6),PHP_EOL; -echo round($polar['long'] ,6),PHP_EOL; -echo round($polar['height'] ,3),PHP_EOL; +$polar = transform_datum($from, GEO_WGS84, GEO_AIRY_1830); + +var_dump($polar); --EXPECT-- -53.235974 --2.305717 --25.649 \ No newline at end of file +array(2) { + ["type"]=> + string(5) "Point" + ["coordinates"]=> + array(2) { + [0]=> + float(-2.3057171628534) + [1]=> + float(53.235974015543) + } +} diff --git a/tests/OSGB36_to_WGS84.phpt b/tests/OSGB36_to_WGS84.phpt index e9de276..0f8b87e 100644 --- a/tests/OSGB36_to_WGS84.phpt +++ b/tests/OSGB36_to_WGS84.phpt @@ -6,11 +6,13 @@ OSGB36 to WGS84 $lat = dms_to_decimal(53, 14, 10.5, 'N'); $long = dms_to_decimal(2, 18, 25.7, 'W'); -$polar = transform_datum($lat, $long, GEO_AIRY_1830, GEO_WGS84); +$from = array('type' => 'Point', 'coordinates' => array( $long, $lat ) ); -var_dump(decimal_to_dms($polar['lat'], 'latitude')); -var_dump(decimal_to_dms($polar['long'] ,'longitude')); -echo round($polar['height'] ,3),PHP_EOL; +$polar = transform_datum($from, GEO_AIRY_1830, GEO_WGS84); + +var_dump(decimal_to_dms($polar['coordinates'][1], 'latitude')); +var_dump(decimal_to_dms($polar['coordinates'][0] ,'longitude')); +?> --EXPECT-- array(4) { ["degrees"]=> @@ -32,4 +34,3 @@ array(4) { ["direction"]=> string(1) "W" } -75.061 \ No newline at end of file diff --git a/tests/WGS84_to_OSGB36.phpt b/tests/WGS84_to_OSGB36.phpt index a142833..9cf0b58 100644 --- a/tests/WGS84_to_OSGB36.phpt +++ b/tests/WGS84_to_OSGB36.phpt @@ -6,12 +6,15 @@ WGS84 to OSGB36 $lat = dms_to_decimal(53, 23, 1); $long = dms_to_decimal(-1, 28, 1); -$polar = transform_datum($lat, $long, GEO_WGS84, GEO_AIRY_1830); +$coordinate = array( + 'type' => 'Point', + 'coordinates' => array( $long, $lat ) +); -echo round($polar['lat'], 8),PHP_EOL; -echo round($polar['long'], 8),PHP_EOL; -echo round($polar['height'], 8),PHP_EOL; +$polar = transform_datum($coordinate, GEO_WGS84, GEO_AIRY_1830); + +echo round($polar['coordinates'][1], 8),PHP_EOL; +echo round($polar['coordinates'][0], 8),PHP_EOL; --EXPECT-- 53.38334018 -1.46541628 --24.78026541 diff --git a/tests/geospatial_haversine_london_edinburgh.phpt b/tests/geospatial_haversine_london_edinburgh.phpt index 1b56cbb..4a8d11e 100644 --- a/tests/geospatial_haversine_london_edinburgh.phpt +++ b/tests/geospatial_haversine_london_edinburgh.phpt @@ -6,7 +6,15 @@ Check the haversine function returns the correct distance between London and Edi precision=14 --FILE-- 'Point', + 'coordinates' => array( 0.1062, 51.5171 ) +); +$to = array( + 'type' => 'Point', + 'coordinates' => array( 3.2200, 55.9500 ) +); +echo haversine($from, $to); /* Test the haversine distance between London and Edinburgh. diff --git a/tests/geospatial_haversine_polar_distance.phpt b/tests/geospatial_haversine_polar_distance.phpt index de30087..0066b79 100644 --- a/tests/geospatial_haversine_polar_distance.phpt +++ b/tests/geospatial_haversine_polar_distance.phpt @@ -6,7 +6,15 @@ Check the haversine function returns the correct distance between the North and precision=14 --FILE-- 'Point', + 'coordinates' => array( 0, -90 ) +); +$to = array( + 'type' => 'Point', + 'coordinates' => array( 0, 90 ) +); +echo haversine($from, $to, 6356.7523); /* Test the haversine distance between the North and South poles. diff --git a/tests/haversine.phpt b/tests/haversine.phpt index 7d87907..14cf0c8 100644 --- a/tests/haversine.phpt +++ b/tests/haversine.phpt @@ -4,12 +4,15 @@ haversine() function - basic test for haversine forumla precision=15 --FILE-- 'Point', + 'coordinates' => array( -104.88544, 39.06546 ) +); +$to = array( + 'type' => 'Point', + 'coordinates' => array( -104.80, 39.06546 ) +); +var_dump(haversine($to, $from)); ?> --EXPECTF-- float(7.384698392931%d) diff --git a/tests/helmert.phpt b/tests/helmert.phpt index 898b6ca..0460857 100644 --- a/tests/helmert.phpt +++ b/tests/helmert.phpt @@ -1,5 +1,5 @@ --TEST-- -helmert() function - basic test for helmert forumla +helmert() function - basic test for helmert formula --FILE-- float(5019888.0705933) -} \ No newline at end of file +} From 49a04be1a2dac25a81035fc3f0938ce5c4456823 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Fri, 29 Nov 2013 16:26:26 +0000 Subject: [PATCH 3/3] General formatting changes and license headers. --- geo_array.c | 21 +++++++++++++++++++++ geo_array.h | 21 +++++++++++++++++++++ geospatial.c | 10 +++++----- php_geospatial.h | 19 +++++++++++-------- tests/JodrellBank.phpt | 1 + tests/WGS84_to_OSGB36.phpt | 1 + tests/decimal_to_dms.phpt | 4 ++-- tests/dms_to_decimal.phpt | 4 ++-- tests/polar_to_cartesian.phpt | 2 +- 9 files changed, 65 insertions(+), 18 deletions(-) diff --git a/geo_array.c b/geo_array.c index 83786e4..1da099b 100644 --- a/geo_array.c +++ b/geo_array.c @@ -1,3 +1,24 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + | Michael Maclean | + | Nathaniel McHugh | + | Marcus Deglos | + +----------------------------------------------------------------------+ +*/ + #include #include "geo_array.h" diff --git a/geo_array.h b/geo_array.h index 3cf64d7..7d1de33 100644 --- a/geo_array.h +++ b/geo_array.h @@ -1,3 +1,24 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + | Michael Maclean | + | Nathaniel McHugh | + | Marcus Deglos | + +----------------------------------------------------------------------+ +*/ + typedef struct geo_array { double *x; double *y; diff --git a/geospatial.c b/geospatial.c index d9cd6b8..1e1f0cb 100644 --- a/geospatial.c +++ b/geospatial.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -12,13 +12,13 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: | + | Authors: Derick Rethans | + | Michael Maclean | + | Nathaniel McHugh | + | Marcus Deglos | +----------------------------------------------------------------------+ */ - -/* $Id$ */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/php_geospatial.h b/php_geospatial.h index 9397b0b..6970a00 100644 --- a/php_geospatial.h +++ b/php_geospatial.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2012 The PHP Group | + | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -12,12 +12,13 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: | + | Authors: Derick Rethans | + | Michael Maclean | + | Nathaniel McHugh | + | Marcus Deglos | +----------------------------------------------------------------------+ */ -/* $Id$ */ - #ifndef PHP_GEOSPATIAL_H #define PHP_GEOSPATIAL_H @@ -25,11 +26,11 @@ extern zend_module_entry geospatial_module_entry; #define phpext_geospatial_ptr &geospatial_module_entry #ifdef PHP_WIN32 -# define PHP_GEOSPATIAL_API __declspec(dllexport) +# define PHP_GEOSPATIAL_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 -# define PHP_GEOSPATIAL_API __attribute__ ((visibility("default"))) +# define PHP_GEOSPATIAL_API __attribute__ ((visibility("default"))) #else -# define PHP_GEOSPATIAL_API +# define PHP_GEOSPATIAL_API #endif #ifdef ZTS @@ -71,6 +72,7 @@ typedef struct { * The WGS84 elipsoid semi major axes */ const geo_ellipsoid wgs84 = {6378137.000, 6356752.3142}; + /** * The Airy 1830 elipsoid semi major axes */ @@ -89,6 +91,7 @@ const geo_helmert_constants wgs84_osgb36 = { -0.2470, -0.8421 }; + /** * The values of the 7 variables for performing helmert transformation between * osgb36 and wgs84 -1 * the values for the reverse transformation @@ -130,7 +133,7 @@ PHP_FUNCTION(dms_to_decimal); PHP_FUNCTION(decimal_to_dms); PHP_FUNCTION(rdp_simplify); -#endif /* PHP_GEOSPATIAL_H */ +#endif /* PHP_GEOSPATIAL_H */ /* * Local variables: diff --git a/tests/JodrellBank.phpt b/tests/JodrellBank.phpt index 84a1974..19bdae6 100644 --- a/tests/JodrellBank.phpt +++ b/tests/JodrellBank.phpt @@ -11,6 +11,7 @@ $from = array('type' => 'Point', 'coordinates' => array( $long, $lat ) ); $polar = transform_datum($from, GEO_WGS84, GEO_AIRY_1830); var_dump($polar); +?> --EXPECT-- array(2) { ["type"]=> diff --git a/tests/WGS84_to_OSGB36.phpt b/tests/WGS84_to_OSGB36.phpt index 9cf0b58..11ed76a 100644 --- a/tests/WGS84_to_OSGB36.phpt +++ b/tests/WGS84_to_OSGB36.phpt @@ -15,6 +15,7 @@ $polar = transform_datum($coordinate, GEO_WGS84, GEO_AIRY_1830); echo round($polar['coordinates'][1], 8),PHP_EOL; echo round($polar['coordinates'][0], 8),PHP_EOL; +?> --EXPECT-- 53.38334018 -1.46541628 diff --git a/tests/decimal_to_dms.phpt b/tests/decimal_to_dms.phpt index 4a71cea..179ef35 100644 --- a/tests/decimal_to_dms.phpt +++ b/tests/decimal_to_dms.phpt @@ -8,7 +8,7 @@ var_dump($dms); $dms = decimal_to_dms(-1.034291666667, 'latitude'); var_dump($dms); - +?> --EXPECT-- array(4) { ["degrees"]=> @@ -29,4 +29,4 @@ array(4) { float(3.4500000011994) ["direction"]=> string(1) "S" -} \ No newline at end of file +} diff --git a/tests/dms_to_decimal.phpt b/tests/dms_to_decimal.phpt index 15f6d92..1a227b6 100644 --- a/tests/dms_to_decimal.phpt +++ b/tests/dms_to_decimal.phpt @@ -12,9 +12,9 @@ var_dump($decimal); $decimal = dms_to_decimal(-2, 18.42833333333333333333, 0, 'W'); var_dump($decimal); - +?> --EXPECT-- float(-1.0342916666667) float(-2.3071388888889) float(-2.3071388888889) -float(-2.3071388888889) \ No newline at end of file +float(-2.3071388888889) diff --git a/tests/polar_to_cartesian.phpt b/tests/polar_to_cartesian.phpt index 917daa8..e17e947 100644 --- a/tests/polar_to_cartesian.phpt +++ b/tests/polar_to_cartesian.phpt @@ -15,4 +15,4 @@ array(3) { float(97591.624686311) ["z"]=> float(5095766.3939034) -} \ No newline at end of file +}