Skip to content

Commit 34f73a5

Browse files
committed
Use geojson for in- and output coordinate pairs
Also fix prototypes where necessary.
1 parent 7f7322b commit 34f73a5

9 files changed

+104
-54
lines changed

geospatial.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ geo_lat_long cartesian_to_polar(double x, double y, double z, geo_ellipsoid eli)
328328
return polar;
329329
}
330330

331-
/* {{{ proto dms_to_decimal(double degrees, double minutes, double seconds [,string direction])
331+
/* {{{ proto double dms_to_decimal(double degrees, double minutes, double seconds [,string direction])
332332
* Convert degrees, minutes & seconds values to decimal degrees */
333333
PHP_FUNCTION(dms_to_decimal)
334334
{
@@ -353,7 +353,7 @@ PHP_FUNCTION(dms_to_decimal)
353353
}
354354
/* }}} */
355355

356-
/* {{{ proto decimal_to_dms(double decimal, string coordinate)
356+
/* {{{ proto array decimal_to_dms(double decimal, string coordinate)
357357
* Convert decimal degrees value to whole degrees and minutes and decimal seconds */
358358
PHP_FUNCTION(decimal_to_dms)
359359
{
@@ -406,7 +406,7 @@ PHP_FUNCTION(helmert)
406406
}
407407
/* }}} */
408408

409-
/* {{{ proto polar_to_cartesian(double latitude, double longitude[, long reference_ellipsoid])
409+
/* {{{ proto array polar_to_cartesian(double latitude, double longitude[, long reference_ellipsoid])
410410
* Convert polar ones (latitude, longitude) tp cartesian co-ordiantes (x, y, z) */
411411
PHP_FUNCTION(polar_to_cartesian)
412412
{
@@ -427,8 +427,8 @@ PHP_FUNCTION(polar_to_cartesian)
427427
}
428428
/* }}} */
429429

430-
/* {{{ proto cartesian_to_polar(double x, double y, double z [, long reference_ellipsoid])
431-
* Convert cartesian co-ordiantes (x, y, z) to polar ones (latitude, longitude) */
430+
/* {{{ proto array cartesian_to_polar(double x, double y, double z [, long reference_ellipsoid])
431+
* Convert cartesian co-ordinates (x, y, z) to polar ones (latitude, longitude) */
432432
PHP_FUNCTION(cartesian_to_polar)
433433
{
434434
double x, y, z;
@@ -449,44 +449,53 @@ PHP_FUNCTION(cartesian_to_polar)
449449
/* }}} */
450450

451451

452-
/* {{{ proto transform_datum(double latitude, double longitude, long from_reference_ellipsoid, long to_reference_ellipsoid)
453-
* Unified function to transform projection of geo-cordinates between datums */
452+
/* {{{ proto GeoJSONPoint transform_datum(GeoJSONPoint coordinates, long from_reference_ellipsoid, long to_reference_ellipsoid)
453+
* Unified function to transform projection of geo-coordinates between datums */
454454
PHP_FUNCTION(transform_datum)
455455
{
456456
double latitude, longitude;
457+
zval *geojson;
457458
long from_reference_ellipsoid, to_reference_ellipsoid;
458459
geo_cartesian point, converted_point;
459460
geo_lat_long polar;
460461

461-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddll", &latitude, &longitude, &from_reference_ellipsoid, &to_reference_ellipsoid) == FAILURE) {
462+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "all", &geojson, &from_reference_ellipsoid, &to_reference_ellipsoid) == FAILURE) {
462463
return;
463464
}
464465

466+
geojson_point_to_lon_lat(geojson, &longitude, &latitude);
467+
465468
geo_ellipsoid eli_from = get_ellipsoid(from_reference_ellipsoid);
466469
geo_ellipsoid eli_to = get_ellipsoid(to_reference_ellipsoid);
467470
point = polar_to_cartesian(latitude, longitude, eli_from);
468471
geo_helmert_constants helmert_constants = get_helmert_constants(from_reference_ellipsoid, to_reference_ellipsoid);
469472
converted_point = helmert(point.x, point.y, point.z, helmert_constants);
470473
polar = cartesian_to_polar(converted_point.x, converted_point.y, converted_point.z, eli_to);
471-
474+
/*
472475
array_init(return_value);
473476
add_assoc_double(return_value, "lat", polar.latitude);
474477
add_assoc_double(return_value, "long", polar.longitude);
475478
add_assoc_double(return_value, "height", polar.height);
479+
*/
480+
retval_point_from_coordinates(return_value, polar.longitude, polar.latitude);
476481
}
477482
/* }}} */
478483

