使用react-bmapgl绘制区域并判断是否重叠

news2024/11/27 2:46:46

需求如下:

  • 在react项目中使用百度地图实现区域(电子围栏)的绘制
  • 绘制的区域类型为:1、多边形 2、圆形
  • 可绘制多个区域
  • 区域不能有重叠
  • 可重新编辑区域

代码如下:

index.tsx

import { useCallback, useEffect, useState } from 'react';
import { Space, Button, Radio, message } from 'antd';
import { Map, DrawingManager, MapApiLoaderHOC } from 'react-bmapgl';
import validator, { Type } from './utils';

interface OptionType {
  value: 'polygon' | 'circle';
  label: '多边形' | '圆形'
}

const TYPE: OptionType[] = [
  { value: 'polygon', label: '多边形' },
  { value: 'circle', label: '圆形' },
];


const IndexPage = () => {
  const [list, setList] = useState<Type[]>([]);
  // 当前绘制区域
  const [current, setCurrent] = useState<any>();
  // 当前绘制区域类型,默认绘制多边形
  const [type, setType] = useState(TYPE[0].value)
  // 是否开启绘制
  const [isOpen, setIsOpen] = useState(true);
  // 是否禁用继续绘制按钮
  const [disabled, setDisabled] = useState(true);
  // 是否处于编辑状态
  const [isEdit, setIsEdit] = useState(false);

  // 重新绘制
  const restart = () => {
    setIsOpen(true);
    setList(list.slice(0, -1));
    current.remove();
  };

  // 继续绘制
  const next = () => {
    setIsOpen(true);
  };

  // 编辑区域
  const edit = () => {
    if (isEdit) {
      current.disableEditing();
      handleValidator(current, type, list.slice(0, -1));
    } else {
      current.enableEditing();
    }
    setIsEdit(!isEdit);
  };

  // 区域重叠判断
  const handleValidator = (overlay: any, drawingMode: any, list: any[]) => {
    const flag = validator({ overlay, drawingMode }, list);
    if (flag) {
      setDisabled(false);
    } else {
      message.warning('区域重叠,请重新绘制');
      setDisabled(true);
    }
  };

  const NewDrawingManager = useCallback((props) => <DrawingManager {...props} />, [isOpen, type]);

  return (
    <div className="index-page" style={{ display: 'flex', flexDirection: 'column' }}>
      <Space>
        <Button size="small" type="primary" onClick={restart} disabled={isOpen}>重新绘制</Button>
        <Button size="small" type="primary" onClick={next} disabled={disabled}>继续绘制</Button>
        <Button size="small" type="primary" onClick={edit} disabled={isOpen}>{isEdit ? '保存编辑' : '编辑区域'}</Button>
      </Space>
      <Radio.Group value={type} onChange={e => setType(e.target.value)}>
        {
          TYPE.map(item => <Radio key={item.value} value={item.value}>{item.label}</Radio>)
        }
      </Radio.Group>
      <div style={{ flex: 1, position: 'relative' }}>
        <Map
          center={new BMapGL.Point(116.404449, 39.914889)}
          zoom={16}
          enableScrollWheelZoom
          style={{ height: '90vh' }}
        >
          <NewDrawingManager
            isOpen={isOpen}
            enableDrawingTool={false}
            drawingMode={type}
            onOverlaycomplete={(e: any, { drawingMode, overlay }: any) => {
              setList([...list, { drawingMode, overlay }]);
              setCurrent(overlay);
              setIsOpen(false);
              handleValidator(overlay, drawingMode, list);
            }}
            onOverlaycancel={(a: any, { overlay }: any) => {
              setIsOpen(false);
              // setCurrent(overlay);
              setTimeout(() => setIsOpen(true), 200)
            }}
          />
        </Map>
      </div>
    </div>
  );
}

export default MapApiLoaderHOC({ak: 'xxx'})(IndexPage);

引入GeoUtils.js

umirc.ts

import { defineConfig } from 'umi';

export default defineConfig({
  headScripts: ['http://127.0.0.1:5500/GeoUtils.js'],
});

