Как использовать границы с динамическими маркерами в React-Leaflet

У меня есть следующий функциональный компонент реакции, который правильно отображает два статических маркера в рамке «границы», которая подходит для обоих маркеров внутри.

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

Это рабочий статический пример:

import React from 'react'
import { MapContainer, TileLayer, Marker } from 'react-leaflet'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'

const MapLeaflet = () => {

// STATIC MARKER POSITIONS
const position = [42.2974279, -85.628292];
const position2 = [-8.852507, -45.351563];

// BOUNDS CODE
const bounds = L.latLngBounds([position, position2]);

return (
    <MapContainer
        className=" map"
        center={position}
        bounds={bounds}
    >
        <Marker key={key} position={position}>
            <Heart/>
        </Marker>
        <Marker key={key} position={position2}>
            <Heart/>
        </Marker>

        <TileLayer
            attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
    </MapContainer>
        
)
}

Если я пройду {coords}, я смогу динамически отображать маркеры:

const MapLeaflet = ({coors}) => {
...
    { coords && coords.map(coord => (
           <Marker key={key} latitude={coord[0]} longitude={coord[1]}>
                <SomeMarker/>
           </Marker>
    ))}
...
}

Но очевидно, что карта еще не учитывает эти «координаты» для границ. Вывод console.log массива, переданного в coords, выглядит следующим образом:

0: (2) [51.52167056034225, -0.12894469488176763]
1: (2) [46.58635156377568, 2.1796793230151184]
2: (2) [40.819721, 14.341111]

Как-то мне нужно заменить следующую строку ссылкой на переданные координаты в формате, который принимает код, но я не могу понять, как это сделать.

const bounds = L.latLngBounds([position, position2]);

к чему-то вроде

const bounds = L.latLngBounds({coords});

Любая помощь будет очень высоко ценится.

С уважением, Мэтт


person Matt Heslington    schedule 28.03.2021    source источник
comment
Вы передаете массив из 3 массивов (значение координат)? latLngBounds принимает пару массивов широт. Также зачем использовать {} на latLngBounds. значение coords - это не объект, а массив массивов   -  person kboul    schedule 28.03.2021
comment
Привет, kboul, вывод журнала консоли показывает только три записи в качестве примера. Я использую массив массивов, хотя, судя по всему, я думаю. {Coords} был здесь как пример, я знаю, что он означает объект. Вы хоть представляете, возможно ли это, пожалуйста?   -  person Matt Heslington    schedule 28.03.2021
comment
Не могли бы вы создать небольшую демонстрацию с вашей текущей попыткой и реальными ценностями, которые вы передаете, потому что мне непонятно, что вы пытаетесь сейчас сделать?   -  person kboul    schedule 28.03.2021
comment
Извините, я не очень ясно выразился. Я сделаю jsfiddle и прокомментирую, когда это будет сделано. А пока я просто хочу заменить статические значения маркеров, const position и const position2 динамическими значениями, которые я передам компоненту в качестве реквизита. Динамические значения берутся из Firestore и выглядят так, как в console.log, который я опубликовал выше. Спасибо за вашу помощь!   -  person Matt Heslington    schedule 28.03.2021


Ответы (1)


Думаю, я понял, чего ты хочешь добиться.

maxBounds неизменен в response-leaflet v.3, поэтому вам нужно создать настраиваемый компонент, который будет изменять границы карты при изменении координат. Он будет использовать координаты в качестве опоры и изменит границы карты при изменении координат или при приземлении компа.

function Bounds({ coords }) {
  const map = useMap();
  useEffect(() => {
    if (!map) return;

    map.fitBounds(coords);
  }, [map, coords]);
  return null;
}

В вашем приложении я включил случай, когда границы изменяются (переменная coords), и границы карты меняются соответственно. Надеюсь, это то, что вы ищете.

function App() {
  const [coords, setCoords] = useState([
    [51.52167056034225, -0.12894469488176763],
    [46.58635156377568, 2.1796793230151184],
    [40.819721, 14.341111]
  ]);

  return (
    <>
      <MapLeaflet coords={coords} />
      <button
        onClick={() =>
          setCoords([
            [52.52167056034225, -0.12894469488176763],
            [47.58635156377568, 2.1796793230151184],
            [41.819721, 14.341111]
          ])
        }
      >
        Change coords
      </button>
    </>
  );
}

Демо

