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

时间:2015-10-02 01:26:38

标签: javascript google-maps google-maps-api-3 socket.io

我找到了一个能够使用绘图工具的要点,并且可以选择几种颜色在Google地图上绘制:https://gist.github.com/Hagith/5765919

我试图在socket.io中使用它,以便多人可以查看地图,当一个人在地图上绘制某些内容时,所有人都可以看到所绘制的内容。

我通过做

来了解标记的基本想法
socket.emit("marker", e.overlay.position);

然而,当放置标记时,使用矩形,多边形和圆形,似乎有点难度。当我使用任何这些形状注销地图上的点击事件时,它返回的数据似乎比用标记返回的数据更复杂,我无法找到我需要的点的坐标能够向其他用户广播。有谁知道在上面的要点的背景下在哪里找到这些?

修改:我已经找到了e.overlay.j.center

的中心

3 个答案:

答案 0 :(得分:7)

建议不要使用这些属性(e.overlay.j),因为它们不适合公开访问,并且无法保证它们不会在下一版 Google Maps JavaScript API中更改

对于google.maps.drawing.OverlayType.RECTANGLEgoogle.maps.drawing.OverlayType.CIRCLE类型,您可以使用getBounds() function来确定当前形状的纬度/经度范围,如下所示:

//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();

对于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()

修改后的示例

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>

答案 1 :(得分:2)

  

编辑:我已经能够通过e.overlay.j.center

找到该中心

您希望使用浏览器调试工具中可以看到的单字母属性非常小心。它们没有记录或静态,并且会在没有警告的情况下发生变化。

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

有一个很好的示例here,它根据返回叠加层的几何类型显示切换行为。

答案 2 :(得分:0)

getCoords(someShape){
    const paths = someShape.getPath().getArray();
    const coords = paths.map((a) => [a.lat(), a.lng()]);
}

给出[lat,lng]的列表