Уменьшение масштаба карты Google - PullRequest
4 голосов
/ 02 мая 2020

Я использую карты Google в своем проекте. И у меня есть поле выбора, состоящее из страны и ее округов. При изменении местоположения с помощью выбора я увеличиваю масштаб до этого местоположения и рисую многоугольник на карте. Это прекрасно работает, когда я рисую многоугольник для одного места. Но если я выберу страну с, в данном случае 20 полигонами, которые нужно нарисовать, а затем уменьшить масштаб с карты, чтобы увидеть, весь процесс анимации становится затруднительным. Я попытался обернуть масштаб в объект Promise и подождать, пока он не закончится, а затем отцентрировать карту и нарисовать полигоны в надежде, что это поможет сделать его плавной анимацией. Ниже у меня есть событие select onchange, где в зависимости от выбранного значения я увеличиваю или уменьшаю масштаб с карты и рисую полигоны. Если выбранное значение было округом, я увеличиваю карту и рисую многоугольник только для этого округа. Если была выбрана страна, я уменьшаю масштаб и рисую многоугольники всех округов этой страны:

        let regions = geodata;
        let center = MAP_CENTER;
        let zoomLevel = 7;

        if (select.value !== country) {
            const location = geodata.find(({ Name }) => Name.includes(select.value));
            regions = [location];
            center = { lat: Number(location.Lat), lng: Number(location.Lng) };
            zoomLevel = 9;
        }

        smoothZoomPromise(map, zoomLevel, map.getZoom()).then((googleMap) => {
            googleMap.panTo(center);
            if (!(select.value === country && polygons.state.arrayOfPolygons.length === geodata.length)) {
                drawRegions(googleMap, regions);
            }
        });

Это функция smoothZoomPromise :

const smoothZoomPromise = (map, wantedLevel, startingLevel) => {
    return new Promise((resolve) => {
        if (wantedLevel === startingLevel) {
            return resolve(map);
        }
        const smoothZoom = (googleMap, finishLevel, startLevel) => {
            if (finishLevel === startLevel) {
                return;
            }
            const current = startLevel > finishLevel ? startLevel - 1 : startLevel + 1;
            const z = google.maps.event.addListener(googleMap, 'zoom_changed', event => {
                google.maps.event.removeListener(z);
                smoothZoom(googleMap, finishLevel, current);
            })

            doZoom(googleMap, current, resolve, current === finishLevel);
        }

        smoothZoom(map, wantedLevel, startingLevel);
    });
}

const doZoom = (map, cnt, resolve, last) => {
    setTimeout(() => {
        map.setZoom(cnt);
        if(last) {resolve(map)}
    }, 80);
}

И это Вот как я рисую полигоны:

export const polygons = {
    state: {
        arrayOfPolygons: []
    },
    clearState: function () {
        this.state.arrayOfPolygons.forEach(polygon => polygon.setMap(null));
        this.state.arrayOfPolygons = []
    }
};

export const drawRegions = (map, regions) => {
    polygons.clearState();
    regions.forEach(region => {
        const coords = region.Coordinates.map(item => ({
            lat: item[1], lng: item[0],
        }))

        // Construct the polygon.
        const color = colorMapper(getStatsData(region.Name));
        const polygon = new google.maps.Polygon({
            paths: coords,
            strokeColor: color,
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: color,
            fillOpacity: 0.35
        });
        polygon.setMap(map);
        polygons.state.arrayOfPolygons.push(polygon)
    })
}

Но, как я уже упоминал, проблема, с которой я столкнулся, заключается в том, что когда я выбираю страну и уменьшаю масштаб от 9 до 7 уровней масштабирования, и рисую для него 20 полигонов, уменьшение масштаба карты становится затруднительным. Есть ли способ, как я могу сделать это гладко и исправить это?

Я сделал пример codesanbox . Единственное, что нужно для его работы - это действительный API_KEY в index.js:

if (document.querySelector(".js-map")) {
  gmap.GMap(".js-map", "YOUR_API_KEY");
}

Я хотел бы добиться того же перехода, что и здесь с гугл картами. Где, если вы полностью увеличите масштаб, а затем измените местоположение с помощью select, карта не будет отображаться, пока не будет уменьшена. Как мне достичь этого эффекта?

1 Ответ

0 голосов
/ 12 мая 2020

Хитрость заключается в том, чтобы обернуть рисунок многоугольника внутри одноразового idle слушателя, то есть:

smoothZoomPromise(map, zoomLevel, map.getZoom()).then((googleMap) => {
  googleMap.panTo(center);
  if (
    !(
      select.value === "Croatia" &&
      polygons.state.arrayOfPolygons.length === geodata.length
    )
  ) {

    //  ----|
    //      |
    //      v
    google.maps.event.addListenerOnce(googleMap, "idle", () => {
      drawRegions(googleMap, regions);
    });

  }
});

Песочница здесь - вам нужно вставьте свой собственный ключ API.

Я думаю, это то, что в любом случае делает Google - это стандартная практика. Вы можете проверить различные типы событий gmap в действии здесь .

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