Skip to content
This repository has been archived by the owner on Aug 28, 2021. It is now read-only.

Commit

Permalink
Added 5th argument for distance type. mi,km, or ft
Browse files Browse the repository at this point in the history
  • Loading branch information
adampresley committed May 30, 2012
1 parent 1f5c89f commit ad087ed
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
8 changes: 8 additions & 0 deletions Makefile
@@ -0,0 +1,8 @@
CC=gcc
CFLAGS=-shared -fPIC -o lib_mysqludf_haversine.so
MYSQLCONFIG=$$(mysql_config --cflags) -lm -DMYSQL_DYNAMIC_PLUGIN
main:
$(CC) $(CFLAGS) lib_mysqludf_haversine.c $(MYSQLCONFIG)

clean:
rm -f lib_mysqludf_haversine.so
9 changes: 7 additions & 2 deletions README.md
Expand Up @@ -8,12 +8,14 @@ Returns the haversine distance from two points
Input parameters
----------------

lat1 (real), lng1 (real), lat2 (real), lng2 (real)
lat1 (real), lng1 (real), lat2 (real), lng2 (real), type (string - optinal - 'km', 'ft', 'mi')

Output
------

Distance in kilometers (real)
Distance between the two points. The measurement is returned in kilometers (real)
by default, however if you specify the 5th *type* argument you may return in other
measurements.

Install
=======
Expand Down Expand Up @@ -70,3 +72,6 @@ Once installed, to calculate distance between two Latitude/Longitude points:

The `SELECT` will return all the records with a distance less then 40 kilometers.

SELECT id, name FROM MY_PLACES WHERE haversine_distance(lat1, lng1, lat2, lng2, 'ft') < 25;

The `SELET` will return all the records with a distance less then 25 feet.
33 changes: 31 additions & 2 deletions lib_mysqludf_haversine.c
Expand Up @@ -25,10 +25,11 @@
* lng1 (real)
* lat2 (real)
* lng2 (real)
* type (string - 'km', 'ft', 'mi')
*
*
* output:
* distance in kilometers (real)
* distance in type of measurement (real)
*
*
* To register this function:
Expand Down Expand Up @@ -92,12 +93,15 @@ haversine_distance_deinit( UDF_INIT* initid );
double
haversine_distance( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );

void
str_to_lowercase( char* src );



my_bool
haversine_distance_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) {

if ( args->arg_count != 4 ) {
if ( args->arg_count < 4 ) {
strcpy(message,"wrong number of arguments: haversine_distance() requires four arguments");
return 1;
}
Expand All @@ -122,6 +126,15 @@ haversine_distance_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) {
args->arg_type[3] = REAL_RESULT;
}

/*
* The 5th argument is the type of distance to return. It is
* optional. Valid arguments are 'km', 'ft', 'mi'
*/
if ( (args->arg_type[4] != STRING_RESULT) ) {
//strcpy( message, "haversine_distance() requires string as parameters 5" ); return 1;
args->arg_type[4] = STRING_RESULT;
}

double *dist = malloc( sizeof(double) );
if ( dist == NULL ) {
strcpy(message, "haversine_distance() allocation error");
Expand Down Expand Up @@ -168,8 +181,24 @@ haversine_distance( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error

result = ( R * c );

/*
* If we have a 5th distance type argument...
*/
if (args->arg_count == 5) {
str_to_lowercase(args->args[4]);

if (strcmp(args->args[4], "ft") == 0) result *= 3280.8399;
if (strcmp(args->args[4], "mi") == 0) result *= 0.621371192;
}

return result;
}


void
str_to_lowercase( char* src ) {
for (; *src; src++) *src = tolower(*src);
}


#endif

0 comments on commit ad087ed

Please sign in to comment.