mirror of https://github.com/apache/lucene.git
LUCENE-2147: Improve Spatial Utility like classes
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@896240 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
36ba04585e
commit
c19d78dd4e
|
@ -32,7 +32,11 @@ API Changes
|
||||||
|
|
||||||
* LUCENE-2108: Add SpellChecker.close, to close the underlying
|
* LUCENE-2108: Add SpellChecker.close, to close the underlying
|
||||||
reader. (Eirik Bjørsnøs via Mike McCandless)
|
reader. (Eirik Bjørsnøs via Mike McCandless)
|
||||||
|
|
||||||
|
* LUCENE-2147: Spatial GeoHashUtils now always decode GeoHash strings
|
||||||
|
with full precision. GeoHash#decode_exactly(String) was merged into
|
||||||
|
GeoHash#decode(String). (Chris Male, Simon Willnauer)
|
||||||
|
|
||||||
* LUCENE-2165: Add a constructor to SnowballAnalyzer that takes a Set of
|
* LUCENE-2165: Add a constructor to SnowballAnalyzer that takes a Set of
|
||||||
stopwords, and deprecate the String[] one. (Nick Burch via Robert Muir)
|
stopwords, and deprecate the String[] one. (Nick Burch via Robert Muir)
|
||||||
|
|
||||||
|
|
|
@ -21,154 +21,119 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Based on http://en.wikipedia.org/wiki/Geohash
|
* Utilities for encoding and decoding geohashes. Based on
|
||||||
*
|
* http://en.wikipedia.org/wiki/Geohash.
|
||||||
* <p><font color="red"><b>NOTE:</b> This API is still in
|
|
||||||
* flux and might change in incompatible ways in the next
|
|
||||||
* release.</font>
|
|
||||||
*/
|
*/
|
||||||
public class GeoHashUtils {
|
public class GeoHashUtils {
|
||||||
|
|
||||||
// geohash's char map
|
private static final char[] BASE_32 = {'0', '1', '2', '3', '4', '5', '6',
|
||||||
// no a's i's l's o's
|
'7', '8', '9', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n',
|
||||||
// old MacDonal wouldn't be happy
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
|
||||||
private static char[] _base32 = {'0','1','2','3','4','5','6','7','8','9',
|
|
||||||
'b','c','d','e','f','g','h','j','k','m',
|
|
||||||
'n','p','q','r','s','t','u','v','w','x',
|
|
||||||
'y','z'} ;
|
|
||||||
|
|
||||||
private final static Map<Character, Integer> _decodemap = new HashMap<Character, Integer>();
|
|
||||||
static {
|
|
||||||
int sz = _base32.length;
|
|
||||||
for (int i = 0; i < sz; i++ ){
|
|
||||||
_decodemap.put(_base32[i], i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int precision = 12;
|
|
||||||
private static int[] bits = {16, 8, 4, 2, 1};
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
GeoHashUtils ghf = new GeoHashUtils();
|
|
||||||
String gc1 = ghf.encode(30, -90.0);
|
|
||||||
String gc2 = ghf.encode(51.4797, -0.0124);
|
|
||||||
|
|
||||||
System.out.println(gc1);
|
|
||||||
System.out.println(gc2);
|
|
||||||
|
|
||||||
double [] gd1 = ghf.decode(gc1);
|
|
||||||
double [] gd2 = ghf.decode(gc2);
|
|
||||||
System.out.println(gd1[0]+ ", "+ gd1[1]);
|
|
||||||
System.out.println(gd2[0]+ ", "+ gd2[1]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String encode(double latitude, double longitude){
|
|
||||||
double[] lat_interval = {-90.0 , 90.0};
|
|
||||||
double[] lon_interval = {-180.0, 180.0};
|
|
||||||
|
|
||||||
StringBuilder geohash = new StringBuilder();
|
|
||||||
boolean is_even = true;
|
|
||||||
int bit = 0, ch = 0;
|
|
||||||
|
|
||||||
while(geohash.length() < precision){
|
|
||||||
double mid = 0.0;
|
|
||||||
if(is_even){
|
|
||||||
mid = (lon_interval[0] + lon_interval[1]) / 2;
|
|
||||||
if (longitude > mid){
|
|
||||||
ch |= bits[bit];
|
|
||||||
lon_interval[0] = mid;
|
|
||||||
} else {
|
|
||||||
lon_interval[1] = mid;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
mid = (lat_interval[0] + lat_interval[1]) / 2;
|
|
||||||
if(latitude > mid){
|
|
||||||
ch |= bits[bit];
|
|
||||||
lat_interval[0] = mid;
|
|
||||||
} else {
|
|
||||||
lat_interval[1] = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is_even = is_even ? false : true;
|
|
||||||
|
|
||||||
if (bit < 4){
|
|
||||||
bit ++;
|
|
||||||
} else {
|
|
||||||
geohash.append(_base32[ch]);
|
|
||||||
bit =0;
|
|
||||||
ch = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return geohash.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double[] decode(String geohash) {
|
|
||||||
double[] ge = decode_exactly(geohash);
|
|
||||||
double lat, lon, lat_err, lon_err;
|
|
||||||
lat = ge[0];
|
|
||||||
lon = ge[1];
|
|
||||||
lat_err = ge[2];
|
|
||||||
lon_err = ge[3];
|
|
||||||
|
|
||||||
double lat_precision = Math.max(1, Math.round(- Math.log10(lat_err))) - 1;
|
|
||||||
double lon_precision = Math.max(1, Math.round(- Math.log10(lon_err))) - 1;
|
|
||||||
|
|
||||||
lat = getPrecision(lat, lat_precision);
|
|
||||||
lon = getPrecision(lon, lon_precision);
|
|
||||||
|
|
||||||
return new double[] {lat, lon};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double[] decode_exactly (String geohash){
|
|
||||||
double[] lat_interval = {-90.0 , 90.0};
|
|
||||||
double[] lon_interval = {-180.0, 180.0};
|
|
||||||
|
|
||||||
double lat_err = 90.0;
|
|
||||||
double lon_err = 180.0;
|
|
||||||
boolean is_even = true;
|
|
||||||
int sz = geohash.length();
|
|
||||||
int bsz = bits.length;
|
|
||||||
double latitude, longitude;
|
|
||||||
for (int i = 0; i < sz; i++){
|
|
||||||
|
|
||||||
int cd = _decodemap.get(geohash.charAt(i));
|
|
||||||
|
|
||||||
for (int z = 0; z< bsz; z++){
|
|
||||||
int mask = bits[z];
|
|
||||||
if (is_even){
|
|
||||||
lon_err /= 2;
|
|
||||||
if ((cd & mask) != 0){
|
|
||||||
lon_interval[0] = (lon_interval[0]+lon_interval[1])/2;
|
|
||||||
} else {
|
|
||||||
lon_interval[1] = (lon_interval[0]+lon_interval[1])/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
lat_err /=2;
|
|
||||||
|
|
||||||
if ( (cd & mask) != 0){
|
|
||||||
lat_interval[0] = (lat_interval[0]+lat_interval[1])/2;
|
|
||||||
} else {
|
|
||||||
lat_interval[1] = (lat_interval[0]+lat_interval[1])/2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is_even = is_even ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
latitude = (lat_interval[0] + lat_interval[1]) / 2;
|
|
||||||
longitude = (lon_interval[0] + lon_interval[1]) / 2;
|
|
||||||
|
|
||||||
return new double []{latitude, longitude, lat_err, lon_err};
|
private final static Map<Character,Integer> DECODE_MAP = new HashMap<Character,Integer>();
|
||||||
|
|
||||||
|
private static final int PRECISION = 12;
|
||||||
|
private static final int[] BITS = {16, 8, 4, 2, 1};
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < BASE_32.length; i++) {
|
||||||
|
DECODE_MAP.put(Character.valueOf(BASE_32[i]), Integer.valueOf(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GeoHashUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the given latitude and longitude into a geohash
|
||||||
|
*
|
||||||
|
* @param latitude Latitude to encode
|
||||||
|
* @param longitude Longitude to encode
|
||||||
|
* @return Geohash encoding of the longitude and latitude
|
||||||
|
*/
|
||||||
|
public static String encode(double latitude, double longitude) {
|
||||||
|
double[] latInterval = {-90.0, 90.0};
|
||||||
|
double[] lngInterval = {-180.0, 180.0};
|
||||||
|
|
||||||
|
final StringBuilder geohash = new StringBuilder();
|
||||||
|
boolean isEven = true;
|
||||||
|
|
||||||
|
int bit = 0;
|
||||||
|
int ch = 0;
|
||||||
|
|
||||||
|
while (geohash.length() < PRECISION) {
|
||||||
|
double mid = 0.0;
|
||||||
|
if (isEven) {
|
||||||
|
mid = (lngInterval[0] + lngInterval[1]) / 2D;
|
||||||
|
if (longitude > mid) {
|
||||||
|
ch |= BITS[bit];
|
||||||
|
lngInterval[0] = mid;
|
||||||
|
} else {
|
||||||
|
lngInterval[1] = mid;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mid = (latInterval[0] + latInterval[1]) / 2D;
|
||||||
|
if (latitude > mid) {
|
||||||
|
ch |= BITS[bit];
|
||||||
|
latInterval[0] = mid;
|
||||||
|
} else {
|
||||||
|
latInterval[1] = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isEven = !isEven;
|
||||||
|
|
||||||
|
if (bit < 4) {
|
||||||
|
bit++;
|
||||||
|
} else {
|
||||||
|
geohash.append(BASE_32[ch]);
|
||||||
|
bit = 0;
|
||||||
|
ch = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return geohash.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the given geohash into a latitude and longitude
|
||||||
|
*
|
||||||
|
* @param geohash Geohash to deocde
|
||||||
|
* @return Array with the latitude at index 0, and longitude at index 1
|
||||||
|
*/
|
||||||
|
public static double[] decode(String geohash) {
|
||||||
|
final double[] latInterval = {-90.0, 90.0};
|
||||||
|
final double[] lngInterval = {-180.0, 180.0};
|
||||||
|
|
||||||
|
boolean isEven = true;
|
||||||
|
|
||||||
|
double latitude;
|
||||||
|
double longitude;
|
||||||
|
for (int i = 0; i < geohash.length(); i++) {
|
||||||
|
final int cd = DECODE_MAP.get(Character.valueOf(
|
||||||
|
geohash.charAt(i))).intValue();
|
||||||
|
|
||||||
|
for (int mask : BITS) {
|
||||||
|
if (isEven) {
|
||||||
|
if ((cd & mask) != 0) {
|
||||||
|
lngInterval[0] = (lngInterval[0] + lngInterval[1]) / 2D;
|
||||||
|
} else {
|
||||||
|
lngInterval[1] = (lngInterval[0] + lngInterval[1]) / 2D;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((cd & mask) != 0) {
|
||||||
|
latInterval[0] = (latInterval[0] + latInterval[1]) / 2D;
|
||||||
|
} else {
|
||||||
|
latInterval[1] = (latInterval[0] + latInterval[1]) / 2D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isEven = !isEven;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
latitude = (latInterval[0] + latInterval[1]) / 2D;
|
||||||
|
longitude = (lngInterval[0] + lngInterval[1]) / 2D;
|
||||||
|
|
||||||
|
return new double[] {latitude, longitude};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
static double getPrecision(double x, double precision) {
|
|
||||||
double base = Math.pow(10,- precision);
|
|
||||||
double diff = x % base;
|
|
||||||
return x - diff;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,11 +18,93 @@
|
||||||
package org.apache.lucene.spatial.geometry;
|
package org.apache.lucene.spatial.geometry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><font color="red"><b>NOTE:</b> This API is still in
|
* Enum representing difference distance units, currently only kilometers and
|
||||||
* flux and might change in incompatible ways in the next
|
* miles
|
||||||
* release.</font>
|
|
||||||
*/
|
*/
|
||||||
public enum DistanceUnits {
|
public enum DistanceUnits {
|
||||||
MILES,
|
|
||||||
KILOMETERS;
|
MILES("miles", 3959, 24902),
|
||||||
|
KILOMETERS("km", 6371, 40076);
|
||||||
|
|
||||||
|
private static final double MILES_KILOMETRES_RATIO = 1.609344;
|
||||||
|
|
||||||
|
private final String unit;
|
||||||
|
|
||||||
|
private final double earthCircumference;
|
||||||
|
|
||||||
|
private final double earthRadius;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new DistanceUnit that represents the given unit
|
||||||
|
*
|
||||||
|
* @param unit Distance unit in String form
|
||||||
|
* @param earthRadius Radius of the Earth in the specific distance unit
|
||||||
|
* @param earthCircumfence Circumference of the Earth in the specific distance unit
|
||||||
|
*/
|
||||||
|
DistanceUnits(String unit, double earthRadius, double earthCircumfence) {
|
||||||
|
this.unit = unit;
|
||||||
|
this.earthCircumference = earthCircumfence;
|
||||||
|
this.earthRadius = earthRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the DistanceUnit which represents the given unit
|
||||||
|
*
|
||||||
|
* @param unit Unit whose DistanceUnit should be found
|
||||||
|
* @return DistanceUnit representing the unit
|
||||||
|
* @throws IllegalArgumentException if no DistanceUnit which represents the given unit is found
|
||||||
|
*/
|
||||||
|
public static DistanceUnits findDistanceUnit(String unit) {
|
||||||
|
if (MILES.getUnit().equals(unit)) {
|
||||||
|
return MILES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KILOMETERS.getUnit().equals(unit)) {
|
||||||
|
return KILOMETERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Unknown distance unit " + unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given distance in given DistanceUnit, to a distance in the unit represented by {@code this}
|
||||||
|
*
|
||||||
|
* @param distance Distance to convert
|
||||||
|
* @param from Unit to convert the distance from
|
||||||
|
* @return Given distance converted to the distance in the given unit
|
||||||
|
*/
|
||||||
|
public double convert(double distance, DistanceUnits from) {
|
||||||
|
if (from == this) {
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
return (this == MILES) ? distance / MILES_KILOMETRES_RATIO : distance * MILES_KILOMETRES_RATIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string representation of the distance unit
|
||||||
|
*
|
||||||
|
* @return String representation of the distance unit
|
||||||
|
*/
|
||||||
|
public String getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the <a href="http://en.wikipedia.org/wiki/Earth_radius">average earth radius</a>
|
||||||
|
*
|
||||||
|
* @return the average earth radius
|
||||||
|
*/
|
||||||
|
public double earthRadius() {
|
||||||
|
return earthRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the <a href="http://www.lyberty.com/encyc/articles/earth.html">circumference of the Earth</a>
|
||||||
|
*
|
||||||
|
* @return the circumference of the Earth
|
||||||
|
*/
|
||||||
|
public double earthCircumference() {
|
||||||
|
return earthCircumference;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You 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.apache.lucene.spatial.geohash;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link GeoHashUtils}
|
||||||
|
*/
|
||||||
|
public class TestGeoHashUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass condition: lat=42.6, lng=-5.6 should be encoded as "ezs42e44yx96",
|
||||||
|
* lat=57.64911 lng=10.40744 should be encoded as "u4pruydqqvj8"
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEncode() {
|
||||||
|
String hash = GeoHashUtils.encode(42.6, -5.6);
|
||||||
|
assertEquals("ezs42e44yx96", hash);
|
||||||
|
|
||||||
|
hash = GeoHashUtils.encode(57.64911, 10.40744);
|
||||||
|
assertEquals("u4pruydqqvj8", hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass condition: lat=52.3738007, lng=4.8909347 should be encoded and then
|
||||||
|
* decoded within 0.00001 of the original value
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDecodePreciseLongitudeLatitude() {
|
||||||
|
String hash = GeoHashUtils.encode(52.3738007, 4.8909347);
|
||||||
|
|
||||||
|
double[] latitudeLongitude = GeoHashUtils.decode(hash);
|
||||||
|
|
||||||
|
assertEquals(52.3738007, latitudeLongitude[0], 0.00001D);
|
||||||
|
assertEquals(4.8909347, latitudeLongitude[1], 0.00001D);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass condition: lat=84.6, lng=10.5 should be encoded and then decoded
|
||||||
|
* within 0.00001 of the original value
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDecodeImpreciseLongitudeLatitude() {
|
||||||
|
String hash = GeoHashUtils.encode(84.6, 10.5);
|
||||||
|
|
||||||
|
double[] latitudeLongitude = GeoHashUtils.decode(hash);
|
||||||
|
|
||||||
|
assertEquals(84.6, latitudeLongitude[0], 0.00001D);
|
||||||
|
assertEquals(10.5, latitudeLongitude[1], 0.00001D);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* see https://issues.apache.org/jira/browse/LUCENE-1815 for details
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDecodeEncode() {
|
||||||
|
String geoHash = "u173zq37x014";
|
||||||
|
assertEquals(geoHash, GeoHashUtils.encode(52.3738007, 4.8909347));
|
||||||
|
double[] decode = GeoHashUtils.decode(geoHash);
|
||||||
|
assertEquals(52.37380061d, decode[0], 0.000001d);
|
||||||
|
assertEquals(4.8909343d, decode[1], 0.000001d);
|
||||||
|
|
||||||
|
assertEquals(geoHash, GeoHashUtils.encode(decode[0], decode[1]));
|
||||||
|
|
||||||
|
geoHash = "u173";
|
||||||
|
decode = GeoHashUtils.decode("u173");
|
||||||
|
geoHash = GeoHashUtils.encode(decode[0], decode[1]);
|
||||||
|
assertEquals(decode[0], GeoHashUtils.decode(geoHash)[0], 0.000001d);
|
||||||
|
assertEquals(decode[1], GeoHashUtils.decode(geoHash)[1], 0.000001d);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package org.apache.lucene.spatial.geometry;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link org.apache.lucene.spatial.geometry.DistanceUnits}
|
||||||
|
*/
|
||||||
|
public class TestDistanceUnits {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass condition: When finding the DistanceUnit for "km", KILOMETRES is found. When finding the DistanceUnit for
|
||||||
|
* "miles", MILES is found.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testFindDistanceUnit() {
|
||||||
|
assertEquals(DistanceUnits.KILOMETERS, DistanceUnits.findDistanceUnit("km"));
|
||||||
|
assertEquals(DistanceUnits.MILES, DistanceUnits.findDistanceUnit("miles"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass condition: Searching for the DistanceUnit of an unknown unit "mls" should throw an IllegalArgumentException.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testFindDistanceUnit_unknownUnit() {
|
||||||
|
try {
|
||||||
|
DistanceUnits.findDistanceUnit("mls");
|
||||||
|
assertTrue("IllegalArgumentException should have been thrown", false);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass condition: Converting between the same units should not change the value. Converting from MILES to KILOMETRES
|
||||||
|
* involves multiplying the distance by the ratio, and converting from KILOMETRES to MILES involves dividing by the ratio
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvert() {
|
||||||
|
assertEquals(10.5, DistanceUnits.MILES.convert(10.5, DistanceUnits.MILES), 0D);
|
||||||
|
assertEquals(10.5, DistanceUnits.KILOMETERS.convert(10.5, DistanceUnits.KILOMETERS), 0D);
|
||||||
|
assertEquals(10.5 * 1.609344, DistanceUnits.KILOMETERS.convert(10.5, DistanceUnits.MILES), 0D);
|
||||||
|
assertEquals(10.5 / 1.609344, DistanceUnits.MILES.convert(10.5, DistanceUnits.KILOMETERS), 0D);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue