簡體   English   中英

Google Maps v3 - 刪除多邊形上的頂點

[英]Google Maps v3 - Delete vertex on Polygon

谷歌地圖有繪圖庫來繪制折線和多邊形以及其他東西。

這里功能的示例: http : //gmaps-samples-v3.googlecode.com/svn-history/r282/trunk/drawing/drawing-tools.html

我希望在繪制和編輯多邊形時能夠刪除路徑上的一個點/頂點。 API 文檔似乎沒有暗示任何內容。

Google 地圖現在為從多邊形或折線觸發的事件提供“ PolyMouseEvent ”回調對​​象。

要建立在建議涉及右鍵單擊的解決方案的其他答案的基礎上,您需要做的就是最新版本的 V3 API 中的以下內容:

// this assumes `my_poly` is an normal google.maps.Polygon or Polyline
var deleteNode = function(mev) {
  if (mev.vertex != null) {
    my_poly.getPath().removeAt(mev.vertex);
  }
}
google.maps.event.addListener(my_poly, 'rightclick', deleteNode);

您會注意到,不再需要對我們是否在該點附近進行任何復雜的計算,因為 Google Maps API 現在會告訴我們我們點擊了哪個頂點。

注意:這僅在折線/多邊形處於編輯模式時有效。 (此時您可能要刪除的頂點可見。)

最后,您可以考慮改用單擊或雙擊事件。 “單擊”足夠智能,不會在拖動時觸發,但使用單擊觸發器可能仍會讓您的某些用戶感到驚訝。

這是目前一個未完成的功能請求(由 Google 確認), 問題 3760

這是我的解決方案: http : //jsbin.com/ajimur/10 它使用一個函數向傳入的多邊形添加一個刪除按鈕(在撤消按鈕下方)。


或者,有人建議使用這種方法:右鍵單擊以刪除最近的 vertex ,這可以正常工作,但在 UI 技巧上有些欠缺。 我根據鏈接中的代碼進行構建,以檢查點擊是否在節點內部(或在節點的 1 像素內) - 在此處的 JSBin 中: http : //jsbin.com/ajimur/

編輯:正如Amr Bekhit指出的那樣 - 這種方法目前已被破壞,因為需要將事件附加到多邊形。

我發現 Sean 的代碼非常簡單和有用。 我剛剛添加了一個限制器以在用戶只剩下 3 個節點時停止刪除。 沒有它,用戶只能使用一個節點,並且不能再編輯:

my_poly.addListener('rightclick', function(mev){
    if (mev.vertex != null && this.getPath().getLength() > 3) {
        this.getPath().removeAt(mev.vertex);
    }
});

我遇到過需要從包含多條路徑的多邊形中刪除節點的情況。 這是對 Sean 和 Evil 代碼的修改:

shape.addListener('rightclick', function(event){
  if(event.path != null && event.vertex != null){
    var path = this.getPaths().getAt(event.path);
    if(path.getLength() > 3){
      path.removeAt(event.vertex);
    }
  }
});

只是想我會做出貢獻,因為我也在為此尋找解決方案,這是我的實現:

if (m_event.hasOwnProperty('edge') && m_event.edge >= 0 &&
GeofenceService.polygon.getPath().getLength() > 3) {
    GeofenceService.polygon.getPath().removeAt(m_event.edge);
    return;
}

if (m_event.hasOwnProperty('vertex') && m_event.vertex >= 0 &&
GeofenceService.polygon.getPath().getLength() > 3) {
    GeofenceService.polygon.getPath().removeAt(m_event.vertex);
    return;
}

這允許處理頂點節點和邊節點的刪除,並通過檢查路徑長度 > 3 始終保持三角形形成多邊形的最小值。

2020 更新

谷歌在他們的文檔中提供了一個工作演示,它演示了如何通過右鍵單擊一個頂點來顯示“刪除”菜單來刪除一個頂點或線上的一個點。

查看刪除頂點

刪除頂點

以及完整性代碼(請參閱他們的Github 存儲庫);

function initialize() {
  const mapOptions = {
    zoom: 3,
    center: new google.maps.LatLng(0, -180),
    mapTypeId: "terrain",
  };
  const map = new google.maps.Map(document.getElementById("map"), mapOptions);
  const flightPlanCoordinates = [
    new google.maps.LatLng(37.772323, -122.214897),
    new google.maps.LatLng(21.291982, -157.821856),
    new google.maps.LatLng(-18.142599, 178.431),
    new google.maps.LatLng(-27.46758, 153.027892),
  ];
  const flightPath = new google.maps.Polyline({
    path: flightPlanCoordinates,
    editable: true,
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 2,
    map: map,
  });

  /**
   * A menu that lets a user delete a selected vertex of a path.
   */
  class DeleteMenu extends google.maps.OverlayView {
    constructor() {
      super();
      this.div_ = document.createElement("div");
      this.div_.className = "delete-menu";
      this.div_.innerHTML = "Delete";
      const menu = this;
      google.maps.event.addDomListener(this.div_, "click", () => {
        menu.removeVertex();
      });
    }
    onAdd() {
      const deleteMenu = this;
      const map = this.getMap();
      this.getPanes().floatPane.appendChild(this.div_);
      // mousedown anywhere on the map except on the menu div will close the
      // menu.
      this.divListener_ = google.maps.event.addDomListener(
        map.getDiv(),
        "mousedown",
        (e) => {
          if (e.target != deleteMenu.div_) {
            deleteMenu.close();
          }
        },
        true
      );
    }
    onRemove() {
      if (this.divListener_) {
        google.maps.event.removeListener(this.divListener_);
      }
      this.div_.parentNode.removeChild(this.div_);
      // clean up
      this.set("position", null);
      this.set("path", null);
      this.set("vertex", null);
    }
    close() {
      this.setMap(null);
    }
    draw() {
      const position = this.get("position");
      const projection = this.getProjection();

      if (!position || !projection) {
        return;
      }
      const point = projection.fromLatLngToDivPixel(position);
      this.div_.style.top = point.y + "px";
      this.div_.style.left = point.x + "px";
    }
    /**
     * Opens the menu at a vertex of a given path.
     */
    open(map, path, vertex) {
      this.set("position", path.getAt(vertex));
      this.set("path", path);
      this.set("vertex", vertex);
      this.setMap(map);
      this.draw();
    }
    /**
     * Deletes the vertex from the path.
     */
    removeVertex() {
      const path = this.get("path");
      const vertex = this.get("vertex");

      if (!path || vertex == undefined) {
        this.close();
        return;
      }
      path.removeAt(vertex);
      this.close();
    }
  }
  const deleteMenu = new DeleteMenu();
  google.maps.event.addListener(flightPath, "rightclick", (e) => {
    // Check if click was on a vertex control point
    if (e.vertex == undefined) {
      return;
    }
    deleteMenu.open(map, flightPath.getPath(), e.vertex);
  });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM