OSMWay(const ::OSMPBF::Way &way) : id(way.id()), size(way.refs_size()) { nodes = (uint64_t *)malloc(size * sizeof(uint64_t)); uint64_t node_id = 0; for (size_t i = 0; i < size; ++i) { node_id += way.refs(i); nodes[i] = node_id; } }
void QcOsmPbfReader::read_ways(OSMPBF::PrimitiveGroup primitive_group) { enter_way_transactions(); int number_of_ways = primitive_group.ways_size(); for (int i = 0; i < number_of_ways; i++) { OSMPBF::Way way = primitive_group.ways(i); int64_t way_id = way.id(); QVector<int64_t> node_ids(way.refs_size()); int j = 0; DeltaCodedInt64 node_id; for (auto ref : way.refs()) { node_ids[j++] = node_id.update(ref); } // qDebug().nospace() << "way" << i << way_id << node_ids; int number_of_attributes = way.keys_size(); QVector<KeyValPair> attributes(number_of_attributes); for (int i = 0; i < number_of_attributes; i++) { int32_t key_id = way.keys(i); int32_t val_id = way.vals(i); // qDebug() << " key_val" << way_id << m_string_table[key_id] << m_string_table[val_id]; attributes[i] = KeyValPair(key_id, val_id); } yield_way(way_id, node_ids, attributes); if (m_read_metadatas and way.has_info()) { // qDebug().nospace() << " with meta-info"; OSMPBF::Info info = way.info(); int32_t version = info.version(); int64_t timestamp = to_timestamp(info.timestamp()); int64_t changeset = info.changeset(); int32_t uid = info.uid(); int32_t user_sid = info.user_sid(); // bool visible = info.visible(); // qDebug() << "Meta information:" << version << timestamp << changeset << uid << user_sid; // yield_way_metadata(way_id, version, timestamp, changeset, uid, user_sid); } } leave_way_transactions(); }
void OsmPbfWriterPrivate::writeBlock(bool forceWrite) { if ( (forceWrite && (nodesList.count() + waysList.count() + relationsList.count() > 0) ) || (nodesList.count() + waysList.count() + relationsList.count() >= entitiesPerBlockLimit) ) { OSMPBF::PrimitiveBlock currentFileBlockParsed; int32_t granularityCoordinate = 100, granularityDate = 1000; int64_t offsetLat = 0, offsetLon = 0; //FIXME: keep order of addition //Extract all strings to hash for future reference //FIXME extract granularities and offset QHash<QString, int32_t> stringTableHash; for (QList<OsmStructures::Node>::const_iterator iNode = nodesList.constBegin(); iNode != nodesList.constEnd() ; ++iNode) addEntityStringsToTable(&stringTableHash, *iNode); for (QList<OsmStructures::Way>::const_iterator iWay = waysList.constBegin(); iWay != waysList.constEnd() ; ++iWay) addEntityStringsToTable(&stringTableHash, *iWay); for (QList<OsmStructures::Relation>::const_iterator iRelation = relationsList.constBegin(); iRelation != relationsList.constEnd() ; ++iRelation) { addEntityStringsToTable(&stringTableHash, *iRelation); for (QSet<OsmStructures::RelationMember>::const_iterator iRelationMember = iRelation->members.constBegin(); iRelationMember != iRelation->members.constEnd() ; ++iRelationMember) { addStringToTable(&stringTableHash, iRelationMember->role); } } //Create list of strings from hash (sorted by value) int32_t stringsCount = stringTableHash.count() + 1; QScopedArrayPointer<QString> stringTableList(new QString[stringsCount]); stringTableList[0] = QString(""); for (QHash<QString, int32_t>::const_iterator iString = stringTableHash.constBegin() ; iString != stringTableHash.constEnd() ; ++iString) { stringTableList[iString.value()] = iString.key(); } //Write list of string to block stringtable for (int iIndex = 0 ; iIndex < stringsCount ; iIndex++) { currentFileBlockParsed.mutable_stringtable()->add_s(stringTableList[iIndex].toUtf8().data(), stringTableList[iIndex].toUtf8().length()); } stringTableList.reset(); //Write granularities and offsets if (granularityCoordinate != 100) currentFileBlockParsed.set_granularity(granularityCoordinate); if (granularityDate != 1000) currentFileBlockParsed.set_date_granularity(granularityDate); if (offsetLat != 0) currentFileBlockParsed.set_lat_offset(offsetLat); if (offsetLon != 0) currentFileBlockParsed.set_lon_offset(offsetLon); //Write nodes if (nodesList.count() > 0) { OSMPBF::PrimitiveGroup* nodesGroup = currentFileBlockParsed.add_primitivegroup(); int64_t denseId = 0, denseLat = 0, denseLon = 0; int64_t denseTimestamp = 0, denseChangeset = 0, denseUid = 0, denseUser = 0; for (QList<OsmStructures::Node>::const_iterator iNode = nodesList.constBegin(); iNode != nodesList.constEnd() ; ++iNode) { if ( ( (iNode->getLatNanoDegree() - offsetLat) % granularityCoordinate ) || (iNode->getLonNanoDegree() - offsetLon) % granularityCoordinate ) qFatal("Loosing precision"); int64_t lat_int = (iNode->getLatNanoDegree() - offsetLat) / granularityCoordinate; int64_t lon_int = (iNode->getLonNanoDegree() - offsetLon) / granularityCoordinate; if (useDenseNodes) { OSMPBF::DenseNodes* pbfDense = nodesGroup->mutable_dense(); pbfDense->add_id(iNode->id - denseId); pbfDense->add_lat(lat_int - denseLat); pbfDense->add_lon(lon_int - denseLon); denseId = iNode->id; denseLat = lat_int; denseLon = lon_int; pbfDense->mutable_denseinfo()->add_version(iNode->version); if (iNode->timestamp.toMSecsSinceEpoch() % granularityDate) qFatal("Loosing precision"); int64_t timestamp_value = iNode->timestamp.toMSecsSinceEpoch() / granularityDate; int32_t user_sid = stringTableHash.value(iNode->user); pbfDense->mutable_denseinfo()->add_timestamp(timestamp_value - denseTimestamp); pbfDense->mutable_denseinfo()->add_changeset(iNode->changeset - denseChangeset); pbfDense->mutable_denseinfo()->add_uid(iNode->uid - denseUid); pbfDense->mutable_denseinfo()->add_user_sid(user_sid - denseUser); denseTimestamp = timestamp_value; denseChangeset = iNode->changeset; denseUid = iNode->uid; denseUser = user_sid; for (QHash<QString, QString>::const_iterator iTagString = iNode->tags.constBegin() ; iTagString != iNode->tags.constEnd() ; ++iTagString) { pbfDense->add_keys_vals(stringTableHash.value(iTagString.key())); pbfDense->add_keys_vals(stringTableHash.value(iTagString.value())); } pbfDense->add_keys_vals(0); } else { OSMPBF::Node* pbfNode = nodesGroup->add_nodes(); pbfNode->set_id(iNode->id); pbfNode->set_lon(lat_int); pbfNode->set_lat(lon_int); packEntityInfo(pbfNode->mutable_info(), *iNode, granularityDate, stringTableHash); for (QHash<QString, QString>::const_iterator iTagString = iNode->tags.constBegin() ; iTagString != iNode->tags.constEnd() ; ++iTagString) { pbfNode->add_keys(stringTableHash.value(iTagString.key())); pbfNode->add_vals(stringTableHash.value(iTagString.value())); } } } } //write ways if (waysList.count() > 0) { OSMPBF::PrimitiveGroup* waysGroup = currentFileBlockParsed.add_primitivegroup(); for (QList<OsmStructures::Way>::const_iterator iWay = waysList.constBegin(); iWay != waysList.constEnd() ; ++iWay) { OSMPBF::Way* pbfWay = waysGroup->add_ways(); pbfWay->set_id(iWay->id); int64_t currentNodeId = 0; for (QList<int64_t>::const_iterator iNodeId = iWay->nodes.constBegin() ; iNodeId != iWay->nodes.constEnd() ; ++iNodeId) { pbfWay->add_refs(*iNodeId - currentNodeId); currentNodeId = *iNodeId; } packEntityInfo(pbfWay->mutable_info(), *iWay, granularityDate, stringTableHash); for (QHash<QString, QString>::const_iterator iTagString = iWay->tags.constBegin() ; iTagString != iWay->tags.constEnd() ; ++iTagString) { pbfWay->add_keys(stringTableHash.value(iTagString.key())); pbfWay->add_vals(stringTableHash.value(iTagString.value())); } } } //write relations if (relationsList.count() > 0) { OSMPBF::PrimitiveGroup* relationsGroup = currentFileBlockParsed.add_primitivegroup(); for (QList<OsmStructures::Relation>::const_iterator iRelation = relationsList.constBegin(); iRelation != relationsList.constEnd() ; ++iRelation) { OSMPBF::Relation *pbfRelation = relationsGroup->add_relations(); pbfRelation->set_id(iRelation->id); int64_t currentMemberId = 0; for (QSet<OsmStructures::RelationMember>::const_iterator iRelationMember = iRelation->members.constBegin(); iRelationMember != iRelation->members.constEnd() ; ++iRelationMember) { pbfRelation->add_roles_sid(stringTableHash.value(iRelationMember->role)); pbfRelation->add_memids(iRelationMember->memberRef.id - currentMemberId); currentMemberId = iRelationMember->memberRef.id; OSMPBF::Relation_MemberType currentType; switch (iRelationMember->memberRef.type) { case OsmStructures::EnumOsmNode: currentType = OSMPBF::Relation_MemberType_NODE; break; case OsmStructures::EnumOsmWay: currentType = OSMPBF::Relation_MemberType_WAY; break; case OsmStructures::EnumOsmRelation: currentType = OSMPBF::Relation_MemberType_RELATION; break; default: throw std::exception(); break; } pbfRelation->add_types(currentType); } packEntityInfo(pbfRelation->mutable_info(), *iRelation, granularityDate, stringTableHash); for (QHash<QString, QString>::const_iterator iTagString = iRelation->tags.constBegin() ; iTagString != iRelation->tags.constEnd() ; ++iTagString) { pbfRelation->add_keys(stringTableHash.value(iTagString.key())); pbfRelation->add_vals(stringTableHash.value(iTagString.value())); } } } QByteArray currentFileBlockPacked = packPbfMessageToArray(currentFileBlockParsed); writeFileblock("OSMData", currentFileBlockPacked); nodesList.clear(); waysList.clear(); relationsList.clear(); } }