Skip to content

Use GeoJSON as format for input and output #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions geo_array.c
Original file line number Diff line number Diff line change
@@ -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 <github@derickrethans.nl> |
| Michael Maclean <michael@no-surprises.co.uk> |
| Nathaniel McHugh <nmchugh@inviqa.com> |
| Marcus Deglos <marcus@deglos.com> |
+----------------------------------------------------------------------+
*/

#include <stdlib.h>

#include "geo_array.h"
Expand Down
21 changes: 21 additions & 0 deletions geo_array.h
Original file line number Diff line number Diff line change
@@ -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 <github@derickrethans.nl> |
| Michael Maclean <michael@no-surprises.co.uk> |
| Nathaniel McHugh <nmchugh@inviqa.com> |
| Marcus Deglos <marcus@deglos.com> |
+----------------------------------------------------------------------+
*/

typedef struct geo_array {
double *x;
double *y;
Expand Down
52 changes: 31 additions & 21 deletions geospatial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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 <github@derickrethans.nl> |
| Michael Maclean <michael@no-surprises.co.uk> |
| Nathaniel McHugh <nmchugh@inviqa.com> |
| Marcus Deglos <marcus@deglos.com> |
+----------------------------------------------------------------------+
*/


/* $Id$ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Expand Down Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
}
Expand All @@ -405,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)
{
Expand All @@ -426,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;
Expand All @@ -448,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);
}
/* }}} */
Expand All @@ -508,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)
{
Expand Down
19 changes: 11 additions & 8 deletions php_geospatial.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -12,24 +12,25 @@
| 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 <github@derickrethans.nl> |
| Michael Maclean <michael@no-surprises.co.uk> |
| Nathaniel McHugh <nmchugh@inviqa.com> |
| Marcus Deglos <marcus@deglos.com> |
+----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_GEOSPATIAL_H
#define PHP_GEOSPATIAL_H

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
Expand Down Expand Up @@ -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
*/
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
38 changes: 24 additions & 14 deletions tests/Greenwich.phpt
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
--TEST--
WGS84 to OSGB36 for Grennwich Observertory
WGS84 to OSGB36 for Greenwich Observertory
--FILE--
<?php

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

$polar = transform_datum($lat, $long, GEO_WGS84, GEO_AIRY_1830);
$from = array('type' => '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
9.44816796
23 changes: 16 additions & 7 deletions tests/JodrellBank.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ 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
array(2) {
["type"]=>
string(5) "Point"
["coordinates"]=>
array(2) {
[0]=>
float(-2.3057171628534)
[1]=>
float(53.235974015543)
}
}
11 changes: 6 additions & 5 deletions tests/OSGB36_to_WGS84.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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"]=>
Expand All @@ -32,4 +34,3 @@ array(4) {
["direction"]=>
string(1) "W"
}
75.061
Loading