#1 楼
是的,可行。通常,我会建议使用部分透明的缓冲区,但是我明白了为什么要用制图法这样做。说来,这不是一件坏事!这是屏幕截图...
如您所见,没有缓冲区。下方的栅格不受影响。我包括了较细的中间轮廓线,并对它们进行了样式设置,以便仅当ELEV%50 <> 0
显示时才会显示它们...您的里程可能会因早期版本而异。
我假设您在每条轮廓线上都有一个“ ELEV”字段。
细分轮廓线
使用处理和GRASS算法v.split.length将轮廓分成等长的段。假设您使用的是米,则需要选择一个与地图单位的标签大小相近的长度。我在这里用了200m。
请小心,因为它会使文件大得多(请注意屏幕快照中的功能计数)。
要解决此问题,您可能只希望生成想要设置样式的轮廓线(例如,每50或100米),以避免处理所有中间轮廓线。
向此层添加一个称为showLabel的1位整数字段。默认为0或NULL。
将标签更改为仅显示在将该字段设置为1的段上。将其用于标签文本表达式...
我认为if(expression,true-value,false-value)相当新;如果使用的是较旧的版本,则可以使用CASE-ELSE
更改线条样式,以便绘制固定长度的线段,但显示标签的线段除外。因此,将基于规则的渲染与两个规则一起使用
if ( "showlabel" is not null, "ELEV", "")
现在,默认情况下将显示所有轮廓,但不显示标签。
手动编辑要显示标签的细分
进入编辑模式,然后手动选择要显示轮廓值的线段,然后将所选特征的
showLabel
值设置为1。您可以使用Ctrl +选择(在Ubuntu / Win上,Cmd + Ctrl +单击/在Mac上?)来多选段以加快处理速度。现在应该“剪切”轮廓想要标签显示,标签将显示在间隙中。在这种情况下,我的标签设置为:
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
< br希望有帮助!
评论
这是我能想到的唯一一个完全有效的解决方案。虽然有很多标签,但非常痛苦,我无法想象以这种方式绘制所有地下水位图(每年数千张)。如果将来可以通过样式实现,那就太好了-最好的办法是自定义线条图案和标签重复+偏移。
–米罗
2015年11月19日,0:02
简化任务的一些想法:若要选择多个线段绘制标签,可以方便地选择“按多边形选择”或“按徒手选择”。另外,另一个方法是创建一个草绘线图层以绘制截取轮廓的线,然后执行“按位置选择”。
–亚历山大·内托(Alexandre Neto)
16-2-3在23:22
#2 楼
我在“标签设置”选项卡上使用“缓冲区”选项。 (使用标签按钮,而不是图层属性对话框上的旧标签选项。)这并没有抹去轮廓线,正如我想像的那样,但这确实使标签清晰易懂。评论
我之前从没想过,但是如果不用为缓冲区分配颜色,而可以选择将其作为“淘汰赛”应用到选定的图层上,那将很方便。
– Scro
13年2月25日在22:01
最新版本的QGIS具有透明的缓冲区,因此您可以减少对地图其他部分的影响。
–内森·W
13年2月25日在22:59
@MAP剔除会删除其下方的像素。如果可以选择,在这种情况下,您将选择剔除轮廓层。
– Scro
13年2月26日在11:41
淘汰赛-esri术语是“掩盖”resources.arcgis.com/en/help/main/10.1/index.html#//…
– Mike
13年2月26日在19:47
@MAP-赞助开发人员,或提交功能请求并等待他人的仁慈。 :)
– Scro
13年2月27日在23:02
#3 楼
我认为,使用当前QGIS功能可以得到的最接近的结果是对表中使用的颜色使用光晕(或背景)效果,该颜色将基于与基础网格相同的高程值和颜色方案。当然,这不会考虑山体阴影和地图中光环下方的其他所有内容。随机颜色示例:通过一些代码,可以将其重写为反映网格颜色的函数。
从理论上讲,应该可以使用自定义线条图案和标签重复+偏移。不幸的是,没有标签偏移设置。
经过一些测试,不可能强制QGIS严格地将标签放置在精确的间隔中,并且没有其他地方(无论如何都缺少起始偏移量)。
无法创建自定义线条图案,其零毫米的空间具有起始偏移量,例如20行-10空间-70行-0空间-因此标签将每100mm放置一次,起始偏移为30mm-意味着标签将在每10mm的中间孔。
#4 楼
在为实现QGIS 3.10中的轮廓线的动态标记而进行的研究中,我将所有内容放到一个小的烹饪食谱中,并更改了原来的答案,与社区分享了发现的结果。以下是成分:这种情况,但我更喜欢“ GeoPackage”与QGIS项目一起存储数据。处理
一个名为“ scratch_lines”的“线串”层,没有任何其他字段,但在空间上进行了索引。我们使用这一层来创建与轮廓线相交以定义所有标签位置的“划痕”线。
使用两个项目层“ contours”和“ scratch_lines”在数据库管理器中定义了一个名为“ contours_with_labels”的虚拟层。
一个名为“ contourlabel_size”的QGIS项目变量包含了所有Map Units。
一个QGIS项目Python宏,用于定义用于检索当前画布范围的表达式函数,以及一些用于在项目重新加载期间刷新虚拟层的代码。
如果没有该代码,我们必须手动刷新虚拟层(即使用出色的插件“ changeDataSource”:右键单击层名称=>更改矢量数据源=>确定),如果我们要更改标签文本的大小。
from qgis.core import qgsfunction,QgsProject,QgsGeometry
from qgis.utils import iface
@qgsfunction(args='auto', group='Custom')
def currentExtent(feature, parent):
return QgsGeometry.fromRect(iface.mapCanvas().extent())
def openProject():
layer = QgsProject.instance().mapLayersByName('contours_with_labels')[0]
layer.reload()
layer.triggerRepaint()
动态创建所有轮廓标签是由在虚拟层的SQL查询中利用QGIS(GDAL)的SpatialLite功能:
------------------------------------------------------------------------
-- select all contour lines that do not intersect any scratch lines
------------------------------------------------------------------------
SELECT c.geometry,c.elev,0 as label
FROM contours c,
(SELECT ST_UNION(geometry) AS geom FROM scratch_lines
WHERE _search_frame_ = currentExtent()) AS scr
WHERE c._search_frame_ = currentExtent()
AND NOT ST_INTERSECTS(c.geometry,scr.geom)
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_difference between contour lines and buffers
-- and set attribute "label" to 0
--------------------------------------------------------------------------------------------------------
SELECT ST_DIFFERENCE(c.geometry,buf.geom) AS geom,c.elev,0 AS label
FROM contours c,
(SELECT c.fid,
ST_UNION(ST_BUFFER(ST_INTERSECTION(c.geometry,scr.geometry),
LENGTH(c.elev) * var('contourlabel_size') / 2.5)) AS geom
FROM contours c, scratch_lines scr
WHERE c._search_frame_ = currentExtent()
AND scr._search_frame_ = currentExtent()
AND st_intersects(c.geometry,scr.geometry)
GROUP BY c.fid) AS buf
WHERE c._search_frame_ = currentExtent()
AND c.fid = buf.fid
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_intersection between contour lines and buffers
-- and set attribute "label" to 1
--------------------------------------------------------------------------------------------------------
SELECT ST_INTERSECTION(c.geometry,ST_BUFFER(ST_INTERSECTION(c.geometry,scr.geometry),
LENGTH(c.elev) * var('contourlabel_size') / 2.5)) AS geom,
c.elev,
1 AS label
FROM contours c,
scratch_lines scr
WHERE c._search_frame_ = currentExtent()
AND scr._search_frame_ = currentExtent()
AND ST_INTERSECTS(c.geometry,scr.geometry)
虚拟层的样式基于两个规则:
规则1(“标签”-简单的线条,宽度= 0,颜色=完全透明):
contains(@map_extent,start_point($ geometry))
AND
contains(@map_extent,end_point($ geometry))
AND“ label” = 1
规则2(“轮廓”-几何生成器:smooth(simplify($ geometry,1),3)>简单线条:width = 0.5,color = black):
ELSE
虚拟层的标签配置(单个标签):
值:
CASE WHEN label = 1 THEN
CASE WHEN
contains( @map_extent ,start_point($geometry))
AND
contains( @map_extent ,end_point($geometry))
THEN elev ELSE ''
END
END
尺寸:
变量“ contourlabel_size”
放置:(平行,在线)
线串几何生成器
make_line(start_point($ geometry),end_point($ geometry))
就是这样!
希望它对任何人都有用,就像对我有用。可以通过在上坡方向绘制划痕线来强制所有轮廓标签的上坡方向:
评论
我必须说,结果给我留下了深刻的印象。在获得内置选项(如果有)之前,这绝对是最干净的方法。虚拟层再次解救。
–加百列C.
19年11月29日在19:37
我的确给我留下了深刻的印象。但是,它可以承受很大的轮廓层吗?
–christoph
19年11月29日在19:43
我很高兴,在测试之后,它也可以与GeoPackages中的数据一起使用!我想验证一下,因为它基于Spatialite。希望我可以投票一次以上...
–加百列C.
19年11月30日14:34
恕我直言,它独立于任何文件格式,因为查询是在QGIS中运行的。因此,它甚至应与CSV一起使用。
–christoph
19年11月30日在14:41
那很有趣。我建议在一切都说完之后,编辑您的原始答案以包括所有更新。
–加百列C.
19/12/2在18:55
#5 楼
最近遇到相同问题后,我整理了一个QGIS Python脚本来执行繁重的工作。该脚本包括一些(英国)测试数据,自述文件(指南)和所使用的样式表,可以在https中找到://github.com/pjgeng/Contour-Labels
简而言之,脚本使用两个矢量层作为输入-带注释的轮廓层和“指南”层。后者由在轮廓上与所需标签位置相交的折线组成。
然后脚本根据轮廓之间的距离和要应用标签的索引轮廓间隔来计算,为标签点添加旋转值
如果用户需要在同一区域以不同的间隔生成等高线图,则该方法特别有效。即指南不会改变)。缺点是脚本完成后无法更改标签位置。为此,用户将不得不调整指导线,并针对原始输入重新运行脚本。我以前在标签周围使用了很多缓冲区来创建中断效果,但是在矢量数据驱动的地图上这在美学上是令人不愉快的。
PS:如果使用存储库中提供的样式层,则用户可能需要“激活”“旋转”,“显示标签”和“始终显示”的自定义字段在标签菜单中。在某些QGIS安装中,这些是从样式表中自动应用的-我还没有找到导致这种情况的原因。
#6 楼
让我向像我这样对GRASS或Python脚本不够熟练的人分享我的自制方法: (例如50m,150m,250m等),您将其称为“中间轮廓”,另一层是您要标记的最重要线的新层(例如100m,200m,300m等) ,您将其称为“主要轮廓”。当然,您应该使用表达式设置为透明中间层中的主要轮廓。
如果轮廓文件很大,则可以通过取消所有中间线来减轻“主要轮廓”层功能,这将加快后续步骤。
为辅助线创建新的线文件,并在要显示标签的位置绘制垂直线(即与轮廓正交)。
将所有位于多边形内的轮廓段保存到一个新文件中,该文件将被称为“轮廓标签”。
将所有不在多边形内的轮廓段保存多边形放入名为“切割主轮廓”的新文件中
用透明线将“轮廓标签”文件与高程标签符号化
用粗线将“切割主轮廓”符号化等等,您有高程标签打断了主要轮廓线。请注意,根据您使用的字体,您可能需要使用两个不同的缓冲区(较大的缓冲区用于切出轮廓线,较窄的标签文件缓冲区),以使标签正确地位于行间隙的中心。 >
#7 楼
这似乎与在QGIS中将高程编号放置在具有上坡方向和位置的轮廓上有关吗?我能想到的解决问题的唯一方法就是用修剪的轮廓层覆盖轮廓层,使用它进行标记并将线条颜色更改为中性可以遮盖标签下的轮廓,希望不要太过分打扰。打破轮廓线也许是一个答案,也许使用用于裁剪轮廓的缓冲层。
评论
您会接受需要PostGIS的答案吗?不幸的是:否:)但是,有没有办法解决PostGIS的问题?