static void process_osmheader(OSMPBF__Blob *blob, unsigned char *data) { OSMPBF__HeaderBlock *header_block; header_block=osmpbf__header_block__unpack(&protobuf_c_system_allocator, blob->raw_size, data); osmpbf__header_block__free_unpacked(header_block, &protobuf_c_system_allocator); }
static int parse_osm_header(VALUE obj, FILE *input) { OSMPBF__BlobHeader *header = read_blob_header(input); // EOF reached if(header == NULL) rb_raise(rb_eEOFError, "EOF reached without finding data"); if(strcmp("OSMHeader", header->type) != 0) rb_raise(rb_eIOError, "OSMHeader not found, probably the file is corrupt or invalid"); void *blob = NULL; size_t blob_length = 0, datasize = header->datasize; OSMPBF__HeaderBlock *header_block = NULL; osmpbf__blob_header__free_unpacked(header, NULL); blob = read_blob(input, datasize, &blob_length); header_block = osmpbf__header_block__unpack(NULL, blob_length, blob); free(blob); if(header_block == NULL) rb_raise(rb_eIOError, "Unable to unpack the HeaderBlock"); VALUE header_hash = rb_hash_new(); VALUE bbox_hash = rb_hash_new(); VALUE required_features = Qnil; VALUE optional_features = Qnil; VALUE writingprogram = Qnil; VALUE source = Qnil; VALUE osmosis_replication_timestamp = Qnil; VALUE osmosis_replication_sequence_number = Qnil; VALUE osmosis_replication_base_url = Qnil; int i = 0; if(header_block->n_required_features > 0) { required_features = rb_ary_new(); for(i = 0; i < (int)header_block->n_required_features; i++) rb_ary_push(required_features, str_new(header_block->required_features[i])); } if(header_block->n_optional_features > 0) { optional_features = rb_ary_new(); for(i = 0; i < (int)header_block->n_optional_features; i++) rb_ary_push(optional_features, str_new(header_block->optional_features[i])); } if(header_block->writingprogram) writingprogram = str_new(header_block->writingprogram); if(header_block->source) source = str_new(header_block->source); if(header_block->bbox) { rb_hash_aset(bbox_hash, STR2SYM("top"), rb_float_new(header_block->bbox->top * NANO_DEGREE)); rb_hash_aset(bbox_hash, STR2SYM("right"), rb_float_new(header_block->bbox->right * NANO_DEGREE)); rb_hash_aset(bbox_hash, STR2SYM("bottom"), rb_float_new(header_block->bbox->bottom * NANO_DEGREE)); rb_hash_aset(bbox_hash, STR2SYM("left"), rb_float_new(header_block->bbox->left * NANO_DEGREE)); } if(header_block->has_osmosis_replication_timestamp) osmosis_replication_timestamp = ULL2NUM(header_block->osmosis_replication_timestamp); if(header_block->has_osmosis_replication_sequence_number) osmosis_replication_sequence_number = ULL2NUM(header_block->osmosis_replication_sequence_number); if(header_block->osmosis_replication_base_url) osmosis_replication_base_url = str_new(header_block->osmosis_replication_base_url); rb_hash_aset(header_hash, str_new("bbox"), bbox_hash); rb_hash_aset(header_hash, str_new("required_features"), required_features); rb_hash_aset(header_hash, str_new("optional_features"), optional_features); rb_hash_aset(header_hash, str_new("writing_program"), writingprogram); rb_hash_aset(header_hash, str_new("source"), source); rb_hash_aset(header_hash, str_new("osmosis_replication_timestamp"), osmosis_replication_timestamp); rb_hash_aset(header_hash, str_new("osmosis_replication_sequence_number"), osmosis_replication_sequence_number); rb_hash_aset(header_hash, str_new("osmosis_replication_base_url"), osmosis_replication_base_url); rb_iv_set(obj, "@header", header_hash); osmpbf__header_block__free_unpacked(header_block, NULL); return 1; }
/** TODO: actually do something and unpack data. */ void unpack_osmblob(OSMPBF__Blob* osm_blob, char* const type) { fprintf(stderr, "Unpacking osmblob %s\n", type); assert(osm_blob); uint8_t* zd = 0; long len = 0; int must_free = 0; if(osm_blob->has_raw){ // TODO zd = (uint8_t*)osm_blob->raw; } else if(osm_blob->has_lzma_data){ // TODO } else // unpack zlib_data if(osm_blob->has_zlib_data){ assert(osm_blob->has_raw_size); zd = malloc(osm_blob->raw_size + 1); must_free = 1; zd[osm_blob->raw_size] = 0; len = unpack_zlib_data(zd, osm_blob->raw_size, osm_blob->zlib_data.data, osm_blob->zlib_data.len); } // parse whatever has been contained. if(!strcmp("OSMHeader", type)) { OSMPBF__HeaderBlock* osm_head = osmpbf__header_block__unpack(0, len, zd); // Debugging stuff fprintf(stderr, "%s:%d OSM Head parsed:\n\tsource: %s\n\twritingprogram: %s\n\tn_required_f: %d\n\tn_optional_:%d\n", __FILE__,__LINE__, (osm_head->source?osm_head->source:"[no source]"), (osm_head->writingprogram?osm_head->writingprogram:"[no w-prog]"), osm_head->n_required_features, osm_head->n_optional_features); if(osm_head->bbox) { OSMPBF__HeaderBBox* bbox = osm_head->bbox; fprintf(stderr, "bbox (%lld, %lld) -- (%lld, %lld)\n", bbox->left, bbox->top, bbox->right, bbox->bottom); // osmpbf__header_bbox__free_unpacked(bbox, 0); } // print features int i; for(i = 0; i < osm_head->n_required_features; i++) fprintf(stderr, "Feature: %s\n", (osm_head->required_features)[i]?(osm_head->required_features)[i]:"[zero]"); for(i = 0; i < osm_head->n_optional_features; i++) fprintf(stderr, "Opt-Feature: %s\n", (osm_head->optional_features)[i]?(osm_head->optional_features)[i]:"[zero]"); osmpbf__header_block__free_unpacked(osm_head, 0); } else // parse OSMData if(!strcmp("OSMData", type)) { OSMPBF__PrimitiveBlock* pb = osmpbf__primitive_block__unpack(0, len, zd); if(pb) { fprintf(stderr, "primitive block \n\tn-primitive: %d\n", pb->n_primitivegroup); // Converting an integer to a lattitude or longitude uses the formula: OUT = IN * granularity / 10**9$ if(pb->has_lat_offset && pb->has_lat_offset) fprintf(stderr, "\toffset [%8lld, %8lld]\n", pb->lat_offset, pb->lon_offset); if(pb->has_granularity) fprintf(stderr, "\tgranularity: %d\n", pb->granularity); // Granularity of dates, normally represented in units of milliseconds since the 1970 epoch. if(pb->has_date_granularity) fprintf(stderr, "\tdate granularity: %d\n", pb->date_granularity); int i = 0; for(; i < pb->n_primitivegroup; i++) { OSMPBF__PrimitiveGroup* pg = pb->primitivegroup[i]; fprintf(stderr, "Primitive Group %d:\n\tn-nodes: %d\n\tdense nodes: %s\n\tn-ways: %d\n\tn-relations: %d\n\tn-changesets: %d\n", i, pg->n_nodes, pg->dense?"yes":"no", pg->n_ways, pg->n_relations, pg->n_changesets); if(pg->n_nodes > 0) { assert(pg->nodes != 0); for(int n = 0; n < pg->n_nodes; n++) { OSMPBF__Node* node = pg->nodes[n]; // TODO get all amenity=bench nodes... fprintf(stderr, "node %lld (keys: %d, vals: %d, [%8lld, %8lld])\n", node->id, node->n_keys, node->n_vals, node->lat, node->lon); fprint_info(stderr, node->info); } } if(pg->dense) { OSMPBF__DenseNodes *dn = pg->dense; fprintf(stderr, "Dense Nodes (id: %d, lat: %d, lon: %d, key: %d)\n", dn->n_id, dn->n_lat, dn->n_lon, dn->n_keys_vals); for(int j=0; j < dn->n_lat && j < dn->n_lon; j++) { // fprintf(stderr, "Dense Node %lld [%8lld, %8lld]\n", (dn->id)[j], dn->lat[j], dn->lon[j]); } } if(pg->n_relations > 0 && pg->relations ) { int r; for(r = 0; r < pg->n_relations; r++) { OSMPBF__Relation* rel = pg->relations[r]; fprintf(stderr,"rel %lld (key: %d, val: %d, role: %d, mem: %d, types: %d)\n", rel->id, rel->n_keys, rel->n_vals, rel->n_roles_sid, rel->n_memids, rel->n_types); // print keys: /* for(int kv=0; kv < rel->n_keys && kv < rel->n_vals; kv++) { char* key = stringtable_get_string(pb->stringtable, rel->keys[kv]); char* val = stringtable_get_string(pb->stringtable, rel->vals[kv]); fprintf(stderr, "\tkey/val: %s (%d) - %s (%d)\n", key?key:"", rel->keys[kv], val?val:"", rel->vals[kv]); free(key); free(val); } */ for(int mem = 0; mem < rel->n_memids; mem++){ // TODO } } } if(pg->n_ways > 0 && pg->ways) { int w; for(w = 0; w < pg->n_ways; w++) { OSMPBF__Way* way = pg->ways[w]; // way->info fprintf(stderr, "way %8lld (keys %d, vals: %d, refs: %d)\n", way->id, way->n_keys, way->n_vals, way->n_refs); for(int k = 0; k < way->n_keys; k++) { if(k < way->n_vals) { char* key = stringtable_get_string(pb->stringtable, way->keys[k]); char* val = stringtable_get_string(pb->stringtable, way->vals[k]); fprintf(stderr, "\tkey/val: %s (%d) - %s (%d)\n", key?key:"", way->keys[k], val?val:"", way->vals[k]); free(key); free(val); } } if(way->info) fprint_info(stderr, way->info); } } } osmpbf__primitive_block__free_unpacked(pb, 0); } } if(must_free) free(zd); // if(osm_blob->has_obsolete_bzip2_data){} // return something }