479-
/* {{{ proto haversine(double fromLat, double fromLong, double toLat, double toLong [, double radius ])
484+
/* {{{ proto double haversine(GeoJSONPoint from, GeoJSONPoint to [, double radius ])
480485
* Calculates the greater circle distance between the two lattitude/longitude pairs */
481486
PHP_FUNCTION(haversine)
482487
{
483-
double from_lat, from_long, to_lat, to_long;
484488
double radius = GEO_EARTH_RADIUS;
489+
zval *from_geojson, *to_geojson;
490+
double from_lat, from_long, to_lat, to_long;
485491

486-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd|d", &from_lat, &from_long, &to_lat, &to_long, &radius) == FAILURE) {
492+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa|d", &from_geojson, &to_geojson, &radius) == FAILURE) {
487493
return;
488494
}
489495

496+
geojson_point_to_lon_lat(from_geojson, &from_long, &from_lat);
497+
geojson_point_to_lon_lat(to_geojson, &to_long, &to_lat);
498+
490499
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);
491500
}
492501
/* }}} */
@@ -509,7 +518,7 @@ void php_geo_fraction_along_gc_line(double from_lat, double from_long, double to
509518
*res_long = atan2(y, x);
510519
}
511520

512-
/* {{{ proto GeoJSON fraction_along_gc_line(GeoJSONPoint from, GeoJSONPoint to, double fraction [, double radius ])
521+
/* {{{ proto GeoJSONPoint fraction_along_gc_line(GeoJSONPoint from, GeoJSONPoint to, double fraction [, double radius ])
513522
* Calculates a lat/long pair at a fraction (0-1) of the distance along a GC line */
514523
PHP_FUNCTION(fraction_along_gc_line)
515524
{

tests/Greenwich.phpt

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,41 @@
11
--TEST--
2-
WGS84 to OSGB36 for Grennwich Observertory
2+
WGS84 to OSGB36 for Greenwich Observertory
33
--FILE--
44
<?php
55

66
$lat = dms_to_decimal(51, 28.675, 0, 'N');
77
$long = dms_to_decimal(0, 0.089, 0, 'W');
88

9-
$polar = transform_datum($lat, $long, GEO_WGS84, GEO_AIRY_1830);
9+
$from = array('type' => 'Point', 'coordinates' => array( $long, $lat ) );
1010

11-
$airyLong = $polar['long'];
12-
$wgs84Long = $long;
11+
$polar = transform_datum($from, GEO_WGS84, GEO_AIRY_1830);
1312

14-
$diferenceWGS84 = haversine($lat, $long, $lat, 0);
15-
$diferenceAiry = haversine($polar['lat'], $polar['long'], $polar['lat'], 0);
13+
$diferenceWGS84 = haversine(
14+
$from,
15+
array('type' => 'Point', 'coordinates' => array( 0, $lat ) )
16+
);
17+
18+
$diferenceAiry = haversine(
19+
$polar,
20+
array('type' => 'Point', 'coordinates' => array( 0, $polar['coordinates'][1] ) )
21+
);
1622
//lat long of merdian in Airy 1830 ideally long of 0
1723
var_dump($polar);
1824
//distance in m of difference from lat long and meridian
1925
echo round($diferenceWGS84 * 1000, 8),PHP_EOL;
2026
echo round($diferenceAiry * 1000, 8),PHP_EOL;
27+
?>
2128
--EXPECT--
22-
array(3) {
23-
["lat"]=>
24-
float(51.477400823311)
25-
["long"]=>
26-
float(0.00013627354767069)
27-
["height"]=>
28-
float(-21.205192557536)
29+
array(2) {
30+
["type"]=>
31+
string(5) "Point"
32+
["coordinates"]=>
33+
array(2) {
34+
[0]=>
35+
float(0.00013627354767069)
36+
[1]=>
37+
float(51.477400823311)
38+
}
2939
}
3040
102.84185171
31-
9.44816796
41+
9.44816796

tests/JodrellBank.phpt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@ WGS84 to OSGB36
66
$lat = dms_to_decimal(53, 14, 10.5);
77
$long = dms_to_decimal(-2, 18, 25.7);
88

9-
$polar = transform_datum($lat, $long, GEO_WGS84, GEO_AIRY_1830);
9+
$from = array('type' => 'Point', 'coordinates' => array( $long, $lat ) );
1010

11-
echo round($polar['lat'] ,6),PHP_EOL;
12-
echo round($polar['long'] ,6),PHP_EOL;
13-
echo round($polar['height'] ,3),PHP_EOL;
11+
$polar = transform_datum($from, GEO_WGS84, GEO_AIRY_1830);
12+
13+
var_dump($polar);
1414
--EXPECT--
15-
53.235974
16-
-2.305717
17-
-25.649
15+
array(2) {
16+
["type"]=>
17+
string(5) "Point"
18+
["coordinates"]=>
19+
array(2) {
20+
[0]=>
21+
float(-2.3057171628534)
22+
[1]=>
23+
float(53.235974015543)
24+
}
25+
}

tests/OSGB36_to_WGS84.phpt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ OSGB36 to WGS84
66
$lat = dms_to_decimal(53, 14, 10.5, 'N');
77
$long = dms_to_decimal(2, 18, 25.7, 'W');
88

9-
$polar = transform_datum($lat, $long, GEO_AIRY_1830, GEO_WGS84);
9+
$from = array('type' => 'Point', 'coordinates' => array( $long, $lat ) );
1010

11-
var_dump(decimal_to_dms($polar['lat'], 'latitude'));
12-
var_dump(decimal_to_dms($polar['long'] ,'longitude'));
13-
echo round($polar['height'] ,3),PHP_EOL;
11+
$polar = transform_datum($from, GEO_AIRY_1830, GEO_WGS84);
12+
13+
var_dump(decimal_to_dms($polar['coordinates'][1], 'latitude'));
14+
var_dump(decimal_to_dms($polar['coordinates'][0] ,'longitude'));
15+
?>
1416
--EXPECT--
1517
array(4) {
1618
["degrees"]=>
@@ -32,4 +34,3 @@ array(4) {
3234
["direction"]=>
3335
string(1) "W"
3436
}
35-
75.061

tests/WGS84_to_OSGB36.phpt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ WGS84 to OSGB36
66
$lat = dms_to_decimal(53, 23, 1);
77
$long = dms_to_decimal(-1, 28, 1);
88

9-
$polar = transform_datum($lat, $long, GEO_WGS84, GEO_AIRY_1830);
9+
$coordinate = array(
10+
'type' => 'Point',
11+
'coordinates' => array( $long, $lat )
12+
);
1013

11-
echo round($polar['lat'], 8),PHP_EOL;
12-
echo round($polar['long'], 8),PHP_EOL;
13-
echo round($polar['height'], 8),PHP_EOL;
14+
$polar = transform_datum($coordinate, GEO_WGS84, GEO_AIRY_1830);
15+
16+
echo round($polar['coordinates'][1], 8),PHP_EOL;
17+
echo round($polar['coordinates'][0], 8),PHP_EOL;
1418
--EXPECT--
1519
53.38334018
1620
-1.46541628
17-
-24.78026541

tests/geospatial_haversine_london_edinburgh.phpt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@ Check the haversine function returns the correct distance between London and Edi
66
precision=14
77
--FILE--
88
<?php
9-
echo haversine(51.5171, 0.1062, 55.9500, 3.2200);
9+
$from = array(
10+
'type' => 'Point',
11+
'coordinates' => array( 0.1062, 51.5171 )
12+
);
13+
$to = array(
14+
'type' => 'Point',
15+
'coordinates' => array( 3.2200, 55.9500 )
16+
);
17+
echo haversine($from, $to);
1018
/*
1119
Test the haversine distance between London and Edinburgh.
1220

tests/geospatial_haversine_polar_distance.phpt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@ Check the haversine function returns the correct distance between the North and
66
precision=14
77
--FILE--
88
<?php
9-
echo haversine(90, 0, -90, 0, 6356.7523);
9+
$from = array(
10+
'type' => 'Point',
11+
'coordinates' => array( 0, -90 )
12+
);
13+
$to = array(
14+
'type' => 'Point',
15+
'coordinates' => array( 0, 90 )
16+
);
17+
echo haversine($from, $to, 6356.7523);
1018
/*
1119
Test the haversine distance between the North and South poles.
1220

tests/haversine.phpt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ haversine() function - basic test for haversine forumla
44
precision=15
55
--FILE--
66
<?php
7-
$lat1 = 39.06546;
8-
$lon1 = -104.88544;
9-
10-
$lat2 = $lat1;
11-
$lon2 = -104.80;
12-
var_dump(haversine($lat1, $lon1, $lat2, $lon2));
7+
$from = array(
8+
'type' => 'Point',
9+
'coordinates' => array( -104.88544, 39.06546 )
10+
);
11+
$to = array(
12+
'type' => 'Point',
13+
'coordinates' => array( -104.80, 39.06546 )
14+
);
15+
var_dump(haversine($to, $from));
1316
?>
1417
--EXPECTF--
1518
float(7.384698392931%d)

tests/helmert.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
helmert() function - basic test for helmert forumla
2+
helmert() function - basic test for helmert formula
33
--FILE--
44
<?php
55
$x = 3909833.018;
@@ -16,4 +16,4 @@ array(3) {
1616
float(-146987.30138174)
1717
["z"]=>
1818
float(5019888.0705933)
19-
}
19+
}

0 commit comments

Comments
 (0)