neXenio / BLE-Indoor-Positioning

Multilateration using bluetooth beacons
Apache License 2.0
430 stars 129 forks source link

Different inputs in SphericalMercatorProjection and SphericalMercatorProjectionTest #121

Closed hadiidbouk closed 5 years ago

hadiidbouk commented 6 years ago

You can see below that in the SphericalMercatorProjection class, the third item of the double array is the altitude :

    /**
     * Converts latitude, longitude, elevation to Earth-Centered-Earth-Fixed (ECEF).
     */
    public static double[] locationToEcef(Location location) {
        double[] geodetic = new double[]{Math.toRadians(location.getLatitude()) , Math.toRadians(location.getLongitude()), location.getAltitude()};
        return geodeticToEcef(geodetic);
    }

    /**
     * Convert latitude, longitude, height to Earth-Centered-Earth-Fixed (ECEF). Input is a three
     * element array containing latitude, longitude (radians) and altitude (in meters). Returned
     * array contains x, y, z in meters
     *
     * @see <a href="http://danceswithcode.net/engineeringnotes/geodetic_to_ecef/geodetic_to_ecef.html">Source</a>
     */
    public static double[] geodeticToEcef(double[] geodetic) {
        double[] ecef = new double[3];
        double latitude = geodetic[0];
        double longitude = geodetic[1];
        double altitude = geodetic[2];
        double n = EARTH_RADIUS / Math.sqrt(1 - e2 * Math.sin(latitude) * Math.sin(latitude));
        ecef[0] = (n + altitude) * Math.cos(latitude) * Math.cos(longitude);
        ecef[1] = (n + altitude) * Math.cos(latitude) * Math.sin(longitude);
        ecef[2] = (n * (1 - e2) + altitude) * Math.sin(latitude);
        return ecef;
    }

But in the SphericalMercatorProjectionTest the third item is elevation

@Test
    public void geodeticToEcef_location_accurateEcef() throws Exception {
        double[] expectedCenter = new double[]{3786292.474596871, 890822.9600122868, 5037857.368752121}; // SOCCER_FIELD_CENTER
        double[] geodetic = new double[]{
                Math.toRadians(LocationTest.SOCCER_FIELD_CENTER.getLatitude()),
                Math.toRadians(LocationTest.SOCCER_FIELD_CENTER.getLongitude()),
                Math.toRadians(LocationTest.SOCCER_FIELD_CENTER.getElevation())
        };
        double[] actualCenter = SphericalMercatorProjection.geodeticToEcef(geodetic);

        assertEquals(expectedCenter[0], actualCenter[0], 1);
        assertEquals(expectedCenter[1], actualCenter[1], 1);
        assertEquals(expectedCenter[2], actualCenter[2], 1);
    }

    @Test
    public void ecefToGeodetic_ecefArray_accurateGeodetic() throws Exception {
        double[] expectedGeodetic = new double[]{
                LocationTest.SOCCER_FIELD_CENTER.getLatitude(),
                LocationTest.SOCCER_FIELD_CENTER.getLongitude(),
                LocationTest.SOCCER_FIELD_CENTER.getElevation()
        };
        double[] ecefArray = new double[]{3786292.474596871, 890822.9600122868, 5037857.368752121}; // SOCCER_FIELD_CENTER
        double[] actualGeodetic = SphericalMercatorProjection.ecefToGeodetic(ecefArray);

        assertEquals(expectedGeodetic[0], Math.toDegrees(actualGeodetic[0]), 1);
        assertEquals(expectedGeodetic[1], Math.toDegrees(actualGeodetic[1]), 1);
        assertEquals(expectedGeodetic[2], Math.toDegrees(actualGeodetic[2]), 1);
    }