34935-vm/api/hurricanes.php
2025-10-14 02:28:06 +00:00

118 lines
3.6 KiB
PHP

<?php
header('Content-Type: application/json');
// URL for the NHC active hurricane KML data
$nhc_kmz_url = 'https://www.nhc.noaa.gov/gis/kml/nhc.kmz';
// Temporary file to store the KMZ
$tmp_kmz_file = tempnam(sys_get_temp_dir(), 'nhc_kmz');
// Fetch the KMZ file
$kmz_data = file_get_contents($nhc_kmz_url);
if ($kmz_data === false) {
echo json_encode(['error' => 'Failed to fetch NHC data.']);
exit;
}
// Save the data to the temporary file
file_put_contents($tmp_kmz_file, $kmz_data);
if (!class_exists('ZipArchive')) {
echo json_encode(['error' => 'ZipArchive class does not exist.']);
exit;
}
// Use ZipArchive to open the KMZ file
$zip = new ZipArchive;
if ($zip->open($tmp_kmz_file) === TRUE) {
// NHC KMZ files typically contain a single KML file, often named doc.kml or similar.
// We will look for the first .kml file in the archive.
$kml_content = false;
for ($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
if (strtolower(substr($filename, -4)) === '.kml') {
$kml_content = $zip->getFromIndex($i);
break;
}
}
$zip->close();
if ($kml_content === false) {
echo json_encode(['error' => 'KML file not found in the KMZ archive.']);
exit;
}
// Parse the KML content
$xml = simplexml_load_string($kml_content, "SimpleXMLElement", LIBXML_NOCDATA);
if ($xml === false) {
echo json_encode(['error' => 'Failed to parse KML data.']);
exit;
}
// Register the KML namespace
$xml->registerXPathNamespace('kml', 'http://www.opengis.net/kml/2.2');
$features = [];
// Find all Placemarks in the KML
foreach ($xml->xpath('//kml:Placemark') as $placemark) {
$placemark->registerXPathNamespace('kml', 'http://www.opengis.net/kml/2.2');
$name = (string)$placemark->name;
// Look for Polygon
$polygon = $placemark->xpath('.//kml:Polygon');
if ($polygon && isset($polygon[0]->outerBoundaryIs->LinearRing->coordinates)) {
$coordinates_str = (string)$polygon[0]->outerBoundaryIs->LinearRing->coordinates;
$coordinates = parse_coordinates($coordinates_str);
if (!empty($coordinates)) {
$features[] = [
'name' => $name,
'type' => 'Polygon',
'coordinates' => $coordinates
];
}
}
// Look for LineString
$linestring = $placemark->xpath('.//kml:LineString');
if ($linestring && isset($linestring[0]->coordinates)) {
$coordinates_str = (string)$linestring[0]->coordinates;
$coordinates = parse_coordinates($coordinates_str);
if (!empty($coordinates)) {
$features[] = [
'name' => $name,
'type' => 'LineString',
'coordinates' => $coordinates
];
}
}
}
echo json_encode($features);
} else {
echo json_encode(['error' => 'Failed to open KMZ file.']);
}
// Clean up the temporary file
unlink($tmp_kmz_file);
function parse_coordinates($coordinates_str) {
$coords = [];
$pairs = explode(' ', trim($coordinates_str));
foreach ($pairs as $pair) {
$parts = explode(',', $pair);
if (count($parts) >= 2) {
$lon = floatval($parts[0]);
$lat = floatval($parts[1]);
// Ensure coordinates are valid
if (is_finite($lat) && is_finite($lon)) {
$coords[] = $lon;
$coords[] = $lat;
}
}
}
return $coords;
}
?>