避免顶点拖动映射api v3

Avoiding vertex drag maps api v3

本文关键字:api v3 映射 拖动 顶点      更新时间:2023-09-26

非常简单。我希望避免拖动第一个和最后一个顶点。我尝试过使用dragstart事件,但显然折线听不进去。

我设法用set_at做了些什么。我存储了最后一个位置,当调用set_at时,我检查该顶点的索引,然后将该顶点的latLng设置为旧的。只有使用setAt函数才能再次触发事件。

所以a创建了一个ignoreNextEvent标志,所以它不会进行无限循环。

问题是,setAt函数os被maps-api使用了很多次,虽然解决方案很有效,但并不完美,每次与折线交互时我都需要担心ignoreNextEvent。

我正在想办法做到这一点,有人能帮忙吗?

工作代码:

google.maps.event.addListener(cable.getPath(), 'set_at', function(e){
    if(!ignoreNextEvent){
        if(e == 0 || e == cable.getPath().length-1){
            var point = new google.maps.LatLng(cable.Cable.vertex[e].latitude, cable.Cable.vertex[e].longitude);
            ignoreNextEvent = true;
            cable.getPath().setAt(e,point);
        }else{
            if(cable.Cable.idx != 0){ saveCable(index, cable.Cable.destination_idx); }  
        }
    }else{
        ignoreNextEvent = false;
    }
});

创建多段线,将可拖动标记绑定到希望能够拖动的顶点,将不可拖动的标记绑定到不希望拖动的顶点。

示例

var gmarkers = [];
var map;
  function addLatLng(event) {
    var path = poly.getPath();
    path.push(event.latLng);
    var len = path.getLength();
    var marker = new google.maps.Marker({
      position: event.latLng,
      title: '#' + len,
      map: map,
      icon: {
        url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
        size: new google.maps.Size(7,7),
        anchor: new google.maps.Point(4,4)
      },
      draggable : true
    });
    gmarkers.push(marker);
    marker.bindTo('position', poly.binder, (len-1).toString());
  }
function initialize() {
  var polyOptions = {
      strokeColor: '#000000',
      strokeOpacity: 1.0,
      strokeWeight: 3, map: map
    };
  poly = new google.maps.Polyline(polyOptions);
  var bounds = new google.maps.LatLngBounds();
  map = new google.maps.Map(document.getElementById('map_canvas'), {
    center: new google.maps.LatLng(10.9386, -84.888),
    zoom: 10,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });
  poly.binder = new MVCArrayBinder(poly.getPath());
  for(var i = 0; i < locations.length; i++) {
    var evt = {};
    evt.latLng = new google.maps.LatLng(locations[i][0], locations[i][1]);
    bounds.extend(evt.latLng);
    addLatLng(evt);
  }
  gmarkers[0].setDraggable(false);
  gmarkers[gmarkers.length-1].setDraggable(false);

  poly.setMap(map);
  map.fitBounds(bounds);
} 
google.maps.event.addDomListener(window, "load", initialize);
  /*
   * Use bindTo to allow dynamic drag of markers to refresh poly.
   */
  function MVCArrayBinder(mvcArray){
    this.array_ = mvcArray;
  }
  MVCArrayBinder.prototype = new google.maps.MVCObject();
  MVCArrayBinder.prototype.get = function(key) {
    if (!isNaN(parseInt(key))){
      return this.array_.getAt(parseInt(key));
    } else {
      this.array_.get(key);
    }
  }
  MVCArrayBinder.prototype.set = function(key, val) {
    if (!isNaN(parseInt(key))){
      this.array_.setAt(parseInt(key), val);
    } else {
      this.array_.set(key, val);
    }
  }

代码片段:

/*
 * Use bindTo to allow dynamic drag of markers to refresh poly.
 */
function MVCArrayBinder(mvcArray) {
  this.array_ = mvcArray;
}
MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function(key) {
  if (!isNaN(parseInt(key))) {
    return this.array_.getAt(parseInt(key));
  } else {
    this.array_.get(key);
  }
}
MVCArrayBinder.prototype.set = function(key, val) {
  if (!isNaN(parseInt(key))) {
    this.array_.setAt(parseInt(key), val);
  } else {
    this.array_.set(key, val);
  }
}
/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * @param {MouseEvent} mouseEvent
 */
function addLatLng(event) {
  var path = poly.getPath();
  path.push(event.latLng);
  var len = path.getLength();
  var marker = new google.maps.Marker({
    position: event.latLng,
    title: '#' + len,
    map: map,
    icon: {
      url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
      size: new google.maps.Size(7, 7),
      anchor: new google.maps.Point(4, 4)
    },
    draggable: true
  });
  gmarkers.push(marker);
  marker.bindTo('position', poly.binder, (len - 1).toString());
}
var locations = [
  [-33.890542, 151.274856, 4, 'Bondi Beach'],
  [-33.923036, 151.259052, 5, 'Coogee Beach'],
  [-34.028249, 151.157507, 3, 'Cronulla Beach'],
  [-33.80010128657071, 151.28747820854187, 2, 'Manly Beach'],
  [-33.950198, 151.259302, 1, 'Maroubra Beach']
];
var poly;
var map;
var gmarkers = [];
function initialize() {
  var polyOptions = {
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 3,
    map: map
  };
  poly = new google.maps.Polyline(polyOptions);
  var bounds = new google.maps.LatLngBounds();
  map = new google.maps.Map(document.getElementById('map_canvas'), {
    center: new google.maps.LatLng(10.9386, -84.888),
    zoom: 10,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });
  poly.binder = new MVCArrayBinder(poly.getPath());
  for (var i = 0; i < locations.length; i++) {
    var evt = {};
    evt.latLng = new google.maps.LatLng(locations[i][0], locations[i][1]);
    bounds.extend(evt.latLng);
    addLatLng(evt);
  }
  gmarkers[0].setDraggable(false);
  gmarkers[0].setIcon({
    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)
  });
  gmarkers[gmarkers.length - 1].setDraggable(false);
  gmarkers[gmarkers.length - 1].setIcon({
    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)
  });
  poly.setMap(map);
  map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
  width: 100%;
  height: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>