static VALUE parse_osm_data(VALUE obj) { FILE *input = DATA_PTR(obj); OSMPBF__BlobHeader *header = read_blob_header(input); if(header == NULL) return Qfalse; if(strcmp("OSMData", header->type) != 0) rb_raise(rb_eIOError, "OSMData not found"); void *blob = NULL; size_t blob_length = 0, datasize = header->datasize; OSMPBF__PrimitiveBlock *primitive_block = NULL; osmpbf__blob_header__free_unpacked(header, NULL); blob = read_blob(input, datasize, &blob_length); primitive_block = osmpbf__primitive_block__unpack(NULL, blob_length, blob); free(blob); if(primitive_block == NULL) rb_raise(rb_eIOError, "Unable to unpack the PrimitiveBlock"); int64_t lat_offset, lon_offset, granularity; int32_t ts_granularity; lat_offset = primitive_block->lat_offset; lon_offset = primitive_block->lon_offset; granularity = primitive_block->granularity; ts_granularity = primitive_block->date_granularity; OSMPBF__StringTable *string_table = primitive_block->stringtable; VALUE data = init_data_arr(); VALUE nodes = rb_hash_aref(data, STR2SYM("nodes")); VALUE ways = rb_hash_aref(data, STR2SYM("ways")); VALUE relations = rb_hash_aref(data, STR2SYM("relations")); size_t i = 0; for(i = 0; i < primitive_block->n_primitivegroup; i++) { OSMPBF__PrimitiveGroup *primitive_group = primitive_block->primitivegroup[i]; if(primitive_group->nodes) process_nodes(nodes, primitive_group, string_table, lat_offset, lon_offset, granularity, ts_granularity); if(primitive_group->dense) process_dense_nodes(nodes, primitive_group->dense, string_table, lat_offset, lon_offset, granularity, ts_granularity); if(primitive_group->ways) process_ways(ways, primitive_group, string_table, ts_granularity); if(primitive_group->relations) process_relations(relations, primitive_group, string_table, ts_granularity); } rb_iv_set(obj, "@data", data); osmpbf__primitive_block__free_unpacked(primitive_block, NULL); // Increment position rb_iv_set(obj, "@pos", INT2NUM(NUM2INT(rb_iv_get(obj, "@pos")) + 1)); return Qtrue; }
/** 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 }