/*
- * Different Lat/Lon related function (conversion, distances, etc)
+ * Different Lat/Lon and related functions
+ * (conversion, distances, etc)
*/
#define _GNU_SOURCE
#include <math.h>
#include <glib.h>
+#include "latlon.h"
#include "osm.h"
/* Int ranges for integerized lat/lon */
#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)
{
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)
{
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
*/
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
/*****************************************************************************/
-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)
{