Published
Edited
May 6, 2021
1 fork
1 star
Insert cell
md`# Leaflet-Heatmap`
Insert cell
L = require('leaflet@1.2.0')
Insert cell
html`<link href='${resolve('leaflet@1.2.0/dist/leaflet.css')}' rel='stylesheet' />`
Insert cell
import {Select} from "@observablehq/inputs"
Insert cell
import {date} from "@jashkenas/inputs"
Insert cell
d3 = require("d3@6")
Insert cell
uniqueCrimes = [...new Set( madCrimes.features.map(obj => obj.properties.incident)) ].sort();

Insert cell
madCrimes
Insert cell
grandCentral = {
let response = await fetch('https://nominatim.openstreetmap.org/search.php?q=grand+central+station%2C+new+york&polygon_geojson=1&format=json');
let json = await response.json();
return json[0].geojson
}
Insert cell
heatLayer = L, require('leaflet.heat').catch(() => L.heatLayer)
Insert cell
crimes = (await fetch('https://opendata.arcgis.com/datasets/6af5cb8dc38e4bcbac8168b27ee104aa_38.geojson')).json()
Insert cell
madCrimes = FileAttachment("new_data.geojson").json()
Insert cell
madCrimesFormatted = madCrimes.features.map((d) => {
d.properties.Occur_date = new Date(d.properties.Occur_date)
return d
})
Insert cell
viewof crimeCategory = Select(uniqueCrimes, {multiple: true, label: "Select crime category"})
Insert cell
new Date(Math.max(...madCrimes.features.map(e => new Date(e.Occur_date))));
Insert cell
madCrimes.features
Insert cell
maxDate = d3.max(madCrimes.features, d => d.properties.Occur_date)

Insert cell
minDate = d3.min(madCrimes.features, d => d.properties.Occur_date)
Insert cell
viewof start_date = date({
title: "Start",
min: minDate,
max: maxDate,
value: minDate,
description: "The earliest day is 01/01/2019"
})
Insert cell
start_date_formatted = new Date(start_date)
Insert cell
viewof end_date = date({
title: "End",
min: minDate,
max: maxDate,
value: maxDate,
description: "The last day in data is 03/10/2021"
})
Insert cell
end_date_formatted = new Date(end_date)
Insert cell
crimeMap = {
// You'll often see Leaflet examples initializing a map like L.map('map'),
// which tells the library to look for a div with the id 'map' on the page.
// In Observable, we instead create a div from scratch in this cell, so it's
// completely self-contained.
let container = DOM.element('div', { style: `width:${width}px;height:${width/1.6}px` });
// Note that I'm yielding the container pretty early here: this allows the
// div to be placed on the page. This is important, because Leaflet uses
// the div's .offsetWidth and .offsetHeight to size the map. If I were
// to only return the container at the end of this method, Leaflet might
// get the wrong idea about the map's size.
yield container;
// Create a map object and add a layer to it.
let map = L.map(container).setView([43.0927993, -89.4171004], 11);
let osmLayer = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// let osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
// attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
// }).addTo(map);
// Filter the data based on user input
let selectedCrimes = madCrimes.features.filter((d) => {
if (crimeCategory.length > 0){
return crimeCategory.includes(d.properties.incident) && new Date(d.properties.Occur_date) >= start_date_formatted && new Date(d.properties.Occur_date) <= end_date_formatted
} else if (crimeCategory.length === 0) {
return uniqueCrimes.includes(d.properties.incident) && new Date(d.properties.Occur_date) >= start_date_formatted && new Date(d.properties.Occur_date) <= end_date_formatted
}
})
//convert data points to [lat,lng, intensity]
let crimePoints = selectedCrimes.map(feature =>
feature.geometry.coordinates.slice().reverse().concat([0.1]));
//Add heatmap layer
let crimeLayer = heatLayer(crimePoints, {
minOpacity: 0.5,
maxZoom: 18,
max: 1.0,
radius: 8,
blur: 4,
gradient: null
}).addTo(map);
let markers = markerCluster({});
// Add popup on the markers
let schoolsLayer = L.geoJson(selectedCrimes, {
onEachFeature: function (feature, layer) {
const d = feature.properties;
// const html = `<div class="popup"><h2>${school.name}</h2>` +
// `<p>${school.district} District</p><p>grades: ${school.grades_served}</p></div>`
// layer.bindPopup(html);
layer.bindTooltip(`${d.incident}, ${d.Occur_date}`, {sticky: true});
}
});
markers.addLayer(schoolsLayer);
map.addLayer(markers);
}
Insert cell
markerCluster = L, require('leaflet.markercluster@1.1.0').catch(() => L.markerClusterGroup)
Insert cell
markerClusterCSS = html`<link href='${resolve('leaflet.markercluster@1.1.0/dist/MarkerCluster.Default.css')}' rel='stylesheet' />`
Insert cell
madCrimesFormatted
Insert cell
result = madCrimesFormatted.reduce(function(acc, curr) {
// Check if there exist an object in empty array whose CategoryId matches
var isElemExist = acc.findIndex(function(item) {
return item.Occur_weekday === curr.properties.Occur_weekday;
})
if (isElemExist === -1) {
var obj = {};
obj.Occur_weekday = curr.properties.Occur_weekday;
obj.count = 1;
acc.push(obj)
} else {
acc[isElemExist].count += 1
}
return acc;

}, [])

Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more