Subversion Repositories mkgmap

Rev

Rev 4464 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2014.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 or
 * version 2 as published by the Free Software Foundation.
 *
 * 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 uk.me.parabola.imgfmt.app;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.List;

import org.junit.Test;

import uk.me.parabola.mkgmap.filters.ShapeMergeFilter;
import uk.me.parabola.mkgmap.reader.osm.Way;

/**
 * Test some basic methods of the Coord class regarding distance and bearing calculations
 * @author GerdP
 *
 */

public class CoordTest {
        Coord pLAX = new Coord(33.95, -118.4);
        Coord pJFK = new Coord(40.6333333333, -73.7833333333333333);
        Coord pD = new Coord(34.5, -116.5);
        Coord p0_10 = new Coord (0.0, 10.0);
        Coord p1_10 = new Coord (1.0, 10.0);
        Coord p1_11 = new Coord (1.0, 11.0);
        Coord p60_10 = new Coord (60.0, 10.0);
        Coord p61_11 = new Coord (61.0, 11.0);
        Coord russia1 = new Coord(3069580,8388608);
        Coord russia2 = new Coord(3105677,8388608);
       
        /**
         */

        @Test
        public void testBearingGC() {
                assertEquals(65.892222, pLAX.bearingToOnGreatCircle(pJFK, true), 0.1);
                assertEquals(0.0, p0_10.bearingToOnGreatCircle(p1_10, true), 0.001);
                assertEquals(89.991388, p1_10.bearingToOnGreatCircle(p1_11, true), 0.001);
                assertEquals(44.99555, p0_10.bearingToOnGreatCircle(p1_11, true), 0.001);
        }
        @Test
        public void testBearingRhumb() {
                assertEquals(79.32388, pLAX.bearingToOnRhumbLine(pJFK, true), 0.1);
                assertEquals(0, p0_10.bearingToOnRhumbLine(p1_10, true), 0.001);
                assertEquals(90, p1_10.bearingToOnRhumbLine(p1_11, true), 0.001);
                assertEquals(44.99861, p0_10.bearingToOnRhumbLine(p1_11, true), 0.001);
                assertEquals(26.214722, p60_10.bearingToOnRhumbLine(p61_11, true), 0.001);
        }
       
        @Test
        public void testDistanceRhumb() {
                // http://www.movable-type.co.uk/scripts/latlong.html says 4011 km  for R=6371 km
                assertEquals(4011000 * Coord.R / 6371000, pLAX.distanceOnRhumbLine(pJFK), 1000);
                assertEquals(4011000 * Coord.R / 6371000, pJFK.distanceOnRhumbLine(pLAX), 1000);
                assertEquals(Coord.U/360, p1_10.distanceOnRhumbLine(p1_11), 20);
                assertEquals(Coord.U/360, p0_10.distanceOnRhumbLine(p1_10), 20);
                assertEquals(157200*Coord.R / 6371000, p0_10.distanceOnRhumbLine(p1_11), 200);
                assertEquals(123900*Coord.R / 6371000, p60_10.distanceOnRhumbLine(p61_11), 200);
        }
       
        @Test
        public void testDistanceGC() {
                // http://www.movable-type.co.uk/scripts/latlong.html says 3973 km  for R=6371 km
                assertEquals(3973000 * Coord.R / 6371000, pLAX.distanceHaversine(pJFK), 1000);
                assertEquals(3973000 * Coord.R / 6371000, pJFK.distanceHaversine(pLAX), 1000);
                assertEquals(111300, p1_10.distanceHaversine(p1_11), 100);
                assertEquals(111300, p0_10.distanceHaversine(p1_10), 100);
                assertEquals(157400, p0_10.distanceHaversine(p1_11), 100);
                assertEquals(124100, p60_10.distanceHaversine(p61_11), 100);
        }

        @Test
        public void testMakeBetweenAt180(){
                Coord russia3 = russia1.makeBetweenPoint(russia2, 0.5);
                assertEquals(russia3.getLongitude(), russia1.getLongitude());
        }
       
        @Test
        public void destOnRhumbLineAt180(){
                Coord russia3 = russia1.destOnRhumbLine(1, 0.0);
                assertEquals(russia3.getLongitude(), russia1.getLongitude());
                Coord russia4 = russia1.destOnRhumbLine(10000, 0.0);
                assertEquals(russia4.getLongitude(), russia1.getLongitude());
        }
       
