All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.n52.io.crs.WGS84Util Maven / Gradle / Ivy

/*
 * Copyright (C) 2013-2019 52°North Initiative for Geospatial Open Source
 * Software GmbH
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * If the program is linked with libraries which are licensed under one of
 * the following licenses, the combination of the program with the linked
 * library is not considered a "derivative work" of the program:
 *
 *     - Apache License, version 2.0
 *     - Apache Software License, version 1.0
 *     - GNU Lesser General Public License, version 3
 *     - Mozilla Public License, versions 1.0, 1.1 and 2.0
 *     - Common Development and Distribution License (CDDL), version 1.0
 *
 * Therefore the distribution of the program linked with libraries licensed
 * under the aforementioned licenses, is permitted by the copyright holders
 * if the distribution is compliant with both the GNU General Public License
 * version 2 and the aforementioned licenses.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 */
package org.n52.io.crs;

import com.vividsolutions.jts.geom.Point;

/**
 * Some utility methods for WGS84 points. Note that all calculations are being
 * made by assuming a spherical shape of the earth (not elliptic). The
 * {@link WGS84Util#EARTH_MEAN_RADIUS} is used as radius.
 */
public class WGS84Util {

    public static final String EPSG_4326 = "EPSG:4326";

    /**
     * The mean radius of WGS84 ellipse.
     */
    protected static final double EARTH_MEAN_RADIUS = 6371.000;

    /**
     * Calculates the shortest distance between two points on a great circle.
     *
     * @param a a point.
     * @param b another point.
     * @return the shortest distance between point A and point B.
     */
    public static double shortestDistanceBetween(Point a, Point b) {
        double aXinRad = Math.toRadians(a.getX());
        double aYinRad = Math.toRadians(a.getY());
        double bXinRad = Math.toRadians(b.getX());
        double bYinRad = Math.toRadians(b.getY());
        double aProd = Math.sin(aYinRad) * Math.sin(bYinRad);
        double bProd = Math.cos(aYinRad) * Math.cos(bYinRad) * Math.cos(aXinRad - bXinRad);
        return Math.acos(aProd + bProd) * EARTH_MEAN_RADIUS;
    }

    /**
     * Calculates the longitude delta for a given distance.
     *
     * @param latitude the latitude in radians to calculate the distance delta
     * from.
     * @param distance the distance in kilometer.
     * @return the longitude delta in degrees.
     */
    public static double getLongitudeDelta(double latitude, double distance) {
        return Math.toDegrees(distance / getLatitutesCircleRadius(latitude)) % 360;
    }

    /**
     * Calculates the latitude delta from a point from a given distance.
     *
     * @param distance the distance in kilometer.
     * @return the latitude delta in degrees.
     */
    public static double getLatitudeDelta(double distance) {
        return Math.toDegrees(distance / EARTH_MEAN_RADIUS) % 180;
    }

    /**
     * @param latitude in degrees in radians.
     * @return the length of the latitude radius.
     */
    static double getLatitutesCircleRadius(double latitude) {
        return EARTH_MEAN_RADIUS * Math.sin(Math.PI / 2 - latitude);
    }

    /**
     * Normalizes given longitude to bounds [-180.0,180.0].
     *
     * @param longitude in degrees.
     * @return the normalized longitude.
     */
    public static double normalizeLongitude(double longitude) {
        double asRad = Math.toRadians(longitude);
        if (asRad > Math.PI) {
            return Math.toDegrees(-2 * Math.PI + asRad) % 180;
        } else if (-Math.PI > asRad) {
            return Math.toDegrees(2 * Math.PI + asRad) % 180;
        }
        return longitude;
    }

    /**
     * Normalizes given latitude to bounds [-90.0,90.0].
     *
     * @param latitude in degrees.
     * @return the normalized latitude.
     */
    public static double normalizeLatitude(double latitude) {
        double asRad = Math.toRadians(latitude);
        if (asRad > Math.PI / 2) {
            return Math.toDegrees(2 * Math.PI - asRad) % 90;
        } else if (-Math.PI / 2 > asRad) {
            return Math.toDegrees(-2 * Math.PI - asRad) % 90;
        }
        return latitude;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy