Fix:Build:Made android compileable again
[navit-package] / navit / coord.c
index 9e554b2..af16946 100644 (file)
@@ -1,9 +1,29 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
 #include <glib.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
 #include "debug.h"
+#include "item.h"
 #include "coord.h"
 #include "transform.h"
 #include "projection.h"
@@ -38,6 +58,18 @@ coord_new(int x, int y)
        return c;
 }
 
+struct coord *
+coord_new_from_attrs(struct attr *parent, struct attr **attrs)
+{
+       struct attr *x,*y;
+       x=attr_search(attrs, NULL, attr_x);
+       y=attr_search(attrs, NULL, attr_y);
+       if (!x || !y)
+               return NULL;
+       return coord_new(x->u.num, y->u.num);
+}
+
+
 void
 coord_destroy(struct coord *c)
 {
@@ -49,8 +81,8 @@ coord_rect_new(struct coord *lu, struct coord *rl)
 {
        struct coord_rect *r=g_new(struct coord_rect, 1);
 
-       g_assert(lu->x <= rl->x);
-       g_assert(lu->y >= rl->y);
+       dbg_assert(lu->x <= rl->x);
+       dbg_assert(lu->y >= rl->y);
 
        r->lu=*lu;
        r->rl=*rl;
@@ -68,10 +100,10 @@ coord_rect_destroy(struct coord_rect *r)
 int 
 coord_rect_overlap(struct coord_rect *r1, struct coord_rect *r2)
 {
-       g_assert(r1->lu.x <= r1->rl.x);
-       g_assert(r1->lu.y >= r1->rl.y);
-       g_assert(r2->lu.x <= r2->rl.x);
-       g_assert(r2->lu.y >= r2->rl.y);
+       dbg_assert(r1->lu.x <= r1->rl.x);
+       dbg_assert(r1->lu.y >= r1->rl.y);
+       dbg_assert(r2->lu.x <= r2->rl.x);
+       dbg_assert(r2->lu.y >= r2->rl.y);
        dbg(1,"0x%x,0x%x - 0x%x,0x%x vs 0x%x,0x%x - 0x%x,0x%x\n", r1->lu.x, r1->lu.y, r1->rl.x, r1->rl.y, r2->lu.x, r2->lu.y, r2->rl.x, r2->rl.y);
        if (r1->lu.x > r2->rl.x)
                return 0;
@@ -87,8 +119,8 @@ coord_rect_overlap(struct coord_rect *r1, struct coord_rect *r2)
 int
 coord_rect_contains(struct coord_rect *r, struct coord *c)
 {
-       g_assert(r->lu.x <= r->rl.x);
-       g_assert(r->lu.y >= r->rl.y);
+       dbg_assert(r->lu.x <= r->rl.x);
+       dbg_assert(r->lu.y >= r->rl.y);
        if (c->x < r->lu.x)
                return 0;
        if (c->x > r->rl.x)
@@ -113,16 +145,19 @@ coord_rect_extend(struct coord_rect *r, struct coord *c)
                r->lu.y=c->y;
 }
 
-       /* [Proj:][Ð]DMM.ss[S][S]... N/S [D][D]DMM.ss[S][S]... E/W */
-       /* [Proj:][-][D]D.d[d]... [-][D][D]D.d[d]... */
-       /* [Proj:][-]0xX [-]0xX */
-/*
- * Currently supported:
- *     [Proj:]-0xX [-]0xX 
- *     - where Proj can be mg/garmin, defaults to mg
- *     [Proj:][D][D]Dmm.ss[S][S] N/S [D][D]DMM.ss[S][S]... E/W
- *     [Proj:][-][D]D.d[d]... [-][D][D]D.d[d]
- *     - where Proj can be geo
+/**
+ * Parses \c char \a *c_str and writes back the coordinates to \c coord \a *c_ret. Uses \c projection \a pro if no projection is given in \c char \a *c_str.
+ * The format for \a *c_str can be: 
+ *     \li [Proj:]-0xX [-]0xX 
+ *         - where Proj can be mg/garmin, defaults to mg
+ *     \li [Proj:][D][D]Dmm.ss[S][S] N/S [D][D]DMM.ss[S][S]... E/W
+ *     \li [Proj:][-][D]D.d[d]... [-][D][D]D.d[d]
+ *         - where Proj can be geo
+ *
+ * @param *c_str String to be parsed
+ * @param pro Projection of the string
+ * @param *pc_ret Where the \a pcoord should get stored
+ * @returns The lenght of the parsed string
  */
 
 int
@@ -157,8 +192,10 @@ coord_parse(const char *c_str, enum projection pro, struct coord *c_ret)
                        goto out;
                }
        }
-       if (! s)
-               return 0;
+       if (! s) {
+               ret=0;
+               goto out;
+       }
        while (*s == ' ') {
                s++;
        }
@@ -181,8 +218,11 @@ coord_parse(const char *c_str, enum projection pro, struct coord *c_ret)
                char ns, ew;
                dbg(1,"str='%s'\n", str);
                args=sscanf(str, "%lf %c %lf %c%n", &lat, &ns, &lng, &ew, &ret);
+               dbg(1,"args=%d\n", args);
+               dbg(1,"lat=%f %c lon=%f %c\n", lat, ns, lng, ew);
                if (args < 4)
                        goto out;
+               dbg(1,"projection=%d str_pro=%d projection_none=%d\n", pro, str_pro, projection_none);
                if (str_pro == projection_none) {
                        g.lat=floor(lat/100);
                        lat-=g.lat*100;
@@ -194,7 +234,9 @@ coord_parse(const char *c_str, enum projection pro, struct coord *c_ret)
                                g.lat=-g.lat;
                        if (ew == 'w' || ew == 'W')
                                g.lng=-g.lng;
+                       dbg(1,"transform_from_geo(%f,%f)",g.lat,g.lng);
                        transform_from_geo(pro, &g, c_ret);
+                       dbg(1,"result 0x%x,0x%x\n", c_ret->x,c_ret->y);
                }
                dbg(3,"str='%s' x=%f ns=%c y=%f ew=%c c=%d\n", str, lng, ns, lat, ew, ret);
                dbg(3,"rest='%s'\n", str+ret);
@@ -214,7 +256,7 @@ coord_parse(const char *c_str, enum projection pro, struct coord *c_ret)
        ret+=str-c_str;
        if (debug) {
                printf("args=%d\n", args);
-               printf("ret=%d delta=%d ret_str='%s'\n", ret, str-c_str, c_str+ret);
+               printf("ret=%d delta=%d ret_str='%s'\n", ret, GPOINTER_TO_INT(str-c_str), c_str+ret);
        }
 out:
        if (proj)
@@ -222,6 +264,26 @@ out:
        return ret;
 }
 
