当前位置: 首页 > news >正文

【QGIS二次开发】地图编辑-04

系列目录:

【QGIS二次开发】地图显示与交互-01_qgis二次开发加载地图案例-CSDN博客

【QGIS二次开发】地图显示与交互-02_setlayerlabeling-CSDN博客

【QGIS二次开发】地图符号与色表-03-CSDN博客


4  地图编辑

4.1 添加点要素

功能演示

运行程序后,点击菜单栏中的“数据->添加矢量数据”以导入测试所需的点要素矢量图层。

图 30 导入数据示意图

在图层列表中选中相应的图层,然后单击右侧边栏中的“启动/关闭几何编辑”按钮,以启动编辑模式。接着,点击“添加点”按钮,进入点添加模式。此时,利用鼠标左键在图框内的任意位置进行点击,将弹出一个窗口,用于设置新增点要素的属性值。

图 31 为新要素添加属性示意图

在属性值编辑窗口中,可以根据需要填写新增点要素的属性信息。这些属性值默认为Null,但可以选择全部填入或者部分填入,根据实际情况进行设置,也可以通过点击“Cancel”按钮取消添加。

添加完成后,新的点要素将在图层和属性表中显示出来。

图 32 添加完成后的新要素及其属性展示

从上图可以看到,添加的点要素成功录入并显示在图层和属性表中。

代码展示

定义了一个名为QgsMapToolEditPoint的类,继承自QgsMapTool用来处理地图编辑操作。构造函数接受一个QgsMapCanvas和QgsVectorLayer,分别表示地图画布和当前图层。

在重载的鼠标按下事件函数canvasPressEvent中,首先检查当前图层是否有效,然后获取鼠标点击位置的坐标。然后启动图层编辑模式,通过addFeature方法创建新的点要素,并通过用户界面弹出窗口(QDialog)收集用户输入的属性值。用户可以为每个属性输入相应的数值或文本,并通过OK按钮确认。

用户在点击OK按钮后,程序会将用户输入的属性值与字段进行匹配,并添加新的要素至图层。如果用户点击Cancel按钮,则取消编辑操作,删除刚刚添加的要素。整个过程通过连接信号槽机制实现,其中包括了用户输入校验、属性值转换以及图层刷新等步骤。核心代码如下:

