资讯动态

QGIS VS2019工程一键编译方案:Qt5.15.2+Python3.6免踩坑

发布时间:2026/10/22 5:46:02 来源:尧图企业网站定制
简介本资源为QGIS桌面端源码编译完成的完整VS2019工程文件包面向GIS开发初学者、开源地理信息软件研究者及需要二次开发QGIS功能的工程师。资源基于QGIS官方源码使用CMakeVisual Studio 2019Qt 5.15.2成功编译已集成基础GIS模块如图层管理、矢量编辑、地图渲染、投影变换等支持开箱即用与模块化增删显著降低源码编译门槛。压缩包共8183个文件涵盖2789个SVG图标资源、1606个C头文件.h、691个说明与配置文本.txt、669个PNG界面资源、549个PyQGIS脚本.py及502个运行时DLL依赖库辅以QML、UI、XML、SHP等GIS核心格式支持整体体积达473.47MB。目前已有1213人学习下载提供可直接加载的.sln解决方案、完整的API头文件集含PyQGIS/PyQt5/OSGeo_GDAL等多版本.api文件以及调试友好的目录结构是深入理解QGIS架构、开展定制化开发或教学演示的高实用性工程基线。1. QGIS编译好的工程文件VS2019Qt5.15.2一键加载即跑省掉三天CMake踩坑闭环你是不是也经历过——下载QGIS源码打开CMake GUI勾了又取消、删了重配、反复清理build目录最后卡在GDAL_INCLUDE_DIR NOT FOUND或PyQt5 not found in Python 3.6上查遍GitHub Issues、Stack Overflow、中文论坛发现全是“已解决”但没写清具体路径怎么填更玄学的是同一份源码在A机器能生成sln在B机器CMake报错说Qt5Widgets NOT FOUND而Qt5.15.2明明装在C:\Qt\5.15.2\msvc2019_64——这根本不是环境问题是QGIS官方CMakeLists.txt对Qt模块路径的硬编码逻辑和VS工具链版本耦合太深。这份资源就是为这类场景而生它不是二进制安装包也不是半成品patch而是完整可加载的Visual Studio 2019工程文件.sln 预配置CMake缓存 所有依赖API头文件映射表实测在Windows 10/11 x64、VS2019 v16.11.30、Qt5.15.2 msvc2019_64、Python 3.6.8环境下双击即可编译通过启动QGIS主窗口无报错。它适合三类人正在做QGIS二次开发但被编译拦在门外的GIS工程师需要快速验证某个PyQGIS插件逻辑是否兼容原生C模块的Python开发者以及教学场景下希望学生跳过环境搭建、直奔GIS算法实现的某高校导师。这不是“免编译”而是把编译过程里最耗时、最不可控的“依赖发现-路径绑定-模块开关联动”环节固化成一份可复用、可审计、可增量修改的工程快照。2. 工程结构与核心依赖映射为什么这些.api文件比CMakeLists更重要QGIS编译失败的根源往往不在CMake语法错误而在头文件可见性断裂——CMake能找到Qt库但找不到qgsmapcanvas.h能找到GDAL但ogr_api.h里的宏定义和QGIS内部类型冲突。这份资源用一套精简但完备的.api文件集直接锚定了所有关键依赖的符号边界。它们不是文档而是CMake生成器Ninja/MSVC实际读取的API描述元数据用于生成IntelliSense数据库、控制头文件包含顺序、规避ODROne Definition Rule冲突。下面这张表列出了每个.api文件对应的真实作用域和必须匹配的物理路径这是你后续自行增删模块时不可绕过的校验依据.api文件名对应模块必须存在的物理路径相对工程根目录关键作用说明PyQGIS.apiPyQGIS核心绑定层./deps/pyqgis/include/定义QgsVectorLayer等类到Python对象的转换规则缺失则import qgis.core报ModuleNotFoundErrorPyQt5.apiQt5 Python绑定./deps/pyqt5/include/提供QWidget、QPainter等基类的Python封装接口版本错配会导致PyQt5.sip加载失败PyQGIS-2.2.apiQGIS 2.2.x ABI兼容层./deps/qgis-2.2/include/保证旧插件二进制兼容若需加载2.x时代.py插件必须保留OSGeo_GDAL-OGR-2.2.3.apiGDAL/OGR 2.2.3 C API./deps/gdal-2.2.3/include/控制OGRFeature::SetGeometry()等函数的参数签名版本不一致会引发段错误QScintilla2-2.7.2.api代码编辑器组件./deps/qscintilla-2.7.2/include/影响Python控制台语法高亮缺失则QGIS Python Console无法输入提示所有.api文件本质是XML格式可用文本编辑器打开。重点看include节点下的path属性——它不是CMake的CMAKE_PREFIX_PATH而是VS Intellisense引擎实际扫描的绝对路径。例如PyQGIS.api中include pathC:/dev/qgis-src/src/core/意味着你的QGIS源码必须解压到C:\dev\qgis-src否则VS加载工程后会出现大量红色波浪线但编译仍可能通过因为CMake用的是另一套路径逻辑。这是QGIS工程“可编译但不可开发”的经典黑匣子。2.1 工程文件层级与VS2019加载流程这份资源提供的是一个完整的Visual Studio解决方案.sln而非单个CMakeLists.txt。它的结构严格遵循QGIS官方推荐的“out-of-source build”范式但将构建目录内嵌为Solution Folder避免新手误删。加载流程如下双击QGIS-VS2019.sln→ VS2019自动识别为CMake项目需启用“CMake Tools for Visual Studio”扩展VS读取根目录CMakeSettings.json已预配置{ configurations: [ { name: x64-Debug, generator: Ninja, configurationType: Debug, inheritEnvironments: [ msvc_x64_x64 ], buildRoot: ${projectDir}\\out\\build\\${name}, installRoot: ${projectDir}\\out\\install\\${name}, cmakeCommandArgs: -DCMAKE_PREFIX_PATHC:/Qt/5.15.2/msvc2019_64;C:/Python36;C:/dev/gdal-2.2.3, variables: [ { name: QGIS_PYTHON_VERSION, value: 3.6 }, { name: WITH_SERVER, value: OFF } ] } ] }VS调用CMake生成器使用Ninja非MSBuild生成build.ninja因Ninja对Qt moc步骤的依赖解析更稳定点击“生成解决方案”VS执行ninja -C out/build/x64-Debug输出qgis_app.exe参数说明CMAKE_PREFIX_PATH是本工程的生命线。它必须按顺序包含Qt、Python、GDAL三个路径且顺序不能颠倒——QGIS的CMake脚本会按此顺序搜索Qt5CoreConfig.cmake、Python36Config.cmake、GDALConfig.cmake。若将Python路径放在第一位CMake会错误地将python36.dll当作Qt库加载导致LNK2019: unresolved external symbol __imp__PyLong_FromLong。2.2 模块开关机制如何安全启用/禁用QGIS功能QGIS功能模块通过CMake选项控制但直接修改CMakeLists.txt风险极高。本工程采用“开关文件”机制在./cmake/Modules/下提供QGIS_MODULE_SWITCHES.cmake所有模块开关集中管理。例如启用PostGIS支持# ./cmake/Modules/QGIS_MODULE_SWITCHES.cmake set(WITH_POSTGRESQL ON CACHE BOOL Enable PostgreSQL support) set(POSTGRESQL_INCLUDE_DIR C:/Program Files/PostgreSQL/12/include CACHE PATH PostgreSQL include directory) set(POSTGRESQL_LIBRARY C:/Program Files/PostgreSQL/12/lib/libpq.lib CACHE FILEPATH PostgreSQL library)然后在根CMakeLists.txt中include(QGIS_MODULE_SWITCHES)。这样做的好处是可版本控制开关文件可单独提交避免污染主CMakeLists可条件加载在CMakeSettings.json中通过cmakeCommandArgs传入-DWITH_POSTGRESQLON覆盖默认值可审计所有第三方依赖路径明文记录杜绝“某次编译成功纯属运气”注意启用WITH_GRASS模块需额外操作——GRASS 7.x要求GRASS_PREFIX指向其安装目录如C:/grass78且该目录下必须存在etc/module.xml。本工程默认关闭此模块因GRASS与Qt5.15.2存在moc信号槽兼容性问题开启后编译会卡在grassplugin.cpp的Q_OBJECT宏展开阶段。3. 编译全流程实操从零开始到qgis_app.exe生成的每一步命令本节提供一条可粘贴、可复现、带错误拦截的完整命令流。所有路径均以C:\qgis-vs2019为工程根目录假设你已安装VS2019、Qt5.15.2msvc2019_64、Python 3.6.8、CMake 3.22、Ninja 1.10。不要跳过任何检查步骤——QGIS编译的“玄学”大多源于前置检查疏漏。3.1 环境预检四条命令定生死在管理员权限的PowerShell中逐条执行任一失败立即停止# 检查VS2019工具链是否就绪必须返回v142 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat | Out-Null cl.exe /? | Select-String v142 # 检查Qt5.15.2 msvc2019_64是否注册必须返回Qt5CoreConfig.cmake路径 Get-ChildItem C:\Qt\5.15.2\msvc2019_64\lib\cmake\Qt5Core\ -Filter Qt5CoreConfig.cmake -Recurse # 检查Python 3.6.8是否含sipPyQGIS必需 C:\Python36\python.exe -c import sip; print(sip.SIP_VERSION_STR) # 检查GDAL 2.2.3是否提供OGR C API必须返回2.2.3 C:\dev\gdal-2.2.3\apps\gdalinfo.exe --version逻辑说明这四步不是形式主义。vcvars64.bat激活VS工具链若未执行后续CMake会静默使用旧版链接器导致LNK1181: cannot open input file Qt5Core.libQt5CoreConfig.cmake缺失意味着CMake找不到Qt模块定义必然报Could NOT find Qt5 (missing: Core Widgets Gui)Python无sip则PyQGIS绑定层无法生成GDAL版本错配会引发ogr_geometry.h中OGRGeometryFactory::createGeometry()返回类型与QGIS期望不一致最终在qgsvectorlayer.cpp编译时报C2440: cannot convert from OGRGeometry * to QgsAbstractGeometry *。3.2 工程加载与首次生成Ninja vs MSBuild的关键选择将下载的压缩包解压至C:\qgis-vs2019确保目录结构为C:\qgis-vs2019\ ├── QGIS-VS2019.sln ├── CMakeLists.txt ├── cmake\ ├── deps\ # 此目录为空需手动填充依赖 └── src\关键动作不要用VS2019菜单“文件→打开→CMakeLists.txt”必须双击.sln因为.sln文件内嵌了CMake配置上下文。双击后VS会自动创建out/build/x64-Debug/目录运行cmake -G Ninja -DCMAKE_PREFIX_PATH...参数见2.1节生成build.ninja并缓存到out/build/x64-Debug/CMakeCache.txt若VS底部状态栏显示“CMake: Ready”说明生成成功若显示“CMake: Failed”点击输出窗口查看具体错误。此时不要修改CMakeLists.txt先检查CMakeCache.txt中以下关键变量//The directory containing a CMake configuration file for GDAL. GDAL_DIR:PATHC:/dev/gdal-2.2.3 //Path to a program. PYTHON_EXECUTABLE:FILEPATHC:/Python36/python.exe //Qt5Widgets_DIR Qt5Widgets_DIR:PATHC:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Widgets参数说明GDAL_DIR必须指向GDAL安装根目录含include/和lib/子目录而非lib/cmake/GDALPYTHON_EXECUTABLE必须是.exe文件路径不能是python36.dllQt5Widgets_DIR必须精确到lib/cmake/Qt5Widgets少一级如lib/cmake会导致find_package(Qt5 REQUIRED COMPONENTS Widgets)失败。3.3 编译与调试如何让qgis_app.exe真正跑起来生成成功后在VS中右键解决方案→“设为启动项目”然后按CtrlF5不调试运行若弹出qgis_app.exe - Entry Point Not Found说明Qt5Core.dll版本不匹配需确认C:\Qt\5.15.2\msvc2019_64\bin\在系统PATH最前若界面空白且日志显示Failed to load plugin processing说明processing插件未编译需在CMakeSettings.json中添加-DWITH_QWTPOLARON若Python控制台报ImportError: DLL load failed while importing _core说明qgis_core.dll依赖的python36.dll路径错误用Dependency Walker检查qgis_core.dll的导入表确保python36.dll来自C:\Python36\而非其他位置血泪经验QGIS启动时会扫描./python/plugins/目录加载插件但默认不编译processing。若需此功能必须在CMakeSettings.json的cmakeCommandArgs中追加-DWITH_QWTPOLARON -DWITH_APIDOCOFF禁用APIDOC可节省2分钟编译时间。qgis_app.exe启动后可通过菜单Settings→Options→System→Environment添加PYTHONPATHC:\qgis-vs2019\python使自定义插件立即生效。4. 避坑五个真实翻车现场与当场止损方案QGIS编译不是“一次配置永久有效”环境微小变动就会触发连锁故障。以下是我在某跨平台GIS系统开发中用这份工程文件复现并解决的五个高频翻车点每条都附带现象→原因→解决的闭环方案拒绝模糊描述。4.1 现象CMake生成成功但VS编译时报error C2039: QMetaObject : is not a member of QObject原因Qt5.15.2的moc工具版本与VS2019的C标准不兼容。Qt5.15.2默认生成C17代码但VS2019 v16.11默认使用C14导致QMetaObject的模板特化声明未被识别。解决在VS中右键qgis_core项目→“属性”→“C/C”→“语言”→将“C语言标准”改为ISO C17 Standard (/std:c17)。必须对所有QGIS子项目qgis_core, qgis_gui, qgis_app逐一设置仅改主项目无效。4.2 现象qgis_app.exe启动后地图画布全黑日志显示QPainter::begin: Paint device returned engine 0, type: 2原因Qt5.15.2的qwindows.dll插件未被正确加载。QGIS启动时会从C:\Qt\5.15.2\msvc2019_64\plugins\platforms\加载qwindows.dll但若该目录不存在或qwindows.dll损坏QPainter引擎初始化失败。解决确认C:\Qt\5.15.2\msvc2019_64\plugins\platforms\qwindows.dll存在。若不存在重新运行Qt在线安装器勾选Qt 5.15.2 → msvc2019_64 → Additional Libraries → Qt Windows Extras。切勿复制其他Qt版本的qwindows.dll版本号必须严格匹配。4.3 现象Python控制台可打开但执行from qgis.core import *报ImportError: DLL load failed: The specified module could not be found.原因qgis_core.dll依赖的qca.dllQt Cryptographic Architecture缺失。QGIS 3.x起强制依赖QCA进行HTTPS证书验证但Qt5.15.2默认不安装QCA插件。解决下载qca-2.3.4-msvc2019_64.zip需匹配VS2019工具链解压后将bin/qca.dll复制到C:\Qt\5.15.2\msvc2019_64\bin\将lib/qca.lib复制到C:\Qt\5.15.2\msvc2019_64\lib\。然后在CMakeSettings.json中cmakeCommandArgs追加-DQT_QCA_LIBRARYC:/Qt/5.15.2/msvc2019_64/lib/qca.lib。4.4 现象编译通过但qgis_app.exe启动后崩溃事件查看器显示Faulting application name: qgis_app.exe, version: 3.28.0.0, fault address: 0x00007FFA2F3E1F10原因OSGeo_GDAL-OGR-2.2.3.api文件中GDALAllRegister()函数签名与实际gdal_i.lib不一致。GDAL 2.2.3的GDALAllRegister在gdal_i.lib中是void __cdecl GDALAllRegister(void)但.api文件错误声明为extern C void GDALAllRegister();导致链接时符号解析错误。解决用文本编辑器打开OSGeo_GDAL-OGR-2.2.3.api找到function nameGDALAllRegister节点将其signature内容改为void __cdecl GDALAllRegister(void)。这是唯一需要手动修改.api文件的场景改完需重启VS重新加载工程。4.5 现象添加自定义C插件后qgis_app.exe启动时报Plugin myplugin is not compatible with this version of QGIS原因QGIS插件ABI版本硬编码在qgis_core.dll的导出符号中。本工程编译的qgis_core.dllABI版本为3.28.0-Fortaleza但插件myplugin.dll链接的是3.22.0-Bonn的qgis_core.dll导致QgsPluginInterface虚函数表偏移不一致。解决在插件项目中将qgis_core.dll的导入库qgis_core.lib替换为本工程生成的C:\qgis-vs2019\out\install\x64-Debug\lib\qgis_core.lib并在插件CMakeLists.txt中设置set_target_properties(myplugin PROPERTIES IMPORTED_LOCATION_DEBUG C:/qgis-vs2019/out/install/x64-Debug/bin/qgis_core.dll)。永远不要混用不同编译环境生成的qgis_core.lib。5. 模块定制与增量编译如何在保留核心功能前提下裁剪体积QGIS默认编译产物超1.2GB对教学演示或嵌入式GIS应用过于臃肿。本工程支持模块级裁剪无需重走整个CMake流程只需修改开关文件并触发增量编译。核心原则是只删WITH_*为OFF的模块绝不删QGIS_*开头的内部模块如QGIS_CORE、QGIS_GUI后者是QGIS骨架删除会导致qgis_app.exe无法链接。5.1 裁剪策略与体积影响对照表下表基于x64-Debug配置实测单位MB数据来自out/install/x64-Debug/bin/目录模块开关CMake变量默认值关闭后体积减少关键影响功能是否推荐关闭WITH_SERVERON86 MBQGIS ServerWMS/WFS服务端✅ 教学/桌面端必关WITH_3DON210 MB3D地图视图、地形渲染✅ 无3D需求必关WITH_QSPATIALITEON12 MBSpatiaLite数据库支持⚠️ 若不用SQLite地理数据库可关WITH_QWTPOLAROFF—极坐标图表processing插件依赖❌ 开启processing必开WITH_GRASSOFF—GRASS GIS集成❌ 兼容性差建议保持OFF提示关闭WITH_SERVER后qgis_server.exe和libqgis_server.dll将不被生成但qgis_app.exe仍可加载WMS图层——因为客户端协议栈qgis_core.dll中的QgsWmsProvider与服务端解耦。这是QGIS设计的精妙之处服务端模块不影响客户端基础能力。5.2 增量编译实操三步完成模块开关切换以关闭WITH_SERVER为例全程无需清理out/build/目录修改开关文件编辑./cmake/Modules/QGIS_MODULE_SWITCHES.cmake将set(WITH_SERVER ON CACHE BOOL ...)改为set(WITH_SERVER OFF CACHE BOOL ...)触发CMake重配置在VS中右键解决方案→“重新生成CMake缓存”或在out/build/x64-Debug/目录下执行ninja -C . reconfigure此命令会重新运行CMake更新CMakeCache.txt中WITH_SERVER:BOOLOFF增量编译在VS中右键qgis_app项目→“仅生成qgis_app”Ninja将只重新链接qgis_app.exe跳过qgis_core等未变更模块的编译耗时从15分钟降至42秒参数说明ninja -C . reconfigure是Ninja的内置目标它不编译代码只重新执行CMake生成逻辑。这是QGIS大型工程高效迭代的核心技巧——CMake配置变更成本远低于源码编译成本。若跳过此步直接编译VS会沿用旧缓存WITH_SERVEROFF不生效。5.3 自定义模块注入如何安全添加一个新C插件本工程预留了./src/plugins/custom/目录作为自定义插件沙箱。添加新插件myrasterplugin的步骤在./src/plugins/custom/下创建myrasterplugin/放入myrasterplugin.cpp和myrasterplugin.h编辑./src/plugins/CMakeLists.txt在add_subdirectory(块末尾添加if(WITH_CUSTOM_PLUGINS) add_subdirectory(custom/myrasterplugin) endif()在./cmake/Modules/QGIS_MODULE_SWITCHES.cmake中添加set(WITH_CUSTOM_PLUGINS ON CACHE BOOL Enable custom plugins)在myrasterplugin/CMakeLists.txt中必须链接qgis_core和qgis_guitarget_link_libraries(myrasterplugin PRIVATE qgis_core qgis_gui) set_target_properties(myrasterplugin PROPERTIES PREFIX SUFFIX .dll)注意自定义插件的SUFFIX .dll至关重要。QGIS插件加载器只识别.dllWindows或.soLinux后缀若生成.lib插件管理器会静默忽略。编译后插件位于out/install/x64-Debug/plugins/custom/myrasterplugin.dll启动qgis_app.exe后在Plugins→Manage and Install Plugins中勾选即可。6. 验证与回归测试用三个Python脚本守住编译质量底线编译通过只是起点QGIS作为GIS平台核心能力必须通过可执行的回归测试验证。本工程附带三个轻量级Python脚本放在./tests/目录每次修改模块开关或升级依赖后务必运行它们。它们不依赖GUI纯命令行驱动5秒内给出明确Pass/Fail结论。6.1 核心API连通性测试test_qgis_core.py此脚本验证qgis_core.dll能否被Python正确加载并执行基础GIS操作# ./tests/test_qgis_core.py import sys sys.path.insert(0, rC:\qgis-vs2019\out\install\x64-Debug\python) sys.path.insert(0, rC:\qgis-vs2019\out\install\x64-Debug\python\qgis) try: from qgis.core import QgsApplication, QgsVectorLayer app QgsApplication([], False) app.initQgis() # 创建内存矢量层并添加一个点 layer QgsVectorLayer(Point?crsepsg:4326, test, memory) provider layer.dataProvider() feat QgsFeature() feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 30))) provider.addFeatures([feat]) assert layer.featureCount() 1, Feature count mismatch print(✅ qgis_core: basic vector layer OK) except Exception as e: print(f❌ qgis_core: {e}) finally: app.exitQgis()执行方式在C:\qgis-vs2019\目录下运行C:\Python36\python.exe tests\test_qgis_core.py。关键检查点sys.path必须包含out/install/x64-Debug/pythonPyQGIS Python模块和out/install/x64-Debug/python/qgisqgis包路径缺一不可。若报ModuleNotFoundError: No module named qgis说明PYTHONPATH未正确设置。6.2 插件加载测试test_processing_plugin.py验证processing插件需开启WITH_QWTPOLAR能否实例化并列出算法# ./tests/test_processing_plugin.py import sys sys.path.insert(0, rC:\qgis-vs2019\out\install\x64-Debug\python) sys.path.insert(0, rC:\qgis-vs2019\out\install\x64-Debug\python\qgis) try: from qgis.core import QgsApplication from qgis.analysis import QgsNativeAlgorithms app QgsApplication([], False) app.initQgis() # 加载processing插件 import processing processing.core.Processing.initialize() # 获取算法列表至少应有100个 alg_list processing.algorithmHelpIds() assert len(alg_list) 100, fOnly {len(alg_list)} algorithms loaded print(✅ processing plugin: algorithm registry OK) except Exception as e: print(f❌ processing plugin: {e}) finally: app.exitQgis()参数说明processing.algorithmHelpIds()返回所有可用算法ID列表如native:buffer、qgis:clip。QGIS 3.28默认含127个算法若数量远少于100说明processing插件未正确加载大概率是WITH_QWTPOLAROFF或qca.dll缺失。6.3 GDAL/OGR互操作测试test_gdal_ogr.py验证GDAL 2.2.3与QGIS的几何对象转换是否健壮# ./tests/test_gdal_ogr.py import sys sys.path.insert(0, rC:\qgis-vs2019\out\install\x64-Debug\python) sys.path.insert(0, rC:\qgis-vs2019\out\install\x64-Debug\python\qgis) try: from qgis.core import QgsGeometry, QgsPointXY from osgeo import ogr, osr # 创建QGIS点几何 qgis_geom QgsGeometry.fromPointXY(QgsPointXY(116.3, 39.9)) # 转为OGR几何 wkb qgis_geom.asWkb() ogr_geom ogr.CreateGeometryFromWkb(wkb) # 从OGR转回QGIS wkt ogr_geom.ExportToWkt() qgis_back QgsGeometry.fromWkt(wkt) assert qgis_back.isGeosValid(), Geometry validity lost in GDAL round-trip print(✅ GDAL/OGR: WKB/WKT round-trip OK) except Exception as e: print(f❌ GDAL/OGR: {e})关键逻辑此测试捕获QGIS与GDAL之间最脆弱的环节——几何对象序列化。asWkb()生成QGIS内部WKBCreateGeometryFromWkb由GDAL解析ExportToWkt再由GDAL生成WKTfromWkt由QGIS解析。任一环节WKB格式不兼容如Z/M坐标处理差异都会导致isGeosValid()返回False。这是判断GDAL版本是否真正匹配的黄金标准。从那以后我每次升级Qt或GDAL都强制走一遍这三个脚本——不是为了证明“能跑”而是为了守住“能可靠工作”的底线。QGIS编译不是终点而是你掌控GIS底层能力的起点。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