Skip to content

Commit 1340ae8

Browse files
author
Nathaniel McHugh
committed
* move constants into structure and allow reverse helmert
1 parent 14d61d5 commit 1340ae8

File tree

3 files changed

+62
-32
lines changed

3 files changed

+62
-32
lines changed

geospatial.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -143,24 +143,35 @@ geo_ellipsoid get_ellipsoid(long ellipsoid_const)
143143
}
144144
}
145145

146-
geo_cartesian php_helmert(double x, double y, double z)
146+
geo_helmert_constants get_helmert_constants(long from, long to)
147+
{
148+
switch (from - to) {
149+
case 1:
150+
return osgb36_wgs84;
151+
break;
152+
default:
153+
case -1:
154+
return wgs84_osgb36;
155+
break;
156+
}
157+
}
158+
159+
geo_cartesian php_helmert(double x, double y, double z, geo_helmert_constants helmet_consts)
147160
{
148161
double rX, rY, rZ;
149162
double xOut, yOut, zOut;
163+
double scale_change;
150164
geo_cartesian point;
165+
scale_change = 1 + (helmet_consts.scale_change);
166+
rX = helmet_consts.rotation_x / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD;
167+
rY = helmet_consts.rotation_y / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD;
168+
rZ = helmet_consts.rotation_z / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD;
151169

152-
rX = ROTATION_X / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD;
153-
rY = ROTATION_Y / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD;
154-
rZ = ROTATION_Z / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD;
170+
xOut = helmet_consts.translation_x + ((x - (rZ * y) + (rY * z)) * scale_change);
155171

156-
xOut = WGS84_OSGB36_X;
157-
xOut += (x - (rZ * y) + (rY * z)) * SCALE_CHANGE;
172+
yOut = helmet_consts.translation_y + (((rZ * x) + y - (rX * z)) * scale_change);
158173

159-
yOut = WGS84_OSGB36_Y;
160-
yOut += ((rZ * x) + y - (rX * z)) * SCALE_CHANGE;
161-
162-
zOut = WGS84_OSGB36_Z;
163-
zOut += ((-1 * rY * x) + (rX * y) + z) * SCALE_CHANGE;
174+
zOut = helmet_consts.translation_z + (((-1 * rY * x) + (rX * y) + z) * scale_change);
164175

165176
point.x = xOut;
166177
point.y = yOut;
@@ -173,12 +184,13 @@ PHP_FUNCTION(helmert)
173184
{
174185
double x, y, z;
175186
geo_cartesian point;
176-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddd", &x, &y, &z) == FAILURE) {
187+
long from_reference_ellipsoid, to_reference_ellipsoid;
188+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddd|ll", &x, &y, &z, &from_reference_ellipsoid, &to_reference_ellipsoid) == FAILURE) {
177189
return;
178190
}
179-
180-
array_init(return_value);
181-
point = php_helmert(x, y, z);
191+
array_init(return_value);\
192+
geo_helmert_constants helmert_constants = get_helmert_constants(from_reference_ellipsoid, to_reference_ellipsoid);
193+
point = php_helmert(x, y, z, helmert_constants);
182194
add_assoc_double(return_value, "x", point.x);
183195
add_assoc_double(return_value, "y", point.y);
184196
add_assoc_double(return_value, "z", point.z);
@@ -267,9 +279,6 @@ PHP_FUNCTION(cartesian_to_polar)
267279
}
268280

269281

270-
271-
272-
273282
PHP_FUNCTION(change_datum)
274283
{
275284
double latitude, longitude;
@@ -282,7 +291,8 @@ PHP_FUNCTION(change_datum)
282291
geo_ellipsoid eli_from = get_ellipsoid(from_reference_ellipsoid);
283292
geo_ellipsoid eli_to = get_ellipsoid(to_reference_ellipsoid);
284293
point = php_polar_to_cartesian(latitude, longitude, eli_from);
285-
converted_point = php_helmert(point.x, point.y, point.z);
294+
geo_helmert_constants helmert_constants = get_helmert_constants(from_reference_ellipsoid, to_reference_ellipsoid);
295+
converted_point = php_helmert(point.x, point.y, point.z, helmert_constants);
286296
polar = php_cartesian_to_polar(converted_point.x, converted_point.y, converted_point.z, eli_to);
287297

288298
array_init(return_value);

php_geospatial.h

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,39 @@ typedef struct {
5353
double z;
5454
} geo_cartesian;
5555

56+
typedef struct {
57+
double translation_x;
58+
double translation_y;
59+
double translation_z;
60+
double scale_change;
61+
double rotation_x;
62+
double rotation_y;
63+
double rotation_z;
64+
} geo_helmert_constants;
65+
5666
const geo_ellipsoid wgs84 = {6378137.000, 6356752.3142};
5767
const geo_ellipsoid airy_1830 = {6377563.396, 6356256.910};
5868

69+
const geo_helmert_constants wgs84_osgb36 = {
70+
-446.448,
71+
125.157,
72+
-542.060,
73+
0.0000204894,
74+
-0.1502,
75+
-0.2470,
76+
-0.8421
77+
};
78+
79+
const geo_helmert_constants osgb36_wgs84 = {
80+
446.448,
81+
-125.157,
82+
542.060,
83+
-0.0000204894,
84+
0.1502,
85+
0.2470,
86+
0.8421
87+
};
88+
5989
#define GEO_DEG_TO_RAD 0.017453292519943295769236907684886
6090
/**
6191
* Calculate the radius using WGS-84's equatorial radius of
@@ -67,16 +97,6 @@ const geo_ellipsoid airy_1830 = {6377563.396, 6356256.910};
6797
#define GEO_WGS84 0x0001
6898
#define GEO_AIRY_1830 0x0002
6999

70-
#define WGS84_OSGB36_X -446.448
71-
#define WGS84_OSGB36_Y 125.157
72-
#define WGS84_OSGB36_Z -542.060
73-
74-
#define SCALE_CHANGE 1.0000204894
75-
76-
#define ROTATION_X -0.1502
77-
#define ROTATION_Y -0.2470
78-
#define ROTATION_Z -0.8421
79-
80100
#define HEIGHT 24.7
81101

82102

tests/OSGB36_to_WGS84.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ echo round($polar['lat'] ,6),PHP_EOL;
1717
echo round($polar['long'] ,6),PHP_EOL;
1818
echo round($polar['height'] ,3),PHP_EOL;
1919
--EXPECT--
20-
53.236525
21-
-2.308560
22-
75.062
20+
53.236526
21+
-2.30856
22+
75.061

0 commit comments

Comments
 (0)