javascript - 调整圆大小时获取半径

标签 javascript google-maps google-maps-api-3

在调整圆的大小时是否可以获取现有圆的半径?

Google map 没有“调整大小”事件,仅在用户停止调整大小后才会触发 radius_changed 事件。

我想我可以设置一个间隔并在调整圆大小时获取半径,但是 .getRadius() 在用户停止调整大小之前不会显示当前半径。

最佳答案

Google Maps Javascript API v3 文档中曾经有一篇“文章”执行此操作,名为“Fun with MVC”。

这个问题关于SO:How to style editable circle controls in Google Maps该文章中有一个示例,该示例在调整圆大小时输出半径。

fiddle (from my answer to that question)

代码片段:

      function init() {
        var mapDiv = document.getElementById('map-canvas');
        var map = new google.maps.Map(mapDiv, {
          center: new google.maps.LatLng(37.790234970864, -122.39031314844),
          zoom: 8,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        var distanceWidget = new DistanceWidget(map);
        google.maps.event.addListener(distanceWidget, 'distance_changed', function() {
          displayInfo(distanceWidget);
        });

        google.maps.event.addListener(distanceWidget, 'position_changed', function() {
          displayInfo(distanceWidget);
        });
      }

      google.maps.event.addDomListener(window, 'load', init);

      /** 
       * A distance widget that will display a circle that can be resized and will
       * provide the radius in km.
       *
       * @param {google.maps.Map} map The map on which to attach the distance widget.
       *
       * @constructor
       */
      function DistanceWidget(map) {
        this.set('map', map);
        this.set('position', map.getCenter());

        var marker = new google.maps.Marker({
          draggable: true,
          icon: {
            url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",
            size: new google.maps.Size(7, 7),
            anchor: new google.maps.Point(4, 4)
          },
          title: 'Move me!'
        });

        // Bind the marker map property to the DistanceWidget map property 
        marker.bindTo('map', this);

        // Bind the marker position property to the DistanceWidget position 
        // property 
        marker.bindTo('position', this);

        // Create a new radius widget 
        var radiusWidget = new RadiusWidget();

        // Bind the radiusWidget map to the DistanceWidget map 
        radiusWidget.bindTo('map', this);

        // Bind the radiusWidget center to the DistanceWidget position 
        radiusWidget.bindTo('center', this, 'position');

        // Bind to the radiusWidgets' distance property 
        this.bindTo('distance', radiusWidget);

        // Bind to the radiusWidgets' bounds property 
        this.bindTo('bounds', radiusWidget);
      }
      DistanceWidget.prototype = new google.maps.MVCObject();

      /** 
       * A radius widget that add a circle to a map and centers on a marker.
       *
       * @constructor
       */
      function RadiusWidget() {
        var circle = new google.maps.Circle({
          strokeWeight: 2
        });

        // Set the distance property value, default to 50km. 
        this.set('distance', 50);

        // Bind the RadiusWidget bounds property to the circle bounds property. 
        this.bindTo('bounds', circle);

        // Bind the circle center to the RadiusWidget center property 
        circle.bindTo('center', this);

        // Bind the circle map to the RadiusWidget map 
        circle.bindTo('map', this);

        // Bind the circle radius property to the RadiusWidget radius property 
        circle.bindTo('radius', this);

        this.addSizer_();
      }
      RadiusWidget.prototype = new google.maps.MVCObject();


      /** 
       * Update the radius when the distance has changed.
       */
      RadiusWidget.prototype.distance_changed = function() {
        this.set('radius', this.get('distance') * 1000);
      };
      /** 
       * Add the sizer marker to the map.
       *
       * @private
       */
      RadiusWidget.prototype.addSizer_ = function() {
        var sizer = new google.maps.Marker({
          draggable: true,
          icon: {
            url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle_blue.png",
            size: new google.maps.Size(7, 7),
            anchor: new google.maps.Point(4, 4)
          },
          title: 'Drag me!'
        });

        sizer.bindTo('map', this);
        sizer.bindTo('position', this, 'sizer_position');

        var me = this;
        google.maps.event.addListener(sizer, 'drag', function() {
          // Set the circle distance (radius) 
          me.setDistance();
        });
      };

      /** 
       * Update the center of the circle and position the sizer back on the line.
       *
       * Position is bound to the DistanceWidget so this is expected to change when
       * the position of the distance widget is changed.
       */
      RadiusWidget.prototype.center_changed = function() {
        var bounds = this.get('bounds');

        // Bounds might not always be set so check that it exists first. 
        if (bounds) {
          var lng = bounds.getNorthEast().lng();

          // Put the sizer at center, right on the circle. 
          var position = new google.maps.LatLng(this.get('center').lat(), lng);
          this.set('sizer_position', position);
        }
      };

      /** 
       * Calculates the distance between two latlng locations in km.
       * @see http://www.movable-type.co.uk/scripts/latlong.html
       *
       * @param {google.maps.LatLng} p1 The first lat lng point.
       * @param {google.maps.LatLng} p2 The second lat lng point.
       * @return {number} The distance between the two points in km.
       * @private
       */
      RadiusWidget.prototype.distanceBetweenPoints_ = function(p1, p2) {
        if (!p1 || !p2) {
          return 0;
        }

        var R = 6371; // Radius of the Earth in km 
        var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
        var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
        var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        var d = R * c;
        return d;
      };


      /** 
       * Set the distance of the circle based on the position of the sizer.
       */
      RadiusWidget.prototype.setDistance = function() {
        // As the sizer is being dragged, its position changes.  Because the 
        // RadiusWidget's sizer_position is bound to the sizer's position, it will 
        // change as well. 
        var pos = this.get('sizer_position');
        var center = this.get('center');
        var distance = this.distanceBetweenPoints_(center, pos);

        // Set the distance property for any objects that are bound to it 
        this.set('distance', distance);
      };

      function displayInfo(widget) {
        var info = document.getElementById('info');
        info.innerHTML = 'Position: ' + widget.get('position').toUrlValue(3) + ', distance: ' + widget.get('distance').toFixed(3);
      }
html,
body,
#map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="info"></div>
<div id="map-canvas"></div>

关于javascript - 调整圆大小时获取半径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32722122/

相关文章:

javascript - 重构 JSON 数组

javascript - 将此变量传递给 Angular $http 回调

javascript - 在桌面上用鼠标滑动手势,如 Photoswipe,但为 div 设置动画

google-maps - 如何使用 Place Id 获得指向谷歌地图上某个地点的直接链接

javascript - 如何停止 webdriver 而不导致 Node js 崩溃

java - map 上未显示位置

javascript - 如何使谷歌地图不脱离世界界限?

html - 谷歌地图标记不拖动

javascript - 使用 onClick 事件显示不同的 map - Google map V3。

javascript - 具有多个停靠点/航点的 Google Maps Route API