打包后会在head标签里加入额外的脚本以便页面加载时在window上挂载BMapGLLib.GeoUtils实例:

<script src="http://127.0.0.1:5500/GeoUtils.js"></script>

utils.ts 区域重叠判断

包含三种:

1. 多边形与多边形是否重叠
2. 多边形与圆形是否重叠
3. 圆形与圆形是否重叠
export interface Type {
    overlay: any;
    drawingMode: 'circle' | 'polygon';
}

export const BMAP_DRAWING_CIRCLE = "circle",     // 鼠标画圆模式
    BMAP_DRAWING_POLYGON = "polygon";    // 鼠标画多边形模式

// 多边形与多边形是否重叠
export const fn1 = (polygon1: Type['overlay'], polygon2: Type['overlay']) => {
    const points1 = polygon1.getPath();
    const points2 = polygon2.getPath();
    return points1.some((item: any) => {
        const point = new BMapGL.Point(item.lng, item.lat);
        // @ts-ignore
        return BMapGLLib.GeoUtils.isPointInPolygon(point, polygon2);
    }) || points2.some((item: any) => {
        const point = new BMapGL.Point(item.lng, item.lat);
        // @ts-ignore
        return BMapGLLib.GeoUtils.isPointInPolygon(point, polygon1);
    });
}

// 多边形与圆形是否重叠
export const fn2 = (polygon: Type['overlay'], circle: Type['overlay']) => {
    const points1 = polygon.getPath();
    const points2 = circle.getPath();
    return points1.some((item : any) => {
        const point = new BMapGL.Point(item.lng, item.lat);
        // @ts-ignore
        return BMapGLLib.GeoUtils.isPointInCircle(point, circle)
    }) || points2.some((item : any) => {
        const point = new BMapGL.Point(item.lng, item.lat);
        // @ts-ignore
        return BMapGLLib.GeoUtils.isPointInPolygon(point, polygon);
    });
}

// 圆形与圆形是否重叠   
export const fn3 = (circle1: Type['overlay'], circle2: Type['overlay']) => {
    const points1 = circle1.getPath();
    const points2 = circle2.getPath();
    console.log(points1, points2);
    return points1.some((item : any) => {
        const point = new BMapGL.Point(item.lng, item.lat);
        // @ts-ignore
        return BMapGLLib.GeoUtils.isPointInCircle(point, circle2)
    }) || points2.some((item : any) => {
        const point = new BMapGL.Point(item.lng, item.lat);
        // @ts-ignore
        return BMapGLLib.GeoUtils.isPointInCircle(point, circle1)
    });
}

// 区域重叠校验是否通过 true-通过 false-不通过
export default ({ overlay, drawingMode }: Type, overlays: Type[]) => {
    try {
        let flag = false; // true-重叠 false-不重叠
        overlays.forEach(item => {
            if (!flag && drawingMode === BMAP_DRAWING_POLYGON && item.drawingMode === BMAP_DRAWING_POLYGON) {
                flag = fn1(overlay, item.overlay);
            }
            if (!flag && drawingMode === BMAP_DRAWING_POLYGON && item.drawingMode === BMAP_DRAWING_CIRCLE) {
                flag = fn2(overlay, item.overlay);
            }
            if (!flag && drawingMode === BMAP_DRAWING_CIRCLE && item.drawingMode === BMAP_DRAWING_POLYGON) {
                flag = fn2(item.overlay, overlay);
            }
            if (drawingMode === BMAP_DRAWING_CIRCLE && item.drawingMode === BMAP_DRAWING_CIRCLE) {
                flag = fn3(overlay, item.overlay);
            }
        });
        return !flag;
    } catch (error) {
        console.log(error);
    }
};

效果图:

在这里插入图片描述
在这里插入图片描述

