Как сместить Направления маршрута Полилинии в сторону холста карты? - PullRequest
0 голосов
/ 19 февраля 2020

В настоящее время я работаю над проектом, основанным на направлении, и хочу рендерить sh мое направление справа при рендеринге. Это то, что я получаю. enter image description here

Я не хочу прокладывать маршруты позади панели. Это то, что я хочу получить. enter image description here

Направление между двумя точками на правой стороне.

Мой код для отображения направлений между двумя точками выглядит следующим образом

renderDirections(): void {
    var placeID = this.destinationPlaceId.getPlace();
    console.log(placeID.place_id);
    this.destinationPlaceId = placeID.place_id;
    let directionsService = new google.maps.DirectionsService;

    let directionsRenderer = new google.maps.DirectionsRenderer({
        preserveViewport: false
    });
    initMap();
    directionsRenderer.setMap(map);

    placeID = this.startPlaceID.getPlace();
    console.log(placeID.place_id);
    this.originPlaceId = placeID.place_id;
    directionsService.route(
        {
            origin: { 'placeId': this.originPlaceId },
            destination: { 'placeId': this.destinationPlaceId },
            travelMode: google.maps.TravelMode[this.travelMode]
        },
        function (response, status) {
            if (status === 'OK') {
                directionsRenderer.setDirections(response);

            } else {
                window.alert('Directions request failed due to ' + status);
                window.location.reload();
            }
        });
}

1 Ответ

1 голос
/ 19 февраля 2020

Нет готовой функции для достижения этой цели, но она выполнима, если вы знаете ширину (и положение) вашего верхнего слоя.

Вот как вы можете это сделать:

  1. Постройте маршрут на карте и прослушайте событие карты idle, прежде чем начинать процесс смещения.

  2. Проверьте крайнюю левую точку границ маршрута, чтобы увидеть, находится ли она позади наложения. При этом используется метод fromLatLngToPoint() для перевода координат широты / долготы в точку на проекции карты.

  3. Проверьте, насколько вы можете сместить маршрут, сравнив крайнюю левую и правую Точки маршрута с доступным пространством на карте. Смещайте карту до тех пор, пока обе точки не уместятся на доступном пространстве холста.

  4. Если обе точки не могут уместиться на холсте карты, уменьшите масштаб и снова запустите один и тот же процесс.

  5. Скрипт должен знать ширину наложения, и вы должны применять некоторые поля, чтобы он всегда хорошо подходил.

Фрагмент рабочего кода:

var directionsDisplay;
var directionsService;
var start, end;
var map;
var routeBounds = false;
var overlayWidth = 200; // Width of the overlay DIV
var leftMargin = 30; // Grace margin to avoid too close fits on the edge of the overlay
var rightMargin = 80; // Grace margin to avoid too close fits on the right and leave space for the controls

overlayWidth += leftMargin;

function initialize() {

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

    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 leftMost = fromLatLngToPoint(leftCoords).x;
        var rightMost = fromLatLngToPoint(routeBounds.getNorthEast()).x;

        // Calculate left and right offsets
        var leftOffset = (overlayWidth - leftMost);
        var rightOffset = ((topRightPoint - rightMargin) - rightMost);

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

            if (leftOffset < rightOffset) {

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

                // Pan the map by the offset calculated on the x axis
                map.panBy(-mapOffset, 0);

                // Get the new left point after pan
                var newLeftPoint = fromLatLngToPoint(leftCoords).x;

                if (newLeftPoint <= overlayWidth) {

                    // Leftmost point is still under the overlay
                    // Offset map again
                    offsetMap();
                }

            } else {

                // 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();
    }
}
body {
    margin: 0;
    padding: 0;
    font-family: Arial, Helvetica, sans-serif;
}
#map-canvas {
    height: 160px;
}
#overlay {
    position: absolute;
    width: 200px;
    height: 160px;
    background: black;
    opacity: 0.8;
    top: 0;
    left: 0;
    overflow: auto;
}
#overlayContent {
    color: white;
    padding: 10px 20px;
}
#overlayContent p {
    font-size: 12px;
    margin: 6px 0;
}
small {
    font-size: 9px;
}
#overlayContent small {
    display: block;
    text-align: right;
    font-style: italic;
}
i {
    color: lightblue;
}
h1 {
    font-size: 20px;
}
h5 {
    font-size: 12px;
}
button {
    margin: 20px 0 0 20px;
}
<div id="map-canvas"></div>
<div id="overlay">
    <div id="overlayContent">
         <h1>DIV OVERLAY</h1>

         <h5>Routes should not be drawn below this element.</h5>

         <h5>Click the <i>Calc route</i> button to draw the directions route.</h5>

         <h5><i>Map offset</i> will be applied automatically.</h5>

         <h5><i>Drag the route</i> to see how it is applied.</h5>

         <h5>Click the <i>Offset map</i> button to reapply the offset.</h5>

         <h5>Click the <i>Fit only</i> button to only fit route bounds.</h5>

         <h5>Click the <i>Fit and offset map</i> button to fit to route bounds and reapply offset.</h5>

    </div>
</div>
<button id="calcRoute">Calc route</button>
<button id="offsetMap">Offset map</button>
<button id="fitMap">Fit only</button>
<button id="fitAndOffsetMap">Fit and offset map</button>


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

Рабочая скрипка:

Вы можете играть с ней на JSFiddle , так как легче увидеть поведение, изменить размер окна и т. д. c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...