peng.peng
1 year ago
8 changed files with 190 additions and 508 deletions
@ -1,470 +0,0 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { render } from 'react-dom'; |
|||
import { data as heatmapData } from './data' |
|||
import { SHUI_ZHAN } from '../constants/water'; |
|||
import './gis.less' |
|||
const MAPDOMID = 'fs-amap-container1'; |
|||
let map = null; |
|||
let heatmap = null; |
|||
let loca = null; |
|||
let gridLayer = null; |
|||
let interval = null; |
|||
const MARKER_IMG_NAME = { |
|||
markergreen: '回迁房', |
|||
markerblue: '城中村', |
|||
markeryellow: '廉租房', |
|||
} |
|||
function Map(props) { |
|||
const { trendData, waterLevelAlarms } = props; |
|||
const [delay, setDelay] = useState(true) |
|||
const [tab, setTab] = useState('overview') |
|||
|
|||
// 地图初始化
|
|||
const loadMap = () => { |
|||
// 图片图层 实现瓦片地图中国地图样式 bounds 第一个点为左下角 第二个点为右上角
|
|||
const imageLayer = new AMap.ImageLayer({ |
|||
url: '/assets/images/map1.svg', |
|||
bounds: new AMap.Bounds( |
|||
[115.800221, 28.225659], |
|||
[116.334849, 28.973298], |
|||
), |
|||
zooms: [3, 14], |
|||
}); |
|||
|
|||
map = new AMap.Map(MAPDOMID, { |
|||
center: [116.054664, 28.538966], |
|||
zoomEnable: true, |
|||
dragEnable: true, |
|||
viewMode: '3D', |
|||
pitch: 22.9, |
|||
labelzIndex: 130, |
|||
zoom: 10.3, |
|||
cursor: 'pointer', |
|||
mapStyle: 'amap://styles/300b147a96946a4f1c1b1b8eb1f92f76', |
|||
layers: [ |
|||
AMap.createDefaultLayer(), |
|||
imageLayer, |
|||
], |
|||
}); |
|||
|
|||
map.on('complete', () => { |
|||
setTimeout(() => { |
|||
setDelay(false) |
|||
map && renderMarkers() |
|||
map && renderAlarms() |
|||
}, 1500); |
|||
}); |
|||
|
|||
map.on('click', (e) => { |
|||
if (!e && !e.lnglat) { |
|||
return |
|||
} |
|||
|
|||
const zoom = map.getZoom(); |
|||
const pitch = map.getPitch(); |
|||
const center = map.getCenter(); |
|||
const Rotation = map.getRotation(); |
|||
console.log('zoom' + zoom) |
|||
console.log('pitch' + pitch) |
|||
console.log('center' + center) |
|||
console.log('Rotation' + Rotation) |
|||
console.log('e.lnglat' + e.lnglat) |
|||
}) |
|||
|
|||
loca = new Loca.Container({ map: map }) |
|||
// { map && renderMarkers() }
|
|||
// { map && renderAlarms() }
|
|||
// setTimeout(() => {
|
|||
// renderLayer()
|
|||
// createText()
|
|||
// }, 1000);
|
|||
}; |
|||
|
|||
const createText = () => { |
|||
var text = new AMap.Text({ |
|||
text: '南昌县', |
|||
anchor: 'center', // 设置文本标记锚点
|
|||
draggable: false, |
|||
// cursor: 'pointer',
|
|||
zooms: [3, 11], |
|||
style: { |
|||
'padding': '.75rem 1.25rem', |
|||
'margin-bottom': '1rem', |
|||
'border-radius': '.25rem', |
|||
'background-color': 'rgba(238,77,90,0.001)', |
|||
'width': '8rem', |
|||
'border-width': 0, |
|||
//'box-shadow': '0 2px 6px 0 rgba(255, 255, 255, .1)',
|
|||
'text-align': 'center', |
|||
'font-size': '14px', |
|||
'color': '#AFEFFF', |
|||
'opacity': 1, |
|||
// 'font-weight': 'bold'
|
|||
}, |
|||
position: [115.934664, 28.538966] |
|||
}); |
|||
text.setMap(map); |
|||
|
|||
} |
|||
const drawBounds = () => { |
|||
let district = null; |
|||
let polygons = []; |
|||
//加载行政区划插件
|
|||
if (!district) { |
|||
//实例化DistrictSearch
|
|||
let opts = { |
|||
subdistrict: 0, //获取边界不需要返回下级行政区
|
|||
extensions: 'all', //返回行政区边界坐标组等具体信息
|
|||
level: 'district' //查询行政级别为 市
|
|||
}; |
|||
district = new AMap.DistrictSearch(opts); |
|||
} |
|||
//行政区查询
|
|||
district.setLevel('district') |
|||
district.search('南昌县', function (status, result) { |
|||
map.remove(polygons)//清除上次结果
|
|||
polygons = []; |
|||
let bounds = result.districtList[0].boundaries; |
|||
if (bounds) { |
|||
for (let i = 0, l = bounds.length; i < l; i++) { |
|||
//生成行政区划polygon
|
|||
let polygon = new AMap.Polygon({ |
|||
strokeWeight: 1, |
|||
path: bounds[i], |
|||
fillOpacity: 0.4, |
|||
fillColor: '#1F2F4D', |
|||
strokeColor: '#DE7B35', |
|||
fillOpacity: 0.35, //填充透明度
|
|||
}); |
|||
polygons.push(polygon); |
|||
} |
|||
} |
|||
map.add(polygons) |
|||
// map.setFitView(polygons);//视口自适应
|
|||
}); |
|||
} |
|||
|
|||
// 初始化GIS 组件销毁清空定时器
|
|||
useEffect(() => { |
|||
loadMap(); |
|||
}, [trendData, waterLevelAlarms]); |
|||
|
|||
const renderMarkers = () => { |
|||
map.clearMap(); |
|||
map.setZoom(10.3) |
|||
map.setCenter([116.054664, 28.538966]) |
|||
map.setPitch(22.9) |
|||
map.setRotation(1.7000) |
|||
if (loca && heatmap) loca.remove(heatmap) |
|||
|
|||
//初始层级 zoom14以下显示聚合点
|
|||
// const data = [
|
|||
// { lng: 116.117906, lat: 28.678096, type: 'home', name: '泵站1', kind: 'markergreen' },
|
|||
// { lng: 116.195238, lat: 28.842114, type: 'home', name: '泵站2', kind: 'markerblue' },
|
|||
// { lng: 116.037227, lat: 28.558811, type: 'home', name: '泵站3', kind: 'markeryellow' },
|
|||
// { lng: 115.925856, lat: 28.558811, type: 'home', name: '泵站4', kind: 'markergreen' },
|
|||
// { lng: 115.989847, lat: 28.484411, type: 'home', name: '泵站5', kind: 'markergreen' },
|
|||
// ]
|
|||
|
|||
//初始点位显示
|
|||
SHUI_ZHAN.map((x, index) => { |
|||
var marker = new AMap.Marker({ |
|||
position: new AMap.LngLat(x.location[0], x.location[1]), |
|||
// 将一张图片的地址设置为 icon
|
|||
icon: '/assets/images/homepage/water/_monitor.png', |
|||
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
|
|||
offset: new AMap.Pixel(-13, -30), |
|||
zooms: [3, 14], |
|||
}); |
|||
marker.setTitle(x.name); |
|||
map.add(marker); |
|||
let infowindow = new AMap.InfoWindow({ |
|||
isCustom: true, //使用自定义窗体
|
|||
content: `<div id="map-content" class="water-gis-infowindow">
|
|||
<div style="height:${360}px;" id="contentid${x.name}"></div></div>`, |
|||
offset: new AMap.Pixel(153, 260) |
|||
}); |
|||
|
|||
marker.on('click', () => { |
|||
let position = marker.getPosition ? marker.getPosition() : marker.getCenter(); |
|||
infowindow.open(map, position); |
|||
map.setCenter(position) |
|||
setTimeout(() => { |
|||
if (document.getElementById(`contentid${x.name}`)) { |
|||
render(<div> |
|||
<div className='gis_exit' onClick={() => { |
|||
map.setCenter([115.922069, 28.554867]) |
|||
map.clearInfoWindow(); |
|||
}} /> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>泵站名称:</span> |
|||
<span className='gis_text'>{x.name}</span> |
|||
</div> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>1#提升泵:</span> |
|||
<div className='gis_text_on'> |
|||
</div> |
|||
</div> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>2#提升泵:</span> |
|||
<div className='gis_text_on'> |
|||
</div> |
|||
</div> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>3#提升泵:</span> |
|||
<div className='gis_text_off'> |
|||
</div> |
|||
</div> |
|||
</div>, |
|||
document.getElementById(`contentid${x.name}`)); |
|||
} |
|||
}, 50) |
|||
}) |
|||
}) |
|||
|
|||
|
|||
if (tab == 'device') { |
|||
const data = [ |
|||
{ lng: 115.921895, lat: 28.556351, type: 'device', name: '廉租房1', kind: 'devicemarker' }, |
|||
{ lng: 115.920839, lat: 28.555323, type: 'device', name: '廉租房2', kind: 'devicemarker' }, |
|||
{ lng: 115.918329, lat: 28.55445, type: 'device', name: '廉租房3', kind: 'devicemarker' }, |
|||
{ lng: 115.919309, lat: 28.553166, type: 'device', name: '廉租房1', kind: 'devicemarker' }, |
|||
{ lng: 115.921585, lat: 28.553925, type: 'device', name: '廉租房2', kind: 'devicemarker' }, |
|||
{ lng: 115.92565, lat: 28.556996, type: 'device', name: '廉租房3', kind: 'devicemarker' }, |
|||
{ lng: 115.922671, lat: 28.558769, type: 'device', name: '廉租房1', kind: 'devicemarker' }, |
|||
] |
|||
|
|||
data.filter(s => s.type == tab).map((x, index) => { |
|||
var marker = new AMap.Marker({ |
|||
position: new AMap.LngLat(x.lng, x.lat), |
|||
// 将一张图片的地址设置为 icon
|
|||
icon: '/assets/images/homepage/communtity/' + x.kind + '.png', |
|||
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
|
|||
offset: new AMap.Pixel(-13, -30), |
|||
zooms: [15, 19], |
|||
}); |
|||
marker.setTitle(x.name); |
|||
map.add(marker); |
|||
}) |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
const renderAlarms = () => { |
|||
if (tab == 'person' || !waterLevelAlarms.length || !trendData.length) { |
|||
return; |
|||
} |
|||
const alarms = waterLevelAlarms.map(a => { |
|||
let alarm = { |
|||
lng: a.lng, |
|||
lat: a.lat, |
|||
// type: 'device',
|
|||
name: a.alarms[0]?.source.name, |
|||
kind: 'markeralarm' |
|||
}; |
|||
for (const t of trendData) { |
|||
if (t?.id == a.alarms[0]?.source.id) { |
|||
alarm.waterLevel = t.waterLevel; |
|||
alarm.alert = t.alert; |
|||
} |
|||
} |
|||
return alarm; |
|||
}) |
|||
alarms.map((x, index) => { |
|||
var marker = new AMap.Marker({ |
|||
position: new AMap.LngLat(x.lng, x.lat), |
|||
// 将一张图片的地址设置为 icon
|
|||
icon: '/assets/images/homepage/communtity/' + x.kind + '.png', |
|||
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
|
|||
offset: new AMap.Pixel(-13, -30), |
|||
zooms: [3, 14], |
|||
zIndex: 13, |
|||
}); |
|||
marker.setTitle(x.name); |
|||
map.add(marker); |
|||
|
|||
let infowindow = new AMap.InfoWindow({ |
|||
isCustom: true, //使用自定义窗体
|
|||
content: `<div id="map-content" class="gis-infowindow-alarm">
|
|||
<div style="height:${360}px;" id="alarmcontentid${x.name}"></div></div>`, |
|||
offset: new AMap.Pixel(233, 260) |
|||
}); |
|||
|
|||
let alarmOk = new AMap.InfoWindow({ |
|||
isCustom: true, //使用自定义窗体
|
|||
// content: `<div id="map-content" class="gis-infowindow gis-infowindow-alarm">
|
|||
// <div style="height:${360}px;" id="contentid${x.name}"></div></div>`,
|
|||
offset: new AMap.Pixel(233, 440) |
|||
}); |
|||
|
|||
marker.on('click', () => { |
|||
let position = marker.getPosition ? marker.getPosition() : marker.getCenter(); |
|||
infowindow.open(map, position); |
|||
// map.setCenter(position)
|
|||
setTimeout(() => { |
|||
if (document.getElementById(`alarmcontentid${x.name}`)) { |
|||
render(<div> |
|||
<div className='gis_exit' onClick={() => { |
|||
map.setCenter([115.922069, 28.554867]) |
|||
map.clearInfoWindow(); |
|||
}} /> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>点位名称</span> |
|||
<span className='gis_text'>{x.name}</span> |
|||
</div> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>实时水位</span> |
|||
<span className='gis_text'>{x.waterLevel}m</span> |
|||
</div> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>预警水位</span> |
|||
<span className='gis_text'>{x.alert}m</span> |
|||
</div> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>近1h雨量</span> |
|||
<span className='gis_text'>1.5mm</span> |
|||
</div> |
|||
<div className='gis_item'> |
|||
<span className='gis_title'>告警</span> |
|||
<span className='gis_text'>高风险</span> |
|||
</div> |
|||
|
|||
</div>, |
|||
document.getElementById(`alarmcontentid${x.name}`)); |
|||
} |
|||
}, 50) |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
const renderLeftTop = () => { |
|||
return <div className='water_gis_home_left'> |
|||
{[{ name: '高风险区域', key: 'high', data: 3 }, |
|||
{ name: '中风险区域', key: 'middle', data: 13 }, |
|||
{ name: '低风险区域', key: 'low', data: 13 }].map(s => { |
|||
return <div className='left_item'> |
|||
<div className='gis_item_left'> |
|||
<div className={`${s.key}_risk`} /> |
|||
</div> |
|||
<div className='gis_item_right'> |
|||
<div>{s.name}</div> |
|||
<div><span className={`${s.key}_text`}>{s.data}</span>/21</div> |
|||
</div> |
|||
</div> |
|||
})} |
|||
|
|||
</div> |
|||
} |
|||
|
|||
const renderRightBottom = () => { |
|||
return tab == 'overview' ? |
|||
<div className='water_home_right'> |
|||
<div className='_right_row1'> |
|||
<div className='_monitor' /><span className='monitor_text'>监测点</span></div> |
|||
<div className='_right_row2'> |
|||
<span className='column1'>预警阈值参照表</span> |
|||
<div className='column2'> |
|||
<div className='flex-row flex-content-around'><span>三级告警</span><span>二级告警</span><span>一级告警</span></div> |
|||
<div className='flex-row flex-content-around'> |
|||
<div className='level3'></div> |
|||
<div className='level2'></div> |
|||
<div className='level1'></div> |
|||
</div> |
|||
{/* <div className='flex-row flex-content-around'> |
|||
<span>0m</span> |
|||
<span>5m</span> |
|||
<span>10m</span> |
|||
<span>15m</span> |
|||
<span>20m</span> |
|||
<span>25m</span> |
|||
<span>30m</span> |
|||
</div> */} |
|||
</div> |
|||
</div> |
|||
</div> : |
|||
<div className='water_home_right_back' onClick={() => { |
|||
setTab('overview') |
|||
props.changeTab('overview') |
|||
}}> |
|||
<div className='_back_icon' /> 返回实时监测 |
|||
</div> |
|||
} |
|||
|
|||
const renderWaterwarningbg = () => { |
|||
return <div className='waterwarningbg'> |
|||
<div className='_alarm_column1'> |
|||
<div>城区沿江水涝<div className='_state'>未启动</div></div> |
|||
<div style={{ color: 'rgba(76, 161, 255, 1)', fontSize: 14 }}>[自然灾害事故]</div> |
|||
</div> |
|||
<div className='_alarm_column2'> |
|||
<div style={{ textAlign: 'right', color: 'rgba(76, 161, 255, 1)' }}>2023-02-12 16:42:34</div> |
|||
<div className='_text_info'> |
|||
6月11日上午11点左右,低洼堤坝出现江水倒灌灾,需要进行救援。6月11日上午11点左右,低洼堤坝出现江水倒灌灾,需要进行救援。 |
|||
</div> |
|||
</div> |
|||
</div> |
|||
} |
|||
|
|||
const tabs = tab == 'overview' ? [ |
|||
{ name: '实时监测', tab: 'overview' }, |
|||
{ name: '应急抢险', tab: 'emergency' } |
|||
] : [ |
|||
{ name: '应急物资', tab: 'yjwz', className: 'emergency_button' }, |
|||
{ name: '消防救援', tab: 'xfjy', className: 'emergency_button' }, |
|||
{ name: '人民武装部', tab: 'rmwzb', className: 'emergency_button' }, |
|||
{ name: '医疗救援', tab: 'yljy', className: 'emergency_button' }, |
|||
{ name: '应急避难场所', tab: 'yjbns', className: 'emergency_button' }, |
|||
] |
|||
|
|||
return ( |
|||
<> |
|||
{/* 延缓加载遮罩 */} |
|||
{delay && <div id='delaydiv' style={{ |
|||
width: '100%', height: '100%', left: 0, top: 0, zIndex: 1000, background: '#000000', position: 'absolute', |
|||
display: 'flex', alignItems: 'center', justifyContent: 'center' |
|||
}}> |
|||
</div>} |
|||
|
|||
{/* 地图容器 */} |
|||
<div className="gis" id={MAPDOMID} /> |
|||
|
|||
|
|||
{/* 底部按钮 */} |
|||
{!delay && tabs.map((s, index) => { |
|||
return <> |
|||
<div className={s.className ? `${s.className} ${s.className}${index + 1}` : 'water-gis-button' + (index + 1)} |
|||
onClick={() => { |
|||
setTab(s.tab) |
|||
s.className ? props.changeEmengencyTab(s.tab) : props.changeTab(s.tab) |
|||
}} |
|||
> |
|||
<div className={ |
|||
s.className ? `button_${s.tab} ${tab == s.tab ? 'button_' + s.tab + '_select' : ''}` : |
|||
`button_img ${tab == s.tab ? 'button_img_select' : ''}`} /> |
|||
<div>{s.name}</div> |
|||
{s.className && <div className='dotbg'>{emergencyList[s.tab]?.length}</div>} |
|||
</div> |
|||
{/* { |
|||
tab !== 'overview' && <> <div className='icon_left'></div> |
|||
<div className='icon_right'></div></> |
|||
} */} |
|||
</> |
|||
}) |
|||
} |
|||
|
|||
{/* 左上角图例 */} |
|||
{tab == 'overview' && renderLeftTop()} |
|||
{tab == 'emergency' && renderWaterwarningbg()} |
|||
{renderRightBottom()} |
|||
{/* 四周遮罩 */} |
|||
<div className='gis-left'></div> |
|||
<div className='gis-right'></div> |
|||
<div className='gis-top'></div> |
|||
<div className='gis-bottom'></div> |
|||
</> |
|||
); |
|||
} |
|||
|
|||
export default connect()(Map); |
Loading…
Reference in new issue