@amap/amap-jsapi-loader 实现高德地图中添加多边围栏,并可编辑,编辑后获得围栏各个点的经纬度

news2024/12/26 10:51:29

先上一张效果图 看看是不是大家想要的效果~ ❤️
希望其中的小点能帮助大家,主要看怎么绘制在地图上的代码即可
在这里插入图片描述

1.第一步要加入项目package.json中或者直接yarn install它都可以
想必大家应该都会

 "@amap/amap-jsapi-loader": "0.0.7"

2.加入项目中

import React, { PureComponent } from 'react';
import { Radio, Checkbox, Input, Button, message as AntMessage } from 'antd';
import AMapLoader from '@amap/amap-jsapi-loader';
import { services } from '@comall-backend-builder/core';
import './index.less';

const { api } = services;
type Geofence = {
    /**
     * 圆形围栏中心点,格式:longitude,latitude
     */
    center?: string;
    /**
     * 围栏名称
     */
    name: string;
    /**
     * 多边形围栏坐标点,格式:lon1,lat1;lon2,lat2;lon3,lat3
     */
    points: string;
    /**
     * 圆形围栏半径,单位:米。范围0~5000
     */
    radius?: number;
};
type GeofenceValue = {
    geofences: Array<Geofence>;
    scope: string;
    isEdit?: boolean;
};
const DEFAULTSCOPE = 'CUSTOM';
const DEFAULTNAME = '默认区域';
interface GeofencesProps {
    onChange: (data: GeofenceValue) => void;
    /**
     * 当前值
     */
    value: GeofenceValue;
    row: any;
}

interface GeofencesStates {
    /**
     * 当前地图实例
     */
    map: any;
    /**
     * 地图api
     */
    AMap: any;
    /**
     * 多边形对象集合
     */
    polygons: any;
    /**
     * 门店位置标记
     */
    marker: any;
    /**
     * 当前的门店维度
     */
    centerPosition: any;
    /**
     * 当前的门店名称
     */
    subsiteName: string;
}

export class Geofences extends PureComponent<GeofencesProps, GeofencesStates> {
    constructor(props: any) {
        super(props);

        this.state = {
            map: undefined,
            AMap: undefined,
            polygons: undefined,
            marker: undefined,
            centerPosition: undefined,
            subsiteName: '',
        };
    }

    componentDidMount() {
        this.initMap();
    }

