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

Commit

Permalink
Merge pull request #3410 from watou/point-type-errors
Browse files Browse the repository at this point in the history
Fixes for PointType; added distanceFrom(otherPoint)
  • Loading branch information
watou committed Nov 17, 2015
2 parents 3af44ee + 538b607 commit 79faa5b
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 79faa5b

Please sign in to comment.