Google 地图搜索 - 地图不会改变搜索输入的焦点

Google Maps search - Map wont change focus from search input

大家好 Whosebug 成员。

我已经提出帮助我们当地社区的紧急志愿者小组,通过改进警报地图来通知成员我们城镇附近的事件。 我一直在使用 google 地图 api,以及 google 地点 api.

我已经成功引入了他们的新闻提醒 JSON 数据,将其与他们的自定义图标匹配,并成功地在地图上显示出来。但是,我现在正在努力让搜索框根据用户输入的地址更新地图。

注意:搜索可以自动完成,但地图没有更新。当前错误是“map.fitBounds 不是函数”

我的参考资料 link,我一直在使用它来尝试整合地点搜索:https://github.com/googlemaps/js-samples/blob/737eb41e78f9cad28e2664b68450676e91424219/dist/samples/places-searchbox/inline.html

我在下面附上了我的代码。我在评论中添加了对搜索功能代码的最新编辑。一个全新的视角将不胜感激。

更新:我编译了一个 JSFiddle 以便于处理: https://jsfiddle.net/mcmacca002/zvghd0nu/

谢谢你和赞赏。

// BUILD GOOGLE MAPS:
var GoogleMap = {
  map: null,
  markers: {},
  init: function(lat, lng, places) {
      var self = this;
      var mapOptions = {
          zoom: 12,
          center: new google.maps.LatLng(lat, lng)
      };
      this.map = new google.maps.Map(document.getElementById('map'), mapOptions);
      this.infowindow = new google.maps.InfoWindow({
          size: new google.maps.Size(50, 50)
      });

// SEARCH STARTS HERE (ALONG WITH ISSUES):
      var searchBox = new google.maps.places.SearchBox(document.getElementById('pac-input'));
      google.maps.event.addListener(searchBox, 'places_changed', function() {
        searchBox.set('map', null);
        var places = searchBox.getPlaces();

     var bounds = new google.maps.LatLngBounds();
     var i, place;
     for (i = 0; place = places[i]; i++) {
       (function(place) {
         var marker = new google.maps.Marker({

           position: place.geometry.location
         });
         marker.bindTo('map', searchBox, 'map');
         google.maps.event.addListener(marker, 'map_changed', function() {
           if (!this.getMap()) {
             this.unbindAll();
           }
         });
         bounds.extend(place.geometry.location);


       }(place));

     }
     map.fitBounds(bounds);
     searchBox.set('map', map);
     map.setZoom(Math.min(map.getZoom(),12));

   });
 
// END OF SEARCH HERE.
      
      
      $.each(places, function() {
          self.addMarker(this);
      });
      this.setCenterPoint();
  },

  
  
  // Create map markers
  addMarker: function(place) {
      var self = this;
      var marker = new google.maps.Marker({
          position: new google.maps.LatLng(place.coordinate.latitude, place.coordinate.longitude),
          map: self.map,
          title: place.name,
          icon: place.image
      });
      console.log(place);
  
  // Create information event for each marker
      marker.info_window_content = 'TEST'
      self.markers[place.id] = marker
      google.maps.event.addListener(marker, 'click', function() {
          self.infowindow.setContent(marker.info_window_content)
          self.infowindow.open(self.map, marker);
      });
  },

  // Update map markers
  updateMarkers: function(records) {
      var self = this;
      $.each(self.markers, function() {
          this.setMap(null);
      })
      $.each(records, function() {
          self.markers[this.id].setMap(self.map);
      });
      //Set map center
      if (records.length) self.setCenterPoint();
  },
  
  // Set centre point for map
  setCenterPoint: function() {
      var lat = 0,
          lng = 0;
      count = 0;
  
      //Calculate approximate center point based on number of JSON entries
      for (id in this.markers) {
          var m = this.markers[id];
          if (m.map) {
              lat += m.getPosition().lat();
              lng += m.getPosition().lng();
              count++;
          }
      }
      if (count > 0) {
          this.map.setCenter(new google.maps.LatLng(lat / count, lng / count));
      }
  }
};
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div class="container" id="map" style="height:900px;"></div>

