Ticket #754: water_relation.diff

File water_relation.diff, 10.2 KB (added by tegzed, 10 years ago)

fixed waterway="riverbank" tag support

  • osm.c

     
    710710        "w      waterway=canal          water_canal\n"
    711711        "w      waterway=drain          water_drain\n"
    712712        "w      waterway=river          water_river\n"
     713        "w      water=river             water_river\n"
    713714        "w      waterway=riverbank      poly_water\n"
    714715        "w      waterway=stream         water_stream\n"
    715716        "w      barrier=ditch   ditch\n"
     
    15441545                if (!strcmp(v,"administrative") || (experimental && !strcmp(v,"postal_code"))) {
    15451546                        boundary=1;
    15461547                }
     1548        } else if (!strcmp(k,"natural")) {
     1549                if (!strcmp(v,"water") ) {
     1550                        boundary=1;
     1551                }
     1552        } else if (!strcmp(k,"waterway")) {
     1553                if (!strcmp(v,"riverbank") ) {
     1554printf("FOUND waterway=riverbank\n");
     1555                        boundary=1;
     1556                }
     1557        } else if (!strcmp(k,"water")) {
     1558                if (!strcmp(v,"river") ) {
     1559                        boundary=1;
     1560                }
    15471561        } else if (!strcmp(k,"ISO3166-1")) {
    15481562                strcpy(iso_code, v);
    15491563        }
     
    25782592                                if (ni) {
    25792593                                        c[i]=ni->c;
    25802594                                        if (ni->ref_way > 1 && i != 0 && i != ccount-1 && i != last && item_get_default_flags(ib->type)) {
    2581                                                 write_item_part(out, out_index, out_graph, ib, last, i, &last_id);
     2595                                                if(!(0 != self_intersect_test(ib) && ib->type==type_poly_water))
     2596                                                        write_item_part(out, out_index, out_graph, ib, last, i, &last_id);
    25822597                                                last=i;
    25832598                                        }
    25842599                                } else if (final) {
     
    25942609                        }
    25952610                }
    25962611                if (ccount) {
    2597                         write_item_part(out, out_index, out_graph, ib, last, ccount-1, &last_id);
     2612                        //if(0 == self_intersect_test(ib))
     2613                        if(!(0 != self_intersect_test(ib) && ib->type==type_poly_water))
     2614                                write_item_part(out, out_index, out_graph, ib, last, ccount-1, &last_id);
    25982615                        if (final && ib->type == type_water_line && out_coastline) {
    2599                                 write_item_part(out_coastline, NULL, NULL, ib, last, ccount-1, NULL);
     2616                                if(0 == self_intersect_test(ib))
     2617                                        write_item_part(out_coastline, NULL, NULL, ib, last, ccount-1, NULL);
    26002618                        }
    26012619                }
    26022620        }
  • maptool.c

     
    854854                }
    855855        }
    856856
    857         if (start_phase(&p,"generating coastlines")) {
    858                 osm_process_coastlines(&p, suffix);
    859         }
    860857        if (start_phase(&p,"assinging towns to countries")) {
    861858                FILE *towns=tempfile(suffix,"towns",0),*boundaries=NULL,*ways=NULL;
    862859                if (towns) {
     
    870867                                tempfile_unlink(suffix,"towns");
    871868                }
    872869        }
     870
     871        if (start_phase(&p,"generating coastlines")) {
     872                osm_process_coastlines(&p, suffix);
     873        }
    873874        if (start_phase(&p,"sorting countries")) {
    874875                sort_countries(p.keep_tmpfiles);
    875876                p.countries_loaded=1;
  • maptool.h

     
    121121struct boundary {
    122122        struct item_bin *ib;
    123123        struct country_table *country;
     124        char *natural;
    124125        char *iso2;
    125126        GList *segments,*sorted_segments;
    126127        GList *children;
     
    189190int geom_poly_segments_point_inside(GList *in, struct coord *c);
    190191void clip_line(struct item_bin *ib, struct rect *r, struct tile_parameter *param, struct item_bin_sink *out);
    191192void clip_polygon(struct item_bin *ib, struct rect *r, struct tile_parameter *param, struct item_bin_sink *out);
     193int self_intersect_test(struct item_bin*ib);
    192194
    193195/* itembin.c */
    194196
     
    240242extern struct buffer node_buffer;
    241243extern int processed_nodes, processed_nodes_out, processed_ways, processed_relations, processed_tiles;
    242244extern struct item_bin *item_bin;
     245extern struct item_bin *item_bin_coastline;
    243246extern int bytes_read;
    244247extern int overlap;
    245248extern int unknown_country;
  • itembin_buffer.c

     
    2222#include "debug.h"
    2323
    2424
    25 static char buffer[800000];
     25static char buffer[8000000];
    2626struct item_bin *item_bin=(struct item_bin *)(void *)buffer;
     27static char buffer_coastline[8000000];
     28struct item_bin *item_bin_coastline=(struct item_bin *)(void *)buffer_coastline;
    2729static struct node_item *node_item=(struct node_item *)(void *)buffer;
    2830
    2931struct node_item *
  • geom.c

     
    620620                item_bin_write_clipped(ib_in, param, out);
    621621        }
    622622}
     623
     624
     625
     626
     627static int coord_dot_prod (struct coord* c1, struct coord* c2)
     628{
     629        return c1->x*c2->x + c1->y*c2->y;
     630}
     631
     632
     633static void coord_sub (struct coord* c1, struct coord* c2, struct coord* cout)
     634{
     635        cout->x = c1->x - c2->x;
     636        cout->y = c1->y - c2->y;
     637}
     638
     639int self_intersect_test(struct item_bin*ib)
     640{
     641        int vertices_count = ib->clen/2;
     642        if(vertices_count<4) {
     643                return 0;
     644        }
     645        struct coord*vertices = (struct coord*)(ib+1);
     646        int i;
     647        for (i = 0; i < vertices_count; ++i) {
     648                if (i < vertices_count - 1) {
     649                    int h;
     650                    for (h = i + 1; h < vertices_count; ++h)
     651                    {
     652                        // Do two vertices lie on top of one another?
     653                        if ( i!=0 && h-i!=1 && h-i!=-1 && vertices[i].x == vertices[h].x && vertices[i].y == vertices[h].y ) {
     654                            return 1;
     655                        }
     656                    }
     657                }
     658
     659                int j = (i + 1) % vertices_count;
     660                struct coord iToj;
     661                coord_sub(&vertices[j], &vertices[i], &iToj);
     662                struct coord iTojNormal;
     663                iTojNormal.x =  iToj.y;
     664                iTojNormal.y = -iToj.x;
     665                // i is the first vertex and j is the second
     666                int startK = (j + 1) % vertices_count;
     667                int endK = (i - 1 + vertices_count) % vertices_count;
     668                endK += startK < endK ? 0 : startK + 1;
     669                int k = startK;
     670                struct coord iTok;
     671                coord_sub(&vertices[k], &vertices[i], &iTok);
     672                int onLeftSide = coord_dot_prod(&iTok, &iTojNormal) >= 0;
     673                struct coord prevK = vertices[k];
     674                ++k;
     675                for (; k <= endK; ++k)
     676                {
     677                    int modK = k % vertices_count;
     678                    coord_sub(&vertices[modK], &vertices[i], &iTok);
     679                    if (onLeftSide != coord_dot_prod(&iTok, &iTojNormal) >= 0)
     680                    {
     681                        struct coord prevKtoK, idiff, jdiff;
     682                        coord_sub(&vertices[modK], &prevK, &prevKtoK);
     683                        struct coord prevKtoKNormal;
     684                        prevKtoKNormal.x = prevKtoK.y;
     685                        prevKtoKNormal.y = -prevKtoK.x;
     686                        coord_sub(&vertices[i],&prevK,&idiff);
     687                        coord_sub(&vertices[j],&prevK,&jdiff);
     688                        if ((coord_dot_prod(&idiff, &prevKtoKNormal) >= 0) != (coord_dot_prod(&jdiff, &prevKtoKNormal) >= 0))
     689                        {
     690                            if(i!=j-1 && i!=j+1) {
     691                               return 1;
     692                            }
     693                        }
     694                    }
     695                    onLeftSide = coord_dot_prod(&iTok, &iTojNormal) > 0;
     696                    prevK = vertices[modK];
     697                }
     698            }
     699            return 0;
     700}
     701
     702
  • boundaries.c

     
    7070        while ((ib=read_item(boundaries))) {
    7171                char *member=NULL;
    7272                struct boundary *boundary=g_new0(struct boundary, 1);
     73
     74                //TODO rename natural to a better name
     75                boundary->natural = 0;
     76                if( osm_tag_value(ib, "natural") && !strcmp(osm_tag_value(ib, "natural"),"water")) {
     77                        boundary->natural = 1;
     78                }
     79                if( osm_tag_value(ib, "waterway") && !strcmp(osm_tag_value(ib, "waterway"),"riverbank")) {
     80                        boundary->natural = 1;
     81                }
     82
    7383                char *admin_level=osm_tag_value(ib, "admin_level");
    7484                char *iso=osm_tag_value(ib, "ISO3166-1");
    7585                /* disable spain for now since it creates a too large index */
     
    92102                        if (sscanf(member,"2:%Ld:%n",&wayid,&read) >= 1) {
    93103                                char *rolestr=member+read;
    94104                                enum geom_poly_segment_type role;
    95                                 if (!strcmp(rolestr,"outer") || !strcmp(rolestr,"exclave"))
     105                                if (!strcmp(rolestr,"outer") || !strcmp(rolestr,"exclave")) {
    96106                                        role=geom_poly_segment_type_way_outer;
     107                                }
    97108                                else if (!strcmp(rolestr,"inner") || !strcmp(rolestr,"enclave"))
    98109                                        role=geom_poly_segment_type_way_inner;
    99110                                else if (!strcmp(rolestr,""))
     
    202213        while (l) {
    203214                struct boundary *boundary=l->data;
    204215                int first=1;
    205                 FILE *f=NULL,*fu=NULL;
     216                FILE *f=NULL,*fu=NULL,*coastline=NULL;;
    206217                if (boundary->country) {
    207218                        char *name=g_strdup_printf("country_%s_poly",boundary->iso2);
    208219                        f=tempfile("",name,1);
    209220                        g_free(name);
    210221                }
     222                int to_write = 0;
     223                if (boundary->natural) {
     224                        coastline=tempfile("","ways_split",2);
     225                        struct item_bin *ib=item_bin_coastline;
     226                        item_bin_init(ib, type_poly_water);
     227                }
    211228                boundary->sorted_segments=geom_poly_segments_sort(boundary->segments, geom_poly_segment_type_way_right_side);
    212229                sl=boundary->sorted_segments;
    213230                while (sl) {
     
    228245                                item_bin_add_coord(ib, gs->first, gs->last-gs->first+1);
    229246                                item_bin_write(ib, f);
    230247                        }
     248                        if (coastline && gs->type==geom_poly_segment_type_way_outer) {
     249                                struct item_bin *ib=item_bin_coastline;
     250                                item_bin_add_coord(ib, gs->first, gs->last-gs->first+1);
     251                                to_write = 1;
     252#if 0
     253struct coord*crd = gs->first;
     254//printf("\nPTR:%p\n",ib);
     255while(crd != gs->last) {
     256        printf("CRD:%d %d\n",crd->x,crd->y);
     257        crd++;
     258}
     259#endif
     260                        }
    231261                        if (boundary->country) {
    232262                                if (!coord_is_equal(*gs->first,*gs->last)) {
    233263                                        if (!fu) {
     
    246276                        }
    247277                        sl=g_list_next(sl);
    248278                }       
     279
     280                if (coastline && to_write ) {
     281                        struct item_bin *ib=item_bin_coastline;
     282                        if(0 == self_intersect_test(ib)) {
     283                                item_bin_write(ib, coastline);
     284                        } else {
     285#if 1
     286struct coord*crd = (struct coord*)(ib+1);
     287int ii;
     288for(ii=0;ii<ib->clen/2;++ii) {
     289        printf("CRD:%d %d\n",crd->x,crd->y);
     290        crd++;
     291}
     292#endif
     293                        }
     294                        item_bin_init(ib, type_poly_water);
     295#if 1
     296printf("CRD:\n");
     297#endif
     298                }
     299
    249300                ret=process_boundaries_insert(ret, boundary);
    250301                l=g_list_next(l);
    251302                if (f)
    252303                        fclose(f);
     304                if (coastline)
     305                        fclose(coastline);
    253306                if (fu) {
    254307                        if (boundary->country)
    255308                                osm_warning("relation",item_bin_get_relationid(boundary->ib),0,"Broken country polygon '%s'\n",boundary->iso2);
    256309                        fclose(fu);
    257310                }
    258                
    259311        }
    260312#if 0
    261313        printf("hierarchy\n");