ol5-react
v1.0.6
Published
#### 文件介绍
Downloads
2
Readme
Openlayers With React Hooks
文件介绍
map.js
context
layersContext.js
openlayersContext.js
提供OpenlayersContext、MapContext
hooks
useFeatchWindData.js
获取风场数据useLayer.js
useMap.js
提供map
useMapEvent.js
useMapTarget.js
useObservable.js
地图点击事件使用useStopEvent.js
useView.js
layers
imageLayer.js
加载png
类型的图片时使用layers.js
包裹各类型图层 提供addLayer,removeLayer
方法titleLayer.js
加载底图,服务器图层时使用vectorLayer.js
调用接口,前端绘制时使用windLayer.js
风场图
popup
弹窗utils
工具类
用法参考
## index.js
import React, { useState, useRef, useEffect } from 'react'
import ReactDOM from 'react-dom';
import OlMap from 'ol/Map';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import VectorSource from 'ol/source/Vector';
import TileWMS from 'ol/source/TileWMS';
import Static from 'ol/source/ImageStatic';
import Point from 'ol/geom/Point';
import Projection from 'ol/proj/Projection';
import { Style, Icon } from 'ol/style';
import { transform, transformExtent } from 'ol/proj';
import { defaults as defaultControls } from 'ol/control';
import Map from './map';
import Layer from './layers';
import Popup from './popup';
import { OpenlayersContext } from './context';
import { useObservable, useFetchWindData } from './hooks';
import sensor from './sensor.json';
import './map.css';
import { Feature } from 'ol';
const initView = new View({
projection: 'EPSG:3857',
center: transform([116, 40], 'EPSG:4326', 'EPSG:3857'),
zoom: 7
});
// 初始化地图实例
const map = new OlMap({
loadTilesWhileAnimating: true,
pixelRatio: 1,
controls: defaultControls({ attribution: false, zoom: false, rotate: false }),
});
// 风场空数据
const initData = [
{
data: [],
header: {
parameterCategory: 2,
parameterNumber: 2
}
},
{
data: [],
header: {
parameterCategory: 2,
parameterNumber: 3
}
}
];
const App = () => {
const refMap = useRef();
const [view, setView] = useState(initView);
const [visible, setVisible] = useState(true);
const url = 'http://101.201.70.8:9087/pic_server/windy_json/gfs.2020061900/2020061913.json';
const [layerUrl, setLayerUrl] = useState('http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i380072576!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0')
const [{ data, isLoading, isError }, setUrl] = useFetchWindData(url, initData);
const [features, setFeatures] = useState([]);
const [feature, setFeature] = useState(null);
const [showPopup, setShowPopup] = useState(true);
const [position, setPosition] = useState([0, 0]);
// useEffect(() => {
//
// }, [refMap]);
const originExtent = [115.4168938, 39.442185, 117.5082261, 41.0592191];
const iamgeExtent = transformExtent(originExtent, 'EPSG:4326', 'EPSG:3857')
const projection = new Projection({
code: 'xkcd-image',
units: 'pixels',
extent: iamgeExtent
})
const style = new Style({
image: new Icon(({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'https://openlayers.org/en/v5.3.0/examples/data/icon.png'
}))
});
const btnClick = e => {
// const { setView, setCenter } = refMap.current;
// setCenter([112, 40], 9)
setView(new View({
projection: 'EPSG:3857',
center: transform([116, 40], 'EPSG:4326', 'EPSG:3857'),
zoom: 7
}))
setVisible(v => !v);
// setLayerUrl('http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m2!1e5!2sshading!2m2!1e6!2scontours!2m3!1e0!2sm!3i456160658!3m8!3scn!5e1105!12m1!1e67!12m1!1e63!12m1!1e3!4e0!5m2!5f1!6b1')
// setUrl('http://101.201.70.8:9087/pic_server/windy_json/gfs.2020061900/2020061914.json')
const features = sensor.filter((item, index) => index <= 10).map(item => {
const lng = Number(item.wgs84_lng);
const lat = Number(item.wgs84_lat);
const geometry = new Point(transform([lng, lat], 'EPSG:4326', 'EPSG:3857'));
const feature = new Feature({
geometry: geometry
})
return feature;
});
setFeatures(features);
}
useEffect(() => {
const features = sensor.map(item => {
const lng = Number(item.wgs84_lng);
const lat = Number(item.wgs84_lat);
const geometry = new Point(transform([lng, lat], 'EPSG:4326', 'EPSG:3857'));
const feature = new Feature({
geometry: geometry
})
return feature;
});
setFeatures(features);
}, [])
// 地图点击事件
useObservable(map, 'singleclick', (evts) => {
const pixel = evts.pixel;
const coordinate = evts.coordinate;
let layer = map.forEachLayerAtPixel(
pixel,
l => {
return l;
},
// 过滤条件
// {
// layerFilter: l => l.get('name') === 'vector'
// }
);
if (!layer) {
return;
}
const type = layer.type;
if (type === 'TILE') {
const source = layer.getSource();
const resolution = map.getView().getResolution();
const url = source.getGetFeatureInfoUrl(
coordinate,
resolution,
'EPSG:3857',
{ 'INFO_FORMAT': 'application/json' }
);
const fetchData = async () => {
const result = await fetch(url).then(response => response.json());
const feature = result.features[0];
setFeature(feature);
}
fetchData();
} else if (type === 'VECTOR') {
map.forEachFeatureAtPixel(pixel, function (feature) {
setFeature(feature);
setPosition(coordinate);
setShowPopup(true);
console.log(coordinate);
});
}
}, []);
// useEffect(() => {
// if (feature) {
// console.log(feature)
// }
// }, [feature]);
return (
<OpenlayersContext.Provider value={{
map: map
}}>
<Map
ref={refMap}
view={view}
listener={{
type: 'click',
callback: (e) => console.log(e)
}}
>
{/* <Overlay
onMount={(e) => console.log(e)}
position={[12574196.901024632, 3233836.6206729477]}
>
<div className="ol-b-line">
<span className="ol-popup-closer" onClick={e => console.log(e)}>x</span>
</div>
</Overlay> */}
<Layer.Group>
<Layer.TileLayer
source={
new XYZ({
url: layerUrl,
crossOrigin: 'Anonymous'
})
}
name="geoq"
/>
<Layer.TileLayer id="2" source={new TileWMS({
url: 'http://gis.airqualitychina.cn:10001/geoserver/hotgrid/wms',
params: {
LAYERS: 'hotgrid:china_regions_gcj',
TILED: true,
cql_filter: 'CITYID = 1'
},
serverType: 'geoserver',
crossOrigin: 'anonymous'
})} name="boundry" />
{/* <Layer.WindLayer
id="2"
name="windy"
map={map}
data={data}
/> */}
<Layer.VectorLayer
source={
new VectorSource({
features: features
})
}
style={style}
visible={visible}
name="vector"
zIndex={2}
/>
<Layer.ImageLayer
id="3"
source={
new Static({
projection: projection,
imageExtent: iamgeExtent,
// url: 'http://47.104.21.213:8781/gfs/TMP/1/1/0/0/hourly/20200620/clip_2020062011.png',
url: 'http://47.104.21.213:8781/gfs/RH/1/1/0/0/hourly/20200620/clip_2020062011.png',
})
}
visible={visible}
/>
</Layer.Group>
<Popup
// onMount={(e) => console.log(e)}
position={position}
show={showPopup}
onClose={() => setShowPopup(false)}
>
<h3>Jeck</h3>
</Popup>
</Map>
<button onClick={btnClick} style={{
position: 'absolute',
top: 20,
right: 20
}}>Click Me</button>
</OpenlayersContext.Provider>
)
}
const el = document.createElement('div');
el.id = 'root';
document.body.appendChild(el);
ReactDOM.render(<App />, el);