Skip to content

Instantly share code, notes, and snippets.

@smitty1eGH
Created November 23, 2019 18:10
Show Gist options
  • Save smitty1eGH/d47a326631d233904cef1d0aace7b843 to your computer and use it in GitHub Desktop.
Save smitty1eGH/d47a326631d233904cef1d0aace7b843 to your computer and use it in GitHub Desktop.
SmithAssignment6
<div id='map'></div>
<div class='filter-ctrl'>
<input id='filter-input' type='text' name='filter' placeholder='Filter by pri_mo ' />
</div>
<div id='menu'></div>
//https://docs.mapbox.com/mapbox-gl-js/example/simple-map/
/* Default style options
mapbox://styles/mapbox/streets-v10
mapbox://styles/mapbox/outdoors-v10
mapbox://styles/mapbox/light-v9
mapbox://styles/mapbox/dark-v9
mapbox://styles/mapbox/satellite-v9
mapbox://styles/mapbox/satellite-streets-v10
mapbox://styles/mapbox/navigation-preview-day-v2
mapbox://styles/mapbox/navigation-preview-night-v2
mapbox://styles/mapbox/navigation-guidance-day-v2
mapbox://styles/mapbox/navigation-guidance-night-v2
*/
mapboxgl.accessToken =
"pk.eyJ1Ijoic21pdHR5MWUiLCJhIjoiY2syY2NnNmhjMXkyazNib2psYzhuNXc4dyJ9.U-kpFeCWrn84xGTm3PZ_rw";
// filtering content
var filterInput = document.getElementById("filter-input");
// create map
var map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/light-v10",
center: [-122.4102, 37.79],
zoom: 15.7,
pitch: 65,
bearing: 83,
container: "map",
antialias: true
});
fetch(
"https://smitty1egh.carto.com/api/v2/sql?format=GeoJSON&q=SELECT CASE WHEN weap='blunt_instrument' THEN 'golf-15' WHEN weap='other' THEN 'alcohol-shop-15' WHEN weap='knife' THEN 'monument-15' WHEN weap='fist' THEN 'police-1' WHEN weap='gun' THEN 'drinking-water-15' END AS w, * FROM (SELECT coalesce(weapon,'fist') as weap, coalesce(primary_mo,'KUNG FU FIGHTING') AS pri_mo, * FROM nyc_homicides) AS A "
)
.then(response => {
return response.json(); // check whether the reply is json
})
.then(poi_data => {
// if promise fulfilled, i.e., json
// console.log("Number of Feature: ", geonames_data.features.length);
// console.log(poi_data.features.length);
// poi_data.features.forEach(function(feature) {
// console.log(feature.properties.name);
// });
map.on("load", function() {
//heatmap-begin
map.addSource("poi-heatmap", {
data: poi_data,
type: "geojson"
});
// heatmap cluster layer
map.addLayer({
id: "poi-heat",
type: "heatmap",
source: "poi-heatmap",
maxzoom: 15,
paint: {
// increase intensity as zoom level increases
"heatmap-intensity": {
stops: [[11, 1], [15, 3]]
},
// assign color values be applied to points depending on their density
"heatmap-color": [
"interpolate",
["linear"],
["heatmap-density"],
0,
"rgba(33,102,172,0)",
0.2,
"rgb(103,169,207)",
0.4,
"rgb(209,229,240)",
0.6,
"rgb(253,219,199)",
0.8,
"rgb(239,138,98)",
1,
"rgb(178,24,43)"
], // increase radius as zoom increases
"heatmap-radius": {
stops: [[11, 8], [15, 12]]
},
// decrease opacity to transition into the circle layer
"heatmap-opacity": {
default: 1,
stops: [[14, 1], [15, 0]]
}
}
}); //map.on("load"
map.addLayer({
id: "3d-buildings",
source: "composite",
"source-layer": "building",
filter: ["==", "extrude", "true"],
type: "fill-extrusion",
minzoom: 15,
paint: {
"fill-extrusion-color": "#aaa",
//'interpolate' expression adds smooth transition effect to the
// buildings as the user zooms in
"fill-extrusion-height": [
"interpolate",
["linear"],
["zoom"],
15,
0,
15.05,
["get", "height"]
],
"fill-extrusion-base": [
"interpolate",
["linear"],
["zoom"],
15,
0,
15.05,
["get", "min_height"]
],
"fill-extrusion-opacity": 0.6
}
}); // map.addLayer({ 3d-buildings
//Add source from our GeoJSON data, set the 'cluster'=true.
// GL-JS adds point_count property to source data.
map.addSource("poi-clusters", {
type: "geojson",
data: poi_data,
cluster: true,
clusterMaxZoom: 14, // Max zoom to cluster points on
clusterRadius: 50 // Cluster radius when clustering (defaults=50)
});
map.addLayer({
id: "poi-clusters",
type: "circle",
source: "poi-clusters",
filter: ["has", "point_count"],
paint: {
// Use step expressions (https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
// with three steps to implement three types of circles:
// * Blue, 20px circles when point count is less than 100
// * Yellow, 30px circles when point count is between 100 and 750
// * Pink, 40px circles when point count is greater than or equal to 750
"circle-color": [
"step",
["get", "point_count"],
"#51bbd6",
250,
"#f1f075",
1000,
"#f28cb1"
],
"circle-radius": [
"step",
["get", "point_count"],
20,
250,
30,
1000,
40
]
}
}); // map.addLayer({ poi-clusters
map.addLayer({
id: "cluster-count",
type: "symbol",
source: "poi-clusters",
filter: ["has", "point_count"],
layout: {
"text-field": "{point_count_abbreviated}",
"text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
"text-size": 12
}
});
map.addLayer({
id: "unclustered-point",
type: "symbol",
source: "poi-clusters",
filter: ["!", ["has", "point_count"]],
layout: {
"icon-image": ['get', 'w'],
"icon-size" : 2
}
});
// fit map to bounds of data
// https://stackoverflow.com/questions/35586360/mapbox-gl-js-getbounds-fitbounds
var bounds = new mapboxgl.LngLatBounds();
poi_data.features.forEach(function(feature) {
bounds.extend(feature.geometry.coordinates);
});
map.fitBounds(bounds);
filterInput.addEventListener("keypress", function(e) {
// If the input value matches a layerID set
// it's visibility to 'visible' or else hide it.
var key = e.which || e.keyCode;
if (key === 13) {
// 13 is enter - if key is enter key, read out value of text field
var term = e.target.value.trim().toLowerCase();
console.log(term);
var filteredFeatures = poi_data.features.filter(function(feature) {
return feature.properties.pri_mo.toLowerCase().includes(term);
});
var filteredFeatureCollection = {
type: "FeatureCollection",
features: filteredFeatures
};
map.getSource("poi-clusters").setData(filteredFeatureCollection);
}
}); // filterInput
//popup-begin
// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
// single location markers
// See also https://docs.mapbox.com/mapbox-gl-js/example/popup-on-hover/
map.on("mouseenter", "unclustered-point", function(e) {
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = "pointer";
//TODO: need to pull the correct field names from
// the dataset for the description variable.
var coordinates = e.features[0].geometry.coordinates.slice();
var description = "Primary MO - " + e.features[0].properties.pri_mo;
// Ensure that if the map is zoomed out such that multiple
// copies of the feature are visible, the popup appears
// over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
// Populate the popup and set its coordinates
// based on the feature found.
popup
.setLngLat(coordinates)
.setHTML(description)
.addTo(map);
});
map.on("mouseleave", "unclustered-point", function() {
map.getCanvas().style.cursor = "";
popup.remove();
});
//popup-end
//layer-begin
//code due to https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/
var toggleableLayerIds = [ "poi-clusters"
, "poi-heat"
];
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i];
var link = document.createElement('a');
link.href = '#';
link.className = 'active';
link.textContent = id;
link.onclick = function (e) {
var clickedLayer = this.textContent;
e.preventDefault();
e.stopPropagation();
var visibility = map.getLayoutProperty(clickedLayer, 'visibility');
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
//layer-end
});
})
.catch(err => {
console.log("Erro loading data: ", err);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.4.0/mapbox-gl.js"></script>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#menu {
position: absolute;
top: 10px;
right: 10px;
display: flex;
border-radius: 3px;
background-color: rgb(255, 255, 255);
padding: 10px;
z-index: 10;
display: flex;
flex-flow: column;
justify-content: space-between;
}
.switch-container {
display: flex;
flex-flow: row;
justify-content: space-between;
}
.switch {
margin-left: 3px;
}
.filter-ctrl {
position: absolute;
top: 10px;
right: 10px;
z-index: 1;
width: 180px;
}
.filter-ctrl input[type="text"] {
font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif;
width: 100%;
border: 0;
background-color: #fff;
height: 40px;
margin: 0;
color: rgba(0, 0, 0, 0.5);
padding: 10px;
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
border-radius: 3px;
}
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.4.1/mapbox-gl.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment