javascript 使用绘图管理器在谷歌地图上绘制时获取矩形/多边形的坐标

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32899213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:53:27  来源:igfitidea点击:

Getting coordinates of rectangle/polygon when drawn on google maps with drawing manager

javascriptgoogle-mapsgoogle-maps-api-3socket.io

提问by Joshua Terrill

I found a gist that enables drawing tools and gives the ability to choose from a few colors to draw on a google map: https://gist.github.com/Hagith/5765919

我找到了一个启用绘图工具的要点,并提供了从几种颜色中进行选择以在谷歌地图上绘图的能力:https: //gist.github.com/Hagith/5765919

I'm trying to utilize this with socket.io so that multiple people can be viewing a map, and when one person draws something onto the map, all of the people can see what is drawn.

我正在尝试将其与 socket.io 结合使用,以便多人可以查看地图,并且当一个人在地图上绘制某些内容时,所有人都可以看到所绘制的内容。

I've got the basic idea down with markers by doing

我已经有了标记的基本想法

socket.emit("marker", e.overlay.position);

When a marker is placed, however, with rectangles, polygons, and circles, it seems a bit harder. When I log out the click event on the map with any of those shapes, the data that it gives back seems way more complicated than what it gave back with marker and I can't find the coordinates for the points that I need to be able to broadcast to the other users. Does anyone know where to find these in the context of the gist above?

然而,当标记放置在矩形、多边形和圆形上时,似乎有点难。当我用这些形状中的任何一个注销地图上的点击事件时,它返回的数据似乎比它用标记返回的数据复杂得多,而且我找不到我需要的点的坐标向其他用户广播。有谁知道在上述要点的上下文中在哪里可以找到这些?

Edit: I've been able to find the center with e.overlay.j.center

编辑:我已经能够找到中心 e.overlay.j.center

回答by Vadim Gremyachev

It is not recommended to utilize those kind of properties (e.overlay.j) since they are not intended for public access and there is no guarantee that they will not change in the next version of Google Maps JavaScript API.

不建议使用这些类型的属性 ( e.overlay.j),因为它们不是供公众访问的,并且不能保证它们不会在下一个版本的Google Maps JavaScript API 中更改。

For google.maps.drawing.OverlayType.RECTANGLEand google.maps.drawing.OverlayType.CIRCLEtypes you could utilize getBounds() functionto determine the lat/lng bounds of the current shape as demonstrated below:

您可以使用Forgoogle.maps.drawing.OverlayType.RECTANGLEgoogle.maps.drawing.OverlayType.CIRCLEtypesgetBounds() function来确定当前形状的 lat/lng 边界,如下所示:

//get lat/lng bounds of the current shape
var bounds = e.overlay.getBounds();
var start = bounds.getNorthEast();
var end = bounds.getSouthWest();
var center = bounds.getCenter();

For google.maps.drawing.OverlayType.POLYLINEand google.maps.drawing.OverlayType.POLYGONtypes you could utilize getPath() function:

对于google.maps.drawing.OverlayType.POLYLINEgoogle.maps.drawing.OverlayType.POLYGON类型,你可以使用getPath() function

//get lat/lng array of the current shape
var locations = e.overlay.getPath().getArray()

Modified example

修改示例

