Skip to content
Snippets Groups Projects
Map.tsx 7.64 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 {
Toavina's avatar
Toavina committed
    MapContainer,
    LayersControl,
    TileLayer,
    WMSTileLayer,
    GeoJSON,
tovo's avatar
map
tovo committed
} from "react-leaflet"
import "leaflet/dist/leaflet.css"

interface Props {
    mapid: number
tovo's avatar
map
tovo committed
}

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

Toavina's avatar
Toavina committed
        // Default id map (from mapstore)
        const mapId = props.mapid
tovo's avatar
map
tovo committed

Toavina's avatar
Toavina committed
        // Default center, zoom
        const center: number[] = [47.1, -1.25]
        const zoom: number = 9
        const layers: any[] = []
tovo's avatar
map
tovo committed

Toavina's avatar
Toavina committed
        // Get current map Object when ready (whenCreated)
        const [map, setMap] = useState(null)
tovo's avatar
map
tovo committed

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

Toavina's avatar
Toavina committed
        // Get Mapstore context
        useEffect(() => {
Tovo Ramontalambo's avatar
Tovo Ramontalambo committed
            fetch("/geoportal/rest/geostore/data/" + mapId)
Toavina's avatar
Toavina committed
                .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
map
tovo committed
                })
Toavina's avatar
Toavina committed
                .catch((error) => {
                    console.log(error)
                })
        }, [projectUrl, map, mapId])
Toavina's avatar
Toavina committed

        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>
                                            )
                                    }
                                })
                        }
tovo's avatar
map
tovo committed

Toavina's avatar
Toavina committed
                        {
                            // OVERLAYS
tovo's avatar
map
tovo committed

Toavina's avatar
Toavina committed
                            // 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>
            </>
        )
    }
tovo's avatar
map
tovo committed

Toavina's avatar
Toavina committed
    return null
tovo's avatar
map
tovo committed
}

export default Map