/***************************************
- $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.69 2010/05/29 13:54:23 amb Exp $
+ $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.73 2010/11/13 14:22:28 amb Exp $
OSM XML file parser (either JOSM or planet)
#include "typesx.h"
#include "functionsx.h"
+
#include "nodesx.h"
#include "segmentsx.h"
#include "waysx.h"
+#include "relationsx.h"
+
#include "xmlparse.h"
#include "tagging.h"
+#include "logging.h"
+
/* Macros */
static node_t *way_nodes=NULL;
static int way_nnodes=0;
-static NodesX *nodes;
-static SegmentsX *segments;
-static WaysX *ways;
+static node_t *relation_nodes=NULL;
+static int relation_nnodes=0;
+static way_t *relation_ways=NULL;
+static int relation_nways=0;
+static relation_t *relation_relations=NULL;
+static int relation_nrelations=0;
+
+static NodesX *nodes;
+static SegmentsX *segments;
+static WaysX *ways;
+static RelationsX *relations;
/* Local functions */
+static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude);
static void process_way_tags(TagList *tags,way_t id);
+static void process_relation_tags(TagList *tags,relation_t id);
/* The XML tag processing function prototypes */
//static int osmType_function(const char *_tag_,int _type_);
static int relationType_function(const char *_tag_,int _type_,const char *id);
static int wayType_function(const char *_tag_,int _type_,const char *id);
-//static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
+static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
static int ndType_function(const char *_tag_,int _type_,const char *ref);
static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon);
static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
static xmltag memberType_tag=
{"member",
3, {"type","ref","role"},
- NULL,
+ memberType_function,
{NULL}};
/*+ The wayType type tag. +*/
static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
{
+ static node_t node_id;
+ static double latitude,longitude;
+
if(_type_&XMLPARSE_TAG_START)
{
- node_t node_id;
- double latitude,longitude;
-
nnodes++;
if(!(nnodes%1000))
- {
- printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
- fflush(stdout);
- }
+ printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
+
+ current_tags=NewTagList();
/* Handle the node information */
XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */
XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude);
XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude);
+ }
- AppendNode(nodes,node_id,degrees_to_radians(latitude),degrees_to_radians(longitude));
+ if(_type_&XMLPARSE_TAG_END)
+ {
+ TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
-// current_tags=NewTagList();
- current_tags=NULL;
- }
+ process_node_tags(result,node_id,latitude,longitude);
-// if(_type_&XMLPARSE_TAG_END)
-// {
-// TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
-//
-// DeleteTagList(current_tags);
-// DeleteTagList(result);
-// }
+ DeleteTagList(current_tags);
+ DeleteTagList(result);
+ }
return(0);
}
XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
- if((way_nnodes%256)==0)
+ if(way_nnodes && (way_nnodes%256)==0)
way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
way_nodes[way_nnodes++]=node_id;
const char *role The contents of the 'role' attribute (or NULL if not defined).
++++++++++++++++++++++++++++++++++++++*/
-//static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
-//{
-// return(0);
-//}
+static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
+{
+ if(_type_&XMLPARSE_TAG_START)
+ {
+ XMLPARSE_ASSERT_STRING(_tag_,type);
+ XMLPARSE_ASSERT_STRING(_tag_,ref);
+
+ if(!strcmp(type,"node"))
+ {
+ node_t node_id=atoll(ref); /* need long long conversion */
+
+ if(relation_nnodes && (relation_nnodes%256)==0)
+ relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t));
+
+ relation_nodes[relation_nnodes++]=node_id;
+ }
+ else if(!strcmp(type,"way"))
+ {
+ way_t way_id=atoll(ref); /* need long long conversion */
+
+ if(relation_nways && (relation_nways%256)==0)
+ relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t));
+
+ relation_ways[relation_nways++]=way_id;
+ }
+ else if(!strcmp(type,"relation"))
+ {
+ relation_t relation_id=atoll(ref); /* need long long conversion */
+
+ if(relation_nrelations && (relation_nrelations%256)==0)
+ relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t));
+
+ relation_relations[relation_nrelations++]=relation_id;
+ }
+ }
+
+ return(0);
+}
/*++++++++++++++++++++++++++++++++++++++
nways++;
if(!(nways%1000))
- {
- printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
- fflush(stdout);
- }
+ printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
current_tags=NewTagList();
+
way_nnodes=0;
/* Handle the way information */
static int relationType_function(const char *_tag_,int _type_,const char *id)
{
+ static relation_t relation_id;
+
if(_type_&XMLPARSE_TAG_START)
{
nrelations++;
if(!(nrelations%1000))
- {
- printf("\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
- fflush(stdout);
- }
+ printf_middle("Reading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
+
+ current_tags=NewTagList();
-// current_tags=NewTagList();
- current_tags=NULL;
+ relation_nnodes=relation_nways=relation_nrelations=0;
+
+ /* Handle the relation information */
+
+ XMLPARSE_ASSERT_STRING(_tag_,id); relation_id=atoll(id); /* need long long conversion */
}
-// if(_type_&XMLPARSE_TAG_END)
-// {
-// TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
-//
-// DeleteTagList(current_tags);
-// DeleteTagList(result);
-// }
+ if(_type_&XMLPARSE_TAG_END)
+ {
+ TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
+
+ process_relation_tags(result,relation_id);
+
+ DeleteTagList(current_tags);
+ DeleteTagList(result);
+ }
return(0);
}
FILE *file The file to read from.
- NodesX *OSMNodes The array of nodes to fill in.
+ NodesX *OSMNodes The data structure of nodes to fill in.
+
+ SegmentsX *OSMSegments The data structure of segments to fill in.
- SegmentsX *OSMSegments The array of segments to fill in.
+ WaysX *OSMWays The data structure of ways to fill in.
- WaysX *OSMWays The arrray of ways to fill in.
+ RelationsX *OSMRelations The data structure of relations to fill in.
++++++++++++++++++++++++++++++++++++++*/
-int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays)
+int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
{
int retval;
- /* Parse the file */
+ /* Copy the function parameters and initialise the variables. */
nodes=OSMNodes;
segments=OSMSegments;
ways=OSMWays;
+ relations=OSMRelations;
+
+ way_nodes=(node_t*)malloc(256*sizeof(node_t));
+
+ relation_nodes =(node_t *)malloc(256*sizeof(node_t));
+ relation_ways =(way_t *)malloc(256*sizeof(way_t));
+ relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
+
+ /* Parse the file */
nnodes=0,nways=0,nrelations=0;
- printf("\rReading: Lines=0 Nodes=0 Ways=0 Relations=0");
- fflush(stdout);
+ printf_first("Reading: Lines=0 Nodes=0 Ways=0 Relations=0");
retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
- printf("\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations);
- fflush(stdout);
+ printf_last("Read: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
return(retval);
}
/*++++++++++++++++++++++++++++++++++++++
+ Process the tags associated with a node.
+
+ TagList *tags The list of node tags.
+
+ node_t id The id of the node.
+
+ double latitude The latitude of the node.
+
+ double longitude The longitude of the node.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude)
+{
+ allow_t allow=Allow_ALL;
+
+ int i;
+
+ /* Parse the tags */
+
+ for(i=0;i<tags->ntags;i++)
+ {
+ char *k=tags->k[i];
+ char *v=tags->v[i];
+
+ switch(*k)
+ {
+ case 'b':
+ if(!strcmp(k,"bicycle"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Bicycle;
+
+ break;
+
+ case 'f':
+ if(!strcmp(k,"foot"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Foot;
+
+ break;
+
+ case 'g':
+ if(!strcmp(k,"goods"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Goods;
+
+ break;
+
+ case 'h':
+ if(!strcmp(k,"horse"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Horse;
+
+ if(!strcmp(k,"hgv"))
+ if(!ISTRUE(v))
+ allow&=~Allow_HGV;
+
+ break;
+
+ case 'm':
+ if(!strcmp(k,"moped"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Moped;
+
+ if(!strcmp(k,"motorbike"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Motorbike;
+
+ if(!strcmp(k,"motorcar"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Motorcar;
+
+ break;
+
+ case 'p':
+ if(!strcmp(k,"psv"))
+ if(!ISTRUE(v))
+ allow&=~Allow_PSV;
+
+ break;
+
+ case 'w':
+ if(!strcmp(k,"wheelchair"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Wheelchair;
+
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ /* Create the node */
+
+ AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
Process the tags associated with a way.
TagList *tags The list of way tags.
if(ISTRUE(v))
way.allow|= Allow_Bicycle;
+ if(!strcmp(k,"bicycleroute"))
+ if(ISTRUE(v))
+ way.props|=Properties_BicycleRoute;
+
if(!strcmp(k,"bridge"))
if(ISTRUE(v))
way.props|=Properties_Bridge;
if(ISTRUE(v))
way.allow|= Allow_Foot;
+ if(!strcmp(k,"footroute"))
+ if(ISTRUE(v))
+ way.props|=Properties_FootRoute;
+
break;
case 'g':
}
}
}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Process the tags associated with a relation.
+
+ TagList *tags The list of relation tags.
+
+ relation_t id The id of the relation.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static void process_relation_tags(TagList *tags,relation_t id)
+{
+ allow_t routes=Allow_None;
+ int i;
+
+ /* Parse the tags */
+
+ for(i=0;i<tags->ntags;i++)
+ {
+ char *k=tags->k[i];
+ char *v=tags->v[i];
+
+ switch(*k)
+ {
+ case 'b':
+ if(!strcmp(k,"bicycleroute"))
+ if(ISTRUE(v))
+ routes|=Allow_Bicycle;
+
+ break;
+
+ case 'f':
+ if(!strcmp(k,"footroute"))
+ if(ISTRUE(v))
+ routes|=Allow_Foot;
+
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ /* 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)
+ AppendRouteRelation(relations,id,routes,
+ relation_ways,relation_nways,
+ relation_relations,relation_nrelations);
+}