Add:maptool:Latest way2poi patch from tryagain
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sat, 9 Jul 2011 18:02:55 +0000 (18:02 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sat, 9 Jul 2011 18:02:55 +0000 (18:02 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@4608 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/navit/maptool/ch.c
navit/navit/maptool/geom.c
navit/navit/maptool/maptool.c
navit/navit/maptool/maptool.h
navit/navit/maptool/osm.c

index 1691241..c16494a 100644 (file)
@@ -142,8 +142,6 @@ item_id_slice_free(void *data)
        g_slice_free(struct item_id, data);
 }
 
-#define sq(x) ((double)(x)*(x))
-
 static void
 add_node_to_hash(FILE *idx, GHashTable *hash, struct coord *c, int *nodes)
 {
index f5627b1..efe4109 100644 (file)
@@ -17,6 +17,7 @@
  * Boston, MA  02110-1301, USA.
  */
 #include <string.h>
+#include <math.h>
 #include "maptool.h"
 
 void
@@ -32,6 +33,41 @@ geom_coord_copy(struct coord *from, struct coord *to, int count, int reverse)
                *to++=*--from;  
 }
 
+/**
+  * Get coordinates of polyline middle point.
+  * @param in *p array of poly vertex coordinates
+  * @param in count count of poly vertexes
+  * @param out *c coordinates of middle point
+  * @returns number of first vertex of segment containing middle point
+  */
+int
+geom_line_middle(struct coord *p, int count, struct coord *c)
+{
+       double length=0,half=0,len=0;
+       int i;
+
+       if(count==1) {
+               *c=*p;
+               return 0;
+       }
+       
+       for (i=0; i<count-1; i++) {
+               length+=sqrt(sq(p[i].x-p[i+1].x)+sq(p[i].y-p[i+1].y));
+       }
+
+       length/=2;
+       for (i=0; (i<count-1) && (half<length); i++) {
+               len=sqrt(sq(p[i].x-p[i+1].x)+sq(p[i].y-p[i+1].y));
+               half+=len;
+       }
+       i--;
+       half-=length;
+       c->x=(p[i].x*half+p[i+1].x*(len-half))/len;
+       c->y=(p[i].y*half+p[i+1].y*(len-half))/len;
+       return i;
+}
+
+
 void
 geom_coord_revert(struct coord *c, int count)
 {
@@ -78,7 +114,7 @@ geom_poly_area(struct coord *c, int count)
 int
 geom_poly_centroid(struct coord *p, int count, struct coord *c)
 {
-       long long area=0/*geom_poly_area(p, count)*/;
+       long long area=0;
        long long sx=0,sy=0,tmp;
        int i,j;
        long long x0=p[0].x, y0=p[0].y, xi, yi, xj, yj;
index 3186686..c045dee 100644 (file)
@@ -359,8 +359,10 @@ osm_collect_data(struct maptool_params *p, char *suffix)
                p->osm.nodes=tempfile(suffix,"nodes",1);
        if (p->process_ways && p->process_nodes) {
                p->osm.turn_restrictions=tempfile(suffix,"turn_restrictions",1);
-               if(doway2poi)
-                       p->osm.way2poi=tempfile(suffix,"way2poi",1);
+               if(doway2poi) {
+                       p->osm.line2poi=tempfile(suffix,"line2poi",1);
+                       p->osm.poly2poi=tempfile(suffix,"poly2poi",1);
+               }
        }
        if (p->process_relations)
                p->osm.boundaries=tempfile(suffix,"boundaries",1);
@@ -393,8 +395,10 @@ osm_collect_data(struct maptool_params *p, char *suffix)
                fclose(p->osm.turn_restrictions);
        if (p->osm.boundaries)
                fclose(p->osm.boundaries);
-       if (p->osm.way2poi)
-               fclose(p->osm.way2poi);
+       if (p->osm.poly2poi)
+               fclose(p->osm.poly2poi);
+       if (p->osm.line2poi)
+               fclose(p->osm.line2poi);
 }
 int debug_ref=0;
 
@@ -413,14 +417,22 @@ osm_count_references(struct maptool_params *p, char *suffix)
                        fclose(ways);
                }
                if(doway2poi) {
-                       FILE *way2poi=tempfile(suffix,first?"way2poi":"way2poi_resolved",0);
-                       FILE *way2poinew=tempfile(suffix,"way2poi_resolved_new",1);
-                       resolve_ways(way2poi, way2poinew);
-                       fclose(way2poi);
-                       fclose(way2poinew);
-                       tempfile_rename(suffix,"way2poi_resolved_new","way2poi_resolved");
-                       if (first && !p->keep_tmpfiles) 
-                               tempfile_unlink(suffix,"way2poi");
+                       FILE *poly2poi=tempfile(suffix,first?"poly2poi":"poly2poi_resolved",0);
+                       FILE *poly2poinew=tempfile(suffix,"poly2poi_resolved_new",1);
+                       FILE *line2poi=tempfile(suffix,first?"line2poi":"line2poi_resolved",0);
+                       FILE *line2poinew=tempfile(suffix,"line2poi_resolved_new",1);
+                       resolve_ways(poly2poi, poly2poinew);
+                       resolve_ways(line2poi, line2poinew);
+                       fclose(poly2poi);
+                       fclose(poly2poinew);
+                       fclose(line2poi);
+                       fclose(line2poinew);
+                       tempfile_rename(suffix,"poly2poi_resolved_new","poly2poi_resolved");
+                       tempfile_rename(suffix,"line2poi_resolved_new","line2poi_resolved");
+                       if (first && !p->keep_tmpfiles) {
+                               tempfile_unlink(suffix,"poly2poi");
+                               tempfile_unlink(suffix,"line2poi");
+                       }
                }
                first=0;
        }
