/[zanavi_public1]/navit/navit/maptool/osm_protobuf.c
ZANavi

Contents of /navit/navit/maptool/osm_protobuf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations) (download)
Fri Oct 28 21:39:42 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 9543 byte(s)
import
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2011 Navit Team
4 *
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.
8 *
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.
13 *
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.
18 */
19 #include <string.h>
20 #include <stdlib.h>
21 #include <math.h>
22 #include <unistd.h>
23 #include <time.h>
24 #include <zlib.h>
25 #include "maptool.h"
26 #include "debug.h"
27 #include "linguistics.h"
28 #include "file.h"
29 #include "generated-code/fileformat.pb-c.h"
30 #include "generated-code/osmformat.pb-c.h"
31
32
33 static double latlon_scale=10000000.0;
34
35 static OSMPBF__BlobHeader *
36 read_header(FILE *f)
37 {
38 unsigned char *buffer,lenb[4];
39 int len;
40
41 len=sizeof(lenb);
42 if (fread(lenb, 4, 1, f) != 1)
43 return NULL;
44 len=(lenb[0] << 24) | (lenb[1] << 16) | (lenb[2] << 8) | lenb[3];
45 buffer=alloca(len);
46 if (fread(buffer, len, 1, f) != 1)
47 return NULL;
48 return osmpbf__blob_header__unpack(&protobuf_c_system_allocator, len, buffer);
49 }
50
51
52 static OSMPBF__Blob *
53 read_blob(OSMPBF__BlobHeader *header, FILE *f)
54 {
55 unsigned char *buffer;
56 int len=header->datasize;
57
58 buffer=alloca(len);
59 if (fread(buffer, len, 1, f) != 1)
60 return NULL;
61 return osmpbf__blob__unpack(&protobuf_c_system_allocator, len, buffer);
62 }
63
64 static unsigned char *
65 uncompress_blob(OSMPBF__Blob *blob)
66 {
67 unsigned char *ret=malloc(blob->raw_size);
68 int zerr;
69 z_stream strm;
70
71 if (!ret)
72 return NULL;
73 strm.zalloc = Z_NULL;
74 strm.zfree = Z_NULL;
75 strm.opaque = Z_NULL;
76 strm.avail_in=blob->zlib_data.len;
77 strm.next_in=blob->zlib_data.data;
78 strm.avail_out=blob->raw_size;
79 strm.next_out=ret;
80 zerr = inflateInit(&strm);
81 if (zerr != Z_OK) {
82 free(ret);
83 return NULL;
84 }
85 zerr = inflate(&strm, Z_NO_FLUSH);
86 if (zerr != Z_STREAM_END) {
87 free(ret);
88 return NULL;
89 }
90 inflateEnd(&strm);
91 return ret;
92 }
93
94 static int
95 get_string(char *buffer, int buffer_size, OSMPBF__PrimitiveBlock *primitive_block, int id, int escape)
96 {
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) {
100 buffer[0]='\0';
101 return 0;
102 }
103 if (escape) {
104 int i;
105 char *p=buffer;
106 for (i = 0 ; i < len ; i++) {
107 switch(data[i]) {
108 case '\t':
109 case '\r':
110 case '\n':
111 case '>':
112 case '<':
113 case '\'':
114 case '"':
115 case '&':
116 sprintf(p,"&#%d;",data[i]);
117 p+=strlen(p);
118 break;
119 default:
120 *p++=data[i];
121 }
122 }
123 *p++='\0';
124 return 1;
125 } else {
126 strncpy(buffer, data, len);
127 buffer[len]='\0';
128 return 1;
129 }
130 }
131
132
133 static void
134 process_osmheader(OSMPBF__Blob *blob, unsigned char *data)
135 {
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);
139 }
140
141 #if 0
142
143 static void
144 process_user(OSMPBF__PrimitiveBlock *primitive_block, int user_sid, int uid, int swap)
145 {
146 char userbuff[1024];
147 get_string(userbuff, sizeof(userbuff), primitive_block, user_sid, 1);
148 if (userbuff[0] && uid != -1) {
149 if (swap)
150 printf(" uid=\"%d\" user=\"%s\"",uid,userbuff);
151 else
152 printf(" user=\"%s\" uid=\"%d\"",userbuff,uid);
153 }
154 }
155
156 static void
157 process_timestamp(long long timestamp)
158 {
159 time_t ts;
160 struct tm *tm;
161 char tsbuff[1024];
162 ts=timestamp;
163 tm=gmtime(&ts);
164 strftime(tsbuff, sizeof(tsbuff), "%Y-%m-%dT%H:%M:%SZ", tm);
165 printf(" timestamp=\"%s\"",tsbuff);
166 }
167
168 #endif
169
170 static void
171 process_tag(OSMPBF__PrimitiveBlock *primitive_block, int key, int val)
172 {
173 char keybuff[1024];
174 char valbuff[1024];
175 #if 0
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);
179 #else
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);
183 #endif
184 }
185
186
187 static void
188 process_dense(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__DenseNodes *dense, FILE *out_nodes)
189 {
190 int i,j=0,has_tags;
191 long long id=0,lat=0,lon=0,changeset=0,timestamp=0;
192 int version,user_sid=0,uid=0;
193
194 if (!dense)
195 return;
196
197 for (i = 0 ; i < dense->n_id ; i++) {
198 id+=dense->id[i];
199 lat+=dense->lat[i];
200 lon+=dense->lon[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);
208 #if 0
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);
212 #endif
213 if (has_tags) {
214 #if 0
215 printf(">\n");
216 #endif
217 while (dense->keys_vals[j]) {
218 process_tag(primitive_block, dense->keys_vals[j], dense->keys_vals[j+1]);
219 j+=2;
220 }
221 #if 0
222 printf("\t</node>\n");
223 } else
224 printf("/>\n");
225 #else
226 }
227 #endif
228 osm_end_node(out_nodes);
229 j++;
230 }
231 }
232
233 #if 0
234 static void
235 process_info(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__Info *info)
236 {
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);
240 }
241 #endif
242
243 static void
244 process_way(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__Way *way, FILE *out_ways)
245 {
246 int i;
247 long long ref=0;
248
249 osm_add_way(way->id);
250 #if 0
251 printf("\t<way id=\"%Ld\"",way->id);
252 process_info(primitive_block, way->info);
253 printf(">\n");
254 #else
255 #endif
256 for (i = 0 ; i < way->n_refs ; i++) {
257 ref+=way->refs[i];
258 osm_add_nd(ref);
259 #if 0
260 printf("\t\t<nd ref=\"%Ld\"/>\n",ref);
261 #else
262 #endif
263 }
264 for (i = 0 ; i < way->n_keys ; i++)
265 process_tag(primitive_block, way->keys[i], way->vals[i]);
266 #if 0
267 printf("\t</way>\n");
268 #endif
269 osm_end_way(out_ways);
270 }
271
272 static void
273 process_relation(OSMPBF__PrimitiveBlock *primitive_block, OSMPBF__Relation *relation, FILE *out_turn_restrictions, FILE *out_boundaries)
274 {
275 int i;
276 long long ref=0;
277 char rolebuff[1024];
278
279 #if 0
280 printf("\t<relation id=\"%Ld\"",relation->id);
281 process_info(primitive_block, relation->info);
282 printf(">\n");
283 #endif
284 osm_add_relation(relation->id);
285 for (i = 0 ; i < relation->n_roles_sid ; i++) {
286 #if 0
287 printf("\t\t<member type=\"");
288 switch (relation->types[i]) {
289 case 0:
290 printf("node");
291 break;
292 case 1:
293 printf("way");
294 break;
295 case 2:
296 printf("relation");
297 break;
298 default:
299 printf("unknown");
300 break;
301 }
302 #endif
303 ref+=relation->memids[i];
304 get_string(rolebuff, sizeof(rolebuff), primitive_block, relation->roles_sid[i], 1);
305 #if 0
306 printf("\" ref=\"%Ld\" role=\"%s\"/>\n",ref,rolebuff);
307 #else
308 osm_add_member(relation->types[i]+1,ref,rolebuff);
309 #endif
310 }
311 for (i = 0 ; i < relation->n_keys ; i++)
312 process_tag(primitive_block, relation->keys[i], relation->vals[i]);
313 #if 0
314 printf("\t</relation>\n");
315 #else
316 osm_end_relation(out_turn_restrictions, out_boundaries);
317 #endif
318 }
319
320 static void
321 process_osmdata(OSMPBF__Blob *blob, unsigned char *data, FILE *out_nodes, FILE *out_ways, FILE *out_turn_restrictions, FILE *out_boundaries)
322 {
323 int i,j;
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, out_nodes);
329 for (j = 0 ; j < primitive_group->n_ways ; j++)
330 process_way(primitive_block, primitive_group->ways[j], out_ways);
331 for (j = 0 ; j < primitive_group->n_relations ; j++)
332 process_relation(primitive_block, primitive_group->relations[j], out_turn_restrictions, out_boundaries);
333 #if 0
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);
335 #endif
336 }
337 osmpbf__primitive_block__free_unpacked(primitive_block, &protobuf_c_system_allocator);
338 }
339
340
341 int
342 map_collect_data_osm_protobuf(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions, FILE *out_boundaries)
343 {
344 OSMPBF__BlobHeader *header;
345 OSMPBF__Blob *blob;
346 unsigned char *data;
347 #if 0
348 printf("<?xml version='1.0' encoding='UTF-8'?>\n");
349 printf("<osm version=\"0.6\" generator=\"pbf2osm\">\n");
350 #endif
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, out_nodes, out_ways, out_turn_restrictions, out_boundaries);
358 } else {
359 printf("unknown\n");
360 return 0;
361 }
362 free(data);
363 osmpbf__blob__free_unpacked(blob, &protobuf_c_system_allocator);
364 osmpbf__blob_header__free_unpacked(header, &protobuf_c_system_allocator);
365 }
366 #if 0
367 printf("</osm>\n");
368 #endif
369 return 1;
370 }

   
Visit the ZANavi Wiki