【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
系列目录: 【QGIS二次开发】地图显示与交互-01_qgis二次开发加载地图案例-CSDN博客 【QGIS二次开发】地图显示与交互-02_setlayerlabeling-CSDN博客 【QGIS二次开发】地图符号与色表-03-CSDN博客 4 地图编辑 4.1 添加点要素 功能演示: 运行程序后…...
Qt 信号和槽-核心知识点小结(11)
目录 小结表格索引 disconnect函数 lambda表达式 啥是耦合,啥是内聚 简介:这是Qt信号和槽的最后一篇文章,最主要的是总结该信号和槽的核心知识点。以及该核心知识点的文章索引(表格太长了,手机可能看不完整&#…...
React响应事件中onClick={handleClick} 的结尾有没有小括号的区别
你可以通过在组件中声明 事件处理 函数来响应事件: function MyButton() {function handleClick() {alert(You clicked me!);}return (<button onClick{handleClick}>点我</button>);} 注意,onClick{handleClick} 的结尾没有小括号&#x…...
React-Query使用react-testing-library进行测试
1.测试react-query首先我们必须得拥有queryClient,所以我们初始化queryClient,因为默认是重试三次,这意味着如果想测试错误的查询,测试可能会超时。所以可以在初始化时关闭 const createWrapper () > {const queryClient new…...
软件设计师CISC与RISC考点分析——求三连
一、考点分值占比与趋势分析(CISC与RISC) 综合知识分值统计表 年份考题数量分值分值占比考察重点2018111.33%指令特征对比2019111.33%控制器实现方式2020222.67%寄存器数量/流水线技术2021111.33%寻址方式对比2022222.67%指令复杂度/译码方式2023111.3…...
GO语言(一期)常用关键字总结
GO语言(主题一)常用关键字总结 我们这里列出一些go语言关键字,方便各位友友们检查一下自己的学习效果,也方便友友们学习查询。 break default func interface select case defer go map …...
Ubuntu搭建NFS服务器的方法
0 工具 Ubuntu 18.041 Ubuntu搭建NFS服务器的方法 在Ubuntu下搭建NFS(网络文件系统)服务器可以让我们像访问本地文件一样访问Ubuntu上的文件,例如可以把开发板的根文件系统放到NFS服务器目录下方便调试。 1.1 安装nfs-kernel-server&#…...
京东商品详情API接口开发指南(含Java/Python实现)
接口概述 京东开放平台提供了商品详情查询接口,开发者可以通过SKUID获取商品的详细信息,包括标题、价格、图片、促销信息等。该接口需要申请API权限和认证密钥。 点击获取key和secret 接口特点 支持批量查询(最多20个SKU)返回J…...
二叉树构造:从前序、中序与后序遍历序列入手
目录 引言 从前序与中序遍历序列构造二叉树(题目 105) 解题思路 举例说明 从中序与后序遍历序列构造二叉树(题目 106) 解题思路 举例说明 总结 引言 二叉树的遍历与构造是算法领域中的经典问题。LeetCode 上的“从前序与中…...
GEE谷歌地球引擎批量下载逐日ERA5气象数据的方法
本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,批量下载逐日的ERA5土壤湿度数据(或者是其他气象数据、遥感影像数据等)的方法。 首先,明确一下本文的需求。我们希望在GEE中,下…...
C#接口(Interface)全方位讲解:定义、特性、应用与实践
引言 在面向对象编程(OOP)中,接口(Interface)是一种重要的结构,它定义了某一类对象或类应遵循的行为规范。接口强调“做什么(What)”,而非“怎么做(How&…...
索引与数据结构、并行算法
3. 索引与数据结构 索引类比目录:类似于书籍目录,帮助我们快速定位信息。索引的核心目的:提升数据查找效率,优化增删改查性能。实际应用广泛:MySQL、Redis、搜索引擎、分布式系统、中间件等。 3.1. 索引设计中的需求…...
GC全场景分析
GC全场景分析 文章目录 GC全场景分析标记-清除法**标记 - 清除法核心流程与 STW 机制****标记 - 清除法四步流程****1. STW 启动(暂停用户线程)****2. 标记可达对象(从根集合出发)****3. 清除未标记对象(回收堆内存&am…...
OSI七层模型和TCP/IP的五层(四层模型)
分层 1.什么是分层 我理解是对同一相同或者相似的事务或者操作功能进行分类,比如我们去餐厅吃饭,就可以分为好多层,客户层,服务员层,前台层,后厨层,每一层都专注自己的事情,客户层…...
MouseDown,MouseUp,LostMouseCapture的先后顺序
本文目标是实现如下功能: 按下一个按钮后置位某变量;鼠标松开后复位某个变量? 看似简单,但是一般来说会存在如下两种现象: 鼠标移出按钮:默认会丢失鼠标事件跟踪,即MouseLeftButtonUp事件并不会被触发。 焦点切换:Tab 键切换焦点会干扰按钮的事件捕获 本文通过几个…...
第8章 常用实用类
8.1 String类 在java.lang包(默认引入)中,可直接使用。 定义为final类,不能扩展String类,不可以继承,不可以有子类。 8.1.1 构造String对象 常量对象: 英文双引号括起来 String常量放入常…...
视差场(disparity field)
视差场(disparity field)是立体视觉中的一个重要概念,用于描述两幅立体图像之间像素的对应关系。以下是对视差场的详细解释: 1. 视差(Disparity)的定义 视差是指同一场景点在两幅立体图像中的像素位置差异…...
AI:OpenAI论坛分享—《AI重塑未来:技术、经济与战略》
AI:OpenAI论坛分享—《AI重塑未来:技术、经济与战略》 导读:2025年4月24日,OpenAI论坛全面探讨了 AI 的发展趋势、技术范式、地缘政治影响以及对经济和社会的广泛影响。强调了 AI 的通用性、可扩展性和高级推理能力,以…...
【已经解决诸多问题】Mamba安装
mamba被称为新一代的计算架构,因此在CV和时序领域存在诸多的方案开始采用这一新架构,但是这个架构的安装过程中存在诸多问题!!!!为了更好帮助大家理解我们给出一个统一的安装流程!!&…...
计算机的基本组成与性能
1. 冯诺依曼体系结构:计算机组成的金字塔 1.1. 计算机的基本硬件组成 1.CPU - 中央处理器(Central Processing Unit)。 2.内存(Memory)。 3.主板(Motherboard)。主板的芯片组(Ch…...
“绿色邮政,智能九识”——呼和浩特邮政无人快递车发车,驶向智慧物流新时代!
5月12日,“绿色邮政,智能九识”呼和浩特邮政无人驾驶快递车发车。 此次投运的邮政无人驾驶快递车实力惊人:单车运量超1000件,时速达40公里,通过智能路径规划实现24小时作业,与传统运输相比,运转…...
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. 查看数据库 语法:show databases;这里的database是要加s的 查看当前自己所处的数据库:select database(); 例如下图,我当前所处的数据库就是在class1数据库 2. 创建数据库 语法: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 开发的重要里程碑,包含 Servlet 3.0(2009年发布)和 Servlet 3.1(2013年发布)两个主要版本。它通过多项革新优化了开发效率、性能及扩展性,成为现代 Java Web 应用的核心技术基础。…...
单目测距和双目测距 bev 3D车道线
单目视觉测距原理 单目视觉测距有两种方式。 第一种,是通过深度神经网络来预测深度,这需要大量的训练数据。训练后的单目视觉摄像头可以认识道路上最典型的参与者——人、汽车、卡车、摩托车,或是其他障碍物(雪糕桶之类…...
weibo_comment_pc_tool | 我于2025.5月用python开发的评论采集软件,根据帖子链接爬取评论的界面工具
本工具仅限学术交流使用,严格遵循相关法律法规,符合平台内容的合法及合规性,禁止用于任何商业用途! 一、背景分析 1.1 开发背景 微博(以下简称wb)是国内极具影响力的社交媒体平台,具有内容形式…...
ubuntu防火墙命令和放行ssh端口
一、关闭UFW防火墙(Ubuntu默认工具) 1. 临时关闭防火墙 sudo ufw disable sudo ufw status # 显示 Status: inactive 表示已关闭 2. 永久禁用防火墙(禁用系统服务) sudo systemctl stop ufw # 立即停止服务 sudo sy…...
PWM讲解+STM32任意频率、占空比、脉宽生成函数介绍
1.PWM讲解 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制。 脉宽调制 最开始使用PWM时,是做智能车时使用的舵机打角,电机驱动。这都属于比较浅显,普通的应用。下面和大家简单分享一下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 中的一个高危远程代码执行(RCE)漏洞,影响版本为 Spring Data Commons 1.13–1.13.10 和 2.0–2.0.5。攻击者通过构造包含恶意 SpEL表达式的 HTTP 请求参数,触发表达式注入&#x…...
C++23:修正常量迭代器、哨兵和范围
文章目录 引言C20范围库回顾C23之前常量迭代器的问题视图可能不传播const代理对象的复杂性泛型代码中的一致性 P2278R4提案及C23的改进std::views::as_const的工作原理代码示例 浅const视图(如std::span)的改进总结 引言 在C的发展历程中,每…...
【漫话机器学习系列】266.雅可比矩阵(Jacobian Matrix)
雅可比矩阵(Jacobian Matrix)详解 | 多变量函数微积分的基石 在深度学习、计算图、优化算法、机器人控制、流形学习等众多领域中,“雅可比矩阵(Jacobian Matrix)”是一个非常核心的数学工具。 这篇文章将结合一张视觉…...
Leetcode 3551. Minimum Swaps to Sort by Digit Sum
Leetcode 3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路2. 代码实现 题目链接:3551. Minimum Swaps to Sort by Digit Sum 1. 解题思路 这一题思路上我实现的非常暴力,就是先求出正确的排列,然后从头考察每一个元素是否处在其目标…...
西门子1200/1500博图(TIA Portal)寻址方式详解
西门子博图(TIA Portal)是西门子公司推出的自动化工程软件平台,广泛应用于工业自动化领域。在编写PLC程序时,寻址方式是一个非常重要的概念,它决定了如何访问和操作PLC中的数据和资源。本文将详细介绍西门子博图中的寻…...
STK手动建链+matlab联调
在右边场景区选择你要建链的卫星,右键在弹出的选项中选择Access 选择你要建链的卫星,这里我选择3轨10星与4轨8星建链,点击compute后再close就行了 建链完成,这里链路的颜色跟起始卫星的颜色一致,要想改变颜色只需改变卫…...
MATLAB中的Switch语句讲解
MATLAB中的Switch语句:一个简单的控制流工具 在MATLAB中,switch语句是一种多分支控制结构,通常用于根据某个表达式的值选择不同的代码块进行执行。它的作用类似于一系列的if-elseif-else语句,但在处理多个条件时,swit…...
【SpringBoot】✈️整合飞书群机器人发送消息
💥💥✈️✈️欢迎阅读本文章❤️❤️💥💥 🏆本篇文章阅读大约耗时3分钟。 ⛳️motto:不积跬步、无以千里 📋📋📋本文目录如下:🎁🎁&am…...
上位机知识篇---流式Web服务器模式的实现
文章目录 前言 前言 本文简单介绍了流式Web服务器模式的实现。...
Go 语言中的一等公民(First-Class Citizens)
在 Go 语言中,一等公民(First-Class Citizens) 是指语言中可以像普通值一样被自由操作的元素,包括赋值、传递、返回等。Go 虽然不是纯粹的函数式语言,但支持多种一等公民,以下是 Go 中常见的 一等公民及其特…...
python3.13版本降为3.12
目录 一、下载Python 二、安装PyCharm 三、 彩蛋 粗糙理解: PyThon是编译器(也可以在命令行编辑,但是麻烦) 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服务器可以让我们下载文件到开发板更加方便,同时也可以实现TFTP加载Linux镜像,方便调试。 1.1 安装tftp-hpa(TFTP客户端)、tftpd-hpa(TFTP服务…...
【AI】Ubuntu 22.04 4060Ti16G 基于SWIFT框架的LoRA微调 模型Qwen3-1.8B 数据集弱智吧 微调笔记
下载Qwen3-1.8B 先更新安装modescope,然后下载模型 pip install -U modelscope modelscope download --model Qwen/Qwen3-1.7B 下载日志 部署模型 参考:【AI】Ubuntu 22.04 4060Ti 16G vllm-api部署Qwen3-8B-FP8_wsl ubantu rtx4060 vllm镜像-CSDN博…...
系分论文《论信息系统缓存的分析和应用》
【摘要】 2023年3月,我作为系统分析师参与了某大型电商平台"云端购物中心"的性能优化项目。该项目日均订单量突破200万,但在促销高峰期频繁出现系统响应迟缓、数据库过载等问题。本项目以构建多级缓存体系为核心,通过系统化分析缓存应用场景和技术选型,重构了平…...
3.4/Q2,Charls最新文章解读
文章题目:Associations between reversible and potentially reversible cognitive frailty and falls in community-dwelling older adults in China: a longitudinal study DOI:10.1186/s12877-025-05872-2 中文标题:中国社区老年人可逆性和…...
Bash fork 炸弹 —— :(){ :|: };:
🧠 什么是 Fork 炸弹? Fork 炸弹是一种拒绝服务(DoS)攻击技术,利用操作系统的 fork() 系统调用不断创建新进程,直到系统资源(如进程表、CPU、内存)被耗尽,从而使系统无法…...
HarmonyOS AVPlayer 音频播放器
鸿蒙文档中心:使用AVPlayer播放视频(ArkTS)文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/video-playback 这张图描述的是 HarmonyOS AVPlayer 音频播放器的状态流转过程,展示了 AVPlayer 在不同状态之间的切换条件和关键操作…...
symfonos: 2靶场
symfonos: 2 来自 <https://www.vulnhub.com/entry/symfonos-2,331/> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.253 3&…...
微服务项目->在线oj系统(Java版 - 2)
相信自己,终会成功 微服务代码: lyyy-oj: 微服务 接口文档定义 响应数据定义: 响应数据格式:通常,HTTP API 的响应数据采用 JSON 格式 例如:成功响应(带数据) {"code": 200,"message": "查询成功","…...