Last active
November 17, 2018 00:21
-
-
Save rkrueger11/7204eed73b46153ba7ba24f024baa24f to your computer and use it in GitHub Desktop.
Box Muti Select Service Area
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset='utf-8' /> | |
<title>Service Area Demo</title> | |
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js'></script> | |
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css' rel='stylesheet' /> | |
<style> | |
body { | |
margin: 0; | |
padding: 0; | |
} | |
#map { | |
position: absolute; | |
top: 0; | |
bottom: 0; | |
width: 100%; | |
} | |
#controls { | |
display: inline-flex; | |
flex-direction: column; | |
position: absolute; | |
right: 0px; | |
margin: 10%; | |
background: white; | |
} | |
button { | |
color: white; | |
border: none; | |
padding: 0; | |
border: 1px solid black; | |
font: inherit; | |
cursor: pointer; | |
outline: inherit; | |
} | |
</style> | |
</head> | |
<body> | |
<style> | |
.boxdraw { | |
background: rgba(6, 134, 34, 0.1); | |
border: 2px solid #05a305; | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 0; | |
height: 0; | |
} | |
</style> | |
<div id='map'></div> | |
<div id='controls'> | |
<button id='selection'><svg width="48px" height="48px" viewBox="0 0 32 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |
<!-- Generator: Sketch 52.3 (67297) - http://www.bohemiancoding.com/sketch --> | |
<title>Artboard</title> | |
<desc>Created with Sketch.</desc> | |
<defs> | |
<polyline id="path-1" points="9 -1.59872116e-14 17.5 -1.59872116e-14 17.5 17 0.5 17 0.5 8.5"></polyline> | |
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="17" height="17" fill="white"> | |
<use xlink:href="#path-1"></use> | |
</mask> | |
</defs> | |
<g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |
<g id="Group-2" transform="translate(5.000000, 6.000000)" stroke-width="2"> | |
<use id="Rectangle-Copy-3" stroke="#4A4A4A" mask="url(#mask-2)" stroke-dasharray="3,1" transform="translate(9.000000, 8.500000) rotate(-180.000000) translate(-9.000000, -8.500000) " xlink:href="#path-1"></use> | |
<g id="Group" transform="translate(12.500000, 12.000000)" stroke="#000000"> | |
<path d="M4.5,-2.66453526e-15 L4.5,9" id="Path"></path> | |
<path d="M9,4.5 L0,4.5" id="Path"></path> | |
</g> | |
</g> | |
</g> | |
</svg></button> | |
<button id='deselection'><svg width="48px" height="48px" viewBox="0 0 32 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |
<!-- Generator: Sketch 52.3 (67297) - http://www.bohemiancoding.com/sketch --> | |
<title>Artboard</title> | |
<desc>Created with Sketch.</desc> | |
<defs> | |
<polyline id="path-1" points="8.5 -1.59872116e-14 17 -1.59872116e-14 17 17 -3.19674842e-14 17 3.01980663e-14 8.5"></polyline> | |
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="17" height="17" fill="white"> | |
<use xlink:href="#path-1"></use> | |
</mask> | |
</defs> | |
<g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |
<g id="Group-3" transform="translate(6.000000, 6.000000)" stroke-width="2"> | |
<use id="Rectangle-Copy" stroke="#4A4A4A" mask="url(#mask-2)" stroke-dasharray="3,1" transform="translate(8.500000, 8.500000) rotate(-180.000000) translate(-8.500000, -8.500000) " xlink:href="#path-1"></use> | |
<g id="Group" transform="translate(12.000000, 16.000000)" stroke="#000000"> | |
<path d="M9,0.5 L0,0.5" id="Path"></path> | |
</g> | |
</g> | |
</g> | |
</svg> | |
</button> | |
</div> | |
<script> | |
mapboxgl.accessToken = 'pk.eyJ1IjoiY2xvdWRvcHNhZG1pbnMiLCJhIjoiY2puYnI3emg5MGM4cTNrcGs4andxOXRvYyJ9.OEY_B7yNuD6YQwAL6xN1YQ'; | |
var map = new mapboxgl.Map({ | |
container: 'map', | |
style: 'mapbox://styles/cloudopsadmins/cjokpgicj0cmu2sojfa6zpkb9', | |
center: [-86.158, 39.768], | |
minZoom: 4, | |
zoom: 10 | |
}); | |
let selectionButtonOn = false; | |
let deselectionButtonOn = false; | |
// Disable default box zooming. | |
map.boxZoom.disable(); | |
map.dragRotate.disable(); | |
// Create a popup, but don't add it to the map yet. | |
var popup = new mapboxgl.Popup({ | |
closeButton: false | |
}); | |
var selectedPostalCodes = ["USP446201", | |
"USP446204", | |
"USP446205", | |
"USP446208", | |
"USP446218", | |
"USP446220", | |
"USP446222", | |
"USP446225"]; | |
map.on('load', function () { | |
const mouseText = document.getElementById('mouse'); | |
var canvas = map.getCanvasContainer(); | |
canvas.style.cursor = 'pointer'; | |
// Variable to hold the starting xy coordinates | |
// when `mousedown` occured. | |
var start; | |
// Variable to hold the current xy coordinates | |
// when `mousemove` or `mouseup` occurs. | |
var current; | |
// Variable for the draw box element. | |
var box; | |
// Add the source to query. In this example we're using | |
// county polygons uploaded as vector tiles | |
map.addSource('postal-4', { | |
"type": "vector", | |
"url": "mapbox://mapbox.enterprise-boundaries-p4-v2" | |
}); | |
map.addLayer({ | |
"id": "postal", | |
"type": "fill", | |
"source": "postal-4", | |
"source-layer": "boundaries_postal_4", | |
"paint": { | |
"fill-color": "rgba(0,0,0,0)", | |
"fill-outline-color": "rgba(0,0,0,0)" | |
} | |
}, 'place-city-sm'); // Place polygon under these labels. | |
map.addLayer({ | |
"id": "postal-highlighted", | |
"type": "fill", | |
"source": "postal-4", | |
"source-layer": "boundaries_postal_4", | |
"paint": { | |
"fill-outline-color": "#05a305", | |
"fill-color": "rgba(6, 134, 34, 0.5)", | |
"fill-opacity": 0.75 | |
}, | |
"filter": [ | |
"in", | |
"id", | |
...selectedPostalCodes, | |
] | |
}, 'place-city-sm'); // Place polygon under these labels. | |
// Click/Tap to select | |
map.on("click", "postal", e => { | |
selectedPostalCodes.push(e.features[0].properties.id); | |
map.setFilter("postal-highlighted", ["in", | |
"id", | |
...selectedPostalCodes]); | |
}); | |
// Click/Tap to deselect | |
map.on("click", "postal-highlighted", e => { | |
selectedPostalCodes = selectedPostalCodes.filter((code) => code != e.features[0].properties.id); | |
map.setFilter("postal-highlighted", ["in", | |
"id", | |
...selectedPostalCodes]); | |
}); | |
document.addEventListener('keydown', (e) => { | |
if (e.key === "Meta") { | |
deselectionButtonOn = true; | |
canvas.style.cursor = 'crosshair'; | |
map.dragPan.disable(); | |
} | |
if (e.key === "Shift") { | |
selectionButtonOn = true; | |
canvas.style.cursor = 'crosshair'; | |
map.dragPan.disable(); | |
} | |
}); | |
document.addEventListener('keyup', (e) => { | |
if (e.key === "Meta") { | |
deselectionButtonOn = false; | |
canvas.style.cursor = 'grab'; | |
} | |
if (e.key === "Shift") { | |
selectionButtonOn = false; | |
canvas.style.cursor = 'grab'; | |
} | |
}); | |
// Set `true` to dispatch the event before other functions | |
// call it. This is necessary for disabling the default map | |
// dragging behaviour. | |
canvas.addEventListener('mousedown', mouseDown, true); | |
canvas.addEventListener('touchstart', mouseDown, true); | |
// Return the xy coordinates of the mouse position | |
function mousePos(e) { | |
var rect = canvas.getBoundingClientRect(); | |
let clientX = e.clientX || (e.touches[0] ? e.touches[0].clientX : e.changedTouches[0].clientX); | |
let clientY = e.clientY || (e.touches[0] ? e.touches[0].clientY : e.changedTouches[0].clientY); | |
return new mapboxgl.Point( | |
clientX - rect.left - canvas.clientLeft, | |
clientY - rect.top - canvas.clientTop | |
); | |
} | |
function mouseDown(e) { | |
// Continue the rest of the function if selection or deselction is toggled on, through keypress or icon | |
if (!(selectionButtonOn || deselectionButtonOn)) return; | |
// Call functions for the following events | |
document.addEventListener('mousemove', onMouseMove); | |
document.addEventListener('touchmove', onTouchMove, { passive: false }); | |
document.addEventListener('mouseup', onMouseUp); | |
document.addEventListener('touchend', onMouseUp); | |
document.addEventListener('keydown', onKeyDown); | |
// Capture the first xy coordinates | |
start = mousePos(e); | |
} | |
function onTouchMove(e) { | |
e.preventDefault(); | |
onMouseMove(e); | |
} | |
function onMouseMove(e) { | |
// Capture the ongoing xy coordinates | |
current = mousePos(e); | |
// Append the box element if it doesnt exist | |
if (!box) { | |
box = document.createElement('div'); | |
box.classList.add('boxdraw'); | |
canvas.appendChild(box); | |
} | |
var minX = Math.min(start.x, current.x), | |
maxX = Math.max(start.x, current.x), | |
minY = Math.min(start.y, current.y), | |
maxY = Math.max(start.y, current.y); | |
// Adjust box style based on selection/deselection | |
if (selectionButtonOn) { | |
box.style.background = 'rgba(6, 134, 34, 0.1)'; | |
box.style.border = '2px solid #05a305'; | |
} else if (deselectionButtonOn) { | |
box.style.background = 'rgba(134, 6, 34, 0.1)'; | |
box.style.border = '2px solid rgb(134, 6, 34)'; | |
} | |
// Adjust width and xy position of the box element ongoing | |
var pos = 'translate(' + minX + 'px,' + minY + 'px)'; | |
box.style.transform = pos; | |
box.style.WebkitTransform = pos; | |
box.style.width = maxX - minX + 'px'; | |
box.style.height = maxY - minY + 'px'; | |
} | |
function onMouseUp(e) { | |
let mode = selectionButtonOn ? "select" : "deselect"; | |
// Capture xy coordinates | |
finish([start, mousePos(e)], mode); | |
// Reset Button Toggles | |
selectionButtonOn = false; | |
deselectionButtonOn = false; | |
// Reset Map Style | |
canvas.style.cursor = 'grab'; | |
} | |
function onKeyDown(e) { | |
// If the ESC key is pressed | |
if (e.keyCode === 27) finish(); | |
} | |
function finish(bbox, mode) { | |
// Remove these events now that finish has been called. | |
document.removeEventListener('mousemove', onMouseMove); | |
document.removeEventListener('touchmove', onTouchMove, { passive: false }); | |
document.removeEventListener('keydown', onKeyDown); | |
document.removeEventListener('mouseup', onMouseUp); | |
document.removeEventListener('touchend', onMouseUp); | |
if (box) { | |
box.parentNode.removeChild(box); | |
box = null; | |
} | |
// If bbox exists. use this value as the argument for `queryRenderedFeatures` | |
if (bbox) { | |
var features = map.queryRenderedFeatures(bbox, { layers: ['postal'] }); | |
// if (features.length >= 1000) { | |
// return window.alert('Select a smaller number of features'); | |
// } | |
// Run through the selected features and set a filter | |
// to match features with unique FIPS codes to activate | |
// the `counties-highlighted` layer. | |
if (mode === 'select') { | |
features.map(function (feature) { | |
selectedPostalCodes.push(feature.properties.id); | |
}); | |
} else if (mode === 'deselect') { | |
selectedPostalCodes = selectedPostalCodes.filter((code) => !features.map(f => f.properties.id).includes(code)); | |
} | |
map.setFilter("postal-highlighted", ["in", | |
"id", | |
...selectedPostalCodes]); | |
} | |
map.dragPan.enable(); | |
} | |
map.on('mousemove', function (e) { | |
var features = map.queryRenderedFeatures(e.point, { layers: ['postal'] }); | |
if (!features.length) { | |
popup.remove(); | |
return; | |
} | |
var feature = features[0]; | |
// popup.setLngLat(e.lngLat) | |
// .setText(feature.properties.id.slice(4)) | |
// .addTo(map); | |
}); | |
document.getElementById('selection').addEventListener('click', function () { | |
selectionButtonOn = true; | |
deselectionButtonOn = false; | |
canvas.style.cursor = 'crosshair'; | |
map.dragPan.disable(); | |
}); | |
document.getElementById('deselection').addEventListener('click', function () { | |
selectionButtonOn = false; | |
deselectionButtonOn = true; | |
canvas.style.cursor = 'crosshair'; | |
map.dragPan.disable(); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment