void OsmApiDbSqlChangesetFileWriter::_createRelationMembers(ConstRelationPtr relation) { LOG_TRACE("Creating relation members for: " << relation->getElementId()); const vector<RelationData::Entry> members = relation->getMembers(); for (size_t i = 0; i < members.size(); i++) { const RelationData::Entry member = members[i]; LOG_VART(member.getElementId()); QString values = QString( "(relation_id, member_type, member_id, member_role, version, sequence_id) VALUES (%1, '%2', %3, '%4', 1, %5);\n") .arg(relation->getId()) .arg(member.getElementId().getType().toString()) .arg(member.getElementId().getId()) .arg(member.getRole()) .arg(i + 1); _outputSql.write(("INSERT INTO " + ApiDb::getRelationMembersTableName() + " " + values).toUtf8()); values = QString( "(relation_id, member_type, member_id, member_role, sequence_id) VALUES (%1, '%2', %3, '%4', %5);\n") .arg(relation->getId()) .arg(member.getElementId().getType().toString()) .arg(member.getElementId().getId()) .arg(member.getRole()) .arg(i + 1); _outputSql.write( ("INSERT INTO " + ApiDb::getCurrentRelationMembersTableName() + " " + values).toUtf8()); } }
void MaximalSublineStringMatcher::_validateElement(const ConstOsmMapPtr& map, ElementId eid) const { ConstElementPtr e = map->getElement(eid); if (e->getElementType() == ElementType::Relation) { ConstRelationPtr r = dynamic_pointer_cast<const Relation>(e); if (OsmSchema::getInstance().isMultiLineString(*r) == false) { throw NeedsReviewException("Internal Error: When matching sublines expected a multilinestring " "relation not a " + r->getType() + ". A non-multilinestring should never be found here. " "Please report this to [email protected]"); } const vector<RelationData::Entry>& entries = r->getMembers(); for (size_t i = 0; i < entries.size(); i++) { if (entries[i].getElementId().getType() != ElementType::Way) { throw NeedsReviewException("MultiLineString relations can only contain ways when matching " "sublines."); } } } if (e->getElementType() == ElementType::Way) { ConstWayPtr w = dynamic_pointer_cast<const Way>(e); if (w->getNodeCount() <= 1) { throw NeedsReviewException("Internal Error: Attempting to match against a zero length way."); } } }
bool LinearCriterion::isSatisfied(const ConstElementPtr& e) const { bool result = false; if (e->getElementType() == ElementType::Node) { return false; } const Tags& t = e->getTags(); if (e->getElementType() == ElementType::Relation) { ConstRelationPtr r = boost::dynamic_pointer_cast<const Relation>(e); result |= r->getType() == MetadataTags::RelationMultilineString(); result |= r->getType() == MetadataTags::RelationRoute(); result |= r->getType() == MetadataTags::RelationBoundary(); } for (Tags::const_iterator it = t.constBegin(); it != t.constEnd(); ++it) { const SchemaVertex& tv = OsmSchema::getInstance().getTagVertex(it.key() + "=" + it.value()); uint16_t g = tv.geometries; if (g & (OsmGeometries::LineString | OsmGeometries::ClosedWay) && !(g & OsmGeometries::Area)) { result = true; break; } } return result; }
boost::shared_ptr<Geometry> Building::buildOutline() const { ElementConverter ec(_map.shared_from_this()); boost::shared_ptr<Geometry> result; // if this is a building relation if (_e->getElementType() == ElementType::Relation) { // construct the outline from the union of the parts. result.reset(GeometryFactory::getDefaultInstance()->createEmptyGeometry()); ConstRelationPtr r = boost::dynamic_pointer_cast<const Relation>(_e); const vector<RelationData::Entry> entries = r->getMembers(); for (size_t i = 0; i < entries.size(); i++) { if (entries[i].role == MetadataTags::RolePart()) { boost::shared_ptr<Geometry> g = ec.convertToGeometry(_map.getElement(entries[i].getElementId())); result.reset(result->Union(g.get())); } } } else { result = ec.convertToGeometry(_e); } return result; }
void MaximalSublineStringMatcher::_validateElement(const ConstOsmMapPtr& map, ElementId eid) const { ConstElementPtr e = map->getElement(eid); if (e->getElementType() == ElementType::Relation) { ConstRelationPtr r = dynamic_pointer_cast<const Relation>(e); if (OsmSchema::getInstance().isMultiLineString(*r) == false) { throw NeedsReviewException("When matching sublines expected a multilinestring relation not" " a " + r->getType()); } const vector<RelationData::Entry>& entries = r->getMembers(); for (size_t i = 0; i < entries.size(); i++) { if (entries[i].getElementId().getType() != ElementType::Way) { throw NeedsReviewException("MultiLineString relations can only contain ways when matching " "sublines."); } } } }
void OsmApiDbSqlChangesetFileWriter::_createTags(ConstElementPtr element) { LOG_TRACE("Creating tags for: " << element->getElementId()); QStringList tableNames = _tagTableNamesForElement(element->getElementId()); Tags tags = element->getTags(); if (_includeDebugTags) { tags.set(MetadataTags::HootStatus(), QString::number(element->getStatus().getEnum())); } LOG_VART(tags); if (element->getElementType().getEnum() == ElementType::Relation && !tags.contains("type")) { ConstRelationPtr tmp = boost::dynamic_pointer_cast<const Relation>(element); tags.appendValue("type", tmp->getType()); } for (Tags::const_iterator it = tags.begin(); it != tags.end(); ++it) { QString k = it.key(); QString v = it.value(); if (k != MetadataTags::HootHash()) { const QString currentTagValues = QString("(%1_id, k, v) VALUES (%2, '%3', '%4');\n") .arg(element->getElementId().getType().toString().toLower()) .arg(element->getElementId().getId()) .arg(k.replace('\'', "''")) .arg(v.replace('\'', "''")); const QString tagValues = QString("(%1_id, k, v, version) VALUES (%2, '%3', '%4', %5);\n") .arg(element->getElementId().getType().toString().toLower()) .arg(element->getElementId().getId()) .arg(k.replace('\'', "''")) .arg(v.replace('\'', "''")) .arg(element->getVersion()); _outputSql.write( (QString("INSERT INTO %1 ").arg(tableNames.at(0)) + currentTagValues).toUtf8()); _outputSql.write((QString("INSERT INTO %1 ").arg(tableNames.at(1)) + tagValues).toUtf8()); } } }
bool ContainsNodeCriterion::isSatisfied(const ConstElementPtr& e) const { if (e->getElementType() == ElementType::Way) { ConstWayPtr w = boost::dynamic_pointer_cast<const Way>(e); return w->hasNode(_nodeId); } else if (e->getElementType() == ElementType::Relation) { ConstRelationPtr r = boost::dynamic_pointer_cast<const Relation>(e); return r->contains(ElementId(ElementType::Node, _nodeId)); } else if (e->getElementType() == ElementType::Node) { ConstNodePtr n = boost::dynamic_pointer_cast<const Node>(e); return (n->getId() == _nodeId); } return false; }
MultiLineStringLocation PertyWaySplitVisitor::_calcSplitPoint(ConstRelationPtr relation, ElementId& wayId) const { const vector<RelationData::Entry>& members = relation->getMembers(); LOG_VART(members.size()); //find the way to split on boost::uniform_int<> randomWayIndexDistribution(0, members.size() - 1); int wayIndex = randomWayIndexDistribution(*_rng); wayId = members.at(wayIndex).getElementId(); LOG_VART(wayIndex); LOG_VART(wayId); ElementPtr element = _map->getElement(wayId); if (element->getElementType() != ElementType::Way) { throw HootException( "PERTY feature splitting for multi-line string relations may only occur on relations which contain only ways."); } WayPtr way = boost::dynamic_pointer_cast<Way>(element); LOG_VART(way->getNodeCount()); //calculate the split point WayLocation wayLocation = _calcSplitPoint(way); //return it, if its valid if (wayLocation.isValid()) { return MultiLineStringLocation( _map->shared_from_this(), relation, wayIndex, wayLocation); } //otherwise, return an empty location else { return MultiLineStringLocation(); } }
void ElementCacheLRU::addElement(ConstElementPtr &newElement) { ConstNodePtr newNode; ConstWayPtr newWay; ConstRelationPtr newRelation; switch ( newElement->getElementType().getEnum() ) { case ElementType::Node: newNode = dynamic_pointer_cast<const Node>(newElement); if ( newNode != ConstNodePtr() ) { // Do we have to replace an entry? if ( _nodes.size() == _maxCountPerType ) { _removeOldest(ElementType::Node); } _nodes.insert(std::make_pair(newNode->getId(), std::make_pair(newNode, boost::posix_time::microsec_clock::universal_time()))); //LOG_DEBUG("Added new node with ID " << newNode->getId() ); } break; case ElementType::Way: newWay = dynamic_pointer_cast<const Way>(newElement); if ( newWay != ConstWayPtr() ) { // Do we have to replace an entry? if ( _ways.size() == _maxCountPerType ) { _removeOldest(ElementType::Way); } _ways.insert(std::make_pair(newWay->getId(), std::make_pair(newWay, boost::posix_time::microsec_clock::universal_time()))); } break; case ElementType::Relation: newRelation = dynamic_pointer_cast<const Relation>(newElement); if ( newRelation != ConstRelationPtr() ) { // Do we have to replace an entry? if ( _relations.size() == _maxCountPerType ) { _removeOldest(ElementType::Relation); } _relations.insert(std::make_pair(newRelation->getId(), std::make_pair(newRelation, boost::posix_time::microsec_clock::universal_time()))); } break; default: throw HootException(QString("Unexpected element type: %1").arg( newElement->getElementType().toString())); break; } // Reset all iterators to maintain interface contract resetElementIterators(); }
geos::geom::GeometryTypeId ElementConverter::getGeometryType(const ConstElementPtr& e, bool throwError, const bool statsFlag) { ElementType t = e->getElementType(); switch (t.getEnum()) { case ElementType::Node: return GEOS_POINT; case ElementType::Way: { ConstWayPtr w = dynamic_pointer_cast<const Way>(e); assert(w); if(statsFlag) { if (w->isValidPolygon() && OsmSchema::getInstance().isAreaForStats(w->getTags(), ElementType::Way)) return GEOS_POLYGON; else return GEOS_LINESTRING; } else { if (w->isValidPolygon() && OsmSchema::getInstance().isArea(w->getTags(), ElementType::Way)) return GEOS_POLYGON; else return GEOS_LINESTRING; } break; } case ElementType::Relation: { ConstRelationPtr r = dynamic_pointer_cast<const Relation>(e); assert(r); if(statsFlag) { if (r->isMultiPolygon() || OsmSchema::getInstance().isAreaForStats(r->getTags(), ElementType::Relation)) return GEOS_MULTIPOLYGON; else if (OsmSchema::getInstance().isLinear(*r)) return GEOS_MULTILINESTRING; } else { if (r->isMultiPolygon() || OsmSchema::getInstance().isArea(r->getTags(), ElementType::Relation)) return GEOS_MULTIPOLYGON; else if (OsmSchema::getInstance().isLinear(*r)) { return GEOS_MULTILINESTRING; } else if (r->getMembers().size() == 0 || OsmSchema::getInstance().isCollection(*r)) { // an empty geometry, pass back a collection return GEOS_GEOMETRYCOLLECTION; } } break; } default: LOG_ERROR("Element was not a node, way, or relation"); break; } if (throwError) { throw IllegalArgumentException("Unknown geometry type."); } else { return GeometryTypeId(-1); } }