Skip to content

Commit

Permalink
Add support for KML
Browse files Browse the repository at this point in the history
  • Loading branch information
pjaudiomv committed Oct 18, 2023
1 parent 733a544 commit b2adf95
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
build/
node_modules/
pages/
scratch.html
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# BMLT Data Converter

* Converts BMLT meeting data from a JSON endpoint to CSV
* Converts BMLT meeting data from a JSON endpoint to CSV or KML
* Note that export of KML is only supported with GetSearchResults.
160 changes: 145 additions & 15 deletions assets/js/main.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
function fetchMeetings(query, callback) {
let isProcessingCSV = false;
let isProcessingKML = false;

const fetchMeetings = (query, callback, isCSV, isKML) => {
const script = document.createElement("script");
script.src = query + "&callback=" + callback.name;
script.src = `${query}&callback=${callback.name}`;
document.body.appendChild(script);
}
isProcessingCSV = isCSV;
isProcessingKML = isKML;
};

const handleMeetingsData = (meetings) => {
if (isProcessingCSV) {
const csvContent = `data:text/csv;charset=utf-8,${encodeURIComponent(
convertToCSV(meetings),
)}`;
const downloadLink = document.getElementById("downloadLink");
downloadLink.href = csvContent;
downloadLink.style.display = "block";
}

function handleMeetingsData(meetings) {
const csvContent =
"data:text/csv;charset=utf-8," + encodeURIComponent(convertToCSV(meetings));
const downloadLink = document.getElementById("downloadLink");
downloadLink.href = csvContent;
downloadLink.style.display = "block";
}
if (isProcessingKML) {
const kmlContent = `data:text/xml;charset=utf-8,${encodeURIComponent(
convertToKML(meetings),
)}`;
const kmlDownloadLink = document.getElementById("kmlDownloadLink");
kmlDownloadLink.href = kmlContent;
kmlDownloadLink.style.display = "block";
}
};

function convertToCSV(data) {
const convertToCSV = (data) => {
const csvRows = [];
const keys = Object.keys(data[0]);

Expand All @@ -35,14 +52,127 @@ function convertToCSV(data) {
});

return csvRows.join("\n");
}
};

const convertToKML = (data) => {
const kmlHeader = `
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
`;

const kmlFooter = `
</Document>
</kml>`;

const placemarks = data.map((meeting) => {
const name = meeting["meeting_name"].trim() || "NA Meeting";
const lng = parseFloat(meeting["longitude"]);
const lat = parseFloat(meeting["latitude"]);

function exportToCSV() {
if (lng || lat) {
const description = prepareSimpleLine(meeting);
const address = prepareSimpleLine(meeting, false);

return (
` <Placemark>\n` +
` <name>${name}</name>\n` +
(address ? ` <address>${address}</address>\n` : "") +
(description
? ` <description>${description}</description>\n`
: "") +
` <Point>\n` +
` <coordinates>${lng},${lat}</coordinates>\n` +
` </Point>\n` +
` </Placemark>\n`
);
}
});

return kmlHeader + placemarks.join("\n") + kmlFooter;
};

const exportData = () => {
const query = document.getElementById("query").value;
if (!query.includes("/client_interface/jsonp")) {
alert("Invalid BMLT query URL, must use jsonp endpoint.");
return;
}
// Only support GetSearchResults for KML
const isKML = query.includes("GetSearchResults");
fetchMeetings(query, handleMeetingsData, true, isKML);
if (isKML) {
fetchMeetings(query, handleMeetingsData, true, true);
}
};

const prepareSimpleLine = (meeting, withDate = true) => {
const getLocationInfo = () => {
const locationInfo = [];
const addInfo = (property) => {
if (property in meeting) {
const value = meeting[property].trim();
if (value) {
locationInfo.push(value);
}
}
};

addInfo("location_text");
addInfo("location_street");
addInfo("location_city_subsection");
addInfo("location_municipality");
addInfo("location_neighborhood");
addInfo("location_province");
addInfo("location_postal_code_1");
addInfo("location_nation");
addInfo("location_info");

return locationInfo.join(", ");
};

const getDateString = () => {
const weekday_strings = [
"All",
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
const weekday = parseInt(meeting["weekday_tinyint"].trim());
const weekdayString = weekday_strings[weekday];

const startTime = `2000-01-01 ${meeting["start_time"]}`;
const time = new Date(startTime);

if (weekdayString && withDate) {
let dateString = weekdayString;

fetchMeetings(query, handleMeetingsData);
}
if (!isNaN(time)) {
dateString += `, ${time.toLocaleTimeString("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true,
})}`;
}

return dateString;
}

return "";
};

const locationInfo = getLocationInfo();
const dateString = getDateString();

if (withDate && dateString && locationInfo) {
return `${dateString}, ${locationInfo}`;
} else if (dateString) {
return dateString;
} else {
return locationInfo;
}
};
10 changes: 5 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<!DOCTYPE HTML>
<html>
<head>
<title>BMLT CSV Export</title>
<title>BMLT Data Converter</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
<h1>BMLT CSV Export</h1>
<h1>BMLT Data Converter</h1>
<div id="export-form">
<label for="query">BMLT URL Query:</label>
<input type="text" id="query" required>
<br>
<button onclick="exportToCSV()">Export CSV</button>
<button onclick="exportData()">Generate Export Data</button>
<a id="downloadLink" style="display: none;" download="BMLT_data.csv">Download CSV</a>
<a id="kmlDownloadLink" style="display: none;" download="BMLT_data.kml">Download KML</a>
</div>
<script src="assets/js/util.js"></script>
<script src="assets/js/main.js"></script>
</body>
</html>
</html>

0 comments on commit b2adf95

Please sign in to comment.