person kboul    schedule 28.03.2021
comment
ты абсолютная легенда. Это потрясающе. Вы меня прекрасно поняли и предоставили блестящее решение. Огромное спасибо. Я удивлен, что вы написали весь этот код в песочнице, чтобы показать мне, я искренне благодарен. Удачного дня - person Matt Heslington; 28.03.2021
comment
Не за что. Не за что. - person kboul; 28.03.2021
comment
Возникла очень странная проблема с кодом. Я связал короткое видео, чтобы показать вам. streamable.com/9ok78f В принципе, он не работает, если запускается заново с динамическим кодом, но если мы начнем со ссылок на маркеры в useState, он работает, а затем мы переключаемся на динамические реквизиты, он все еще работает, пока страница не будет перезагружена, когда снова произойдет сбой - person Matt Heslington; 29.03.2021
comment
Я не вижу той части, где вы используете MapLeafet и передаете реквизиты coords. Вы удаляете статическую переменную, но затем в качестве реквизита должны появиться координаты. В демонстрации я передаю координаты из App comp. Вы уверены, что он все еще идет и не будет неопределенным? И, кроме того, есть ли у них правильная структура, как ожидалось (массив массивов чисел)? - person kboul; 29.03.2021
comment
Извините, я добавил более медленное видео. Я начинаю использовать состояние маркеров, что, конечно же, работает. Затем я удаляю состояние и импортирую «координаты» в качестве реквизита, и это работает (чтобы переменные имели правильную структуру - вы можете видеть изменение маркеров карты). Затем я холодно обновляю страницу и получаю ошибку «Границы недействительны». Затем я просто снова прохожу процесс, чтобы показать. streamable.com/r6sqka - person Matt Heslington; 29.03.2021
comment
Извините, но я не вижу той части, где вы делаете MapLeaflet coords={...}. Также попробуйте вернуться из useeffect, если также coords.length равно 0. If (!map || coords.length===0) return внутри Bounds comp - person kboul; 29.03.2021
comment
Это через 6 секунд видео и через 47 секунд тоже. Кажется, это как-то связано с инициализацией границ или инициализацией компонента. Добавление строки выше привело к тому, что карта не отображалась. - person Matt Heslington; 29.03.2021
comment
Я имею в виду не код компонента, а то, где вы создаете экземпляр MapLeaflet в приложении или где-либо еще. Я ищу эту строку и переменную coords, которую вы передаете ‹MapLeaflet coords = {coords} /›, а не сам компонент MapLeaflet - person kboul; 29.03.2021
comment
Ой, извини, ха. Вот и все: cldup.com/B2-5wPzwV5.jpg Вот код, назначающий массив из Firestore cldup.com/FFfYA0Z416.jpg - person Matt Heslington; 29.03.2021
comment
Одна из возможных ошибок, которую я вижу, заключается в том, что вы напрямую нажимаете на массив coords. Тебе этого не сделать. Вы изменяете массив. Вы сначала клонировали его? Пожалуйста, зарегистрируйте значение coords внутри useeffect, если оно говорит, что границы недействительны - person kboul; 29.03.2021
comment
Вот скриншот: cldup.com/LJdBTEwF-Z.jpg Здесь есть координаты. странный. Я удалил || coords.length === 0, так как это предотвращает появление ошибки, но карта не отображается - person Matt Heslington; 29.03.2021
comment
Я модифицировал песочницу. Я использовал featureGroup, чтобы разместить там маркеры, не добавляя их на карту, и получить границы из группы. Не могли бы вы попробовать такой подход? - person kboul; 29.03.2021
comment
Ваш код работает отлично, у меня все еще та же проблема с использованием динамических значений. Я знаю почему - раньше, когда я тестировал исходный код, я начинал (чтобы проверить концепцию) со значениями статического состояния. Карта работала с ними. Затем я изменил компонент, чтобы принять динамические значения, т.е. функция экспорта по умолчанию MapLeaflet ({coords}) - это сработало, потому что на этом этапе значения динамических координат сохраняются в системе. Если я попытаюсь сделать это динамически из свежего массива, массив coords будет пуст. Возникла проблема с тем, как я звоню и сохраняю данные coords из Firestore - person Matt Heslington; 29.03.2021
comment
Большое вам спасибо за ваше время. Мы определили проблему, и она вовсе не в вашем коде, а в моем извлечении и хранении данных. - person Matt Heslington; 29.03.2021
comment
Пожалуйста. Удачи в твоем проекте. - person kboul; 29.03.2021
comment
Еще раз спасибо, вы здорово помогли - person Matt Heslington; 29.03.2021
comment
В качестве окончательного решения этой разворачивающейся драмы нам просто нужно было убедиться, что массив coords не пуст перед рендерингом Bounds: {coords.length ›0 &&‹ Bounds coords = {coords} / ›} - person Matt Heslington; 29.03.2021
comment
ха-ха. действительно драма! Круто! - person kboul; 29.03.2021