Geo-MedianCenter-XS
view release on metacpan or search on metacpan
data[ dx + 4 ] = cos(data[ dx ]) * sin(data[ dx + 1 ]); /* y */
data[ dx + 5 ] = sin(data[ dx ]); /* z */
}
return data;
}
int
median_center(HV* opts, double* plat, double* plon) {
U32 max_iterations = 4;
double tolerance = 0.0f;
SV** value;
double* data = NULL;
double clat = 0;
double clon = 0;
I32 count = 0;
if (opts == NULL || !( SvTYPE(opts) == SVt_PVHV )) {
return -1;
}
data = data_from_av((AV*)rv);
}
}
value = hv_fetch(opts, "tolerance", 9, 0);
if (value && *value && SvOK(*value)) {
tolerance = SvNV(*value);
}
value = hv_fetch(opts, "max_iterations", 14, 0);
if (value && *value && SvOK(*value)) {
max_iterations = SvUV(*value);
}
while (data) {
double sumkx, sumky, sumkz, sumk, avgx, avgy, avgz, nlat, nlon, ndst;
size_t last = (count + 1) * 6;
size_t ix;
sumkx = sumky = sumkz = sumk = 0;
avgx = sumkx / sumk;
avgy = sumky / sumk;
avgz = sumkz / sumk;
/* Should this rather use asin(avgz)? */
nlat = atan2(avgz, sqrt(avgx * avgx + avgy * avgy));
nlon = atan2(avgy, avgx);
ndst = haversine_distance_rad(clat, clon, nlat, nlon);
if (!(max_iterations-- > 0) || (ndst <= tolerance)) {
*plat = nlat * (180.0 / PI);
*plon = nlon * (180.0 / PI);
Safefree(data);
return 0;
}
clat = nlat;
clon = nlon;
lib/Geo/MedianCenter/XS.pm view on Meta::CPAN
=head2 FUNCTIONS
=over 2
=item median_center(\%options)
Computes the median center of a list of points. Options are C<points>,
an array of arrays of latitude and longitude in decimal degrees and
optionally a weight; C<tolerance>, a number in meters, if the iterative
algorithm improves its approximation by at most this value, the function
will return; C<max_iterations>, the function will return after this
many attempts to refine the approximation. Returns the latitude and
longitude in decimal degrees.
=item haversine_distance_dec($lat1, $lon1, $lat2, $long2)
Computes the distance between the two points using the Haversine
formula in meters. Latitude and longitude are specified in decimal
degrees.
=item haversine_distance_rad($lat1, $lon1, $lat2, $long2)
( run in 1.511 second using v1.01-cache-2.11-cpan-71847e10f99 )