如何更改 Google 地图 API 绘图层控件中使用的默认标记

How to change the default Marker used in the Google Maps API Drawing Layer controls

我想知道如何将自定义标记与 google 地图绘制控件一起使用。我想这样做是因为我需要在用户单击地图时放置一个标记并让它打开一个信息 window(单击时)并在其中进行一些自定义操作(按钮等)。

我为此使用了 React 和 @react-google-maps/api,但这可能不是重点,因为它只是 Javascript API 提供的地图的包装器 [=53] =].

docs 可以提供 google.maps.MarkerOptionsgoogle.maps.drawing.DrawingManagerOptions。不幸的是,那里没有提供要呈现的自定义 Marker 的选项。

我尝试使用 google.maps.drawing.DrawingManager 暴露的 markercomplete() 回调,因为它有新创建的 Marker 作为参数,然后做这样的事情:

const handleNewMarker = (marker) => {
  marker.addListener('click', function() {
    setActiveMarker(marker);
  });
}

我的地图组件将是这样的:

<GoogleMap
  zoom={18}
  center={latLng}
>
  {activeMarker && <CustomInfoWindow anchor={activeMarker} />}
  <DrawingManager
    options={{
      markerOptions: {
        clickable: true,
        draggable: true,
      },
    }}
    onMarkerComplete={handleNewMarker}
  />
</GoogleMap>

虽然这有效,但它根本不适合生产,由于某种原因 InfoWindow 需要太多时间才能出现在屏幕上,这种方法可能会导致内存泄漏,我不知道为什么了。

我可能在这里遗漏了一些东西,但在我的研究中,我没有发现任何人试图用绘图工具创建自定义标记,只是自己自定义标记,这相对容易做到。我的理想情况是,因为我使用的是 React,所以会创建一个 CustomMarker 组件,里面有一个 CustomInfoWindow,然后告诉绘图控件,"hey, take this marker and use it whenever a user tries to draw a new marker with your drawing tool".

谢谢。

编辑

这是我的意思的屏幕截图,屏幕截图中的标记是使用 "new marker" 绘图控件放置在那里的,我需要 "new marker" 绘图控件来放置定义的自定义标记由我

你需要做的就是在MarkerOptions中设置icon 属性,如果我正确理解你"custom marker"的意思的话。下面是一个使用 SVG 路径作为图标的示例。

此代码段是完整的 JS,但同样适用于 React 库。

var map;

function initialize() {

  var mapOptions = {
    center: new google.maps.LatLng(-34.397, 150.644),
    zoom: 8
  };

  map = new google.maps.Map(document.getElementById('map'), mapOptions);

  var drawingManager = new google.maps.drawing.DrawingManager({

    drawingControl: true,
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_CENTER,
      drawingModes: [google.maps.drawing.OverlayType.MARKER]
    },
    markerOptions: {
      draggable: false,
      icon: {
        path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
        fillColor: '#FF0000',
        fillOpacity: 0.6,
        anchor: new google.maps.Point(0, 0),
        strokeWeight: 0,
        scale: 1
      }
    }
  });

  drawingManager.setMap(map);
}
#map {
  height: 180px;
}
<div id="map"></div>

<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize&libraries=drawing" async defer></script>

现在,如果您需要可点击的标记、信息窗口等,您真的需要使用绘图管理器吗?你能不能简单地监听一个地图点击事件,然后创建一个标准标记?

或者两者都用? (使用绘图管理器创建标记并使用 markercomplete 事件将其转换为标准标记,这似乎或多或少是您在做的事情。)

编辑:

如果您需要使用信息窗口创建一个 "real" 标记,您可以在 markercomplete 事件中进行。

var map;
var infowindow;

function initialize() {

  var mapOptions = {
    center: new google.maps.LatLng(-34.397, 150.644),
    zoom: 8
  };

  map = new google.maps.Map(document.getElementById('map'), mapOptions);
  infowindow = new google.maps.InfoWindow();

  var drawingManager = new google.maps.drawing.DrawingManager({

    drawingControl: true,
    drawingControlOptions: {
      position: google.maps.ControlPosition.TOP_CENTER,
      drawingModes: [google.maps.drawing.OverlayType.MARKER]
    }
  });

  drawingManager.setMap(map);

  google.maps.event.addListener(drawingManager, 'markercomplete', function(marker) {

    // Remove overlay from map
    marker.setMap(null); // Optional, but this will remove the drawn marker
    drawingManager.setDrawingMode(null); // Optional, but this will "disable" the drawing tools

    // Create the "real" marker
    createMarker(marker.getPosition());
  });
}

function createMarker(position) {

  var marker = new google.maps.Marker({
    position: position,
    map: map,
    title: 'Custom marker',
    icon: {
      path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
      fillColor: '#FF0000',
      fillOpacity: 0.6,
      anchor: new google.maps.Point(0, 0),
      strokeWeight: 0,
      scale: 1
    }
  });

  google.maps.event.addListener(marker, 'click', function() {
    infowindow.setContent('This is the content');
    infowindow.open(map, this);
  });
}
#map {
  height: 180px;
}
<div id="map"></div>

<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize&libraries=drawing" async defer></script>