您有一个错误,因为您对 this 的引用有误。我在这里更新了你的 Jsfiddle:https://jsfiddle.net/k23auboq/ 但我也会在下面告诉你哪里出了问题。

init: function(lat, lng, places) {
    // ... 

    var searchBox = new google.maps.places.SearchBox(document.getElementById('pac-input'));
    google.maps.event.addListener(searchBox, 'places_changed', () => { // if you pass an arrow function here instead, 'this' will be taken from the outer context
        searchBox.set('map', null);
        var places = searchBox.getPlaces();
        var bounds = new google.maps.LatLngBounds();
        var i, place;
        for (i = 0; place = places[i]; i++) {
            var marker = new google.maps.Marker({
            position: place.geometry.location
            });
            marker.bindTo('map', searchBox, 'map');
            google.maps.event.addListener(marker, 'map_changed', function() {
            if (!this.getMap()) {
                this.unbindAll();
            }
            });
            bounds.extend(place.geometry.location);
        }
        this.map.fitBounds(bounds); // this.map.fitBounds(...) now exists and works
        searchBox.set('map', map);
        this.map.setZoom(Math.min(map.getZoom(), 12));
    });

    // ... 
},

为了简化它,请看以下示例:

function Test() {
  this.map = 'test map';
  
  this.callbackAction = function (callback) {
    callback();
  }
  
  this.action = function () {
    this.callbackAction(function () { // callback passed as 'function'
      console.log(this.map);
    });
  }
  
  return this;
}

const instance = new Test();
instance.action();

function Test() {
  this.map = 'test map';
  
  this.callbackAction = function (callback) {
    callback();
  }
  
  this.action = function () {
    this.callbackAction(() => { // callback passed as 'ARROW function'
      console.log(this.map);
    });
  }
  
  return this;
}

const instance = new Test();
instance.action();

我已经更新了上面提供的答案。答案在技术上是正确的,但是使用 bounds 方法会将地图缩小到级别 1。

这是一个适合您的解决方案。我无法将图钉添加到搜索到的位置。希望其他人可以在那里帮助你,因为我只是应用了我使用 leaflet.js 学到的东西,这与 Google 地图略有不同,而且我还在学习 Javascript.

var GoogleMap = {
    map: null,
    markers: {},
    init: function(lat, lng, places) {
        var self = this;
        var mapOptions = {
            zoom: 12,
            center: new google.maps.LatLng(lat, lng),
            draggable: true
        };
        this.map = new google.maps.Map(document.getElementById('map'), mapOptions);
        this.infowindow = new google.maps.InfoWindow({
            size: new google.maps.Size(10, 10)
        });
        // SEARCH STARTS HERE:
        var searchBox = new google.maps.places.SearchBox(document.getElementById('pac-input'));
        google.maps.event.addListener(searchBox, 'places_changed', () => {
            searchBox.set('map', null);
            var places = searchBox.getPlaces();
            var bounds = new google.maps.LatLngBounds();
            var i, place;
            for (i = 0; place = places[i]; i++) {
              var marker = new google.maps.Marker({
                title: places.name,
                zoom: 4,
                position: place.geometry.location             
              });
              marker.bindTo('map', searchBox, 'map');
              google.maps.event.addListener(marker, 'map_changed', function() {
                if (!this.getMap()) {
                  this.unbindAll();
                }
                bounds.extend(place.geometry.location);
              });
              marker.setPosition(place.geometry.location);
            }
            // ADDING PANTO FOR RETAINING THE MAP ZOOM LEVEL - INSTEAD OF SETZOOM :D
            this.map.panTo(marker.getPosition());

        });

        // WHICH THEN ENABLES YOU TO REMOVE THIS:
        // this.map.fitBounds(bounds);
        // searchBox.set('map', map);
        // this.map.setZoom(Math.min(map.getZoom(), 12));
        
        // END OF SEARCH HERE.