fixed kilometer calculation
This commit is contained in:
@@ -436,45 +436,133 @@ class WarehouseShippingNoteController extends TTCrud {
|
||||
die(json_encode(['success' => true, 'status' => 'USER_NO_CAR']));
|
||||
}
|
||||
|
||||
protected function geoAutocompleteAction() {
|
||||
$search = $this->request->q;
|
||||
$search = urlencode($search);
|
||||
$url = "https://nominatim.haid.in/search?q=$search&format=json&addressdetails=1";
|
||||
$data = json_decode(file_get_contents($url), true);
|
||||
$out = [];
|
||||
/**
|
||||
* Helper function to parse Google Geocoding API response into the format expected by the frontend.
|
||||
* @param array $components The address_components array from Google's response.
|
||||
* @return array The formatted address array.
|
||||
*/
|
||||
private function formatGoogleAddress(array $components): array {
|
||||
$address = [
|
||||
'house_number' => null,
|
||||
'road' => null,
|
||||
'postcode' => null,
|
||||
'city' => null,
|
||||
'town' => null,
|
||||
'village' => null,
|
||||
'residential' => null,
|
||||
'hamlet' => null,
|
||||
];
|
||||
|
||||
foreach ($data as $entry) {
|
||||
$parsedDisplayNameParts = [];
|
||||
foreach (explode(',', $entry['display_name']) as $part) {
|
||||
// if str_includes Bezirk remove it
|
||||
if (strpos($part, 'Bezirk') !== false) {
|
||||
continue;
|
||||
}
|
||||
$parsedDisplayNameParts[] = $part;
|
||||
foreach ($components as $component) {
|
||||
$types = $component['types'];
|
||||
if (in_array('street_number', $types)) {
|
||||
$address['house_number'] = $component['long_name'];
|
||||
}
|
||||
|
||||
if (!empty($out)) {
|
||||
foreach ($out as $key => $value) {
|
||||
if ($value['text'] === implode(',', $parsedDisplayNameParts)) {
|
||||
continue 2;
|
||||
}
|
||||
if (in_array('route', $types)) {
|
||||
$address['road'] = $component['long_name'];
|
||||
}
|
||||
if (in_array('postal_code', $types)) {
|
||||
$address['postcode'] = $component['long_name'];
|
||||
}
|
||||
if (in_array('locality', $types)) {
|
||||
$address['city'] = $component['long_name'];
|
||||
$address['town'] = $component['long_name']; // Town is often the same as city
|
||||
}
|
||||
// A village in Google can be sublocality or sublocality_level_1
|
||||
if (in_array('sublocality', $types) || in_array('sublocality_level_1', $types)) {
|
||||
$address['village'] = $component['long_name'];
|
||||
}
|
||||
if (in_array('neighborhood', $types)) {
|
||||
$address['residential'] = $component['long_name'];
|
||||
if (!$address['village']) { // Fallback for village if not already set
|
||||
$address['village'] = $component['long_name'];
|
||||
}
|
||||
}
|
||||
$out[] = ['value' => $entry['lat'] . "," . $entry['lon'] . (!isset($entry['address']['house_number']) ? ", area" : ""), 'text' => implode(',', $parsedDisplayNameParts)];
|
||||
}
|
||||
|
||||
// If city is null, try to find it in administrative areas
|
||||
if (!$address['city']) {
|
||||
foreach ($components as $component) {
|
||||
if (in_array('administrative_area_level_3', $component['types'])) {
|
||||
$address['city'] = $component['long_name'];
|
||||
$address['town'] = $component['long_name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $address;
|
||||
}
|
||||
|
||||
protected function geoAutocompleteAction() {
|
||||
$search = urlencode($this->request->q);
|
||||
$apiKey = TT_GEOCODING_API_SECRET;
|
||||
// Bias search results for Austria (AT) in German (de)
|
||||
$url = TT_GEOCODING_API_URL . "?address=$search&key=$apiKey®ion=at&language=de&components=country:AT";
|
||||
|
||||
$response = @file_get_contents($url);
|
||||
if ($response === false) {
|
||||
self::returnJson([]);
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($response, true);
|
||||
$out = [];
|
||||
|
||||
if ($data['status'] === 'OK') {
|
||||
foreach ($data['results'] as $entry) {
|
||||
$lat = $entry['geometry']['location']['lat'];
|
||||
$lng = $entry['geometry']['location']['lng'];
|
||||
$text = $entry['formatted_address'];
|
||||
|
||||
$hasHouseNumber = false;
|
||||
foreach ($entry['address_components'] as $component) {
|
||||
if (in_array('street_number', $component['types'])) {
|
||||
$hasHouseNumber = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$value = $lat . "," . $lng . (!$hasHouseNumber ? ", area" : "");
|
||||
|
||||
// Deduplication logic from original code
|
||||
$isDuplicate = false;
|
||||
foreach ($out as $existing) {
|
||||
if ($existing['text'] === $text) {
|
||||
$isDuplicate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$isDuplicate) {
|
||||
$out[] = ['value' => $value, 'text' => $text];
|
||||
}
|
||||
}
|
||||
}
|
||||
self::returnJson($out);
|
||||
}
|
||||
|
||||
protected function geoReverseAction() {
|
||||
$lat = $this->request->lat;
|
||||
$lon = $this->request->lon;
|
||||
$url = "https://nominatim.haid.in/reverse?lat=$lat&lon=$lon&format=json&addressdetails=1";
|
||||
$data = json_decode(file_get_contents($url), true);
|
||||
self::returnJson(is_array($data) ? $data : ['data' => $data]);
|
||||
}
|
||||
$apiKey = TT_GEOCODING_API_SECRET;
|
||||
$url = TT_GEOCODING_API_URL . "?latlng=$lat,$lon&key=$apiKey&language=de";
|
||||
|
||||
$response = @file_get_contents($url);
|
||||
if ($response === false) {
|
||||
self::returnJson(['address' => [], 'error' => 'REQUEST_FAILED', 'error_message' => 'Could not connect to Google Maps API.']);
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if ($data['status'] === 'OK' && !empty($data['results'])) {
|
||||
$addressComponents = $data['results'][0]['address_components'];
|
||||
$formattedAddress = $this->formatGoogleAddress($addressComponents);
|
||||
self::returnJson(['address' => $formattedAddress]);
|
||||
} else {
|
||||
self::returnJson(['address' => [], 'error' => $data['status'], 'error_message' => $data['error_message'] ?? 'Reverse geocoding failed.']);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: export this to an api class for openstreetmap
|
||||
protected function getDistanceAction() {
|
||||
@@ -486,7 +574,6 @@ class WarehouseShippingNoteController extends TTCrud {
|
||||
self::returnJson(json_decode($data, true));
|
||||
}
|
||||
|
||||
|
||||
$from = $this->request->from;
|
||||
$to = $this->request->to;
|
||||
$from = urlencode($from);
|
||||
@@ -497,47 +584,66 @@ class WarehouseShippingNoteController extends TTCrud {
|
||||
return [['lat' => 46.99555015, 'lon' => 15.77507876755547]];
|
||||
}
|
||||
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => "https://nominatim.haid.in/search?q=$address&format=json",
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_ENCODING => "",
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => "GET",
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"accept: application/json",
|
||||
"accept-language: de-AT,de;q=0.9,en;q=0.8",
|
||||
"origin: https://routing.openstreetmap.de",
|
||||
"referer: https://routing.openstreetmap.de/",
|
||||
"user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
|
||||
],
|
||||
]);
|
||||
$address = urlencode($address);
|
||||
$apiKey = TT_GEOCODING_API_SECRET;
|
||||
// Bias search results for Austria
|
||||
$url = TT_GEOCODING_API_URL . "?address=$address&key=$apiKey®ion=at&components=country:AT";
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$err = curl_error($curl);
|
||||
|
||||
if ($err) {
|
||||
die(json_encode(['success' => false, 'message' => 'Error while geocoding']));
|
||||
$response = @file_get_contents($url);
|
||||
if ($response === false) {
|
||||
die(json_encode(['success' => false, 'message' => 'Error while geocoding: API connection failed.']));
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
return json_decode($response, true);
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if ($data['status'] === 'OK' && !empty($data['results'])) {
|
||||
$location = $data['results'][0]['geometry']['location'];
|
||||
// The OSRM routing engine expects 'lon', so we map Google's 'lng' to 'lon'.
|
||||
return [['lat' => $location['lat'], 'lon' => $location['lng']]];
|
||||
} else {
|
||||
die(json_encode(['success' => false, 'message' => 'Error while geocoding: ' . ($data['error_message'] ?? $data['status'])]));
|
||||
}
|
||||
}
|
||||
|
||||
function route($from, $to) {
|
||||
// The geocode() function (which you've already updated to use Google)
|
||||
// will provide the necessary coordinates. It will `die()` on error, so we can
|
||||
// assume we have valid data if the script continues.
|
||||
$fromData = geocode($from);
|
||||
$toData = geocode($to);
|
||||
|
||||
$fromLat = $fromData[0]['lat'];
|
||||
$fromLon = $fromData[0]['lon'];
|
||||
$toLat = $toData[0]['lat'];
|
||||
$toLon = $toData[0]['lon'];
|
||||
$url = "https://router.project-osrm.org/route/v1/driving/$fromLon,$fromLat;$toLon,$toLat?overview=false";
|
||||
$data = json_decode(file_get_contents($url), true);
|
||||
$distance = $data['routes'][0]['distance'];
|
||||
return $distance * 2;
|
||||
|
||||
$apiKey = TT_GEOCODING_API_SECRET;
|
||||
$url = "https://maps.googleapis.com/maps/api/directions/json" .
|
||||
"?origin={$fromLat},{$fromLon}" .
|
||||
"&destination={$toLat},{$toLon}" .
|
||||
"&key={$apiKey}" .
|
||||
"&mode=driving" .
|
||||
"®ion=at"; // Bias results for Austria
|
||||
|
||||
$response = @file_get_contents($url);
|
||||
if ($response === false) {
|
||||
die(json_encode(['success' => false, 'message' => 'Could not connect to Google Directions API.']));
|
||||
}
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
// Check for a successful response and if a route was found
|
||||
if ($data['status'] === 'OK' && !empty($data['routes'])) {
|
||||
// The distance is provided in meters in the first "leg" of the first "route"
|
||||
$distance = $data['routes'][0]['legs'][0]['distance']['value'];
|
||||
|
||||
// Return the round-trip distance
|
||||
return $distance * 2;
|
||||
} else {
|
||||
// Handle cases where no route is found or another API error occurred
|
||||
$errorMessage = $data['error_message'] ?? 'No route could be found between the locations.';
|
||||
die(json_encode(['success' => false, 'message' => "Routing Error: " . $errorMessage]));
|
||||
}
|
||||
}
|
||||
|
||||
$distance = route($from, $to);
|
||||
|
||||
Reference in New Issue
Block a user