Skip to content

v0.2.55..v0.2.56 changeset Line.js

Garret Voltz edited this page Aug 14, 2020 · 3 revisions
diff --git a/rules/Line.js b/rules/Line.js
index 461b8ac..bd1eaf1 100644
--- a/rules/Line.js
+++ b/rules/Line.js
@@ -28,9 +28,18 @@ var angleHistogramExtractor = new hoot.AngleHistogramExtractor();
 var weightedShapeDistanceExtractor = new hoot.WeightedShapeDistanceExtractor();
 var distanceScoreExtractor = new hoot.DistanceScoreExtractor();
 var lengthScoreExtractor = new hoot.LengthScoreExtractor();
-var sublineMatcher = new hoot.MaximalSublineStringMatcher({
+var sublineMatcher =  // default subline matcher
+  new hoot.MaximalSublineStringMatcher(
+  {
     "way.matcher.max.angle": hoot.get("generic.line.matcher.max.angle"),
-    "way.subline.matcher": hoot.get("generic.line.subline.matcher")});
+    "way.subline.matcher": hoot.get("generic.line.subline.matcher"),
+    // borrowing this from rivers for the time being; TODO: make separate option for it?
+    "maximal.subline.max.recursive.complexity": hoot.get("waterway.maximal.subline.max.recursive.complexity")
+  });
+var frechetSublineMatcher = // we'll switch over to this one if the default matcher runs too slowly
+  new hoot.MaximalSublineStringMatcher(
+    { "way.matcher.max.angle": hoot.get("waterway.matcher.max.angle"),
+      "way.subline.matcher": "hoot::FrechetSublineMatcher" }); 
 
 /**
  * Returns true if e is a candidate for a match. Implementing this method is
@@ -39,12 +48,21 @@ var sublineMatcher = new hoot.MaximalSublineStringMatcher({
  */
 exports.isMatchCandidate = function(map, e)
 {
-  // Even though a route relation passes the linear crit, we want only highway or rail
-  // conflation to conflate it.
+  hoot.trace("e: " + e.getElementId());
+  // Even though a route relation passes the linear crit, we want only highway or rail conflation to conflate it.
   if (e.getElementId().getType() == "Relation" && e.getTags().contains("route"))
   {
     return false;
   }
+  // This prevents some of the problems seen in #4149. It should be removed after that issue is fixed.
+  else if (e.getElementId().getType() == "Way" && !hasType(e) &&
+           isMemberOfRelationSatisfyingCriterion(map, e.getElementId(), "hoot::CollectionRelationCriterion"))
+  {
+    return false;
+  }
+
+  hoot.trace("isLinear: " + isLinear(e));
+  hoot.trace("isSpecificallyConflatable: " + isSpecificallyConflatable(map, e, exports.geometryType));
   return isLinear(e) && !isSpecificallyConflatable(map, e, exports.geometryType);
 };
 
@@ -79,19 +97,19 @@ exports.matchScore = function(map, e1, e2)
     return result;
   }
 
-  hoot.trace("e1: " + e1.getId() + ", " + e1.getTags().get("name"));
+  hoot.trace("e1: " + e1.getElementId() + ", " + e1.getTags().get("name"));
+  //hoot.trace("e1: " + e1);
   if (e1.getTags().get("note"))
   {
     hoot.trace("e1 note: " + e1.getTags().get("note"));
   }
-  hoot.trace("e2: " + e2.getId() + ", " + e2.getTags().get("name"));
+  hoot.trace("e2: " + e2.getElementId() + ", " + e2.getTags().get("name"));
+  //hoot.trace("e2: " + e2);
   if (e2.getTags().get("note"))
   {
     hoot.trace("e2 note: " + e2.getTags().get("note"));
   }
 
-  // TODO: Should we do anything with names?
-
   // If both features have types and they aren't just generic types, let's do a detailed type comparison and 
   // look for an explicit type mismatch. Otherwise, move on to the geometry comparison.
   var typeScorePassesThreshold = !explicitTypeMismatch(e1, e2, exports.tagThreshold);
@@ -100,9 +118,21 @@ exports.matchScore = function(map, e1, e2)
   {
     return result;
   }
+  hoot.trace("mostSpecificType(e1): " + mostSpecificType(e1));
+  hoot.trace("mostSpecificType(e2): " + mostSpecificType(e2));
+
+  // extract the sublines needed for matching - Note that some of this was taken from Highway.js and other parts 
+  // from River.js. See notes on the dual subline matcher approach in River.js.
+  var sublines;
+  hoot.trace("Extracting sublines with default...");
+  sublines = sublineMatcher.extractMatchingSublines(map, e1, e2);
+  hoot.trace(sublines);
+  if (sublines && sublines == "RecursiveComplexityException")
+  {
+    hoot.trace("Extracting sublines with Frechet...");
+    sublines = frechetSublineMatcher.extractMatchingSublines(map, e1, e2);
+  }
 
-  // extract the sublines needed for matching - Note that this was taken directly from Highway.js.
-  var sublines = sublineMatcher.extractMatchingSublines(map, e1, e2);
   var distanceScore = -1.0;
   var weightShapeDistanceScore = -1.0;
   var lengthScore = -1.0;
@@ -112,6 +142,7 @@ exports.matchScore = function(map, e1, e2)
     var m = sublines.map;
     var m1 = sublines.match1;
     var m2 = sublines.match2;
+    hoot.trace("Scoring distance and length...");
     distanceScore = distanceScoreExtractor.extract(m, m1, m2);
     weightShapeDistanceScore = weightedShapeDistanceExtractor.extract(m, m1, m2);
     lengthScore = lengthScoreExtractor.extract(m, m1, m2);
@@ -154,10 +185,9 @@ exports.matchScore = function(map, e1, e2)
  */
 exports.mergeSets = function(map, pairs, replaced) 
 {
-  // snap the ways in the second input to the first input. Use the default tag 
-  // merge method.
-  var result = snapWays(sublineMatcher, map, pairs, replaced, exports.baseFeatureType);
-  return result;
+  // Snap the ways in the second input to the first input. Use the default tag 
+  // merge method. See related notes in exports.mergeSets in River.js.
+  return snapWays2(sublineMatcher, map, pairs, replaced, exports.baseFeatureType, frechetSublineMatcher);
 };
 
 exports.getMatchFeatureDetails = function(map, e1, e2)
Clone this wiki locally