允许仅在Google Maps V3中的特定国家/地区内拖动标记

时间:2014-10-28 23:56:33

标签: php google-maps

我想做的事情:

  1. 一个可拖动的标记,只允许在一个国家/地区上移动。

  2. 拖动结束后,该位置会显示在输入文字中。

  3. 信息:将标记锁定到一个国家/地区是有效的,但是当我快速移动标记多次时,即使在允许的国家/地区也是如此。它回到了应该发生在其他国家的位置。

    2个所需内容的每个部分分开工作,当它们组合在一起作为下面的代码时,它们不起作用。问题必须是(dragend)听众,但我无法找到它是什么。

    <script src="http://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=false"></script>
    <script>
    
    
    var map = null;
    var marker = null;
    var country = 'DE';  
    
    function updateMarkerAddress(str) {
      document.getElementById('address').value = str;
    }    
    
    function initialize() {
      var startDragPosition = null;
      var mapOptions = {
        zoom: 6,
        center: new google.maps.LatLng(50.8,10.3),
        mapTypeId: google.maps.MapTypeId.TERRAIN
      };
      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(48.784084,9.181635),
        map: map,
        draggable: true
      });
    
      var myGeocoder = new google.maps.Geocoder();
    
    
      google.maps.event.addListener(marker,'dragstart',function(event) {
    
        startDragPosition = marker.getPosition();
      });
      google.maps.event.addListener(marker,'dragend',function(event) {
        myGeocoder.geocode({'latLng': marker.getPosition()}, function(responses,results, status) {
          if (status == google.maps.GeocoderStatus.OK && results[1]) {
            var countryMarker = addresComponent('country', results[1], true);
            if (country != countryMarker) {
              marker.setPosition(startDragPosition);
            }
           }
          else {
            marker.setPosition(startDragPosition);
          }
           if (responses && responses.length > 0) 
            {
              updateMarkerAddress(responses[0].formatted_address);
            } 
            else 
           {
              updateMarkerAddress('Cannot determine address at this location.');
           }
        });
      });
    }
    
    function addresComponent(type, geocodeResponse, shortName) {
      for(var i=0; i < geocodeResponse.address_components.length; i++) {
        for (var j=0; j < geocodeResponse.address_components[i].types.length; j++) {
          if (geocodeResponse.address_components[i].types[j] == type) {
            if (shortName) {
              return geocodeResponse.address_components[i].short_name;
            }
            else {
              return geocodeResponse.address_components[i].long_name;
            }
          }
        }
      }
      return '';
    }
    </script>
    <style>
    #map-canvas {
      height:400px;
    }
    </style>
    <input type="text" id="address">
    

1 个答案:

答案 0 :(得分:3)

一般问题在于myGeocoder.geocode()的回调。该函数只返回两个变量 - 响应和状态。所以下面的代码应该可行。

google.maps.event.addListener(marker,'dragend',function(event) {
    myGeocoder.geocode({'latLng': marker.getPosition()}, function(responses,status) {
        if (status == google.maps.GeocoderStatus.OK && responses[0]) {
            var countryMarker = addresComponent('country', responses[0], true);
            if (country != countryMarker) {
                marker.setPosition(startDragPosition);
            }
        } else {
            marker.setPosition(startDragPosition);
        }
        if (responses && responses.length > 0) {
            updateMarkerAddress(responses[0].formatted_address);
        } else {
            updateMarkerAddress('Cannot determine address at this location.');
        }
    });
});

快速多次移动标记会破坏代码有两个原因。

  1. geocode()函数是异步的,所以如果你创建了数字 在短间隔内连续回调,完成订单 可以与创建顺序不同。
  2. Google地理编码器有费率 限制。如果您过快地执行太多查询,它将停止工作。
  3. 这两个问题都可以解决将代码重组为这样的问题。 (注意:这部分代码使用了jquery,因此你可能也必须包含它。)

    //wrap the geocoder in a function.
    function geocode (marker,country) {
        myGeocoder.geocode('query', function(){ ... } ); 
    }
    
    // call the geocoder with a timeout and clear the timeout everytime the geocoder is called again.
    google.maps.event.addListener(marker,'dragend',function(event) {
        clearTimeout($.data(marker,'timer'));
        $(marker).data('timer', setTimeout(function(){geocode(marker,country)}, 1000));
    
    });
    

    上述方法将确保无论您移动标记的速度有多快,地理编码功能仅在它们之间的最小间隙(上述情况下为1000毫秒)时触发。