使用 vue.draggable 实现拖拽、克隆

article/2025/8/15 0:42:26

这是大佬的博客 https://blog.csdn.net/zjiang1994/article/details/79809687
里面对vue.draggable的一些方法和属性,进行了详解,非常的详细,比官网的还要详细哦!给大佬点赞!!!
这是vue.draggable的官网 https://www.itxst.com/vue-draggable/jirneq6b.html
虽然官网说的不是很详细,但是有一些例子还不错

在这里插入图片描述
如图,想要实现这样的效果,左侧列表有一堆框框,要把左侧的列表拖拽到右侧列表,然后就去了官网

在这里插入图片描述
官网列子 未拖拽之前是这样的
在这里插入图片描述

拖拽后是这样的
在这里插入图片描述
首先用的这个方法,多个列表之间进行拖拽,但是用了这个方法后,发现左侧的一些项到右侧去了,但是同时左侧的一些项也消失了,若是想在右侧列表存在两个单选框就无法实现,所以换了个方法,使用了 clone拷贝

未拖拽前是这样的
在这里插入图片描述
拖拽后是这样的(有个点需要注意下,从左侧向右侧进行拖拽时,记得从右侧的一列数据上面拖进去,不要从下面往上面拖,否则拖不进去,而且右侧列表需要保留一列数据,否则左侧数据也会拖不过来
在这里插入图片描述
可以发现 ,初步实现了效果
接下来就是一些比较细的注意事项了
在这里插入图片描述
可以发现,左侧可以向右侧拖拽,但是同时右侧也可以往左侧拖拽,这会导致左侧列表混乱起来,这和我的需求就不符了,我是想着左侧的列表项是固定的,这样就只是单纯的把左侧的一些项复制到右侧
然后就去看了大佬的博客
在这里插入图片描述
可以看到 pull:‘clone’时可以进行克隆,所以 pull:''时,就相当于禁止克隆了
以下是代码截图

在这里插入图片描述

但是又有一个问题 我只想 右侧列表实现内部拖拽,左侧列表禁止内部拖拽,现在是两边都可以进行拖拽 ,这无疑又导致了左侧列表发生了混乱
然后又去仔细看了下大佬的博客,有这么段话

在这里插入图片描述
发现了这个 sort 属性,sort:true时,可以进行内部拖拽,sort:false时,禁止拖拽

在这里插入图片描述
ok,这下舒服了

监测右侧列表内部拖拽后的下标
在这里插入图片描述
在这里插入图片描述
以下是目前的全部代码

<template><div><div class="body_top"><el-row :gutter="20"><el-col :span="24"><el-card shadow="always"><div style="background-color: #fff"><el-form :inline="true"><el-form-item label="模块标识:" prop="molds"><el-input  v-model="top_form.molds" controls-position="right"    placeholder="请输入模块标识" class="ele-fluid ele-text-left"/></el-form-item>                                                  <el-form-item label="模块名称:" prop="name"><el-input  v-model="top_form.name" controls-position="right"  placeholder="请输入模块名称" class="ele-fluid ele-text-left"/></el-form-item><el-form-item label="状态码:" prop="state"><el-input  v-model="top_form.state" controls-position="right"  placeholder="请输入状态码" class="ele-fluid ele-text-left"/></el-form-item><el-form-item><el-button @click="showEdit=false">取消</el-button><el-button type="primary" @click="formSave">保存</el-button></el-form-item></el-form></div></el-card></el-col></el-row></div><div class="ele-body"><el-row :gutter="20"><el-col :span="7"><el-card shadow="never"><div class="col"><el-row><div class="base_title">基础字段</div><el-divider></el-divider><draggable v-model="arr1" @end="end1" :options="{ group: { name: 'tt', pull: 'clone' },sort: false,}" animation="300" style="width: 100%; min-height: 330px"><!-- <transition-group> --><div v-for="item in arr1" :key="item.id"><div class="base_style"><span class="el-icon-circle-check icon"></span>{{ item.name }}</div></div><!-- </transition-group> --></draggable></el-row><el-row><div class="base_title remark_margin">特殊字段</div><el-divider></el-divider><draggable v-model="arr2" @end="end1" :options="{ group: { name: 'tt', pull: 'clone' }, sort: false,}" animation="300" style="width: 100%; min-height: 330px"><!-- <transition-group> --><div v-for="item in arr2" :key="item.id"><div class="base_style"><span class="el-icon-circle-check icon"></span>{{ item.name }}</div></div><!-- </transition-group> --></draggable></el-row></div></el-card></el-col><el-col :span="10"><el-card shadow="never"><div class="col"><draggable v-model="arr3" :options="{ group: { name: 'tt', pull: '' }, sort: true,}" animation="300" :move="onMove" style="width: 100%; min-height: 330px"><!-- <transition-group> --><div v-for="(item, index) in arr3" :key="index"><div v-if="item.type == 'text'" class="base_margin" @click="showMenu(item)"><div class="static_wrap">{{ item.name }} <div class="static_border"></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><div v-if="item.type == 'textarea'" class="base_margin" @click="showMenu(item)"><div class="static_wrap"> {{ item.name }}<div class="static_border static_textarea"><span class="static_bias">//</span></div></div><div> <el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><div v-if="item.type == 'select'" class="base_margin" @click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border static_textarea"><span class="el-icon-arrow-down static_select"></span></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'number'"class="base_margin"@click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border"></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'radio'"class="base_margin"@click="showMenu(item)"><div class="circle_wrap">{{ item.name }}<span class="static_circle"></span></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'checkbox'"class="base_margin"@click="showMenu(item)"><div class="circle_wrap">{{ item.name }}<span class="static_react"></span></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'datetime'"class="base_margin"@click="showMenu(item)"><div class="static_wrap"><span>{{ item.name }}</span><div class="static_border static_textarea"><span class="el-icon-time static_time"></span></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'daterange'"class="base_margin"@click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border static_textarea"><span class="el-icon-date static_time"></span></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'place'"class="base_margin"@click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border"></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'image'"class="base_margin"@click="showMenu(item)"><div class="image_wrap">{{ item.name }}<spanstyle="font-size: 40px; line-height: 60px"class="el-icon-picture"></span></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'file'"class="base_margin"@click="showMenu(item)"><div class="file_wrap">{{ item.name }}<div class="static_file">点击上传</div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'tel'"class="base_margin"@click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border"></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'button'"class="base_margin"@click="showMenu(item)"><div class="file_wrap">{{ item.name }}<div class="static_file"></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'signature'"class="base_margin"@click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border"></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'content'"class="base_margin"@click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border"></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><divv-if="item.type == 'city'"class="base_margin"@click="showMenu(item)"><div class="static_wrap">{{ item.name }}<div class="static_border static_textarea"><span class="el-icon-arrow-down static_select"></span></div></div><div><el-button type="text" @click="deleteDomain(index)"><i class="el-icon-delete"></i></el-button></div></div><div v-if="item.type == 'example'" class="base_margin" style="visibility:hidden;"><div class="static_wrap"><span style="color: red">{{ item.name }}</span><div class="static_border"></div></div><div></div></div></div><!-- </transition-group> --></draggable></div></el-card></el-col><el-col :span="7"><el-card shadow="never"><div class="col"><divstyle="text-align: center;margin-bottom: 10px;font-weight: bold;color: rgb(2, 167, 240);">字段属性</div><el-divider></el-divider><div v-if="isShow"><el-form:model="controlForm"ref="controlForm"label-width="100px;"><div class="remark_margin">控件说明</div><div class="remark_margin">此控件 {{ controlForm.remark }}</div><div class="remark_margin">大小:</div><divstyle="display: flex;justify-content: space-around;margin-bottom: 10px;"><div><el-inputclass="base_input"v-model="controlForm.height"></el-input></div><div><el-inputclass="base_input"v-model="controlForm.width"></el-input></div></div><el-form-item label="标题:"><el-inputv-model="controlForm.label"style="width: calc(100% - 20px)"></el-input></el-form-item><el-form-item><el-checkbox-group v-model="controlForm.checkList"><el-checkbox label="1">显示标题</el-checkbox><el-checkbox label="2">换行</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="提示文字:"><el-inputv-model="controlForm.placeholder"style="width: calc(100% - 20px)"></el-input></el-form-item><el-form-item label="默认值:"><el-select v-model="controlForm.default"><el-option label="自定义" :value="1" /><el-option label="关联系统表" :value="2" /> </el-select></el-form-item><el-form-item label="选格式:"><el-select v-model="controlForm.format"><el-option label="文本" :value="1" /><el-option label="手机号" :value="2" /><el-option label="邮箱" :value="3" /><el-option label="身份证号" :value="4" /><el-option label="邮政编码" :value="5" /> </el-select></el-form-item><div style="margin-bottom: 20px">校验:</div><el-form-item><el-checkbox-group v-model="controlForm.checked"><el-checkbox label="1">必填</el-checkbox><el-checkbox label="2">不允许重复</el-checkbox><el-checkbox label="3">脱敏</el-checkbox></el-checkbox-group></el-form-item><div style="margin-bottom: 20px">字段权限:</div><el-form-item><el-checkbox-group v-model="controlForm.force"><el-checkbox label="3">指定人员可见</el-checkbox><el-checkbox label="1">可见</el-checkbox><el-checkbox label="2">可编辑</el-checkbox><el-checkbox label="4">指定人员可编辑</el-checkbox><el-checkbox label="5">导入</el-checkbox><el-checkbox label="6">导出</el-checkbox></el-checkbox-group></el-form-item></el-form><divslot="footer"style="display: flex; justify-content: center"><el-button icon="el-icon-close">重置</el-button><el-button type="primary" @click="fieldSave">保存</el-button></div></div></div></el-card></el-col></el-row></div></div>
</template>
<script>
//导入draggable组件
import draggable from "vuedraggable";
export default {//注册draggable组件name:'oa_template_add',components: {draggable,},data() {return {//基本字段arr1: [{ id: 1, icon: "", name: "单行文本框", type: "text" },{ id: 2, icon: "", name: "多行文本框", type: "textarea" },{ id: 3, icon: "", name: "下拉列表框", type: "select" },{ id: 4, icon: "", name: "数字文本框", type: "number" },{ id: 5, icon: "", name: "单选按钮组", type: "radio" },{ id: 6, icon: "", name: "复选框组", type: "checkbox" },{ id: 7, icon: "", name: "日期时间框", type: "datetime" },{ id: 8, icon: "", name: "日期区间", type: "daterange" },],//特殊字段arr2: [{ id: 9, icon: "", name: "地址框", type: "place" },{ id: 10, icon: "", name: "图片", type: "image" },{ id: 12, icon: "", name: "附件", type: "file" },{ id: 13, icon: "", name: "手机号", type: "tel" },{ id: 14, icon: "", name: "按钮", type: "button" },{ id: 16, icon: "", name: "手写签名", type: "signature" },{ id: 15, icon: "", name: "内容联动", type: "content" },{ id: 17, icon: "", name: "城市级联", type: "city" },],// arr3: [{ id: 100, icon: "", name: "示例框", type: "example" }],arr3: [],controlForm: {width: "",height: "",label: "",checkList: [],checked: [],force: [],placeholder: "",default: "",format: "",type: "",remark: "",id: "",},//顶部表单top_form: {name: "",molds:"",state:"",field: [],},formArr: [],isShow: false, //字段属性是否显示};},methods: {//左侧拖动结束时的事件end1() {let arr5 = [];//对数组进行重新赋值,使其id等于下标this.arr3.forEach((d, index) => {arr5.push({id: index,name: d.name,type: d.type,});});this.arr3 = arr5;// console.log(this.arr3);},//内部拖拽时触发的方法onMove(e) {//e.draggedContext.index为拖拽前的下标,e.draggedContext.futureIndex为拖拽后的下标// console.log(e);// console.log(e.draggedContext.index, e.draggedContext.futureIndex);},//删除按钮deleteDomain(index) {this.arr3.splice(index, 1);},//字段表单的显示与隐藏showMenu(e) {this.isShow = true;// console.log(e);this.controlForm.remark = e.name;this.controlForm.id = e.id;this.controlForm.type = e.type;},//提交字段表单fieldSave() {this.formArr.push(this.controlForm)// console.log(this.controlForm);// let newArr = this.top_form.field;// newArr.push(this.controlForm);// if (newArr.length == 0) {//   newArr.push(this.controlForm);// } else {//   for (var i = 0; i < newArr.length; i++) {//     if (newArr[i].id == this.controlForm.id) {//       newArr[i] = this.controlForm;//       this.$message.warning("警告");//     } else {//       newArr.push(this.controlForm);//       this.$message.success("添加");//     }//   }// }// console.log(this.top_form);},//提交form表单formSave() {this.top_form.field=this.formArr;console.log(this.top_form);},},
};
</script>
<style scoped>
.col {background-color: #fff;height: 750px;overflow: scroll;
}
.base_title {font-size: 18px;width: 80px;height: 20px;line-height: 20px;text-align: center;color: #000;font-weight: bold;margin-bottom: 10px;
}
.base_style {width: 135px;height: 35px;border: 1px solid #999;line-height: 35px;text-align: center;float: left;margin-left: 10px;margin-top: 10px;margin-right: 10px;margin-bottom: 10px;box-sizing: border-box;border-radius: 5px;text-align: left;cursor: pointer;
}
.icon {color: rgb(86, 169, 251);margin-right: 5px;margin-left: 10px;
}
.base_input {width: 160px;
}
.base_margin {margin-top: 10px;margin-bottom: 10px;background-color: rgba(235, 248, 251, 1);height: 80px;line-height: 60px;border-radius: 10px;padding: 10px;box-sizing: border-box;display: flex;justify-content: space-between;cursor: pointer;
}
.remark_margin {margin-top: 10px;margin-bottom: 10px;
}
.body_top {padding: 15px 15px 0 15px;
}
/* 中间静态框css样式 */
.static_wrap {width: 300px;display: flex;justify-content: space-between;align-items: center;
}
.static_border {width: 200px;height: 36px;background-color: #fff;border-radius: 5px;border: 1px solid #c0c4cc;cursor: pointer;
}
.static_textarea {position: relative;
}
.static_bias {position: absolute;right: 2px;top: 0;font-size: 12px;
}
.static_select {position: absolute;right: 5px;top: 10px;
}
.circle_wrap {width: 110px;display: flex;justify-content: space-between;align-items: center;
}
.static_circle {width: 10px;height: 10px;border-radius: 50%;border: 1px solid #c0c4cc;cursor: pointer;
}
.static_react {width: 10px;height: 10px;border: 1px solid #c0c4cc;cursor: pointer;
}
.static_time {position: absolute;left: 10px;top: 10px;
}
.image_wrap {width: 135px;display: flex;justify-content: space-between;align-items: center;cursor: pointer;
}
.file_wrap {width: 180px;display: flex;justify-content: space-between;align-items: center;
}
.static_file {width: 80px;height: 40px;background-color: rgb(86, 169, 251);text-align: center;line-height: 40px;color: #fff;border-radius: 5px;font-size: 12px;
}
</style>

还有一点 拖拽 group 里的 name 记得改成 一致 的,否则拖拽不过去
在这里插入图片描述

<----------------------------------------->
2021.10.29更
之前提到过,右侧列表数据为空时,左侧的标签拖拽不到右侧列表,所以当时就想着给右侧列表加个默认的数据,并且给这个数据背景颜色设为空白,但是这会有很多问题,比如说必须从默认的数据上面拖,才能拖拽到右侧,而且原地会有个空白区,用户体验不好,今日碰巧看到了大佬的博客,解决了!!感谢感谢

这是之前的效果图,可以看到第一次拖拽的时候拖不过去,需要从右侧隐藏的那个示例框上面拖才行,而且拖过去了也会有空白,
在这里插入图片描述
这是现在的图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这是大佬的博客地址,说的很详细哦 vue.draggable多列表间拖拽列表数据为空时,拖拽失效bug解决


http://chatgpt.dhexx.cn/article/jZNLX3ja.shtml

相关文章

React Draggable 实现拖拽 - 最详细中文教程 - 卡拉云

本文首发&#xff1a;《React Draggable 实现拖拽 - 最详细中文教程 - 卡拉云》 React Draggable 是 react 生态中&#xff0c;最好用的拖拽实现库之一。如果你的应用中需要实现拖拽功能&#xff0c;可以尝试用 react-draggable&#xff0c;它可以满足多数情况下的拖拽需求&am…

draggable属性的应用

draggable属性用来定义元素是否可以拖动。 效果图&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>draggable属性的应用</title> </head> <body> <h3>元素拖…

draggable 和 sortable的JS原生实现

概要 本文主要利用html 5的draggable原生特性&#xff0c;实现一个可拖拽的效果。我们可以创建包含多个页面节点的容器&#xff0c;每个容器可以包含多个节点。通过拖拽&#xff0c;可以移动一个容器内的节点到其他容器&#xff0c;每个容器内的节点和以通过拖拽改变排列顺序。…

vue3使用拖拽组件draggable.next的使用教程【保姆级】

环境&#xff1a;vue3setup语法 首先放官方文档的链接&#xff1a; 中文版本&#xff1a; https://www.itxst.com/vue-draggable-next/tutorial.html &#xff08;民间翻译&#xff09; 英文版本&#xff1a;https://github.com/SortableJS/vue.draggable.next 因为自己写的过程…

vue的拖拽插件: vue.draggable

中文文档地址: vue.draggable中文文档 - itxst.comVue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动&#xff0c;可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作&#xff0c;总之是一款非常优秀的…

react-draggable实现拖拽详解

react-draggable 属性常用属性属性列表 事件列表举例首先安装 react-draggable实现移动 希望小编写的能够帮助到你&#x1f618; 属性 常用属性 属性默认值介绍axisxhandle拖动的方向&#xff0c;可选值 x ,y,bothhandle无指定拖动handle的classposition无handle的位置&#…

draggable拖拽组件使用

项目开发中需要用到拖拽组件&#xff0c;因为前端技术框架是vue&#xff0c;这里就使用了vue的一款拖拽插件vue.draggable&#xff0c;一般基本的需求都能满足&#xff0c;这里使用了多个draggable嵌套&#xff0c;达到两级之前相互拖拽的功能。 以下是类似teambition的效果图…

原生JS的拖拽属性draggable(详解)

摘要 作为h5新增的属性draggable&#xff0c;它能够给与一切的html元素拖动的效果。而在这个属性之下&#xff0c;也有着关于拖动效果的各个方法。 而这一篇文章&#xff0c;主要就是说一下关于draggable属性的使用以及工作场景。 1.了解draggable属性的使用 对我来讲&#…

EasyUI基础入门之Draggable(拖拽)

前面学习了easyui基础的解析器,加载器。对于他们入门阶段我们只需简单的了解下即可&#xff0c;毕竟先阶段并不会太过深入。接下来根据easyui官网文档的顺序安排学习下Draggable插件。 Draggable是什么 Draggable是easyui中用于实现拖拽功能的一个插件。利用它&#xff0c;我们…

jts-core 使用说明(二)

jts-core 使用说明 示例代码库 JTS源码底层使用说明&#xff0c;通过一下章节介绍说明 层次结构 org.locationtech.jts: algorithm - 算法包jts-io-common - I/O classes for open spatial formatsgeom - geom基础包geom.prep - 对适当准备的几何图形执行优化的几何操作类e…

java jts获取线上任意一点到起点的距离

java jts获取线上任意一点到起点的距离 近期项目要求计算某段公路上一辆车的运行轨迹&#xff0c;通过路上的设备实时获取车辆的经纬度信息并发送到后台接收。 抽象出来就是获取线上任意一点到起点的距离&#xff0c;按照一定每秒一次的频率去计算就获取该点的运动轨迹了。 主要…

JTS-Geometry 使用说明(五)

org.locationtech.jts.geom.Geometry 使用说明 示例代码库 Geometry 经纬度操作类 Geometry类继承关系 说明 平面、线性几何操作抽象类 提供的相关方法: 1.基础方法&#xff1a; 1.1 getLength:获取长度&#xff0c;线几何返回点与点之间的长度之和&#xff1b;闭合几何返回…

JAVA使用JTS 判断坐标点是否在坐标多边形内部

JAVA使用JTS 判断坐标点是否在坐标多边形内部 思路Geometry之间的关系API及参考博客代码依赖工具类测试类 思路 判断坐标点是否在坐标多边形内部&#xff0c;首先不能直接计算坐标点&#xff0c;是需要字符串坐标点转化为地理空间数据Geometry&#xff0c;然后使用JTS包中提供…

JTS学习笔记

JTS学习笔记 基础的类 Geometry geom对象Coordinate坐标类Point Point对象MultiPoint 基本对象MultiPoint等等GeometryFactory工厂对象PreparedGeometryFactoryPreparedGeometry 几何对象Geometry public abstract class Geometry implements Cloneable, Comparable, Seria…

JTS-Angle GIS几何角度计算使用说明(十八)

org.locationtech.jts.algorithm.Angle 角度计算使用说明 示例代码库 Angle 角度计算 1.Angle.angle(p0,p1) public static double angle(Coordinate p0, Coordinate p1) {double dx p1.x - p0.x;double dy p1.y - p0.y;return Math.atan2(dy, dx); }返回与x轴正方向的夹…

java jts_Java Topology Suite (JTS)与空间数据模型

JTS是Java的处理地理数据的API&#xff0c;它提供以下功能&#xff1a; 实现了OGC关于简单要素SQL查询规范定义的空间数据模型 一个完整的、一致的、基本的二维空间算法的实现&#xff0c;包括二元运算(例如touch和overlap)和空间分析方法(例如intersection和buffer) 一个显示的…

java jts点到面的距离_jts-空间索引

前言&#xff1a; 如果您对JTS这三个词还是没有一个概念&#xff0c;那么推荐您关注一下sinoly的博客。这个我能够找到为数不多的关于jts的中文资料。 http://www.blogjava.net/sinoly/archive/2007/02/09/99042.html 下面这段话就是摘抄自sinoly老兄的博客&#xff1a; ......…

JTS Geometry关系判断和分析

关系判断 Geometry之间的关系有如下几种&#xff1a; 相等(Equals)&#xff1a; 几何形状拓扑上相等。 脱节(Disjoint)&#xff1a; 几何形状没有共有的点。 相交(Intersects)&#xff1a; 几何形状至少有一个共有点&#xff08;区别于脱节&#xff09; 接触(Touches)&a…

JTS Geometry用例分析

微信搜索&#xff1a;“二十同学” 公众号&#xff0c;欢迎关注一条不一样的成长之路 拓扑关系 GeometryTest import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import…

JTS 笔记

简介 JTS由加拿大的VividSolutions公司开发&#xff0c;是一个用Java语言描述的几何拓扑套件&#xff0c;遵循OpenGIS的Simple Feature Specification&#xff0c;封装了2D几何类型和非常多的空间分析操作&#xff0c;而且包含了不少常见的计算几何算法实现。     JTS被广泛…