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; }
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."); } } }
void OsmApiDbSqlChangesetFileWriter::_createNewElement(ConstElementPtr element) { const QString elementTypeStr = element->getElementType().toString().toLower(); ElementPtr changeElement = _getChangeElement(element); //we only grab and assign a new id if we have a new element with a negative id, since we'll be //writing this directly to the database and negative ids aren't allowed LOG_TRACE("ID before: " << changeElement->getElementId()); long id; if (changeElement->getId() < 0) { id = _db.getNextId(element->getElementType().getEnum()); } else { id = changeElement->getId(); } LOG_TRACE("ID after: " << ElementId(changeElement->getElementType(), id)); changeElement->setId(id); changeElement->setVersion(1); changeElement->setVisible(true); changeElement->setChangeset(_changesetId); LOG_TRACE("Creating: " << changeElement->getElementId()); QString note = ""; LOG_VART(changeElement->getId()); LOG_VART(note); LOG_VART(changeElement->getVersion()); QString commentStr = "/* create " + elementTypeStr + " " + QString::number(changeElement->getId()); commentStr += "*/\n"; _outputSql.write((commentStr).toUtf8()); const QString values = _getInsertValuesStr(changeElement); _outputSql.write( ("INSERT INTO " + elementTypeStr + "s (" + elementTypeStr + "_id, " + values).toUtf8()); _outputSql.write(("INSERT INTO current_" + elementTypeStr + "s (id, " + values).toUtf8()); _createTags(changeElement); switch (changeElement->getElementType().getEnum()) { case ElementType::Way: _createWayNodes(boost::dynamic_pointer_cast<const Way>(changeElement)); break; case ElementType::Relation: _createRelationMembers(boost::dynamic_pointer_cast<const Relation>(changeElement)); break; default: //node break; } }
static bool isRelated(ConstElementPtr e1, ConstElementPtr e2) { if (e1->getStatus() != e2->getStatus() && e1->isUnknown() && e2->isUnknown() && OsmSchema::getInstance().isBuilding(e1->getTags(), e1->getElementType()) && OsmSchema::getInstance().isBuilding(e2->getTags(), e2->getElementType())) { return true; } else { return false; } }
void TranslatedTagCountVisitor::visit(const ConstElementPtr& e) { if (e->getTags().getInformationCount() > 0) { shared_ptr<Geometry> g = ElementConverter(_map->shared_from_this()).convertToGeometry(e); Tags t = e->getTags(); t["error:circular"] = QString::number(e->getCircularError()); t["hoot:status"] = e->getStatusString(); // remove all the empty tags. for (Tags::const_iterator it = e->getTags().begin(); it != e->getTags().end(); ++it) { if (t[it.key()] == "") { t.remove(it.key()); } } QString layerName; vector<ScriptToOgrTranslator::TranslatedFeature> f = _translator->translateToOgr(t, e->getElementType(), g->getGeometryTypeId()); // only write the feature if it wasn't filtered by the translation script. for (size_t i = 0; i < f.size(); i++) { _countTags(f[i].feature); } } }
bool PoiPolygonMatch::isPoiIsh(ConstElementPtr e) { return e->getElementType() == ElementType::Node && (OsmSchema::getInstance().getCategories(e->getTags()).intersects( OsmSchemaCategory::building() | OsmSchemaCategory::poi()) || e->getTags().getNames().size() > 0); }
Handle<Object> ElementJs::New(ConstElementPtr e) { HandleScope scope; Handle<Object> result; switch (e->getElementType().getEnum()) { case ElementType::Node: { ConstNodePtr n = dynamic_pointer_cast<const Node>(e); result = NodeJs::New(n); break; } case ElementType::Way: { ConstWayPtr w = dynamic_pointer_cast<const Way>(e); result = WayJs::New(w); break; } case ElementType::Relation: { ConstRelationPtr r = dynamic_pointer_cast<const Relation>(e); result = RelationJs::New(r); break; } default: throw IllegalArgumentException("Unexpected element type."); } return scope.Close(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 PertyRemoveRandomElementVisitor::visit(const ConstElementPtr& e) { boost::uniform_real<> uni(0.0, 1.0); if (uni(*_rng) <= _p) { RecursiveElementRemover(ElementId(e->getElementType(), e->getId())).apply(_map->shared_from_this()); } }
virtual void visit(const ConstElementPtr& e) { if (e->getElementType() == ElementType::Way) { WayDiscretizer wd(_map->shared_from_this(), dynamic_pointer_cast<const Way>(e)); wd.discretize(_spacing, _result); } }
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; }
void OgrWriter::_writePartial(ElementProviderPtr& provider, const ConstElementPtr& e) { if (_translator.get() == 0) { throw HootException("You must call open before attempting to write."); } if (e->getTags().getInformationCount() > 0) { // There is probably a cleaner way of doing this. // convertToGeometry calls getGeometryType which will throw an exception if it gets a relation // that it doesn't know about. E.g. "route", "superroute", " turnlanes:turns" etc shared_ptr<Geometry> g; try { g = ElementConverter(provider).convertToGeometry(e); } catch (IllegalArgumentException& err) { LOG_WARN("Error converting geometry: " << err.getWhat() << " (" << e->toString() << ")"); g.reset((GeometryFactory::getDefaultInstance()->createEmptyGeometry())); } /* LOG_DEBUG("After conversion to geometry, element is now a " << g->getGeometryType() ); */ Tags t = e->getTags(); t["error:circular"] = QString::number(e->getCircularError()); t["hoot:status"] = e->getStatusString(); for (Tags::const_iterator it = e->getTags().begin(); it != e->getTags().end(); ++it) { if (t[it.key()] == "") { t.remove(it.key()); } } vector<ScriptToOgrTranslator::TranslatedFeature> tf = _translator->translateToOgr(t, e->getElementType(), g->getGeometryTypeId()); // only write the feature if it wasn't filtered by the translation script. for (size_t i = 0; i < tf.size(); i++) { OGRLayer* layer = _getLayer(tf[i].tableName); if (layer != 0) { _addFeature(layer, tf[i].feature, g); } } } }
void DecomposeBuildingRelationsVisitor::visit(const ConstElementPtr& e) { if (e->getElementType() == ElementType::Relation) { const shared_ptr<Relation>& r = _map->getRelation(e->getId()); if (r->getType() == "building") { _decomposeBuilding(r); } } }
bool HgisPoiCriterion::isSatisfied(const ConstElementPtr& e) const { bool result = false; // See ticket #6853 for a definition of a "HGIS POI" if (e->getElementType() == ElementType::Node) { result = OsmSchema::getInstance().hasCategory(e->getTags(), OsmSchemaCategory::hgisPoi().toString()); } return result; }
void OsmApiDbSqlChangesetFileWriter::_updateExistingElement(ConstElementPtr element) { const QString elementTypeStr = element->getElementType().toString().toLower(); ElementPtr changeElement = _getChangeElement(element); //if another parsed change previously modified the element with this id, we want to get the //modified version const long currentVersion = changeElement->getVersion(); const long newVersion = currentVersion + 1; changeElement->setVersion(newVersion); changeElement->setChangeset(_changesetId); changeElement->setVisible(true); LOG_TRACE("Updating: " << changeElement->getElementId()); QString note = ""; LOG_VART(changeElement->getId()); LOG_VART(note); LOG_VART(changeElement->getVersion()); QString commentStr = "/* modify " + elementTypeStr + " " + QString::number(changeElement->getId()); commentStr += "*/\n"; _outputSql.write((commentStr).toUtf8()); //<element-name> table contains all version of all elements of that type in a history, so insert //into that table. _outputSql.write( ("INSERT INTO " + elementTypeStr + "s (" + elementTypeStr + "_id, " + _getInsertValuesStr(changeElement)).toUtf8()); //current_<element-name> contains the single latest version of the element, so update that record _outputSql.write( ("UPDATE current_" + elementTypeStr + "s SET " + _getUpdateValuesStr(changeElement)).toUtf8()); _deleteCurrentTags(changeElement->getElementId()); _createTags(changeElement); switch (changeElement->getElementType().getEnum()) { case ElementType::Way: _deleteAll(ApiDb::getCurrentWayNodesTableName(), "way_id", changeElement->getId()); _deleteAll(ApiDb::getWayNodesTableName(), "way_id", changeElement->getId()); _createWayNodes(boost::dynamic_pointer_cast<const Way>(changeElement)); break; case ElementType::Relation: _deleteAll(ApiDb::getCurrentRelationMembersTableName(), "relation_id", changeElement->getId()); _deleteAll(ApiDb::getRelationMembersTableName(), "relation_id", changeElement->getId()); _createRelationMembers(boost::dynamic_pointer_cast<const Relation>(changeElement)); break; default: //node break; } }
QString OsmApiDbSqlChangesetFileWriter::_getInsertValuesStr(ConstElementPtr element) const { switch (element->getElementType().getEnum()) { case ElementType::Node: return _getInsertValuesNodeStr(boost::dynamic_pointer_cast<const Node>(element)); case ElementType::Way: return _getInsertValuesWayOrRelationStr(element); case ElementType::Relation: return _getInsertValuesWayOrRelationStr(element); default: throw HootException("Unknown element type"); } }
void KeepBuildingsVisitor::visit(const ConstElementPtr& e) { ElementType type = e->getElementType(); long id = e->getId(); if (type != ElementType::Node) { boost::shared_ptr<Element> ee = _map->getElement(type, id); if (BuildingCriterion().isSatisfied(ee->getTags(), type) == false) { RemoveElementOp::removeElementNoCheck(_map->shared_from_this(), e->getElementId()); } } }
void KeepBuildingsVisitor::visit(const ConstElementPtr& e) { ElementType type = e->getElementType(); long id = e->getId(); if (type != ElementType::Node) { shared_ptr<Element> ee = _map->getElement(type, id); if (OsmSchema::getInstance().isBuilding(ee->getTags(), type) == false) { // @todo This could do bad things if the element is in use. _map->removeElementNoCheck(type, id); } } }
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()); } } }
ElementPtr OsmApiDbSqlChangesetFileWriter::_getChangeElement(ConstElementPtr element) { ElementPtr changeElement; switch (element->getElementType().getEnum()) { case ElementType::Node: changeElement.reset(new Node(*boost::dynamic_pointer_cast<const Node>(element))); break; case ElementType::Way: changeElement.reset(new Way(*boost::dynamic_pointer_cast<const Way>(element))); break; case ElementType::Relation: changeElement.reset(new Relation(*boost::dynamic_pointer_cast<const Relation>(element))); break; default: throw HootException("Unknown element type"); } return changeElement; }
void RemoveElementsVisitor::visit(const ConstElementPtr& e) { assert(_filter); ElementType type = e->getElementType(); long id = e->getId(); const shared_ptr<Element>& ee = _map->getElement(type, id); if (_filter->isSatisfied(ee)) { if (_recursive) { RecursiveElementRemover(ee->getElementId()).apply(_map->shared_from_this()); } else { _map->removeElement(ElementId(type, id)); } } }
bool isMatchCandidate(ConstElementPtr element) { if (element->getElementType() == ElementType::Node) { const shared_ptr<const Node>& n(dynamic_pointer_cast<const Node>(element)); bool inBounds = true; // if the bounds is specified, make sure this node is inside the bounds. if (_bounds.isNull() == false) { Coordinate uc = _projectToWgs84(n->toCoordinate()); inBounds = _bounds.contains(uc); } if (inBounds && OsmSchema::getInstance().isPoi(*n)) { return true; } } return false; }
void RemoveRef2Visitor::visit(const ConstElementPtr& e) { if (!_criterion) { throw IllegalArgumentException("You must specify a criterion before calling " "RemoveRef2Visitor."); } ElementType type = e->getElementType(); long id = e->getId(); ElementPtr ee = _map->getElement(ElementId(type, id)); // if e has a REF2 and meets the criterion if (_hasRef2Tag(ee) && _criterion->isSatisfied(ee)) { // go through each REF2 and evaluate for deletion for (int i = 0; i < _ref2Keys.size(); i++) { _checkAndDeleteRef2(ee, _ref2Keys[i]); } } }
Meters ElementConverter::calculateLength(const ConstElementPtr &e) const { // Doing length/distance calcs only make sense if we've projected down onto a flat surface assert(MapReprojector::isPlanar(_constProvider)); // if the element is not a point and is not an area. // NOTE: Originally I was using isLinear. This was a bit too strict in that it wants evidence of // being linear before the length is calculated. Conversely, this wants evidence that is is not // linear before it will assume it doesn't have a length. if (e->getElementType() != ElementType::Node && OsmSchema::getInstance().isArea(e) == false) { /// @optimize // we don't really need to convert first, we can just loop through the nodes and sum up the // distance. return convertToGeometry(e)->getLength(); } else { return 0; } }
virtual void visit(const ConstElementPtr& e) { if (e->getElementType() == ElementType::Way) { const ConstWayPtr& w = boost::dynamic_pointer_cast<const Way>(e); vector<long> nodes = w->getNodeIds(); if (nodes[0] != nodes[nodes.size() - 1]) { nodes.push_back(nodes[0]); } Coordinate last = _map.getNode(nodes[0])->toCoordinate(); for (size_t i = 1; i < nodes.size(); i++) { Coordinate c = _map.getNode(nodes[i])->toCoordinate(); double distance = c.distance(last); double theta = atan2(c.y - last.y, c.x - last.x); _h.addAngle(theta, distance); last = c; } } }
bool NodeCriterion::isSatisfied(const ConstElementPtr& e) const { return e->getElementType() == ElementType::Node; }
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(); }
void OsmApiDbSqlChangesetFileWriter::_deleteExistingElement(ConstElementPtr element) { const QString elementIdStr = QString::number(element->getId()); const QString elementTypeStr = element->getElementType().toString().toLower(); ElementPtr changeElement = _getChangeElement(element); const long currentVersion = changeElement->getVersion(); const long newVersion = currentVersion + 1; changeElement->setVersion(newVersion); changeElement->setVisible(false); changeElement->setChangeset(_changesetId); LOG_TRACE("Deleting: " << changeElement->getElementId()); QString note = ""; LOG_VART(changeElement->getId()); LOG_VART(note); LOG_VART(changeElement->getVersion()); QString commentStr = "/* delete " + elementTypeStr + " " + QString::number(changeElement->getId()); commentStr += "*/\n"; _outputSql.write((commentStr).toUtf8()); //OSM API DB keeps history for all elements, so the existing element in the master table is not //modified and a new record is added with the updated version and visible set to false _outputSql.write(("INSERT INTO " + elementTypeStr + "s (" + elementTypeStr + "_id, " + _getInsertValuesStr(changeElement)).toUtf8()); _deleteCurrentTags(changeElement->getElementId()); switch (changeElement->getElementType().getEnum()) { case ElementType::Node: _outputSql.write( ("DELETE FROM " + ApiDb::getCurrentWayNodesTableName() + " WHERE node_id=" + elementIdStr + ";\n").toUtf8()); _outputSql.write( ("DELETE FROM " + ApiDb::getCurrentRelationMembersTableName() + " WHERE member_type = 'Node' AND member_id = " + elementIdStr + ";\n").toUtf8()); break; case ElementType::Way: //all of its entries in current way nodes are removed _outputSql.write( ("DELETE FROM " + ApiDb::getCurrentWayNodesTableName() + " WHERE way_id=" + elementIdStr + ";\n").toUtf8()); _outputSql.write( ("DELETE FROM " + ApiDb::getCurrentRelationMembersTableName() + " WHERE member_type = 'Way' AND member_id = " + elementIdStr + ";\n").toUtf8()); break; case ElementType::Relation: _outputSql.write( ("DELETE FROM " + ApiDb::getCurrentRelationMembersTableName() + " WHERE relation_id=" + elementIdStr + ";\n").toUtf8()); _outputSql.write( ("DELETE FROM " + ApiDb::getCurrentRelationMembersTableName() + " WHERE member_type = 'Relation' AND member_id = " + elementIdStr + ";\n").toUtf8()); break; default: throw HootException("Unknown element type"); } //in the current table, the element isn't deleted but set to be invisible const QString values = QString("changeset_id=%1, visible=%2, version=%3 WHERE id=%4;\n") .arg(changeElement->getChangeset()) .arg(_getVisibleStr(changeElement->getVisible())) .arg(changeElement->getVersion()) .arg(changeElement->getId()); _outputSql.write(("UPDATE current_" + elementTypeStr + "s SET " + values).toUtf8()); }
static bool isMatchCandidate(ConstElementPtr element) { return OsmSchema::getInstance().isBuilding(element->getTags(), element->getElementType()); }
bool PoiPolygonMatch::isBuildingIsh(ConstElementPtr e) { return OsmSchema::getInstance().isArea(e->getTags(), e->getElementType()) && OsmSchema::getInstance().getCategories(e->getTags()).intersects( OsmSchemaCategory::building() | OsmSchemaCategory::poi()); }