void RubberSheet::applyTransform(shared_ptr<OsmMap>& map) { _map = map; if (!_interpolator2to1) { LOG_WARN("No appropriate interpolator was specified, skipping rubber sheet transform."); return; } if (_projection.get() != 0) { MapReprojector::reproject(_map, _projection); } else { // if it is already planar then nothing will be done. MapReprojector::reprojectToPlanar(_map); } const OsmMap::NodeMap& nm = map->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nm.constBegin(); it != nm.constEnd(); ++it) { const shared_ptr<Node>& n = it.value(); if (_ref == false || n->getStatus() == Status::Unknown2) { Coordinate c = n->toCoordinate(); Coordinate newC = _translate(c, n->getStatus()); n->setX(newC.x); n->setY(newC.y); } } }
void _buildIndex() { LOG_DEBUG(SystemInfo::getMemoryUsageString()); LOG_DEBUG("Creating index. (node count: " << _map->getNodeMap().size() << ")"); vector<TreeKey> keys; vector<long> nids; // reserve some space to reduce reallocs keys.reserve(_map->getNodeMap().size() * 2); nids.reserve(_map->getNodeMap().size() * 2); for (OsmMap::NodeMap::const_iterator it = _map->getNodeMap().begin(); it != _map->getNodeMap().end(); ++it) { const shared_ptr<const Node>& n = it.value(); set<QString> allNames = _getNamePermutations(n->getTags().getNames()); for (set<QString>::iterator it = allNames.begin(); it != allNames.end(); ++it) { TreeKey tk(n->toCoordinate(), *it); keys.push_back(tk); nids.push_back(n->getId()); } } LOG_DEBUG(SystemInfo::getMemoryUsageString()); LOG_DEBUG("Calling build index."); _index.reset(new hybrid::RFqHybridTree<TreeKey, long, LevenshteinDistance>()); _index->buildIndex(keys, nids); LOG_DEBUG("Built index with " << keys.size() << " keys and " << _map->getNodeMap().size() << " nodes."); LOG_DEBUG(SystemInfo::getMemoryUsageString()); }
void WayJoin1Mapper::_map(shared_ptr<OsmMap>& m, HadoopPipes::MapContext& context) { LOG_INFO("Starting map"); string keyStr; string valueStr; keyStr.resize(sizeof(int64_t)); int64_t* key = (int64_t*)keyStr.data(); // Remove all non-roads. m->removeWays(TagFilter(Filter::FilterMatches, "highway", "")); Debug::printTroubled(m); // emit the node's ID as the key and x/y as the value. valueStr.resize(sizeof(ValueNode)); ValueNode* valueNode = (ValueNode*)valueStr.data(); const OsmMap::NodeMap& nm = m->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nm.constBegin(); it != nm.constEnd(); ++it) { const shared_ptr<const Node>& n = it.value(); *key = n->getId(); valueNode->x = n->getX(); valueNode->y = n->getY(); context.emit(keyStr, valueStr); } // emit the way's nodes as the key and the way's id as the value. valueStr.resize(sizeof(ValueWay)); ValueWay* valueWay = (ValueWay*)valueStr.data(); const WayMap& wm = m->getWays(); for (WayMap::const_iterator it = wm.begin(); it != wm.end(); ++it) { const shared_ptr<const Way>& w = it->second; valueWay->id = w->getId(); const std::vector<long>& nids = w->getNodeIds(); for (size_t i = 0; i < nids.size(); i++) { *key = nids[i]; context.emit(keyStr, valueStr); } } }
bool Debug::printTroubled(const shared_ptr<const OsmMap>& map) { bool result = false; const OsmMap::NodeMap& nm = map->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nm.constBegin(); it != nm.constEnd(); ++it) { const shared_ptr<Node>& n = it.value(); if (isTroubledNode(n->getId())) { LOG_WARN("Found troubled node: " << n->toString()); result = true; } } const WayMap& wm = map->getWays(); for (WayMap::const_iterator it = wm.begin(); it != wm.end(); ++it) { const shared_ptr<Way>& w = it->second; if (isTroubledWay(w->getId())) { LOG_WARN("Found troubled way: " << w->toString()); result = true; } else { vector<long> troubled; const vector<long>& nids = w->getNodeIds(); for (size_t i = 0; i < nids.size(); i++) { if (isTroubledNode(nids[i])) { troubled.push_back(nids[i]); } } if (troubled.size() > 0) { LOG_WARN("Found a way with troubled node(s): " << w->toString()); LOG_WARN(" troubled nodes: " << troubled); result = true; } } } return result; }
void PointsToTracksOp::apply(shared_ptr<OsmMap>& map) { HashMap<QString, deque<long> > trackIdToNid; const OsmMap::NodeMap& nm = map->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nm.begin(); it != nm.end(); ++it) { if (it.value()->getTags().contains("hoot:track:id") && it.value()->getTags().contains("hoot:track:seq")) { QString trackId = it.value()->getTags()["hoot:track:id"]; trackIdToNid[trackId].push_back(it.key()); } } _sortTracks(map, trackIdToNid); _createWays(map, trackIdToNid); }
void WayJoin2Mapper::mapOsmMap(shared_ptr<OsmMap> m) { // The first byte on the value says if it is a PBF/WayJoin1Reducer::Value PbfWriter writer; // Remove all non-roads. m->removeWays(TagFilter(Filter::FilterMatches, "highway", "")); _key->elementType = NodesType; // Go through all the nodes const OsmMap::NodeMap& nm = m->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nm.constBegin(); it != nm.constEnd(); ++it) { // add this node onto a map. Since the nodes aren't very important at this stage we'll just // ship a bunch at a time in one big record. _emitNode(it.value()); } _key->elementType = WayType; // Go through all the ways const WayMap& wm = m->getWays(); for (WayMap::const_iterator it = wm.begin(); it != wm.end(); ++it) { const shared_ptr<const Way>& w = it->second; _key->id = w->getId(); stringstream ss(stringstream::out); pp::DataOutputStream dos(ss); //LOG_INFO("Writing way: " << _key->id); dos.writeByte(PbfData); writer.writePb(w, &ss); // Emit the way _context->emit(_keyStr, ss.str()); } }
v8::Handle<v8::Value> PoiMergerJs::jsPoiMerge(const v8::Arguments& args) { HandleScope scope; try{ if (args.Length() != 2) { return v8::ThrowException(HootExceptionJs::create(IllegalArgumentException( "Expected exactly two arguments to 'poiMerge'."))); } // Argument 1: script -- note second param is directory to search under (~/hoot/rules) const QString scriptPath = ConfPath::search(toCpp<QString>(args[0]), "rules"); // Argument 2: Map with POIs OsmMapJs* mapJs = node::ObjectWrap::Unwrap<OsmMapJs>(args[1]->ToObject()); // Pull out internal POI map OsmMapPtr map( mapJs->getMap() ); // Instantiate script merger shared_ptr<PluginContext> script(new PluginContext()); v8::HandleScope handleScope; v8::Context::Scope context_scope(script->getContext()); script->loadScript(scriptPath, "plugin"); v8::Handle<v8::Object> global = script->getContext()->Global(); if (global->Has(String::New("plugin")) == false) { return v8::ThrowException(HootExceptionJs::create(IllegalArgumentException( "Expected the script to have exports."))); } v8::Handle<v8::Value> pluginValue = global->Get(String::New("plugin")); v8::Persistent<v8::Object> plugin = v8::Persistent<v8::Object>::New(v8::Handle<v8::Object>::Cast(pluginValue)); if (plugin.IsEmpty() || plugin->IsObject() == false) { return v8::ThrowException(HootExceptionJs::create(IllegalArgumentException( "Expected plugin to be a valid object."))); } // Got in Map with POIs A, B, C, D, E // // Make a set of pairs to indicate all are same object: // A->B, A->C, A->D, A->E // // ...then pass those pairs one at a time through the merger, since it only merges pairs OsmMap::NodeMap nodes = map->getNodeMap(); OsmMapPtr mergedMap(map); const ElementId firstId = ElementId::node((*(nodes.constBegin()))->getId()); //LOG_DEBUG("First ID: " << firstId.getId()); for (OsmMap::NodeMap::const_iterator it = nodes.constBegin() + 1; it != nodes.constEnd(); ++it) { const boost::shared_ptr<const Node>& n = it.value(); std::set< std::pair< ElementId, ElementId> > matches; matches.insert(std::pair<ElementId,ElementId>(firstId, ElementId::node(n->getId()))); // Now create scriptmerger, and invoke apply method which will apply apply merge transformation, reducing the POIs down to one ScriptMerger merger(script, plugin, matches); OsmMapPtr mergedMap(map); std::vector< std::pair< ElementId, ElementId > > replacedNodes; merger.apply(mergedMap, replacedNodes ); if ( replacedNodes.size() == 1 ) { /* LOG_DEBUG("POI merge: replacing node #" << replacedNodes[0].first.getId() << " with updated version of node #" << replacedNodes[0].second.getId() ); */ mergedMap->replaceNode(replacedNodes[0].first.getId(), replacedNodes[0].second.getId()); } } // Hand merged POIs back to caller in OsmMap v8::Handle<v8::Object> returnMap = OsmMapJs::create(mergedMap); return scope.Close(returnMap); } catch ( const HootException& e ) { return v8::ThrowException(HootExceptionJs::create(e)); } }
void MergeNearbyNodes::apply(shared_ptr<OsmMap>& map) { LOG_INFO("MergeNearbyNodes start"); QTime time; time.start(); shared_ptr<OsmMap> wgs84; shared_ptr<OsmMap> planar; if (MapReprojector::isGeographic(map)) { wgs84 = map; planar.reset(new OsmMap(map)); MapReprojector::reprojectToPlanar(planar); } else { planar = map; // if we need to check for bounds containment if (_bounds.isNull() == false) { wgs84.reset(new OsmMap(map)); MapReprojector::reprojectToWgs84(wgs84); } } ClosePointHash cph(_distance); const OsmMap::NodeMap& nodes = planar->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nodes.begin(); it != nodes.end(); it++) { const shared_ptr<Node>& n = it.value(); cph.addPoint(n->getX(), n->getY(), n->getId()); } int mergeCount = 0; int count = 0; cph.resetIterator(); while (cph.next()) { const vector<long>& v = cph.getMatch(); for (size_t i = 0; i < v.size(); i++) { for (size_t j = 0; j < v.size(); j++) { if (v[i] != v[j] && map->containsNode(v[i]) && map->containsNode(v[j])) { const shared_ptr<Node>& n1 = planar->getNode(v[i]); const shared_ptr<Node>& n2 = planar->getNode(v[j]); double d = calcDistance(n1, n2); if (d < _distance && n1->getStatus() == n2->getStatus()) { bool replace = false; // if the geographic bounds are not specified. if (_bounds.isNull() == true) { replace = true; } // if the geographic bounds are specified, then make sure both points are inside. else { const shared_ptr<Node>& g1 = wgs84->getNode(v[i]); const shared_ptr<Node>& g2 = wgs84->getNode(v[j]); if (_bounds.contains(g1->getX(), g1->getY()) && _bounds.contains(g2->getX(), g2->getY())) { replace = true; } } if (replace) { map->replaceNode(v[j], v[i]); mergeCount++; } } } } } if (Log::getInstance().isInfoEnabled() && count % 1000 == 0) { cout << "MergeNearbyNodes " << count << " " << mergeCount << " \r"; cout.flush(); } count++; } if (Log::getInstance().isInfoEnabled()) { cout << "MergeNearbyNodes " << nodes.size() << " elapsed: " << time.elapsed() << "ms \n"; } }
void ShapefileWriter::writePoints(shared_ptr<const OsmMap> map, const QString& path) { OGRRegisterAll(); _removeShapefile(path); const char *pszDriverName = "ESRI Shapefile"; OGRSFDriver *poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName); if( poDriver == NULL ) { throw HootException(QString("%1 driver not available.").arg(pszDriverName)); } OGRDataSource* poDS = poDriver->CreateDataSource(path.toAscii(), NULL ); if( poDS == NULL ) { throw HootException(QString("Data source creation failed. %1").arg(path)); } OGRLayer *poLayer; QString layerName; layerName = QFileInfo(path).baseName(); poLayer = poDS->CreateLayer(layerName.toAscii(), map->getProjection().get(), wkbPoint, NULL ); if( poLayer == NULL ) { throw HootException(QString("Layer creation failed. %1").arg(path)); } QStringList shpColumns; QStringList columns = getColumns(map, ElementType::Node); for (int i = 0; i < columns.size(); i++) { OGRFieldDefn oField(columns[i].toAscii(), OFTString); oField.SetWidth(64); if( poLayer->CreateField( &oField ) != OGRERR_NONE ) { throw HootException(QString("Error creating field (%1).").arg(columns[i])); } shpColumns.append(poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()); } if (_includeInfo) { OGRFieldDefn oField("error_circ", OFTReal); if( poLayer->CreateField( &oField ) != OGRERR_NONE ) { throw HootException(QString("Error creating field (error:circular).")); } _circularErrorIndex = poLayer->GetLayerDefn()->GetFieldCount() - 1; } const OsmMap::NodeMap& nodes = map->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nodes.begin(); it != nodes.end(); ++it) { const shared_ptr<Node>& node = it.value(); if (node->getTags().getNonDebugCount() > 0) { OGRFeature* poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() ); // set all the column values. for (int i = 0; i < columns.size(); i++) { if (node->getTags().contains(columns[i])) { QByteArray c = shpColumns[i].toAscii(); QByteArray v = node->getTags()[columns[i]].toAscii(); poFeature->SetField(c.constData(), v.constData()); } } if (_includeInfo) { poFeature->SetField(_circularErrorIndex, node->getCircularError()); } // convert the geometry. OGRGeometry* geom = new OGRPoint(node->getX(), node->getY()); if (poFeature->SetGeometryDirectly(geom) != OGRERR_NONE) { throw HootException(QString("Error setting geometry")); } if (poLayer->CreateFeature(poFeature) != OGRERR_NONE) { throw HootException(QString("Error creating feature")); } OGRFeature::DestroyFeature(poFeature); } } OGRDataSource::DestroyDataSource(poDS); }
void MapCropper::apply(shared_ptr<OsmMap>& map) { LOG_INFO("Cropping map."); shared_ptr<OsmMap> result = map; if (MapReprojector::isGeographic(map) == false && _nodeBounds.isNull() == false) { throw HootException("If the node bounds is set the projection must be geographic."); } // @todo visit the elements from the most senior (e.g. relation that has no parents) to the // most junior (nodes). // go through all the ways const WayMap ways = result->getWays(); for (WayMap::const_iterator it = ways.begin(); it != ways.end(); it++) { const shared_ptr<Way>& w = it->second; shared_ptr<LineString> ls = ElementConverter(map).convertToLineString(w); const Envelope& e = *(ls->getEnvelopeInternal()); // if the way is completely outside the region we're keeping if (_isWhollyOutside(e)) { // remove the way result->removeWayFully(w->getId()); } else if (_isWhollyInside(e)) { // keep the way } else { // do an expensive operation to decide how much to keep, if any. _cropWay(result, w->getId()); } } shared_ptr<NodeToWayMap> n2wp = result->getIndex().getNodeToWayMap(); NodeToWayMap& n2w = *n2wp; LOG_INFO(" Removing nodes..."); // go through all the nodes const OsmMap::NodeMap nodes = result->getNodeMap(); for (OsmMap::NodeMap::const_iterator it = nodes.constBegin(); it != nodes.constEnd(); it++) { const Coordinate& c = it.value()->toCoordinate(); bool nodeInside = false; if (_envelope.isNull() == false) { if (_invert == false) { nodeInside = _envelope.covers(c); } else { nodeInside = !_envelope.covers(c); } } else { auto_ptr<Point> p(GeometryFactory::getDefaultInstance()->createPoint(c)); if (_invert == false) { nodeInside = _envelopeG->intersects(p.get()); } else { nodeInside = !_envelopeG->intersects(p.get()); } } // if the node is outside if (!nodeInside) { // if the node is within the limiting bounds. if (_nodeBounds.isNull() == true || _nodeBounds.contains(c)) { // if the node is not part of a way if (n2w.find(it.key()) == n2w.end()) { // remove the node result->removeNodeNoCheck(it.value()->getId()); } } } } RemoveEmptyRelationsVisitor v; map->visitRw(v); }