1. 从一份"打不开的shp"说起:Qgis到底该从哪儿下手
我刚开始带新人的时候,最常听到的一句抱怨是:"哥,这数据我打不开。"拿到一个压缩包,里面有shp、有dbf、有prj,甚至还有几个不知道干什么用的xml,双击那个shp,要么弹一堆乱码,要么干脆什么都不显示。这时候我一般不会直接告诉他点哪个按钮,而是先问一句:你知道自己手里这份数据是什么格式吗?
Qgis这款工具,入门阶段最大的门槛从来不是软件本身有多难,而是数据源、数据格式、标注、符号化这四个词背后代表的四件事,很多人是混着理解、混着操作的,结果就是每一步都在试错。我把这套流程拆开讲,是因为这四个环节其实是递进关系:先搞清楚数据从哪来(数据源)、再搞清楚数据长什么样(数据格式)、接着让它看得懂(标注),最后让它看得顺眼(符号化)。顺序错了,后面全是返工。
这篇文章主要面向刚接触Qgis、手里有真实数据但不知道从哪动手的朋友。我会用一个完整的小案例贯穿:假设你拿到一份某区域的县界矢量数据和一份卫星影像,目标是把它做成一张能发给同事看的专题图。过程中涉及的所有操作、参数、坑点我都会讲清楚。Qgis使用教程网上一抓一大把,但大多数只告诉你"点这里、点那里",不讲为什么,我尽量把"为什么"补上。
先说清楚一件事,Qgis是开源免费的桌面地理信息处理软件,跨平台,Windows、macOS、Linux都能跑。它的版本迭代很快,长期支持版(LTR)相对稳定,我建议新手直接装LTR版本,不要追最新版,因为很多插件对新版的支持会滞后几个月。装完之后界面是英文的也别慌,设置里可以切成简体中文,这个后面细说。安装包在官网就能下到,选对应操作系统的安装程序,一路下一步即可,中间那个"下载示例数据集"的选项建议勾上,初学阶段拿来练手很合适。
2. 数据源这件事:Qgis能读的东西比你想象的多
2.1 先分清"数据源"和"数据格式"是两个概念
很多人把这两个词当同义词用,这是个根子上的误解。数据源指的是数据的来源位置和访问方式,比如它是一个本地文件、一个数据库、还是一个网络地图服务;数据格式指的是数据在磁盘上或传输中的组织方式,比如shp、GeoJSON、GeoPackage、GeoTIFF。同一个数据源可以有不同的格式,同一种格式也可以来自不同的数据源。
举个例子你就明白了。你从某部门拿到的县级行政区划数据,可能是一个shp文件夹,也可能是一个GeoPackage文件(后缀.gpkg),还有可能是对方直接给你一个数据库连接参数。这三种情况在Qgis里的操作路径完全不同:shp是"添加矢量图层",GeoPackage同样是"添加矢量图层"但选中文件后还要选具体图层,数据库则要走"添加数据库图层"的流程。所以第一步永远是问清楚:这东西是怎么存、怎么给我的。
我在实战里总结了一个判断顺序,你可以照着走:
- 看到文件夹里有一堆同名不同后缀的文件(.shp/.shx/.dbf/.prj),这是Shapefile,属于矢量格式,注意这几个文件必须放在一起,少一个都打不开;
- 看到单个文件后缀是.gpkg,这是GeoPackage,一个文件里可以装多个图层和多个表,是目前推荐的矢量存储格式;
- 看到后缀是.geojson或.json,这是GeoJSON,文本格式,可读性好,适合网页和轻量交换;
- 看到后缀是.tif或.tiff,这是GeoTIFF,属于栅格影像,通常带地理坐标信息;
- 看到后缀是.csv但里面有经纬度列,这是文本坐标数据,需要按"分隔文本图层"的方式导入,而不是直接当表格打开。
2.2 矢量数据、栅格数据,加进来的方式不一样
Qgis把数据分成两大阵营:矢量(点、线、面)和栅格(像素网格)。这两类在"图层"菜单下有不同的入口,别试图用一个按钮全搞定。
矢量数据的添加路径是"图层 → 添加图层 → 添加矢量图层",快捷键是Ctrl+Shift+V。选中文件之后它会问你要不要指定坐标系,如果文件自带坐标系信息(比如shp的.prj文件),它会自动识别,你直接确认就行;如果没有,那就得手动选,这一步非常关键,选错了后面的坐标全是歪的。
栅格数据的添加路径是"图层 → 添加图层 → 添加栅格图层",快捷键Ctrl+Shift+R。像我们案例里的卫星影像,就属于这一类。栅格数据的坐标系同样重要,而且有个常见坑:有些影像的坐标信息写在附属的tfw文件或者xml里,如果只把.tif拷出来丢给Qgis,它会显示"未知坐标系",你得把附属文件一起带上。
数据库和服务类型的图层,统一在"图层 → 添加图层"菜单里能找到对应入口,比如PostGIS数据库、WMS/WMTS网络地图服务等。这部分新手可以先跳过,等有实际需求再研究。
2.3 踩坑记录:那个"图层加载了但空白"的夜晚
我印象很深的一次,有个同事发来一个shp,我拖进去之后图层面板里确实多了一行,但地图窗口一片空白。当时第一反应是软件卡了,重启、重装、换电脑都没用。后来才发现问题出在坐标系上:这份数据的坐标数值是经纬度(大概在100到120之间),但系统默认把项目坐标系设成了某种投影坐标系(数值级别在几十万到几百万),Qgis按项目坐标系去解释那份经纬度数据,结果数据被"放"到了地图外很远的地方,自然什么都看不到。
排查这类问题的完整链路是这样的:先右键图层打开属性,看"信息"里显示的坐标系是什么;再看地图窗口底部状态栏显示的当前项目坐标系;两者不一致的时候,就会出问题。解决方式有两种,一种是临时把项目坐标系改成和数据一致的,另一种是保持项目坐标系不变,给图层做一次坐标转换(右键图层 → 导出 → 另存为,在对话框里指定目标坐标系)。
提示:判断一个图层是不是"跑偏"了,有个特别简单的方法——全选所有图层后按键盘上的快捷键缩放到图层范围,如果缩放到某个图层时地图跑到了世界地图的角落,基本就是坐标系问题,不用怀疑别的。
还有一种"空白"是另一种原因造成的:图层本身有数据,但被别的图层完全盖住了。这时候图层面板的顺序就是关键,上面的图层会覆盖下面的图层,把可疑图层往上层拖一下就好。
3. 数据格式转换:什么时候需要转,怎么转才不丢东西
3.1 转换的动机:不是为了转,而是为了解决具体问题
我见过不少新手一上来就把手里的shp转成GeoJSON,问他为什么,答"听说GeoJSON更好"。这是典型的没有目标的转换。格式转换只在有明确需求时才做,常见的真实需求有这么几类:
第一类是字段名长度限制。Shapefile格式的字段名最长只能10个字符,中文属性字段转过去会变成乱码或者被截断,如果你要做属性统计,就得换成GeoPackage或者GeoJSON这类对字段名友好的格式。第二类是文件体积和传输,shp是一堆文件打包,发给别人容易漏,GeoPackage只有一个文件,传输和归档都更省事。第三类是字段类型限制,shp的文本字段有长度上限,超过254个字符的内容会被截断,这种数据必须换格式存。第四类是跨软件兼容,某些网页地图或前端库只认GeoJSON。
所以每次转换前,先问自己一句:我转完之后要拿它干什么?答案会决定你选哪种目标格式。
3.2 用Qgis做转换的标准操作流程
转换功能藏在"导出"里,不是在"保存"里,这是新手最常找错的地方。右键图层 → 导出 → 要素另存为(矢量)或者另存为(栅格),弹出的对话框是整个转换流程的核心。
对话框里有几个字段必须认真填:
- 格式:下拉选择目标格式,矢量可选GeoPackage、GeoJSON、ESRI Shapefile等,栅格可选GeoTIFF、PNG等;
- 文件名:点右边的浏览按钮选路径,注意GeoPackage要指定一个.gpkg文件,如果这个文件已存在,Qgis会把图层追加进去而不是覆盖,这点很实用;
- 图层名:GeoPackage和数据库类格式需要单独填图层名,shp和GeoJSON不需要;
- 坐标系:默认是"图层坐标系",如果要换坐标系就在这里选目标CRS;
- 编码:这个字段容易被忽略,中文数据建议显式指定UTF-8,否则属性表里的中文可能是问号;
- 选择的要素:如果图层里只选中了一部分要素,勾选"仅保存选中的要素"可以只导出选中部分。
填完之后点确定,会看到右下角有个进度条,完成后新图层会直接加载到图层面板里。我一般会顺手把原图层关掉,对比一下新旧图层的位置、属性是否一致。
3.3 转换后必须做的三项验证
转换完不检查等于白转。我固定会做三件事:
- 属性表比对:打开新旧两个图层的属性表,看字段数量和行数是否一致,重点看中文字段有没有变成乱码。有一次我把shp转GeoPackage,发现某个字段的数值被四舍五入了一位小数,原因是原字段类型是文本但内容看起来像数字,转换时被自动推断成了整数,这种问题不看属性表根本发现不了。
- 几何比对:把两个图层叠在一起,把其中一个的填充色改成半透明或者干脆关掉填充只留边框,肉眼检查边界是否重合。如果出现整体偏移,就是坐标转换环节出了问题。
- 范围比对:右键图层看"信息"面板里的要素数量和范围坐标,两个图层的范围值应该完全一样,差一点都不行。
| 目标格式 | 适用场景 | 字段名限制 | 单文件 | 备注 |
|---|---|---|---|---|
| Shapefile | 传统软件兼容 | 10字符 | 否,一组文件 | 字段易截断,不推荐新项目用 |
| GeoPackage | 通用存储、多图层 | 无严格限制 | 是 | 当前推荐首选 |
| GeoJSON | 网页、轻量交换 | 无严格限制 | 是 | 体积偏大,坐标精度注意 |
| CSV | 表格分析 | 无严格限制 | 是 | 需要正确的经纬度列 |
4. 标注:让地图自己开口说话
4.1 标注的本质是"用属性字段驱动显示"
很多人第一次接触标注,以为是要在图上"画"字,其实Qgis的标注机制完全不同——它是让要素的属性字段内容自动显示在要素旁边。你不需要一个个去写,只要指定"用哪个字段作为标注内容",所有要素就会批量显示出来,而且要素移动了,标注跟着走。
在图层属性的"标注"选项卡里,把类型从"无标注"改成"单一标注",然后在下拉框里选择要显示的字段,比如县界数据就选"名称"字段,标注立刻出现。这是最快的方式,适合字段单一的情况。
但如果需求复杂一点,比如你想显示"某县(人口12万)"这种拼接形式,就得用表达式。点字段下拉框旁边的那个小图标,进入表达式编辑器,可以用字符串拼接函数把多个字段组合起来,格式大概是"字段1" || '(人口' || "字段2" || '万)'。表达式是Qgis标注功能里最有价值的部分,值得花时间熟悉。
4.2 中文标注乱码:一个几乎人人都会遇到的坑
我第一次做中文标注的时候,地图上显示的全是一个个方块。这不是Qgis的bug,而是字体问题。解决办法是在标注选项卡的"文本格式"里,把字体换成支持中文的字体,比如系统里的黑体、宋体、微软雅黑。默认字体有些是西文字体,没有中文字形,所以显示不出来。
还有个更隐蔽的情况:字体换了,但还是有部分字符显示不对,那可能是数据本身的编码问题。前面转换格式时如果没指定UTF-8,属性表里的中文可能已经损坏了,这种情况下要先回去修数据,标注环节怎么调都没用。
注意:换了中文字体之后,建议顺便检查一下字体大小和颜色的默认值,很多中文字体在小字号下笔画会糊在一起,地图缩小时完全看不清,适当调大一号会好很多。
4.3 标注的避让、优先级和缩小时隐藏
标注一多就会互相压叠,密密麻麻什么都看不清。Qgis提供了几个机制来处理这件事。
避让在标注选项卡的"放置"和"渲染"部分,可以设置标注与要素、标注与标注之间是否允许重叠。默认允许重叠,改成不允许之后,Qgis会尝试把标注挪开,挪不开的就自动隐藏。这个设置能大幅提升可读性,但也要注意计算量,要素特别多的时候会让渲染变慢。
优先级通过表达式或字段控制,重要要素的标注优先显示。原理是给每个要素一个优先级数值,Qgis在空间不足时优先保留高优先级的标注。比如省级名称的优先级高于县级,缩放状态下省名永远保留。
按比例尺控制显示是最实用的技巧。在标注选项卡的"渲染"里可以设一个最小比例尺,比如设定"小于1:50000时才显示",意思就是缩得很近才显示标注,缩远了自动隐藏。这样同一份数据在全局视图和局部视图下都能保持清爽。我做一个大范围的县界图时,就是靠这个把几百个标注分层控制的。
5. 符号化:同一份数据,做出完全不同的观感
5.1 从"单一符号"到"分类符号"的跨越
刚加进来的矢量图层默认是单一颜色,所有要素长得一模一样。符号化就是给要素按规则分配不同的样式。Qgis的符号化选项在图层属性的"符号化"选项卡里,默认是"单一符号",把所有要素画成一种样子。
切换到"分类"可以按某个属性字段的值分组着色。比如县界数据有"所属地市"字段,按这个字段分类,每个地市一套颜色,一眼就能看出行政区划归属。操作步骤是:符号化类型选"分类",值字段选"所属地市",点"分类"按钮让它自动读取所有唯一值,然后选一个配色方案,点应用。
分类模式有个细节要注意:颜色数量由唯一值数量决定,字段里如果有几十个唯一值,颜色会多到看不出区别,这时候要么换用渐变色方案,要么合并成几个大类再分类。我见过有人按"村名"字段分类,结果生成了几百种颜色,图上一片花,完全没有表达力。
5.2 分级符号:数值字段的正确打开方式
如果字段是数值型的,比如人口、面积,用"分类"就不合适了,应该用"分级"。分级的核心是把连续的数值切成几个区间,每个区间一个颜色或一个符号大小。
Qgis提供几种分级模式,我常用的两种:
- 等间距:数值范围平均切成若干份。优点是简单直观,缺点是如果数据分布不均,会出现某些区间挤满要素、某些区间空无一物的情况。
- 分位数:每个区间的要素数量尽量相等。优点是每个级别都有内容,视觉上分布匀称,缺点是不了解统计背景的人容易误读区间含义。
选哪种取决于你的表达目的。要突出"极端值"就用等间距,要让每个级别都有代表性就用分位数。模式选好后设置级别数(一般5到7级比较合适),点"分类"生成区间,再选配色。配色方案建议选单色渐变而不是彩虹色,彩虹色的中间色容易让人误解为特殊含义,单色深浅渐变最符合人的数值直觉。
5.3 点、线、面的符号细节调整
面的符号可以调填充色、填充样式(实心、斜线、网格)、轮廓线颜色和宽度。轮廓宽度别设太粗,超过1毫米在大范围图上会让相邻区域糊成一片。轮廓颜色建议比填充色深一到两个色阶,形成层次但不割裂。
线的符号核心是宽度和线型。主干道用粗实线,次要道路用细实线或虚线,这是基本约定。Qgis里可以给线加"偏移"效果做出双线道路的感觉,也可以用符号图层叠加,比如底层粗浅色加顶层细深色,做出有立体感的道路。
点的符号除了圆形,Qgis内置了大量形状,还支持用svg图标。做POI点位图时,用不同的svg图标(医院、学校、加油站)比用不同颜色的圆点传达信息更直接。图标可以在符号选择器里从svg目录里挑,也可以自己导入外部的svg文件。
6. 从零到成图:一个完整流程串起来
6.1 操作顺序为什么不能乱
把前面几节串起来,一个合理的顺序是:先添加数据源 → 确认坐标系一致 → 需要的话转换格式 → 设置标注 → 做符号化 → 最后出图。这个顺序有它的道理:标注和符号化都依赖属性字段,如果格式转换在标注之后做,字段名可能变化,前面设好的标注表达式全部失效,得重来。
我踩过一次这个坑:辛辛苦苦把标注表达式写好了,结果发现原数据是shp,字段名被截断成了拼音缩写,为了让中文正常显示不得不转成GeoPackage,转完之后字段名变了,标注全丢。从那以后我的习惯是先把格式定下来,再动标注和符号化。
6.2 项目文件、样式保存与出图前的检查
Qgis的项目文件后缀是.qgz,它记录的是"图层引用了哪些文件、用了什么样式、项目坐标系是什么",不包含数据本身。所以项目文件拷给别人时,数据文件也要一起给,并且相对路径要保持一致,否则对方打开会看到一堆红叉。我习惯把项目和所有数据放在同一个文件夹里,用相对路径引用,这样整个文件夹拷走就能直接打开。
样式可以单独保存和加载。在图层属性对话框底部有"样式"菜单,可以保存成.qml文件或者存入数据库风格库,下次同样的数据直接加载样式,不用重设。做批量出图的时候这个功能能省下大量时间。
出图前我会固定检查这几项:坐标系是否正确、标注是否遮挡、配色在灰度打印下是否还能区分(重要!很多人忽略了黑白打印场景)、图例是否完整、比例尺和指北针是否加上。Qgis的"新建打印布局"功能就是干这个的,把地图、图例、比例尺拖进布局,导出成PDF或图片。
6.3 几个我用了很多年才形成习惯的小技巧
第一个,养成随手保存项目的习惯,Qgis偶尔会因为插件崩溃,未保存的工作可能丢失。
第二个,图层命名要规范。默认图层名往往是文件名,一堆数字和英文缩写,图层面板里找起来很痛苦。右键重命名,改成"县界_2024"这种一眼能懂的名字。
第三个,善用"过滤"功能。图层属性里的过滤条件可以直接写表达式筛选要素,比每次都做一遍导出要快得多,而且不影响原数据。
第四个,遇到插件装不上或者界面语言混乱,先看版本。Qgis的插件生态在不同版本间差异很大,LTR版本的插件最稳定。装插件在"插件 → 管理并安装插件"里操作,装完记得在插件菜单里启用。
7. 新手最容易卡住的几个问题
7.1 "数据加载了但不显示"的三种典型原因
这个问题的排查顺序我前面提过一次,这里再系统化一遍,因为它出现频率太高了。
第一种是坐标系不匹配,数据和项目的坐标系级别差太远,要素被放到了视图之外。解决方式是统一坐标系,或者对图层做坐标转换。
第二种是图层被覆盖,特别是面图层叠在一起的时候,上层不透明就会把下层完全遮住。解决方式是调整图层顺序或者降低上层透明度。
第三种是数据本身有问题,比如几何为空、坐标是无效值。可以在属性表里看要素数量,如果要素数量正常但一个都看不到,可以尝试"缩放到图层"来判断是不是几何损坏。几何损坏的数据可以用"处理工具箱"里的修复几何功能处理。
7.2 中文乱码的两种来源要分清
一种是显示乱码,数据本身是好的,只是标注字体不支持中文,换字体即可。另一种是数据乱码,转换格式时编码没选对,属性表里本身就是问号,这时候换什么字体都没用,必须回到数据源头重新转换,编码指定UTF-8。
判断方法很简单:打开属性表看字段内容,如果属性表里是好的但地图上是乱的,就是字体问题;如果属性表里就是乱的,就是数据问题。这个判断顺序能帮你省下大量瞎折腾的时间。
7.3 属性表编辑后地图没更新
Qgis的属性表编辑需要先进入编辑模式(属性表工具栏上的铅笔图标),改完之后要点击保存(软盘图标)才会真正写入。改完没保存,地图上的标注自然不会变,而且切换图层后改动还会丢失。这个设计是为了防止误操作,刚上手的人经常忘记点保存。
7.4 影像加载慢或者显示成灰白
栅格影像加载慢通常是分辨率太高或者文件太大。可以在图层属性的"金字塔"选项卡里构建金字塔,构建后缩放浏览会快很多。显示成灰白一般是波段拉伸设置的问题,在"符号化"里调整最小最大值或者选一个合适的拉伸方式,影像的对比度就会回来。这个现象在遥感影像上特别常见,原始数据是16位的高动态范围,直接显示会灰蒙蒙一片,拉伸之后细节才出得来。
说到底,Qgis的入门过程就是把数据源、格式、标注、符号化这四件事各自走通一遍,然后组合起来用。我个人的体会是,别怕出错,坐标系歪了、标注糊了、颜色丑了,改就是了,每修一次对工具的理解就深一层。真正卡人的从来不是软件功能本身,而是遇到问题时不知道从哪个环节开始查。把上面这些排查顺序记在心里,大部分问题你都能自己定位。