diff --git a/src/pages/Map.tsx b/src/pages/Map.tsx index d17e559..296cd2e 100644 --- a/src/pages/Map.tsx +++ b/src/pages/Map.tsx @@ -7,25 +7,67 @@ import OSM from 'ol/source/OSM'; import { useEffect, useRef } from 'react'; import Header from './component/Header'; import SearchMenu from './component/SearchMenu'; +import VectorSource from 'ol/source/Vector'; +import Feature from 'ol/Feature'; +import Point from 'ol/geom/Point'; +import VectorLayer from 'ol/layer/Vector'; +import Cluster from 'ol/source/Cluster'; +import Style from 'ol/style/Style'; +import CircleStyle from 'ol/style/Circle'; +import Fill from 'ol/style/Fill'; +import Stroke from 'ol/style/Stroke'; +import Text from 'ol/style/Text'; const MapPage = () => { - const mapRef = useRef( - new Map({ + const wrapperEl = useRef(null); + const source = useRef( + new VectorSource>({ + features: [], + }), + ); + + const mapRef = useRef(); + + useEffect(() => { + mapRef.current = new Map({ view: new View({ projection: PROJECTIONS[0], center: [127.3922689, 36.3407831], - zoom: 18, + zoom: 16, // extent: [124, 32, 134, 40], // maxZoom: 10, // minZoom: 6, }), - layers: [new TileLayer({ source: new OSM() })], - }), - ); - - const wrapperEl = useRef(null); - - useEffect(() => { + layers: [ + new TileLayer({ source: new OSM() }), + new VectorLayer({ + source: new Cluster({ + distance: 40, + source: source.current, + }), + style: (feature) => { + const size = feature.get('features').length; + return new Style({ + image: new CircleStyle({ + radius: 10, + stroke: new Stroke({ + color: '#fff', + }), + fill: new Fill({ + color: '#3399CC', + }), + }), + text: new Text({ + text: size.toString(), + fill: new Fill({ + color: '#fff', + }), + }), + }); + }, + }), + ], + }); const map = mapRef.current; map.setTarget(wrapperEl.current ?? undefined); return () => { @@ -33,6 +75,18 @@ const MapPage = () => { }; }, []); + useEffect(() => { + source.current.clear(); + for (let i = 0; i < 1000; i++) { + const r = Math.random() * 0.1; + const deg = Math.random() * 360; + const lat = 36.3407831 + r * Math.sin(deg); + const lon = 127.3922689 + r * Math.cos(deg); + const feature = new Feature(new Point([lon, lat])); + source.current.addFeature(feature); + } + }); + return (