Reputation: 71
Warning: novice here
I am building a real estate website in PHP. I am now adding a map view via LeafLetJs which is all JavaScript. I have my map setup and all properties are coming in correctly. My issue is that the page takes about 17 seconds to load. It only loads around 500 properties instead of the 2000 being supplied in the json url. I believe it is timing out as the json data is pretty large (30mb).
What is the proper way to populate a map quickly? Here is my code:
var url =
"https://api.bridgedataoutput.com/api/v2/OData/actris/Property/replication?access_token=(TokenHere)&$top=2000";
var map = L.map("map", { tap: false }).setView([30.26, -97.74], 11);
var markers = L.markerClusterGroup();
$(document).ready(function () {
$.ajax({
url: url,
dataType: "json",
error: function () {
console.log("JSON FAILED for data");
},
success: function (results) {
const numberFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 0,
});
var markers = L.markerClusterGroup();
var cartItemsList = document.getElementById("cartItemsList");
results.value.forEach(function (element) {
//cartItemsList.insertAdjacentHTML( 'beforeend',"<li>" + element.UnparsedAddress + " : " + element.Longitude+ " : " + element.Latitude+ " </li>");
var marker = L.marker([element.Latitude, element.Longitude]).bindPopup(
'<a href="property.php?id=' + element.ListingId +
'"><div class="card"><img class="card-img-top" src="' + element.Media[0].MediaURL +
'" style="height:160px;max-height:160px;object-fit: scale-down;"><div class="d-inline-flex p-2 justify-content-between align-items-start"><div class="rp-1 bd-highlight">' +
element.StreetNumber + " " + element.StreetName + " " +
element.StreetSuffix + "<br>" + element.City + ", " +
element.StateOrProvince + " " + element.PostalCode +
'</div><div class="lp-1 bd-highlight" style="text-align: right;">' +
numberFormatter.format(element.ListPrice) +
" <br> ID " + element.ListingId +
"</div></div></div></a>"
);
markers.addLayer(marker);
map.addLayer(markers);
}); // end of forEach
}, // end of success fn
}); // end of Ajax call
}); // end of $(document).ready() function
L.tileLayer(
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=my_mapbox_access_token",
{
maxZoom: 18,
attribution:
'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
id: "mapbox/streets-v11",
}
).addTo(map);
markers.addLayer(marker);
map.fitBounds(markers.getBounds());
Upvotes: 1
Views: 1617
Reputation: 71
Turns out the json URL was taking too much time to load. I was able to use a select rule and only pull back the fields I needed. Now the map loads 2000 results in just a few seconds.
Upvotes: 0
Reputation: 53280
Most probably there are 2 performance bottlenecks:
addLayers
method (note the s at the end) once with an array of all your Markers:Bulk adding and removing Markers
addLayers
andremoveLayers
are bulk methods for adding and removing markers and should be favoured over the single versions when doing bulk addition/removal of markers. Each takes an array of markers.
In your case it could be something like: (in your success callback)
const arrayOfMarkers = results.value.map(element =>
L.marker([element.Latitude, element.Longitude]).bindPopup(/* etc. */)
);
const mcg = L.markerClusterGroup();
mcg.addLayers(arrayOfMarkers);
mcg.addTo(map);
As for the discrepancy between the number of displayed features, it might be due to the computation delay, but I rather suspect you may not receive as many features as you think: simply log results.value.length
to make sure.
Upvotes: 1