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

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

本文介绍了地图边界更改时显示新标记并清除旧标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 bounds updated and clearing the old position markers. I am exactly trying to do this.

到目前为止我所做的就在下面.没有错误,但仍然可以同时看到所有标记..?

what I have done so far is right below. No errors but, still seeing all markers at once..?

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

推荐答案

正如我在评论中所说,你可以反过来做.仅获取地图视口内可见的标记.您只需要稍微重新组织您的代码并修改您的数据库查询.

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

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

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.

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

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.

这篇关于地图边界更改时显示新标记并清除旧标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 06:52