Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible lost matches #9

Open
echeipesh opened this issue Sep 3, 2019 · 0 comments
Open

Possible lost matches #9

echeipesh opened this issue Sep 3, 2019 · 0 comments
Labels

Comments

@echeipesh
Copy link
Collaborator

There is a logical mistake in the match algorithm:

  1. First possible matches are computed using straight intersection
  2. OSM buildings containing Bing building centroid are considered matched
  3. OSM buildings overlapping by 75% of area with Bing building are matched
  4. OSM buildings failing that check are dropped from output set

Relevant bloc:

case (Some(msftBuildings), Some(osmBuildings)) => {
val msftSet = msftBuildings.toSet
val osmSet = osmBuildings.toSet
val osmPossibleMatches = scala.collection.mutable.Set[FeatureWithId]()
val msftPossibleMatches = scala.collection.mutable.Set[FeatureWithId]()
// First limit comparisons to only geometries that could possibly match
msftSet.foreach { msftBuilding =>
osmSet.foreach { osmBuilding =>
if (msftBuilding.geom.intersects(osmBuilding.geom)) {
osmPossibleMatches += osmBuilding
msftPossibleMatches += msftBuilding
}
}
}
// Construct feature sets where there are no matches
val osmNoMatches = (osmSet -- osmPossibleMatches).toList
val msftNoMatches = (msftSet -- msftPossibleMatches).toList
// Loop osm buildings and check if any bing footprint contains the osm centroid. If so, a match!
// Note that this algorithm implies a one to many relationship for bing to osm buildings. One
// bing building can match many osm buildings. Which is fine because in most cases the bing
// satellite detected polygon is larger and less precise than the actual OSM building.
val msftPossibleMatchesList = msftPossibleMatches.toList
val matches = new ListBuffer[FeatureWithId]()
osmPossibleMatches.foreach { osmFeature =>
val isMatched = msftPossibleMatchesList.exists { msftFeature =>
msftFeature.geom.jtsGeom.contains(osmFeature.geom.jtsGeom.getCentroid)
}
if (isMatched) {
matches += FeatureWithId(osmFeature.id, osmFeature.geom, osmFeature.data ++ Map("source" -> "both"))
}
}
// Remove successful matches in last step from consideration
osmPossibleMatches --= matches
// Attempt 1 to 1 area intersection ratio check with remaining geometries
osmPossibleMatches.foreach { osmFeature =>
val isMatched = msftPossibleMatchesList.exists { msftFeature =>
(msftFeature.geom.as[Polygon], osmFeature.geom.as[Polygon]) match {
case (Some(msftPoly), Some(osmPoly)) => {
if (msftPoly.isValid && osmPoly.isValid) {
val AREA_THRESHOLD = 0.75
msftFeature.geom.intersection(osmFeature.geom) match {
case PolygonResult(p) => if (p.area / msftPoly.area > AREA_THRESHOLD) true else false
case MultiPolygonResult(p) => if (p.area / msftPoly.area > AREA_THRESHOLD) true else false
case _ => false
}
} else {
false
}
}
case _ => false
}
}
if (isMatched) {
matches += FeatureWithId(osmFeature.id, osmFeature.geom, osmFeature.data ++ Map("source" -> "both"))
}
}
// Return all output plus any remaining unmatched OSM geometries
msftNoMatches ++ osmNoMatches ++ matches

This if needs an else:

if (isMatched) {
matches += FeatureWithId(osmFeature.id, osmFeature.geom, osmFeature.data ++ Map("source" -> "both"))
}

@echeipesh echeipesh added the bug label Sep 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant