From 1c9496b60c477bb69b0f06ab732ed30303568ee3 Mon Sep 17 00:00:00 2001 From: Matthew Wigginton Conway Date: Mon, 30 Jan 2017 17:19:11 -0500 Subject: [PATCH 1/2] Buffer implied pointsets, and allow sub-pointsets to be uncontained by super pointsets (so that the non-transit component of a browsochrones search will not cause exceptions when undertaken near the edge of the graph, with part of the non-transit result grid outside the graph) --- .../r5/analyst/WebMercatorGridPointSet.java | 17 +++++++++++++---- .../com/conveyal/r5/streets/LinkedPointSet.java | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java b/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java index 7c72afd6d..7f001c181 100644 --- a/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java +++ b/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java @@ -1,10 +1,14 @@ package com.conveyal.r5.analyst; +import com.conveyal.r5.common.SphericalDistanceLibrary; import com.conveyal.r5.profile.StreetMode; import com.conveyal.r5.streets.LinkedPointSet; +import com.conveyal.r5.streets.Split; import com.conveyal.r5.streets.StreetLayer; +import com.conveyal.r5.transit.TransitLayer; import com.conveyal.r5.transit.TransportNetwork; import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Envelope; import org.mapdb.Fun; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,10 +54,15 @@ public WebMercatorGridPointSet(TransportNetwork transportNetwork) { LOG.info("Creating web mercator pointset for transport network with extents {}", transportNetwork.streetLayer.envelope); this.zoom = DEFAULT_ZOOM; - int west = lonToPixel(transportNetwork.streetLayer.envelope.getMinX()); - int east = lonToPixel(transportNetwork.streetLayer.envelope.getMaxX()); - int north = latToPixel(transportNetwork.streetLayer.envelope.getMaxY()); - int south = latToPixel(transportNetwork.streetLayer.envelope.getMinY()); + + double latBuffer = SphericalDistanceLibrary.metersToDegreesLatitude(TransitLayer.DISTANCE_TABLE_SIZE_METERS); + double lonBuffer = SphericalDistanceLibrary + .metersToDegreesLongitude(TransitLayer.DISTANCE_TABLE_SIZE_METERS, transportNetwork.streetLayer.envelope.centre().y); + + int west = lonToPixel(transportNetwork.streetLayer.envelope.getMinX() - lonBuffer); + int east = lonToPixel(transportNetwork.streetLayer.envelope.getMaxX() + lonBuffer); + int north = latToPixel(transportNetwork.streetLayer.envelope.getMaxY() + latBuffer); + int south = latToPixel(transportNetwork.streetLayer.envelope.getMinY() - latBuffer); this.west = west; this.north = north; diff --git a/src/main/java/com/conveyal/r5/streets/LinkedPointSet.java b/src/main/java/com/conveyal/r5/streets/LinkedPointSet.java index 8c8630e04..93cea8444 100644 --- a/src/main/java/com/conveyal/r5/streets/LinkedPointSet.java +++ b/src/main/java/com/conveyal/r5/streets/LinkedPointSet.java @@ -161,7 +161,9 @@ public LinkedPointSet(LinkedPointSet sourceLinkage, WebMercatorGridPointSet subG } if (superGrid.west > subGrid.west || superGrid.west + superGrid.width < subGrid.west + subGrid.width || superGrid.north > subGrid.north || superGrid.north + superGrid.height < subGrid.north + subGrid.height) { - throw new IllegalArgumentException("Sub-grid must lie fully inside the super-grid."); + // we simply warn if it does not lie within the super grid. This used to throw an error but that prevents + // analyses with origins near the edge of the graph. + LOG.warn("Part of sub-grid does not lie with super grid"); } // Initialize the fields of the new LinkedPointSet instance @@ -174,10 +176,22 @@ public LinkedPointSet(LinkedPointSet sourceLinkage, WebMercatorGridPointSet subG distances0_mm = new int[nCells]; distances1_mm = new int[nCells]; + // mark all points as unlinked, in case part of the subGrid lies outside the super grid. Points within the super + // grid will be overwritten below + Arrays.fill(edges, -1); + // Copy values over from the source linkage to the new sub-linkage // x, y, and pixel are relative to the new linkage for (int y = 0, pixel = 0; y < subGrid.height; y++) { + int row = subGrid.north + y; + boolean rowWithinSuperGrid = row >= superGrid.north && row < superGrid.north + superGrid.height; + if (!rowWithinSuperGrid) continue; + for (int x = 0; x < subGrid.width; x++, pixel++) { + int col = subGrid.west + x; + boolean colWithinSuperGrid = col >= superGrid.west && col < superGrid.west + superGrid.width; + if (!colWithinSuperGrid) continue; + int sourceColumn = subGrid.west + x - superGrid.west; int sourceRow = subGrid.north + y - superGrid.north; int sourcePixel = sourceRow * superGrid.width + sourceColumn; From 062a1a1ff4f4f81e7d4663472e4f4bfe521be85a Mon Sep 17 00:00:00 2001 From: Matthew Wigginton Conway Date: Mon, 30 Jan 2017 17:30:37 -0500 Subject: [PATCH 2/2] Use max offstreet walk not distance table size to buffer implied pointset. --- .../java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java b/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java index 7f001c181..db301b28d 100644 --- a/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java +++ b/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java @@ -55,9 +55,9 @@ public WebMercatorGridPointSet(TransportNetwork transportNetwork) { this.zoom = DEFAULT_ZOOM; - double latBuffer = SphericalDistanceLibrary.metersToDegreesLatitude(TransitLayer.DISTANCE_TABLE_SIZE_METERS); + double latBuffer = SphericalDistanceLibrary.metersToDegreesLatitude(LinkedPointSet.MAX_OFFSTREET_WALK_METERS); double lonBuffer = SphericalDistanceLibrary - .metersToDegreesLongitude(TransitLayer.DISTANCE_TABLE_SIZE_METERS, transportNetwork.streetLayer.envelope.centre().y); + .metersToDegreesLongitude(LinkedPointSet.MAX_OFFSTREET_WALK_METERS, transportNetwork.streetLayer.envelope.centre().y); int west = lonToPixel(transportNetwork.streetLayer.envelope.getMinX() - lonBuffer); int east = lonToPixel(transportNetwork.streetLayer.envelope.getMaxX() + lonBuffer);