Qgis 开发初级 《数据库和图层》
Qgis 可以加载很多数据源,像shapefile 文件, gdb文件等,还可以直接链接企业数据库。在这里,我只介绍比较常用的本地数据库 gdb。gdb 是esri 开发的数据库,gdb数据库不是开源的,qigs用了OpenFileGdb的驱动读写的,这个驱动目前是支持读写的。Qgis 读写数据库做了一层封装的,读写都是通过Qgis 的图层类实现,所以这里和图层一起介绍。
1、数据库操作
1.1、数据库的读取
读取数据库里面的某个表,从数据库的表到Qgis的QgsVectorLayer 矢量图层类中。参数表示 读取 D盘 test.gdb 的 名为 point 的表。注意这里 |layername= 附近 不要有空格,否则可能会读取失败。
QString layerName="point";
QString dbPath="D:\\test.gdb"+"|layername="+layerName;
QgsVectorLayer* gdbLayer = new QgsVectorLayer(dbPath, layerName, QStringLiteral("ogr"));
1.2、数据库的写入
这里会将QgsVectorLayer 写入到gdb中。
QgsVectorFileWriter::SaveVectorOptions options;
options.actionOnExistingFile = QgsVectorFileWriter::AppendToLayerNoNewFields;
options.driverName = "openFileGDB";
options.layerName = layerName;QgsCoordinateTransform ct;
ct = QgsCoordinateTransform(vectorlayer->crs(), vectorlayer->crs(), vectorlayer->transformContext());
ptions.ct = ct;
QgsVectorFileWriter::writeAsVectorFormatV3(vectorlayer, cds.workSpacePath(), vectorlayer->transformContext(), options);
其中QgsVectorFileWriter::AppendToLayerNoNewFields是个枚举值。 通过它来确定数据库记录是覆盖还是增加。
enum ActionOnExistingFile
{
//! Create or overwrite file
CreateOrOverwriteFile,
//! Create or overwrite layer
CreateOrOverwriteLayer,
//! Append features to existing layer, but do not create new fields
AppendToLayerNoNewFields,
//! Append features to existing layer, and create new fields if needed
AppendToLayerAddFields
};
2、图层的操作
Qgis的图层是Qgis封装的通用类,Qgis 用它屏蔽了数据源的不同,使用它可以操作所有的数据源。数据库的字段和记录都是通过Qgis的图层来实现的。Qgis 里面有各种类型的图层,跟gdb 有关的主要是QgsVectorLayer的矢量图层。
2.1、 图层的新建和添加
图层第一种创建方式就是从数据库读取的图层。这个时候图层是与数据库表同步的。获取方法参考 1.1 数据库的读取。
图层第二种创建是直接创建内存图层, 创建一个名字叫 test的点图层,并设置坐标系。
QgsVectorLayer* layer=new QgsVectorLayer("PointZ", "test", "memory");
layer->setCrs(QgsProject::instance()->crs());
这种创建的第一个参数是Qgis 的类型,该类型是个枚举,点,线,面都可以创建,枚举如下,创建的时候直接写字符串就可以。
enum Type{Unknown = 0,Point = 1,LineString = 2,Polygon = 3,Triangle = 17,MultiPoint = 4,MultiLineString = 5,MultiPolygon = 6,GeometryCollection = 7,CircularString = 8,CompoundCurve = 9,CurvePolygon = 10, //13, //should be 10. Seems to be correct in newer PostGIS versionsMultiCurve = 11,MultiSurface = 12,NoGeometry = 100, //attributes onlyPointZ = 1001,LineStringZ = 1002,PolygonZ = 1003,TriangleZ = 1017,MultiPointZ = 1004,MultiLineStringZ = 1005,MultiPolygonZ = 1006,GeometryCollectionZ = 1007,CircularStringZ = 1008,CompoundCurveZ = 1009,CurvePolygonZ = 1010,MultiCurveZ = 1011,MultiSurfaceZ = 1012,PointM = 2001,LineStringM = 2002,PolygonM = 2003,TriangleM = 2017,MultiPointM = 2004,MultiLineStringM = 2005,MultiPolygonM = 2006,GeometryCollectionM = 2007,CircularStringM = 2008,CompoundCurveM = 2009,CurvePolygonM = 2010,MultiCurveM = 2011,MultiSurfaceM = 2012,PointZM = 3001,LineStringZM = 3002,PolygonZM = 3003,MultiPointZM = 3004,MultiLineStringZM = 3005,MultiPolygonZM = 3006,GeometryCollectionZM = 3007,CircularStringZM = 3008,CompoundCurveZM = 3009,CurvePolygonZM = 3010,MultiCurveZM = 3011,MultiSurfaceZM = 3012,TriangleZM = 3017,Point25D = 0x80000001,LineString25D,Polygon25D,MultiPoint25D,MultiLineString25D,MultiPolygon25D};
这种方式再介绍下指定地方坐标系的情况,str 填写的是坐标系的 wkt 字符串。其中layer 是QgsVectorLayer * 的指针对象。
QString str = "";
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromWkt(str);
layer->setCrs(crs);
这两种图层创建后,其实还没加入到Qgis 工程中。通过QgsProject 加入到工程中。代码如下。
QgsProject::instance()->addMapLayer(layer);
加入到工程中的图层,可以通过名字或者ID 重新获取指针。下面代码是获取名字叫test的图层。mapLayersByName 返回的是QList 列表对象。因为Qgis 多个图层可以叫同一个名字。当然可以通过layer的id获取,再次不多介绍了。
QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>(QgsProject::instance()->mapLayersByName("test").at(0));
2.2、 图层的删除
其中di 是 图层QgsVectorLayer * 的指针对象 的图层id; 这个里面会自动删除指针对象。
QgsProject::instance()->removeMapLayer(id);
2.3、添加字段
Qgis 添加字段涉及到 QgsField 的类,如下代码,添加了一个String 类型的 Name 字段,一个Double类型的X 字段和一个Double类型的Y字段。Qgis 是用Qt 开发,经常会用到一些qt的语法。其中layer 是QgsVectorLayer * 的指针对象。
QList<QgsField> fieldList;
fieldList.append(QgsField("Name", QVariant::String));
fieldList.append(QgsField("X", QVariant::Double));
fieldList.append(QgsField("Y", QVariant::Double));QgsVectorDataProvider* provider=layer->dataProvider();
provider->addAttributes(fieldList);
layer->updateFields();
3 、要素操作
图层和字段创建好了后,就需要对要素做进一步操作。主要实现增删改查,图层的要素编辑其实有两种,一种在编辑模式下,一种不在编辑模式下。两种的区别是编辑模式考虑的用户操作体验,可以做回撤,重做等操作,批处理时,效率相对较低。非编辑模式下直接操作同步数据库,效率比较高。这里先介绍下非编辑模式。Qgis的要素类是QgsFeature。 代表着数据库中的一行记录。
3.1 、添加要素
添加要素的代码如下,首先,创建QgsFature对象,其中layer 是QgsVectorLayer * 的指针对象。
QgsFeature feature = QgsFeature(layer->fields());
QgsVectorDataProvider* provider = layer->dataProvider();
provider->addFeature(feature );
也可以用addFeatures 批量添加,这种方式应该更快一些。QList 可以换成QgsFeatureList 是一样,QgsFeatureList 是QList<QgsFeature> 的宏命令。
QList<QgsFeature> features;
QgsFeature feature = QgsFeature(layer->fields());
features.push_back(feature );
QgsVectorDataProvider* provider = layer->dataProvider();
provider->addFeatures(features);
添加几何字段值,在平面坐标系下这样操作。在setGeometry 的参数是QgsGeometry。这个对象的具体操作会在后面介绍。注意,添加的几何,要与创建的图层一致,图层是点,添加点,图层是线,添加线,
feature.setGeometry(QgsGeometry::fromPointXY(QgsPointXY(1000, 1000)));
添加字段属性值,单个添加。
feature.setAttribute("X", 1000);
feature.setAttribute("Y", 1000);
也可以批量添加属性。但是要注意属性的顺序。
feature.setAttributes(QgsAttributes() << "Point 1");
3.2、要素更新
要素更新,主要更新地理字段和属性字段。可以使用下面的方法批量添加地理字段和属性字段。其中index 是字段的所在字段索引,id 是QgsFeature的 id ,layer 是 QgsVectorLayer * 的指针对象。 类型是QgsFeatureId。其中geo 和 amap 的不在举例子了。
QgsGeometry geo;QgsAttributeMap amap;amap.insert(index, 1000);QgsChangedAttributesMap camap;QgsGeometryMap geoMap;camap.insert(id,amap);geoMap.insert(id,geo);layer->dataProvider()->changeFeatures(camap, geoMap);
3.3、要素删除
通过以下方法删除要素
QgsFeatureIds ids;
layer->dataProvider()->deleteFeatures(ids);
4、小节
我们介绍了数据库的操作,图层和要素的操作,其中图层和要素实在非编辑模式下的操作,也是比较高效率的操作。编辑模式下的操作其实类似,在后面qigs的编辑功能里面在介绍。
相关文章:

Qgis 开发初级 《数据库和图层》
Qgis 可以加载很多数据源,像shapefile 文件, gdb文件等,还可以直接链接企业数据库。在这里,我只介绍比较常用的本地数据库 gdb。gdb 是esri 开发的数据库,gdb数据库不是开源的,qigs用了OpenFileGdb的驱动读…...
三大机器学习框架对比:TensorFlow、PyTorch与Scikit-Learn
目录 前言 概述 TensorFlow PyTorch Scikit-Learn 总结 前言 本篇旨在深入探讨三种主流机器学习框架——TensorFlow、PyTorch与Scikit-Learn。随着数据科学和人工智能领域的快速发展,这些框架已成为构建和部署机器学习模型的关键工具。鉴于每种框架的特点和优…...

Apache OFBiz 曝出严重漏洞,允许预身份验证 RCE
近日,研究人员发现 Apache OFBiz 中存在一个新的关键漏洞,该漏洞是 Apache OFBiz 中的一个错误授权问题,被追踪为CVE-2024-38856。该漏洞影响 18.12.14 之前的版本,18.12.15 版本解决了该漏洞。 SonicWall 的安全研究员 Hasib Vh…...
SpringCloud 微服务nacos和eureka
Spring是微服务架构,是一种经过良好架构设计的分布式架构方案。 微服务架构有如下特性 单一:微服务拆分粒度小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发 面向服务:微服务对外暴漏…...

Java学习篇(一)| 如何生成分布式全局唯一ID
Java学习篇(一)| 如何生成分布式全局唯一ID 一、使用场景二、常用方法1、UUID (尽量不要用)2、数据库自增 (用的最多-但不适合做分布式ID)3、Redis 生成ID (可用)1、原因2、通过代码…...
c++ 弹窗办法
在C中,创建弹窗的方法有多种。下面我会逐一介绍几种常见的方法,并提供相应的代码示例。 使用Windows API创建弹窗 使用Windows API可以创建原生的Windows弹窗。前面已经提供了一个示例代码,下面我会逐步解释该代码的关键部分: …...
小程序使用this.animate实现3维动画切换
小程序使用this.animate实现3维动画切换 这里以三张图片为例 话不多说,直接上代码 wxml <view class"container"><view class"carousel" id"carousel_id"><view class"box" wx:for"{{items}}"…...
【区块链+社会公益】第一反应互助急救链 | FISCO BCOS应用案例
第一反应互助急救链将现有业务体系和系统与 FISCO BCOS 的区块链底层技术相结合,使得公益行为及其证据、 积分、奖励过程以区块链的方式进行记录,确保公正、透明、不可篡改。此外,项目将赛事保障、公益急救培训、 社区互助急救、AED 勘察等社…...
leetcode 136. 只出现一次的数字
https://leetcode.cn/problems/single-number/description/?envTypestudy-plan-v2&envIdtop-interview-150 136. 只出现一次的数字 已解答 简单 相关标签 相关企业 提示 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出…...

可扩展架构设计:策略与最佳实践
在快速变化的数字世界中,构建可扩展的架构设计已经成为企业成功的关键因素之一。随着业务规模的不断扩大,系统需求也随之增加,因此,能够灵活适应变化的系统架构变得尤为重要。本文将详细介绍可扩展架构设计的核心概念、重要性以及…...

一图胜千言|图解Pandas常用操作!
Pandas 展示 请看下表: 它描述了一个在线商店的不同产品线,共有四种不同的产品。与前面的例子不同,它可以用NumPy数组或Pandas DataFrame表示。但让我们看一下它的一些常见操作。 1. 排序 使用Pandas按列排序更具可读性,如下所示: 这里arg…...

ue5正确导入资源 content(内容),content只能有一个
把资源content下的东西,全部拷贝,放在项目的content下 content只能有一个...

HTTP协议基础知识【后端 4】
HTTP协议基础知识 HTTP(Hyper Text Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,它定义了客户端(如浏览器)与服务器之间数据传输的格式和规则。无论是浏览网页、在线购物还是使…...

2024/8/10 英语每日一段
Microsoft, Meta Platforms and Alphabet have spent billions on generative AI, spurred on by the release of startup OpenAI’s ChatGPT software released in late 2022. The world’s biggest technology companies have yet to unveil a strategy that points to relia…...

深入探索 Wireshark——网络封包分析的利器
一、引言 在当今数字化的时代,网络通信变得日益复杂和关键。无论是企业的网络运维,还是网络安全研究,都需要深入了解网络中传输的数据。Wireshark 作为一款强大的网络封包分析工具,成为了网络工程师、安全研究人员和技术爱好者不…...
VS2022使用.Net Framework4.0方法
从安装了低版本VS的电脑中 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework \ 目录下 复制.Net Framework 4.0 等需要的目标包 如果打开项目仍然需要升级目标包的,先升级,加载项目后仍可更改目标包为.Net Framework 4…...
创建一个简单的贪吃蛇游戏:HTML、CSS和JavaScript教程
在本教程中,我们将逐步构建一个简单的贪吃蛇游戏。这个项目适合初学者,可以帮助你理解HTML、CSS和JavaScript的基础知识,并掌握如何将它们结合起来创建一个完整的游戏。 准备工作 在开始之前,请确保你已经安装了一个代码编辑器&…...

全面讲解电子齿轮比与脉冲数计算
一、什么是编码器分辨率 编码器(encoder)是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换为电信号,按照读出方式编码器可以分为接触式和非接触式两种…...

音频进阶学习一——模拟信号和数字信号
文章目录 前言|版本声明:山河君,未经博主允许,禁止转载 一、什么是模拟信号和数字信号信号模拟信号数字信号数字和模拟信号的区别一览 二、信号处理系统总结 前言 所有软件的运行都得益于硬件上的突破,数字信号是从40年前就开始高…...

SpringBoot企业人事管理系统-附源码与配套论文
1.1引言 随着计算机技术的飞速发展,计算机在各种单位机构管理中应用的普及﹐管理信息系统的开发在强调管理、强调信息的现代社会中也显得越来越重要。因此,利用计算机高效率地完成人事管理的日常事务,是适应现代各种单位机构制度要求、推动各种单位机构…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...