Skip to content

Instantly share code, notes, and snippets.

@pjaudiomv
Last active May 6, 2023 18:55
Show Gist options
  • Select an option

  • Save pjaudiomv/5a8c8d16f425ed1a1c22264503f44e69 to your computer and use it in GitHub Desktop.

Select an option

Save pjaudiomv/5a8c8d16f425ed1a1c22264503f44e69 to your computer and use it in GitHub Desktop.
bmlt2kml.php
<?php
/*
bmlt2kml.php
This file converts a JSON BMLT GetSearchResults query to KML
To use run `php bmlt2kml.php` or place on your webserver and
specify a query param with a url encoded bmlt query url.
https://domain.com/bmlt2kml.php?query=https%3A%2F%2Flatest.aws.bmlt.app%2Fmain_server%2Fclient_interface%2Fjson%2F%3Fswitcher%3DGetSearchResults%26services%3D1010%26weekdays%3D2
*/
$cli_query = null;
if (!isset($_GET['query'])) {
echo "\e[1;35m\nEnter Your BMLT Url Query: \e[0m";
$cli_query = rtrim(fgets(STDIN));
}
if (!isset($cli_query) && !isset($_GET['query'])) {
echo "You must provide url to bmlt query";
exit(0);
}
$query = $cli_query ?? urldecode($_GET['query']);
if (!str_contains($query, "/client_interface/json/?switcher=GetSearchResults")) {
echo "BMLT query url is invalid";
exit(0);
}
$meetings = file_get_contents($query);
$meetings = json_decode($meetings, true);
$filename = 'BMLT' . date('_Y_m_d_H_i_s') . '.kml';
$file = isset($cli_query) ? $filename : 'php://output';
$file_pointer = fopen($file, 'w');
ob_start();
$dom = new DOMDocument('1.0', 'UTF-8');
$node = $dom->createElementNS('http://www.opengis.net/kml/2.2', 'kml');
$parNode = $dom->appendChild($node);
$dnode = $dom->createElement('Document');
$docNode = $parNode->appendChild($dnode);
foreach ($meetings as $meeting) {
$desc = prepareSimpleLine($meeting);
$address = prepareSimpleLine($meeting, false);
$name = htmlspecialchars(trim(stripslashes($meeting['meeting_name'])));
if (!$name) {
$name = "NA Meeting";
}
$lng = floatval($meeting['longitude']);
$lat = floatval($meeting['latitude']);
if ($lng || $lat) {
$placemarkNode = $dom->createElement('Placemark');
$placemarkNode = $dnode->appendChild($placemarkNode);
$name = $dom->createElement('name', $name);
$placemarkNode->appendChild($name);
if ($address) {
$address = $dom->createElement('address', $address);
$placemarkNode->appendChild($address);
}
if ($desc) {
$description = $dom->createElement('description', $desc);
$placemarkNode->appendChild($description);
}
$pointNode = $dom->createElement('Point');
$pointNode = $placemarkNode->appendChild($pointNode);
$coordinates = $dom->createElement('coordinates', htmlspecialchars($lng).','.htmlspecialchars($lat).',0');
$pointNode->appendChild($coordinates);
}
}
fwrite($file_pointer, $dom->saveXML());
if (isset($_GET['query'])) {
$data = ob_get_clean();
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=$filename");
echo $data;
ob_end_flush();
}
if (isset($cli_query)) {
echo "\e[1;35m\nFile has been outputted to current directory:\e[0m $filename";
}
fclose($file_pointer);
function prepareSimpleLine(
$meeting, /**< An associative array of meeting data */
$withDate = true /**< If false (default is true), the weekday and time will not be added. */
) {
$location_borough = array_key_exists('location_city_subsection', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_city_subsection']))) : "";
$location_neighborhood = array_key_exists('location_neighborhood', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_neighborhood']))) : "";
$location_province = array_key_exists('location_province', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_province']))) : "";
$location_nation = array_key_exists('location_nation', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_nation']))) : "";
$location_postal_code_1 = array_key_exists('location_postal_code_1', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_postal_code_1']))) : "";
$location_text = array_key_exists('location_text', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_text']))) : "";
$street = array_key_exists('location_street', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_street']))) : "";
$info = array_key_exists('location_info', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_info']))) : "";
$town = array_key_exists('location_municipality', $meeting) ? htmlspecialchars(trim(stripslashes($meeting['location_municipality']))) : "";
$desc = $withDate ? '' : $location_text;
if ($location_borough) {
$town = $location_borough;
}
if ($location_province) {
$town = "$town, $location_province";
}
if ($location_postal_code_1) {
$town = "$town, $location_postal_code_1";
}
if ($location_nation) {
$town = "$town, $location_nation";
}
if ($withDate && $location_neighborhood) {
$town = "$town ($location_neighborhood)";
}
if ($street) {
if ($desc) {
$desc .= ", ";
}
$desc .= $street;
}
if ($town) {
if ($desc) {
$desc .= ", ";
}
$desc .= $town;
}
if ($withDate && $info) {
if ($desc) {
$desc .= " ($info)";
} else {
$desc = $info;
}
}
$weekday = intval(trim(stripslashes($meeting['weekday_tinyint'])));
$time = date('g:i A', strtotime($meeting['start_time']));
$weekday_strings = array('All', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
$weekday = $weekday_strings[$weekday];
$ret = null;
if ($withDate && $weekday) {
$ret = $weekday;
}
if ($withDate && $time) {
if ($ret) {
$ret .= ', ';
}
$ret .= $time;
}
if ($ret) {
$ret .= ', ';
}
$ret .= $desc;
return $ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment