Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /branches/destination-access/extras/find-fixme/osmparser.c
Parent Directory
|
Revision Log
Revision 2175 -
(show annotations)
(download)
(as text)
Wed Jul 19 17:50:40 2023 UTC (20 months, 3 weeks ago) by amb
File MIME type: text/x-csrc
File size: 10446 byte(s)
Wed Jul 19 17:50:40 2023 UTC (20 months, 3 weeks ago) by amb
File MIME type: text/x-csrc
File size: 10446 byte(s)
Merge from trunk (re-factor OSM parser functions).
1 | /*************************************** |
2 | OSM file parser (either JOSM or planet) |
3 | |
4 | Part of the Routino routing software. |
5 | ******************/ /****************** |
6 | This file Copyright 2008-2015, 2023 Andrew M. Bishop |
7 | |
8 | This program is free software: you can redistribute it and/or modify |
9 | it under the terms of the GNU Affero General Public License as published by |
10 | the Free Software Foundation, either version 3 of the License, or |
11 | (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU Affero General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU Affero General Public License |
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | ***************************************/ |
21 | |
22 | |
23 | #include <stdlib.h> |
24 | #include <string.h> |
25 | #include <stdint.h> |
26 | |
27 | #include "types.h" |
28 | #include "typesx.h" |
29 | |
30 | #include "nodesx.h" |
31 | #include "waysx.h" |
32 | #include "relationsx.h" |
33 | |
34 | #include "osmparser.h" |
35 | #include "tagging.h" |
36 | #include "logging.h" |
37 | |
38 | |
39 | /* Local parsing variables (re-initialised for each file) */ |
40 | |
41 | static NodesX *nodes; |
42 | static WaysX *ways; |
43 | static RelationsX *relations; |
44 | |
45 | static node_t *way_nodes; |
46 | static int way_nnodes; |
47 | |
48 | static node_t *relation_nodes; |
49 | static int relation_nnodes; |
50 | static way_t *relation_ways; |
51 | static int relation_nways; |
52 | static relation_t *relation_relations; |
53 | static int relation_nrelations; |
54 | |
55 | /* Local parsing functions */ |
56 | |
57 | static void ProcessNodeTags(TagList *tags,int64_t node_id,double latitude,double longitude,int mode); |
58 | static void ProcessWayTags(TagList *tags,int64_t way_id,int mode); |
59 | static void ProcessRelationTags(TagList *tags,int64_t relation_id,int mode); |
60 | |
61 | |
62 | /*++++++++++++++++++++++++++++++++++++++ |
63 | Initialise the OSM parser by initialising the local variables. |
64 | |
65 | NodesX *OSMNodes The data structure of nodes to fill in. |
66 | |
67 | WaysX *OSMWays The data structure of ways to fill in. |
68 | |
69 | RelationsX *OSMRelations The data structure of relations to fill in. |
70 | ++++++++++++++++++++++++++++++++++++++*/ |
71 | |
72 | void InitialiseParser(NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations) |
73 | { |
74 | /* Copy the function parameters and initialise the variables */ |
75 | |
76 | nodes=OSMNodes; |
77 | ways=OSMWays; |
78 | relations=OSMRelations; |
79 | |
80 | way_nodes=(node_t*)malloc(256*sizeof(node_t)); |
81 | |
82 | relation_nodes =(node_t *)malloc(256*sizeof(node_t)); |
83 | relation_ways =(way_t *)malloc(256*sizeof(way_t)); |
84 | relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); |
85 | } |
86 | |
87 | |
88 | /*++++++++++++++++++++++++++++++++++++++ |
89 | Clean up the memory after parsing. |
90 | ++++++++++++++++++++++++++++++++++++++*/ |
91 | |
92 | void CleanupParser(void) |
93 | { |
94 | /* Free the variables */ |
95 | |
96 | free(way_nodes); |
97 | |
98 | free(relation_nodes); |
99 | free(relation_ways); |
100 | free(relation_relations); |
101 | } |
102 | |
103 | |
104 | /*++++++++++++++++++++++++++++++++++++++ |
105 | Add node references to a way. |
106 | |
107 | int64_t node_id The node ID to add or zero to clear the list. |
108 | ++++++++++++++++++++++++++++++++++++++*/ |
109 | |
110 | void AddWayRefs(int64_t node_id) |
111 | { |
112 | if(node_id==0) |
113 | way_nnodes=0; |
114 | else |
115 | { |
116 | node_t id; |
117 | |
118 | if(way_nnodes && (way_nnodes%256)==0) |
119 | way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); |
120 | |
121 | id=(node_t)node_id; |
122 | 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. */ |
123 | |
124 | way_nodes[way_nnodes++]=id; |
125 | } |
126 | } |
127 | |
128 | |
129 | /*++++++++++++++++++++++++++++++++++++++ |
130 | Add node, way or relation references to a relation. |
131 | |
132 | int64_t node_id The node ID to add or zero if it is not a node. |
133 | |
134 | int64_t way_id The way ID to add or zero if it is not a way. |
135 | |
136 | int64_t relation_id The relation ID to add or zero if it is not a relation. |
137 | |
138 | const char *role The role played by this referenced item or NULL. |
139 | |
140 | If all of node_id, way_id and relation_id are zero then the list is cleared. |
141 | ++++++++++++++++++++++++++++++++++++++*/ |
142 | |
143 | void AddRelationRefs(int64_t node_id,int64_t way_id,int64_t relation_id,const char *role) |
144 | { |
145 | if(node_id==0 && way_id==0 && relation_id==0) |
146 | { |
147 | relation_nnodes=0; |
148 | relation_nways=0; |
149 | relation_nrelations=0; |
150 | } |
151 | else if(node_id!=0) |
152 | { |
153 | node_t id; |
154 | |
155 | id=(node_t)node_id; |
156 | 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. */ |
157 | |
158 | if(relation_nnodes && (relation_nnodes%256)==0) |
159 | relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t)); |
160 | |
161 | relation_nodes[relation_nnodes++]=id; |
162 | } |
163 | else if(way_id!=0) |
164 | { |
165 | way_t id; |
166 | |
167 | id=(way_t)way_id; |
168 | 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. */ |
169 | |
170 | if(relation_nways && (relation_nways%256)==0) |
171 | relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t)); |
172 | |
173 | relation_ways[relation_nways++]=id; |
174 | } |
175 | else /* if(relation_id!=0) */ |
176 | { |
177 | relation_t id; |
178 | |
179 | id=(relation_t)relation_id; |
180 | 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. */ |
181 | |
182 | if(relation_nrelations && (relation_nrelations%256)==0) |
183 | relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t)); |
184 | |
185 | relation_relations[relation_nrelations++]=relation_id; |
186 | } |
187 | } |
188 | |
189 | |
190 | /*++++++++++++++++++++++++++++++++++++++ |
191 | Add a node after processing the tags associated with it. |
192 | |
193 | int64_t node_id The id of the node. |
194 | |
195 | double latitude The latitude of the node. |
196 | |
197 | double longitude The longitude of the node. |
198 | |
199 | int mode The mode of operation to take (create, modify, delete). |
200 | |
201 | TagList *raw_tags The accumulated set of tags for the node. |
202 | ++++++++++++++++++++++++++++++++++++++*/ |
203 | |
204 | void AddNode(int64_t node_id,double latitude,double longitude,int mode,TagList *raw_tags) |
205 | { |
206 | TagList *processed_tags=ApplyNodeTaggingRules(raw_tags,node_id); |
207 | |
208 | ProcessNodeTags(processed_tags,node_id,latitude,longitude,mode); |
209 | |
210 | DeleteTagList(raw_tags); |
211 | DeleteTagList(processed_tags); |
212 | } |
213 | |
214 | |
215 | /*++++++++++++++++++++++++++++++++++++++ |
216 | Add a way after processing the tags associated with it. |
217 | |
218 | int64_t way_id The id of the way. |
219 | |
220 | int mode The mode of operation to take (create, modify, delete). |
221 | |
222 | TagList *raw_tags The accumulated set of tags for the node. |
223 | ++++++++++++++++++++++++++++++++++++++*/ |
224 | |
225 | void AddWay(int64_t way_id,int mode,TagList *raw_tags) |
226 | { |
227 | TagList *processed_tags=ApplyWayTaggingRules(raw_tags,way_id); |
228 | |
229 | ProcessWayTags(processed_tags,way_id,mode); |
230 | |
231 | DeleteTagList(raw_tags); |
232 | DeleteTagList(processed_tags); |
233 | } |
234 | |
235 | |
236 | /*++++++++++++++++++++++++++++++++++++++ |
237 | Add a relation after processing the tags associated with it. |
238 | |
239 | int64_t relation_id The id of the relation. |
240 | |
241 | int mode The mode of operation to take (create, modify, delete). |
242 | |
243 | TagList *raw_tags The accumulated set of tags for the node. |
244 | ++++++++++++++++++++++++++++++++++++++*/ |
245 | |
246 | void AddRelation(int64_t relation_id,int mode,TagList *raw_tags) |
247 | { |
248 | TagList *processed_tags=ApplyRelationTaggingRules(raw_tags,relation_id); |
249 | |
250 | ProcessRelationTags(processed_tags,relation_id,mode); |
251 | |
252 | DeleteTagList(raw_tags); |
253 | DeleteTagList(processed_tags); |
254 | } |
255 | |
256 | |
257 | /*++++++++++++++++++++++++++++++++++++++ |
258 | Process the tags associated with a node. |
259 | |
260 | TagList *tags The list of node tags. |
261 | |
262 | int64_t node_id The id of the node. |
263 | |
264 | double latitude The latitude of the node. |
265 | |
266 | double longitude The longitude of the node. |
267 | |
268 | int mode The mode of operation to take (create, modify, delete). |
269 | ++++++++++++++++++++++++++++++++++++++*/ |
270 | |
271 | static void ProcessNodeTags(TagList *tags,int64_t node_id,double latitude,double longitude,int mode) |
272 | { |
273 | node_t id; |
274 | int i; |
275 | |
276 | /* Convert id */ |
277 | |
278 | id=(node_t)node_id; |
279 | 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. */ |
280 | |
281 | /* Parse the tags */ |
282 | |
283 | for(i=0;i<tags->ntags;i++) |
284 | { |
285 | char *k=tags->k[i]; |
286 | |
287 | if(!strcmp(k,"fixme-finder:keep")) |
288 | { |
289 | DeleteTag(tags,"fixme-finder:keep"); |
290 | logerror("<node id='%"Pnode_t"'>%s</node>\n",logerror_node(id),StringifyTag(tags)); |
291 | } |
292 | } |
293 | |
294 | /* Store the node */ |
295 | |
296 | AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),0,0,0); |
297 | } |
298 | |
299 | |
300 | /*++++++++++++++++++++++++++++++++++++++ |
301 | Process the tags associated with a way. |
302 | |
303 | TagList *tags The list of way tags. |
304 | |
305 | int64_t way_id The id of the way. |
306 | |
307 | int mode The mode of operation to take (create, modify, delete). |
308 | ++++++++++++++++++++++++++++++++++++++*/ |
309 | |
310 | static void ProcessWayTags(TagList *tags,int64_t way_id,int mode) |
311 | { |
312 | Way way={0}; |
313 | way_t id; |
314 | int i; |
315 | |
316 | /* Convert id */ |
317 | |
318 | id=(way_t)way_id; |
319 | 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. */ |
320 | |
321 | /* Parse the tags */ |
322 | |
323 | for(i=0;i<tags->ntags;i++) |
324 | { |
325 | char *k=tags->k[i]; |
326 | |
327 | if(!strcmp(k,"fixme-finder:keep")) |
328 | { |
329 | DeleteTag(tags,"fixme-finder:keep"); |
330 | logerror("<way id='%"Pway_t"'>%s</way>\n",logerror_way(id),StringifyTag(tags)); |
331 | } |
332 | } |
333 | |
334 | /* Store the way */ |
335 | |
336 | AppendWayList(ways,id,&way,way_nodes,way_nnodes,""); |
337 | } |
338 | |
339 | |
340 | /*++++++++++++++++++++++++++++++++++++++ |
341 | Process the tags associated with a relation. |
342 | |
343 | TagList *tags The list of relation tags. |
344 | |
345 | int64_t relation_id The id of the relation. |
346 | |
347 | int mode The mode of operation to take (create, modify, delete). |
348 | ++++++++++++++++++++++++++++++++++++++*/ |
349 | |
350 | static void ProcessRelationTags(TagList *tags,int64_t relation_id,int mode) |
351 | { |
352 | relation_t id; |
353 | int i; |
354 | |
355 | /* Convert id */ |
356 | |
357 | id=(relation_t)relation_id; |
358 | 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. */ |
359 | |
360 | /* Parse the tags */ |
361 | |
362 | for(i=0;i<tags->ntags;i++) |
363 | { |
364 | char *k=tags->k[i]; |
365 | |
366 | if(!strcmp(k,"fixme-finder:keep")) |
367 | { |
368 | DeleteTag(tags,"fixme-finder:keep"); |
369 | logerror("<relation id='%"Prelation_t"'>%s</relation>\n",logerror_relation(id),StringifyTag(tags)); |
370 | } |
371 | } |
372 | |
373 | /* Store the relation */ |
374 | |
375 | AppendRouteRelationList(relations,id,0, |
376 | relation_nodes,relation_nnodes, |
377 | relation_ways,relation_nways, |
378 | relation_relations,relation_nrelations); |
379 | } |