QGIS开发笔记(五):qgis加载标记点功能,基础标记数量与性能对比测试

news/2025/11/17 14:00:48/文章来源:https://www.cnblogs.com/qq21497936/p/19232452

前言

  对地图增加标记点、标记图标、线条、图形等等,都是常规通用操作,本篇先实现添加标记点,然后对比点数量性能,同时由于像素大小对性能也有较大印象,测试了1、2像素超大数量绘图时,拽托性能与显示效果。

 

Demo

1000标记点1像素大小

  在这里插入图片描述

  Cpu和内存大小:
  在这里插入图片描述

  拽托缩放不间断操作的CPU和内存大小:
  在这里插入图片描述

10000标记点1像素大小

  在这里插入图片描述

1000标记点2像素大小

  在这里插入图片描述

10000标记点2像素大小

  在这里插入图片描述

 

QsgVectorLayer

概述

  QgsVectorLayer是QGIS中用于处理矢量数据的核心类,它负责加载、管理和操作各种矢量空间数据(点、线、面等几何类型)。
  其作为矢量数据的容器,连接数据源(如 Shapefile、PostGIS、GeoJSON 等)并提供数据访问接口。加载矢量数据、管理属性表、处理几何对象、实现空间查询等。继承自QgsMapLayer,与QgsRasterLayer共同构成QGIS中两种主要的图层类型。

数据源连接字符串

  创建QgsVectorLayer时需要指定数据源字符串(data source string),格式因数据格式而异:
  

常用驱动(Provider)

  

注意事项

内存管理

  QgsVectorLayer对象通常由QgsProject管理,调用 QgsProject::addMapLayer后无需手动删除。

非线程安全

  QGIS 核心类(包括QgsVectorLayer)不保证线程安全,避免在非主线程中直接操作。

性能优化

  • 对大数据集使用空间索引(layer->createSpatialIndex())。
  • 批量操作时使用QgsVectorLayerUtils::addFeatures()替代循环添加。
  • 避免频繁调用 commitChanges(),建议批量修改后一次性提交。
      通过QgsVectorLayer,可以在C++中实现QGI 几乎所有矢量数据处理功能,结合QgsGeometry、QgsFeature 等类可完成复杂的空间分析任务。

常用属性和操作

构造与初始化

  通过数据源字符串(URI)、图层名、数据提供者类型构造 QgsVectorLayer。

// 加载 Shapefile
QString uri = "/path/to/data.shp";
QgsVectorLayer* layer = new QgsVectorLayer(uri, "my_layer", "ogr");
if (!layer->isValid()) {// 处理加载失败
}
// 添加到地图画布
QgsProject::instance()->addMapLayer(layer);

图层基本信息

  • geometryType():返回图层几何类型(QgsWkbTypes::GeometryType)。
  • crs():返回图层坐标系(QgsCoordinateReferenceSystem)。
  • fields():返回属性字段集合(QgsFields)。
  • featureCount():返回要素总数。
// 图层名称
QString name = layer->name();// 几何类型(点/线/面等)
QgsWkbTypes::Type geomType = layer->wkbType();
QString geomTypeName = QgsWkbTypes::displayString(geomType); // 如 "Point"// 坐标参考系(CRS)
QgsCoordinateReferenceSystem crs = layer->crs();
QString crsId = crs.authid(); // 如 "EPSG:4326"// 要素总数
int featureCount = layer->featureCount();// 空间范围
QgsRectangle extent = layer->extent();

属性表操作

  属性表由QgsFields管理,每个字段对应QgsField:

// 获取所有字段
const QgsFields& fields = layer->fields();// 遍历字段
for (int i = 0; i < fields.count(); ++i) {const QgsField& field = fields.at(i);qDebug() << "字段名:" << field.name() << "类型:" << field.typeName();
}// 根据名称查找字段索引
int fieldIndex = fields.indexOf("population");

要素迭代与访问

  通过QgsFeatureIterator遍历要素:

// 获取要素迭代器(默认遍历所有要素)
QgsFeatureIterator it = layer->getFeatures();QgsFeature feature;
while (it.nextFeature(feature)) {// 要素 IDQgsFeatureId fid = feature.id();// 几何对象(转为 WKT 字符串)QgsGeometry geom = feature.geometry();QString wkt = geom.asWkt();// 属性值(通过索引或字段名访问)QVariant population = feature.attribute("population"); // 字段名QVariant id = feature.attribute(0); // 字段索引qDebug() << "FID:" << fid << "几何:" << wkt << "人口:" << population.toInt();
}

查询与过滤

// 1. 属性查询(例如:population > 100000)
QgsExpression expr("\"population\" > 100000");
if (expr.hasParserError()) {qWarning() << "表达式错误:" << expr.parserErrorString();
}QgsFeatureRequest request(expr);
QgsFeatureIterator attrIt = layer->getFeatures(request);// 2. 空间查询(例如:在指定范围内的要素)
QgsRectangle rect(116.0, 39.0, 117.0, 40.0); // 北京附近范围
QgsFeatureRequest spatialRequest;
spatialRequest.setFilterRect(rect);
QgsFeatureIterator spatialIt = layer->getFeatures(spatialRequest);

编辑要素

// 开启编辑
if (!layer->startEditing()) {qWarning() << "无法开启编辑模式";return;
}// 1. 添加新要素
QgsFeature newFeature(layer->fields());
newFeature.setGeometry(QgsGeometry::fromPointXY(QgsPointXY(116.4, 39.9))); // 点坐标
newFeature.setAttribute("name", "Beijing");
newFeature.setAttribute("population", 21540000);
if (!layer->addFeature(newFeature)) {qWarning() << "添加要素失败";
}// 2. 更新现有要素
QgsFeature feature;
if (layer->getFeature(1, feature)) { // 获取 ID=1 的要素feature.setAttribute("population", 22000000);if (!layer->updateFeature(feature)) {qWarning() << "更新要素失败";}
}// 3. 删除要素
if (!layer->deleteFeature(2)) { // 删除 ID=2 的要素qWarning() << "删除要素失败";
}// 提交编辑(保存修改)
if (!layer->commitChanges()) {qWarning() << "提交修改失败:" << layer->commitErrors();layer->rollBack(); // 回滚
} else {qDebug() << "修改已保存";
}

样式设置

// 从 QML 文件加载样式
if (!layer->loadNamedStyle("/path/to/style.qml")) {qWarning() << "加载样式失败";
}
layer->triggerRepaint(); // 刷新图层
 

Demo源码

QGisManager.cpp

bool QGisManager::addMakerPointToCanvas(QgsMapCanvas * pMapCanvas, double x, double y, QString baseName, QString name, QString crs, QColor color, int size)
{// 步骤一:创建点图层QgsVectorLayer *pMarkerLayer = new QgsVectorLayer(QString("Point?crs=%1").arg(crs),   // 坐标系name,                               // 名称"memory");if(!pMarkerLayer->isValid()){LOG << "Failed to" << "new QgsVectorLayer(" << QString("Point?crs=%1").arg(crs) << "," << name << "," << "memory)";return false;}// 步骤二:添加属性字段,用于存储标记名称QgsField nameFiled(baseName, QVariant::String);pMarkerLayer->dataProvider()->addAttributes({nameFiled});pMarkerLayer->updateFields();// 步骤三:创建一个点要素QgsFeature feature;feature.setGeometry(QgsGeometry::fromPointXY(QgsPointXY(x, y)));feature.setAttributes(QgsAttributes({name}));// 步骤四:将要素添加到图层pMarkerLayer->dataProvider()->addFeature(feature);pMarkerLayer->updateExtents();// 步骤五:创建配置标记符号QgsMarkerSymbol * pMarkerSymbol = new QgsMarkerSymbol();pMarkerSymbol->setColor(color);pMarkerSymbol->setSize(size);// 步骤六:设置图层渲染器QgsSingleSymbolRenderer * pSingleSymbolRenderer = new QgsSingleSymbolRenderer(pMarkerSymbol);pMarkerLayer->setRenderer(pSingleSymbolRenderer);// 步骤七:添加到地图QList<QgsMapLayer *> listMapLayer = pMapCanvas->layers();if(!listMapLayer.contains(pMarkerLayer)){listMapLayer.push_front(pMarkerLayer);}pMapCanvas->setLayers(listMapLayer);//pMapCanvas->refresh();return true;
}

QGisWidget.cpp

