virtual void visit(const ConstElementPtr& e) { QStringList refs; if (e->getTags().contains("REF1")) { e->getTags().readValues("REF1", refs); refs.removeAll("todo"); refs.removeAll("none"); if (refs.size() > 0) { // Find the REF1 id's in REF2. // NOTE: this blindly assumes that there is only ONE value in the REF1 tag list RefToEidVisitor::RefToEid::const_iterator refId = _refSet.find(refs[0]); if (refId != _refSet.end()) { // Loop through the element Id's in REF2 for (set<ElementId>::const_iterator eid = refId->second.begin(); eid != refId->second.end(); ++eid) { // Loop through the Tags in REF1 for (Tags::const_iterator tag1 = e->getTags().begin(); tag1 != e->getTags().end(); ++tag1 ) { QString kvp1 = OsmSchema::getInstance().toKvp(tag1.key(),tag1.value()); // We are only looking at Enumerated tags if (OsmSchema::getInstance().getTagVertex(kvp1).valueType == hoot::Enumeration) { // Get the value from the corresponding tag in REF2 QString kvp2 = OsmSchema::getInstance().toKvp(tag1.key(), _map->getElement(*eid)->getTags()[tag1.key()]); // LOG_INFO("Got Tags:" + kvp1 + " " + kvp2); _coOccurence[kvp1][kvp2]++; } } // End for REF1 tag list // now loop through the REF2 tag list and fill in any missing tags. for (Tags::const_iterator tag2 = _map->getElement(*eid)->getTags().begin(); tag2 != _map->getElement(*eid)->getTags().end(); ++tag2 ) { QString kvp2 = OsmSchema::getInstance().toKvp(tag2.key(),tag2.value()); // Skip the tags that are common if (e->getTags().contains(tag2.key())) continue; if (OsmSchema::getInstance().getTagVertex(kvp2).valueType == hoot::Enumeration) { // "Missing" == "" tag value QString kvp1 = OsmSchema::getInstance().toKvp(tag2.key(),""); // LOG_INFO("Got Tags:" + kvp1 + " " + kvp2); _coOccurence[kvp1][kvp2]++; } } // End for REF2 tag list // now try matching up the "name" fields QString name1 = e->getTags()["name"]; QString name2 = _map->getElement(*eid)->getTags()["name"]; QString kvpNull = OsmSchema::getInstance().toKvp("name","<NULL>"); QString kvpNonNull = OsmSchema::getInstance().toKvp("name","<NON NULL>"); QString kvpSame = OsmSchema::getInstance().toKvp("name","<SIMILAR>"); if (name1 == "") { if (name2 == "") { _coOccurence[kvpNull][kvpNull]++; } else { _coOccurence[kvpNull][kvpNonNull]++; } } else if (name2 == "") { _coOccurence[kvpNonNull][kvpNull]++; } else { // Check if the names match double nameScore = _calculateNameScore(e, _map->getElement(*eid)); bool nameMatch = nameScore >= ConfigOptions().getPoiPolygonMatchNameThreshold(); if (nameMatch) { _coOccurence[kvpSame][kvpSame]++; } else { _coOccurence[kvpNonNull][kvpNonNull]++; } } } // End for ref2 Element ID's } // End refId != End } // End refs > 0 } // End contains "REF1" } // End Visit
PoiPolygonMatch::PoiPolygonMatch(const ConstOsmMapPtr& map, const ElementId& eid1, const ElementId& eid2, ConstMatchThresholdPtr threshold) : Match(threshold) { ConstElementPtr e1 = map->getElement(eid1); ConstElementPtr e2 = map->getElement(eid2); ConstElementPtr poi, poly; if (isPoiIsh(e1) && isBuildingIsh(e2)) { _poiEid = eid1; _polyEid = eid2; poi = e1; poly = e2; } else if (isPoiIsh(e2) && isBuildingIsh(e1)) { _poiEid = eid2; _polyEid = eid1; poi = e2; poly = e1; } else { LOG_WARN(e1->toString()); LOG_WARN(e2->toString()); throw IllegalArgumentException("Expected a POI & polygon, got: " + eid1.toString() + " " + eid2.toString()); } shared_ptr<Geometry> gpoly = ElementConverter(map).convertToGeometry(poly); shared_ptr<Geometry> gpoi = ElementConverter(map).convertToGeometry(poi); bool typeMatch = _calculateTypeMatch(poi, poly); double nameScore = _calculateNameScore(poi, poly); bool nameMatch = nameScore >= ConfigOptions().getPoiPolygonMatchNameThreshold(); double distance = gpoly->distance(gpoi.get()); // calculate the 2 sigma for the distance between the two objects double sigma1 = e1->getCircularError() / 2.0; double sigma2 = e1->getCircularError() / 2.0; double ce = sqrt(sigma1 * sigma1 + sigma2 * sigma2) * 2; double reviewDistance = ConfigOptions().getPoiPolygonMatchReviewDistance() + ce; bool closeMatch = distance <= reviewDistance; int evidence = 0; evidence += typeMatch ? 1 : 0; evidence += nameMatch ? 1 : 0; evidence += distance == 0 ? 2 : 0; if (!closeMatch) { _c.setMiss(); } else if (evidence >= 3) { _c.setMatch(); } else if (evidence >= 1) { _c.setReview(); } else { _c.setMiss(); } }