Ticket #859: poi-inside.2.diff

File poi-inside.2.diff, 3.2 KB (added by https://wiki.navit-project.org/index.php/user:tryagain, 10 months ago)

updated

  • navit/maptool/osm.c

     
    21352135{ 
    21362136        struct item_bin *ib; 
    21372137        while ((ib=read_item(in))) { 
    2138                 if(ib->clen>2 && ib->type<type_line) { 
    2139                         struct coord *c=(struct coord *)(ib+1); 
    2140                         if(ib->clen/2>2) { 
    2141                                 if(!geom_poly_centroid(c,ib->clen/2,c)) { 
     2138                int count=ib->clen/2; 
     2139                if(count>1 && ib->type<type_line) { 
     2140                        struct coord *c=(struct coord *)(ib+1), c1, c2; 
     2141                        if(count>2) { 
     2142                                if(!geom_poly_centroid(c, count, &c1)) { 
    21422143                                        // we have poly with zero area 
    21432144                                        // Falling back to coordinates of its first vertex... 
    21442145                                        osm_warning("way",item_bin_get_wayid(ib),0,"Broken polygon, area is 0\n"); 
     2146                                } else { 
     2147                                        if(geom_poly_point_inside(c, count, &c1)) { 
     2148                                                c[0]=c1; 
     2149                                        } else { 
     2150                                                geom_poly_closest_point(c, count, &c1, &c2); 
     2151                                                c[0]=c2; 
     2152                                        } 
    21452153                                } 
    2146                         } else if (ib->clen/2==2) { 
     2154                        } else if (count==2) { 
    21472155                                osm_warning("way",item_bin_get_wayid(ib),0, "Expected polygon, but only two points defined\n"); 
    21482156                                c[0].x=(c[0].x+c[1].x)/2; 
    21492157                                c[0].y=(c[0].y+c[1].y)/2; 
  • navit/maptool/maptool.h

     
    145145void geom_coord_revert(struct coord *c, int count); 
    146146long long geom_poly_area(struct coord *c, int count); 
    147147int geom_poly_centroid(struct coord *c, int count, struct coord *r); 
     148int geom_poly_point_inside(struct coord *cp, int count, struct coord *c); 
    148149int geom_poly_closest_point(struct coord *pl, int count, struct coord *p, struct coord *c); 
    149150GList *geom_poly_segments_insert(GList *list, struct geom_poly_segment *first, struct geom_poly_segment *second, struct geom_poly_segment *third); 
    150151void geom_poly_segment_destroy(struct geom_poly_segment *seg); 
  • navit/maptool/geom.c

     
    148148        return vertex; 
    149149} 
    150150 
     151/** 
     152  * Check if point is inside polgone. 
     153  * @param in *cp array of polygon vertex coordinates 
     154  * @param in count count of polygon vertexes 
     155  * @param in *c point coordinates  
     156  * @returns 1 - inside, 0 - outside 
     157  */ 
     158int 
     159geom_poly_point_inside(struct coord *cp, int count, struct coord *c) 
     160{ 
     161        int ret=0; 
     162        struct coord *last=cp+count-1; 
     163        while (cp < last) { 
     164                if ((cp[0].y > c->y) != (cp[1].y > c->y) && 
     165                        c->x < (cp[1].x-cp[0].x)*(c->y-cp[0].y)/(cp[1].y-cp[0].y)+cp[0].x) 
     166                        ret=!ret; 
     167                cp++; 
     168        } 
     169        return ret; 
     170} 
    151171 
     172 
     173 
    152174GList * 
    153175geom_poly_segments_insert(GList *list, struct geom_poly_segment *first, struct geom_poly_segment *second, struct geom_poly_segment *third) 
    154176{ 
     
    294316        while (in) { 
    295317                struct geom_poly_segment *seg=in->data; 
    296318                cp=seg->first; 
    297                 while (cp < seg->last) { 
    298                         if ((cp[0].y > c->y) != (cp[1].y > c->y) && 
    299                                 c->x < (cp[1].x-cp[0].x)*(c->y-cp[0].y)/(cp[1].y-cp[0].y)+cp[0].x) 
    300                                 ret=!ret; 
    301                         cp++; 
    302                 } 
     319                ret^=geom_poly_point_inside(seg->first, seg->last-seg->first+1, c); 
    303320                in=g_list_next(in); 
    304321        } 
    305322        return ret;