view gnv-artifacts/src/main/java/de/intevation/gnv/utils/DistanceCalculator.java @ 1129:ccfa07b88476

merged geo-backend
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:01 +0200
parents f953c9a559d8
children
line wrap: on
line source
/*
 * Copyright (c) 2010 by Intevation GmbH
 *
 * This program is free software under the LGPL (>=v2.1)
 * Read the file LGPL.txt coming with the software for details
 * or visit http://www.gnu.org/licenses/ if it does not exist.
 */

package de.intevation.gnv.utils;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Point;

import java.util.List;

/**
 * A helper class to calculate distances between points and coordinates.
 *
 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
 *
 */
public class DistanceCalculator {

    private final static double flattening = 1.0 / 298.257233563;

    private final static double earthRadius = 6378137.0 / 1000.0 ;

    /**
     * Constructor
     */
    public DistanceCalculator() {
    }


    /**
     * Calculates the distance between two points.
     *
     * @param p1 First point.
     * @param p2 Second point.
     * @return the distance.
     */
    public static double calculateDistance(Point p1, Point p2){
        return calculateDistance(p1.getCoordinate(), p2.getCoordinate());
    }


    /**
     * Calculates the distance between two coordinates.
     *
     * @param p1 First coordinate.
     * @param p2 Second coordinate.
     * @return the distance.
     */
    public static double calculateDistance(Coordinate p1, Coordinate p2){
        double resultValue = 0.0;

        double b1 = p1.y;
        double b2 = p2.y;

        double l1 = p1.x;
        double l2 = p2.x;


        double F = (b1 + b2) / 2.0;
        double G = (b1 - b2) / 2.0;
        double l = (l1 - l2) / 2.0;

        F = (Math.PI / 180.0) * F;
        G = (Math.PI / 180.0) * G;
        l = (Math.PI / 180.0) * l;

        double S = ((Math.sin(G) * Math.sin(G)) * ((Math.cos(l) * Math.cos(l))))+
                   ((Math.cos(F) * Math.cos(F)) * ((Math.sin(l) * Math.sin(l))));

        double C = ((Math.cos(G) * Math.cos(G)) * ((Math.cos(l) * Math.cos(l))))+
                   ((Math.sin(F) * Math.sin(F)) * ((Math.sin(l) * Math.sin(l))));

        double w = Math.atan(Math.sqrt((S/C)));

        double D = 2.0 * w * earthRadius;

        double R = Math.sqrt((S*C)) / w;

        double H1 = (3.0 * R - 1.0 ) / (2.0 * C);
        double H2 = (3.0 * R + 1.0 ) / (2.0 * S);

        resultValue = D * (1 + (flattening * H1 * (Math.sin(F) * Math.sin(F)) *
                                                  (Math.cos(G) * Math.cos(G))) -
                           (flattening * H2 * (Math.cos(F) * Math.cos(F)) *
                                              (Math.sin(G) * Math.sin(G))));

        return resultValue;
    }

    /**
     * Calculates the length of a path specified by coordinates in <i>path</i>.
     *
     * @param path A list of coordinates.
     * @return the length of the given path.
     */
    public static final double calculateDistance(List<Coordinate> path) {
        int N = path.size();
        if (N < 2) {
            return 0d;
        }
        double sum = 0d;
        for (int i = 1; i < N; ++i) {
            sum += calculateDistance(path.get(i-1), path.get(i));
        }
        return sum;
    }

}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org