相关链接:

  1. react-bmapgl文档:https://lbsyun.baidu.com/solutions/reactBmapDoc
  2. DrawingManager.js:https://github.com/huiyan-fe/BMapGLLib/blob/master/DrawingManager/src/DrawingManager.js
  3. DrawingManager.tsx:https://github.com/huiyan-fe/react-bmapgl/blob/master/src/Library/DrawingManager.tsx
  4. GeoUtils.js:https://github.com/huiyan-fe/BMapGLLib/blob/master/GeoUtils/src/GeoUtils.js

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

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

相关文章

Python入门实践(二)——变量的使用

文章目录变量1、变量的命名和使用1.1、避免命名错误2、字符串2.1、修改字符串大小写2.2、合并&#xff08;拼接&#xff09;字符串2.3、使用制表符或换行符来添加空白2.4、删除空白3、数字3.1、整数3.2、浮点数3.3、使用str()避免类型错误4、注释变量是对一种数据结构的命名&am…

2023年基建工程(设计规划施工)经验分享,超多干货

为了彻底打通从工程外业勘探调查、数据资料整理&#xff0c;到内业详细设计之间的一系列障碍&#xff0c;结合工程外业调查的特点&#xff0c;基于安卓&#xff08;Android&#xff09;操作系统&#xff0c;精心打磨推出了“外业精灵”移动端应用软件。 该系统把工程外业探勘、…

MPP数据库简介及架构分析

目录什么是MPP&#xff1f;特性并行处理超大规模数据仓库真正适合什么典型的分析工作量数据集中化线性可伸缩性MPP架构技术特性数据库架构分析Shared EverythingShared DiskShare MemoryShared NothingShared Nothing数据库架构优势什么是MPP&#xff1f; MPP (Massively Paral…

分享88个C源码,总有一款适合您

C源码 分享88个C源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c;大家下载后可以看到。 源码下载链接&#xff1a;https://pan.baidu.com/s/1TT87gt66kn5BtLqgRUTlUQ?pwdwje5 提取码…

Java图形化界面---JOptionPane

目录 一、JOptionPane的介绍 二、JOptionalPane的使用 &#xff08;1&#xff09;消息对话框 &#xff08;2&#xff09; 确认对话框 &#xff08;3&#xff09;输入对话框 &#xff08;4&#xff09;选项对话框 一、JOptionPane的介绍 通过JOptionPane可以非常方便地创建…

SpringCloud复习之Sleuth+Zipkin链路追踪实战

文章目录写作背景为什么要有链路监控SpringCloud SleuthZipkin能做什么上手实战启动一个Zipkin Server微服务集成SleuthZipkin写作背景 前面复习了SpringCloud Netflix的几个核心组件&#xff0c;包括Eureka、Ribbon、Feign、Hystrix、Zuul&#xff0c;并进行了Demo级别的实战…

高精度减法【c++】超详细讲解

前言 大家学过高精度加法之后&#xff0c;可能已经知道高精度减法的实现方法了吧 如果你还没有学过高精度加法的话&#xff0c;请点击这里&#xff08;很详细的&#xff09;—>高精度加法【C实现】详解 最大的问题 最大的问题莫过于负数问题了。其他方法和加法一样。 负…

4.二级缓存解析

文章目录1. 二级缓存配置2. 二级缓存结构3. 二级缓存命中条件4. 缓存空间的理解5. 二级缓存执行流程二级缓存也称作是应用级缓存&#xff0c;与一级缓存不同的&#xff0c;是它的作用范围是整个应用&#xff0c;而且可以跨线程使用。所以二级缓存有更高的命中率&#xff0c;适合…

从南丁格尔图到医学发展史

可视化中&#xff0c;前端用于表现不同类目的数据在总和中的占比的场景&#xff0c;往往会采用饼图。 针对数据大小相近&#xff0c;南丁格尔图的呈现会更加美观。 南丁格尔图&#xff0c;又称玫瑰图&#xff0c;是由弗罗伦斯南丁格尔发明。 弗洛伦斯南丁格尔 开创了护理事业…

二、django中的路由系统

django中的路由系统 django中路由的作用和路由器类似&#xff0c;当一个用户请求Django站点的一个页面时&#xff0c;是路由系统通过对url的路径部分进行匹配&#xff0c;一旦匹配成功就导入并执行对应的视图来返回响应。 django如何处理请求 当一个请求来到时&#xff0c;d…

SpringSecurityOauth2架构Demo笔记

总体分为SpringSecurityOauth2授权码模式演示和密码模式演示 一直下一步,依赖手动导入,SpringBoot版本改成2.2.5.RELEASE,JDK版本1.8 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xml…

Open3D 点云投影至指定球面(Python版本)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 假设球体的相关参数:中心为 C ( x c , y c , z c ) C(x_c,y_c,z_c)

【数据结构和算法】栈—模拟实现Stack和栈相关算法题

文章目录栈的定义Stack模拟实现相关算法题1.栈的压入弹出序列2.逆波兰表达式(后缀表达式)⭐1.什么是逆波兰表达式?如何转换成逆波兰表达式逆波兰表达式如何计算3.有效的括号总结栈的定义 栈作为一种数据结构&#xff0c;是一种只能在一端进行插入和删除操作的特殊线性表。它按…

华为MPLS跨域C2方案实验配置

MPLS隧道——跨域解决方案C1、C2讲解_静下心来敲木鱼的博客-CSDN博客_route-policy rr permit node 10 if-match mpls-labelhttps://blog.csdn.net/m0_49864110/article/details/127634890?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId…

深度学习——长短期记忆网络LSTM(笔记)

长短期记忆网络LSTM&#xff1a; ①隐变量模型存在长期信息保存和短期输入缺失问题&#xff0c;解决方法是LSTM ②发明于90年代 ③使用效果和GRU差别不大&#xff0c;但是实现起来复杂 1.长短期记忆网络 ①忘记门Ft&#xff1a;将值朝0减少 ②输入门It&#xff1a;是否忽…

最容易理解的并查集详解

并查集 并查集&#xff0c;在一些有N个元素的集合应用问题中&#xff0c;我们通常是在开始时让每个元素构成一个单元素的集合&#xff0c;然后按一定顺序将属于同一组的元素所在的集合合并&#xff0c;其间要查找一个元素在哪个集合中。 比如下面这幅图&#xff0c;总共有 10 …

MySQL之存储过程

MySQL存储过程1、基本介绍1.1、介绍存储过程&#xff1a;1.2、特点1.3、基本语法1.3.1、delimiter1.3.1、创建存储过程1.3.2、调用存储过程1.3.3、查看存储过程1.3.4、删除存储过程2、变量2.1、系统变量2.1.1、查询(会话、全局、模糊、精确)2.1.2、设置系统变量2.2、用户定义变…

IB学生必须具备的三大特质

以往的专栏亦提及过&#xff0c;修读IB课程要面对几大挑战。而要应对这些挑战&#xff0c;IB学生须具备以下三大条件&#xff1a; 时间管理能力 IBDP 首先&#xff0c;要对时间分配掌握得很好。两年的IB预科课程非常紧凑&#xff0c;不但每科都有其内部评核&#xff08;Interna…

VMware17虚拟机安装Ubuntu最新版本(Ubuntu22.04LTS)详细步骤

目录 一、概述 二、下载Ubuntu 22.04.1 LTS 三、在VMware虚拟机下安装Ubuntu22.04 四、配置网络 一、概述 Ubuntu是基于Linux内核开发的&#xff0c;免费下载&#xff0c;使用和分享的开源系统。如果需要在Linux下开发程序&#xff0c;这是一个很好的选择。本文介绍了Ubuntu最…

【问题解决】Tomcat启动服务时提示Filter初始化或销毁出现java.lang.AbstractMethodError错误

问题背景 最近在开发项目接口&#xff0c;基于SpringBoot 2.6.8&#xff0c;最终部署到外置Tomcat 8.5.85 下&#xff0c;开发过程中写了一个CookieFilter&#xff0c;实现javax.servlet.Filter接口&#xff0c;代码编译期正常。部署到外置Tomcat 8.5.85 下&#xff0c;在控制…