void QGisWidget::test_demo3(QString filePath, int pointNum)
{// 步骤一:创建画布层QgsMapCanvas *pMapCanvas = new QgsMapCanvas();// 启用并行渲染pMapCanvas->setParallelRenderingEnabled(true);// 强制始终允许渲染pMapCanvas->setRenderFlag(true);// 步骤二:创建图片数据影像层QgsRasterLayer *pLayer = new QgsRasterLayer(filePath);if(!pLayer->isValid()){LOG << "Failed to load:" << filePath;return;}// 步骤三:设置图层进入画布pMapCanvas->setLayers({pLayer});    // 并不会影响QgsProject::instance()->mapLayers()的数量// 步骤四:设置画布范围pMapCanvas->setExtent(pLayer->extent());// 步骤五:刷新画布pMapCanvas->refresh();// 步骤六:需要拽托移动,则需要QgsMapToolPan,否则无法移动只能滚轮缩放QgsMapToolPan *pMapToolPan = new QgsMapToolPan(pMapCanvas);pMapCanvas->setMapTool(pMapToolPan);// 步骤七:随机生成点,pointNumdouble step = 1;int col = 100;LOG << "add" << pointNum << "points," << "step:" << step << ", col:" << col;for(int index = 0; index < pointNum; index++){QGisManager::addMakerPointToCanvas(pMapCanvas,index % col * step,index / col * step,"point",QString("point_%1").arg(index),"EPSG:3857",Qt::green,1);LOG << (index % col * step) << (index / col * step) << QString("point_%1").arg(index);}// 布局初始化QHBoxLayout *pHBoxLayout = dynamic_cast<QHBoxLayout *>(this->layout());if(!pHBoxLayout){pHBoxLayout = new QHBoxLayout(this);}pHBoxLayout->addWidget(pMapCanvas, 1);pHBoxLayout->setMargin(0);setLayout(pHBoxLayout);
}
 

工程模板v1.2.0

  在这里插入图片描述

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

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

相关文章

2025敏感肌面霜选购指南,从泛红到维稳全搞定!5大温和修护品牌实测

2025敏感肌面霜选购指南,从泛红到维稳全搞定!5大温和修护品牌实测随着环境刺激加剧与护肤需求升级,敏感肌人群占比持续上升,专为敏感肌设计的面霜已成为护肤刚需。优质敏感肌面霜不仅需做到温和无刺激,更要精准解…

2025留学机构哪些好

2025留学机构哪些好一、2025年留学机构哪些好?这些疑问你有吗?作为一名从事国际教育规划工作超过八年的咨询师,我每天都会接触到大量学生和家长的咨询。2025年已经过去近四分之三,许多计划明年秋季入学的同学已经开…

2025杭州好的留学机构有哪些

2025杭州好的留学机构有哪些一、杭州留学中介怎么选?这五个问题帮你理清思路作为一位拥有12年经验的国际教育规划师,我经常被杭州的学生和家长问及如何选择留学中介。在2025年10月24日的今天,留学市场竞争愈发激烈,…

2025出国留学机构国内排名榜

2025出国留学机构国内排名榜一、2025年选择留学中介,你是否有这些疑问?作为从事12年国际教育规划师的我,在日常工作中经常遇到学生和家长提出各种关于留学中介选择的困惑。随着2025年留学市场的不断变化,许多人在搜…

2025成都最好的留学中介机构有哪些公司

2025成都最好的留学中介机构有哪些公司一、成都留学中介选择指南:用户常见问题解析作为一位在留学咨询领域耕耘超过十年的国际教育规划师,我每天都会接触到大量来自成都学生和家长的咨询。2025年10月23日,当我整理最…

2025年长沙心理咨询机构专业度排名,线上/在线公司口碑推荐

行业背景分析 随着社会对心理健康重视程度的提升,长沙心理咨询服务市场呈现出专业化、规范化的发展趋势。据行业数据显示,近年来长沙心理咨询机构数量增长显著,服务模式从传统的线下咨询逐步发展为线上线下相结合的…

2025年电动护理床批发厂家权威推荐榜单:医院办公家具/医用医疗床/候诊椅源头厂家精选

全球医用电动护理床市场持续增长,预计到2031年市场规模将达161.4亿元,中国企业在其中扮演着越来越重要的角色。 本文将为您深度解析电动护理床行业的市场格局,并基于产能规模、技术实力、质量认证、市场覆盖四大维度…

2025年新中式高定服装五大品牌权威推荐,诚信的新中式高定服装品牌色麦新中式层层把关品质优

新中式高定服装市场格局深度解析 随着国潮复兴与文化自信的持续升温,新中式高定服装市场正迎来前所未有的发展机遇。据行业数据显示,2024年新中式服装市场规模已突破千亿元,年复合增长率保持在25%以上。在这一蓬勃发…

OpenEuler安装Java + Mysql环境

JDK安装 sudo dnf install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel #查看版本 java -version javac -versionMysql安装 # 添加 MySQL 官方仓库 sudo dnf install -y https://repo.mysql.com/mysql80-communit…

2025油皮必囤面霜清单:构象编织霜领衔,控油抗老/补水不黏腻/敏肌适配款怎么选

2025油皮必囤面霜清单:构象编织霜领衔,控油抗老/补水不黏腻/敏肌适配款怎么选随着美妆护肤理念的精细化发展,油皮面霜不再局限于单一控油功能,兼具抗老、修护、持妆适配等多元需求的产品成为市场主流。油皮面临的“…

