Как разработать адаптивный слой-контейнер в Leaflet? - PullRequest
0 голосов
/ 16 января 2020

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

Карта листовки и ее слои должны соответствовать экрану. Например, если пользователь выбрал кружок в левом нижнем углу с разрешением 1920x1080 p c, то я должен увидеть его в левом нижнем углу с разрешением 1366x768 p c. Размер листовки для карты корректно изменяется со страницей, но в моем p c из-за его широты и долготы в этом примере круг выходит за пределы экрана.

Я пытался разработать этот пример с invalidateSize, maxBounds , fitBounds, et c. но пока не удалось. Как я могу разработать этот сценарий?

Сохраненный Geo JSON из 1920x1080 со слоями, выглядящими: enter image description here

Загруженные же Geo JSON из 1366x768 смотря (внимание в левый угол): enter image description here

Карта (React):

  const corner1 = L.latLng(-180, -180);
  const corner2 = L.latLng(180, 180);
  const bounds = L.latLngBounds(corner1, corner2);

        <Map
        ref={map => {
          this.tryToCreate(map);
        }}
        className="c-leaflet-map-map"
        center={[0, 0]}
        zoom={0}
        maxZoom={10}
        zoomControl={false}
        onzoomend={this.zoomLevelsChange}
        maxBounds={bounds}
        maxBoundsViscosity={1.0}
        zoomSnap={0}
        crs={L.CRS.Simple}
      >
        <ImageOverlay
          bounds={map.backgroundImageBounds || map.bounds}
          attribution="&amp;copy TofnaTech"
          url={
            map.backgroundImage ||
            map.backgroundImageURL ||
            TransparentImage
          }
          opacity={map.opacity}
          className={cn({ transparentImage: !map.backgroundImage })}
        />
        <FeatureGroup
          ref={controller => {
            this.controller = controller;
            this.tryToCreate();
          }}
        >
          <EditControl
            position="topleft"
            onCreated={this._onCreated}
            onEditStart={this.onEditStart}
            onEditStop={this.onEditStop}
            onEdited={this.onEdited}
            draw={{
              polyline: false,
              polygon: {
                shapeOptions: { ...defaultShapeOptions }
              },
              rectangle: {
                shapeOptions: { ...defaultShapeOptions }
              },
              circle: {
                shapeOptions: { ...defaultShapeOptions }
              },
              marker: false,
              circlemarker: false
            }}
            edit={{
              remove: false
            }}
          /></Map>

1 Ответ

0 голосов
/ 18 февраля 2020

Использование React-Leaflet немного отличается. Вы можете выполнить sh то, что вы пытаетесь сделать, в componentDidMount, где вы можете сделать ссылку на вашу карту и затем вызвать fitBounds для этого.

Редактировать: Добавление прямоугольника

Однако следующая проблема - это решение. Листовка будет поддерживать соотношение сторон, поэтому вам действительно нужно динамически визуализировать ваш круг (или прямоугольник) в углу, если вы всегда хотите, чтобы он отображался в нижнем левом углу экрана независимо от соотношения сторон экрана и браузера. Таким образом, в componentDidMount, сразу после того, как вы установили новые границы, вы можете получить эти границы и определить прямоугольник (или что-нибудь еще), чтобы всегда отображать в одном и том же месте относительно, скажем, границы getBounds()._southWest. В этом коде я обернул этот код в setTimeout, потому что анимация занимает мгновение, и этот момент должен пройти, чтобы получить новые значения границ из getBounds(). Я уверен, что есть способ уменьшить или убрать это время анимации.

Чтобы держать прямоугольник в одном и том же месте, я написал функцию onMove, чтобы карта всегда пересчитывала положение независимо от перемещения карты или изменения размера окна.

Обратите внимание, что размер прямоугольника в этом примере немного маловат sh, но я думаю, что вам будет проще получить постоянный размер с помощью CRS, поскольку CRS намного более однороден, чем лат и lngs.

class Map extends React.Component {

  state = {
    rectCoords: null
  };

  componentDidMount() {
    const map = this.mapReference.leafletElement;
    window.map = map;
    console.log("Initiates with bounds:", map.getBounds());

    map.fitBounds([[32.852169, -90.5322], [33.852169, -85.5322]]);

    setTimeout(() => {
      console.log("Bounds immediately reset to", map.getBounds());

      const rectCoords = [
        [
          map.getBounds()._southWest.lat + 0.1,
          map.getBounds()._southWest.lng + 0.1
        ],
        [
          map.getBounds()._southWest.lat + 1, 
          map.getBounds()._southWest.lng + 1
        ]
      ];

      this.setState({ rectCoords });
    }, 500);
  }

  onMapmove = () => {
    const map = this.mapReference.leafletElement;
    const rectCoords = [
      [
        map.getBounds()._southWest.lat + 0.1,
        map.getBounds()._southWest.lng + 0.1
      ],
      [map.getBounds()._southWest.lat + 1, map.getBounds()._southWest.lng + 1]
    ];

    this.setState({ rectCoords });
  }

  render() {

    return (
      <LeafletMap
        ref={mapReference => this.mapReference = mapReference}
        zoom={4}
        center={[33.852169, -100.5322]}
        onMove={() => this.onMapmove() } >

        <TileLayer ... />

        {this.state.rectCoords && (
          <Rectangle
            bounds={this.state.rectCoords}
            color={"#ff7800"}
            weight={1}
          />
        )}

      </LeafletMap>
    );

  }

}

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

Здесь это рабочий код andbox. Я уверен, что это можно адаптировать и для использования CRS Simple.

...