1 /***************************************
2 $Header: /home/amb/routino/src/RCS/tagmodifier.c,v 1.5 2010/05/30 18:18:54 amb Exp $
4 Test application for OSM XML file parser / tagging rule testing.
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2010 Andrew M. Bishop
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ***************************************/
31 #include "functions.h"
38 static long nnodes=0,nways=0,nrelations=0;
39 TagList *current_tags=NULL;
44 static void print_usage(int detail);
47 /* The XML tag processing function prototypes */
49 static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
50 static int osmType_function(const char *_tag_,int _type_,const char *version,const char *generator);
51 static int relationType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action);
52 static int wayType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action);
53 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
54 static int ndType_function(const char *_tag_,int _type_,const char *ref);
55 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action);
56 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
57 static int boundType_function(const char *_tag_,int _type_,const char *box,const char *origin);
58 static int boundsType_function(const char *_tag_,int _type_,const char *minlat,const char *minlon,const char *maxlat,const char *maxlon,const char *origin);
61 /* The XML tag definitions */
63 /*+ The boundsType type tag. +*/
64 static xmltag boundsType_tag=
66 5, {"minlat","minlon","maxlat","maxlon","origin"},
70 /*+ The boundType type tag. +*/
71 static xmltag boundType_tag=
77 /*+ The tagType type tag. +*/
78 static xmltag tagType_tag=
84 /*+ The nodeType type tag. +*/
85 static xmltag nodeType_tag=
87 9, {"id","lat","lon","timestamp","uid","user","visible","version","action"},
91 /*+ The ndType type tag. +*/
92 static xmltag ndType_tag=
98 /*+ The memberType type tag. +*/
99 static xmltag memberType_tag=
101 3, {"type","ref","role"},
105 /*+ The wayType type tag. +*/
106 static xmltag wayType_tag=
108 7, {"id","timestamp","uid","user","visible","version","action"},
110 {&ndType_tag,&tagType_tag,NULL}};
112 /*+ The relationType type tag. +*/
113 static xmltag relationType_tag=
115 7, {"id","timestamp","uid","user","visible","version","action"},
116 relationType_function,
117 {&memberType_tag,&tagType_tag,NULL}};
119 /*+ The osmType type tag. +*/
120 static xmltag osmType_tag=
122 2, {"version","generator"},
124 {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}};
126 /*+ The xmlDeclaration type tag. +*/
127 static xmltag xmlDeclaration_tag=
129 2, {"version","encoding"},
130 xmlDeclaration_function,
134 /*+ The complete set of tags at the top level. +*/
135 static xmltag *xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL};
138 /* The XML tag processing functions */
141 /*++++++++++++++++++++++++++++++++++++++
142 The function that is called when the boundsType XSD type is seen
144 int boundsType_function Returns 0 if no error occured or something else otherwise.
146 const char *_tag_ Set to the name of the element tag that triggered this function call.
148 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
150 const char *minlat The contents of the 'minlat' attribute (or NULL if not defined).
152 const char *minlon The contents of the 'minlon' attribute (or NULL if not defined).
154 const char *maxlat The contents of the 'maxlat' attribute (or NULL if not defined).
156 const char *maxlon The contents of the 'maxlon' attribute (or NULL if not defined).
158 const char *origin The contents of the 'origin' attribute (or NULL if not defined).
159 ++++++++++++++++++++++++++++++++++++++*/
161 static int boundsType_function(const char *_tag_,int _type_,const char *minlat,const char *minlon,const char *maxlat,const char *maxlon,const char *origin)
163 printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
164 if(minlat) printf(" minlat=\"%s\"",ParseXML_Encode_Safe_XML(minlat));
165 if(minlon) printf(" minlon=\"%s\"",ParseXML_Encode_Safe_XML(minlon));
166 if(maxlat) printf(" maxlat=\"%s\"",ParseXML_Encode_Safe_XML(maxlat));
167 if(maxlon) printf(" maxlon=\"%s\"",ParseXML_Encode_Safe_XML(maxlon));
168 if(origin) printf(" origin=\"%s\"",ParseXML_Encode_Safe_XML(origin));
169 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
174 /*++++++++++++++++++++++++++++++++++++++
175 The function that is called when the boundType XSD type is seen
177 int boundType_function Returns 0 if no error occured or something else otherwise.
179 const char *_tag_ Set to the name of the element tag that triggered this function call.
181 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
183 const char *box The contents of the 'box' attribute (or NULL if not defined).
185 const char *origin The contents of the 'origin' attribute (or NULL if not defined).
186 ++++++++++++++++++++++++++++++++++++++*/
188 static int boundType_function(const char *_tag_,int _type_,const char *box,const char *origin)
190 printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
191 if(box) printf(" box=\"%s\"",ParseXML_Encode_Safe_XML(box));
192 if(origin) printf(" origin=\"%s\"",ParseXML_Encode_Safe_XML(origin));
193 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
198 /*++++++++++++++++++++++++++++++++++++++
199 The function that is called when the tagType XSD type is seen
201 int tagType_function Returns 0 if no error occured or something else otherwise.
203 const char *_tag_ Set to the name of the element tag that triggered this function call.
205 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
207 const char *k The contents of the 'k' attribute (or NULL if not defined).
209 const char *v The contents of the 'v' attribute (or NULL if not defined).
210 ++++++++++++++++++++++++++++++++++++++*/
212 static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
214 if(_type_&XMLPARSE_TAG_START)
216 XMLPARSE_ASSERT_STRING(_tag_,k);
217 XMLPARSE_ASSERT_STRING(_tag_,v);
219 AppendTag(current_tags,k,v);
226 /*++++++++++++++++++++++++++++++++++++++
227 The function that is called when the nodeType XSD type is seen
229 int nodeType_function Returns 0 if no error occured or something else otherwise.
231 const char *_tag_ Set to the name of the element tag that triggered this function call.
233 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
235 const char *id The contents of the 'id' attribute (or NULL if not defined).
237 const char *lat The contents of the 'lat' attribute (or NULL if not defined).
239 const char *lon The contents of the 'lon' attribute (or NULL if not defined).
241 const char *timestamp The contents of the 'timestamp' attribute (or NULL if not defined).
243 const char *uid The contents of the 'uid' attribute (or NULL if not defined).
245 const char *user The contents of the 'user' attribute (or NULL if not defined).
247 const char *visible The contents of the 'visible' attribute (or NULL if not defined).
249 const char *version The contents of the 'version' attribute (or NULL if not defined).
251 const char *action The contents of the 'action' attribute (or NULL if not defined).
252 ++++++++++++++++++++++++++++++++++++++*/
254 static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action)
256 if(_type_&XMLPARSE_TAG_START)
261 fprintf(stderr,"\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
263 current_tags=NewTagList();
266 if(_type_&XMLPARSE_TAG_END)
268 TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
271 for(i=0;i<result->ntags;i++)
274 printf(" k=\"%s\"",ParseXML_Encode_Safe_XML(result->k[i]));
275 printf(" v=\"%s\"",ParseXML_Encode_Safe_XML(result->v[i]));
279 DeleteTagList(current_tags);
280 DeleteTagList(result);
283 printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
284 if(id) printf(" id=\"%s\"",ParseXML_Encode_Safe_XML(id));
285 if(lat) printf(" lat=\"%s\"",ParseXML_Encode_Safe_XML(lat));
286 if(lon) printf(" lon=\"%s\"",ParseXML_Encode_Safe_XML(lon));
287 if(timestamp) printf(" timestamp=\"%s\"",ParseXML_Encode_Safe_XML(timestamp));
288 if(uid) printf(" uid=\"%s\"",ParseXML_Encode_Safe_XML(uid));
289 if(user) printf(" user=\"%s\"",ParseXML_Encode_Safe_XML(user));
290 if(visible) printf(" visible=\"%s\"",ParseXML_Encode_Safe_XML(visible));
291 if(version) printf(" version=\"%s\"",ParseXML_Encode_Safe_XML(version));
292 if(action) printf(" action=\"%s\"",ParseXML_Encode_Safe_XML(action));
293 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
298 /*++++++++++++++++++++++++++++++++++++++
299 The function that is called when the ndType XSD type is seen
301 int ndType_function Returns 0 if no error occured or something else otherwise.
303 const char *_tag_ Set to the name of the element tag that triggered this function call.
305 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
307 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
308 ++++++++++++++++++++++++++++++++++++++*/
310 static int ndType_function(const char *_tag_,int _type_,const char *ref)
312 printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
313 if(ref) printf(" ref=\"%s\"",ParseXML_Encode_Safe_XML(ref));
314 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
319 /*++++++++++++++++++++++++++++++++++++++
320 The function that is called when the memberType XSD type is seen
322 int memberType_function Returns 0 if no error occured or something else otherwise.
324 const char *_tag_ Set to the name of the element tag that triggered this function call.
326 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
328 const char *type The contents of the 'type' attribute (or NULL if not defined).
330 const char *ref The contents of the 'ref' attribute (or NULL if not defined).
332 const char *role The contents of the 'role' attribute (or NULL if not defined).
333 ++++++++++++++++++++++++++++++++++++++*/
335 static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
337 printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
338 if(type) printf(" type=\"%s\"",ParseXML_Encode_Safe_XML(type));
339 if(ref) printf(" ref=\"%s\"",ParseXML_Encode_Safe_XML(ref));
340 if(role) printf(" role=\"%s\"",ParseXML_Encode_Safe_XML(role));
341 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
346 /*++++++++++++++++++++++++++++++++++++++
347 The function that is called when the wayType XSD type is seen
349 int wayType_function Returns 0 if no error occured or something else otherwise.
351 const char *_tag_ Set to the name of the element tag that triggered this function call.
353 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
355 const char *id The contents of the 'id' attribute (or NULL if not defined).
357 const char *timestamp The contents of the 'timestamp' attribute (or NULL if not defined).
359 const char *uid The contents of the 'uid' attribute (or NULL if not defined).
361 const char *user The contents of the 'user' attribute (or NULL if not defined).
363 const char *visible The contents of the 'visible' attribute (or NULL if not defined).
365 const char *version The contents of the 'version' attribute (or NULL if not defined).
367 const char *action The contents of the 'action' attribute (or NULL if not defined).
368 ++++++++++++++++++++++++++++++++++++++*/
370 static int wayType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action)
372 if(_type_&XMLPARSE_TAG_START)
377 fprintf(stderr,"\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
379 current_tags=NewTagList();
382 if(_type_&XMLPARSE_TAG_END)
384 TagList *result=ApplyTaggingRules(&WayRules,current_tags);
387 for(i=0;i<result->ntags;i++)
390 printf(" k=\"%s\"",ParseXML_Encode_Safe_XML(result->k[i]));
391 printf(" v=\"%s\"",ParseXML_Encode_Safe_XML(result->v[i]));
395 DeleteTagList(current_tags);
396 DeleteTagList(result);
399 printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
400 if(id) printf(" id=\"%s\"",ParseXML_Encode_Safe_XML(id));
401 if(timestamp) printf(" timestamp=\"%s\"",ParseXML_Encode_Safe_XML(timestamp));
402 if(uid) printf(" uid=\"%s\"",ParseXML_Encode_Safe_XML(uid));
403 if(user) printf(" user=\"%s\"",ParseXML_Encode_Safe_XML(user));
404 if(visible) printf(" visible=\"%s\"",ParseXML_Encode_Safe_XML(visible));
405 if(version) printf(" version=\"%s\"",ParseXML_Encode_Safe_XML(version));
406 if(action) printf(" action=\"%s\"",ParseXML_Encode_Safe_XML(action));
407 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
412 /*++++++++++++++++++++++++++++++++++++++
413 The function that is called when the relationType XSD type is seen
415 int relationType_function Returns 0 if no error occured or something else otherwise.
417 const char *_tag_ Set to the name of the element tag that triggered this function call.
419 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
421 const char *id The contents of the 'id' attribute (or NULL if not defined).
423 const char *timestamp The contents of the 'timestamp' attribute (or NULL if not defined).
425 const char *uid The contents of the 'uid' attribute (or NULL if not defined).
427 const char *user The contents of the 'user' attribute (or NULL if not defined).
429 const char *visible The contents of the 'visible' attribute (or NULL if not defined).
431 const char *version The contents of the 'version' attribute (or NULL if not defined).
433 const char *action The contents of the 'action' attribute (or NULL if not defined).
434 ++++++++++++++++++++++++++++++++++++++*/
436 static int relationType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action)
438 if(_type_&XMLPARSE_TAG_START)
442 if(!(nrelations%1000))
443 fprintf(stderr,"\rReading: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld",ParseXML_LineNumber(),nnodes,nways,nrelations);
445 current_tags=NewTagList();
448 if(_type_&XMLPARSE_TAG_END)
450 TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
453 for(i=0;i<result->ntags;i++)
456 printf(" k=\"%s\"",ParseXML_Encode_Safe_XML(result->k[i]));
457 printf(" v=\"%s\"",ParseXML_Encode_Safe_XML(result->v[i]));
461 DeleteTagList(current_tags);
462 DeleteTagList(result);
465 printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
466 if(id) printf(" id=\"%s\"",ParseXML_Encode_Safe_XML(id));
467 if(timestamp) printf(" timestamp=\"%s\"",ParseXML_Encode_Safe_XML(timestamp));
468 if(uid) printf(" uid=\"%s\"",ParseXML_Encode_Safe_XML(uid));
469 if(user) printf(" user=\"%s\"",ParseXML_Encode_Safe_XML(user));
470 if(visible) printf(" visible=\"%s\"",ParseXML_Encode_Safe_XML(visible));
471 if(version) printf(" version=\"%s\"",ParseXML_Encode_Safe_XML(version));
472 if(action) printf(" action=\"%s\"",ParseXML_Encode_Safe_XML(action));
473 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
478 /*++++++++++++++++++++++++++++++++++++++
479 The function that is called when the osmType XSD type is seen
481 int osmType_function Returns 0 if no error occured or something else otherwise.
483 const char *_tag_ Set to the name of the element tag that triggered this function call.
485 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
487 const char *version The contents of the 'version' attribute (or NULL if not defined).
489 const char *generator The contents of the 'generator' attribute (or NULL if not defined).
490 ++++++++++++++++++++++++++++++++++++++*/
492 static int osmType_function(const char *_tag_,int _type_,const char *version,const char *generator)
494 printf("<%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_);
495 if(version) printf(" version=\"%s\"",ParseXML_Encode_Safe_XML(version));
496 if(generator) printf(" generator=\"%s\"",ParseXML_Encode_Safe_XML(generator));
497 printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":"");
502 /*++++++++++++++++++++++++++++++++++++++
503 The function that is called when the XML declaration is seen
505 int xmlDeclaration_function Returns 0 if no error occured or something else otherwise.
507 const char *_tag_ Set to the name of the element tag that triggered this function call.
509 int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
511 const char *version The contents of the 'version' attribute (or NULL if not defined).
513 const char *encoding The contents of the 'encoding' attribute (or NULL if not defined).
514 ++++++++++++++++++++++++++++++++++++++*/
516 static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding)
518 printf("<?%s",_tag_);
519 if(version) printf(" version=\"%s\"",ParseXML_Encode_Safe_XML(version));
520 if(encoding) printf(" encoding=\"%s\"",ParseXML_Encode_Safe_XML(encoding));
526 /*++++++++++++++++++++++++++++++++++++++
527 The main program for the planetsplitter.
528 ++++++++++++++++++++++++++++++++++++++*/
530 int main(int argc,char **argv)
532 char *tagging=NULL,*filename=NULL;
536 /* Parse the command line arguments */
538 for(arg=1;arg<argc;arg++)
540 if(!strcmp(argv[arg],"--help"))
542 else if(!strncmp(argv[arg],"--tagging=",10))
543 tagging=&argv[arg][10];
544 else if(argv[arg][0]=='-' && argv[arg][1]=='-')
552 /* Check the specified command line options */
554 if(tagging && ExistsFile(tagging))
556 else if(!tagging && ExistsFile("tagging.xml"))
557 tagging="tagging.xml";
559 if(tagging && ParseXMLTaggingRules(tagging))
561 fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging);
567 fprintf(stderr,"Error: Cannot run without reading some tagging rules.\n");
573 file=fopen(filename,"rb");
577 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",argv[arg],strerror(errno));
586 fprintf(stderr,"\rReading: Lines=0 Nodes=0 Ways=0 Relations=0");
588 retval=ParseXML(file,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE);
590 fprintf(stderr,"\rRead: Lines=%ld Nodes=%ld Ways=%ld Relations=%ld \n",ParseXML_LineNumber(),nnodes,nways,nrelations);
601 /*++++++++++++++++++++++++++++++++++++++
602 Print out the usage information.
604 int detail The level of detail to use - 0 = low, 1 = high.
605 ++++++++++++++++++++++++++++++++++++++*/
607 static void print_usage(int detail)
610 "Usage: tagmodifier [--help]\n"
611 " [--tagging=<filename>]\n"
612 " [<filename.osm>]\n");
617 "--help Prints this information.\n"
619 "--tagging=<filename> The name of the XML file containing the tagging rules\n"
620 " (defaults to 'tagging.xml' in current directory).\n"
622 "<filename.osm> The name of the file to process (by default data is\n"
623 " read from standard input).\n");