        @Test
        public void testOffset() {
                assertEquals(pLAX, pLAX.offset(60, 100).offset(120, 100).offset(180, 100).offset(240, 100).offset(300, 100).offset(360, 100));
        }
       
        @Test
        public void testOverflow() {
                Coord c1 = new Coord(90.0,180.0);
                Coord c2 = new Coord(90.0,-180.0);
                assertFalse(c1.equals(c2));
                assertFalse(c1.highPrecEquals(c2));
                assertEquals(0,c1.distance(c2),0.0000001);
                assertEquals(0x800000, c1.getLongitude());
        }
       
        @SuppressWarnings("unused")
        @Test
        public void testRounding() {
                if (Coord.DELTA_SHIFT + 24 == Integer.SIZE) {
                        Coord c1 = new Coord(61.0000001, -23.0000001);
                        Coord c2 = new Coord(61.0000000, -23.0000001);
                        Coord c3 = new Coord(61.0000001, -23.0000000);
                        assertFalse(c1.highPrecEquals(c2));
                        assertFalse(c1.highPrecEquals(c3));
                        assertFalse(c2.highPrecEquals(c3));
                        assertTrue(c1.equals(c2));
                        assertTrue(c1.equals(c3));
                        assertTrue(c2.equals(c3));
                        assertEquals(61.0000001d,c1.getLatDegrees(),0.0000001);
                        assertEquals(61.0000000d,c2.getLatDegrees(),0.0000001);
                        assertEquals(61.0000001d,c3.getLatDegrees(),0.0000001);
                        assertEquals(-23.0000001d,c1.getLonDegrees(),0.0000001);
                        assertEquals(-23.0000001d,c2.getLonDegrees(),0.0000001);
                        assertEquals(-23.0000000d,c3.getLonDegrees(),0.0000001);
                        double lat1 = -1;
                        double lat2 = 1;
                        double lon1 = -1;
                        double lon2 = 1;
                        for (int i = 0; i < 1000; i++) {
                                Coord ct1 = new Coord(lat1,lon1);
                                Coord ct2 = new Coord(lat2,lon2);
                                assertEquals(lat1,ct1.getLatDegrees(),0.0000001);
                                assertEquals(lat2,ct2.getLatDegrees(),0.0000001);
                                assertEquals(lon1,ct1.getLonDegrees(),0.0000001);
                                assertEquals(lon2,ct2.getLonDegrees(),0.0000001);
                                lat1 = Math.nextAfter((float) lat1, 90);
                                lat2 = Math.nextAfter((float) lat2, 90);
                                lon1 = Math.nextAfter((float) lon1, 180);
                                lon2 = Math.nextAfter((float) lon2, 180);
                        }
                }
        }

        @Test
        public void alternativePos() {
                Coord c1 = new Coord(61.0000001, -23.0000001);
                List<Coord> alt1 = c1.getAlternativePositions();
                assertEquals(1, alt1.size());
                for (Coord c : alt1) {
                        assertTrue(c.distance(c1) < 3);
                        assertTrue(c.hasAlternativePos());
                        List<Coord> altx = c.getAlternativePositions();
                        assertFalse(altx.isEmpty());
                }
                Coord c2 = new Coord(61.1, -23.3);
                List<Coord> alt2 = c2.getAlternativePositions();
                assertEquals(3, alt2.size());
                for (Coord c : alt2) {
                        assertTrue(c.distance(c2) < 3);
                        assertTrue(c.hasAlternativePos());
                        List<Coord> altx = c.getAlternativePositions();
                        assertFalse(altx.isEmpty());
                }
        }
       
       
        @Test
        public void testPlanet() throws Exception {
                final uk.me.parabola.imgfmt.app.Area planet = uk.me.parabola.imgfmt.app.Area.PLANET;
                long testVal = ShapeMergeFilter.calcAreaSizeTestVal(planet.toCoords());
                double areaSizeCoords = (double) testVal / (2 * (1<<Coord.DELTA_SHIFT) * (1<<Coord.DELTA_SHIFT));
                areaSizeCoords = Math.abs(areaSizeCoords);
                double areaSizeBounds = (double) planet.getHeight() * planet.getWidth();
                assertEquals(areaSizeBounds, areaSizeCoords, 0.0001);
                boolean dir = Way.clockwise(planet.toCoords());
                assertFalse(dir);
        }      
       
}