when map bound moved by user, make disappear old position markers and display new markers.
For an example you can check this map. Markers are moving every time bound
You need to store old Value and compare with new one you need timeout function to update each time iterval ex window.setTimeout(insertMarkers,3000)
for(var i=0, len=res.length; i<len; i++) {
//Do we have this marker already?
if(markerStore.hasOwnProperty(res[i].driver_id)) {
markerStore[res[i].id].setPosition(new google.maps.LatLng({lat: parseFloat(res[i].lat), lng: parseFloat(res[i].lng)}));
} else {
marker = new google.maps.Marker({
position: {lat: parseFloat(res[i].lat), lng: parseFloat(res[i].lng)},
map:map
});
google.maps.event.addListener(marker, 'click', (function(marker, i,id) {
return function() {
console.log(id)
}
})(marker, i,id));
markerStore[res[i].id] = marker;
}
}
markerStore[estate.id] = marker;
}
});
UPDATE
mounted() {
.
.
.
this.initMap();
window.setTimeout(this.insertMarkers,3000)
},
methods: {
.
.
.
insertMarkers: function() {
var marker=[];
var markerStore = {};
this.estates.forEach((estate, index) => {
//Do we have this marker already?
if(markerStore.hasOwnProperty(estate.id)) {
markerStore[estate.id].setPosition(new google.maps.LatLng({lat: parseFloat(estate.lat), lng: parseFloat(estate.lng)}));
} else {
marker = new google.maps.Marker({
icon: '/img/marker.png',
position: {lat: parseFloat(estate.lat), lng: parseFloat(estate.lng)},
map:map
});
var es_id=estate.id;
google.maps.event.addListener(marker, 'click', (function(marker, index,es_id) {
return function() {
console.log(es_id)
window.location.href = "/pages/" + es_id;
}
})(marker, index,es_id));
markerStore[estate.id] = marker;
}
});
As I said in my comment, you can do it the other way around. Fetch only markers that are visible within the map viewport. You just need to reorganize your code a bit and modify your database query.
You need to pass a minimum and maximum latitude and longitude to your controller so that you can query the DB for markers between the given latitudes and longitudes. You can get these by getting your map bounds and extracting southwest and northeast lat/lng.
export default {
data() {
return {
bounds: {},
map: {},
mapName: "map",
estates: [],
markers: [] // Added markers array here
}
},
mounted() {
this.initMap(); // On "mounted" only call initMap
},
methods: {
initMap: function() {
//giving specific location of japan.
this.bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(34.652500, 135.506302),
);
var mapOptions = {
mapTypeId: 'roadmap',
center: new google.maps.LatLng(0, 0),
zoom: 5
};
this.map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);
let self = this;
var boundsListener = google.maps.event.addListener((this.map), 'idle', function(event) {
self.getMarkers(); // When map is idle, get markers
});
this.map.fitBounds(this.bounds);
},
getMarkers: function() {
// Get current map bounds
let bounds = this.map.getBounds();
let southWest = bounds.getSouthWest();
let northEast = bounds.getNorthEast();
// Send request with min/max latitude and longitude to only fetch markers for that area
axios.get('/ajax', {
params: {
fromLat: southWest.lat(),
toLat: northEast.lat(),
fromLng: southWest.lng(),
toLng: northEast.lng(),
}
}).then((response) => {
this.estates = response.data;
this.updateMarkers();
});
},
updateMarkers: function() {
// Remove previous markers
for (let i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(null);
}
// Reset markers array
this.markers = [];
// Add current markers
for (i = 0; i < estates.length; i++) {
var position = new google.maps.LatLng(estates[i].lat, estates[i].lng);
var marker = new google.maps.Marker({
position: position,
map: map,
icon: '/img/marker.png',
url: "/pages/" + estates[i].id,
});
// Push marker to markers array for future removal
this.markers.push(marker);
}
}
}
}
In your controller, you need to get the parameters you send with the axios request (fromLat
, toLat
, etc.)
public function ajax() {
// Here you need to retrieve the parameters sent by the axios request !
// And set them as $fromLat, $toLat, etc.
$data = \DB::table('allestates')
->where('lat', '>', $fromLat)
->where('lat', '<', $toLat)
->where('lng', '>', $fromLng)
->where('lng', '<', $toLng)
->get();
$response = response()->json($data);
return $response;
}
Untested, but that should work. You need to adapt some parts! Read my comments in the code as well.
Note: the bounds_changed
event is triggered repeatedly when a user drags the map, so this way you are going to send a lot of requests to your database. Instead, you should probably prefer another event such as idle
or delay the trigger of your ajax call somehow to reduce the number of queries.