+/**
+ * A wrapper for pcoord_parse that also return the projection
+ * @param *c_str String to be parsed
+ * @param pro Projection of the string
+ * @param *pc_ret Where the \a pcoord should get stored
+ * @returns The lenght of the parsed string
+ */
+
+int
+pcoord_parse(const char *c_str, enum projection pro, struct pcoord *pc_ret)
+{
+    struct coord c;
+    int ret;
+    ret = coord_parse(c_str, pro, &c);
+    pc_ret->x = c.x;
+    pc_ret->y = c.y;
+    pc_ret->pro = pro;
+    return ret;
+}
+
 void
 coord_print(enum projection pro, struct coord *c, FILE *out) {
        unsigned int x;
@@ -242,10 +304,80 @@ coord_print(enum projection pro, struct coord *c, FILE *out) {
                y = c->y;
        }
        fprintf( out, "%s: %s0x%x %s0x%x\n",
-                projection_to_name( pro ),
+                projection_to_name( pro , NULL),
                 sign_x, x,
                 sign_y, y );
        return;
 }
 
+/**
+ * @brief Converts a lat/lon into a text formatted text string.
+ * @param lat The latitude
+ * @param lng The longitude
+ * @param fmt The format to use. 
+ *    @li DEGREES=>(45.5000N 100.9000S)
+ *    @li DEGREES_MINUTES=>(45 30.))00N 100 120.54.0000S)
+ *    @li DEGREES_MINUTES_SECONDS=>(4530.0000N 12054.0000S)
+ *           
+ * 
+ * @param buffer  A buffer large enough to hold the output + a terminating NULL (26 bytes)
+ * @param size The size of the buffer
+ *
+ */
+void coord_format(float lat,float lng, enum coord_format fmt, char * buffer, int size)
+{
+
+       char lat_c='N';
+       char lng_c='E';
+       float lat_deg,lat_min,lat_sec;
+       float lng_deg,lng_min,lng_sec;
+
+       if (lng < 0) {
+               lng=-lng;
+               lng_c='W';
+       }
+       if (lat < 0) {
+               lat=-lat;
+               lat_c='S';
+       }
+       lat_deg=lat;
+       lat_min=(lat-floor(lat_deg))*60;
+       lat_sec=fmod(lat*3600,60);
+       lng_deg=lng;
+       lng_min=(lng-floor(lng_deg))*60;
+       lng_sec=fmod(lng*3600,60);
+       switch(fmt)
+       {
+
+       case DEGREES_DECIMAL:
+         snprintf(buffer,size,"%02.6f%c %03.7f%c",lat,lat_c,lng,lng_c);
+         break;
+       case DEGREES_MINUTES:
+         snprintf(buffer,size,"%02.0f %07.4f%c %03.0f %07.4f%c",floor(lat_deg),lat_min , lat_c, floor(lng), lng_min, lng_c);
+                  break;
+       case DEGREES_MINUTES_SECONDS:
+         snprintf(buffer,size,"%02.0f%07.4f%c %03.0f%07.4f%c",floor(lat), fmod(lat*60,60), lat_c, floor(lng), fmod(lng*60,60), lng_c);
+         break;
+         
+       
+       }
+       
+}
+
+unsigned int 
+coord_hash(const void *key)
+{
+        const struct coord *c=key;
+       return c->x^c->y;
+}
+
+int
+coord_equal(const void *a, const void *b)
+{
+        const struct coord *c_a=a;
+        const struct coord *c_b=b;
+       if (c_a->x == c_b->x && c_a->y == c_b->y)
+                return TRUE;
+        return FALSE;
+}
 /** @} */