Determine if latitude/longitude is within the home radius

Does anyone know if there is a built-in way within Hubitat APIs to determine if a provided lat/log is within the radius of the home? Or is that something that I would have to code using the haversine formula myself?

Don't think it's built in.

I have a Groovy version of Haversine in my Purple Air driver if you want to use it:

3 Likes

Just curious if I could benefit from this too: where is the lat/lon coming from?

The lat/log is coming from a car. Here is the code that I wrote to solve it:

/**
 * Check if the coordinates are within the home radius.
 *
 * @param latitude The latitude of the current object.
 * @param longitude The longitude of the current object.
 * @param radius The radius the object should be within in meters or miles if.
 * @param radiusInMiles Use miles instead of meters for the radius.
 *
 * @return
 */
private Boolean isCoordinatesInHomeRadius(
    Number latitude,
    Number longitude,
    Number radius,
    Boolean radiusInMiles = false
) {
    if (radiusInMiles) {
        radius *= 1609.34
    }

    Double distance = calculateDistance(
        latitude.doubleValue(),
        longitude.doubleValue(),
        location.getLatitude().doubleValue(),
        location.getLongitude().doubleValue(),
    )

    return distance <= radius
}

/**
 * Calculate the distance between two points using the Haversine formula.
 *
 * @param lat1 The latitude of the first point, in degrees.
 * @param lon1 The longitude of the first point, in degrees.
 * @param lat2 The latitude of the second point, in degrees.
 * @param lon2 The longitude of the second point, in degrees.
 *
 * @return The distance between the two points, in meters.
 */
private Double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
    final int earthRadius = 6371 * 1000;

    def dLat = Math.toRadians(lat2 - lat1);
    def dLon = Math.toRadians(lon2 - lon1);
    def a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2);
    def c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

    return earthRadius * c;
}
2 Likes