Skip to content

Commit

Permalink
Merge pull request #899 from conveyal/merge-pixel-functions
Browse files Browse the repository at this point in the history
Merge WGS84 / web Mercator conversion functions
  • Loading branch information
abyrd authored Nov 2, 2023
2 parents 862ae15 + 401459f commit 6741964
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 486 deletions.
41 changes: 23 additions & 18 deletions src/main/java/com/conveyal/r5/analyst/Grid.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.csvreader.CsvReader;
import com.google.common.io.LittleEndianDataInputStream;
import com.google.common.io.LittleEndianDataOutputStream;
import org.apache.commons.math3.util.FastMath;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.coverage.grid.io.AbstractGridFormat;
Expand Down Expand Up @@ -64,15 +63,17 @@

import static com.conveyal.gtfs.util.Util.human;
import static com.conveyal.r5.common.GeometryUtils.checkWgsEnvelopeSize;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static java.lang.Double.parseDouble;
import static org.apache.commons.math3.util.FastMath.atan;
import static org.apache.commons.math3.util.FastMath.cos;
import static org.apache.commons.math3.util.FastMath.log;
import static org.apache.commons.math3.util.FastMath.sinh;
import static org.apache.commons.math3.util.FastMath.tan;
import static org.apache.commons.math3.util.FastMath.toRadians;
import static java.lang.Math.PI;
import static java.lang.Math.atan;
import static java.lang.Math.cos;
import static java.lang.Math.log;
import static java.lang.Math.pow;
import static java.lang.Math.sinh;
import static java.lang.Math.tan;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;

/**
* Class that represents a grid of opportunity counts in the spherical Mercator "projection" at a given zoom level.
Expand Down Expand Up @@ -482,7 +483,7 @@ public static int lonToPixel (double lon, int zoom) {
* Naming should somehow be revised to clarify that it doesn't return the center of the pixel.
*/
public static double pixelToLon (double xPixel, int zoom) {
return xPixel / (Math.pow(2, zoom) * 256) * 360 - 180;
return xPixel / (pow(2, zoom) * 256) * 360 - 180;
}

/**
Expand All @@ -505,20 +506,24 @@ public static int latToPixel (double lat, int zoom) {
}

/**
* Return the latitude of the center of all pixels at the given zoom level and absolute (world) y pixel number
* measured southward from the north edge of the world.
* Given an integer web Mercator pixel number, return the latitude in degrees of the north edge of that pixel at the
* given zoom level relative to the top (north) edge of the world (not relative to this grid or to any particular
* tile). Given a non-integer web Mercator pixel number, return WGS84 locations within that pixel.
*
* TODO Profile this some time because we had versions using both FastMath and built-in Math functions.
* The difference should be less significant these days. Java now has a StrictMath and the normal Math is optimized.
*/
public static double pixelToCenterLat (int yPixel, int zoom) {
return pixelToLat(yPixel + 0.5, zoom);
public static double pixelToLat (double yPixel, int zoom) {
final double tile = yPixel / 256d;
return toDegrees(atan(sinh(PI - tile * PI * 2 / pow(2, zoom))));
}

/**
* Return the latitude of the north edge of any pixel at the given zoom level and y coordinate relative to the top
* edge of the world (assuming an integer pixel). Noninteger pixels will return locations within the pixel.
* We're using FastMath here, because the built-in math functions were taking a large amount of time in profiling.
* Return the latitude of the center of all pixels at the given zoom level and absolute (world) y pixel number
* measured southward from the north edge of the world.
*/
public static double pixelToLat (double yPixel, int zoom) {
return FastMath.toDegrees(atan(sinh(Math.PI - (yPixel / 256d) / Math.pow(2, zoom) * 2 * Math.PI)));
public static double pixelToCenterLat (int yPixel, int zoom) {
return pixelToLat(yPixel + 0.5, zoom);
}

/**
Expand Down
Loading

0 comments on commit 6741964

Please sign in to comment.