QgsMapToolEditPoint::QgsMapToolEditPoint(QgsMapCanvas* mapcanvas, QgsVectorLayer* currentlayer) : QgsMapTool(mapcanvas), m_mapCanvas(mapcanvas), m_currentLayer(currentlayer)  
{  m_mapCanvas = mapcanvas;  m_currentLayer = currentlayer;  
}  QgsMapToolEditPoint::~QgsMapToolEditPoint() {};  void  QgsMapToolEditPoint::canvasPressEvent(QgsMapMouseEvent* e) {  if (!m_currentLayer)  {  // 处理图层无效的情况  return;  }  // 从函数体内获取点击的点坐标  QgsMapCanvas* canvas = this->canvas();  if (!canvas)  {  // 处理无效的画布  return;  }  QgsPointXY point = canvas->getCoordinateTransform()->toMapCoordinates(canvas->mouseLastXY());  m_currentLayer->startEditing();  QgsFeature feature;  // 创建新要素,传递用户点击的点坐标  feature.setGeometry(QgsGeometry::fromPointXY(point));  QgsFields fields = m_currentLayer->fields();  feature.setFields(fields);  QDialog inputDialog;  QFormLayout formLayout(&inputDialog);  QList<QString> attributeNames;  QList<QVariant> attributeValues;  for (const QgsField& field : fields)  {  QString attributeName = field.name();  QVariant::Type attributeType = field.type();  QString labelText = "输入属性 " + attributeName + " 的属性值:";  QString defaultValue = "";  // Set default value if needed  QLineEdit* inputLineEdit = new QLineEdit(&inputDialog);  inputLineEdit->setText(defaultValue);  formLayout.addRow(labelText, inputLineEdit);  attributeNames.append(attributeName);  }  QPushButton* okButton = new QPushButton("OK", &inputDialog);  QPushButton* cancelButton = new QPushButton("CANCEL", &inputDialog);  formLayout.addRow(okButton);  formLayout.addRow(cancelButton);  QObject::connect(okButton, &QPushButton::clicked, [&]() {  QMap<QString, QVariant> attributeMap;  for (int i = 0; i < attributeNames.size(); ++i)  {  QLineEdit* inputLineEdit = qobject_cast<QLineEdit*>(formLayout.itemAt(i, QFormLayout::FieldRole)->widget());  if (inputLineEdit)  {  QString inputValue = inputLineEdit->text().trimmed();  // Trim leading and trailing whitespaces  if (inputValue == "") continue;  QVariant::Type attributeType = fields[i].type();  QVariant convertedValue;  bool conversionOk;  switch (attributeType)  {  case QVariant::Int:  convertedValue = inputValue.toInt(&conversionOk);  break;  case QVariant::Double:  convertedValue = inputValue.toDouble(&conversionOk);  break;  // 其他类型的转换可以根据需要继续添加  default:  convertedValue = inputValue;  conversionOk = true;  }  if (!conversionOk)  {  // 用户取消输入,中断操作  return;  }  attributeMap[attributeNames[i]] = convertedValue;  }  }  QgsAttributes attributes;  for (const QString& attributeName : attributeNames)  {  QVariant value = attributeMap.value(attributeName, QVariant());  // Get value from map, default to QVariant()  attributes << value;  }  feature.setAttributes(attributes);  m_currentLayer->dataProvider()->addFeature(feature);  m_currentLayer->commitChanges();  m_mapCanvas->refresh();  inputDialog.accept();  // Close the dialog after processing  });  QObject::connect(cancelButton, &QPushButton::clicked, [&]() {  m_currentLayer->removeSelection();  m_currentLayer->dataProvider()->deleteFeatures({ feature.id() });  inputDialog.reject();  // Close the dialog without processing  return;  });  inputDialog.setWindowTitle("输入属性值");  inputDialog.exec();  }  

4.2 添加线要素

运行程序后,点击菜单栏中的“数据->添加矢量数据”以导入测试所需的线要素矢量图层。

图 33 导入数据示意图

在图层列表中选中所需的图层,点击右侧边栏中的“启动/关闭几何编辑”按钮,启用编辑模式。接下来,点击“添加线”按钮,进入线添加模式。在这个模式下,使用鼠标左键在图框内的各个位置点击,以添加线的顶点。当线的形状满足需求后,通过右键停止添加顶点,并弹出窗口,用于设置新增线要素的属性值。

图 34 鼠标左键绘制新要素示意图

图 35 为新要素添加属性示意图

在属性值编辑窗口中,可以根据具体需求填写新增线要素的属性信息。这些属性值默认为Null,可以选择全部填入或者部分填入,具体取决于实际情况。如果想要取消添加,点击“Cancel”按钮即可。

添加操作完成后,新的线要素将在图层和属性表中显示。

图 36 添加完成后的新要素及其属性展示

代码展示

定义了一个名为QgsMapToolAddLine的类,继承自QgsMapTool,用于处理地图编辑操作。构造函数接受一个QgsMapCanvas和QgsVectorLayer,表示地图画布和当前图层。在canvasMoveEvent函数中,实时响应鼠标移动事件,根据用户的交互动作动态绘制线的顶点,对于左键点击,记录线的顶点坐标,并在右键点击时停止绘制,弹出窗口用于设置新增线要素的属性值。用户可以在弹出的属性值编辑窗口中填写相应的属性信息,完成后将新的线要素添加至图层。

整个过程通过QgsRubberBand类实现线的实时绘制,同时通过信号槽机制连接属性值编辑窗口的确认和取消按钮。在完成线要素的添加后刷新地图画布以更新显示。

QgsMapToolAddLine::QgsMapToolAddLine(QgsMapCanvas* canvas, QgsVectorLayer* currentlayer) :QgsMapTool(canvas), pMapCanvas(canvas), m_currentLayer(currentlayer)  
{  pMapCanvas = canvas;  m_currentLayer = currentlayer;  //设置QgsRubberBand对象,绘制折线  pRubBand = new QgsRubberBand(pMapCanvas);  mColor = QColor(255, 0, 0);  LineWidth = 2;  ButtonClickFlag = false;  
}  QgsMapToolAddLine::~QgsMapToolAddLine(void)  
{  /*if(pRubBand){ delete pRubBand ; }*/  
}  
//重载鼠标移动事件  
void QgsMapToolAddLine::canvasMoveEvent(QgsMapMouseEvent* e)  
{  m_currentLayer->startEditing();  int xc, yc;  //如果鼠标左键没有双击  if (!ButtonClickFlag) {  return;  }  pRubBand->setColor(mColor);  pRubBand->setWidth(LineWidth);  xc = e->x();  yc = e->y();  //得到当前坐标变换对象  const QgsMapToPixel* pTransform = pMapCanvas->getCoordinateTransform();  //转换成地图坐标  QgsPoint mPoint(pTransform->toMapCoordinates(xc, yc));  if (pRubBand->numberOfVertices() > 1) {  pRubBand->removeLastPoint();  }  //把当前点添加到QgsRubberBand对象中用于绘制  pRubBand->addPoint(mPoint);  
}  
//重载鼠标单击事件  
void  QgsMapToolAddLine::canvasPressEvent(QgsMapMouseEvent* e)  
{  // 创建要素  QgsFeature feature;  int xc, yc;  pRubBand->setColor(mColor);  pRubBand->setWidth(LineWidth);  //得到当前坐标变换对象  const QgsMapToPixel* pTransform = pMapCanvas->getCoordinateTransform();  //得到产生事件的按钮信息  Qt::MouseButton mButton = e->button();  xc = e->x();  yc = e->y();  QgsPoint  mPoint(pTransform->toMapCoordinates(xc, yc));  //如果是左按钮  if (mButton == Qt::MouseButton::LeftButton) {  ButtonClickFlag = true;  //把当前点添加到QgsRubberBand对象中用于绘制  pRubBand->addPoint(mPoint);  mPointSet.append(mPoint);  }  else if (mButton == Qt::MouseButton::RightButton) {  pRubBand->addPoint(mPoint);  mPointSet.append(mPoint);  ButtonClickFlag = false;  //转化为几何体  QgsGeometry geometry = pRubBand->asGeometry();  feature.setGeometry(geometry);  if (feature.hasGeometry())  {  QgsFields fields = m_currentLayer->fields();  feature.setFields(fields);  QDialog inputDialog;  QFormLayout formLayout(&inputDialog);  QList<QString> attributeNames;  QList<QVariant> attributeValues;  for (const QgsField& field : fields)  {  QString attributeName = field.name();  QVariant::Type attributeType = field.type();  QString labelText = "输入属性 " + attributeName + " 的属性值:";  QString defaultValue = "";  // Set default value if needed  QLineEdit* inputLineEdit = new QLineEdit(&inputDialog);  inputLineEdit->setText(defaultValue);  formLayout.addRow(labelText, inputLineEdit);  attributeNames.append(attributeName);  }  QPushButton* okButton = new QPushButton("OK", &inputDialog);  QPushButton* cancelButton = new QPushButton("CANCEL", &inputDialog);  formLayout.addRow(okButton);  formLayout.addRow(cancelButton);  QObject::connect(okButton, &QPushButton::clicked, [&]() {  QMap<QString, QVariant> attributeMap;  for (int i = 0; i < attributeNames.size(); ++i)  {  QLineEdit* inputLineEdit = qobject_cast<QLineEdit*>(formLayout.itemAt(i, QFormLayout::FieldRole)->widget());  if (inputLineEdit)  {  QString inputValue = inputLineEdit->text().trimmed();  // Trim leading and trailing whitespaces  if (inputValue == "") continue;  QVariant::Type attributeType = fields[i].type();  QVariant convertedValue;  bool conversionOk;  switch (attributeType)  {  case QVariant::Int:  convertedValue = inputValue.toInt(&conversionOk);  break;  case QVariant::Double:  convertedValue = inputValue.toDouble(&conversionOk);  break;  // 其他类型的转换可以根据需要继续添加  default:  convertedValue = inputValue;  conversionOk = true;  }  if (!conversionOk)  {  // 用户取消输入,中断操作  return;  }  attributeMap[attributeNames[i]] = convertedValue;  }  }  QgsAttributes attributes;  for (const QString& attributeName : attributeNames)  {  QVariant value = attributeMap.value(attributeName, QVariant());  // Get value from map, default to QVariant()  attributes << value;  }  feature.setAttributes(attributes);  m_currentLayer->dataProvider()->addFeature(feature);  m_currentLayer->commitChanges();  pMapCanvas->refresh();  inputDialog.accept();  // Close the dialog after processing  });  QObject::connect(cancelButton, &QPushButton::clicked, [&]() {  pRubBand->reset();  mPointSet.clear();  inputDialog.reject();  // Close the dialog without processing  });  inputDialog.setWindowTitle("输入属性值");  inputDialog.exec();  pMapCanvas->refresh();  pRubBand->reset();  mPointSet.clear();  }  }  }  
//设置绘制颜色和线宽  
void QgsMapToolAddLine::SetColorAndWidth(QColor color, int nWidth)  
{  mColor = color;  LineWidth = nWidth;  
}  //返回构成线段的数据点数  
int QgsMapToolAddLine::GetVertexCount()  
{  return mPointSet.size();  
}  
//得到点的坐标  
bool QgsMapToolAddLine::GetCoord(int index, double& x, double& y)  
{  QgsPoint mPoint;  if (index >= mPointSet.size()) {  return true;  }  mPoint = mPointSet.at(index);  x = mPoint.x();  y = mPoint.y();  
}  

4.3 添加面要素

首先添加一个面数据之后,再点击按钮“添加面”

图 37 添加面按键

鼠标左键点击来绘制要素;

图 38 添加面操作

右键之后完成绘制,跳出相关属性的填写框;

图 39 输入属性

填写完之后,点击OK;完成绘制

图 40 添加面成功

相关代码思路分析

首先,它获取当前在图层树视图中选中的图层,并把它转换为一个矢量图层(假设当前层是矢量层)。然后,该代码使该矢量图层进入编辑模式。接着,在地图画布中设置这个矢量图层为当前图层,并创建一个用于添加多边形要素的地图工具QgsMapToolAddFeature,最后将此工具设置为当前地图画布的工具,同时将捕获模式为多边形绘制。

代码部分如下

void DataViewer::on_actionAddPolygons_triggered()    
{    currentLayer = m_layerTreeView->currentLayer();    QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>(currentLayer);    //面编辑——添加要素    layer->startEditing();    m_mapCanvas->setLayers(QList<QgsMapLayer*>() << layer);    m_mapCanvas->setCurrentLayer(layer);    QgsMapToolAddFeature* addFeaturepolygonTool = new QgsMapToolAddFeature(m_mapCanvas, QgsMapToolCapture::CapturePolygon);    m_mapCanvas->setMapTool(addFeaturepolygonTool);    }   

相关文章:

【QGIS二次开发】地图编辑-04

系列目录&#xff1a; 【QGIS二次开发】地图显示与交互-01_qgis二次开发加载地图案例-CSDN博客 【QGIS二次开发】地图显示与交互-02_setlayerlabeling-CSDN博客 【QGIS二次开发】地图符号与色表-03-CSDN博客 4 地图编辑 4.1 添加点要素 功能演示&#xff1a; 运行程序后…...

Qt 信号和槽-核心知识点小结(11)

目录 小结表格索引 disconnect函数 lambda表达式 啥是耦合&#xff0c;啥是内聚 简介&#xff1a;这是Qt信号和槽的最后一篇文章&#xff0c;最主要的是总结该信号和槽的核心知识点。以及该核心知识点的文章索引&#xff08;表格太长了&#xff0c;手机可能看不完整&#…...

React响应事件中onClick={handleClick} 的结尾有没有小括号的区别

你可以通过在组件中声明 事件处理 函数来响应事件&#xff1a; function MyButton() {function handleClick() {alert(You clicked me!);}return (<button onClick{handleClick}>点我</button>);} 注意&#xff0c;onClick{handleClick} 的结尾没有小括号&#x…...

React-Query使用react-testing-library进行测试

1.测试react-query首先我们必须得拥有queryClient&#xff0c;所以我们初始化queryClient&#xff0c;因为默认是重试三次&#xff0c;这意味着如果想测试错误的查询&#xff0c;测试可能会超时。所以可以在初始化时关闭 const createWrapper () > {const queryClient new…...

软件设计师CISC与RISC考点分析——求三连

一、考点分值占比与趋势分析&#xff08;CISC与RISC&#xff09; 综合知识分值统计表 年份考题数量分值分值占比考察重点2018111.33%指令特征对比2019111.33%控制器实现方式2020222.67%寄存器数量/流水线技术2021111.33%寻址方式对比2022222.67%指令复杂度/译码方式2023111.3…...

GO语言(一期)常用关键字总结

GO语言&#xff08;主题一&#xff09;常用关键字总结 我们这里列出一些go语言关键字&#xff0c;方便各位友友们检查一下自己的学习效果&#xff0c;也方便友友们学习查询。 break default func interface select case defer go map …...

Ubuntu搭建NFS服务器的方法

0 工具 Ubuntu 18.041 Ubuntu搭建NFS服务器的方法 在Ubuntu下搭建NFS&#xff08;网络文件系统&#xff09;服务器可以让我们像访问本地文件一样访问Ubuntu上的文件&#xff0c;例如可以把开发板的根文件系统放到NFS服务器目录下方便调试。 1.1 安装nfs-kernel-server&#…...

京东商品详情API接口开发指南(含Java/Python实现)

接口概述 京东开放平台提供了商品详情查询接口&#xff0c;开发者可以通过SKUID获取商品的详细信息&#xff0c;包括标题、价格、图片、促销信息等。该接口需要申请API权限和认证密钥。 点击获取key和secret 接口特点 支持批量查询&#xff08;最多20个SKU&#xff09;返回J…...

二叉树构造:从前序、中序与后序遍历序列入手

目录 引言 从前序与中序遍历序列构造二叉树&#xff08;题目 105&#xff09; 解题思路 举例说明 从中序与后序遍历序列构造二叉树&#xff08;题目 106&#xff09; 解题思路 举例说明 总结 引言 二叉树的遍历与构造是算法领域中的经典问题。LeetCode 上的“从前序与中…...

GEE谷歌地球引擎批量下载逐日ERA5气象数据的方法

本文介绍在谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#xff09;中&#xff0c;批量下载逐日的ERA5土壤湿度数据&#xff08;或者是其他气象数据、遥感影像数据等&#xff09;的方法。 首先&#xff0c;明确一下本文的需求。我们希望在GEE中&#xff0c;下…...

C#接口(Interface)全方位讲解:定义、特性、应用与实践

引言 在面向对象编程&#xff08;OOP&#xff09;中&#xff0c;接口&#xff08;Interface&#xff09;是一种重要的结构&#xff0c;它定义了某一类对象或类应遵循的行为规范。接口强调“做什么&#xff08;What&#xff09;”&#xff0c;而非“怎么做&#xff08;How&…...

索引与数据结构、并行算法

3. 索引与数据结构 索引类比目录&#xff1a;类似于书籍目录&#xff0c;帮助我们快速定位信息。索引的核心目的&#xff1a;提升数据查找效率&#xff0c;优化增删改查性能。实际应用广泛&#xff1a;MySQL、Redis、搜索引擎、分布式系统、中间件等。 3.1. 索引设计中的需求…...

GC全场景分析

GC全场景分析 文章目录 GC全场景分析标记-清除法**标记 - 清除法核心流程与 STW 机制****标记 - 清除法四步流程****1. STW 启动&#xff08;暂停用户线程&#xff09;****2. 标记可达对象&#xff08;从根集合出发&#xff09;****3. 清除未标记对象&#xff08;回收堆内存&am…...

OSI七层模型和TCP/IP的五层(四层模型)

分层 1.什么是分层 我理解是对同一相同或者相似的事务或者操作功能进行分类&#xff0c;比如我们去餐厅吃饭&#xff0c;就可以分为好多层&#xff0c;客户层&#xff0c;服务员层&#xff0c;前台层&#xff0c;后厨层&#xff0c;每一层都专注自己的事情&#xff0c;客户层…...

MouseDown,MouseUp,LostMouseCapture的先后顺序

本文目标是实现如下功能: 按下一个按钮后置位某变量;鼠标松开后复位某个变量? 看似简单,但是一般来说会存在如下两种现象: 鼠标移出按钮:默认会丢失鼠标事件跟踪,即MouseLeftButtonUp事件并不会被触发。 焦点切换:Tab 键切换焦点会干扰按钮的事件捕获 本文通过几个…...

第8章 常用实用类

8.1 String类 在java.lang包&#xff08;默认引入&#xff09;中&#xff0c;可直接使用。 定义为final类&#xff0c;不能扩展String类&#xff0c;不可以继承&#xff0c;不可以有子类。 8.1.1 构造String对象 常量对象&#xff1a; 英文双引号括起来 String常量放入常…...

视差场(disparity field)

视差场&#xff08;disparity field&#xff09;是立体视觉中的一个重要概念&#xff0c;用于描述两幅立体图像之间像素的对应关系。以下是对视差场的详细解释&#xff1a; 1. 视差&#xff08;Disparity&#xff09;的定义 视差是指同一场景点在两幅立体图像中的像素位置差异…...

AI:OpenAI论坛分享—《AI重塑未来:技术、经济与战略》

AI&#xff1a;OpenAI论坛分享—《AI重塑未来&#xff1a;技术、经济与战略》 导读&#xff1a;2025年4月24日&#xff0c;OpenAI论坛全面探讨了 AI 的发展趋势、技术范式、地缘政治影响以及对经济和社会的广泛影响。强调了 AI 的通用性、可扩展性和高级推理能力&#xff0c;以…...

【已经解决诸多问题】Mamba安装

mamba被称为新一代的计算架构&#xff0c;因此在CV和时序领域存在诸多的方案开始采用这一新架构&#xff0c;但是这个架构的安装过程中存在诸多问题&#xff01;&#xff01;&#xff01;&#xff01;为了更好帮助大家理解我们给出一个统一的安装流程&#xff01;&#xff01;&…...

计算机的基本组成与性能

1. 冯诺依曼体系结构&#xff1a;计算机组成的金字塔 1.1. 计算机的基本硬件组成 1.CPU - 中央处理器&#xff08;Central Processing Unit&#xff09;。 2.内存&#xff08;Memory&#xff09;。 3.主板&#xff08;Motherboard&#xff09;。主板的芯片组&#xff08;Ch…...

“绿色邮政,智能九识”——呼和浩特邮政无人快递车发车,驶向智慧物流新时代!

5月12日&#xff0c;“绿色邮政&#xff0c;智能九识”呼和浩特邮政无人驾驶快递车发车。 此次投运的邮政无人驾驶快递车实力惊人&#xff1a;单车运量超1000件&#xff0c;时速达40公里&#xff0c;通过智能路径规划实现24小时作业&#xff0c;与传统运输相比&#xff0c;运转…...

AGI大模型(24):通过LangChain的接口来调用OpenAI对话

1 创建对话 使用langchain库中的ChatOpenAI类来创建一个对话模型。 from dotenv import load_dotenvload_dotenv()import os from langchain_openai import ChatOpenAIllm = ChatOpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"),base_url="https://api.deepsee…...

大模型中的Token机制深度解析

目录 大模型中的Token机制深度解析 一、Token的本质与核心作用 二、主流分词算法对比 三、GPT-3分词机制详解 四、分词策略对模型性能的影响 五、工程实践建议 六、未来演进方向 一、Token的本质与核心作用 Token是大模型处理文本的​​最小语义单元​​,类似于人类语…...

【MySQL】库与表的操作

一、库的操作 1. 查看数据库 语法&#xff1a;show databases;这里的database是要加s的 查看当前自己所处的数据库&#xff1a;select database(); 例如下图&#xff0c;我当前所处的数据库就是在class1数据库 2. 创建数据库 语法&#xff1a;create database [if not e…...

创建指定版本的vite项目

1、获取vite的版本号 npm view create-vite versions 注:4.4.1版本即对应着node16版本的项目 2、创建制定版本的vite项目 npm init vite<version>...

java中的Servlet3.x详解

Servlet 3.x 是 Java Web 开发的重要里程碑&#xff0c;包含 Servlet 3.0&#xff08;2009年发布&#xff09;和 Servlet 3.1&#xff08;2013年发布&#xff09;两个主要版本。它通过多项革新优化了开发效率、性能及扩展性&#xff0c;成为现代 Java Web 应用的核心技术基础。…...

单目测距和双目测距 bev 3D车道线

单目视觉测距原理 单目视觉测距有两种方式。 第一种&#xff0c;是通过深度神经网络来预测深度&#xff0c;这需要大量的训练数据。训练后的单目视觉摄像头可以认识道路上最典型的参与者——人、汽车、卡车、摩托车&#xff0c;或是其他障碍物&#xff08;雪糕桶之类&#xf…...

weibo_comment_pc_tool | 我于2025.5月用python开发的评论采集软件,根据帖子链接爬取评论的界面工具

本工具仅限学术交流使用&#xff0c;严格遵循相关法律法规&#xff0c;符合平台内容的合法及合规性&#xff0c;禁止用于任何商业用途&#xff01; 一、背景分析 1.1 开发背景 微博&#xff08;以下简称wb&#xff09;是国内极具影响力的社交媒体平台&#xff0c;具有内容形式…...

ubuntu防火墙命令和放行ssh端口

一、关闭UFW防火墙&#xff08;Ubuntu默认工具&#xff09; 1. 临时关闭防火墙 sudo ufw disable sudo ufw status # 显示 Status: inactive 表示已关闭 2. 永久禁用防火墙&#xff08;禁用系统服务&#xff09; sudo systemctl stop ufw # 立即停止服务 sudo sy…...

PWM讲解+STM32任意频率、占空比、脉宽生成函数介绍

1.PWM讲解 脉冲宽度调制(PWM)&#xff0c;是英文“Pulse Width Modulation”的缩写&#xff0c;简称脉宽调制。 脉宽调制 最开始使用PWM时&#xff0c;是做智能车时使用的舵机打角&#xff0c;电机驱动。这都属于比较浅显&#xff0c;普通的应用。下面和大家简单分享一下PWM的…...

C++23 范围迭代器作为非范围算法的输入 (P2408R5)

文章目录 一、引言二、C23及范围迭代器的背景知识2.1 C23概述2.2 范围迭代器的概念 三、P2408R5提案的内容3.1 提案背景3.2 提案内容 四、范围迭代器作为非范围算法输入的优势4.1 代码简洁性4.2 提高开发效率4.3 更好的兼容性 五、具体的代码示例5.1 使用范围迭代器进行并行计算…...

CVE-2018-1273 漏洞深度分析

漏洞概述 CVE-2018-1273 是 Spring Data Commons 中的一个高危远程代码执行&#xff08;RCE&#xff09;漏洞&#xff0c;影响版本为 Spring Data Commons 1.13–1.13.10 和 2.0–2.0.5。攻击者通过构造包含恶意 SpEL表达式的 HTTP 请求参数&#xff0c;触发表达式注入&#x…...

C++23:修正常量迭代器、哨兵和范围

文章目录 引言C20范围库回顾C23之前常量迭代器的问题视图可能不传播const代理对象的复杂性泛型代码中的一致性 P2278R4提案及C23的改进std::views::as_const的工作原理代码示例 浅const视图&#xff08;如std::span&#xff09;的改进总结 引言 在C的发展历程中&#xff0c;每…...

【漫话机器学习系列】266.雅可比矩阵(Jacobian Matrix)

雅可比矩阵&#xff08;Jacobian Matrix&#xff09;详解 | 多变量函数微积分的基石 在深度学习、计算图、优化算法、机器人控制、流形学习等众多领域中&#xff0c;“雅可比矩阵&#xff08;Jacobian Matrix&#xff09;”是一个非常核心的数学工具。 这篇文章将结合一张视觉…...

Leetcode 3551. Minimum Swaps to Sort by Digit Sum

Leetcode 3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路2. 代码实现 题目链接&#xff1a;3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路 这一题思路上我实现的非常暴力&#xff0c;就是先求出正确的排列&#xff0c;然后从头考察每一个元素是否处在其目标…...

西门子1200/1500博图(TIA Portal)寻址方式详解

西门子博图&#xff08;TIA Portal&#xff09;是西门子公司推出的自动化工程软件平台&#xff0c;广泛应用于工业自动化领域。在编写PLC程序时&#xff0c;寻址方式是一个非常重要的概念&#xff0c;它决定了如何访问和操作PLC中的数据和资源。本文将详细介绍西门子博图中的寻…...

STK手动建链+matlab联调

在右边场景区选择你要建链的卫星&#xff0c;右键在弹出的选项中选择Access 选择你要建链的卫星&#xff0c;这里我选择3轨10星与4轨8星建链&#xff0c;点击compute后再close就行了 建链完成&#xff0c;这里链路的颜色跟起始卫星的颜色一致&#xff0c;要想改变颜色只需改变卫…...

MATLAB中的Switch语句讲解

MATLAB中的Switch语句&#xff1a;一个简单的控制流工具 在MATLAB中&#xff0c;switch语句是一种多分支控制结构&#xff0c;通常用于根据某个表达式的值选择不同的代码块进行执行。它的作用类似于一系列的if-elseif-else语句&#xff0c;但在处理多个条件时&#xff0c;swit…...

【SpringBoot】✈️整合飞书群机器人发送消息

&#x1f4a5;&#x1f4a5;✈️✈️欢迎阅读本文章❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;本篇文章阅读大约耗时3分钟。 ⛳️motto&#xff1a;不积跬步、无以千里 &#x1f4cb;&#x1f4cb;&#x1f4cb;本文目录如下&#xff1a;&#x1f381;&#x1f381;&am…...

上位机知识篇---流式Web服务器模式的实现

文章目录 前言 前言 本文简单介绍了流式Web服务器模式的实现。...

Go 语言中的一等公民(First-Class Citizens)

在 Go 语言中&#xff0c;一等公民&#xff08;First-Class Citizens&#xff09; 是指语言中可以像普通值一样被自由操作的元素&#xff0c;包括赋值、传递、返回等。Go 虽然不是纯粹的函数式语言&#xff0c;但支持多种一等公民&#xff0c;以下是 Go 中常见的 一等公民及其特…...

python3.13版本降为3.12

目录 一、下载Python 二、安装PyCharm 三、 彩蛋 粗糙理解&#xff1a; PyThon是编译器&#xff08;也可以在命令行编辑&#xff0c;但是麻烦&#xff09; PyCharm是编辑器 一、下载Python https://repo.huaweicloud.com/python/3.12.9/python-3.12.9-amd64.exe 点击Insta…...

Ubuntu搭建TFTP服务器的方法

0 工具 Ubuntu 18.041 Ubuntu搭建TFTP服务器的方法 在Ubuntu下搭建TFTP服务器可以让我们下载文件到开发板更加方便&#xff0c;同时也可以实现TFTP加载Linux镜像&#xff0c;方便调试。 1.1 安装tftp-hpa&#xff08;TFTP客户端&#xff09;、tftpd-hpa&#xff08;TFTP服务…...

【AI】Ubuntu 22.04 4060Ti16G 基于SWIFT框架的LoRA微调 模型Qwen3-1.8B 数据集弱智吧 微调笔记

下载Qwen3-1.8B 先更新安装modescope&#xff0c;然后下载模型 pip install -U modelscope modelscope download --model Qwen/Qwen3-1.7B 下载日志 部署模型 参考&#xff1a;【AI】Ubuntu 22.04 4060Ti 16G vllm-api部署Qwen3-8B-FP8_wsl ubantu rtx4060 vllm镜像-CSDN博…...

系分论文《论信息系统缓存的分析和应用》

【摘要】 2023年3月,我作为系统分析师参与了某大型电商平台"云端购物中心"的性能优化项目。该项目日均订单量突破200万,但在促销高峰期频繁出现系统响应迟缓、数据库过载等问题。本项目以构建多级缓存体系为核心,通过系统化分析缓存应用场景和技术选型,重构了平…...

3.4/Q2,Charls最新文章解读

文章题目&#xff1a;Associations between reversible and potentially reversible cognitive frailty and falls in community-dwelling older adults in China: a longitudinal study DOI&#xff1a;10.1186/s12877-025-05872-2 中文标题&#xff1a;中国社区老年人可逆性和…...

Bash fork 炸弹 —— :(){ :|: };:

&#x1f9e0; 什么是 Fork 炸弹&#xff1f; Fork 炸弹是一种拒绝服务&#xff08;DoS&#xff09;攻击技术&#xff0c;利用操作系统的 fork() 系统调用不断创建新进程&#xff0c;直到系统资源&#xff08;如进程表、CPU、内存&#xff09;被耗尽&#xff0c;从而使系统无法…...

HarmonyOS AVPlayer 音频播放器

鸿蒙文档中心&#xff1a;使用AVPlayer播放视频(ArkTS)文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/video-playback 这张图描述的是 HarmonyOS AVPlayer 音频播放器的状态流转过程&#xff0c;展示了 AVPlayer 在不同状态之间的切换条件和关键操作…...

symfonos: 2靶场

symfonos: 2 来自 <https://www.vulnhub.com/entry/symfonos-2,331/> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182&#xff0c;靶场IP192.168.23.253 3&…...

微服务项目->在线oj系统(Java版 - 2)

相信自己,终会成功 微服务代码: lyyy-oj: 微服务 接口文档定义 响应数据定义: 响应数据格式:通常&#xff0c;HTTP API 的响应数据采用 JSON 格式 例如:成功响应&#xff08;带数据&#xff09; {"code": 200,"message": "查询成功","…...