You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
357 lines
14 KiB
357 lines
14 KiB
import React, { useEffect, useState } from 'react';
|
|
import { Tooltip } from 'antd';
|
|
import { connect } from 'react-redux';
|
|
import { render } from 'react-dom';
|
|
import { useMockRequest, useFsRequest } from '$utils';
|
|
import { communtity_data } from '../constants/index'
|
|
import moment from 'moment';
|
|
import './gis.less'
|
|
const MAPDOMID = 'fs-amap-container';
|
|
let map = null;
|
|
const TYPES = {
|
|
1: '消火栓',
|
|
2: '水箱',
|
|
3: '烟感',
|
|
4: '配电箱'
|
|
}
|
|
function Map(props) {
|
|
const [delay, setDelay] = useState(true)
|
|
const [tab, setTab] = useState('home')
|
|
const [type, setType] = useState(3)
|
|
|
|
const { data: devices = [] } = useMockRequest({
|
|
url: 'https://superchangnan.anxinyun.cn/api/xiaofang/devices',
|
|
method: 'mockGet',
|
|
});
|
|
|
|
const { data: communtityInfo = {} } = useFsRequest({ url: 'community/info' });
|
|
|
|
// 地图初始化
|
|
const loadMap = () => {
|
|
// 图片图层 实现瓦片地图中国地图样式 bounds 第一个点为左下角 第二个点为右上角
|
|
const imageLayer = new AMap.ImageLayer({
|
|
url: '/assets/images/map.svg',
|
|
bounds: new AMap.Bounds(
|
|
[115.800221, 28.265659],
|
|
[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/4eb48d1ef0a024c73376fd2256d0b5a5',
|
|
layers: [
|
|
AMap.createDefaultLayer(),
|
|
imageLayer,
|
|
],
|
|
});
|
|
|
|
map.on('complete', () => {
|
|
setDelay(false)
|
|
// tab == 'home' && map && renderMarkers()
|
|
});
|
|
|
|
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)
|
|
})
|
|
|
|
|
|
};
|
|
|
|
useEffect(() => {
|
|
loadMap();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!delay) {
|
|
setTimeout(() => {
|
|
tab == 'home' && map && renderMarkers()
|
|
tab == 'device' && map && renderDevices()
|
|
}, 200);
|
|
}
|
|
}, [tab, devices]);
|
|
|
|
useEffect(() => {
|
|
if (!delay) map && renderDevices()
|
|
}, [type]);
|
|
|
|
|
|
const renderMarkers = () => {
|
|
map.clearMap();
|
|
map.setZoom(10.3)
|
|
map.setCenter([116.054664, 28.538966])
|
|
map.setPitch(22.9)
|
|
map.setRotation(1.7000)
|
|
|
|
|
|
const data = communtity_data
|
|
const markers = []
|
|
//下钻点位显示
|
|
data.map((x, index) => {
|
|
var marker = new AMap.Marker({
|
|
position: new AMap.LngLat(x.lng, x.lat),
|
|
// 将一张图片的地址设置为 icon
|
|
icon: `/assets/images/homepage/communtity/${x.name}.png`,
|
|
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
|
|
offset: new AMap.Pixel(-69, -70),
|
|
zooms: [3, 19],
|
|
});
|
|
marker.setTitle(x.name);
|
|
map.add(marker);
|
|
markers.push(marker)
|
|
let infowindow = new AMap.InfoWindow({
|
|
isCustom: true, //使用自定义窗体
|
|
content: `<div id="map-content" class="gis-infowindow">
|
|
<div style="height:${360}px;" id="contentid${x.name}"></div></div>`,
|
|
offset: new AMap.Pixel(233, 260)
|
|
});
|
|
|
|
marker.on('click', () => {
|
|
let position = marker.getPosition ? marker.getPosition() : marker.getCenter();
|
|
infowindow.open(map, position);
|
|
map.setCenter(position)
|
|
setTimeout(() => {
|
|
let inuse = communtityInfo?.communityInUse?.find(v => v.houseCommunity == x.name)?.count || 0
|
|
let unuse = communtityInfo?.communityUnUse?.find(v => v.houseCommunity == x.name)?.count || 0
|
|
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'>
|
|
<div className='gis_title'>小区名称:</div>
|
|
<div className='gis_text'>{x.name}</div>
|
|
</div>
|
|
|
|
<div className='gis_item'>
|
|
<div className='gis_title'>房龄:</div>
|
|
<div className='gis_text'>{moment().diff(moment(x.build), 'years')}年</div>
|
|
</div>
|
|
<div className='gis_item'>
|
|
<div className='gis_title' style={{ color: '#13D3C9' }}>租赁中:</div>
|
|
<div className='gis_text'>
|
|
<span>{inuse}套</span>
|
|
<span style={{ color: '#FAC46E', marginLeft: 5, marginRight: 3 }}>空置:</span>
|
|
<span>{unuse}套</span>
|
|
</div>
|
|
</div>
|
|
<div className='gis_item'>
|
|
<div className='gis_title'>地址:</div>
|
|
<div className='gis_text'>{x.address}</div>
|
|
</div>
|
|
</div>,
|
|
document.getElementById(`contentid${x.name}`));
|
|
}
|
|
}, 50)
|
|
})
|
|
})
|
|
|
|
// map.setFitView(markers, false, [150, 150, 400, 400])
|
|
// data.map((x, index) => {
|
|
// var marker = new AMap.Marker({
|
|
// position: new AMap.LngLat(x.lng, x.lat),
|
|
// // 将一张图片的地址设置为 icon
|
|
// // 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
|
|
// // offset: new AMap.Pixel(-13, -30),
|
|
// zooms: [3, 19],
|
|
// });
|
|
// marker.setTitle(x.name);
|
|
// map.add(marker);
|
|
// })
|
|
}
|
|
|
|
const renderDevices = () => {
|
|
map.clearMap()
|
|
var style = [{
|
|
url: '/assets/images/homepage/communtity/gishydrant.png',
|
|
anchor: new AMap.Pixel(6, 6),
|
|
size: new AMap.Size(11, 11)
|
|
}, {
|
|
url: '/assets/images/homepage/communtity/giswatertank.png',
|
|
anchor: new AMap.Pixel(4, 4),
|
|
size: new AMap.Size(11, 11)
|
|
}, {
|
|
url: '/assets/images/homepage/communtity/gissmoke.png',
|
|
anchor: new AMap.Pixel(3, 3),
|
|
size: new AMap.Size(11, 11)
|
|
}, {
|
|
url: '/assets/images/homepage/communtity/giselectricity.png',
|
|
anchor: new AMap.Pixel(3, 3),
|
|
size: new AMap.Size(11, 11)
|
|
}];
|
|
let points = [], markers = [];
|
|
devices?.filter(x => x.type == type)?.map(x => {
|
|
let data = JSON.parse(x.data)
|
|
data?.map((s, index) => {
|
|
points.push(
|
|
{
|
|
lnglat: new AMap.LngLat(s.lng, s.lat),
|
|
style: x.type - 1,//对应的status相对应的样式style
|
|
name: s.address,
|
|
id: s.address + s.type + index,
|
|
data: s,
|
|
}
|
|
);
|
|
// if (index < 2000 && s.lng && s.lat) {
|
|
// const marker = new AMap.Marker({
|
|
// icon: '/assets/images/homepage/fire/leader.png',
|
|
// // icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
|
|
// position: [s.lng, s.lat],
|
|
// // offset: new AMap.Pixel(-13, -30),
|
|
// // content: ''
|
|
// // size: [13, 13]
|
|
// });
|
|
// marker.setTitle(index);
|
|
// marker.setMap(map);
|
|
// }
|
|
|
|
});
|
|
})
|
|
|
|
var mass = new AMap.MassMarks(points, {
|
|
opacity: 0.8,
|
|
zIndex: 11111111,
|
|
cursor: 'pointer',
|
|
style: style
|
|
});
|
|
|
|
mass.on('click', function (e) {
|
|
let id = Math.random(1000)
|
|
map.setCenter(e.data.lnglat)
|
|
let infowindow = new AMap.InfoWindow({
|
|
isCustom: true, //使用自定义窗体
|
|
content: `<div class="device-infowindow">
|
|
<div style="height:${360}px;" id="info-window${id}"></div></div>`,
|
|
offset: new AMap.Pixel(181, 260)
|
|
});
|
|
infowindow.open(map, e.data.lnglat)
|
|
|
|
setTimeout(() => {
|
|
if (document.getElementById('info-window' + id)) {
|
|
render(
|
|
<div>
|
|
<div className='gis_exit' onClick={() => { map.clearInfoWindow() }} />
|
|
<div style={{ marginTop: 10 }}>
|
|
<div className='gis_item'>
|
|
<div className='gis_title'></div>
|
|
<div className='gis_text'>{TYPES[type]}</div>
|
|
</div>
|
|
<div className='gis_item'>
|
|
<div className='gis_title'>地址</div><div className='gis_text'>
|
|
<Tooltip placement="top" title={e.data.name}>
|
|
<span style={{ color: '#FFF' }}>{e.data.name?.length > 20 ? e.data.name?.substring(0, 20) + '...' : e.data.name}</span>
|
|
</Tooltip>
|
|
</div>
|
|
</div>
|
|
<div className='gis_item'>
|
|
<div className='gis_title'>状态</div><div className='gis_text'>正常</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
,
|
|
document.getElementById('info-window' + id));
|
|
}
|
|
}, 50)
|
|
|
|
window.closeTooltip = () => {
|
|
testDiv.close();
|
|
}
|
|
})
|
|
|
|
mass.setMap(map)
|
|
}
|
|
|
|
const renderLeftTop = () => {
|
|
return <div className='home_left'>
|
|
<div className='hometotalbg'>廉租房总数</div>
|
|
<div className='home_total_number'>{communtityInfo ? (communtityInfo?.inuse + communtityInfo?.unuse) : '-'} </div>
|
|
|
|
<div className='hqtotal'>租赁中</div>
|
|
<div className='home_total_number'>{communtityInfo ? (communtityInfo?.inuse) : '-'}</div>
|
|
|
|
<div className='cztotal'>空置</div>
|
|
<div className='home_total_number'>{communtityInfo ? (communtityInfo?.unuse) : '-'}</div>
|
|
</div>
|
|
}
|
|
|
|
const renderRightBottom = () => {
|
|
return <div className='device_home_right'>
|
|
{[
|
|
{ name: '烟感设备', icon: 'gissmoke', type: 3 },
|
|
{ name: '配电箱', icon: 'giselectricity', type: 4 },
|
|
{ name: '消火栓', icon: 'gishydrant', type: 1 },
|
|
{ name: '水箱', icon: 'giswatertank', type: 2 }
|
|
].map(s => <div className='flex-row flex-item-center' style={{ marginBottom: 8 }}>
|
|
<div onClick={() => { setType(s.type) }} className={`checkbox`} >{s.type == type ? '✓' : ''}</div>
|
|
<img src={`/assets/images/homepage/communtity/${s.icon}.png`} />
|
|
<span>{s.name}</span>
|
|
</div>)}
|
|
</div>
|
|
|
|
}
|
|
|
|
|
|
return (
|
|
<>
|
|
{/* 延缓加载遮罩 */}
|
|
{delay && <div className='map_delay'><div className='delay_img' /></div>}
|
|
|
|
{/* 地图容器 */}
|
|
<div className="gis" id={MAPDOMID} />
|
|
|
|
|
|
{/* 底部按钮 */}
|
|
{[
|
|
{ name: '房屋分布', tab: 'home' },
|
|
{ name: '人口分布', tab: 'person' },
|
|
{ name: '基础设施', tab: 'device' }
|
|
].map((s, index) => {
|
|
|
|
return index == 1 ? '' : <div className={'gis-button' + (index + 1)}
|
|
onClick={() => {
|
|
if (delay) return
|
|
setTab(s.tab)
|
|
}}
|
|
style={{ zIndex: 1001 }}
|
|
>
|
|
<div className={`button_img ${tab == s.tab ? 'button_img_select' : ''}`} />
|
|
<div>{s.name}</div>
|
|
</div>
|
|
})
|
|
}
|
|
|
|
{/* 左上角图例 */}
|
|
{tab == 'home' && renderLeftTop()}
|
|
{tab == 'device' && 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);
|
|
|