diff --git a/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java b/src/main/java/com/conveyal/r5/analyst/WebMercatorGridPointSet.java index 7c72afd6d..db301b28d 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(LinkedPointSet.MAX_OFFSTREET_WALK_METERS); + double lonBuffer = SphericalDistanceLibrary + .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); + 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;