React 高德地图画点画区域放大缩小

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

原文地址:https://www.cnblogs.com/-Kam/p/12841377.html