CoordUtil.java
/*
* Copyright 2018 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.util;
/**
* Coordinate utilities
*/
public class CoordUtil {
/**
* Convert tile index at zoom level to longitude.
*
* @param zoom
* zoom level
* @param xtile
* tile index
* @return longitude of left side of tile
*/
public static double tileToLon(final int zoom, final int xtile) {
return 360.0 * xtile / (1 << zoom) - 180.0;
}
/**
* Convert tile index at zoom level to latitude
*
* @param zoom
* zoom level
* @param ytile
* tile index
* @return latitude of the top side of the tile
*/
public static double tileToLat(final int zoom, final int ytile) {
final double n = Math.PI - 2.0 * Math.PI * ytile / (1 << zoom);
return Math.toDegrees(Math.atan(Math.sinh(n)));
}
/**
* Lon to tile.
*
* @param zoom
* the zoom
* @param lon
* the lon
* @return the int
*/
public static int lonToTile(final int zoom, final double lon) {
return (int) Math.floor((lon + 180.0) / 360.0 * (1 << zoom));
}
/**
* Lat to tile.
*
* @param zoom
* the zoom
* @param lat
* the lat
* @return the int
*/
public static int latToTile(final int zoom, final double lat) {
final double latr = Math.toRadians(lat);
return (int) Math.floor((1 - Math.log(Math.tan(latr) + 1 / Math.cos(latr)) / Math.PI) / 2 * (1 << zoom));
}
/**
* Lon to img.
*
* @param zoom
* the zoom
* @param lon
* the lon
* @return the int
*/
public static int lonToImg(final int zoom, double lon) {
// n = 2 ^ zoom
final int xtile = lonToTile(zoom, lon);
final double a = tileToLon(zoom, xtile);
final double b = tileToLon(zoom, xtile + 1);
// System.err.println("a=" + a + " b=" + b);
// Translate to start of tile
lon -= a;
// Scale by (ba)*256;
// System.err.println("b-a="+(b-a));
lon = 256.0 * lon / (b - a);
return (int) Math.floor(lon);
}
/**
* Lat to img.
*
* @param zoom
* the zoom
* @param lat
* the lat
* @return the int
*/
public static int latToImg(final int zoom, double lat) {
// n = 2 ^ zoom
final int ytile = latToTile(zoom, lat);
// System.err.println("ytile=" + ytile);
final double a = tileToLat(zoom, ytile);
final double b = tileToLat(zoom, ytile + 1);
// System.err.println("a=" + a + " b=" + b);
// Translate to start of tile
lat -= a;
// Scale by (ba)*256;
// System.err.println("b-a=" + (b - a));
lat = 256.0 * lat / (b - a);
return (int) Math.floor(lat);
}
/**
* Mercator projection of decimal latitude to a y-pixel on tile at
* specific zoom level.
*
* @param zoom
* Zoom level
* @param tile
* Tile index
* @param lat
* Latitude
* @return the int
*/
public static int latToImg3(final int zoom, final int tile, double lat) {
lat = Math.min(85.0511287, Math.max(lat, -85.0511287));
final double pixAtZoom = (1 << zoom) * 256;
final double latr = Math.toRadians(lat);
final double y1 = Math.floor((1 - Math.log(Math.tan(latr) + 1 / Math.cos(latr)) / Math.PI) / 2 * pixAtZoom);
return (int) y1 - tile * 256;
}
/**
* Convert decimal longitude to an x-pixel on tile at specific zoom
* level.
*
* @param zoom
* Zoom level
* @param tile
* Tile index
* @param lng
* Longitude
* @return the int
*/
public static int lonToImg3(final int zoom, final int tile, final double lng) {
final double totalPixelsAtZoom = (1 << zoom) * 256;
final double longitudePixelAtZoom = Math.floor((180.0 + lng) / 360.0 * totalPixelsAtZoom);
return (int) (longitudePixelAtZoom - tile * 256);
}
}