var drawingManager;
var selectedShape;
var colors = ['#1E90FF', '#FF1493', '#32CD32', '#FF8C00', '#4B0082'];
var selectedColor;
var colorButtons = {};
function clearSelection() {
    if (selectedShape) {
        selectedShape.setEditable(false);
        selectedShape = null;
    }
}
function setSelection(shape) {
    clearSelection();
    selectedShape = shape;
    shape.setEditable(true);
    selectColor(shape.get('fillColor') || shape.get('strokeColor'));
}
function deleteSelectedShape() {
    if (selectedShape) {
        selectedShape.setMap(null);
    }
}
function selectColor(color) {
    selectedColor = color;
    for (var i = 0; i < colors.length; ++i) {
        var currColor = colors[i];
        colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
    }
    // Retrieves the current options from the drawing manager and replaces the
    // stroke or fill color as appropriate.
    var polylineOptions = drawingManager.get('polylineOptions');
    polylineOptions.strokeColor = color;
    drawingManager.set('polylineOptions', polylineOptions);
    var rectangleOptions = drawingManager.get('rectangleOptions');
    rectangleOptions.fillColor = color;
    drawingManager.set('rectangleOptions', rectangleOptions);
    var circleOptions = drawingManager.get('circleOptions');
    circleOptions.fillColor = color;
    drawingManager.set('circleOptions', circleOptions);
    var polygonOptions = drawingManager.get('polygonOptions');
    polygonOptions.fillColor = color;
    drawingManager.set('polygonOptions', polygonOptions);
}
function setSelectedShapeColor(color) {
    if (selectedShape) {
        if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
            selectedShape.set('strokeColor', color);
        } else {
            selectedShape.set('fillColor', color);
        }
    }
}
function makeColorButton(color) {
    var button = document.createElement('span');
    button.className = 'color-button';
    button.style.backgroundColor = color;
    google.maps.event.addDomListener(button, 'click', function () {
        selectColor(color);
        setSelectedShapeColor(color);
    });
    return button;
}
function buildColorPalette() {
    var colorPalette = document.getElementById('color-palette');
    for (var i = 0; i < colors.length; ++i) {
        var currColor = colors[i];
        var colorButton = makeColorButton(currColor);
        colorPalette.appendChild(colorButton);
        colorButtons[currColor] = colorButton;
    }
    selectColor(colors[0]);
}
function initialize() {
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 16,
        center: new google.maps.LatLng(52.25097, 20.97114),
        mapTypeId: google.maps.MapTypeId.SATELLITE,
        disableDefaultUI: true,
        zoomControl: true
    });
    var polyOptions = {
        strokeWeight: 0,
        fillOpacity: 0.45,
        editable: true,
        draggable: true
    };
    // Creates a drawing manager attached to the map that allows the user to draw
    // markers, lines, and shapes.
    drawingManager = new google.maps.drawing.DrawingManager({
        drawingMode: google.maps.drawing.OverlayType.POLYGON,
        markerOptions: {
            draggable: true
        },
        polylineOptions: {
            editable: true,
            draggable: true
        },
        rectangleOptions: polyOptions,
        circleOptions: polyOptions,
        polygonOptions: polyOptions,
        map: map
    });
    google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
        if (e.type !== google.maps.drawing.OverlayType.MARKER) {
            // Switch back to non-drawing mode after drawing a shape.
            drawingManager.setDrawingMode(null);
            // Add an event listener that selects the newly-drawn shape when the user
            // mouses down on it.
            var newShape = e.overlay;
            newShape.type = e.type;
            google.maps.event.addListener(newShape, 'click', function (e) {
                if (e.vertex !== undefined) {
                    if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
                        var path = newShape.getPaths().getAt(e.path);
                        path.removeAt(e.vertex);
                        if (path.length < 3) {
                            newShape.setMap(null);
                        }
                    }
                    if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
                        var path = newShape.getPath();
                        path.removeAt(e.vertex);
                        if (path.length < 2) {
                            newShape.setMap(null);
                        }
                    }
                }
                setSelection(newShape);
            });
            setSelection(newShape);

            if (e.type == google.maps.drawing.OverlayType.POLYLINE || google.maps.drawing.OverlayType.POLYGON) {
                var locations = e.overlay.getPath().getArray()
                //console.log(bounds.toString());    
                document.getElementById('output').innerHTML = locations.toString();
            }
            else {
                //get lat/lng bounds of the current shape
                var bounds = e.overlay.getBounds();
                var start = bounds.getNorthEast();
                var end = bounds.getSouthWest();
                var center = bounds.getCenter();
                //console.log(bounds.toString());    
                document.getElementById('output').innerHTML = bounds.toString();
            }


        }
    });
    // Clear the current selection when the drawing mode is changed, or when the
    // map is clicked.
    google.maps.event.addListener(drawingManager, 'drawingmode_changed', clearSelection);
    google.maps.event.addListener(map, 'click', clearSelection);
    google.maps.event.addDomListener(document.getElementById('delete-button'), 'click', deleteSelectedShape);
    buildColorPalette();
}
google.maps.event.addDomListener(window, 'load', initialize);
#map, html, body {
            padding: 0;
            margin: 0;
            width: 960px;
            height: 300px;
        }

        #panel {
            width: 200px;
            font-family: Arial, sans-serif;
            font-size: 13px;
            float: right;
            margin: 10px;
        }

        #color-palette {
            clear: both;
        }

        .color-button {
            width: 14px;
            height: 14px;
            font-size: 0;
            margin: 2px;
            float: left;
            cursor: pointer;
        }

        #delete-button {
            margin-top: 5px;
        }
<script type="text/javascript"
            src="http://maps.google.com/maps/api/js?sensor=false&libraries=drawing"></script> 
<div id="panel">
        <div id="color-palette"></div>
        <div>
            <button id="delete-button">Delete Selected Shape</button>
        </div>
 </div>
 <div id="map"></div>
 <div id="output"></div>

回答by Juffy

Edit: I've been able to find the center with e.overlay.j.center

编辑:我已经能够用 e.overlay.j.center 找到中心

You want to be VERY careful using the single-letter properties you can see in the browser debug tools. They are not documented, or static, and will change without warning.

您需要非常小心地使用可以在浏览器调试工具中看到的单字母属性。它们没有记录在案或静态,并且会在没有警告的情况下更改。



To answer the actual question - the type of e.overlaydepends on what you've initialised the DrawingManager with, see the docs here. So if you're drawing polygons, e.overlaywill be of type Polygon. You can then get the points that make up that Polygon using e.overlay.getPath(0).getArray(), which gives you an array of LatLngobjects. (obviously loop over all the available paths, not just 0).

要回答实际问题 - 类型e.overlay取决于您初始化 DrawingManager 的内容,请参阅此处的文档。因此,如果您正在绘制多边形,e.overlay则类型为Polygon。然后,您可以使用 获得组成该 Polygon 的点e.overlay.getPath(0).getArray(),它为您提供了一组LatLng对象。(显然,循环遍历所有可用路径,而不仅仅是0)。

There's a good example herewhich shows switching behaviour based on what type of geometry the overlay is returned as.

这里有一个很好的例子它显示了基于覆盖返回的几何类型的切换行为。