/[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 - (hide annotations) (download)
Fri Oct 28 21:39:42 2011 UTC (9 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 9543 byte(s)
import
1 zoff99 8 /**
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