在Google地图API中显示两点之间的方向,并带有填充。

5
我想使用谷歌地图 API 并在两点之间绘制路径。我的地图部分被一个灰色框盖住,其中可能显示一些文本。当两点之间的距离太远并且其中一个点被灰色框盖时,问题就出现了。
我应该如何强制它以这样的方式绘制路径,使整个路径都显示在灰色框的右侧,并且没有任何一个点与灰色框重叠?
我目前拥有的是: enter image description here 我期望的是: enter image description here

不是一项容易的任务。您应该查看getProjection()fromLatLngToPoint()方法。您可以计算一个点是否在覆盖层下方。这将涉及在地图绘制路线后,在地图完成加载时进行计算。这可能有些棘手。祝你好运。 - MrUpsidown
看看这个答案,它可能会帮到你:https://dev59.com/YnE85IYBdhLWcg3wqVT4#2692617 - MrUpsidown
也许这里也可以:http://stackoverflow.com/a/4850765/1238965 - MrUpsidown
2个回答

9

我在SO上看到了一些关于如何偏移地图上覆盖元素后面内容的问题,所以我想花点时间来解决这个问题。

这是我是如何做到的:

  1. 在地图上绘制路线并在开始偏移过程之前监听地图的空闲事件。

  2. 检查路线边界的最左侧点是否落在覆盖物后面。这利用了fromLatLngToPoint()方法将经纬度坐标转换为地图投影上的点。

  3. 通过比较路线的最左侧点和最右侧点与地图上可用空间的大小,检查您可以偏移多少路线。偏移地图直到两点都适合地图画布。

  4. 如果两个点都无法适合地图画布,则缩小地图并重新开始相同的过程。

  5. 脚本必须知道覆盖物的宽度,并应用一些边距,以使其始终适合良好。

以下是用于在坐标和点之间进行转换的函数:

function fromLatLngToPoint(latLng) {

    var scale = Math.pow(2, map.getZoom());
    var nw = new google.maps.LatLng(map.getBounds().getNorthEast().lat(), map.getBounds().getSouthWest().lng());
    var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
    var worldCoordinate = map.getProjection().fromLatLngToPoint(latLng);

    return new google.maps.Point(Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale), Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale));
}

以下是演示:

JSFiddle demo

我相信它仍然可以优化,但它已经很好地完成了工作。如果您发现任何问题,请在此处报告。

编辑:

同样的技术也适用于标记:

JSFiddle demo


1

这是右侧边栏的重写。将以下代码粘贴到JSFiddle链接的js中,并更改边栏的CSS为right:0

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var routeBounds = false;
var overlayWidth = 400; // Width of the overlay DIV
var leftMargin = 30; // Grace margin to avoid too close fits on the edge of the overlay
var rightMargin = 30; // Grace margin to avoid too close fits on the right and leave space for the controls

overlayWidth+= rightMargin;

var start = new google.maps.LatLng(48.857380, 2.351717);
var end = new google.maps.LatLng(50.108814, 8.672309);

function initialize() {

    var btn1 = document.getElementById('calcRoute');
    btn1.addEventListener('click', calcRoute);

    var btn2 = document.getElementById('offsetMap');
    btn2.addEventListener('click', offsetMap);

    var btn3 = document.getElementById('fitAndOffsetMap');
    btn3.addEventListener('click', fitAndOffsetMap);

    var btn4 = document.getElementById('fitMap');
    btn4.addEventListener('click', fitMap);

    directionsDisplay = new google.maps.DirectionsRenderer({
        draggable: true
    });

    var mapOptions = {
        zoom: 13,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        center: start,
        panControlOptions: {
            position: google.maps.ControlPosition.TOP_RIGHT
        },
        zoomControlOptions: {
            position: google.maps.ControlPosition.TOP_RIGHT
        }
    };

    map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
    directionsDisplay.setMap(map);
}

