|
|
|
@ -1,44 +1,52 @@
|
|
|
|
import maplibregl from "maplibre-gl";
|
|
|
|
import maplibregl from "maplibre-gl";
|
|
|
|
import Map, { Layer, Popup, Source } from "react-map-gl";
|
|
|
|
import Map from "react-map-gl";
|
|
|
|
import { useRef, useState } from "react";
|
|
|
|
import { useRef, useState } from "react";
|
|
|
|
import {
|
|
|
|
|
|
|
|
clusterCountLayer,
|
|
|
|
|
|
|
|
clusterLayer,
|
|
|
|
|
|
|
|
unclusteredPointLayer,
|
|
|
|
|
|
|
|
} from "../clusters";
|
|
|
|
|
|
|
|
import { countoursLayer } from "../vector-tile";
|
|
|
|
|
|
|
|
import { NavigateButton } from "../NavigateButton";
|
|
|
|
|
|
|
|
import { Sidebar } from "../modules/Sidebar/Sidebar";
|
|
|
|
import { Sidebar } from "../modules/Sidebar/Sidebar";
|
|
|
|
|
|
|
|
import { gridLayer, pointLayer } from "./layers-config";
|
|
|
|
|
|
|
|
import { Layers } from "./Layers";
|
|
|
|
|
|
|
|
import { MapPopup } from "./Popup";
|
|
|
|
|
|
|
|
|
|
|
|
const MAP_TILER_KEY = "hE7PBueqYiS7hKSYUXP9";
|
|
|
|
const MAP_TILER_KEY = "hE7PBueqYiS7hKSYUXP9";
|
|
|
|
|
|
|
|
|
|
|
|
export const MapComponent = () => {
|
|
|
|
export const MapComponent = () => {
|
|
|
|
const mapRef = useRef(null);
|
|
|
|
const mapRef = useRef(null);
|
|
|
|
const [showPopup, setShowPopup] = useState(true);
|
|
|
|
const [clickedFeature, setClickedFeature] = useState(null);
|
|
|
|
|
|
|
|
const [popupCoordinates, setPopupCoordinates] = useState(null);
|
|
|
|
|
|
|
|
|
|
|
|
const onClick = (event) => {
|
|
|
|
const handleClick = (event) => {
|
|
|
|
try {
|
|
|
|
if (!event.features) return;
|
|
|
|
const feature = event.features[0];
|
|
|
|
|
|
|
|
if (!feature) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const clusterId = feature.properties.cluster_id;
|
|
|
|
const feature = event.features[0];
|
|
|
|
|
|
|
|
if (!feature) return;
|
|
|
|
|
|
|
|
|
|
|
|
const mapboxSource = mapRef.current.getSource("earthquakes");
|
|
|
|
const { lng: pointLng, lat: pointLat } = event.lngLat;
|
|
|
|
|
|
|
|
|
|
|
|
mapboxSource.getClusterExpansionZoom(clusterId, (err, zoom) => {
|
|
|
|
if (feature.geometry.type === "Point") {
|
|
|
|
if (err) {
|
|
|
|
const coordinates = feature.geometry.coordinates.slice();
|
|
|
|
return;
|
|
|
|
while (Math.abs(pointLng - coordinates[0]) > 180) {
|
|
|
|
}
|
|
|
|
coordinates[0] += pointLng > coordinates[0] ? 360 : -360;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mapRef.current.easeTo({
|
|
|
|
setPopupCoordinates(coordinates);
|
|
|
|
center: feature.geometry.coordinates,
|
|
|
|
} else {
|
|
|
|
zoom,
|
|
|
|
setPopupCoordinates([pointLng, pointLat]);
|
|
|
|
duration: 500,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
console.error(err);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setClickedFeature(feature);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleMouseEnter = (event) => {
|
|
|
|
|
|
|
|
const feature = event.features[0];
|
|
|
|
|
|
|
|
if (!feature) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mapRef.current.getCanvas().style.cursor = "pointer";
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleMouseLeave = (event) => {
|
|
|
|
|
|
|
|
const feature = event.features[0];
|
|
|
|
|
|
|
|
if (!feature) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mapRef.current.getCanvas().style.cursor = "";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
@ -52,39 +60,25 @@ export const MapComponent = () => {
|
|
|
|
zoom: 10,
|
|
|
|
zoom: 10,
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
ref={mapRef}
|
|
|
|
ref={mapRef}
|
|
|
|
interactiveLayerIds={[clusterLayer.id]}
|
|
|
|
interactiveLayerIds={[pointLayer.id, gridLayer.id]}
|
|
|
|
onClick={onClick}
|
|
|
|
onClick={handleClick}
|
|
|
|
|
|
|
|
onMouseEnter={handleMouseEnter}
|
|
|
|
|
|
|
|
onMouseLeave={handleMouseLeave}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{showPopup && (
|
|
|
|
{clickedFeature && popupCoordinates && (
|
|
|
|
<Popup
|
|
|
|
<MapPopup
|
|
|
|
longitude={-100}
|
|
|
|
lat={popupCoordinates[1]}
|
|
|
|
latitude={40}
|
|
|
|
lng={popupCoordinates[0]}
|
|
|
|
anchor="bottom"
|
|
|
|
feature={clickedFeature}
|
|
|
|
onClose={() => setShowPopup(false)}
|
|
|
|
onClose={() => {
|
|
|
|
>
|
|
|
|
setPopupCoordinates(null);
|
|
|
|
<div style={{ color: "red", fontWeight: "bold" }}>You are here</div>
|
|
|
|
setClickedFeature(null);
|
|
|
|
</Popup>
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
<Source
|
|
|
|
|
|
|
|
id="earthquakes"
|
|
|
|
<Layers />
|
|
|
|
type="geojson"
|
|
|
|
|
|
|
|
data="https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"
|
|
|
|
|
|
|
|
cluster={true}
|
|
|
|
|
|
|
|
clusterMaxZoom={14}
|
|
|
|
|
|
|
|
clusterRadius={50}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<Layer {...clusterLayer} />
|
|
|
|
|
|
|
|
<Layer {...clusterCountLayer} />
|
|
|
|
|
|
|
|
<Layer {...unclusteredPointLayer} />
|
|
|
|
|
|
|
|
</Source>
|
|
|
|
|
|
|
|
<Source
|
|
|
|
|
|
|
|
id="countours"
|
|
|
|
|
|
|
|
type="vector"
|
|
|
|
|
|
|
|
url="https://api.maptiler.com/tiles/contours/tiles.json?key=hE7PBueqYiS7hKSYUXP9"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<Layer {...countoursLayer} />
|
|
|
|
|
|
|
|
</Source>
|
|
|
|
|
|
|
|
<NavigateButton />
|
|
|
|
|
|
|
|
<Sidebar />
|
|
|
|
<Sidebar />
|
|
|
|
</Map>
|
|
|
|
</Map>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|