Display new markers when map bound changed and clear old marker

后端 未结 2 1247
小蘑菇
小蘑菇 2020-12-21 18:24

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

相关标签:
2条回答
  • 2020-12-21 19:03

    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;
                }
    
        });
    
    0 讨论(0)
  • 2020-12-21 19:23

    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.

    0 讨论(0)
提交回复
热议问题