Created
June 30, 2021 04:32
-
-
Save highway900/ae038ca146f949d130a09353fd85c047 to your computer and use it in GitHub Desktop.
use map.on(<event> ...) to get the bounding box.
This file contains hidden or 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>Highlight features within a bounding box</title> | |
| <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> | |
| <link href="https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.css" rel="stylesheet"> | |
| <script src="https://api.mapbox.com/mapbox-gl-js/v2.3.1/mapbox-gl.js"></script> | |
| <script src="https://unpkg.com/[email protected]/dist/flatgeobuf-geojson.min.js"></script> | |
| <script src="https://unpkg.com/json-formatter-js"></script> | |
| <style> | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| } | |
| #cost { | |
| display: block; | |
| position: relative; | |
| margin: 20px auto; | |
| width: 50%; | |
| height: 40px; | |
| padding: 0px; | |
| border: none; | |
| border-radius: 3px; | |
| font-size: 12px; | |
| text-align: center; | |
| color: #fff; | |
| background: #ee8a65; | |
| } | |
| #map { | |
| position: absolute; | |
| top: 0; | |
| bottom: 0; | |
| width: 100%; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <style> | |
| .boxdraw { | |
| background: rgba(56, 135, 190, 0.1); | |
| border: 2px solid #3887be; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 0; | |
| height: 0; | |
| } | |
| </style> | |
| <div id="map"></div> | |
| <button id="cost">Your Fiber Home Passed Network Install Distance is: ??? <br>(Hold Shift and Click to Create a Box | |
| Selection)</button> | |
| <button id="header">test</button> | |
| <script> | |
| // TO MAKE THE MAP APPEAR YOU MUST | |
| // ADD YOUR ACCESS TOKEN FROM | |
| // https://account.mapbox.com | |
| mapboxgl.accessToken = 'pk.eyJ1IjoiZmhrIiwiYSI6ImNqczVveGNhdTAzanU0NG12NHF5anN0eG0ifQ.VKTajL9diCZk2afccGfbRw'; | |
| var map = new mapboxgl.Map({ | |
| container: 'map', | |
| style: 'mapbox://styles/mapbox/streets-v11', | |
| // center: [-98, 38.88], | |
| center: [8.8, 47.2], | |
| minZoom: 2, | |
| zoom: 3 | |
| }); | |
| // Disable default box zooming. | |
| map.boxZoom.disable(); | |
| // Create a popup, but don't add it to the map yet. | |
| var popup = new mapboxgl.Popup({ | |
| closeButton: false | |
| }); | |
| map.on('load', function () { | |
| var canvas = map.getCanvasContainer(); | |
| // Variable to hold the starting xy coordinates | |
| // when `mousedown` occured. | |
| var start; | |
| let startLngLat = []; | |
| // Variable to hold the current xy coordinates | |
| // when `mousemove` or `mouseup` occurs. | |
| var current; | |
| // Variable for the draw box element. | |
| var box; | |
| // map.fitBounds([-87.76005585013002, 33.42767364639681, -87.34698671203543, 33.014276881381846]); | |
| map.fitBounds([-73.36116172723975, 46.06264786003379, -69.88048561753695, 41.7784533368563]); | |
| // map.fitBounds([8.8, 47.2, 9.5, 55.3]); | |
| // Add a custom vector tileset source. The tileset used in | |
| // this example contains a feature for every county in the U.S. | |
| // Each county contains four properties. For example: | |
| // { | |
| // COUNTY: "Uintah County", | |
| // FIPS: 49047, | |
| // median-income: 62363, | |
| // population: 34576 | |
| // } | |
| map.addSource('solution', { | |
| 'type': 'vector', | |
| 'url': 'mapbox://fhk.capai6ra' | |
| }); | |
| map.addLayer( | |
| { | |
| 'id': 'solution', | |
| 'type': 'line', | |
| 'source': 'solution', | |
| 'source-layer': 'solution' | |
| }, | |
| 'settlement-label' | |
| ); // Place polygon under these labels. | |
| map.addLayer( | |
| { | |
| 'id': 'solution-highlighted', | |
| 'type': 'line', | |
| 'source': 'solution', | |
| 'source-layer': 'solution', | |
| 'filter': ['in', 'id', ''], | |
| 'paint': { | |
| "line-color": "rgb(255, 0, 0)", | |
| "line-width": 10 | |
| } | |
| }, | |
| 'settlement-label' | |
| ); // Place polygon under these labels. | |
| map.on('mousedown', (e) => { | |
| if (!(e.originalEvent.shiftKey && e.originalEvent.button === 0)) return; | |
| console.log('map.on.down', [e.lngLat.lng, e.lngLat.lat]); | |
| startLngLat = [e.lngLat.lng, e.lngLat.lat]; | |
| }) | |
| map.on('mouseup', (e) => { | |
| console.log('map.on.up', e, [start, mousePos(e.originalEvent)]); | |
| console.log('map.on.up', [startLngLat[0], startLngLat[1], e.lngLat.lng, e.lngLat.lat]); | |
| if (!(e.originalEvent.shiftKey && e.originalEvent.button === 0)) return; | |
| //updateResults([startLngLat[0], startLngLat[1], e.lngLat.lng, e.lngLat.lat]); | |
| startLngLat = []; | |
| }) | |
| // 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); | |
| // Return the xy coordinates of the mouse position | |
| function mousePos(e) { | |
| var rect = canvas.getBoundingClientRect(); | |
| return new mapboxgl.Point( | |
| e.clientX - rect.left - canvas.clientLeft, | |
| e.clientY - rect.top - canvas.clientTop | |
| ); | |
| } | |
| function mouseDown(e) { | |
| // Continue the rest of the function if the shiftkey is pressed. | |
| if (!(e.shiftKey && e.button === 0)) return; | |
| // Disable default drag zooming when the shift key is held down. | |
| map.dragPan.disable(); | |
| // Call functions for the following events | |
| document.addEventListener('mousemove', onMouseMove); | |
| document.addEventListener('mouseup', onMouseUp); | |
| document.addEventListener('keydown', onKeyDown); | |
| // Capture the first xy coordinates | |
| start = mousePos(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 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) { | |
| // Capture xy coordinates | |
| finish([start, mousePos(e)]); | |
| } | |
| function onKeyDown(e) { | |
| // If the ESC key is pressed | |
| if (e.keyCode === 27) finish(); | |
| } | |
| function finish(bbox) { | |
| // Remove these events now that finish has been called. | |
| document.removeEventListener('mousemove', onMouseMove); | |
| document.removeEventListener('keydown', onKeyDown); | |
| document.removeEventListener('mouseup', 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: ['solution'] | |
| }); | |
| if (features.length >= 100000) { | |
| return window.alert('Select a smaller number of features'); | |
| } | |
| var total_length = 0 | |
| features.forEach(function (feature) { | |
| total_length = total_length + feature.properties.id; | |
| }) | |
| const elem = document.getElementById("cost"); | |
| elem.innerText = "Your Fiber Home Passed Network Install Distance is: " + total_length + " miles"; | |
| console.log(elem.value) | |
| // Run through the selected features and set a filter | |
| // to match features with unique FIPS codes to activate | |
| // the `counties-highlighted` layer. | |
| var filter = features.reduce( | |
| function (memo, feature) { | |
| memo.push(feature.properties.id); | |
| return memo; | |
| }, | |
| ['in', 'id'] | |
| ); | |
| map.setFilter('solution-highlighted', filter); | |
| } | |
| map.dragPan.enable(); | |
| } | |
| map.on('mousemove', function (e) { | |
| var features = map.queryRenderedFeatures(e.point, { | |
| layers: ['solution-highlighted'] | |
| }); | |
| // Change the cursor style as a UI indicator. | |
| map.getCanvas().style.cursor = features.length ? 'pointer' : ''; | |
| if (!features.length) { | |
| popup.remove(); | |
| return; | |
| } | |
| var feature = features[0]; | |
| popup | |
| .setLngLat(e.lngLat) | |
| .setText(feature.properties.id) | |
| .addTo(map); | |
| }); | |
| // map.addSource('fgb', {'type': 'geojson'}); | |
| // optionally show some meta-data about the FGB file | |
| function handleHeaderMeta(headerMeta) { | |
| const header = document.getElementById('header') | |
| const formatter = new JSONFormatter(headerMeta, 10) | |
| while (header.firstChild) | |
| header.removeChild(header.firstChild) | |
| header.appendChild(formatter.render()) | |
| } | |
| async function updateResults(bounds) { | |
| //let bounds = [-88.6830418859433, 35.14535067587707, -84.77575812292764, 30.20346180002214]; | |
| let bb = { | |
| minX: bounds[0], | |
| maxX: bounds[1], | |
| minY: bounds[2], | |
| maxY: bounds[3], | |
| }; | |
| // Use flatgeobuf JavaScript API to iterate features as geojson. | |
| // Because we specify a bounding box, flatgeobuf will only fetch the relevant subset of data, | |
| // rather than the entire file. | |
| const iter = flatgeobuf.deserialize('https://flatgeobuf.septima.dk/population_areas.fgb', bb, handleHeaderMeta); | |
| const colorScale = ((d) => { | |
| return d > 750 ? '#800026' : | |
| d > 500 ? '#BD0026' : | |
| d > 250 ? '#E31A1C' : | |
| d > 100 ? '#FC4E2A' : | |
| d > 50 ? '#FD8D3C' : | |
| d > 25 ? '#FEB24C' : | |
| d > 10 ? '#FED976' : | |
| '#FFEDA0' | |
| }); | |
| for await (const feature of iter) { | |
| console.debug(feature); | |
| // map.getSource('fgb').setData(feature); | |
| } | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment