Example Overview
This example shows how to build a custom map interface using the embedded map and API. By applying query parameters, you can modify the map’s display, like changing zoom levels, highlighting specific locations, or filtering by categories. The API gives you the flexibility to adjust the map’s behavior to fit different use cases.
Available query parameters here.
Why is This Valuable?
Customizing the embedded map with the API and query parameters allows you to create a more tailored user experience. You can highlight important areas, focus on specific audiences, or make navigation easier by adjusting the map’s view. This approach makes it easier to deliver relevant information and improve user interaction with the map.
Example
<!DOCTYPE html>
<html lang="en">
<body>
<div style="width: 1100px; margin: 0 auto;">
<p>
The interactive map uses query parameters to create customized map displays.
<a href="https://help.concept3d.com/hc/en-us/articles/115004127673-Query-Strings">Available query parameters here</a>.
</p>
<div style="display: flex; gap: 20px; margin-bottom: 20px;">
<div style="flex: 1;">
<label for="categorySelect" style="font-size: 18px; margin-bottom: 10px; display: block;">Select a category to display on the map:</label>
<select id="categorySelect" onchange="updateCategory()" style="width: 100%; padding: 10px; border-radius: 5px; border: 1px solid #ccc; font-size: 16px;">
<option value="">-- Select a Category --</option>
</select>
</div>
<div style="flex: 1; display: none;" id="locationContainer">
<label for="locationSelect" style="font-size: 18px; margin-bottom: 10px; display: block;">Select a location:</label>
<select id="locationSelect" onchange="updateIframeByLocation()" style="width: 100%; padding: 10px; border-radius: 5px; border: 1px solid #ccc; font-size: 16px;">
<option value="">-- Select a Location --</option>
</select>
</div>
</div>
<!-- Map iframe -->
<div>
<iframe id="mapFrame" src="https://map.concept3d.com/?id=862&sbh" frameborder="0" scrolling="no" style="width: 100%; height: 900px;"></iframe>
</div>
<!-- Inline JavaScript -->
<script>
let categories;
// Add your map id here
const mapId = null;
// Add your API Key here
const apiKey = 'Your Api Key'
// Function to fetch categories from the API
async function fetchCategories() {
const url = `https://api.concept3d.com/categories?map=${mapId}&key=${apiKey}&full=true&parent=0`;
try {
const response = await fetch(url);
const data = await response.json();
populateCategories(data);
} catch (error) {
console.error('Error fetching categories:', error);
}
}
// Function to populate the dropdown with categories
function populateCategories(data) {
categories = data;
const categorySelect = document.getElementById('categorySelect');
categories.forEach(category => {
if (category.catId && category.name) {
const option = document.createElement('option');
option.value = category.catId;
option.textContent = category.name;
categorySelect.appendChild(option);
}
});
}
// Function to build the map URL
function urlBuilder(category) {
let url = `https://map.concept3d.com/?id=862&sbh#!ct/${category.catId}`;
if (category.lat && category.lng && category.mapAlt) {
url = `${url}?mc/${category.lat},${category.lng}?z/${altitudeToZoom(category.mapAlt)}`;
}
return url;
}
// Function to convert altitude to zoom level
function altitudeToZoom(altitude) {
return Math.round(26 - (Math.log(altitude) / Math.log(2)));
}
// Function to handle category selection
async function updateCategory() {
const categoryId = parseInt(document.getElementById('categorySelect').value);
const category = categories.find(cat => cat.catId === categoryId);
const locationContainer = document.getElementById('locationContainer');
const locationSelect = document.getElementById('locationSelect');
// Reset location selector
locationSelect.innerHTML = '<option value="">-- Select a Location --</option>';
if (category) {
// Update the map iframe to show the selected category
document.getElementById('mapFrame').src = urlBuilder(category);
// Fetch locations associated with the selected category
await fetchLocationsByCategory(categoryId);
// Show the location selector if locations are available
if (locationSelect.options.length > 1) {
locationContainer.style.display = 'block';
} else {
locationContainer.style.display = 'none';
}
} else {
// Hide the location selector if no category is selected
locationContainer.style.display = 'none';
}
}
// Function to fetch locations by category
async function fetchLocationsByCategory(categoryId) {
const url = `https://api.concept3d.com/locations?map=${mapId}&key=${apiKey}`;
try {
const response = await fetch(url);
const data = await response.json();
// Filter locations by categoryId
const locations = data.filter(location => location.catId === categoryId);
populateLocations(locations);
} catch (error) {
console.error('Error fetching locations:', error);
}
}
// Function to populate the location dropdown
function populateLocations(locations) {
const locationSelect = document.getElementById('locationSelect');
locations.forEach(location => {
if (location.id && location.name) {
const option = document.createElement('option');
option.value = location.id;
option.textContent = location.name;
locationSelect.appendChild(option);
}
});
}
// Function to update the iframe based on selected location
function updateIframeByLocation() {
const locationId = document.getElementById('locationSelect').value;
if (locationId) {
const url = `https://map.concept3d.com/?id=862&sbh#!m/${locationId}`;
document.getElementById('mapFrame').src = url;
}
}
// Function to copy code
function copyCode() {
const codeBlock = document.getElementById('codeblock').innerText;
const tempTextarea = document.createElement('textarea');
tempTextarea.value = codeBlock;
document.body.appendChild(tempTextarea);
tempTextarea.select();
document.execCommand('copy');
document.body.removeChild(tempTextarea);
alert('Code copied to clipboard!');
}
// Fetch categories on page load
fetchCategories();
</script>
</div>
</body>
</html>