12 #include "osmbinary.h"
17 * <tag k=".." v=".." />
29 static void parser(char *range
, unsigned long int max
) {
30 typedef enum { OSM
= 0, NODE
= 1, WAY
= 2, RELATION
= 3, TAG
= 4, ND
= 5, MEMBER
= 6 } osm_state_t
;
31 typedef enum { UNKNOWN
= 0, ID
, LAT
, LON
, USER
, TIMESTAMP
, KEY
, VALUE
, TYPE
, REF
, ROLE
} key_state_t
;
32 char *attr_id
= NULL
, *attr_lat
= NULL
, *attr_lon
= NULL
, *attr_user
= NULL
, *attr_timestamp
= NULL
, *attr_key
= NULL
, *attr_value
= NULL
,
33 *attr_type
= NULL
, *attr_ref
= NULL
, *attr_role
= NULL
;
35 // unsigned long int count_nodes = 0, count_node_tags = 0,
36 // count_ways = 0, count_way_tags = 0, count_way_nds = 0,
37 // count_relations = 0, count_relation_tags = 0, count_members_node = 0, count_members_relation = 0, count_members_way = 0;
39 // unsigned long int sequence = 0;
50 bi
= open("osm.bin", O_WRONLY
| O_CREAT
, S_IRUSR
| S_IWUSR
|S_IRGRP
|S_IROTH
);
52 osm_state_t current_tag
= OSM
;
53 osm_state_t parent_tag
= OSM
;
55 char *start
, *end
, *nodename
, *nodename_end
;
58 end
= strchrnul((const char*) start
, '\n');
60 if (strncmp(start
, "<?xml", 5) != 0)
64 end
= strchrnul((const char*) start
, '\n');
66 if (strncmp(start
, "<osm", 4) != 0)
72 end
= strchrnul((const char*) start
, '\n');
74 nodename
= strchrnul(start
, '<') + 1;
75 nodename_end
= strchrnul(nodename
, ' ');
77 if (nodename
[0] == '/') {
88 attr_timestamp
= NULL
;
96 switch (nodename_end
- nodename
) {
101 switch (nodename
[0]) {
112 fprintf(stderr
, "--> %c%c", nodename
[0], nodename
[1]);
120 current_tag
= MEMBER
;
123 current_tag
= RELATION
;
126 fprintf(stderr
, "--> %c%c", nodename
[0], nodename
[1]);
130 char *key
, *key_end
, *value_end
;
131 key
= nodename_end
+ 1;
135 key_state_t current_key
= UNKNOWN
;
136 key_end
= strchrnul(key
, '=');
138 if (key_end
== NULL
|| key_end
>= end
)
141 switch (key_end
- key
) {
151 current_key
= UNKNOWN
;
170 current_key
= UNKNOWN
;
171 fprintf(stderr
, "--> %c%c\n", key
[0], key
[1]);
187 current_key
= UNKNOWN
;
188 fprintf(stderr
, "--> %c%c\n", key
[0], key
[1]);
193 current_key
= TIMESTAMP
;
196 char *thingie
= strndup(key
, (key_end
- key
));
197 current_key
= UNKNOWN
;
199 fprintf(stderr
, "UNKNOWN ATTR %s-> %c%c\n", thingie
, key
[0], key
[1]);
206 value_end
= strchr(value_end
, '"');
211 switch (current_key
) {
213 if (attr_id
) free(attr_id
);
214 attr_id
= strndup(value
, (value_end
- value
));
218 if (attr_lat
) free(attr_lat
);
219 attr_lat
= strndup(value
, (value_end
- value
));
223 if (attr_lon
) free(attr_lon
);
224 attr_lon
= strndup(value
, (value_end
- value
));
228 if (attr_timestamp
) free(attr_timestamp
);
229 attr_timestamp
= strndup(value
, (value_end
- value
));
230 // attr_timestamp[10] = ' '; /* Stupid timestamp fix */
235 if (attr_user
) free(attr_user
);
236 attr_user
= strndup(value
, (value_end
- value
));
237 // tmp = escape_string(attr_user);
245 if (attr_key
) free(attr_key
);
246 attr_key
= strndup(value
, (value_end
- value
));
247 // tmp = escape_string(attr_key);
255 if (attr_value
) free(attr_value
);
256 attr_value
= strndup(value
, (value_end
- value
));
257 // tmp = escape_string(attr_value);
264 if (attr_type
) free(attr_type
);
265 attr_type
= strndup(value
, (value_end
- value
));
269 if (attr_ref
) free(attr_ref
);
270 attr_ref
= strndup(value
, (value_end
- value
));
275 if (attr_role
) free(attr_role
);
276 attr_role
= strndup(value
, (value_end
- value
));
277 // tmp = escape_string(attr_role);
284 fprintf(stderr
, "--> %c%c\n", value
[0], value
[1]);
290 switch (current_tag
) {
292 bin_node
.id
= strtoul(attr_id
, (char **) NULL
, 10);
293 bin_node
.lon
= strtof(attr_lon
, (char **) NULL
);
294 bin_node
.lat
= strtof(attr_lat
, (char **) NULL
);
296 bin_node
.userlen
= 0;
297 bin_node
.user
= NULL
;
299 bin_node
.userlen
= strlen(attr_user
);
300 bin_node
.user
= attr_user
;
302 strptime(attr_timestamp
, "%FT%T%Z", &bin_tmp
);
303 bin_node
.stamp
= mktime(&bin_tmp
);
304 writenode(bi
, &bin_node
);
305 // fprintf(fd_nodes, "%s, %s, %s, '%s', %s\n", attr_id, attr_lat, attr_lon, attr_user, attr_timestamp);
309 bin_tag
.klen
= strlen(attr_key
);
310 bin_tag
.k
= attr_key
;
311 bin_tag
.vlen
= strlen(attr_value
);
312 bin_tag
.v
= attr_value
;
313 writetag(bi
, &bin_tag
);
315 /* switch (parent_tag) {
317 fprintf(fd_node_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
321 fprintf(fd_way_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
325 fprintf(fd_relation_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
326 count_relation_tags++;
334 bin_other
.id
= strtoul(attr_id
, (char **) NULL
, 10);
336 bin_other
.userlen
= 0;
337 bin_other
.user
= NULL
;
339 bin_other
.userlen
= strlen(attr_user
);
340 bin_other
.user
= attr_user
;
342 strptime(attr_timestamp
, "%FT%T%Z", &bin_tmp
);
343 bin_other
.stamp
= mktime(&bin_tmp
);
344 writeother(bi
, &bin_other
, 'W');
346 // fprintf(fd_ways, "%s, '%s', '%s'\n", attr_id, attr_user, attr_timestamp);
348 // fprintf(fd_way_tags, "%s, '%s', '%s'\n", attr_id, "type", "way");
352 bin_other
.id
= strtoul(attr_id
, (char **) NULL
, 10);
354 bin_other
.userlen
= 0;
355 bin_other
.user
= NULL
;
357 bin_other
.userlen
= strlen(attr_user
);
358 bin_other
.user
= attr_user
;
360 strptime(attr_timestamp
, "%FT%T%Z", &bin_tmp
);
361 bin_other
.stamp
= mktime(&bin_tmp
);
362 writeother(bi
, &bin_other
, 'R');
364 // fprintf(fd_relations, "%s, '%s', '%s'\n", attr_id, attr_user, attr_timestamp);
365 // count_relations++;
368 bin_member
.type
= attr_type
;
369 bin_member
.typelen
= strlen(attr_type
);
370 bin_member
.ref
= attr_ref
;
371 bin_member
.reflen
= strlen(attr_ref
);
372 bin_member
.role
= attr_role
;
373 bin_member
.rolelen
= strlen(attr_role
);
374 writemember(bi
, &bin_member
);
376 /* if (strcmp(attr_type, "node") == 0) {
377 fprintf(fd_members_node, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
378 count_members_node++;
379 } else if (strcmp(attr_type, "way") == 0) {
380 fprintf(fd_members_way, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
382 } else if (strcmp(attr_type, "relation") == 0) {
383 fprintf(fd_members_relation, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
384 count_members_relation++;
389 bin_nd
.id
= strtoul(attr_id
, (char **) NULL
, 10);
390 writend(bi
, &bin_nd
);
391 /* fprintf(fd_way_nds, "%s, %lu, %s\n", attr_id, sequence, attr_ref);
399 if (end
[-2] == '/') {
400 switch (current_tag
) {
411 free(attr_timestamp
);
416 attr_timestamp
= NULL
;
441 } else if (current_tag
== NODE
|| current_tag
== WAY
|| current_tag
== RELATION
) {
442 parent_tag
= current_tag
;
445 } while ((start
= ++end
) < (range
+ max
));
450 free(attr_timestamp
);
460 int main(int argc
, char *argv
[]) {
467 fprintf(stderr
, "Analysing %s...\n", argv
[1]);
469 fd
= open(argv
[1], O_RDONLY
);
474 if (fstat (fd
, &statbuf
) == -1) { perror("fstat:"); exit(-1); }
476 if (statbuf
.st_size
> 0) {
478 range
= mmap(NULL
, statbuf
.st_size
, PROT_READ
, MAP_SHARED
, fd
, (off_t
) 0);
479 if (range
== MAP_FAILED
) { perror("Mmap:"); printf("(did you compile PAE in the kernel?)\n"); exit(-1); }
480 parser(range
, statbuf
.st_size
/ sizeof(char));
481 munmap(range
, statbuf
.st_size
);