更改地图边界时显示新标记,并清除旧标记

时间:2019-02-19 04:51:44

标签: javascript google-maps vue.js google-maps-api-3 vuejs2

当用户移动地图边界时,使旧的位置标记消失并显示新的标记。

例如,您可以选中此map。每次更新边界时都会移动标记,并清除旧的位置标记。我正是在尝试这样做。

更新2

我到目前为止所做的事情就在下面。没有错误,但是仍然可以一次看到所有标记。.

data(){
     return {
        bounds:{},
        map: {},
        mapName: "map",
        estates: [], 
     }
},
mounted() {
    axios.get('/ajax').then((response) => {
        this.estates =  response.data
        this.insertMarkers();
    });
    this.initMap();

},
methods: {

            initMap: function() {

        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: 8
        };


        let self = this;

        this.map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);

        var boundsListener = google.maps.event.addListener((this.map), 'bounds_changed', function(event) {

            self.getMarkers();

        });

        this.map.fitBounds(this.bounds);
    },

    getMarkers: function() {

        let bounds = this.map.getBounds();

        let southWest = bounds.getSouthWest();
        let northEast = bounds.getNorthEast();
        console.log(southWest);

        axios.get('/ajax', {
            params: {
                fromLat: southWest.lat()-0.01,
                toLat: northEast.lat()-0.01,
                fromLng: southWest.lng()+0.01,
                toLng: northEast.lng()+0.01,
            }
        }).then((response) => {
            this.estates = response.data;
            this.updateMarkers();
        });

    },

    updateMarkers: function() {


        google.maps.event.addListener(map, 'idle', function() {

            var map = this.map;
            var estates = this.estates;
            let i = 0;

            for (i = 0; i < this.markers.length; i++) {
                this.markers[i].setMap(null);
            }

            this.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,
                    label: {
                        text:
                            estates[i].price.toString().length == 1 ?
                            estates[i].price.toString().replace("1", "未定") :
                            estates[i].price.toString() + "万",
                        color: '#fff',
                    },
                    icon: '/img/marker.png',
                    url: "/pages/" + estates[i].id,
                });

                this.markers.push(marker);

                google.maps.event.addListener(marker, 'click', function () {
                    window.location.href = this.url;
               });
            }
        });
    },

2 个答案:

答案 0 :(得分:1)

正如我在评论中所说,您可以采用其他方法。仅获取在地图视口内可见的标记。您只需要稍微重新组织代码并修改数据库查询即可。

您需要将最小和最大纬度和经度传递给控制器​​,以便可以在数据库中查询给定纬度和经度之间的标记。您可以通过获取地图边界并提取西南和东北纬度/经度来获取这些数据。

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);
      }
    }
  }
}

在控制器中,您需要获取随axios请求发送的参数(fromLattoLat等)

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;
}

未经测试,但这应该可行。您需要调整一些部分!还要阅读我在代码中的注释。

注意:bounds_changed事件在用户拖动地图时反复触发,因此,您将向数据库发送大量请求。相反,您可能应该选择另一个事件,例如idle或以某种方式延迟ajax调用的触发,以减少查询数量。

答案 1 :(得分:0)

您需要存储旧值并与新值进行比较,您需要使用超时功能在每次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;

            }

    });

更新

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;
            }

    });