bool LoadData(const osmscout::Projection& projection, osmscout::MapData& data) { osmscout::TypeSet nodeTypes; std::vector<osmscout::TypeSet> wayTypes; osmscout::TypeSet areaTypes; styleConfig->GetNodeTypesWithMaxMag(projection.GetMagnification(), nodeTypes); styleConfig->GetWayTypesByPrioWithMaxMag(projection.GetMagnification(), wayTypes); styleConfig->GetAreaTypesWithMaxMag(projection.GetMagnification(), areaTypes); return database->GetObjects(nodeTypes, wayTypes, areaTypes, projection.GetLonMin(), projection.GetLatMin(), projection.GetLonMax(), projection.GetLatMax(), projection.GetMagnification(), searchParameter, data.nodes, data.ways, data.areas); }
bool buildTable(Kompex::SQLiteStatement * stmt, int32_t &name_id, boost::unordered_map<std::string,int32_t> &table_names, std::string const &sql_table_name, std::vector<Tile*> list_tiles, osmscout::Database &map, osmscout::TypeSet const &typeSet, bool allow_duplicate_nodes, bool allow_duplicate_ways, bool allow_duplicate_areas) { // spec area search parameter osmscout::AreaSearchParameter area_search_param; area_search_param.SetUseLowZoomOptimization(false); // create the sql statement std::string stmt_insert = "INSERT INTO "+sql_table_name; stmt_insert += "(id,node_offsets,way_offsets,area_offsets) VALUES(" "@id,@node_offsets,@way_offsets,@area_offsets);"; try { stmt->BeginTransaction(); stmt->Sql(stmt_insert); } catch(Kompex::SQLiteException &exception) { qDebug() << "ERROR: SQLite exception with insert statement:" << QString::fromStdString(exception.GetString()); return false; } // osmscout may return nearby results again so we make // sure offsets are only included once if requested std::set<osmscout::FileOffset> set_node_offsets; std::set<osmscout::FileOffset> set_way_offsets; std::set<osmscout::FileOffset> set_area_offsets; // container for blob memory we delete after // committing the sql transaction std::vector<char*> list_blobs; // keep track of the number of transactions and // commit after a certain limit size_t transaction_limit=5000; size_t transaction_count=0; for(size_t i=0; i < list_tiles.size(); i++) { // for each tile // get objects from osmscout GeoBoundingBox const &bbox = list_tiles[i]->bbox; std::vector<osmscout::NodeRef> listNodes; std::vector<osmscout::WayRef> listWays; std::vector<osmscout::AreaRef> listAreas; map.GetObjects(bbox.minLon,bbox.minLat, bbox.maxLon,bbox.maxLat, typeSet, listNodes, listWays, listAreas); // merge all of the object refs into one list // of MapObjects so its easier to manage std::vector<MapObject> list_map_objects; list_map_objects.reserve(listNodes.size()+listWays.size()+listAreas.size()); for(size_t j=0; j < listNodes.size(); j++) { osmscout::NodeRef &nodeRef = listNodes[j]; if(nodeRef->GetName().empty()) { continue; } if(!allow_duplicate_nodes) { if(set_node_offsets.count(nodeRef->GetFileOffset()) != 0) { continue; } set_node_offsets.insert(nodeRef->GetFileOffset()); } MapObject map_object; map_object.name = nodeRef->GetName(); map_object.offset = nodeRef->GetFileOffset(); map_object.type = osmscout::refNode; list_map_objects.push_back(map_object); } for(size_t j=0; j < listWays.size(); j++) { osmscout::WayRef &wayRef = listWays[j]; if(wayRef->GetName().empty()) { continue; } if(!allow_duplicate_ways) { if(set_way_offsets.count(wayRef->GetFileOffset()) != 0) { continue; } set_way_offsets.insert(wayRef->GetFileOffset()); } MapObject map_object; map_object.name = wayRef->GetName(); map_object.offset = wayRef->GetFileOffset(); map_object.type = osmscout::refWay; list_map_objects.push_back(map_object); } for(size_t j=0; j < listAreas.size(); j++) { osmscout::AreaRef &areaRef = listAreas[j]; if(areaRef->rings.front().GetName().empty()) { continue; } if(!allow_duplicate_areas) { if(set_area_offsets.count(areaRef->GetFileOffset()) != 0) { continue; } set_area_offsets.insert(areaRef->GetFileOffset()); } MapObject map_object; map_object.name = areaRef->rings.front().GetName(); map_object.offset = areaRef->GetFileOffset(); map_object.type = osmscout::refArea; list_map_objects.push_back(map_object); } // create structs to sort file offsets by name lookup // [name_lookup_id] [list_offsets] boost::unordered_map<int32_t,OffsetGroup> entry_admin_regions; for(size_t j=0; j < list_map_objects.size(); j++) { MapObject &map_object = list_map_objects[j]; // add name_lookup up to table_names std::string name_lookup = convNameToLookup(map_object.name); int32_t name_lookup_id; // check if this lookup string already exists if(table_names.count(name_lookup) == 0) { // insert lookup string std::pair<std::string,int32_t> data; data.first = name_lookup; data.second = name_id; table_names.insert(data); name_lookup_id = name_id; name_id++; } else { name_lookup_id = table_names.find(name_lookup)->second; } // check if this lookup string already exists if(entry_admin_regions.count(name_lookup_id) == 0) { // insert new list of offsets std::pair<int32_t,OffsetGroup> data; data.first = name_lookup_id; entry_admin_regions.insert(data); } // add offset to list boost::unordered_map<int32_t,OffsetGroup>::iterator it; it = entry_admin_regions.find(name_lookup_id); if(map_object.type == osmscout::refNode) { it->second.node_offsets.push_back(map_object.offset); } else if(map_object.type == osmscout::refWay) { it->second.way_offsets.push_back(map_object.offset); } else if(map_object.type == osmscout::refArea) { it->second.area_offsets.push_back(map_object.offset); } } //qDebug() << list_tiles[i]->id << ":" << entry_admin_regions.size(); // write information for this tile to the database boost::unordered_map<int32_t,OffsetGroup>::iterator it; for(it = entry_admin_regions.begin(); it != entry_admin_regions.end(); ++it) { // convert offsets to byte arrays char * data_node_offsets = NULL; size_t sz_node_offsets=0; char * data_way_offsets = NULL; size_t sz_way_offsets=0; char * data_area_offsets = NULL; size_t sz_area_offsets=0; OffsetGroup &g = it->second; // // ### debug start // if(g_table_nameid_count.count(it->first) == 0) { // std::pair<int64_t,int64_t> debugdata; // debugdata.first = it->first; // debugdata.second = // g.node_offsets.size()+ // g.way_offsets.size()+ // g.area_offsets.size(); // g_table_nameid_count.insert(debugdata); // } // else { // std::map<int64_t,int64_t>::iterator d_it; // d_it = g_table_nameid_count.find(it->first); // d_it->second += // g.node_offsets.size()+ // g.way_offsets.size()+ // g.area_offsets.size(); // } // // ### debug end if(!(g.node_offsets.empty())) { sz_node_offsets = sizeof(osmscout::FileOffset)*g.node_offsets.size(); data_node_offsets = new char[sz_node_offsets]; memcpy(data_node_offsets,&(g.node_offsets[0]),sz_node_offsets); list_blobs.push_back(data_node_offsets); } if(!(g.way_offsets.empty())) { sz_way_offsets = sizeof(osmscout::FileOffset)*g.way_offsets.size(); data_way_offsets = new char[sz_way_offsets]; memcpy(data_way_offsets,&(g.way_offsets[0]),sz_way_offsets); list_blobs.push_back(data_way_offsets); } if(!(g.area_offsets.empty())) { sz_area_offsets = sizeof(osmscout::FileOffset)*g.area_offsets.size(); data_area_offsets = new char[sz_area_offsets]; memcpy(data_area_offsets,&(g.area_offsets[0]),sz_area_offsets); list_blobs.push_back(data_area_offsets); } if(data_node_offsets == NULL && data_way_offsets == NULL && data_area_offsets == NULL) { continue; } // prepare sql try { // cat name_id and tile_id into one id // get mask for bitlength int32_t mask = pow(2,g_sz_bits_tile_id)-1; int64_t id = it->first; // name_id id = id << g_sz_bits_tile_id; // bitshift id |= (list_tiles[i]->id & mask); // 24 most sig bits of tile_id stmt->BindInt64(1,id); if(data_node_offsets) { stmt->BindBlob(2,data_node_offsets,sz_node_offsets); } else { stmt->BindNull(2); } if(data_way_offsets) { stmt->BindBlob(3,data_way_offsets,sz_way_offsets); } else { stmt->BindNull(3); } if(data_area_offsets) { stmt->BindBlob(4,data_area_offsets,sz_area_offsets); } else { stmt->BindNull(4); } stmt->Execute(); stmt->Reset(); if(transaction_count > transaction_limit) { stmt->FreeQuery(); stmt->CommitTransaction(); stmt->BeginTransaction(); stmt->Sql(stmt_insert); transaction_count=0; } transaction_count++; } catch(Kompex::SQLiteException &exception) { qDebug() << "ERROR: SQLite exception writing tile data:" << QString::fromStdString(exception.GetString()); qDebug() << "ERROR: id:" << list_tiles[i]->id; qDebug() << "ERROR: name_lookup_id:" << it->first; qDebug() << "ERROR:" << sz_node_offsets << sz_way_offsets << sz_area_offsets; return false; } } // debug // qDebug() << i << "/" << list_tiles.size(); } stmt->FreeQuery(); stmt->CommitTransaction(); // free up blob memory for(size_t i=0; i < list_blobs.size(); i++) { delete[] list_blobs[i]; } return true; }