搭建环境:基于clickhouse的流式数据处理最小系统 - dalifornia

本人搭建clickhouse流式数据处理系统时,由于驱动兼容性的问题踩了一系列坑。在此记录一个成功配置的参数和步骤。系统组成 基于 docker 搭建 kafka + flink + clickhouse + grafana 的流式数据处理系统。系统功能 支持…

2025 年 11 月混合机厂家推荐排行榜,卧式螺带混合机,锥形螺杆螺带混合机,双锥混合机,V型混合机,二维运动混合机,三维运动混合机,槽型混合机公司推荐

2025年11月混合机厂家推荐排行榜:卧式螺带/锥形螺杆螺带/双锥/V型/二维运动/三维运动/槽型混合机权威指南 行业背景与发展现状 随着现代工业生产的精细化发展,混合设备作为化工、制药、食品、冶金等行业的核心工艺装…

干皮救星面霜榜单2025:高保湿抗老品牌全解析,深滋润强修护不踩雷

干皮救星面霜榜单2025:高保湿抗老品牌全解析,深滋润强修护不踩雷随着气候环境变化与护肤需求升级,干皮面霜作为基础护肤的核心单品,市场需求持续攀升。优质干皮面霜需同时满足长效保湿、屏障修护、温和安全三大核心…

2025 年 11 月真空上料机厂家推荐排行榜,电动真空上料机,气动真空上料机,全自动真空上料机公司推荐

2025 年 11 月真空上料机厂家推荐排行榜:电动真空上料机、气动真空上料机、全自动真空上料机公司推荐 行业背景与发展趋势 真空上料机作为现代工业生产中不可或缺的粉粒物料输送设备,在制药、化工、食品、塑料等行业…

2025年廊坊电线电缆十大厂家推荐排行榜,阻燃电缆供应厂家,耐火电线公司,防火电缆厂家排名,消防电缆厂家,电线电缆供应厂家-云岭兴成

2025年廊坊电线电缆十大厂家推荐排行榜,阻燃电缆供应厂家,耐火电线公司,防火电缆厂家排名,消防电缆厂家,电线电缆供应厂家-云岭兴成2025年廊坊电线电缆十大厂家推荐排行榜,阻燃电缆供应厂家,耐火电线公司,防火…

2025 年 11 月铝合金门窗厂家推荐排行榜,断桥门窗,断桥推拉门窗,系统门窗,金属门窗,阳台门窗,封阳台门窗,平开门窗,推拉门窗,折叠门窗公司推荐

2025年11月铝合金门窗厂家推荐排行榜:断桥门窗、系统门窗与金属门窗深度解析 随着建筑节能标准的不断提高和消费者对居住环境品质要求的提升,铝合金门窗行业正迎来新一轮技术革新与市场洗牌。作为建筑外围护结构的重…

2025 年 11 月增压器厂家权威推荐榜单:涡轮增压器/汽车涡轮增压器/增压器总成/增压器叶轮/增压器机芯/工程机械增压器/丰田增压器/五十铃增压器/底特律增压器

2025 年 11 月增压器厂家权威推荐榜单:涡轮增压器/汽车涡轮增压器/增压器总成/增压器叶轮/增压器机芯/工程机械增压器/丰田增压器/五十铃增压器/底特律增压器 行业背景与发展趋势 随着全球汽车工业向高效节能方向转型…

2025 年 11 月不锈钢珠、碳钢珠厂家推荐排行榜,316/304/420/440不锈钢珠,轴承铬钢珠,高精度碳钢珠,弹簧定位钢珠公司精选

2025 年 11 月不锈钢珠、碳钢珠厂家推荐排行榜,316/304/420/440不锈钢珠,轴承铬钢珠,高精度碳钢珠,弹簧定位钢珠公司精选 在工业制造领域,钢球作为基础零部件,其质量直接影响设备的性能和寿命。随着制造业向高端…

【ImageMagick】批量修改文件夹内的图片尺寸

安装 ImageMagickWindows: 下载安装包 https://imagemagick.org/ macOS: brew install imagemagick Linux: sudo apt-get install imagemagick基本使用命令 # 调整所有JPG图片为800x600(保持比例) magick mogrify -r…

dubbo 版本 alibaba 和apache 对比

好的,用户问的是Dubbo的Alibaba和Apache版本对比,我得先理清楚这两个版本的关系。首先,用户可能是在做技术选型,或者项目里正在用Dubbo,遇到了版本选择的问题。他的身份可能是开发人员或者架构师,负责中间件决策…