Skip to content

Commit c9481fd

Browse files
committed
Added the initial_bearing() function.
1 parent 68e10cb commit c9481fd

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

geospatial.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ ZEND_BEGIN_ARG_INFO_EX(fraction_along_gc_line_args, 0, 0, 3)
4848
ZEND_ARG_INFO(0, radius)
4949
ZEND_END_ARG_INFO()
5050

51+
ZEND_BEGIN_ARG_INFO_EX(initial_bearing_args, 0, 0, 2)
52+
ZEND_ARG_INFO(0, geoJsonPointFrom)
53+
ZEND_ARG_INFO(0, geoJsonPointTo)
54+
ZEND_ARG_INFO(0, radius)
55+
ZEND_END_ARG_INFO()
56+
5157
ZEND_BEGIN_ARG_INFO_EX(helmert_args, 0, 0, 3)
5258
ZEND_ARG_INFO(0, x)
5359
ZEND_ARG_INFO(0, y)
@@ -97,6 +103,7 @@ ZEND_END_ARG_INFO()
97103
*/
98104
const zend_function_entry geospatial_functions[] = {
99105
PHP_FE(haversine, haversine_args)
106+
PHP_FE(initial_bearing, initial_bearing_args)
100107
PHP_FE(fraction_along_gc_line, fraction_along_gc_line_args)
101108
PHP_FE(helmert, helmert_args)
102109
PHP_FE(polar_to_cartesian, polar_to_cartesian_args)
@@ -613,6 +620,47 @@ PHP_FUNCTION(fraction_along_gc_line)
613620
}
614621
/* }}} */
615622

623+
double php_initial_bearing(double from_lat, double from_long, double to_lat, double to_long)
624+
{
625+
/*
626+
var y = Math.sin(dLon) * Math.cos(lat2);
627+
var x = Math.cos(lat1)*Math.sin(lat2) -
628+
Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
629+
var brng = Math.atan2(y, x).toDeg();
630+
*/
631+
double x, y;
632+
633+
y = sin(to_long - from_long) * cos(to_lat);
634+
x = cos(from_lat) * sin(to_lat) - sin(from_lat) * cos(to_lat) * cos(to_long - to_long);
635+
636+
return atan2(y, x);
637+
}
638+
639+
/* {{{ proto float initial_bearing(GeoJSONPoint from, GeoJSONPoint to)
640+
Calculates the initial bearing to from from to to. */
641+
PHP_FUNCTION(initial_bearing)
642+
{
643+
zval *from_geojson, *to_geojson;
644+
double from_lat, from_long, to_lat, to_long, bearing;
645+
646+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa", &from_geojson, &to_geojson) == FAILURE) {
647+
return;
648+
}
649+
650+
geojson_point_to_lon_lat(from_geojson, &from_long, &from_lat);
651+
geojson_point_to_lon_lat(to_geojson, &to_long, &to_lat);
652+
653+
bearing = php_initial_bearing(
654+
from_lat * GEO_DEG_TO_RAD,
655+
from_long * GEO_DEG_TO_RAD,
656+
to_lat * GEO_DEG_TO_RAD,
657+
to_long * GEO_DEG_TO_RAD
658+
);
659+
660+
RETURN_DOUBLE(bearing / GEO_DEG_TO_RAD);
661+
}
662+
/* }}} */
663+
616664
geo_array *geo_hashtable_to_array(zval *array)
617665
{
618666
geo_array *tmp;

php_geospatial.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ PHP_MINIT_FUNCTION(geospatial);
129129
PHP_MINFO_FUNCTION(geospatial);
130130

131131
PHP_FUNCTION(haversine);
132+
PHP_FUNCTION(initial_bearing);
132133
PHP_FUNCTION(fraction_along_gc_line);
133134
PHP_FUNCTION(helmert);
134135
PHP_FUNCTION(polar_to_cartesian);

tests/initial_bearing.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
initial_bearing() function - basic test for initial_bearing forumla
3+
--INI--
4+
precision=15
5+
--FILE--
6+
<?php
7+
$from = array(
8+
'type' => 'Point',
9+
'coordinates' => array( -1, 53 )
10+
);
11+
$to = array(
12+
'type' => 'Point',
13+
'coordinates' => array( 0, 52 )
14+
);
15+
var_dump(initial_bearing($from, $to));
16+
?>
17+
--EXPECT--
18+
float(148.380993462535)

0 commit comments

Comments
 (0)