I am very new to web development and creating maps using Leaflet. Currently I developed a website that has an interactive map based off this tutorial. The map eventually loads and works but it is very very slow. I would like to speed up this map loading and I was thinking I would break up the US map into 50 states and have an input where people would select a state and only that specific states data would load. I was thinking I would break up the US GeoJSON file into 50 files and have each one called based on a user input. I know how to break up the file already but can someone point me in the direction of how to use an input to load a specific GeoJSON file?
Edit
The reason why I want to separate by state is because the unit of analysis is on the ZIP code level. Having an analysis this granular makes the entire U.S map ~200mb. Using the plugin in the comments would work if I wanted to highlight just the state border. My GeoJSON file is on the ZIP code level so using get.Bounds
will get the bounds of each ZIP and not the state. Having the User pick the state data will hopefully help with the speed.
Here is the map code:
<div class="content-section middle toppad" >
<h3>Interactive Maps</h3>
The interactive heatmap displays median property value at the ZIP code level. The legend on the bottom right is median property value (in the thousands of dollars). The map is meant to help pick an area that is right for you to invest in. Data are provided from Zillow. If you hover over a ZIP code, median sale price, median monthly rent, naming; removed appreciation; questionifiedmedian property value, and one-year change in property value will be displayed in the upper right-hand corner of the map.
<br>
Note not all the above information is available for all ZIP codes.
</div>
<div id="llmap" class = "content-section middle toppad" ></div>
<script type="text/javascript" src="{{url_for('static', filename='us-states.js')}}"></script>
<script type="text/javascript">
var TILE_URL = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
var MB_ATTR = 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
map = L.map('llmap', {});
L.tileLayer(TILE_URL, {attribution: MB_ATTR}).addTo(map);
map.locate({setView: true, maxZoom: 9});
function onLocationError(e) {
alert(e.message);
}
// control that shows state info on hover
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML = '<h6>Market Info by ZIP Code</h6>' + (props ?
'<b>' + 'ZIP: ' + props.ZIP + '</b><br />' +
'Median Home Property Value, May 2020: ' + props.valmay2020 + '<br />' +
'Median Home Sale Price, March 2020: ' + props.salemarch2020 + '<br />' +
'Median Rent, April 2020: ' + props.rentapr2020 + ', City Level Only' + '<br / >' +
'1yr. House Value Change: ' + props.chg1yrpropval +'%' + '<br />'
: 'Hover over a ZIP Code');
};
info.addTo(map);
// get color depending on population density value
function getColor(d) {
return d > 400000 ? '#800026' :
d > 300000 ? '#BD0026' :
d > 200000 ? '#E31A1C' :
d > 150000 ? '#FC4E2A' :
d > 100000 ? '#FD8D3C' :
d > 50000 ? '#FEB24C' :
d > 25000 ? '#FED976' :
'#FFEDA0';
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.valmay2020)
};
}
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}
geojson = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
/*map.on('moveend',function(){
alert(map.getBounds());
})
*/
map.attributionControl.addAttribution('Housing and Rental data © Zillow');
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [0, 25000, 50000, 100000, 150000, 200000, 300000, 400000],
labels = [],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
froml = grades[i]/1000 + 'k';
tol = grades[i +1]/1000 + 'k';
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' +
froml + (to ? '–' + tol : '+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
legend.addTo(map);
</script>
get.bounds
and then highlights the country border. That is helpful but my level of analysis is at the more granular level than state. So I would like to grab state and then highlight the boundaries at a smaller level (ZIP codes).select.on('change' ...
event processing function to display desired state's ZIP features in a GeoJSON layer.