void Network::consolidateRelations(bool discard_if_missing_reference) { std::map<unsigned long long int, RelationPtr>::iterator relIt = relations.begin(); //loop through the relations while (relIt != relations.end()) { RelationPtr relation = relIt->second; try { relation->consolidate(this); relIt++; } catch (RefNotFoundException e) { //the relation references a node, way or relation that doesn't exist if (discard_if_missing_reference) { //discard relations referencing this relation std::map<unsigned long long int, RelationPtr>::iterator relIt2 = relations.begin(); while (relIt2 != relations.end() && relIt2 != relIt) { if (relIt2->second->contains(relation)) { relations.erase(relIt2++); } else { relIt2++; } } //discard the relation itself std::map<unsigned long long int, RelationPtr>::iterator rel_to_delete = relIt++; relations.erase(rel_to_delete); } else { relIt++; } } } }
void runEscapeTags() { OsmMapPtr map(new OsmMap()); Coordinate coords[] = { Coordinate(0, 0), Coordinate(0, 1), Coordinate(1, 1), Coordinate(1, 0), Coordinate::getNull() }; Tags tags; tags.set("note", "<2>"); tags.set("aerialway", "t-bar"); tags.set("first name", "first name goes here"); tags.set("full_name", "\"Hacksaw\" Jim Duggan"); WayPtr way = TestUtils::createWay(map, Status::Unknown1, coords); way->setTags(tags); QList<ElementPtr> nodes; NodePtr node1(new Node(Status::Unknown1, map->createNextNodeId(), Coordinate(0.0, 0.1), 15)); node1->getTags().appendValue("name", "test1"); nodes.append(node1); NodePtr node2(new Node(Status::Unknown1, map->createNextNodeId(), Coordinate(0.1, 0.0), 15)); node2->getTags().appendValue("name", "test2"); nodes.append(node2); RelationPtr relation = TestUtils::createRelation(map, nodes); relation->setType("review"); relation->getTags().appendValue("name", "Test Review"); std::vector<RelationData::Entry> members = relation->getMembers(); members[0].role = "reviewee"; members[1].role = "reviewee"; relation->setMembers(members); QString output = OsmPgCsvWriter::toString(map); // Compare the results HOOT_STR_EQUALS(expected_runEscapeTags, output); }
// Get parent of relation D3MetaDatabase // D3MetaDatabasePtr D3DatabasePermissionBase::GetD3MetaDatabase() { RelationPtr pRelation; pRelation = GetParentRelation(D3MDDB_D3DatabasePermission_PR_D3MetaDatabase); if (!pRelation) return NULL; return (D3MetaDatabasePtr) pRelation->GetParent(); }
// Get parent of relation D3MetaColumn // D3MetaColumnPtr D3ColumnPermissionBase::GetD3MetaColumn() { RelationPtr pRelation; pRelation = GetParentRelation(D3MDDB_D3ColumnPermission_PR_D3MetaColumn); if (!pRelation) return NULL; return (D3MetaColumnPtr) pRelation->GetParent(); }
void GeometryConverter::convertPolygonToRelation(const Polygon* polygon, const OsmMapPtr& map, const RelationPtr& r, Status s, double circularError) { WayPtr outer = convertLineStringToWay(polygon->getExteriorRing(), map, s, circularError); if (outer != NULL) { r->addElement(MetadataTags::RoleOuter(), outer); for (size_t i = 0; i < polygon->getNumInteriorRing(); i++) { WayPtr inner = convertLineStringToWay(polygon->getInteriorRingN(i), map, s, circularError); r->addElement(MetadataTags::RoleInner(), inner); } } }
MapJoint::MapJoint( RelationPtr &rel, AbstractKeyValSetMapPtr &emap, ExpressionPtr &key, ExpressionPtr &val ) :Listener() { jp_=new MapJointPriv(rel,emap,key,val); rel->registerListener( this ); }
void AddHilbertReviewSortOrderOp::apply(shared_ptr<OsmMap>& map) { _mapEnvelope.reset(); MapReprojector::reprojectToPlanar(map); const RelationMap& relations = map->getRelationMap(); Envelope e = map->calculateEnvelope(); vector< pair<ElementId, int64_t> > reviewOrder; // reserves at least as much as we need. reviewOrder.reserve(relations.size()); for (RelationMap::const_iterator it = relations.begin(); it != relations.end(); ++it) { RelationPtr r = it->second; if (ReviewMarker::isReviewUid(map, r->getElementId())) { int64_t hv = _calculateHilbertValue(map, ReviewMarker::getReviewElements(map, r->getElementId())); pair<ElementId, int64_t> p(r->getElementId(), hv); reviewOrder.push_back(p); } } sort(reviewOrder.begin(), reviewOrder.end(), reviewLess); for (size_t i = 0; i < reviewOrder.size(); ++i) { RelationPtr r = map->getRelation(reviewOrder[i].first.getId()); r->getTags().set(ReviewMarker::reviewSortOrderKey, (long)i); } }
QSize LegendItem::paintRelation(QString name, RelationPtr relation, QPainter *painter, bool draw) { Label::Parsed *parsed = Label::parse(name); parsed->chunk->attributes.color = _color; int fontHeight = painter->fontMetrics().height(); int fontAscent = painter->fontMetrics().ascent(); QSize symbol_size = relation->legendSymbolSize(painter); int label_width = 0; int paddingValue = fontHeight / 4; if (relation->symbolLabelOnTop()) { Label::RenderContext tmprc(painter->font(), painter); Label::renderLabel(tmprc, parsed->chunk, false, false); label_width = tmprc.x; painter->translate(paddingValue, fontHeight+paddingValue / 2); symbol_size.setWidth(qMax(label_width, symbol_size.width())); } else { painter->translate(paddingValue, paddingValue / 2); } if (draw) { relation->paintLegendSymbol(painter, symbol_size); } if (relation->symbolLabelOnTop()) { painter->translate((symbol_size.width()-label_width)/2, fontAscent - fontHeight); } else { painter->translate(symbol_size.width() + paddingValue, 0); } Label::RenderContext rc(painter->font(), painter); if (relation->symbolLabelOnTop()) { rc.y = 0; } else { rc.y = (symbol_size.height()+painter->fontMetrics().boundingRect('M').height())/2; } if (parsed) { Label::renderLabel(rc, parsed->chunk, false, draw); delete parsed; parsed = 0; } double h = symbol_size.height() + paddingValue; if (relation->symbolLabelOnTop()) { h += fontHeight; } if (relation->symbolLabelOnTop()) { return QSize(qMax(rc.x,(symbol_size.width())) + (paddingValue * 2), h); } else { return QSize((symbol_size.width()) + (paddingValue * 3) + rc.x, h); } }
void verifyFullReadOutput(OsmMapPtr map) { //nodes CPPUNIT_ASSERT_EQUAL(2, (int)map->getNodes().size()); HOOT_STR_EQUALS(true, map->containsNode(1)); NodePtr node = map->getNode(1); CPPUNIT_ASSERT_EQUAL((long)1, node->getId()); CPPUNIT_ASSERT_EQUAL(38.4, node->getY()); CPPUNIT_ASSERT_EQUAL(-106.5, node->getX()); CPPUNIT_ASSERT_EQUAL(15.0, node->getCircularError()); CPPUNIT_ASSERT_EQUAL(2, node->getTags().size()); NodePtr node1 = map->getNode(2); CPPUNIT_ASSERT_EQUAL((long)2, node1->getId()); CPPUNIT_ASSERT_EQUAL(38.0, node1->getY()); CPPUNIT_ASSERT_EQUAL(-104.0, node1->getX()); //ways HOOT_STR_EQUALS(true, map->containsWay(1)); WayPtr way = map->getWay(1); CPPUNIT_ASSERT_EQUAL((long)1, way->getId()); CPPUNIT_ASSERT_EQUAL(2, (int)way->getNodeCount()); CPPUNIT_ASSERT_EQUAL((long)1, way->getNodeId(0)); CPPUNIT_ASSERT_EQUAL((long)2, way->getNodeId(1)); CPPUNIT_ASSERT_EQUAL(15.0, way->getCircularError()); CPPUNIT_ASSERT_EQUAL(1, way->getTags().size()); //relations HOOT_STR_EQUALS(true, map->containsRelation(1)); RelationPtr relation = map->getRelation(1); CPPUNIT_ASSERT_EQUAL((long)1, relation->getId()); vector<RelationData::Entry> relationData = relation->getMembers(); CPPUNIT_ASSERT_EQUAL(2, (int)relation->getMembers().size()); HOOT_STR_EQUALS("wayrole", relationData[0].getRole()); HOOT_STR_EQUALS("noderole",relationData[1].getRole()); CPPUNIT_ASSERT_EQUAL(15.0, relation->getCircularError()); }
std::map<unsigned long long int,RelationPtr> Network::getAdministrativeBoundaries(int admin_level) { std::map<unsigned long long int, RelationPtr> ret; std::map<unsigned long long int, RelationPtr>::const_iterator it = relations.begin(); while (it != relations.end()) { RelationPtr relation = it->second; if(relation->hasTag(Element::TAG_BOUNDARY) && relation->hasTag(Element::TAG_ADMINLEVEL) && boost::iequals(relation->getTag(Element::TAG_BOUNDARY), "administrative") && relation->getTag(Element::TAG_ADMINLEVEL) == boost::lexical_cast<std::string>(admin_level) ){ if(relation->toGeometry()) ret[relation->getId()] = relation; } it++; } return ret; }
void LegendItem::paint(QPainter *painter) { if (!isVisible()) { return; } RelationList legendItems; if (_auto) { legendItems = plot()->renderItem(PlotRenderItem::Cartesian)->relationList(); } else { legendItems = _relations; } int count = legendItems.count(); if (count <= 0) { // no legend or box if there are no legend items return; } QList<DrawnLegendItem> legendPixmaps; QSize legendSize(0, 0); QFont font(_font); font.setPointSizeF(view()->viewScaledFontSize(_fontScale)); // generate string list of relation names QStringList names; bool allAuto = true; bool sameX = true; bool sameYUnits = true; LabelInfo label_info = legendItems.at(0)->xLabelInfo(); QString yUnits = legendItems.at(0)->yLabelInfo().units; for (int i = 0; i<count; i++) { RelationPtr relation = legendItems.at(i); if (relation->descriptiveNameIsManual()) { allAuto = false; } if (relation->xLabelInfo() != label_info) { sameX = false; } // sameYUnits is false if any non empty units are defined differently. if (yUnits.isEmpty()) { yUnits = relation->yLabelInfo().units; } else if (relation->yLabelInfo().units != yUnits) { if (!relation->yLabelInfo().units.isEmpty()) { sameYUnits = false; } } } if (!allAuto) { for (int i = 0; i<count; i++) { names.append(legendItems.at(i)->descriptiveName()); } } else { for (int i = 0; i<count; i++) { RelationPtr relation = legendItems.at(i); QString label = relation->titleInfo().singleRenderItemLabel(); if (label.isEmpty()) { label_info = relation->yLabelInfo(); QString y_label = label_info.name; if (!sameYUnits) { if (!label_info.units.isEmpty()) { y_label = i18n("%1 \\[%2\\]").arg(y_label).arg(label_info.units); } } if (!y_label.isEmpty()) { LabelInfo xlabel_info = relation->xLabelInfo(); if (!sameX) { label = i18n("%1 vs %2").arg(y_label).arg(xlabel_info.name); } else if (xlabel_info.quantity.isEmpty()) { label = y_label; } else if (xlabel_info.quantity != xlabel_info.name) { label = i18n("%1 vs %2").arg(y_label).arg(xlabel_info.name); } else { label = y_label; } } else { label = relation->descriptiveName(); } } int i_dup = names.indexOf(label); if (i_dup<0) { names.append(label); } else { RelationPtr dup_relation = legendItems.at(i_dup); if (!dup_relation->yLabelInfo().file.isEmpty()) { names.replace(i_dup, label + " (" + dup_relation->yLabelInfo().file + ')'); } if (!relation->yLabelInfo().file.isEmpty()) { names.append(label + " (" + relation->yLabelInfo().file + ')'); } } } } for (int i = 0; i<count; i++) { RelationPtr relation = legendItems.at(i); DrawnLegendItem item; item.pixmap = QPixmap(LEGENDITEMMAXWIDTH, LEGENDITEMMAXHEIGHT); item.size = paintRelation(names.at(i), relation, &item.pixmap, font); if (_verticalDisplay) { legendSize.setWidth(qMax(legendSize.width(), item.size.width())); legendSize.setHeight(legendSize.height() + item.size.height()); } else { legendSize.setHeight(qMax(legendSize.height(), item.size.height())); legendSize.setWidth(legendSize.width() + item.size.width()); } legendPixmaps.append(item); } int x = rect().left(); int y = rect().top(); painter->save(); if (!_title.isEmpty()) { // Paint the title Label::Parsed *parsed = Label::parse(_title); if (parsed) { painter->save(); QPixmap pixmap(400, 100); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); Label::RenderContext rc(font, &pixmapPainter); QFontMetrics fm(font); rc.y = fm.ascent(); Label::renderLabel(rc, parsed->chunk, false); int startPoint = qMax(0, (legendSize.width() / 2) - (rc.x / 2)); int paddingValue = fm.height() / 4; setViewRect(viewRect().x(), viewRect().y(), qMax(rc.x, legendSize.width()), rc.y + legendSize.height() + paddingValue * 3); painter->drawRect(rect()); painter->drawPixmap(QPoint(x + startPoint, y + paddingValue), pixmap, QRect(0, 0, rc.x, fm.height())); painter->restore(); y += fm.height() + (paddingValue *2); delete parsed; parsed = 0; } } else { // No Title setViewRect(viewRect().x(), viewRect().y(), legendSize.width(), legendSize.height()); painter->drawRect(rect()); } foreach(const DrawnLegendItem &item, legendPixmaps) { painter->drawPixmap(QPoint(x, y), item.pixmap, QRect(0, 0, item.size.width(), item.size.height())); if (_verticalDisplay) { y += item.size.height(); } else { x += item.size.width(); } }
StringArrayListener::StringArrayListener( StringArrayPtr &sa, RelationPtr &r ) { d_=new StringArrayListenerPriv ( sa, r ); r->registerListener( this ); }
void runPartialReadTest() { //The differences in tag counts here when compared to //ServiceHootApiDbReaderTest::runPartialReadTest are due to differences between the way //HootApiDbWriter and OsmApiDbBulkInserter handle metadata tags, which is by design. populatePartialMap(); OsmApiDbReader reader; const int chunkSize = 3; reader.setMaxElementsPerMap(chunkSize); reader.open(ServicesDbTestUtils::getOsmApiDbUrl().toString()); reader.initializePartial(); int ctr = 0; OsmMapPtr map(new OsmMap()); //3 nodes CPPUNIT_ASSERT(reader.hasMoreElements()); reader.readPartial(map); CPPUNIT_ASSERT_EQUAL(3, (int)map->getNodes().size()); CPPUNIT_ASSERT_EQUAL(0, (int)map->getWays().size()); CPPUNIT_ASSERT_EQUAL(0, (int)map->getRelations().size()); NodePtr node = map->getNode(1); CPPUNIT_ASSERT_EQUAL((long)1, node->getId()); CPPUNIT_ASSERT_EQUAL(0.0, node->getX()); CPPUNIT_ASSERT_EQUAL(0.0, node->getY()); CPPUNIT_ASSERT_EQUAL(0, node->getTags().size()); node = map->getNode(2); CPPUNIT_ASSERT_EQUAL((long)2, node->getId()); CPPUNIT_ASSERT_EQUAL(0.1, node->getX()); CPPUNIT_ASSERT_EQUAL(0.0, node->getY()); CPPUNIT_ASSERT_EQUAL(1, node->getTags().size()); HOOT_STR_EQUALS("n2b", node->getTags().get("noteb")); node = map->getNode(3); CPPUNIT_ASSERT_EQUAL((long)3, node->getId()); CPPUNIT_ASSERT_EQUAL(0.2, node->getX()); CPPUNIT_ASSERT_EQUAL(0.0, node->getY()); CPPUNIT_ASSERT_EQUAL(1, node->getTags().size()); HOOT_STR_EQUALS("n3", node->getTags().get("note")); ctr++; //2 nodes, 1 way map.reset(new OsmMap()); CPPUNIT_ASSERT(reader.hasMoreElements()); reader.readPartial(map); CPPUNIT_ASSERT_EQUAL(2, (int)map->getNodes().size()); CPPUNIT_ASSERT_EQUAL(1, (int)map->getWays().size()); CPPUNIT_ASSERT_EQUAL(0, (int)map->getRelations().size()); node = map->getNode(4); CPPUNIT_ASSERT_EQUAL((long)4, node->getId()); CPPUNIT_ASSERT_EQUAL(0.3, node->getX()); CPPUNIT_ASSERT_EQUAL(0.0, node->getY()); CPPUNIT_ASSERT_EQUAL(1, node->getTags().size()); HOOT_STR_EQUALS("n4", node->getTags().get("note")); node = map->getNode(5); CPPUNIT_ASSERT_EQUAL((long)5, node->getId()); CPPUNIT_ASSERT_EQUAL(0.4, node->getX()); CPPUNIT_ASSERT_EQUAL(0.0, node->getY()); CPPUNIT_ASSERT_EQUAL(0, node->getTags().size()); WayPtr way = map->getWay(1); CPPUNIT_ASSERT_EQUAL((long)1, way->getId()); CPPUNIT_ASSERT(way->hasNode(1)); CPPUNIT_ASSERT(way->hasNode(2)); CPPUNIT_ASSERT_EQUAL(1, way->getTags().size()); HOOT_STR_EQUALS("w1b", way->getTags().get("noteb")); ctr++; //2 ways, 1 relation map.reset(new OsmMap()); CPPUNIT_ASSERT(reader.hasMoreElements()); reader.readPartial(map); CPPUNIT_ASSERT_EQUAL(0, (int)map->getNodes().size()); CPPUNIT_ASSERT_EQUAL(2, (int)map->getWays().size()); CPPUNIT_ASSERT_EQUAL(1, (int)map->getRelations().size()); way = map->getWay(2); CPPUNIT_ASSERT_EQUAL((long)2, way->getId()); CPPUNIT_ASSERT(way->hasNode(2)); CPPUNIT_ASSERT(way->hasNode(3)); CPPUNIT_ASSERT_EQUAL(1, way->getTags().size()); HOOT_STR_EQUALS("w2", way->getTags().get("note")); way = map->getWay(3); CPPUNIT_ASSERT_EQUAL((long)3, way->getId()); CPPUNIT_ASSERT(way->hasNode(2)); CPPUNIT_ASSERT_EQUAL(0, way->getTags().size()); RelationPtr relation = map->getRelation(1); CPPUNIT_ASSERT_EQUAL((long)1, relation->getId()); CPPUNIT_ASSERT_EQUAL(size_t(2), relation->getMembers().size()); CPPUNIT_ASSERT(relation->contains(ElementId::node(1))); CPPUNIT_ASSERT(relation->contains(ElementId::way(1))); RelationData::Entry member = relation->getMembers().at(0); HOOT_STR_EQUALS("n1", member.role); CPPUNIT_ASSERT_EQUAL((long)1, member.getElementId().getId()); member = relation->getMembers().at(1); HOOT_STR_EQUALS("w1", member.role); CPPUNIT_ASSERT_EQUAL((long)1, member.getElementId().getId()); CPPUNIT_ASSERT_EQUAL(1, relation->getTags().size()); HOOT_STR_EQUALS("r1", relation->getTags().get("note")); ctr++; //1 relation map.reset(new OsmMap()); CPPUNIT_ASSERT(reader.hasMoreElements()); reader.readPartial(map); CPPUNIT_ASSERT_EQUAL(0, (int)map->getNodes().size()); CPPUNIT_ASSERT_EQUAL(0, (int)map->getWays().size()); CPPUNIT_ASSERT_EQUAL(1, (int)map->getRelations().size()); relation = map->getRelation(2); CPPUNIT_ASSERT_EQUAL((long)2, relation->getId()); HOOT_STR_EQUALS("", relation->getType()); CPPUNIT_ASSERT(relation->contains(ElementId::node(2))); CPPUNIT_ASSERT_EQUAL(size_t(1), relation->getMembers().size()); member = relation->getMembers().at(0); HOOT_STR_EQUALS("n2", member.role); CPPUNIT_ASSERT_EQUAL((long)2, member.getElementId().getId()); CPPUNIT_ASSERT_EQUAL(0, relation->getTags().size()); ctr++; CPPUNIT_ASSERT(!reader.hasMoreElements()); reader.finalizePartial(); CPPUNIT_ASSERT_EQUAL(4, ctr); }
std::map<unsigned long long int, std::pair<RelationPtr, std::map<unsigned long long int, WayPtr> > > Network::getWaysByAdminBoundary(int admin_level) { typedef std::map<unsigned long long int, WayPtr> WayMap; typedef std::pair<unsigned long long int, WayPtr> WayType; typedef std::map<unsigned long long int, RelationPtr> RelationMap; typedef std::pair<RelationPtr, WayMap> RelationWayPair; typedef std::map<unsigned long long int, RelationWayPair> GlobalMap; GlobalMap ret; util::Log::GetInstance().info("extracting administrative boundaries"); RelationMap adminBoundaries = getAdministrativeBoundaries(admin_level); util::Log::GetInstance().info("finished extracting administrative boundaries"); WayMap waysList; BOOST_FOREACH(WayType w, ways) { if( w.second->getNodes()->size() > 1 && w.second->hasTag(Element::TAG_HIGHWAY) && Way::highwayTypes.find(w.second->getTag(Element::TAG_HIGHWAY)) != Way::highwayTypes.end() ) { waysList[w.second->getId()] = w.second; } } util::Log::GetInstance().info("extracting ways by administrative boundaries"); RelationMap::iterator boundaryIterator = adminBoundaries.begin(); while(boundaryIterator != adminBoundaries.end()) { RelationPtr boundary = boundaryIterator->second; ret[boundaryIterator->first] = RelationWayPair(boundary, WayMap()); boundaryIterator++; } WayMap::iterator wayIterator = waysList.begin(); while(wayIterator != waysList.end()) { WayPtr way = wayIterator->second; boost::shared_ptr<const geos::geom::Geometry> wayGeom = way->toGeometry(); boundaryIterator = adminBoundaries.begin(); while(boundaryIterator != adminBoundaries.end()) { RelationPtr boundary = boundaryIterator->second; boost::shared_ptr<const geos::geom::prep::PreparedGeometry> boundaryPrepGeom = boundary->toPreparedGeometry(); if(boundaryPrepGeom->covers(wayGeom.get()) || boundaryPrepGeom->intersects(wayGeom.get())) { //the way is inside or intersected by the boundary, keep it ret[boundaryIterator->first].second[wayIterator->first] = way; //mark the nodes of this way for next step reference counting way->referenceWithNodes(); break; } else //no interaction with current boundary boundaryIterator++; } ++wayIterator; } util::Log::GetInstance().info("finished extracting ways by administrative boundaries"); return ret; }
std::map<unsigned long long int,std::pair<RelationPtr,std::map<unsigned long long int, WayPtr> > > Network::getWalkableWaysByAdminBoundary(int admin_level) { std::map<unsigned long long int, std::pair<RelationPtr, std::map<unsigned long long int, WayPtr> > > ret; util::Log::GetInstance().info("extracting administrative boundaries"); std::map<unsigned long long int, RelationPtr> adminBoundaries = getAdministrativeBoundaries(admin_level); util::Log::GetInstance().info("finished extracting administrative boundaries"); std::map<unsigned long long int, WayPtr> walkableWays = getWalkableWays(); util::Log::GetInstance().info("extracting ways by administrative boundaries"); /* std::map<unsigned long long int,RelationPtr>::iterator boundaryIterator = adminBoundaries.begin(); while(boundaryIterator != adminBoundaries.end()) { RelationPtr boundary = boundaryIterator->second; ret[boundaryIterator->first] = std::pair<RelationPtr,std::map<unsigned long long int,WayPtr> >(boundary, std::map<unsigned long long int,WayPtr>()); boost::shared_ptr<const geos::geom::prep::PreparedGeometry> boundaryPrepGeom = boundary->toPreparedGeometry(); std::map<unsigned long long int,WayPtr>::iterator wayIterator = walkableWays.begin(); while(wayIterator != walkableWays.end()) { WayPtr way = wayIterator->second; boost::shared_ptr<const geos::geom::Geometry> wayGeom = way->toGeometry(); if(boundaryPrepGeom->covers(wayGeom.get())) { //the way is inside this boundary, keep it ret[boundaryIterator->first].second[wayIterator->first]=way; //mark the nodes of this way for next step reference counting way->referenceWithNodes(); //remove way from list to avoid further superfluous geometry computations walkableWays.erase(wayIterator++); } else if(boundaryPrepGeom->intersects(wayGeom.get())) { //the way isn't inside, but intersects, flag it as invalid walkableWays.erase(wayIterator++); //TODO: log the way } else { //no interaction with current boundary wayIterator++; } } boundaryIterator++; } */ std::map<unsigned long long int, RelationPtr>::iterator boundaryIterator = adminBoundaries.begin(); while(boundaryIterator != adminBoundaries.end()) { RelationPtr boundary = boundaryIterator->second; ret[boundaryIterator->first] = std::pair<RelationPtr, std::map<unsigned long long int, WayPtr> >(boundary, std::map<unsigned long long int, WayPtr>()); boundaryIterator++; } std::map<unsigned long long int,WayPtr>::iterator wayIterator = walkableWays.begin(); while(wayIterator != walkableWays.end()) { WayPtr way = wayIterator->second; boost::shared_ptr<const geos::geom::Geometry> wayGeom = way->toGeometry(); boundaryIterator = adminBoundaries.begin(); while(boundaryIterator != adminBoundaries.end()) { RelationPtr boundary = boundaryIterator->second; boost::shared_ptr<const geos::geom::prep::PreparedGeometry> boundaryPrepGeom = boundary->toPreparedGeometry(); if(boundaryPrepGeom->covers(wayGeom.get())) { //the way is inside this boundary, keep it ret[boundaryIterator->first].second[wayIterator->first] = way; //mark the nodes of this way for next step reference counting way->referenceWithNodes(); break; } else if(boundaryPrepGeom->intersects(wayGeom.get())) { //the way isn't inside, but intersects, continue break; //TODO: log the way } else { //no interaction with current boundary boundaryIterator++; } } ++wayIterator; } util::Log::GetInstance().info("finished extracting ways by administrative boundaries"); return ret; }
void LegendItem::paint(QPainter *painter) { if (!isVisible()) { return; } RelationList legendItems; if (_auto) { legendItems = plot()->renderItem(PlotRenderItem::Cartesian)->relationList(); } else { legendItems = _relations; } int count = legendItems.count(); if (count <= 0) { // no legend or box if there are no legend items return; } QFont font(_font); font.setPointSizeF(view()->scaledFontSize(_fontScale, *painter->device())); painter->setFont(font); // generate string list of relation names QStringList names; bool allAuto = true; bool sameX = true; bool sameYUnits = true; LabelInfo label_info = legendItems.at(0)->xLabelInfo(); QString yUnits = legendItems.at(0)->yLabelInfo().units; for (int i = 0; i<count; i++) { RelationPtr relation = legendItems.at(i); if (relation->descriptiveNameIsManual()) { allAuto = false; } if (relation->xLabelInfo() != label_info) { sameX = false; } // sameYUnits is false if any non empty units are defined differently. if (yUnits.isEmpty()) { yUnits = relation->yLabelInfo().units; } else if (relation->yLabelInfo().units != yUnits) { if (!relation->yLabelInfo().units.isEmpty()) { sameYUnits = false; } } } if (!allAuto) { for (int i = 0; i<count; i++) { names.append(legendItems.at(i)->descriptiveName()); } } else { for (int i = 0; i<count; i++) { RelationPtr relation = legendItems.at(i); QString label = relation->titleInfo().singleRenderItemLabel(); if (label.isEmpty()) { label_info = relation->yLabelInfo(); QString y_label = label_info.name; if (!sameYUnits) { if (!label_info.units.isEmpty()) { y_label = tr("%1 \\[%2\\]", "axis labels. %1 is quantity, %2 is units. eg Time [s]. '[' must be escaped.").arg(y_label).arg(label_info.units); } } if (!y_label.isEmpty()) { LabelInfo xlabel_info = relation->xLabelInfo(); if (!sameX) { label = tr("%1 vs %2", "describes a plot. %1 is X axis. %2 is Y axis").arg(y_label).arg(xlabel_info.name); } else if (xlabel_info.quantity.isEmpty()) { label = y_label; } else if (xlabel_info.quantity != xlabel_info.name) { label = tr("%1 vs %2", "describes a plot. %1 is X axis. %2 is Y axis").arg(y_label).arg(xlabel_info.name); } else { label = y_label; } } else { label = relation->descriptiveName(); } } int i_dup = names.indexOf(label); if (i_dup<0) { names.append(label); } else { RelationPtr dup_relation = legendItems.at(i_dup); if (!dup_relation->yLabelInfo().file.isEmpty()) { names.replace(i_dup, label + " (" + dup_relation->yLabelInfo().escapedFile() + ')'); } if (!relation->yLabelInfo().file.isEmpty()) { names.append(label + " (" + relation->yLabelInfo().escapedFile() + ')'); } } } } QSize legendSize(0, 0); QSize titleSize(0,0); Label::Parsed *parsed = Label::parse(_title); int pad = painter->fontMetrics().ascent()/4; Label::RenderContext rc(painter->font(), painter); Label::renderLabel(rc, parsed->chunk, false, false); if (!_title.isEmpty()) { titleSize.setWidth(rc.x+3*pad); titleSize.setHeight(painter->fontMetrics().height()+pad); } QList<QSize> sizes; int max_w = 0; int max_h = 0; for (int i = 0; i<count; i++) { RelationPtr relation = legendItems.at(i); QSize size; painter->save(); size = paintRelation(names.at(i), relation, painter, false); painter->restore(); sizes.append(size); max_w = qMax(max_w, size.width()); max_h = qMax(max_h, size.height()); } // determine number of rows and number of columns int n_rows = 0; int n_cols = 0; if (_verticalDisplay) { int h=titleSize.height(); for (int i = 0; i<count; i++) { h+=sizes.at(i).height(); } int max_legend_height = _plotItem->plotRect().height()*0.6+1; n_cols = qMin(count, h / max_legend_height + 1); n_rows = count / n_cols; while (n_rows*n_cols<count) { n_rows++; } } else { int w = 0; for (int i = 0; i<count; i++) { w+=sizes.at(i).width(); } int max_legend_width = _plotItem->plotRect().width()*0.8+1; n_rows = qMin(count, w / max_legend_width+1); n_cols = count/n_rows; while (n_rows*n_cols<count) { n_cols++; } } // determine the dimensions of each column QList<QSize> col_sizes; for (int i=0; i<n_cols; i++) { col_sizes.append(QSize(0,0)); } for (int i = 0; i<count; i++) { int col = i/n_rows; col_sizes[col].rheight()+= sizes.at(i).height(); col_sizes[col].setWidth(qMax(sizes.at(i).width(), col_sizes.at(col).width())); } // determine the dimensions of the legend int w = 0; int h = 0; for (int col = 0; col < n_cols; col++) { w += col_sizes.at(col).width(); h = qMax(h, col_sizes.at(col).height()); } legendSize.setHeight(h + titleSize.height()); legendSize.setWidth(qMax(titleSize.width(), w)); setViewRect(rect().x(), rect().y(), legendSize.width()+pad, legendSize.height()+pad); // Now paint everything painter->drawRect(rect()); int x=rect().x(); int y=rect().y(); if (!_title.isEmpty()) { rc.y = rect().y() + titleSize.height()-pad; rc.x = qMax(rect().x()+pad, rect().x() + legendSize.width()/2 - titleSize.width()/2); Label::renderLabel(rc, parsed->chunk, false, true); y+= titleSize.height(); } legendSize.setWidth(0); legendSize.setHeight(0); for (int i = 0; i<count; i++) { RelationPtr relation = legendItems.at(i); painter->save(); painter->translate(x,y); paintRelation(names.at(i), relation, painter, true); painter->restore(); int col = i/n_rows; int row = i%n_rows; if (row == n_rows-1) { // end of a column x += col_sizes.at(col).width(); y = rect().y() + titleSize.height(); } else { y += sizes.at(i).height(); } } delete parsed; }
foreach (RelationPtr s, objectStore()->getObjects<Relation>()) { s->save(xml); }
void CumulativeConflator::conflate(const QStringList inputs, const QString output) { assert(inputs.size() >= 3); //for NoInformationElementRemover if (ConfigOptions().getWriterCleanReviewTags()) { throw HootException( "Multi-conflation must be run with " + ConfigOptions::getWriterCleanReviewTagsKey() + "=false"); } //for TagMergerFactory if (ConfigOptions().getTagMergerDefault() != "hoot::ProvenanceAwareOverwriteTagMerger") { throw HootException( "Multi-conflation must be run with " + ConfigOptions::getTagMergerDefaultKey() + "=hoot::ProvenanceAwareOverwriteTagMerger"); } OsmMapPtr cumulativeMap(new OsmMap()); LOG_VARD(inputs.size()); for (int i = 0; i < inputs.size(); i++) { OsmMapPtr reviewCache; if (i == 0) { OsmMapReaderFactory::read( cumulativeMap, inputs[i], ConfigOptions().getReaderConflateUseDataSourceIds1(), Status::Unknown1); //keep a source tag history on the data for provenance; append to any existing source values //(this shouldn't be added to any review relations) LOG_DEBUG("Setting source tags for map " << QString::number(i + 1) << "..."); SetTagValueVisitor sourceTagVisitor(MetadataTags::HootSource(), QString::number(i + 1)); cumulativeMap->visitRw(sourceTagVisitor); } else { if (i == 1) { LOG_INFO("Conflating " << inputs[i - 1] << " with " << inputs[i] << "..."); } else { LOG_INFO("Conflating cumulative map with " << inputs[i] << "..."); } //I'm not yet sure all the projecting going on here is the right way to go about this, but //the maps must be in the same projection for the appending to work. OsmMapPtr unknown2Map(new OsmMap()); OsmMapReaderFactory::read( unknown2Map, inputs[i], ConfigOptions().getReaderConflateUseDataSourceIds2(), Status::Unknown2); MapProjector::projectToWgs84(unknown2Map); //Same as above, but do this before combining the cumulative map with the unknown2 map to //prevent incorrect tags from being added to the cumulative map. LOG_DEBUG("Setting source tags for map " << QString::number(i + 1) << "..."); SetTagValueVisitor sourceTagVisitor( MetadataTags::HootSource(), QString::number(i + 1)/*, true*/); unknown2Map->visitRw(sourceTagVisitor); //now combine the two maps before conflation MapProjector::projectToWgs84(cumulativeMap); MapProjector::projectToWgs84(unknown2Map); cumulativeMap->append(unknown2Map); //load in cached reviews from previous conflations - I believe this is necessary, b/c the //UnifyingConflator is ignoring any incoming reviews by design (need to verify this). It //could be argued that modifying it to optionally retain the reviews is a better design //than the caching going on here... if (reviewCache.get() && reviewCache->getElementCount() > 0) { LOG_DEBUG("Adding previous reviews..."); const RelationMap& reviews = reviewCache->getRelations(); for (RelationMap::const_iterator it = reviews.begin(); it != reviews.end(); ++it) { RelationPtr review = it->second; review->setId(cumulativeMap->createNextRelationId()); cumulativeMap->addRelation(review); } LOG_DEBUG("Added " << reviews.size() << " cached reviews."); } NamedOp(ConfigOptions().getConflatePreOps()).apply(cumulativeMap); UnifyingConflator().apply(cumulativeMap); //going to apply this at the end of all conflation jobs, but maybe we'll find out later that //it needs to be done here instead (?) //NamedOp(ConfigOptions().getConflatePostOps()).apply(cumulativeMap); if (i < inputs.size() - 1) { //Up until just before the last conflate job, set the status tag back to 1 so that the //accumulated data will conflate with the next dataset. //there is a bug here that will affect river conflation in that somehow hoot:status=3 //tags are being left in at some point which causes the SearchRadiusCalculator to skip the //features. LOG_DEBUG("Setting status tags for map " << QString::number(i + 1) << "..."); SetTagValueVisitor statusTagVisitor( MetadataTags::HootStatus(), QString("%1").arg(Status(Status::Unknown1).getEnum())); cumulativeMap->visitRw(statusTagVisitor); } //copy the map and save the reviews LOG_DEBUG("Caching reviews..."); reviewCache.reset(new OsmMap(cumulativeMap->getProjection())); KeepReviewsVisitor vis; reviewCache->visitRw(vis); LOG_DEBUG("Cached " << reviewCache->getElementCount() << " reviews."); } } NamedOp(ConfigOptions().getConflatePostOps()).apply(cumulativeMap); MapProjector::projectToWgs84(cumulativeMap); OsmMapWriterFactory::write(cumulativeMap, output); }