Uses exif location data to fill data.txt if empty
This commit is contained in:
parent
fc25d8e7f4
commit
3ea09af486
1 changed files with 81 additions and 0 deletions
81
admin.php
81
admin.php
|
|
@ -373,12 +373,93 @@ function read_data($dir){
|
|||
}
|
||||
return $data;
|
||||
}
|
||||
function location_language_for_country($countryCode){
|
||||
$map = ['dk'=>'da','de'=>'de','at'=>'de','ch'=>'de','hr'=>'hr','se'=>'sv','no'=>'no','fi'=>'fi','pl'=>'pl','cz'=>'cs','sk'=>'sk','fr'=>'fr','it'=>'it','es'=>'es','pt'=>'pt','nl'=>'nl','be'=>'nl','ba'=>'bs','rs'=>'sr','si'=>'sl','hu'=>'hu','gb'=>'en','uk'=>'en','ie'=>'en'];
|
||||
$countryCode = strtolower(trim((string)$countryCode));
|
||||
return $map[$countryCode] ?? 'en';
|
||||
}
|
||||
function nominatim_reverse_json($lat, $lon, $language){
|
||||
$url = 'https://nominatim.openstreetmap.org/reverse?' . http_build_query(['format'=>'jsonv2','lat'=>sprintf('%.8F', $lat),'lon'=>sprintf('%.8F', $lon),'addressdetails'=>'1','accept-language'=>$language]);
|
||||
$context = stream_context_create(['http'=>['method'=>'GET','header'=>'User-Agent: mvlog-admin/1.0 (reverse geocoding media metadata)\r\n','timeout'=>12]]);
|
||||
$json = @file_get_contents($url, false, $context);
|
||||
$data = $json !== false ? json_decode((string)$json, true) : null;
|
||||
return is_array($data) ? $data : [];
|
||||
}
|
||||
function reverse_geocode_place($lat, $lon){
|
||||
$cacheFile = __DIR__ . '/cache/reverse-geocode.json';
|
||||
$cache = is_file($cacheFile) ? json_decode((string)file_get_contents($cacheFile), true) : [];
|
||||
if (!is_array($cache)) $cache = [];
|
||||
$key = sprintf('%.5F,%.5F', $lat, $lon);
|
||||
if (isset($cache[$key]) && is_string($cache[$key])) return $cache[$key];
|
||||
$first = nominatim_reverse_json($lat, $lon, 'en');
|
||||
$countryCode = (string)($first['address']['country_code'] ?? '');
|
||||
$language = location_language_for_country($countryCode);
|
||||
$data = ($language === 'en') ? $first : nominatim_reverse_json($lat, $lon, $language);
|
||||
$address = is_array($data['address'] ?? null) ? $data['address'] : [];
|
||||
$city = (string)($address['city'] ?? $address['town'] ?? $address['village'] ?? $address['island'] ?? $address['suburb'] ?? $address['hamlet'] ?? $address['municipality'] ?? '');
|
||||
$country = (string)($address['country'] ?? '');
|
||||
$place = trim(implode(', ', array_filter([$city, $country], fn($v)=>trim((string)$v) !== '')));
|
||||
if ($place === '') $place = trim($country);
|
||||
if ($place !== '') {
|
||||
$cache[$key] = $place;
|
||||
@file_put_contents($cacheFile, json_encode($cache, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n", LOCK_EX);
|
||||
@chmod($cacheFile, 0664);
|
||||
}
|
||||
return $place;
|
||||
}
|
||||
function media_gps_coordinates($path){
|
||||
$exiftool = trim((string)shell_exec('command -v exiftool 2>/dev/null'));
|
||||
if ($exiftool === '' || !is_file($path)) return null;
|
||||
$cmd = escapeshellarg($exiftool) . ' -json -n -GPSLatitude -GPSLongitude -GPSCoordinates ' . escapeshellarg($path) . ' 2>/dev/null';
|
||||
$rows = json_decode((string)shell_exec($cmd), true);
|
||||
$row = is_array($rows) && isset($rows[0]) && is_array($rows[0]) ? $rows[0] : [];
|
||||
$lat = $row['GPSLatitude'] ?? null;
|
||||
$lon = $row['GPSLongitude'] ?? null;
|
||||
if ((!is_numeric($lat) || !is_numeric($lon)) && !empty($row['GPSCoordinates']) && preg_match('/(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)/', (string)$row['GPSCoordinates'], $m)) {
|
||||
$lat = $m[1];
|
||||
$lon = $m[2];
|
||||
}
|
||||
if (!is_numeric($lat) || !is_numeric($lon)) return null;
|
||||
$lat = (float)$lat;
|
||||
$lon = (float)$lon;
|
||||
if (abs($lat) < 0.000001 && abs($lon) < 0.000001) return null;
|
||||
return [$lat, $lon];
|
||||
}
|
||||
function infer_location_from_first_media($dir){
|
||||
foreach (visual_order_files($dir) as $name) {
|
||||
$gps = media_gps_coordinates($dir . '/' . $name);
|
||||
if (!$gps) continue;
|
||||
$place = reverse_geocode_place($gps[0], $gps[1]);
|
||||
if ($place !== '') return $place;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function display_month_year_from_media_datetime($value){
|
||||
$value = preg_replace('/[^0-9]/', '', (string)$value);
|
||||
if (strlen($value) < 8) return '';
|
||||
$year = (int)substr($value, 0, 4);
|
||||
$month = (int)substr($value, 4, 2);
|
||||
$day = (int)substr($value, 6, 2);
|
||||
if (!checkdate($month, $day, $year)) return '';
|
||||
return date('F Y', mktime(0, 0, 0, $month, $day, $year));
|
||||
}
|
||||
function infer_date_from_first_media($dir){
|
||||
foreach (visual_order_files($dir) as $name) {
|
||||
$date = media_file_date($dir . '/' . $name);
|
||||
if ($date === null) continue;
|
||||
$display = display_month_year_from_media_datetime($date);
|
||||
if ($display !== '') return $display;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function write_data($dir, $post){
|
||||
$title = trim($post['title'] ?? '');
|
||||
$teaser = trim($post['teaser'] ?? '');
|
||||
$quote_da = trim($post['quote_da'] ?? '');
|
||||
$place = trim($post['place'] ?? '');
|
||||
if ($place === '') $place = infer_location_from_first_media($dir);
|
||||
$date = trim($post['date'] ?? '');
|
||||
if ($date === '') $date = infer_date_from_first_media($dir);
|
||||
$description = trim($post['description'] ?? '');
|
||||
if (function_exists('mb_substr')) $description = mb_substr($description, 0, 5000, 'UTF-8'); else $description = substr($description, 0, 5000);
|
||||
$lines = [];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue