oak-frontend-base/es/components/map/openlayer/index.js

125 lines
4.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { assert } from 'oak-domain/lib/utils/assert';
import { wgs84togcj02 } from 'oak-domain/lib/utils/geo';
import React, { useEffect, useState } from 'react';
import OlMap from 'ol/Map';
import Feature from 'ol/Feature';
import XYZ from 'ol/source/XYZ';
import VectorSource from 'ol/source/Vector';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import { Style, Circle, Fill } from 'ol/style';
import View from 'ol/View';
import { fromLonLat, toLonLat } from 'ol/proj';
import DragPan from 'ol/interaction/DragPan';
import MouseWheelZoom from 'ol/interaction/MouseWheelZoom';
import 'ol/ol.css';
import Styles from './web.module.less';
import { locate } from '../../../utils/locate';
import { Point } from 'ol/geom';
const prefix = Math.ceil(Math.random() * 1000);
const DEFAULT_CENTER = [120.123, 30.259]; // 浙大玉泉
const DEFAULT_ZOOM = 15;
export default function Map(props) {
const { id } = props;
const [map, setMap] = useState();
useEffect(() => {
const map2 = new OlMap({
target: id || `map-${prefix}`,
layers: [
new TileLayer({
source: new XYZ({
// 用的高德的瓦片gcj02坐标
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
wrapX: false,
}),
}),
new VectorLayer({
source: new VectorSource(),
}),
],
view: new View({
center: fromLonLat(wgs84togcj02(props.center || DEFAULT_CENTER)),
zoom: props.zoom || DEFAULT_ZOOM,
minZoom: props.unzoomable ? props.zoom : undefined,
maxZoom: props.unzoomable ? props.zoom : undefined,
}),
controls: props.unzoomable ? [] : undefined,
});
if (props.undragable) {
map2.getInteractions().forEach((ele) => {
if (ele instanceof DragPan) {
ele.setActive(false);
}
});
}
if (props.disableWheelZoom) {
map2.getInteractions().forEach((ele) => {
if (ele instanceof MouseWheelZoom) {
ele.setActive(false);
}
});
}
if (!props.center) {
locate().then(({ latitude, longitude }) => {
map2.getView().setCenter(fromLonLat(wgs84togcj02([longitude, latitude])));
});
}
setMap(map2);
}, []);
useEffect(() => {
if (props.center && map) {
const originCenter = map.getView().getCenter();
if (originCenter) {
const oc2 = toLonLat(originCenter);
if (oc2[0] !== props.center[0] || oc2[1] !== props.center[1]) {
map.getView().animate({
center: fromLonLat(wgs84togcj02(props.center)),
duration: 500,
});
}
}
else {
map.getView().setCenter(fromLonLat(wgs84togcj02(props.center)));
}
}
}, [props.center]);
useEffect(() => {
// marker好像没有效果以后再调
if (map) {
if (props.markers) {
const markerLayer = map
.getAllLayers()
.find((ele) => ele instanceof VectorLayer);
assert(markerLayer && markerLayer instanceof VectorLayer);
let feature = markerLayer.getSource().getFeatureById('markers');
if (feature) {
// feature.setGeometry(new MultiPoint(props.markers.map(ele => fromLonLat(ele))));
feature.setGeometry(new Point(fromLonLat(wgs84togcj02(props.markers[0]))));
}
else {
// feature = new Feature(new MultiPoint(props.markers.map(ele => fromLonLat(ele))));
feature = new Feature(new Point(fromLonLat(wgs84togcj02(props.markers[0]))));
feature.setStyle(new Style({
image: new Circle({
// 点的颜色
fill: new Fill({
color: 'red',
}),
// 圆形半径
radius: 10,
}),
// 填充样式
fill: new Fill({
color: 'red',
}),
}));
feature.setId('markers');
markerLayer.getSource().addFeature(feature);
}
}
map.render();
}
}, [props.markers, map]);
return (<div id={id || `map-${prefix}`} className={Styles.map} style={props.style}/>);
}