From e4cd684027f14da2301fe6ff4d004ee36b79558a Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Fri, 26 Oct 2007 12:37:36 +0300 Subject: [PATCH] Move and add new functions to latlon.c : - Add quadtile functions from OSM. - Move distance to line function from osm-db.c to latlon.c. --- src/latlon.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/latlon.h | 7 +++++ src/osm-db.c | 34 --------------------- 3 files changed, 88 insertions(+), 37 deletions(-) diff --git a/src/latlon.c b/src/latlon.c index a9e0beb..1d4e44f 100644 --- a/src/latlon.c +++ b/src/latlon.c @@ -1,11 +1,13 @@ /* - * Different Lat/Lon related function (conversion, distances, etc) + * Different Lat/Lon and related functions + * (conversion, distances, etc) */ #define _GNU_SOURCE #include #include +#include "latlon.h" #include "osm.h" /* Int ranges for integerized lat/lon */ @@ -14,7 +16,72 @@ #define EARTH_RADIUS (3440.06479f) -/* Convert latitude to integerized+mercator projected value */ +static inline gdouble +magnitude(gdouble x1, gdouble y1, gdouble x2, gdouble y2) +{ +gdouble x,y; +x=x2-x1; +y=y2-y1; + +return sqrt((x*x)+(y*y)); +} + +gboolean +distance_point_to_line(gdouble x, gdouble y, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble *d) +{ +gdouble lm,u,tmp; +gdouble ix,iy; + +lm=magnitude(x1,y1,x2,y2); +if (lm==0.0f) + return FALSE; + +tmp=((x-x1)*(x2-x1))+((y-y1)*(y2-y1)); +u=tmp/(lm*lm); + +if (u<0.0f || u>1.0f) + return FALSE; + +ix=x1+u*(x2-x1); +iy=y1+u*(y2-y1); + +*d=magnitude(x,y, ix, iy); + +return TRUE; +} + +/* + * QuadTile calculation functions, from: + * http://trac.openstreetmap.org/browser/sites/rails_port/lib/quad_tile/quad_tile.h + */ +guint32 +xy2tile(guint x, guint y) +{ +guint32 tile=0; +gint i; + +for (i=15;i>=0;i--) { + tile=(tile << 1) | ((x >> i) & 1); + tile=(tile << 1) | ((y >> i) & 1); +} +return tile; +} + +guint32 +lon2x(gdouble lon) +{ +return round((lon + 180.0) * 65535.0 / 360.0); +} + +guint32 +lat2y(gdouble lat) +{ +return round((lat + 90.0) * 65535.0 / 180.0); +} + +/* + * Convert latitude to integerized+mercator projected value + */ gint32 lat2mp_int(gdouble lat) { @@ -22,7 +89,9 @@ return lat > 85.051128779 ? LATLON_MAX : lat < -85.051128779 ? LATLON_MIN : lrint(log(tan(M_PI_4l+lat*M_PIl/360))/M_PIl*LATLON_MAX); } -/* Convert longitude to integerized+mercator projected value */ +/* + * Convert longitude to integerized+mercator projected value + */ gint32 lon2mp_int(gdouble lon) { @@ -41,12 +110,21 @@ mp_int2lat(gint lat) return 0; } +/** + * Quick distance calculation, (does not handle earth curvature, so use for quick non exact needs only) + */ gulong calculate_idistance(gint lat1, gint lon1, gint lat2, gint lon2) { return lrint(sqrt((double)((lat1-lat2)*(lat1-lat2)+(lon1-lon2)*(lon1-lon2)))); } +gdouble +calculate_ddistance(gint lat1, gint lon1, gint lat2, gint lon2) +{ +return sqrt((double)((lat1-lat2)*(lat1-lat2)+(lon1-lon2)*(lon1-lon2))); +} + /** * Quick distance for comparing, skips the final square root */ diff --git a/src/latlon.h b/src/latlon.h index 162b4bf..5ac94ae 100644 --- a/src/latlon.h +++ b/src/latlon.h @@ -11,8 +11,15 @@ gint32 lon2mp_int(gdouble lon); gint32 lat2mp_int(gdouble lat); gdouble calculate_distance(gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2); +gdouble calculate_ddistance(gint lat1, gint lon1, gint lat2, gint lon2); gulong calculate_idistance(gint lat1, gint lon1, gint lat2, gint lon2); gulong calculate_idistance_cmp(gint lat1, gint lon1, gint lat2, gint lon2); gdouble calculate_course(gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2); +gboolean distance_point_to_line(gdouble x, gdouble y, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble *d); + +guint32 xy2tile(guint x, guint y); +guint32 lon2x(gdouble lon); +guint32 lat2y(gdouble lat); + #endif diff --git a/src/osm-db.c b/src/osm-db.c index 204737f..6fdf2e7 100644 --- a/src/osm-db.c +++ b/src/osm-db.c @@ -489,40 +489,6 @@ return ways; /*****************************************************************************/ -static inline gdouble -magnitude(gdouble x1, gdouble y1, gdouble x2, gdouble y2) -{ -gdouble x,y; -x=x2-x1; -y=y2-y1; - -return sqrt((x*x)+(y*y)); -} - -static gboolean -distance_point_to_line(gdouble x, gdouble y, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble *d) -{ -gdouble lm,u,tmp; -gdouble ix,iy; - -lm=magnitude(x1,y1,x2,y2); -if (lm==0.0f) - return FALSE; - -tmp=((x-x1)*(x2-x1))+((y-y1)*(y2-y1)); -u=tmp/(lm*lm); - -if (u<0.0f || u>1.0f) - return FALSE; - -ix=x1+u*(x2-x1); -iy=y1+u*(y2-y1); - -*d=magnitude(x,y, ix, iy); - -return TRUE; -} - gboolean osm_way_distance(gint lat, gint lon, osm_way_node *f, osm_way_node *t, gdouble *d) { -- 2.39.5