TileIndexCalculator.java
- /*
- * Copyright 2021 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.genesys.util;
- /**
- * Raster grid utilities.
- */
- public class TileIndexCalculator {
- /**
- * Gets the 3x3 minute grid cell zero-based index starting in the NW corner
- * (-180,90) with `tile=0` and ending in the SW corner (180,-90). A 3 minute
- * grid has `ncol=7200` "columns" and `nrow=3600` "rows".
- *
- * @param longitude the longitude
- * @param latitude the latitude
- * @return the cell index for a 3 degree grid
- */
- public static final Integer get3MinuteTileIndex(Number longitude, Number latitude) {
- if (longitude == null || latitude == null)
- return null;
- if (longitude.doubleValue() < -180 || longitude.doubleValue() > 180)
- return null;
- if (latitude.doubleValue() < -90 || latitude.doubleValue() > 90)
- return null;
- final int columns = 7200;
- final int rows = 3600;
- final float xres_inv = columns / 360f;
- final float yres_inv = rows / 180f;
- // yx is offset by 0.5 * yd in
- // https://github.com/rspatial/raster/blob/master/R/rasterFromBIL.R#L92
- // I took two days to find out why math doesn't work out!
- var ymax = 89.99990f; // 90.0d
- int nrow;
- if (latitude.intValue() == -90) {
- nrow = (int) (rows) - 1;
- } else if (latitude.intValue() == 90) {
- nrow = 0;
- } else {
- nrow = (int) ((ymax - latitude.floatValue()) * yres_inv);
- }
- // longitude (-180:180) -> (0:columns-1)
- int ncol = (int) ((longitude.floatValue() + 180f) * xres_inv);
- if (longitude.intValue() == 180) {
- ncol = (int) (columns - 1);
- }
- return nrow * columns + ncol;
- }
- }