当地图绑定更改并清除旧标记时显示新标记 [英] Display new markers when map bound changed and clear old marker

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

问题描述

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

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

In您的控制器,您需要获取您使用axios请求发送的参数( fromLat toLat 等)

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.

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