import React from 'react' import { Map, LngLat } from 'react-amap' import { Row, Col, Spin } from 'antd' import { connect } from 'react-redux' import { getData, changePageStatus } from 'reduxs/actions/amap' import { adCodes } from 'config/adcode' require('./amap.less') interface AmapState { currentAmap: any dataList: any[] markersList: any[] disProvince?: any loading: boolean lastLnglat: any[] mapConfig: { center: LngLat zoom: number events: any zooms: any } } interface AmapProps { dataList: any[] distributionType: number loading: boolean loadMapData: (params: searchModel) => void pageLoading: (status: boolean) => void } const currentWindow: any = window class PolymerizationMap extends React.Component<AmapProps, AmapState> { constructor(props: AmapProps) { super(props) this.state = { loading: true, markersList: [], dataList: [], lastLnglat: [104.65637, 35.414172], currentAmap: null, mapConfig: { zoom: 5, zooms: [5, 12], center: [104.65637, 35.414172], events: { created: this.createdAmap, zoomend: this.mapZoomend, hotspotover: this.mapHotspotover, complete: this.mapComplete }, } } } componentDidMount = () => { } /** * 获取鼠标最后悬停位置,用于鼠标缩放定位中心点 */ mapHotspotover = (arg: any) => { let lastLnglat = [] lastLnglat.push(arg.lnglat.lng) lastLnglat.push(arg.lnglat.lat) this.setState({ lastLnglat }) } /** * 地图缩放事件 */ mapZoomend = () => { const _that = this; const { currentAmap, dataList, lastLnglat } = this.state let oldMarkersList = this.state.markersList // 移除之前的点信息 oldMarkersList.map(item => { currentAmap.remove(item.marker) }); const { distributionType } = this.props if (distributionType === parseInt(distributionTypeEnum.Warehouse)) { return; } let zoom = currentAmap.getZoom(); console.log(zoom) currentWindow.AMap.plugin('AMap.Geocoder', function () { let geocoder = new currentWindow.AMap.Geocoder({ radius: 1000 //范围,默认:500 }); geocoder.getAddress(lastLnglat, function (status: any, result: any) { let markersList: any = [] if (status === "complete" && result.regeocode) { let province = result.regeocode.addressComponent.province; if (zoom > 7 && zoom < 10) { // 市 // let listdata = dataList.filter(t => { return province.indexOf(t.receiverProvince) > -1 }); let isExistence: any = {}; dataList.map(item => { let key = item.receiverProvince + item.receiverCity; if (isExistence[key] === undefined) { isExistence[key] = { city: item.receiverCity, cityLocal: item.cityCoordinates, count: item.ordersNumber }; } else { let it = isExistence[key]; it.count = it.count + item.ordersNumber; isExistence[key] = it; } }); let listKey = Object.keys(isExistence); listKey.map(key => { let item = isExistence[key]; let local = item.cityLocal.split(","); isExistence[item.city] = local; let mark = _that.createMarker(local, item.count, item.city, "city"); markersList.push(mark) }); } else if (zoom >= 10) { // 区 let listdata = dataList.filter(t => { return (province.indexOf(t.receiverProvince) > -1) }); listdata.map(item => { let local = item.districtCoordinates.split(","); let mark = _that.createMarker(local, item.ordersNumber, item.receiverDistrict, "area"); markersList.push(mark) }); } else { _that.createProvince(null) return } _that.setState({ markersList: markersList }) } else { _that.createProvince(null) } }) }) } createProvince = (data: any) => { const { dataList } = this.state let dataSource = [] if (data) { dataSource = data } else { dataSource = dataList } let isExistence: any = {}; dataSource.map((item: any) => { let key = item.receiverProvince if (isExistence[key] === undefined) { isExistence[key] = { province: item.receiverProvince, provinceLocal: item.provinceCoordinates, count: item.ordersNumber }; } else { let it = isExistence[key]; it.count = it.count + item.ordersNumber; isExistence[key] = it; } }); let listKey = Object.keys(isExistence); let markersList: any = [] listKey.map(key => { let item: any = isExistence[key]; let local = item.provinceLocal.split(","); let mark = this.createMarker(local, item.count, item.province, "province"); markersList.push(mark) }); this.setState({ markersList }) } // 创建地图 createdAmap = (instance: any) => { this.setState({ currentAmap: instance }) } // 地图加载结束 mapComplete = () => { let now = new Date() let pre = new Date(now.getTime() - 24 * 60 * 60 * 1000) let end = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate() let begin = pre.getFullYear() + '-' + (pre.getMonth() + 1) + '-' + pre.getDate() let params: searchModel = { distributionType: distributionTypeEnum.Customer, createTimeStart: begin, createTimeEnd: end } this.props.loadMapData(params) } /** * 方法-- 创建仓库分别区域 * @param local 坐标位置 * @param name 仓库显示名称 * @param number 仓库对应单量 */ creatMarkerWarehouse = (local: any[], name: string, number: number = 0) => { const position = []; // color = ` style="background:${fontColor}"`; position.push(parseFloat(local[0])); position.push(parseFloat(local[1])); const labelContent = `<div class="amap-text-warehouse"> <div class="amap-text-warehouse-title"> ${name} </div> <div class="amap-text-warehouse-content">出库量:${number}</div> </div>`; const marker = new currentWindow.AMap.Marker({ position, offset: new currentWindow.AMap.Pixel(-13, -30), content: labelContent }); marker.setMap(this.state.currentAmap); } // 创建点 createMarker = (local: any[], number: number, addressName: string, level: string) => { // let { markersList } = this.state let color = '' const position = []; position.push(parseFloat(local[0])); position.push(parseFloat(local[1])); switch (level) { case "city": color = ` style="background:#990099"`; break; case "area": color = ` style="background:#dd4477"`; break; } let labelContent = `<div class="amap-text"><div class="amap-text-left" ${color}>${number}</div>` labelContent += `<div class="amap-text-right">${addressName}</div></div>`; const marker = new currentWindow.AMap.Marker({ position, offset: new currentWindow.AMap.Pixel(-13, -30), content: labelContent }); marker.setMap(this.state.currentAmap); const _this = this; currentWindow.AMap.event.addListener(marker, "click", function (e: any) { _this.handlerMaker(e, local, level); // 得到的数据 }); let markers = { key: addressName, marker: marker } // markersList.push(markers) // this.setState({ markersList }) return markers } handlerMaker = (item: any, local: any, level: any) => { const { currentAmap } = this.state let c = []; c.push(parseFloat(local[0])); c.push(parseFloat(local[1])); currentAmap.setCenter(c); switch (level) { case "province": currentAmap.setZoom(8); break; case "city": currentAmap.setZoom(11); break; } } /** * 创建区域颜色 * @param dataList 渲染使用的数据 */ createColorArea = (dataList: any[] = []) => { const { currentAmap, disProvince } = this.state const _curr = this currentWindow.AMap.plugin(["AMap.DistrictLayer"], function () { let codes: any = [] let orderNumbers: any = {} adCodes.map(item => { let adcode = item.adcode let list = dataList.filter(t => item.name.indexOf(t.receiverProvince) > -1) if (list.length > 0) { codes.push(adcode) list.map(order => { orderNumbers[adcode] = orderNumbers[adcode] === undefined ? order.ordersNumber : orderNumbers[adcode] + order.ordersNumber }) } }) disProvince && disProvince.setMap(null); let _disProvince = new currentWindow.AMap.DistrictLayer.Province({ zIndex: 5, adcode: codes, styles: { 'fill': function (properties: any) { // properties为可用于做样式映射的字段,包含 // NAME_CHN:中文名称 // adcode_pro // adcode_cit // adcode var adcode = properties.adcode_pro; let count = orderNumbers[adcode] return _curr.getColorByValue(count); }, 'province-stroke': 'cornflowerblue', 'city-stroke': 'white', // 中国地级市边界 'county-stroke': 'rgba(255,255,255,0.5)' // 中国区县边界 } }); _disProvince.setMap(currentAmap); _curr.setState({ disProvince: _disProvince }) _curr.props.pageLoading(false) }) } getColorByValue(number: number) { if (number <= 0) { return "#a3ccff"; } if (number <= 100) { return "#98dcca"; } else if (number <= 500) { return "#69f6d0"; } else if (number <= 1000) { return "#3e9c83"; } else if (number <= 2000) { return "#03dda2"; } else if (number <= 5000) { return "#f945ee"; } else if (number <= 8000) { return "#c701bb"; } else if (number <= 10000) { return "#ff7e00"; } else if (number > 10000) { return "#fb0000"; } else { return "#a3ccff"; } } initMapData = (dataList: any[], distributionType: string) => { if (distributionType === '0') { this.createProvince(dataList) this.createColorArea(dataList) } else { dataList.map(item => { if (!item.deliveryWarehouseCoordinates) { return } let local = item.deliveryWarehouseCoordinates.split(',') this.creatMarkerWarehouse(local, item.warehouseName, item.ordersNumber) }) setTimeout(() => { this.props.pageLoading(false) }, 20); } this.setState({ dataList }) } componentWillReceiveProps = (nextProps: any) => { if (!nextProps.loading) { this.setState({ loading: nextProps.loading }) return } else { const { currentAmap, markersList } = this.state // currentAmap.clearMap() // 性能开销太大 markersList.map(item => { currentAmap.remove(item.marker) }); currentAmap.setZoom(5); currentAmap.setCenter([104.65637, 35.414172]); this.setState({ markersList: [], loading: nextProps.loading }) setTimeout(() => { const { dataList } = nextProps this.initMapData(dataList, nextProps.distributionType) }, 0); } } render() { const { loading, mapConfig } = this.state return <> <Spin spinning={loading} tip="loading..." size="large"> <Row> <Col style={{ '100%', height: '100vh', position: 'relative' }}> <Map {...mapConfig} useAMapUI amapkey="" > </Map> </Col> </Row> </Spin> </> } } const mapStateToProps = (state: any) => { return { dataList: state.AMapReducer.dataList, distributionType: state.AMapReducer.distributionType, loading: state.AMapReducer.loading } }; const mapDispatchToProps = (dispatch: any) => { return { loadMapData: (params: searchModel) => dispatch(getData(params)), pageLoading: (status: boolean) => dispatch(changePageStatus(status)), } } export default connect(mapStateToProps, mapDispatchToProps)(PolymerizationMap)
adcode 数据源 https://a.amap.com/Loca/static/mock/adcodes.js