Skip to content
Snippets Groups Projects
Map.tsx 5.28 KiB
Newer Older
tovo's avatar
map
tovo committed
/* eslint-disable react-hooks/rules-of-hooks */
import React, { useState, useEffect } from "react"
import { isArray } from "lodash"
import {
  MapContainer,
  LayersControl,
  TileLayer,
  WMSTileLayer,
  GeoJSON,
} from "react-leaflet"
import "leaflet/dist/leaflet.css"

interface Props {
  idMap: number;
}

const Map = (props: Props) => {
  const projectUrl = process.env.PROJECT_URL as string
  if (typeof window !== "undefined") {
    let className = "z-40 h-full w-full"

    // Default id map (from mapstore)
    const idMap = props.idMap

    // Default center, zoom
    const center: number[] = [47.1, -1.25]
    const zoom: number = 9
    const layers: any[] = []

    // Get current map Object when ready (whenCreated)
    const [map, setMap] = useState(null)

    // Init default map context
    const [mapContext, setMapContext] = useState({
      center: {
        x: center[1],
        y: center[0],
      },
      zoom: zoom,
      layers: layers,
    })

    // Get Mapstore context
    useEffect(() => {
      fetch(projectUrl + "/geoportail/rest/geostore/data/" + idMap)
        .then((response) => response.json())
        .then((resultData) => {
          setMapContext(resultData.map)
          // Update map view with context data
          if (map)
            // @ts-ignore
            map.setView(
              [resultData.map.center.y, resultData.map.center.x],
              resultData.map.zoom
            )
        })
tovo's avatar
tovo committed
        .catch((error) => {
          console.log(error);
        })
tovo's avatar
map
tovo committed
    }, [projectUrl, map, idMap])

    return (
      <>
        <MapContainer
          center={[mapContext.center.y, mapContext.center.x]}
          zoom={mapContext.zoom}
          // @ts-ignore
          whenCreated={setMap}
          className={className}
          // scrollWheelZoom={false}
        >
          <LayersControl>
            {
              // BACKGROUNDS
              mapContext.layers
                .filter((layer) => layer.group === "background")
                .map((layer, key) => {
                  switch (layer.type) {
                    case "osm":
                      return (
                        <LayersControl.BaseLayer
                          key={key}
                          checked={layer.visibility}
                          name={layer.title}
                        >
                          <TileLayer
                            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                          />
                        </LayersControl.BaseLayer>
                      )
                    case "wmts":
                      // URL for IGN WMTS services
                      // TODO: test for other WMTS
                      const url =
                        layer.url +
                        "?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=" +
                        layer.name +
                        "&format=" +
                        layer.format +
                        "&style=" +
                        layer.style
                      return (
                        <LayersControl.BaseLayer
                          key={key}
                          checked={layer.visibility}
                          name={layer.title}
                        >
                          <TileLayer
                            url={url}
                            tileSize={256}
                            opacity={layer.opacity}
                          />
                        </LayersControl.BaseLayer>
                      )
                  }
                })
            }

            {
              // OVERLAYS

              // Load layers from context
              mapContext.layers.map((layer, key) => {
                if (isArray(layer.url)) return null
                switch (layer.type) {
                  case "vector":
                    return (
                      <LayersControl.Overlay
                        key={key}
                        checked={layer.visibility}
                        name={layer.name}
                      >
                        <GeoJSON
                          data={layer.features}
                          pathOptions={layer.style || ""}
                        />
                      </LayersControl.Overlay>
                    )
                  case "wfs":
                    break
                  case "wms":
                    return (
                      <LayersControl.Overlay
                        key={key}
                        checked={layer.visibility}
                        name={layer.title}
                      >
                        <WMSTileLayer
                          layers={layer.name}
                          format={layer.format}
                          transparent={true}
                          url={layer.url}
                          styles={layer.style || ""}
                          opacity={layer.opacity}
                        />
                      </LayersControl.Overlay>
                    )
                }
                return null
              })
            }
          </LayersControl>
        </MapContainer>
      </>
    )
  }

  return null
}

export default Map