Esempio n. 1
0
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);
  }
Esempio n. 3
0
	// Get parent of relation D3MetaDatabase
	//
	D3MetaDatabasePtr D3DatabasePermissionBase::GetD3MetaDatabase()
	{
		RelationPtr		pRelation;

		pRelation = GetParentRelation(D3MDDB_D3DatabasePermission_PR_D3MetaDatabase);

		if (!pRelation)
			return NULL;

		return (D3MetaDatabasePtr) pRelation->GetParent();
	}
Esempio n. 4
0
	// Get parent of relation D3MetaColumn
	//
	D3MetaColumnPtr D3ColumnPermissionBase::GetD3MetaColumn()
	{
		RelationPtr		pRelation;

		pRelation = GetParentRelation(D3MDDB_D3ColumnPermission_PR_D3MetaColumn);

		if (!pRelation)
			return NULL;

		return (D3MetaColumnPtr) pRelation->GetParent();
	}
Esempio n. 5
0
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);
    }
  }
}
Esempio n. 6
0
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);
  }
}
Esempio n. 8
0
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());
  }
Esempio n. 10
0
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();
    }
  }
Esempio n. 12
0
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);
  }
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
 foreach (RelationPtr s, objectStore()->getObjects<Relation>()) {
   s->save(xml);
 }
Esempio n. 18
0
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);
}