function offsetMap() {

    if (routeBounds !== false) {

        // Clear listener defined in directions results
        google.maps.event.clearListeners(map, 'idle');

        // Top right corner
        var topRightCorner = new google.maps.LatLng(map.getBounds().getNorthEast().lat(), map.getBounds().getNorthEast().lng());

        // Top right point
        var topRightPoint = fromLatLngToPoint(topRightCorner).x;

        // Get pixel position of leftmost and rightmost points
        var leftCoords = routeBounds.getSouthWest();
        var rightCoords = routeBounds.getNorthEast();
        
        var leftMost = fromLatLngToPoint(leftCoords).x;
        var rightMost = fromLatLngToPoint(rightCoords).x;

        // Calculate left and right offsets
        var leftOffset = leftMost-leftMargin;
        var rightOffset = (overlayWidth-(topRightPoint - rightMost));
        console.log(leftMost,rightMost,topRightPoint,leftOffset,rightOffset)

        // Only if left offset is needed
        if (rightOffset >= 0) {

            if (rightOffset < leftOffset) {
var mapOffset = Math.round((leftOffset-rightOffset ) / 2);

                // Pan the map by the offset calculated on the x axis
                map.panBy(mapOffset, 0);
                // Get the new left point after pan
     var newRightPoint = fromLatLngToPoint(rightCoords).x;
  
           console.log("e",newRightPoint,(topRightPoint-newRightPoint))
                if ((topRightPoint-newRightPoint) <= overlayWidth) {
           console.log("jjjj")
                    // Leftmost point is still under the overlay
                    // Offset map again
                 offsetMap();
                                    }
           
            }
            else {
            console.log("j")
                // Cannot offset map at this zoom level otherwise both leftmost and rightmost points will not fit
                // Zoom out and offset map again
                map.setZoom(map.getZoom() - 1);
                offsetMap();
            }
        }
    }
}

function fromLatLngToPoint(latLng) {

    var scale = Math.pow(2, map.getZoom());
    var nw = new google.maps.LatLng(map.getBounds().getNorthEast().lat(), map.getBounds().getSouthWest().lng());
    var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
    var worldCoordinate = map.getProjection().fromLatLngToPoint(latLng);

    return new google.maps.Point(Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale), Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale));
}

function calcRoute() {

    var request = {
        origin: start,
        destination: end,
        travelMode: google.maps.DirectionsTravelMode.DRIVING
    };

    directionsService.route(request, function (response, status) {

        if (status == google.maps.DirectionsStatus.OK) {

            directionsDisplay.setDirections(response);

            // Define route bounds for use in offsetMap function
            routeBounds = response.routes[0].bounds;

            // Write directions steps
            writeDirectionsSteps(response.routes[0].legs[0].steps);

            // Wait for map to be idle before calling offsetMap function
            google.maps.event.addListener(map, 'idle', function () {

                // Offset map
                offsetMap();
            });

            // Listen for directions changes to update bounds and reapply offset
            google.maps.event.addListener(directionsDisplay, 'directions_changed', function () {

                // Get the updated route directions response
                var updatedResponse = directionsDisplay.getDirections();

                // Update route bounds
                routeBounds = updatedResponse.routes[0].bounds;

                // Fit updated bounds
                map.fitBounds(routeBounds);

                // Write directions steps
                writeDirectionsSteps(updatedResponse.routes[0].legs[0].steps);

                // Offset map
                offsetMap();
            });
        }
    });
}

function writeDirectionsSteps(steps) {

    var overlayContent = document.getElementById("overlayContent");
    overlayContent.innerHTML = '';

    for (var i = 0; i < steps.length; i++) {

        overlayContent.innerHTML += '<p>' + steps[i].instructions + '</p><small>' + steps[i].distance.text + '</small>';
    }
}

function fitMap() {

    if (routeBounds !== false) {

        map.fitBounds(routeBounds);
    }
}

function fitAndOffsetMap() {

    if (routeBounds !== false) {

        map.fitBounds(routeBounds);
        offsetMap();
    }
}

initialize();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接