void ProcessRelationTags(TagList *tags,int64_t relation_id,int mode) { transports_t routes=Transports_None; transports_t except=Transports_None; int relation_turn_restriction=0; TurnRestriction restriction=TurnRestrict_None; relation_t id; int i; /* Convert id */ id=(relation_t)relation_id; logassert((int64_t)id==relation_id,"Relation ID too large (change relation_t to 64-bits?)"); /* check relation id can be stored in relation_t data type. */ /* Delete */ if(mode==MODE_DELETE || mode==MODE_MODIFY) { AppendRouteRelationList(relations,id,RELATION_DELETED, relation_nodes,relation_nnodes, relation_ways,relation_nways, relation_relations,relation_nrelations); AppendTurnRelationList(relations,id, relation_from,relation_to,relation_via, restriction,RELATION_DELETED); } if(mode==MODE_DELETE) return; /* Sanity check */ if(relation_nnodes==0 && relation_nways==0 && relation_nrelations==0) { logerror("Relation %"Prelation_t" has no nodes, ways or relations.\n",logerror_relation(id)); return; } /* Parse the tags */ for(i=0;i<tags->ntags;i++) { int recognised=0; char *k=tags->k[i]; char *v=tags->v[i]; switch(*k) { case 'b': if(!strcmp(k,"bicycleroute")) { if(ISTRUE(v)) routes|=Transports_Bicycle; else if(!ISFALSE(v)) logerror("Relation %"Prelation_t" has an unrecognised tag 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",logerror_relation(id),v); recognised=1; break; } break; case 'e': if(!strcmp(k,"except")) { for(i=1;i<Transport_Count;i++) if(strstr(v,TransportName(i))) except|=TRANSPORTS(i); if(except==Transports_None) logerror("Relation %"Prelation_t" has an unrecognised tag 'except' = '%s' (after tagging rules); ignoring it.\n",logerror_relation(id),v); recognised=1; break; } break; case 'f': if(!strcmp(k,"footroute")) { if(ISTRUE(v)) routes|=Transports_Foot; else if(!ISFALSE(v)) logerror("Relation %"Prelation_t" has an unrecognised tag 'footroute' = '%s' (after tagging rules); using 'no'.\n",logerror_relation(id),v); recognised=1; break; } break; case 'r': if(!strcmp(k,"restriction")) { if(!strcmp(v,"no_right_turn" )) restriction=TurnRestrict_no_right_turn; if(!strcmp(v,"no_left_turn" )) restriction=TurnRestrict_no_left_turn; if(!strcmp(v,"no_u_turn" )) restriction=TurnRestrict_no_u_turn; if(!strcmp(v,"no_straight_on" )) restriction=TurnRestrict_no_straight_on; if(!strcmp(v,"only_right_turn" )) restriction=TurnRestrict_only_right_turn; if(!strcmp(v,"only_left_turn" )) restriction=TurnRestrict_only_left_turn; if(!strcmp(v,"only_straight_on")) restriction=TurnRestrict_only_straight_on; if(restriction==TurnRestrict_None) logerror("Relation %"Prelation_t" has an unrecognised tag 'restriction' = '%s' (after tagging rules); ignoring it.\n",logerror_relation(id),v); recognised=1; break; } break; case 't': if(!strcmp(k,"type")) { if(!strcmp(v,"restriction")) relation_turn_restriction=1; /* Don't log an error for relations of types that we don't handle - there are so many */ recognised=1; break; } break; default: break; } if(!recognised) logerror("Relation %"Prelation_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",logerror_relation(id),k,v); } /* Create the route relation (must store all relations that have ways or relations even if they are not routes because they might be referenced by other relations that are routes) */ if((relation_nways || relation_nrelations) && !relation_turn_restriction) AppendRouteRelationList(relations,id,routes, relation_nodes,relation_nnodes, relation_ways,relation_nways, relation_relations,relation_nrelations); /* Create the turn restriction relation. */ if(relation_turn_restriction && restriction!=TurnRestrict_None) { if(relation_from==NO_WAY_ID) { /* Extra logerror information since relation isn't stored */ if(relation_to!=NO_WAY_ID) logerror_way(relation_to); if(relation_via!=NO_NODE_ID) logerror_node(relation_via); logerror("Relation %"Prelation_t" is a turn restriction but has no 'from' way.\n",logerror_relation(id)); } if(relation_to==NO_WAY_ID) { /* Extra logerror information since relation isn't stored */ if(relation_via!=NO_NODE_ID) logerror_node(relation_via); if(relation_from!=NO_WAY_ID) logerror_way(relation_from); logerror("Relation %"Prelation_t" is a turn restriction but has no 'to' way.\n",logerror_relation(id)); } if(relation_via==NO_NODE_ID) { /* Extra logerror information since relation isn't stored */ if(relation_to!=NO_WAY_ID) logerror_way(relation_to); if(relation_from!=NO_WAY_ID) logerror_way(relation_from); logerror("Relation %"Prelation_t" is a turn restriction but has no 'via' node.\n",logerror_relation(id)); } if(relation_from!=NO_WAY_ID && relation_to!=NO_WAY_ID && relation_via!=NO_NODE_ID) AppendTurnRelationList(relations,id, relation_from,relation_to,relation_via, restriction,except); } }
void ProcessNodeTags(TagList *tags,int64_t node_id,double latitude,double longitude,int mode) { transports_t allow=Transports_ALL; nodeflags_t flags=0; node_t id; int i; /* Convert id */ id=(node_t)node_id; logassert((int64_t)id==node_id,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */ /* Delete */ if(mode==MODE_DELETE) { AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,NODE_DELETED); return; } /* Parse the tags */ for(i=0;i<tags->ntags;i++) { int recognised=0; char *k=tags->k[i]; char *v=tags->v[i]; switch(*k) { case 'b': if(!strcmp(k,"bicycle")) { if(ISFALSE(v)) allow&=~Transports_Bicycle; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'bicycle' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'f': if(!strcmp(k,"foot")) { if(ISFALSE(v)) allow&=~Transports_Foot; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'foot' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'g': if(!strcmp(k,"goods")) { if(ISFALSE(v)) allow&=~Transports_Goods; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'goods' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'h': if(!strcmp(k,"horse")) { if(ISFALSE(v)) allow&=~Transports_Horse; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'horse' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } if(!strcmp(k,"hgv")) { if(ISFALSE(v)) allow&=~Transports_HGV; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'hgv' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'm': if(!strcmp(k,"moped")) { if(ISFALSE(v)) allow&=~Transports_Moped; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'moped' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } if(!strcmp(k,"motorcycle")) { if(ISFALSE(v)) allow&=~Transports_Motorcycle; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'motorcycle' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } if(!strcmp(k,"motorcar")) { if(ISFALSE(v)) allow&=~Transports_Motorcar; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'motorcar' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'p': if(!strcmp(k,"psv")) { if(ISFALSE(v)) allow&=~Transports_PSV; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'psv' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'r': if(!strcmp(k,"roundabout")) { if(ISTRUE(v)) flags|=NODE_MINIRNDBT; else logerror("Node %"Pnode_t" has an unrecognised tag 'roundabout' = '%s' (after tagging rules); using 'no'.\n",id,v); recognised=1; break; } break; case 'w': if(!strcmp(k,"wheelchair")) { if(ISFALSE(v)) allow&=~Transports_Wheelchair; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'wheelchair' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; default: break; } if(!recognised) logerror("Node %"Pnode_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",logerror_node(id),k,v); } /* Create the node */ AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags); }
void ProcessWayTags(TagList *tags,int64_t way_id,int mode) { Way way={0}; int oneway=0,area=0; int roundabout=0,lanes=0; char *name=NULL,*ref=NULL,*refname=NULL; way_t id; int i; /* Convert id */ id=(way_t)way_id; logassert((int64_t)id==way_id,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */ /* Delete */ if(mode==MODE_DELETE || mode==MODE_MODIFY) { way.type=WAY_DELETED; AppendWayList(ways,id,&way,way_nodes,way_nnodes,""); } if(mode==MODE_DELETE) return; /* Sanity check */ if(way_nnodes==0) { logerror("Way %"Pway_t" has no nodes.\n",logerror_way(id)); return; } if(way_nnodes==1) { logerror_node(way_nodes[0]); /* Extra logerror information since way isn't stored */ logerror("Way %"Pway_t" has only one node.\n",logerror_way(id)); return; } /* Parse the tags - just look for highway */ for(i=0;i<tags->ntags;i++) { char *k=tags->k[i]; char *v=tags->v[i]; if(!strcmp(k,"highway")) { way.type=HighwayType(v); if(way.type==Highway_None) logerror("Way %"Pway_t" has an unrecognised highway type '%s' (after tagging rules); ignoring it.\n",logerror_way(id),v); break; } } /* Don't continue if this is not a highway (bypass error logging) */ if(way.type==Highway_None) return; /* Parse the tags - look for the others */ for(i=0;i<tags->ntags;i++) { int recognised=0; char *k=tags->k[i]; char *v=tags->v[i]; switch(*k) { case 'a': if(!strcmp(k,"area")) { if(ISTRUE(v)) area=1; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'area' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'b': if(!strcmp(k,"bicycle")) { if(ISTRUE(v)) way.allow|=Transports_Bicycle; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'bicycle' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"bicycleroute")) { if(ISTRUE(v)) way.props|=Properties_BicycleRoute; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"bridge")) { if(ISTRUE(v)) way.props|=Properties_Bridge; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'bridge' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'c': if(!strcmp(k,"cycleway")) { if(!strcmp(v,"opposite_lane")) way.props|=Properties_DoubleSens; recognised=1; break; } break; case 'f': if(!strcmp(k,"foot")) { if(ISTRUE(v)) way.allow|=Transports_Foot; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'foot' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"footroute")) { if(ISTRUE(v)) way.props|=Properties_FootRoute; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'footroute' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'g': if(!strcmp(k,"goods")) { if(ISTRUE(v)) way.allow|=Transports_Goods; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'goods' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'h': if(!strcmp(k,"highway")) {recognised=1; break;} if(!strcmp(k,"horse")) { if(ISTRUE(v)) way.allow|=Transports_Horse; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'horse' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"hgv")) { if(ISTRUE(v)) way.allow|=Transports_HGV; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'hgv' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'i': if(!strcmp(k,"incline")) { /* logerror("Way %"Pway_t" has an 'incline' = '%s' \n",logerror_way(id),v); */ way.incline=pourcent_to_incline(parse_incline(id,k,v)); recognised=1; break; } break; case 'l': if(!strcmp(k,"lanes")) { int en=0; float lanesf; if(sscanf(v,"%f%n",&lanesf,&en)==1 && en && !v[en]) lanes=(int)lanesf; else logerror("Way %"Pway_t" has an unrecognised tag 'lanes' = '%s' (after tagging rules); ignoring it.\n",logerror_way(id),v); recognised=1; break; } break; case 'm': if(!strncmp(k,"max",3)) { if(!strcmp(k+3,"speed")) { way.speed=kph_to_speed(parse_speed(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"weight")) { way.weight=tonnes_to_weight(parse_weight(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"height")) { way.height=metres_to_height(parse_length(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"width")) { way.width=metres_to_height(parse_length(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"length")) { way.length=metres_to_height(parse_length(id,k,v)); recognised=1; break; } } if(!strcmp(k,"moped")) { if(ISTRUE(v)) way.allow|=Transports_Moped; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'moped' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"motorcycle")) { if(ISTRUE(v)) way.allow|=Transports_Motorcycle; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'motorcycle' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"motorcar")) { if(ISTRUE(v)) way.allow|=Transports_Motorcar; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'motorcar' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"multilane")) { if(ISTRUE(v)) way.props|=Properties_Multilane; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'multilane' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'n': if(!strcmp(k,"name")) { name=v; recognised=1; break; } break; case 'o': if(!strcmp(k,"oneway")) { if(ISTRUE(v)) oneway=1; else if(!strcmp(v,"-1")) oneway=-1; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'oneway' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'p': if(!strcmp(k,"paved")) { if(ISTRUE(v)) way.props|=Properties_Paved; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'paved' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"psv")) { if(ISTRUE(v)) way.allow|=Transports_PSV; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'psv' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'r': if(!strcmp(k,"ref")) { ref=v; recognised=1; break; } if(!strcmp(k,"roundabout")) { if(ISTRUE(v)) roundabout=1; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'roundabout' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 't': if(!strcmp(k,"tunnel")) { if(ISTRUE(v)) way.props|=Properties_Tunnel; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'tunnel' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'w': if(!strcmp(k,"wheelchair")) { if(ISTRUE(v)) way.allow|=Transports_Wheelchair; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; default: break; } if(!recognised) logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",logerror_way(id),k,v); } /* Create the way */ if(area && oneway) { logerror("Way %"Pway_t" is an area and oneway; ignoring area tagging.\n",logerror_way(id)); area=0; } if(!way.allow) return; if(oneway) { way.type|=Highway_OneWay; if(oneway==-1) for(i=0;i<way_nnodes/2;i++) { node_t temp; temp=way_nodes[i]; way_nodes[i]=way_nodes[way_nnodes-i-1]; way_nodes[way_nnodes-i-1]=temp; } } if(roundabout) way.type|=Highway_Roundabout; if(area) { way.type|=Highway_Area; if(way_nodes[0]!=way_nodes[way_nnodes-1]) logerror("Way %"Pway_t" is an area but not closed.\n",logerror_way(id)); } if(lanes) { if(oneway || (lanes/2)>1) way.props|=Properties_Multilane; if(oneway && lanes==1) way.props&=~Properties_Multilane; } if(ref && name) { refname=(char*)malloc(strlen(ref)+strlen(name)+4); sprintf(refname,"%s (%s)",name,ref); } else if(ref && !name) refname=ref; else if(!ref && name) refname=name; else /* if(!ref && !name) */ refname=""; AppendWayList(ways,id,&way,way_nodes,way_nnodes,refname); if(ref && name) free(refname); }
SegmentsX *SplitWays(WaysX *waysx,NodesX *nodesx,int keep) { SegmentsX *segmentsx; index_t i; int fd,nfd; char *name=NULL; int namelen=0; /* Print the start message */ printf_first("Splitting Ways: Ways=0 Segments=0"); segmentsx=NewSegmentList(); /* Re-open the file read-only and a new file writeable */ waysx->fd=ReOpenFileBuffered(waysx->filename_tmp); if(keep) RenameFile(waysx->filename_tmp,waysx->filename); else DeleteFile(waysx->filename_tmp); fd=OpenFileBufferedNew(waysx->filename_tmp); nfd=OpenFileBufferedNew(waysx->nfilename_tmp); /* Loop through the ways and create the segments and way names */ for(i=0;i<waysx->number;i++) { WayX wayx; FILESORT_VARINT size; node_t node,prevnode=NO_NODE_ID; index_t index,previndex=NO_NODE; ReadFileBuffered(waysx->fd,&size,FILESORT_VARSIZE); ReadFileBuffered(waysx->fd,&wayx,sizeof(WayX)); waysx->allow|=wayx.way.allow; while(!ReadFileBuffered(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID) { index=IndexNodeX(nodesx,node); if(prevnode==node) { logerror("Way %"Pway_t" contains node %"Pnode_t" that is connected to itself.\n",logerror_way(wayx.id),logerror_node(node)); } else if(index==NO_NODE) { logerror("Way %"Pway_t" contains node %"Pnode_t" that does not exist in the Routino database.\n",logerror_way(wayx.id),logerror_node(node)); } else if(previndex==NO_NODE) ; else { distance_t segment_flags=0; if(wayx.way.type&Highway_OneWay) segment_flags|=ONEWAY_1TO2; if(wayx.way.type&Highway_Area) segment_flags|=SEGMENT_AREA; AppendSegmentList(segmentsx,i,previndex,index,segment_flags); } prevnode=node; previndex=index; size-=sizeof(node_t); } size-=sizeof(node_t)+sizeof(WayX); if(namelen<size) name=(char*)realloc((void*)name,namelen=size); ReadFileBuffered(waysx->fd,name,size); WriteFileBuffered(fd,&wayx,sizeof(WayX)); size+=sizeof(index_t); WriteFileBuffered(nfd,&size,FILESORT_VARSIZE); WriteFileBuffered(nfd,&i,sizeof(index_t)); WriteFileBuffered(nfd,name,size-sizeof(index_t)); if(!((i+1)%1000)) printf_middle("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,i+1,segmentsx->number); } FinishSegmentList(segmentsx); if(name) free(name); /* Close the files */ waysx->fd=CloseFileBuffered(waysx->fd); CloseFileBuffered(fd); CloseFileBuffered(nfd); /* Print the final message */ printf_last("Split Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,waysx->number,segmentsx->number); return(segmentsx); }