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