2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2011 Navit Team
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
27 #include "linguistics.h"
29 #include "generated-code/fileformat.pb-c.h"
30 #include "generated-code/osmformat.pb-c.h"
33 static double latlon_scale=10000000.0;
35 static OSMPBF__BlobHeader *
38 unsigned char *buffer,lenb[4];
42 if (fread(lenb, 4, 1, f) != 1)
44 len=(lenb[0] << 24) | (lenb[1] << 16) | (lenb[2] << 8) | lenb[3];
46 if (fread(buffer, len, 1, f) != 1)
48 return osmpbf__blob_header__unpack(&protobuf_c_system_allocator, len, buffer);
53 read_blob(OSMPBF__BlobHeader *header, FILE *f)
55 unsigned char *buffer;
56 int len=header->datasize;
59 if (fread(buffer, len, 1, f) != 1)
61 return osmpbf__blob__unpack(&protobuf_c_system_allocator, len, buffer);
64 static unsigned char *
65 uncompress_blob(OSMPBF__Blob *blob)
67 unsigned char *ret=malloc(blob->raw_size);
76 strm.avail_in=blob->zlib_data.len;
77 strm.next_in=blob->zlib_data.data;
78 strm.avail_out=blob->raw_size;
80 zerr = inflateInit(&strm);
85 zerr = inflate(&strm, Z_NO_FLUSH);
86 if (zerr != Z_STREAM_END) {
95 get_string(char *buffer, int buffer_size, OSMPBF__PrimitiveBlock *primitive_block, int id, int escape)
97 int len=primitive_block->stringtable->s[id].len;
98 char *data=(char *)primitive_block->stringtable->s[id].data;
99 if (primitive_block->stringtable->s[id].len >= buffer_size) {
106 for (i = 0 ; i < len ; i++) {
116 sprintf(p,"&#%d;",data[i]);
126 strncpy(buffer, data, len);
134 process_osmheader(OSMPBF__Blob *blob, unsigned char *data)
136 OSMPBF__HeaderBlock *header_block;
137 header_block=osmpbf__header_block__unpack(&protobuf_c_system_allocator, blob->raw_size, data);
138 osmpbf__header_block__free_unpacked(header_block, &protobuf_c_system_allocator);
144 process_user(OSMPBF__PrimitiveBlock *primitive_block, int user_sid, int uid, int swap)
147 get_string(userbuff, sizeof(userbuff), primitive_block, user_sid, 1);
148 if (userbuff[0] && uid != -1) {
150 printf(" uid=\"%d\" user=\"%s\"",uid,userbuff);
152 printf(" user=\"%s\" uid=\"%d\"",userbuff,uid);
157 process_timestamp(long long timestamp)
164 strftime(tsbuff, sizeof(tsbuff), "%Y-%m-%dT%H:%M:%SZ", tm);
165 printf(" timestamp=\"%s\"",tsbuff);
171 process_tag(OSMPBF__PrimitiveBlock *primitive_block, int key, int val)
176 get_string(keybuff, sizeof(keybuff), primitive_block, key, 1);
177 get_string(valbuff, sizeof(valbuff), primitive_block, val, 1);
178 printf("\t\t<tag k=\"%s\" v=\"%s\" />\n",keybuff,valbuff);
180 get_string(keybuff, sizeof(keybuff), primitive_block, key, 0);
181 get_string(valbuff, sizeof(valbuff), primitive_block, val, 0);
182 osm_add_tag(keybuff, valbuff);
188 process_dense(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__DenseNodes *dense, struct maptool_osm *osm)
191 long long id=0,lat=0,lon=0,changeset=0,timestamp=0;
192 int version,user_sid=0,uid=0;
197 for (i = 0 ; i < dense->n_id ; i++) {
201 version=dense->denseinfo->version[i];
202 changeset+=dense->denseinfo->changeset[i];
203 user_sid+=dense->denseinfo->user_sid[i];
204 uid+=dense->denseinfo->uid[i];
205 timestamp+=dense->denseinfo->timestamp[i];
206 has_tags=dense->keys_vals && dense->keys_vals[j];
207 osm_add_node(id, lat/latlon_scale,lon/latlon_scale);
209 printf("\t<node id=\"%Ld\" lat=\"%.7f\" lon=\"%.7f\" version=\"%d\" changeset=\"%Ld\"",id,lat/latlon_scale,lon/latlon_scale,version,changeset);
210 process_user(primitive_block, user_sid, uid, 0);
211 process_timestamp(timestamp);
217 while (dense->keys_vals[j]) {
218 process_tag(primitive_block, dense->keys_vals[j], dense->keys_vals[j+1]);
222 printf("\t</node>\n");
235 process_info(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__Info *info)
237 printf(" version=\"%d\" changeset=\"%Ld\"",info->version,info->changeset);
238 process_user(primitive_block, info->user_sid, info->uid, 1);
239 process_timestamp(info->timestamp);
244 process_way(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__Way *way, struct maptool_osm *osm)
249 osm_add_way(way->id);
251 printf("\t<way id=\"%Ld\"",way->id);
252 process_info(primitive_block, way->info);
256 for (i = 0 ; i < way->n_refs ; i++) {
260 printf("\t\t<nd ref=\"%Ld\"/>\n",ref);
264 for (i = 0 ; i < way->n_keys ; i++)
265 process_tag(primitive_block, way->keys[i], way->vals[i]);
267 printf("\t</way>\n");
273 process_relation(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__Relation *relation, struct maptool_osm *osm)
280 printf("\t<relation id=\"%Ld\"",relation->id);
281 process_info(primitive_block, relation->info);
284 osm_add_relation(relation->id);
285 for (i = 0 ; i < relation->n_roles_sid ; i++) {
287 printf("\t\t<member type=\"");
288 switch (relation->types[i]) {
303 ref+=relation->memids[i];
304 get_string(rolebuff, sizeof(rolebuff), primitive_block, relation->roles_sid[i], 1);
306 printf("\" ref=\"%Ld\" role=\"%s\"/>\n",ref,rolebuff);
308 osm_add_member(relation->types[i]+1,ref,rolebuff);
311 for (i = 0 ; i < relation->n_keys ; i++)
312 process_tag(primitive_block, relation->keys[i], relation->vals[i]);
314 printf("\t</relation>\n");
316 osm_end_relation(osm);
321 process_osmdata(OSMPBF__Blob *blob, unsigned char *data, struct maptool_osm *osm)
324 OSMPBF__PrimitiveBlock *primitive_block;
325 primitive_block=osmpbf__primitive_block__unpack(&protobuf_c_system_allocator, blob->raw_size, data);
326 for (i = 0 ; i < primitive_block->n_primitivegroup ; i++) {
327 OSMPBF__PrimitiveGroup *primitive_group=primitive_block->primitivegroup[i];
328 process_dense(primitive_block, primitive_group->dense, osm);
329 for (j = 0 ; j < primitive_group->n_ways ; j++)
330 process_way(primitive_block, primitive_group->ways[j], osm);
331 for (j = 0 ; j < primitive_group->n_relations ; j++)
332 process_relation(primitive_block, primitive_group->relations[j], osm);
334 printf("Group %p %d %d %d %d\n",primitive_group->dense,primitive_group->n_nodes,primitive_group->n_ways,primitive_group->n_relations,primitive_group->n_changesets);
337 osmpbf__primitive_block__free_unpacked(primitive_block, &protobuf_c_system_allocator);
342 map_collect_data_osm_protobuf(FILE *in, struct maptool_osm *osm)
344 OSMPBF__BlobHeader *header;
348 printf("<?xml version='1.0' encoding='UTF-8'?>\n");
349 printf("<osm version=\"0.6\" generator=\"pbf2osm\">\n");
351 while ((header=read_header(in))) {
352 blob=read_blob(header, in);
353 data=uncompress_blob(blob);
354 if (!strcmp(header->type,"OSMHeader")) {
355 process_osmheader(blob, data);
356 } else if (!strcmp(header->type,"OSMData")) {
357 process_osmdata(blob, data, osm);
363 osmpbf__blob__free_unpacked(blob, &protobuf_c_system_allocator);
364 osmpbf__blob_header__free_unpacked(header, &protobuf_c_system_allocator);