【问题标题】:How to change the default Marker used in the Google Maps API Drawing Layer controls如何更改 Google Maps API 绘图层控件中使用的默认标记
【发布时间】:2020-09-22 17:39:27
【问题描述】:

我想知道如何将自定义标记与谷歌地图绘图控件一起使用。我想这样做是因为我需要在用户点击地图时放置一个标记并让它打开一个信息窗口(点击时)并在那里有一些自定义操作(按钮等)。

我为此使用 react 和 @react-google-maps/api,但这可能不是重点,因为它只是 Google 提供的 Maps Javascript API 的封装。

docs 可以将google.maps.MarkerOptions 提供给google.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,然后告诉绘图控件,“嘿,只要用户尝试使用这个标记,就可以使用它用你的绘图工具画一个新的标记”。

谢谢。

编辑

这是我的意思的屏幕截图,屏幕截图中的标记是使用“新标记”绘图控件放置在那里的,我需要“新标记”绘图控件来放置我定义的自定义标记。

【问题讨论】:

    标签: javascript reactjs google-maps-api-3 react-google-maps


    【解决方案1】:

    如果我正确理解您对“自定义标记”的含义,您需要做的就是在MarkerOptions 中设置icon 属性。下面是一个使用 SVG 路径作为图标的示例。

    这个 sn-p 是完整的 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 事件将其转换为标准标记,这似乎或多或少是您在做的事情。)

    编辑:

    如果您需要使用 InfoWindow 创建“真实”标记,可以在 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>

    【讨论】:

    • 感谢您的回复,我需要创建可单击的标记,因为我正在创建一个使用折线和多边形绘图控件以及标记控件的应用程序,以允许用户执行一些操作地图上的标记,稍后将用于城市数据分析。标记将允许用户“标记”给定城市中的影响点。该点有一些属性,例如名称和值(这些属性是我希望用户在通过单击新创建的标记可访问的信息窗口上编辑的内容。
    • 我尝试创建一个标记向量并使用markercomplete 回调向该向量添加一个新标记。然后在谷歌地图中,​​我只是遍历该向量创建标记,但这次使用自定义标记组件和我创建的信息窗口。然而,这似乎只在重新加载地图时出现蠕虫,此时用户使用绘图控件添加新标记,该自定义标记实际上已创建,但不可点击。我相信这是因为实际上有 2 个标记,我的自定义标记和默认标记在我的顶部,所以我点击的是默认标记。
    • 如果我只使用地图onClick 回调来创建它可以工作的标记,但这将分散用户的控制,因为他们已经使用折线来标记街道和多边形来标记区域在一个城市。你知道我怎么能使用markcomplete 事件而没有两个堆叠标记?我想知道是否可以使用标记绘图控件来获取单击点的位置但实际上不创建默认标记,然后我会使用该位置来创建我的自定义标记。
    • 是的,我明白了,但是你应该按照我们已经提到的那样做:使用绘图管理器创建标记,完成后,创建最终的“真实”标记(并删除使用创建的标记)绘图工具)。我会将这部分添加到我的答案中。
    • 请检查我的答案中的第二个 sn-p,它可以满足您的要求,除了它创建默认标记并立即将其删除。你甚至不能说这正在发生,所以应该没问题,我认为你不能以不同的方式做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    相关资源
    最近更新 更多