    initMap = () => {
        api.get({}, { apiPath: '/admin/amap/config' }).then((result: any) => {
            AMapLoader.load({
                key: result.key, // 申请好的Web端开发者Key,首次调用 load 时必填
                version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
                plugins: ['AMap.Marker', 'AMap.Polygon', 'AMap.PolyEditor'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
            })
                .then((AMap: any) => {
                    let map = new AMap.Map('mapContainer', {
                        zoom: 13,
                    });
                    this.initSubsiteCenterPosition(AMap, map);
                    this.setState({ AMap, map });
                })
                .catch((e: any) => {
                    console.log(e);
                });
        });
    };

    initSubsiteCenterPosition = (AMap: any, map: any) => {
        const result = {
            longitude: 150.644,
            latitude: -34.397
        }
        //以上是我们项目接口返回的一个点的经纬度,在此我就简单设置了
        let centerPosition = new AMap.LngLat(result.longitude, result.latitude); // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
        this.setState(
            {
                centerPosition: centerPosition,
            },
            () => {
                this.initGeofrences(AMap, map);
            }
        );
    };

    initGeofrences = (AMap: any, map: any) => {
        const { centerPosition, subsiteName } = this.state;
        //移除所有覆盖物
        const { polygons, marker } = this.state;
        if (polygons) {
            map.remove(polygons);
        }
        if (marker) {
            map.remove(marker);
        }

        // 创建一个 Marker 实例:
        let newMarker = new AMap.Marker({
            position: centerPosition,
            title: subsiteName,
            zIndex: 101,
            bubble: true,
        });
        // 将创建的点标记添加到已有的地图实例:
        map.add(newMarker);

        let newPolygons = [];
        const path = [
            centerPosition.offset(-1500, 1500),
            centerPosition.offset(1500, 1500),
            centerPosition.offset(1500, -1500),
            centerPosition.offset(-1500, -1500),
        ];

        let polygon = new AMap.Polygon({
            path: path,
            strokeColor: '#1791fc',
            strokeWeight: 6,
            strokeOpacity: 0.2,
            fillOpacity: 0.4,
            fillColor: '#1791fc',
            zIndex: 100,
            bubble: true,
        });
        newPolygons.push(polygon);

        map.add(newPolygons);
        // 缩放地图到合适的视野级别
        map.setFitView(newPolygons);

        //开启多边形编辑
        newPolygons.forEach((newPolygon, index) => {
            let newPolyEditor = new AMap.PolyEditor(map, newPolygon);
            newPolyEditor.open();

            newPolyEditor.on('addnode', () => {
                this.onPolygonChange(index);
            });

            newPolyEditor.on('adjust', () => {
                this.onPolygonChange(index);
            });

            newPolyEditor.on('removenode', () => {
                this.onPolygonChange(index);
            });
        });

        this.setState({
            map,
            polygons: newPolygons,
            marker: newMarker,
        });
        //回传默认值
        let points = this.getPoints(path);
        let newValue: GeofenceValue = {
            scope: DEFAULTSCOPE,
            geofences: [
                {
                    name: DEFAULTNAME,
                    points,
                },
            ],
        };
        this.onChange(newValue);
    };

    onChange = (data: GeofenceValue) => {
        const { onChange } = this.props;
        onChange(data);
    };

    onPolygonChange = (index: number) => {
        let { value } = this.props;
        const { polygons } = this.state;
        let geofences;
        let geofence;
        if (value) {
            geofences = value.geofences;
            geofence = geofences[index];

            let points;
            if (polygons && polygons[index]) {
                points = this.getPoints(polygons[index].getPath());
            }
            geofence = { ...geofence, points };

            geofences.splice(index, 1, geofence);

            value = { ...value, geofences: geofences };
            this.onChange(value);
        }
    };

    onChangeScope = () => {};

    onNameChange = (event: any, index: number) => {
        let { value } = this.props;
        let geofences;
        let geofence;
        if (value) {
            geofences = value.geofences;
            geofence = geofences[index];
            geofence = { ...geofence, name: event.target.value };

            geofences.splice(index, 1, geofence);

            value = { ...value, geofences: geofences };
            this.onChange(value);
        }
    };

    getPoints = (path: any) => {
        return path
            .map((point: any) => {
                return point.lng + ',' + point.lat;
            })
            .join(';');
    };

    addPolygon = () => {
        const { AMap, map, centerPosition } = this.state;
        const { value } = this.props;
        if (value && value.geofences && value.geofences.length >= 10) {
            AntMessage.warning('仅支持最多配置10个自定义范围');
            return;
        }
        if (AMap && map && centerPosition) {
            const path = [
                centerPosition.offset(-1500, 1500),
                centerPosition.offset(1500, 1500),
                centerPosition.offset(1500, -1500),
                centerPosition.offset(-1500, -1500),
            ];
            const points = this.getPoints(path);
            let geofences = value.geofences;
            geofences.push({
                name: DEFAULTNAME,
                points,
            });
            value.geofences = geofences;
            this.onChange(value);
            setTimeout(() => {
                this.initGeofrences(AMap, map);
            }, 1000);
        }
    };

    deletePolygon = (index: number) => {
        let { value } = this.props;
        const { AMap, map } = this.state;
        if (value && map) {
            const newGeofences = value.geofences.slice();
            newGeofences.splice(index, 1);
            value.geofences = newGeofences;
            this.onChange(value);
            setTimeout(() => {
                map.clearMap();
                this.initGeofrences(AMap, map);
            }, 1000);
        }
    };

    render() {
        const { value } = this.props;

        const geofences = value && value.geofences ? value.geofences : [];
        const scope = value && value.scope ? value.scope : DEFAULTSCOPE;
        return (
            <div className="geofences">
                <Radio.Group onChange={this.onChangeScope} value={scope}>
                    <Radio value={'CUSTOM'}>自定义配送范围</Radio>
                </Radio.Group>
                <div className="scope-tip">
                    可以自定义半径5公里内的区域,收货地址在配送范围外的买家,不可以选择下单
                </div>
                <div className="geofences-wrap">
                    <div className="map-container" id="mapContainer"></div>

                    {geofences && geofences.length > 0 && (
                        <div className="setting-wrap">
                            <div className="setting-geofences-wrap">
                                {geofences.map((geofence, index) => {
                                    return (
                                        <Checkbox key={index} checked>
                                            <Input
                                                onChange={(e) => {
                                                    this.onNameChange(e, index);
                                                }}
                                                style={{ width: 145 }}
                                                value={geofence.name}
                                                maxLength={10}
                                            />
                                            {index !== 0 && (
                                                <span
                                                    className="setting-delete"
                                                    onClick={this.deletePolygon.bind(this, index)}
                                                >
                                                    {services.language.getText('common.delete')}
                                                </span>
                                            )}
                                        </Checkbox>
                                    );
                                })}
                            </div>
                            <Button type="default" className="add-btn" onClick={this.addPolygon}>
                                添加配送区域
                            </Button>
                        </div>
                    )}
                </div>
            </div>
        );
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1893511.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle EBS PO采购订单预审批状态处理

系统版本 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 问题症状: 采购订单状态:预审批 采购订单流程报错如下: po.plsql.PO_DOCUMENT_ACTION_AUTH.approve:90:archive_po not successful - po.plsql.PO_DOCUMENT_ACTION_PVT.do_action:110:unexpected error in acti…

Unity In App Purchasing内购校验

1&#xff0c;利用收据验证混淆器 把后台的key填进去&#xff0c;点击自动生成一些文件 2&#xff0c;代码过滤 using UnityEngine.Purchasing.Security;在IAPManager.cs的 public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)增加 #if !UNITY_EDITOR…

Linux—文件内系统与日志分析

目录 一、Linux文件系统 1、inode 与 block概述 1.2、inode内容 1.3、查找inode 1.4、inode故障处理 2、硬盘分区后的结构 3、访问文件的流程 4、文件恢复 4.1、恢复ext3格式文件 4.2、恢复 xfs 格式文件 二、Linux日志文件 1、日志的功能 2、日志的默认位置 3、日…

第一百四十二节 Java数据类型教程 - Java字符数据类型

Java数据类型教程 - Java字符数据类型 Character类的一个对象包装一个char值。 字符类包含isLetter()和isDigit()方法来检查字符是否为字母和数字。 toUpperCase()和toLowerCase()方法将字符转换为大写和小写。 该类提供了一个构造函数和一个工厂valueOf()方法来从char创建对…

高精度定位技术:赋能电网智能化转型的新引擎

在当今社会&#xff0c;电力作为经济发展的血脉&#xff0c;其稳定高效运行对于国家能源安全与社会发展至关重要。随着科技的飞速进步&#xff0c;高精度定位技术正逐步渗透至电网管理的各个环节&#xff0c;成为推动电网智能化转型的关键力量。本文将深入探讨高精度定位技术在…

联合查询(多表查询)

多表查询是对多张表的数据取笛卡尔积&#xff08;关联查询可以对关联表使用别名&#xff09; 数据准备 insert into classes(name, desc) values (计算机系2019级1班, 学习了计算机原理、C和Java语言、数据结构和算法), (中文系2019级3班,学习了中国传统文学), (自动化2019级5…

【java计算机毕设】美容院管理系统 项目源代码MySQL springboot vue html maven+文档 前后端可分离也可不分离

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】美容院管理系统 项目源代码MySQL springboot vue html maven文档 前后端可分离也可不分离 2项目介绍 系统功能&#xff1a; 美容院管理系统包括管理员、用户俩种角色。 管理员功能包括个人中心模块用于修改…

起飞,纯本地实时语音转文字!

简介 偶然在 github 上翻到了这个项目 https://github.com/k2-fsa/sherpa-ncnn 在没有互联网连接的情况下使用带有 ncnn 的下一代 Kaldi 进行实时语音识别。支持 iOS、Android、Raspberry Pi、VisionFive2、LicheePi4A等。 也就是说语音转文字可以不再借助网络服务的接口&am…

为什么技术合作伙伴必须获得 ISO 27001 认证

在当今的数字环境中&#xff0c;强大的安全措施的重要性怎么强调都不为过。 即使是像 Snowflake 这样的巨头&#xff0c;也很少有一天不出现重大漏洞&#xff0c;据《连线》报道&#xff0c;这可能是历史上最大的漏洞之一。 此外&#xff0c;98.3%的组织与至少一家第三方供应商…

【公益案例展】四川农担x中电金信——大数据智能风控平台建设

‍ 中电金信公益案例 本项目案例由中电金信投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2024中国数据智能产业最具社会责任感企业》榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 1、外部经济环境带来的挑战 近几年经济发展和市场需求的挑…

关于5G和卫星

手机&#xff0c;已经串联起了我们生活中的一切环节。我们随时随地拿出手机&#xff0c;都能畅快地上网。 这一切是如此地理所当然&#xff0c;以至于我们甚至想不到这样不可思议的问题&#xff1a; 移动通信网络真的无处不在吗&#xff1f; 我们都知道&#xff0c;地球虽叫…

企业级监控系统Zabbix

文章目录 Zabbix介绍Zabbix架构Zabbix serverZabbix agentZabbix proxy Zabbix Server的安装Zabbix Agent的安装监控主机流程zabbix_get自定义模板和监控项实战用户登录数监控1.指定监控项命令2.重启Agent服务3.在Server上创建监控项4.测试监控项5.查看监控项图形 故障自愈实现…

轮廓检测(python和c++实现)

利用轮廓检测&#xff0c;我们可以检测物体的边界&#xff0c;并在图像中轻松定位。这通常是许多有趣应用的第一步&#xff0c;如图像前景提取、简单图像分割、检测和识别。 无人看管物体检测&#xff1a;公共场所的任何无人看管物体一般都被视为可疑物体。一种有效而安全的解…

农作物生长环境的远程监控与智能调控

农作物生长环境的远程监控与智能调控 农作物生长环境的远程监控与智能调控技术&#xff0c;作为现代农业科技的核心组成部分&#xff0c;正逐步革新传统农业的生产模式&#xff0c;推动农业向精准化、智能化转型。这一技术体系综合应用了物联网、大数据、云计算以及人工智能等…

医疗器械进销存软件 专业合规的医疗公司器械出入库管理软件

财务管理&#xff1a;财务档案统一管理&#xff0c;有利于科学管理企业资金 财务管理&#xff1a;发票关联业务单据&#xff0c;业财融合&#xff0c;加速财务数字化转型 财务管理&#xff1a;提供收付款功能&#xff0c;加快企业应收账款的回收&#xff0c;降低付款的资金浮…

数据融合平台的概述、特点及技术方案

在当今数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据的分散存储和格式不一&#xff0c;常常导致数据孤岛现象&#xff0c;使得数据的潜在价值难以被充分挖掘和利用。在这样的背景下&#xff0c;数据融合平台应运而生&#xff0c;它的意义不仅在…

“第六感”真的存在吗?

现在已有证据表明&#xff0c;人类除视觉、听觉、嗅觉、味觉和触觉五种感觉以外&#xff0c;确实存在“第六感” “第六感”的学术名称为“超感自知觉”(简称ESP)&#xff0c;它能透过正感官之外的渠道接收信息&#xff0c; 预知将要发生的事&#xff0c;而且与当事人之前的经…

Windows的管理工具

任务计划程序&#xff1a;这是一个用来安排任务自动运行的工具。你可以在这里创建新的任务&#xff0c;设定触发条件&#xff0c;并指定任务的操作。 事件查看器&#xff1a;这是一套日志记录和分析工具&#xff0c;&#xff0c;你可以了解到系统的工作状况&#xff0c;帮助诊…

蓝蜂网关接入雄安新区物联网统一开放平台应用案例

蓝蜂网关接入雄安新区物联网统一开放平台案例 一、应用背景 为响应国家《河北雄安新区规划纲要》&#xff0c;由中国雄安集团数字城市科技有限公司牵头&#xff0c;以中移物联网有限公司为牵头单位的联合体&#xff0c;构建了雄安新区物联网统一开放平台&#xff08;简称雄安…

Anaconda安装及配置+pytorch深度学习环境(2024复旦计算机工作站0704)

目录 前言 一、Anaconda的下载与安装 二、检查是否有Nvidia显卡 三、安装CPU环境的pytorch 四、安装GPU环境的pytorch&#xff08;待写...) 五、Anaconda与Pycharm 配置 总结 前言 深度学习越来越火啦&#xff0c;深入到各行各业&#xff0c;小北个人也对深度学习很感兴…