map/src/pages/BaseMap/index.js
2023-12-10 22:37:15 +08:00

692 lines
26 KiB
JavaScript
Raw 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 React from 'react';
import { Select, Input, Card, Col, Row, Button, message, Modal, Spin, Form } from 'antd';
import axios from 'axios';
import LayerData from './LayerData';
import { AimOutlined } from '@ant-design/icons';
import Header from '../../components/Header/index.js';
import { createPoint, queryUserLayers } from '../../api';
import { GaodeMap ,Scene, Heatmap, PolygonLayer, Marker, MarkerLayer, Popup } from '@antv/l7';
import styles from './index.less';
const { Option } = Select;
const nullSearchAddress = () => {
message.error('地址信息为空');
};
const errorSearchAddress = () => {
message.error('地址搜索信息异常,请联系开发人员');
};
const successSearchAddress = () => {
message.success('已成功进行地图定位');
};
class BaseMap extends React.Component{
constructor(){
super();
this.state = {
map: null,
// 地图中心
center: {
// title: '石家庄',longitude: 114.502461,latitude: 38.045474
},
provinceList: [],// 省
provinceAdcode: '',//选中的省
provinceLabel: '',//选中的省
cityList: [],//市
cityAdcode:'',//选中的市
cityLabel: '',
districtList: [],//区
districtAdcode:'',//选中的区
zoom: 4,
inputExplainKey: 0,
inputExplainValue: "请输入地址详情信息",
inputContent: '',
heatMapList: [],
loading: false,
markerLayerList: [],
isModalOpen: false,
selectLayerList: [],
pointAdd: {
},
}
}
startLoading = () => {
this.setState({
loading: true,
});
}
stopLoading = () => {
this.setState({
loading: false,
});
}
// 钩子,打开执行
componentDidMount = () => {
this.getAllProvince();
this.createMap();
}
// 创建地图
createMap = () => {
const scene = new Scene({
id: 'container',
map: new GaodeMap({
pitch: 20,
style: 'light',
center: [ 116.405285, 39.904989 ],
zoom: 3
})
});
this.setState({
map: scene
});
}
//设置地图省份级别位置
gotoProvince = (data) => {
let zoom = data.zoom || 6;
let lng = data.len || 116.405285;
let lat = data.lat || 39.904989;
this.state.map.setZoomAndCenter(zoom, [lng, lat]);
}
//根据cityname、adcode、citycode设置地图位置
gotoCity = (data) => {
this.state.map.removeAllMarkers();
let zoom = data.zoom || 10;
let lng = data.len || 116.405285;
let lat = data.lat || 39.904989;
this.state.map.setZoomAndCenter(zoom, [lng, lat]);
}
// 获取图层明细点位数据/热力图数据
getLayerPoints = (layerId, selected, nodeType) => {
if (selected) {
this.startLoading();
return axios.get('/api/basicMap/getLayerPoints', {
params: {
adcode: this.state.districtAdcode || this.state.cityAdcode || this.state.provinceAdcode,
layerId: layerId
}
}).then((e) => {
let layerPointsData = e.data.data;
layerPointsData = layerPointsData.map((item) => {
item.lng = item.location.split(',')[0];
item.lat = item.location.split(',')[1];
item.value = 15;
return item;
});
if (nodeType === 1) {
this.setMarkers(layerPointsData, layerId);
} else if (nodeType === 4) {
this.setHeatMap(layerPointsData, layerId);
}
}).then(() => {
this.stopLoading();
});
} else {
let self = this;
let getLayers = self.state.markerLayerList;
for (let i = 0; i < getLayers.length; i++) {
if (getLayers[i].markerLayerOption.name == layerId) {
self.state.map.removeMarkerLayer(getLayers[i]);
}
}
self.hideHeatMap(layerId);
}
}
// 隐藏热力图
hideHeatMap = (layerId) => {
let heatMapList = this.state.heatMapList
for (let i = 0; i < heatMapList.length; i++) {
if (heatMapList[i].og.data[0].id === layerId || layerId === undefined || layerId === null || layerId === '') {
heatMapList[i].hide();
}
}
}
// 在地图上设置点位 【经度,纬度】
setMarkers = (data, layerId) => {
let self = this;
let map = this.state.map;
let LabelsData = data || [];
let markerLayer = new MarkerLayer({name: layerId});
let el, popup, marker, icon;
for (let i = 0; i < LabelsData.length; i++) {
icon = LabelsData[0].logoImage;
el = document.createElement('label');
el.style.width = '22px';
el.style.height = '22px';
el.style.background = 'url("' + icon + '") no-repeat';
el.style.backgroundSize = 'contain';
marker = new Marker({
element: el
}).setLnglat({lng: LabelsData[i].lng, lat: LabelsData[i].lat})
marker.on('click', (e) => {
popup = new Popup({
offsets: [0, 30]
})
.setLnglat(e.lngLat)
.setHTML(`
<div>
<div class="popup-title"><span class="popup-title-border"></span>详情信息</div>
<div class="popup-name">名称:${LabelsData[i].pointName}</div>
<div class="popup-address">地址:${LabelsData[i].address || ''}</div>
<div class="popup-memo">备注:${LabelsData[i].memo || ''}</div>
</div>`);
this.state.map.addPopup(popup)
});
markerLayer.addMarker(marker);
}
this.setState({
markerLayerList: [...this.state.markerLayerList, markerLayer],
})
this.state.map.addMarkerLayer(markerLayer);
}
// 在地图上设置热力图 【经度,纬度】
setHeatMap = (data, layerId) => {
let self = this;
let map = this.state.map;
let LabelsData = data || [];
let heatLayer = new Heatmap({nmae: layerId})
.source(LabelsData)
.shape('heatmap')
.size('mag', [ 0, 1.0 ]) // weight映射通道
.style({
intensity: 2,
radius: 20,
rampColors: {
colors: [
'#FF4818',
'#F7B74A',
'#FFF598',
'#91EABC',
'#2EA9A1',
'#206C7C'
].reverse(),
positions: [ 0, 0.2, 0.4, 0.6, 0.8, 1.0 ]
}
});
map.addLayer(heatLayer);
// 加载热力图插件
// var heatmap;
// var points = [];
// LabelsData.forEach(function (item) {
// points.push(
// {
// "lng": Number(item.location.split(',')[0]),
// "lat": Number(item.location.split(',')[1]),
// "count": item.weight,
// "id": layerId,
// }
// )
// })
// map.plugin(["AMap.Heatmap"],function(){
// // 在地图对象叠加热力图
// heatmap = new AMap.Heatmap(map, {
// radius: 25, //热力图的每个点的半径大小 [0,+∞)
// opacity: [0, 0.8], //热力图的透明度,分别对应heatmap.js的minOpacity和maxOpacity
// gradient:{ //热力图的颜色渐变区间。 {JSON}:key 插值的位置, 0-1; value颜色值
// 0.5: 'blue',
// 0.65: 'rgb(117,211,248)',
// 0.7: 'rgb(0, 255, 0)',
// 0.9: '#ffea00',
// 1.0: 'red'
// },
// });
// // 设置热力图数据集
// heatmap.setDataSet({data:points,max:100});
// });
// this.setState((state) => {
// state.heatMapList.push(heatmap);
// });
}
// 获取围栏图层数据
getLayerShapes = (layerId, selected, adcode) => {
if (selected) {
return axios.get('/api/basicMap/getLayerShapes', {
params: {
adcode: adcode || this.state.districtAdcode || this.state.cityAdcode || this.state.provinceAdcode,
layerId: layerId
}
}).then((e) => {
let positionBorderData = e.data.data;
this.setPolygon(positionBorderData, layerId);
});
} else {
this.state.map.removeAllLayer();
}
}
// 在地图上设置围栏、面
setPolygon = (d, layerId) => {
let self = this;
let map = this.state.map;
let data = d || [];
let overlayList = [];
const layer = new PolygonLayer({})
.source(data)
.shape('extrude')
.size('h20', [ 100, 120, 160, 200, 260, 500 ])
.color('h20', [
'#816CAD',
'#A67FB5',
'#C997C7',
'#DEB8D4',
'#F5D4E6',
'#FAE4F1',
'#FFF3FC'
]);
map.addLayer(layer);
// paths.forEach(function(path) {
// if(path.type === "ENVELOPE"){
// var tmp1 = path.positionRectangle[0]
// var tmp2 = path.positionRectangle[1]
// var southWest = new AMap.LngLat(tmp1[0], tmp1[1])
// var northEast = new AMap.LngLat(tmp2[0], tmp2[1])
// var bound = new AMap.Bounds(southWest,northEast);
// var rectangle = new AMap.Rectangle({
// id: layerId,
// bounds: bound,
// strokeColor: path.borderColor,
// strokeWeight: 1,
// strokeOpacity: path.borderOpacity,
// fillOpacity: path.opacity,
// fillColor: path.themeColor,
// zIndex: 50,
// });
// overlayList.push(rectangle);
// }else if(path.type === "POLYGON"){
// var polygon = new AMap.Polygon({
// id: layerId,
// path: path.positionBorder,
// strokeColor: path.borderColor,
// strokeWeight: 1,
// strokeOpacity: path.borderOpacity,
// fillOpacity: path.opacity,
// fillColor: path.themeColor,
// zIndex: 50,
// });
// overlayList.push(polygon);
// }
// });
// let overlay = new AMap.OverlayGroup(overlayList);
// map.add(overlay)
// 缩放地图到合适的视野级别
// map.setFitView([ polygon ])
}
// 获取省
getAllProvince = () => {
return axios.get('/api/mapCommon/getAllProvince').then((e) => {
let provinceData = e.data.data;
let provinceList = [];
for (var i in provinceData) {
provinceList.push({
'value': provinceData[i].provinceAdcode,
'label': provinceData[i].provinceName,
'zoom': 7,
'len': provinceData[i].centerCoordinate && provinceData[i].centerCoordinate.split(',')[0],
'lat': provinceData[i].centerCoordinate && provinceData[i].centerCoordinate.split(',')[1],
})
}
this.setState ({
provinceList: provinceList
})
});
}
// 选择省
onProvinceChange = (provinceAdcode, data) => {
var self = this;
let getLayers = this.state.map.getLayers();
// let getOverlays = this.state.map.getAllOverlays();
for (let i = 0; i < getLayers.length; i++) {
if (getLayers[i].CLASS_NAME === 'AMap.LabelsLayer') {
self.state.map.remove(getLayers[i]);
}
}
// this.state.map.remove(getOverlays);
data && this.gotoProvince(data)
this.getCityByProvince(`${provinceAdcode}`);
this.hideHeatMap();
this.setState ({
provinceAdcode: provinceAdcode ? `${provinceAdcode}` : '',
provinceLabel: data ? data.label : '',
zoom: 8,
districtList: [],//区
cityAdcode:'',//选中的市
cityLabel: '',
districtAdcode: '',
})
}
// 获取市
getCityByProvince = (provinceAdcode) => {
return axios.get('/api/mapCommon/getCityByProvince', {
params: {
provinceAdcode: provinceAdcode
}
}).then((e) => {
let cityData = e.data.data;
let cityList = [];
for (var i in cityData) {
cityList.push({
'value': cityData[i].cityAdcode,
'label': cityData[i].cityName,
'zoom': 10,
'len': cityData[i].centerCoordinate && cityData[i].centerCoordinate.split(',')[0],
'lat': cityData[i].centerCoordinate && cityData[i].centerCoordinate.split(',')[1],
})
}
this.setState ({
cityList: cityList
})
});
}
//选择市
onCityChange = (cityAdcode,data) => {
var self = this;
let getLayers = this.state.map.getLayers();
self.startLoading();
// let getOverlays = this.state.map.getAllOverlays();
for (let i = 0; i < getLayers.length; i++) {
if (getLayers[i].CLASS_NAME === 'AMap.LabelsLayer') {
self.state.map.remove(getLayers[i]);
}
}
// this.state.map.remove(getOverlays);
this.getDistrictByCity(`${cityAdcode}`);
this.refs.getLayerDataFun.getBasicLayerMenu(`${cityAdcode}`).then(() => {
self.stopLoading();
});
data && this.gotoCity(data);
this.hideHeatMap();
this.setState ({
cityAdcode: cityAdcode ? `${cityAdcode}` : '',
cityLabel: data ? data.label : '',
center: data && [parseFloat(data.lat), parseFloat(data.len)],
zoom: 10,
districtAdcode: ''
})
}
// 获取区
getDistrictByCity = (cityAdcode) => {
return axios.get('/api/mapCommon/getDistrictByCity', {
params: {
cityAdcode: cityAdcode
}
}).then((e) => {
let districtData = e.data.data;
let districtList = [];
for (var i in districtData) {
districtList.push({
'value': districtData[i].districtAdcode,
'label': districtData[i].districtName,
'zoom': 13,
'len': districtData[i].centerCoordinate && districtData[i].centerCoordinate.split(',')[0],
'lat': districtData[i].centerCoordinate && districtData[i].centerCoordinate.split(',')[1],
})
}
this.setState ({
districtList: districtList
})
});
}
//选择区
onDistrictChange = (provinceAdcode,data) => {
var self = this;
let getLayers = this.state.map.getLayers();
self.startLoading()
// let getOverlays = this.state.map.getAllOverlays();
for (let i = 0; i < getLayers.length; i++) {
if (getLayers[i].CLASS_NAME === 'AMap.LabelsLayer') {
self.state.map.remove(getLayers[i]);
}
}
// this.state.map.remove(getOverlays);
this.refs.getLayerDataFun.getBasicLayerMenu(`${provinceAdcode}`).then(() => {
self.stopLoading();
});
data && this.gotoCity(data);
this.hideHeatMap();
this.setState({
districtAdcode: provinceAdcode ? `${provinceAdcode}` : '',
center: data && [parseFloat(data.lat), parseFloat(data.len)],
zoom: 13,
})
}
onSearchSwitch = (data) => {
if(data === "1"){
this.setState({
inputExplainKey: 1,
inputExplainValue: "请输入经纬度详情格式例如116.405285,39.904989",
inputContent: ""
})
}else{
this.setState({
inputExplainKey: 0,
inputExplainValue: "请输入地址详情信息",
inputContent: ""
})
}
}
onSearchMap = () => {
if(this.state.inputExplainKey === 1){
let location = this.state.inputContent
let data = {
'zoom': 8,
'len': location.split(',')[0],
'lat': location.split(',')[1],
}
this.gotoCity(data)
let icon = "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png";
let searchPointMarker = new Marker().setLnglat({lng: location.split(',')[0], lat: location.split(',')[1]});
this.state.map.addMarker(searchPointMarker);
successSearchAddress();
}else{
let address = this.state.inputContent
if(address === "" ||address === null){
nullSearchAddress();
return false;
}else{
address = this.state.provinceLabel + this.state.cityLabel + address;
return axios.get('/api/mapCommon/getPointByAddress', {
params: {
address: address
}
}).then((e) => {
let coordinate = e.data.data;
if(coordinate === ""||coordinate === null){
errorSearchAddress();
}else{
let data = {
'zoom': 8,
'len': coordinate.location.split(',')[0],
'lat': coordinate.location.split(',')[1],
}
this.gotoCity(data)
let icon = "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png";
let searchPointMarker = new Marker().setLnglat({lng: coordinate.location.split(',')[0], lat: coordinate.location.split(',')[1]});
this.state.map.addMarker(searchPointMarker);
successSearchAddress();
}
});
}
}
}
//弹出框事件
showModal = () => {
queryUserLayers().then((e) => {debugger
let data = e.data;
let selectLayerList = [];
for (var i in data) {
selectLayerList.push({
'value': data[i].id,
'label': data[i].name,
})
}
this.setState({
isModalOpen: true,
selectLayerList: selectLayerList,
});
});
};
handleOk = (values) => {
createPoint({ //创建图层
"layerId": this.state.pointAdd.layerId,
"name": this.state.pointAdd.name,
"note": this.state.pointAdd.note,
"address": this.state.pointAdd.address,
"cityAdcode": this.state.cityAdcode,
// "cityName": "string",
"districtAdcode": this.state.districtAdcode,
// "districtName": "string",
// "location": "string",
"provinceAdcode": this.state.provinceAdcode,
// "provinceName": "string",
}).then((e) => {
if (e.success) {
message.success(e.message || '成功!');
this.setState({
isModalOpen: false
});
} else {
message.error(e.message || '失败!');
}
})
};
handleCancel = () => {
this.setState({
isModalOpen: false
});
};
onLayerNameChange = (e) => {
this.setState({
pointAdd: {
"layerId": this.state.pointAdd.layerId,
"name": this.state.pointAdd.name,
"note": this.state.pointAdd.note,
"address": this.state.pointAdd.address,
},
})
}
onPointAddNameChange = (e) => {
this.setState({
pointAdd: {
"layerId": this.state.pointAdd.layerId,
"name": this.state.pointAdd.name,
"note": this.state.pointAdd.note,
"address": this.state.pointAdd.address,
},
})
}
onPointAddAddressChange = (e) => {
this.setState({
pointAdd: {
"layerId": this.state.pointAdd.layerId,
"name": this.state.pointAdd.name,
"note": this.state.pointAdd.note,
"address": this.state.pointAdd.address,
},
})
}
onLayerNoteChange = (e) => {
this.setState({
pointAdd: {
"layerId": this.state.pointAdd.layerId,
"name": this.state.pointAdd.name,
"note": this.state.pointAdd.note,
"address": this.state.pointAdd.address,
},
})
}
render(){
return (
<div className={styles.basseMap} id='base_map'>
<Spin id='spin-show' size='large' spinning={this.state.loading}></Spin>
<Header></Header>
{/* 筛选框 */}
<Card className={styles.selectWrap} bordered={false}>
<Row>
<Col span={12}>
<Input.Group compact style={{display:"inline"}}>
<label className={styles.labelForm}>行政区域</label>
<Select style={{width: 120, marginLeft: 18}} onChange={this.onProvinceChange} options={this.state.provinceList} value={this.state.provinceAdcode} allowClear/>
<Select style={{width: 120, marginLeft: 18}} onChange={this.onCityChange} options={this.state.cityList} value={this.state.cityAdcode} allowClear/>
<Select style={{width: 120, marginLeft: 18}} onChange={this.onDistrictChange} options={this.state.districtList} value={this.state.districtAdcode} allowClear/>
</Input.Group>
</Col>
<Col span={12}>
<Input.Group compact style={{display:"inline",float:"right"}}>
<label className={styles.labelForm}>查询</label>
<Select defaultValue="0" style={{width: '80px'}} onChange={(e)=>{
this.onSearchSwitch(e);
}}>
<Option value="0">地址</Option>
<Option value="1">经纬度</Option>
</Select>
<Input id="tipinput" style={{width: '60%', height: 32, marginLeft: 18}} placeholder={this.state.inputExplainValue} value={this.state.inputContent} onChange={(e)=>{
this.setState({
inputContent: e.target.value
})
}}/>
<Button
type="primary"
style={{color: '#2F66F2', backgroundColor: 'white', }}
icon={<AimOutlined />}
onClick={this.onSearchMap}
/>
</Input.Group>
</Col>
</Row>
</Card>
{/* 图层数据显示 */}
<LayerData ref="getLayerDataFun" getLayerPoints = {this.getLayerPoints} getLayerShapes = {this.getLayerShapes}/>
<div className={styles.btnRightWrap}>
<Button type="primary" className={styles.btnRight} onClick={this.showModal}>点位创建</Button>
<Modal title="点位创建" open={this.state.isModalOpen} onOk={this.handleOk} onCancel={this.handleCancel} className='add-point-modal'>
<Form name='base' id='add-point-form' onFinish={this.handleOk}>
<Form.Item label="选择自定义图层"
rules={[
{
required: true,
message: '请输入图层名称!',
}
]}>
<Select name='name' value={this.state.pointAdd.layerId} options={this.state.selectLayerList} onChange={this.onLayerNameChange} allowClear>
</Select>
</Form.Item>
<Form.Item label="点位名称">
<Input name='note' value={this.state.pointAdd.name} onChange={this.onPointAddNameChange}/>
</Form.Item>
<Form.Item label="点位地址">
<Input name='note' value={this.state.pointAdd.address} onChange={this.onPointAddAddressChange}/>
</Form.Item>
<Form.Item label="图层备注">
<Input name='note' value={this.state.pointAdd.note} onChange={this.onLayerNoteChange}/>
</Form.Item>
</Form>
</Modal>
<Button disabled className={styles.btnRight}>点位导入</Button>
</div>
{/* 地图 */}
<div className={styles.mapWrap}>
<div style={{width: '100%', height: '100vh'}} id="container" />
</div>
</div>
)
}
}
export default BaseMap