Created
May 14, 2021 06:45
-
-
Save dimaslanjaka/df43624980171c0979fea59443890844 to your computer and use it in GitHub Desktop.
MapBox Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { margin:0; padding:0; } | |
#map { position:absolute; top:0; bottom:0; width:100%; } | |
#map { | |
position:absolute; | |
left:25%; | |
top:0; | |
bottom:0; | |
width: 75%; | |
} | |
.map-overlay { | |
position: absolute; | |
width: 25%; | |
top: 0; | |
bottom: 0; | |
left: 0; | |
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif; | |
background-color: #fff; | |
max-height: 100%; | |
overflow: hidden; | |
} | |
.map-overlay fieldset { | |
display: none; | |
background: #ddd; | |
border: none; | |
padding: 10px; | |
margin: 0; | |
} | |
.map-overlay input { | |
display: block; | |
border: none; | |
width: 100%; | |
border-radius: 3px; | |
padding: 10px; | |
margin: 0; | |
} | |
.map-overlay .listing { | |
overflow: auto; | |
max-height: 100%; | |
} | |
.map-overlay .listing > * { | |
display: block; | |
padding: 5px 10px; | |
margin: 0; | |
} | |
.map-overlay .listing a { | |
border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |
color: #404; | |
text-decoration: none; | |
} | |
.map-overlay .listing a:last-child { | |
border: none; | |
} | |
.map-overlay .listing a:hover { | |
background: #f0f0f0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.35.1/mapbox-gl.js'></script> | |
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.35.1/mapbox-gl.css' rel='stylesheet' /> | |
<link href='main.css' rel='stylesheet' /> | |
<script src='main.js' async></script> | |
<div id='map'></div> | |
<div class='map-overlay'> | |
<fieldset> | |
<input id='feature-filter' type='text' placeholder='Filter results by name' /> | |
</fieldset> | |
<div id='feature-listing' class='listing'></div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mapboxgl.accessToken = 'pk.eyJ1IjoiZGltYXNsYW5qYWthIiwiYSI6ImNrb254eDM4MzAxejgyd3F4bDF1aWhycGkifQ.lWod7dsXeO47iINNB05iew'; | |
var map = new mapboxgl.Map({ | |
container: 'map', | |
style: 'mapbox://styles/mapbox/streets-v9', | |
center: [-98, 38.88], | |
maxZoom: 5, | |
minZoom: 1, | |
zoom: 3 | |
}); | |
// Holds visible airport features for filtering | |
var airports = []; | |
// Create a popup, but don't add it to the map yet. | |
var popup = new mapboxgl.Popup({ | |
closeButton: false | |
}); | |
var filterEl = document.getElementById('feature-filter'); | |
var listingEl = document.getElementById('feature-listing'); | |
function renderListings(features) { | |
// Clear any existing listings | |
listingEl.innerHTML = ''; | |
if (features.length) { | |
features.forEach(function(feature) { | |
var prop = feature.properties; | |
var item = document.createElement('a'); | |
item.href = prop.wikipedia; | |
item.target = '_blank'; | |
item.textContent = prop.name + ' (' + prop.abbrev + ')'; | |
item.addEventListener('mouseover', function() { | |
// Highlight corresponding feature on the map | |
popup.setLngLat(feature.geometry.coordinates) | |
.setText(feature.properties.name + ' (' + feature.properties.abbrev + ')') | |
.addTo(map); | |
}); | |
listingEl.appendChild(item); | |
}); | |
// Show the filter input | |
filterEl.parentNode.style.display = 'block'; | |
} else { | |
var empty = document.createElement('p'); | |
empty.textContent = 'Drag the map to populate results'; | |
listingEl.appendChild(empty); | |
// Hide the filter input | |
filterEl.parentNode.style.display = 'none'; | |
// remove features filter | |
map.setFilter('airport', ['has', 'abbrev']); | |
} | |
} | |
function normalize(string) { | |
return string.trim().toLowerCase(); | |
} | |
function getUniqueFeatures(array, comparatorProperty) { | |
var existingFeatureKeys = {}; | |
// Because features come from tiled vector data, feature geometries may be split | |
// or duplicated across tile boundaries and, as a result, features may appear | |
// multiple times in query results. | |
var uniqueFeatures = array.filter(function(el) { | |
if (existingFeatureKeys[el.properties[comparatorProperty]]) { | |
return false; | |
} else { | |
existingFeatureKeys[el.properties[comparatorProperty]] = true; | |
return true; | |
} | |
}); | |
return uniqueFeatures; | |
} | |
map.on('load', function() { | |
map.addLayer({ | |
"id": "airport", | |
"source": { | |
"type": "vector", | |
"url": "mapbox://mapbox.04w69w5j" | |
}, | |
"source-layer": "ne_10m_airports", | |
"type": "symbol", | |
"layout": { | |
"icon-image": "airport-15", | |
"icon-padding": 0, | |
"icon-allow-overlap":true | |
} | |
}); | |
map.on('moveend', function() { | |
var features = map.queryRenderedFeatures({layers:['airport']}); | |
if (features) { | |
var uniqueFeatures = getUniqueFeatures(features, "iata_code"); | |
// Populate features for the listing overlay. | |
renderListings(uniqueFeatures); | |
// Clear the input container | |
filterEl.value = ''; | |
// Store the current features in sn `airports` variable to | |
// later use for filtering on `keyup`. | |
airports = uniqueFeatures; | |
} | |
}); | |
map.on('mousemove', 'airport', function(e) { | |
// Change the cursor style as a UI indicator. | |
map.getCanvas().style.cursor = 'pointer'; | |
// Populate the popup and set its coordinates based on the feature. | |
var feature = e.features[0]; | |
popup.setLngLat(feature.geometry.coordinates) | |
.setText(feature.properties.name + ' (' + feature.properties.abbrev + ')') | |
.addTo(map); | |
}); | |
map.on('mouseleave', 'airport', function() { | |
map.getCanvas().style.cursor = ''; | |
popup.remove(); | |
}); | |
filterEl.addEventListener('keyup', function(e) { | |
var value = normalize(e.target.value); | |
// Filter visible features that don't match the input value. | |
var filtered = airports.filter(function(feature) { | |
var name = normalize(feature.properties.name); | |
var code = normalize(feature.properties.abbrev); | |
return name.indexOf(value) > -1 || code.indexOf(value) > -1; | |
}); | |
// Populate the sidebar with filtered results | |
renderListings(filtered); | |
// Set the filter to populate features into the layer. | |
map.setFilter('airport', ['in', 'abbrev'].concat(filtered.map(function(feature) { | |
return feature.properties.abbrev; | |
}))); | |
}); | |
// Call this function on initialization | |
// passing an empty array to render an empty state | |
renderListings([]); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment