Skip to content
This repository has been archived by the owner on May 17, 2021. It is now read-only.

Commit

Permalink
Require PointType(String) to throw exception on bad arg
Browse files Browse the repository at this point in the history
Make PointType.valueOf a static method like in ESH
Return parseable string from PointType.toString() just like ESH
Moved implementation of LocationItem.distanceFrom to PointType.distanceFrom
Changed LocationItem.distanceFrom(PointType) to LocationItem.distanceFrom(LocationItem) and delegate to PointType.distanceFrom
Updated LocationItemTest to match above.
  • Loading branch information
watou committed Nov 15, 2015
1 parent 5977a1c commit 538b607
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ public void testDistance() {
LocationItem locationBerlin = new LocationItem("berlin");
locationBerlin.setState(pointBerlin);

DecimalType distance = locationParis.distanceFrom(pointParis);
DecimalType distance = locationParis.distanceFrom(locationParis);
assertEquals(distance.intValue(),0);

double parisBerlin = locationParis.distanceFrom(pointBerlin).doubleValue();
double parisBerlin = locationParis.distanceFrom(locationBerlin).doubleValue();
assertEquals(parisBerlin,878400,50);

double gravParis = pointParis.getGravity().doubleValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,16 @@ public List<Class<? extends Command>> getAcceptedCommandTypes() {
}

/**
* Compute the distance with another Point type,
* http://stackoverflow.com/questions/837872/calculate-distance-in-meters-when-you-know-longitude-and-latitude-in-java
* Return the distance from another LocationItem.
* @return distance between the two points in meters
*/
public DecimalType distanceFrom(PointType away){

double dist = -1;

if ((away != null) && (this.state instanceof PointType)) {

PointType me = (PointType) this.state;

double dLat = Math.pow(Math.sin(Math.toRadians(away.getLatitude().doubleValue() - me.getLatitude().doubleValue()) / 2),2);
double dLng = Math.pow(Math.sin(Math.toRadians(away.getLongitude().doubleValue() - me.getLongitude().doubleValue()) / 2),2);
double a = dLat + Math.cos(Math.toRadians(me.getLatitude().doubleValue()))
* Math.cos(Math.toRadians(away.getLatitude().doubleValue())) * dLng;

dist = PointType.WGS84_a * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
public DecimalType distanceFrom(LocationItem awayItem) {
if (awayItem != null && awayItem.state instanceof PointType && this.state instanceof PointType) {
PointType thisPoint = (PointType)this.state;
PointType awayPoint = (PointType)awayItem.state;
return thisPoint.distanceFrom(awayPoint);
}

return new DecimalType(dist);
return new DecimalType(-1);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;
import org.openhab.core.types.Command;
import org.openhab.core.types.ComplexType;
import org.openhab.core.types.PrimitiveType;
Expand Down Expand Up @@ -74,15 +75,18 @@ public PointType(StringType latitude, StringType longitude,
}

public PointType(String value) {
if (!value.isEmpty()) {
if (StringUtils.isNotBlank(value)) {
String[] elements = value.split(",");
if (elements.length >= 2) {
canonicalize(new DecimalType(elements[0]), new DecimalType(
elements[1]));
canonicalize(new DecimalType(elements[0]), new DecimalType(elements[1]));
if (elements.length == 3) {
setAltitude(new DecimalType(elements[2]));
}
} else {
throw new IllegalArgumentException(value + " is not a valid PointType syntax");
}
} else {
throw new IllegalArgumentException("Constructor argument must not be blank");
}
}

Expand Down Expand Up @@ -112,6 +116,25 @@ public DecimalType getGravity() {
return new DecimalType(result);
}

/**
* Return the distance in meters from otherPoint, ignoring altitude. This algorithm also
* ignores the oblate spheroid shape of Earth and assumes a perfect sphere, so results
* are inexact.
*
* @param otherPoint
* @return distance in meters
* @see <a href="https://en.wikipedia.org/wiki/Haversine_formula">Haversine formula</a>
*/
public DecimalType distanceFrom(PointType otherPoint) {
double dLat = Math.toRadians(otherPoint.latitude.doubleValue() - this.latitude.doubleValue());
double dLong = Math.toRadians(otherPoint.longitude.doubleValue() - this.longitude.doubleValue());
double a = Math.pow(Math.sin(dLat / 2D), 2D) + Math.cos(Math.toRadians(this.latitude.doubleValue()))
* Math.cos(Math.toRadians(otherPoint.latitude.doubleValue()))
* Math.pow(Math.sin(dLong / 2D), 2D);
double c = 2D * Math.atan2(Math.sqrt(a), Math.sqrt(1D - a));
return new DecimalType(WGS84_a * c);
}

/**
* <p>
* Formats the value of this type according to a pattern (@see
Expand All @@ -129,13 +152,20 @@ public String format(String pattern) {
return String.format(pattern, getConstituents().values().toArray());
}

public PointType valueOf(String value) {
public static PointType valueOf(String value) {
return new PointType(value);
}

@Override
public String toString() {
return String.format("%1$.2f°N, %2$.2f°W, %3$.2f m", latitude, longitude, altitude);
StringBuilder sb = new StringBuilder(latitude.toPlainString());
sb.append(',');
sb.append(longitude.toPlainString());
if (!altitude.equals(BigDecimal.ZERO)) {
sb.append(',');
sb.append(altitude.toPlainString());
}
return sb.toString();
}

@Override
Expand Down

0 comments on commit 538b607

Please sign in to comment.