@@ -462,10 +474,17 @@ osm_find_intersections(struct maptool_params *p, char *suffix)
 static void
 osm_process_way2poi(struct maptool_params *p, char *suffix)
 {
-       FILE *way2poi=tempfile(suffix,"way2poi_resolved",0);
+       FILE *poly2poi=tempfile(suffix,"poly2poi_resolved",0);
+       FILE *line2poi=tempfile(suffix,"line2poi_resolved",0);
        FILE *way2poi_result=tempfile(suffix,"way2poi_result",1);
-       process_way2poi(way2poi, way2poi_result);
-       fclose(way2poi);
+       if (poly2poi) {
+               process_way2poi(poly2poi, way2poi_result, type_area);
+               fclose(poly2poi);
+       }
+       if (line2poi) {
+               process_way2poi(line2poi, way2poi_result, type_line);
+               fclose(line2poi);
+       }
        fclose(way2poi_result);
 }
 
@@ -598,7 +617,8 @@ maptool_assemble_map(struct maptool_params *p, char *suffix, char **filenames, c
                tempfile_unlink(suffix,"relations");
                tempfile_unlink(suffix,"nodes");
                tempfile_unlink(suffix,"ways_split");
-               tempfile_unlink(suffix,"way2poi_resolved");
+               tempfile_unlink(suffix,"poly2poi_resolved");
+               tempfile_unlink(suffix,"line2poi_resolved");
                tempfile_unlink(suffix,"ways_split_ref");
                tempfile_unlink(suffix,"coastline");
                tempfile_unlink(suffix,"turn_restrictions");
index 844ab7b..8c8001b 100644 (file)
@@ -32,6 +32,8 @@
 #define LONGLONG_FMT "%lld"
 #endif
 
+#define sq(x) ((double)(x)*(x))
+
 #define BUFFER_SIZE 1280
 
 #define debug_tile(x) 0
@@ -143,6 +145,7 @@ struct geom_poly_segment {
 
 void geom_coord_copy(struct coord *from, struct coord *to, int count, int reverse);
 void geom_coord_revert(struct coord *c, int count);
+int geom_line_middle(struct coord *p, int count, struct coord *c);
 long long geom_poly_area(struct coord *c, int count);
 int geom_poly_centroid(struct coord *c, int count, struct coord *r);
 int geom_poly_point_inside(struct coord *cp, int count, struct coord *c);
@@ -235,7 +238,8 @@ struct maptool_osm {
        FILE *turn_restrictions;
        FILE *nodes;
        FILE *ways;
-       FILE *way2poi;
+       FILE *line2poi;
+       FILE *poly2poi;
 };
 
 void osm_add_tag(char *k, char *v);
@@ -253,7 +257,8 @@ void sort_countries(int keep_tmpfiles);
 void process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out);
 void ref_ways(FILE *in);
 void resolve_ways(FILE *in, FILE *out);
-void process_way2poi(FILE *in, FILE *out);
+FILE *resolve_ways_file(FILE *in, char *suffix, char *filename);
+void process_way2poi(FILE *in, FILE *out, int type);
 int map_find_intersections(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final);
 void write_countrydir(struct zip_info *zip_info);
 void remove_countryfiles(void);
index ac76739..5ed148f 100644 (file)
@@ -1540,6 +1540,7 @@ osm_end_way(struct maptool_osm *osm)
        int *def_flags,add_flags;
        enum item_type types[10];
        struct item_bin *item_bin;
+       int count_lines=0, count_areas=0;
 
        in_way=0;
 
@@ -1567,8 +1568,10 @@ osm_end_way(struct maptool_osm *osm)
                        continue;
                if (ignore_unkown && (types[i] == type_street_unkn || types[i] == type_point_unkn))
                        continue;
-               if(!osm->way2poi && types[i]<type_line)
-                       continue;
+               if(types[i]<type_area)  
+                       count_lines++;  
+               else    
+                       count_areas++;
                item_bin=init_item(types[i]);
                item_bin_add_coord(item_bin, coord_buffer, coord_count);
                nodes_ref_item_bin(item_bin);
@@ -1589,7 +1592,7 @@ osm_end_way(struct maptool_osm *osm)
                        item_bin_add_attr_int(item_bin, attr_maxspeed, maxspeed_attr_value);
                item_bin_write(item_bin,osm->ways);
        }
-       if(osm->way2poi) {
+       if(osm->line2poi) {
                count=attr_longest_match(attr_mapping_way2poi, attr_mapping_way2poi_count, types, sizeof(types)/sizeof(enum item_type));
                dbg_assert(count < 10);
                for (i = 0 ; i < count ; i++) {
@@ -1606,8 +1609,7 @@ osm_end_way(struct maptool_osm *osm)
                        item_bin_add_attr_string(item_bin, attr_county_name, attr_strings[attr_string_county_name]); 
                        item_bin_add_attr_string(item_bin, attr_url, attr_strings[attr_string_url]);
                        item_bin_add_attr_longlong(item_bin, attr_osm_wayid, osmid_attr_value);
-
-                       item_bin_write(item_bin,osm->way2poi);
+                       item_bin_write(item_bin, count_areas<count_lines?osm->line2poi:osm->poly2poi);
                }
        }
        attr_longest_match_clear();
@@ -2133,18 +2135,39 @@ resolve_ways(FILE *in, FILE *out)
        }
 }
 
+FILE *
+resolve_ways_file(FILE *in, char *suffix, char *filename)
+{
+       char *newfilename=g_strdup_printf("%s_new",filename);
+       FILE *new=tempfile(suffix,newfilename,1);
+       resolve_ways(in, new);
+       fclose(in);
+       fclose(new);
+       tempfile_rename(suffix,newfilename,filename);
+       g_free(newfilename);
+       return tempfile(suffix,filename,0);
+}
+
+/**
+  * Get POI coordinates from area/line coordinates.
+  * @param in *in input file with area/line coordinates.
+  * @param in *out output file with POI coordinates
+  * @param in type input file original contents type: type_line or type_area
+  * @returns nothing
+  */
 void
-process_way2poi(FILE *in, FILE *out)
+process_way2poi(FILE *in, FILE *out, int type)
 {
        struct item_bin *ib;
        while ((ib=read_item(in))) {
                int count=ib->clen/2;
                if(count>1 && ib->type<type_line) {
                        struct coord *c=(struct coord *)(ib+1), c1, c2;
-                       if(count>2) {
-                               if(!geom_poly_centroid(c, count, &c1)) {
-                                       // we have poly with zero area
-                                       // Falling back to coordinates of its first vertex...
+                       int done=0;
+                       if(type==type_area) {
+                               if(count<3) {
+                                       osm_warning("way",item_bin_get_wayid(ib),0,"Broken polygon, less than 3 points defined\n");
+                               }  else if(!geom_poly_centroid(c, count, &c1)) {
                                        osm_warning("way",item_bin_get_wayid(ib),0,"Broken polygon, area is 0\n");
                                } else {
                                        if(geom_poly_point_inside(c, count, &c1)) {
@@ -2153,11 +2176,12 @@ process_way2poi(FILE *in, FILE *out)
                                                geom_poly_closest_point(c, count, &c1, &c2);
                                                c[0]=c2;
                                        }
+                                       done=1;
                                }
-                       } else if (count==2) {
-                               osm_warning("way",item_bin_get_wayid(ib),0, "Expected polygon, but only two points defined\n");
-                               c[0].x=(c[0].x+c[1].x)/2;
-                               c[0].y=(c[0].y+c[1].y)/2;
+                       }
+                       if(!done) {
+                               geom_line_middle(c,count,&c1);
+                               c[0]=c1;
                        }
                        write_item_part(out, NULL, NULL, ib, 0, 0, NULL);
                }