import Toybox.Communications; import Toybox.Lang; // Reverse-geocodes a lat/lon pair via Photon API. Calls back with // a formatted address string or null on failure. class GeocodingService { private var _callback as Method(address as String or Null) as Void; private var _lat as Float; private var _lon as Float; function initialize(lat as Float, lon as Float, callback as Method(address as String or Null) as Void) { _callback = callback; _lat = lat; _lon = lon; } function start() as Void { var url = Config.PHOTON_URL; var params = { "lon" => _lon, "lat" => _lat, "limit" => 1 }; var options = { :method => Communications.HTTP_REQUEST_METHOD_GET, :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON, :headers => { "Accept" => "application/json" } }; Communications.makeWebRequest(url, params, options, method(:_onResponse)); } function _onResponse(responseCode as Number, data as Dictionary or String or Null) as Void { if (responseCode != 200 || data == null || !(data instanceof Dictionary)) { _callback.invoke(null); return; } var features = data["features"]; if (features == null || !(features instanceof Array) || features.size() == 0) { _callback.invoke(null); return; } var feature = features[0] as Dictionary; var props = feature["properties"] as Dictionary; var geometry = feature["geometry"] as Dictionary; // Haversine check: only use address if result is within threshold. if (geometry != null) { var coords = geometry["coordinates"] as Array; if (coords != null && coords.size() >= 2) { var rLon = (coords[0] as Double).toFloat(); var rLat = (coords[1] as Double).toFloat(); var dist = Haversine.distance(_lat, _lon, rLat, rLon); if (dist > Config.ADDRESS_MAX_DISTANCE_M) { _callback.invoke(null); return; } } } _callback.invoke(_formatAddress(props)); } private function _formatAddress(props as Dictionary) as String { var street = props["street"]; var number = props["housenumber"]; var city = props["city"]; var parts = ""; if (street != null) { parts = street as String; if (number != null) { parts = parts + " " + number; } } if (city != null) { if (!parts.equals("")) { parts = parts + ", "; } parts = parts + city; } return parts.equals("") ? "Unbekannt" : parts; } }