118 lines
3.6 KiB
PHP
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;
|
|
}
|
|
?>
|