@@ -41,15 +41,17 @@ ZEND_BEGIN_ARG_INFO_EX(helmert_args, 0, 0, 3)
41
41
ZEND_ARG_INFO (0 , z )
42
42
ZEND_END_ARG_INFO ()
43
43
44
- ZEND_BEGIN_ARG_INFO_EX (polar_to_cartesian_args , 0 , 0 , 2 )
44
+ ZEND_BEGIN_ARG_INFO_EX (polar_to_cartesian_args , 0 , 0 , 3 )
45
45
ZEND_ARG_INFO (0 , latitude )
46
46
ZEND_ARG_INFO (0 , longitude )
47
+ ZEND_ARG_INFO (0 , reference_ellipsoid )
47
48
ZEND_END_ARG_INFO ()
48
49
49
- ZEND_BEGIN_ARG_INFO_EX (cartesian_to_polar_args , 0 , 0 , 3 )
50
+ ZEND_BEGIN_ARG_INFO_EX (cartesian_to_polar_args , 0 , 0 , 4 )
50
51
ZEND_ARG_INFO (0 , x )
51
52
ZEND_ARG_INFO (0 , y )
52
53
ZEND_ARG_INFO (0 , z )
54
+ ZEND_ARG_INFO (0 , reference_ellipsoid )
53
55
ZEND_END_ARG_INFO ()
54
56
55
57
/* {{{ geospatial_functions[]
@@ -95,7 +97,9 @@ ZEND_GET_MODULE(geospatial)
95
97
PHP_MINIT_FUNCTION (geospatial )
96
98
{
97
99
REGISTER_DOUBLE_CONSTANT ("GEO_DEG_TO_RAD" , GEO_DEG_TO_RAD , CONST_CS | CONST_PERSISTENT );
98
- REGISTER_DOUBLE_CONSTANT ("GEO_EARTH_RADIUS" , GEO_EARTH_RADIUS , CONST_CS | CONST_PERSISTENT );
100
+ REGISTER_DOUBLE_CONSTANT ("GEO_EARTH_RADIUS" , GEO_EARTH_RADIUS , CONST_CS | CONST_PERSISTENT );
101
+ REGISTER_LONG_CONSTANT ("GEO_AIRY_1830" , GEO_AIRY_1830 , CONST_CS | CONST_PERSISTENT );
102
+ REGISTER_LONG_CONSTANT ("GEO_WGS84" , GEO_WGS84 , CONST_CS | CONST_PERSISTENT );
99
103
return SUCCESS ;
100
104
}
101
105
/* }}} */
@@ -129,73 +133,71 @@ PHP_FUNCTION(helmert)
129
133
}
130
134
131
135
array_init (return_value );
132
- rX = ROTATION_X ;
133
- rX /= 3600 ;
134
- rX *= GEO_DEG_TO_RAD ;
136
+ rX = ROTATION_X / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD ;
137
+ rY = ROTATION_Y / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD ;
138
+ rZ = ROTATION_Z / GEO_SEC_IN_DEG * GEO_DEG_TO_RAD ;
135
139
136
- rY = ROTATION_Y ;
137
- rY /= 3600 ;
138
- rY *= GEO_DEG_TO_RAD ;
140
+ xOut = WGS84_OSGB36_X ;
141
+ xOut += (x - (rZ * y ) + (rY * z )) * SCALE_CHANGE ;
139
142
140
- rZ = ROTATION_Z ;
141
- rZ /= 3600 ;
142
- rZ *= GEO_DEG_TO_RAD ;
143
+ yOut = WGS84_OSGB36_Y ;
144
+ yOut += ((rZ * x ) + y - (rX * z )) * SCALE_CHANGE ;
143
145
144
- xOut = x - (rZ * y ) + (rY * z );
145
- xOut *= SCALE_CHANGE ;
146
- xOut += WGS84_OSGB36_X ;
146
+ zOut = WGS84_OSGB36_Z ;
147
+ zOut += ((-1 * rY * x ) + (rX * y ) + z ) * SCALE_CHANGE ;
147
148
148
- yOut = (rZ * x ) + y - (rX * z );
149
- yOut *= SCALE_CHANGE ;
150
- yOut += WGS84_OSGB36_Y ;
151
-
152
- zOut = (- rY * x ) + (rX * y ) + z ;
153
- zOut *= SCALE_CHANGE ;
154
- zOut += WGS84_OSGB36_Z ;
155
-
156
- add_next_index_double (return_value , xOut );
157
- add_next_index_double (return_value , yOut );
158
- add_next_index_double (return_value , zOut );
149
+ add_assoc_double (return_value , "x" , xOut );
150
+ add_assoc_double (return_value , "y" , yOut );
151
+ add_assoc_double (return_value , "z" , zOut );
159
152
}
160
153
161
154
PHP_FUNCTION (polar_to_cartesian )
162
155
{
163
156
double latitude , longitude ;
164
157
double x , y , z ;
165
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "dd" , & latitude , & longitude ) == FAILURE ) {
158
+ long reference_ellipsoid ;
159
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "dd|l" , & latitude , & longitude , & reference_ellipsoid ) == FAILURE ) {
166
160
return ;
167
161
}
168
-
162
+ geo_ellipsoid eli = {WGS84_A , WGS84_B };
163
+ if (reference_ellipsoid == GEO_AIRY_1830 ) {
164
+ eli .a = AIRY_1830_A ;
165
+ eli .b = AIRY_1830_B ;
166
+ }
169
167
array_init (return_value );
170
168
double phi = latitude * GEO_DEG_TO_RAD ;
171
169
double lambda = longitude * GEO_DEG_TO_RAD ;
172
- double eSq = ((AIRY_1830_A * AIRY_1830_A ) - (AIRY_1830_B * AIRY_1830_B )) / (AIRY_1830_A * AIRY_1830_A );
173
- double nu = AIRY_1830_A / sqrt (1 - (eSq * sin (phi ) * sin (phi )));
170
+ double eSq = ((eli . a * eli . a ) - (eli . b * eli . b )) / (eli . a * eli . a );
171
+ double nu = eli . a / sqrt (1 - (eSq * sin (phi ) * sin (phi )));
174
172
x = nu + HEIGHT ;
175
173
x *= cos (phi ) * cos (lambda );
176
174
y = nu + HEIGHT ;
177
175
y *= cos (phi ) * sin (lambda );
178
176
z = ((1 - eSq ) * nu ) + HEIGHT ;
179
177
z *= sin (phi );
180
- add_next_index_double (return_value , x );
181
- add_next_index_double (return_value , y );
182
- add_next_index_double (return_value , z );
183
-
178
+ add_assoc_double (return_value , "x" , x );
179
+ add_assoc_double (return_value , "y" , y );
180
+ add_assoc_double (return_value , "z" , z );
184
181
}
185
182
186
183
PHP_FUNCTION (cartesian_to_polar )
187
184
{
188
185
double latitude , longitude ;
189
186
double x , y , z ;
190
187
double nu , lambda , h ;
191
-
192
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "ddd" , & x , & y , & z ) == FAILURE ) {
188
+ long reference_ellipsoid ;
189
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "ddd|l " , & x , & y , & z , & reference_ellipsoid ) == FAILURE ) {
193
190
return ;
194
191
}
192
+ geo_ellipsoid eli = {WGS84_A , WGS84_B };
193
+ if (reference_ellipsoid == GEO_AIRY_1830 ) {
194
+ eli .a = AIRY_1830_A ;
195
+ eli .b = AIRY_1830_B ;
196
+ }
195
197
//aiming for 1m accuracy
196
- double precision = 0.1 / AIRY_1830_A ;
198
+ double precision = 0.1 / eli . a ;
197
199
array_init (return_value );
198
- double eSq = ((AIRY_1830_A * AIRY_1830_A ) - (AIRY_1830_B * AIRY_1830_B )) / (AIRY_1830_A * AIRY_1830_A );
200
+ double eSq = ((eli . a * eli . a ) - (eli . b * eli . b )) / (eli . a * eli . a );
199
201
double p = sqrt (x * x + y * y );
200
202
double phi = atan2 (z , p * (1 - eSq ));
201
203
double phiP = 2 * M_PI ;
@@ -210,7 +212,6 @@ PHP_FUNCTION(cartesian_to_polar)
210
212
add_assoc_double (return_value , "lat" , phi / GEO_DEG_TO_RAD );
211
213
add_assoc_double (return_value , "long" , lambda / GEO_DEG_TO_RAD );
212
214
add_assoc_double (return_value , "height" , h );
213
-
214
215
}
215
216
216
217
/* {{{ proto haversine(double fromLat, double fromLong, double toLat, double toLong [, double radius ])
0 commit comments