@Test public void testRemove() { Scenario s = ScenarioUtils.createScenario(ConfigUtils.createConfig()); LinkQuadTree qt = new LinkQuadTree(0, 0, 1000, 1000); Link l13 = createLink(s, 0, 1000, 400, 400); Link l23 = createLink(s, 1000, 1000, 400, 400); Link l53 = createLink(s, 0, 0, 400, 400); Link l63 = createLink(s, 1000, 0, 400, 400); qt.put(l13); qt.put(l23); qt.put(l53); qt.put(l63); Assert.assertEquals(l13, qt.getNearest(100, 800)); qt.remove(l13); Assert.assertEquals(l23, qt.getNearest(100, 800)); }
private static double calcLineSegmentDistanceIndicator(final double x, final double y, final Link link) { double fx = link.getFromNode().getCoord().getX(); double fy = link.getFromNode().getCoord().getY(); double lineDX = link.getToNode().getCoord().getX() - fx; double lineDY = link.getToNode().getCoord().getY() - fy; if ((lineDX == 0.0) && (lineDY == 0.0)) { // the line segment is a point without dimension return calcDistanceIndicator(fx, fy, x, y); } double u = ((x - fx)*lineDX + (y - fy)*lineDY) / (lineDX*lineDX + lineDY*lineDY); if (u <= 0) { // (x | y) is not on the line segment, but before lineFrom return calcDistanceIndicator(fx, fy, x, y); } if (u >= 1) { // (x | y) is not on the line segment, but after lineTo return calcDistanceIndicator(fx + lineDX, fy + lineDY, x, y); } return calcDistanceIndicator(fx + u*lineDX, fy + u*lineDY, x, y); }
@Test public void testGetNearest() { Scenario s = ScenarioUtils.createScenario(ConfigUtils.createConfig()); LinkQuadTree qt = new LinkQuadTree(0, 0, 2000, 2000); Link foo = createLink(s, 100, 200, 800, 500); Link bar = createLink(s, 400, 300, 500, 400); Link fbr = createLink(s, 800, 1400, 1400, 800); Link a = createLink(s, 1100, 1100, 1200, 1200); Link b = createLink(s, 1100, 1100, 1200, 1100); Link c = createLink(s, 1200, 1200, 1200, 1100); qt.put(foo); qt.put(bar); qt.put(fbr); qt.put(a); qt.put(b); qt.put(c); Assert.assertEquals(foo, qt.getNearest(200, 200)); Assert.assertEquals(foo, qt.getNearest(300, 300)); Assert.assertEquals(bar, qt.getNearest(390, 300)); Assert.assertEquals(fbr, qt.getNearest(1000, 1100)); Assert.assertEquals(foo, qt.getNearest(-50, -50)); Assert.assertEquals(a, qt.getNearest(1105, 1104)); Assert.assertEquals(a, qt.getNearest(1105, 1103)); Assert.assertEquals(b, qt.getNearest(1105, 1102)); Assert.assertEquals(b, qt.getNearest(1105, 1101)); Assert.assertEquals(c, qt.getNearest(1205, 1101)); }
double linkMinY = Math.min(link.getFromNode().getCoord().getY(), link.getToNode().getCoord().getY()); double linkMaxY = Math.max(link.getFromNode().getCoord().getY(), link.getToNode().getCoord().getY()); if (Double.isInfinite(this.linkQuadTree.getMinEasting())) { } else if (this.linkQuadTree.getMinEasting() <= linkMinX && this.linkQuadTree.getMaxEasting() > linkMaxX && this.linkQuadTree.getMinNorthing() <= linkMinY && this.linkQuadTree.getMaxNorthing() > linkMaxY) { this.linkQuadTree.put(link); } else {
synchronized private void buildLinkQuadTree() { if (this.linkQuadTree != null) { return; } double startTime = System.currentTimeMillis(); double minx = Double.POSITIVE_INFINITY; double miny = Double.POSITIVE_INFINITY; double maxx = Double.NEGATIVE_INFINITY; double maxy = Double.NEGATIVE_INFINITY; for (Node n : this.nodes.values()) { if (n.getCoord().getX() < minx) { minx = n.getCoord().getX(); } if (n.getCoord().getY() < miny) { miny = n.getCoord().getY(); } if (n.getCoord().getX() > maxx) { maxx = n.getCoord().getX(); } if (n.getCoord().getY() > maxy) { maxy = n.getCoord().getY(); } } minx -= 1.0; miny -= 1.0; maxx += 1.0; maxy += 1.0; // yy the above four lines are problematic if the coordinate values are much smaller than one. kai, oct'15 log.info("building LinkQuadTree for nodes: xrange(" + minx + "," + maxx + "); yrange(" + miny + "," + maxy + ")"); LinkQuadTree qt = new LinkQuadTree(minx, miny, maxx, maxy); for (Link l : this.links.values()) { qt.put(l); } this.linkQuadTree = qt; log.info("Building LinkQuadTree took " + ((System.currentTimeMillis() - startTime) / 1000.0) + " seconds."); }
@Override public Link getNearestLinkExactly(final Coord coord) { if (this.linkQuadTree == null) { buildLinkQuadTree(); } return this.linkQuadTree.getNearest(coord.getX(), coord.getY()); }
@Override public Link removeLink(final Id<Link> linkId) { Link l = this.links.remove(linkId); if (l == null) { return null; } l.getFromNode().removeOutLink(l.getId()) ; l.getToNode().removeInLink(l.getId()) ; if (this.linkQuadTree != null) { this.linkQuadTree.remove(l); } return l; }
LinkQuadTree qt = new LinkQuadTree(0, 0, 2000, 2000); Link a = createLink(s, 500, 200, 700, 200); Link b = createLink(s, 100, 100, 900, 100); qt.put(a); qt.put(b); Assert.assertEquals(b, qt.getNearest(600, 0)); Assert.assertEquals(a, qt.getNearest(600, 210)); Assert.assertEquals(b, qt.getNearest(300, 210)); // outside of segment (1)-(2), thus (3)-(4) is closer Assert.assertEquals(a, qt.getNearest(400, 210)); // distance to (1) is smaller than to (3)-(4)
/** * Test for MATSIM-687: links not stored in top-node are not removed */ @Test public void testRemove_inSubNode() { Scenario s = ScenarioUtils.createScenario(ConfigUtils.createConfig()); LinkQuadTree qt = new LinkQuadTree(0, 0, 1000, 1000); Link lInTop1 = createLink(s, 400, 400, 600, 600); Link lInChildSW1 = createLink(s, 0, 0, 400, 400); qt.put(lInTop1); qt.put(lInChildSW1); Assert.assertEquals(lInChildSW1, qt.getNearest(100, 80)); qt.remove(lInChildSW1); Assert.assertEquals(lInTop1, qt.getNearest(100, 80)); }
LinkQuadTree qt = new LinkQuadTree(0, 0, 1000, 1000); Link l13 = createLink(s, 0, 1000, 400, 400); Link l23 = createLink(s, 1000, 1000, 400, 400); Link l43 = createLink(s, 400, 400, 400, 400); Link l34 = createLink(s, 400, 400, 400, 400); qt.put(l13); qt.put(l23); qt.put(l53); qt.put(l63); qt.put(l43); qt.put(l34); Assert.assertEquals(l13, qt.getNearest(100, 800));