You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

62 lines
1.9 KiB

import React, { useEffect, useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import "leaflet/dist/leaflet.css"
import L from 'leaflet';
export function MapView(props) {
// This is bad React design: this component holds state which the parent needs (the Leaflet map object).
// Normally we'd make such an object in the parent and pass it as a prop. However, the object cannot
// be created without a div being present for it to reside in, so we have a chicken-egg problem.
// We solve it by loading the map after mounting this component, then passing a handle to the parent.
const { onMapChange, style } = props;
const [map, setMap] = useState(null);
const [camera, setCameraNoPush] = useState([51.505, -0.09, 13]); //lat, long, zoom
var _ = require('lodash');
const id = _.uniqueId("leaflet_map_");
function updateCamera() {
var c = map.getCenter();
var z = map.getZoom();
setCameraNoPush([c[0], c[1], z]);
}
// Initialize the map on mount.
useEffect(() => {
setMap(L.map(id, {
center: [camera[0], camera[1]],
zoom: camera[2],
layers: [
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}),
]
}
));
}, [])
// Notify parent if map object changes.
useEffect(() => {
if (onMapChange) {
onMapChange(map);
}
}, map);
// Update camera state of this component when map changes.
useEffect(() => {
if (map != null) {
map.on('move', function (e) {
updateCamera();
});
map.on('zoom', function (e) {
updateCamera();
});
}
}, [map])
return <div id={id} style={style}></div>
}