Answers:
似乎没有办法仅将线符号表示为锯齿形:不幸的是,您必须更改基础数据。
通过先将原始线分成许多等距的线段,然后将每隔一个点偏移固定的量,可以得到一个相当好的之字形线。
这是执行此操作的Python脚本,它采用了NathanW的答案:如何在QGIS中沿折线创建随机点?作为起点。将代码块保存到目录(或Windows)中称为的文件zigzag.py
中,然后通过键入将其导入QGIS Python控制台中。然后,您可以选择要进行锯齿形调整的一条或多条线,然后在QGIS Python控制台中键入,其中和分别是以地图单位表示的锯齿形线段的“长度”和“宽度”。~/.qgis/python
{User Directory}\.qgis\python\
import zigzag
zigzag.createZigzag(<wavelength>, <amplitude>)
<wavelength>
<amplitude>
这是一个例子:
如您所见,锯齿形线在原始线条的拐角处不是很好,但是至少锯齿形线没有任何中断。
如果您使用詹姆士·康克林(James Conkling)的建议,首先使用柴肯(Chaiken)算法对直线进行平滑处理,则结果会更好:
这是脚本:
from qgis.utils import iface
from qgis.core import *
import numpy as np
from cmath import rect, phase
# Function for calculating the mean of two angles.
# Based on http://rosettacode.org/wiki/Averages/Mean_angle#Python
def meanAngle(a1, a2):
return phase((rect(1, a1) + rect(1, a2)) / 2.0)
def createZigzag(wavelength, amplitude):
# Create a new memory layer to store the zigzag line.
vl = QgsVectorLayer("LineString", "Zigzag", "memory")
pr = vl.dataProvider()
# For each selected object in the current layer
layer = iface.mapCanvas().currentLayer()
for feature in layer.selectedFeatures():
geom = feature.geometry()
# Number of zigzag segments
length = geom.length()
segments = np.round(length / wavelength)
# Find equally spaced points that approximate the line
points = [geom.interpolate(distance).asPoint() for
distance in np.linspace(0, length, segments)]
# Calculate the azimuths of the approximating line segments
azimuths = np.radians(
[points[i].azimuth(points[i + 1]) for i in range(len(points) - 1)])
# Average consecutive azimuths and rotate 90 deg counterclockwise
zigzagazimuths = [azimuths[0] - np.pi / 2]
zigzagazimuths.extend([meanAngle(azimuths[i],
azimuths[i - 1]) - np.pi / 2 for i in range(len(points) - 1)]
)
zigzagazimuths.append(azimuths[-1] - np.pi / 2)
# Offset the points along the zigzagazimuths
zigzagpoints = []
for i in range(len(points)):
# Alternate the sign
dst = amplitude * (1 - 2 * np.mod(i, 2))
zigzagpoints.append(
QgsPoint(points[i][0] + np.sin(zigzagazimuths[i]) * dst,
points[i][1] + np.cos(zigzagazimuths[i]) * dst
)
)
# Create new feature from the list of zigzag points
fet = QgsFeature()
fet.setGeometry(QgsGeometry.fromPolyline(zigzagpoints))
pr.addFeatures([fet])
vl.updateExtents()
QgsMapLayerRegistry.instance().addMapLayer(vl)
我以前曾尝试过这样做,但运气不太好。
qGIS根据一个参考点(尽管可以将其设置为上/中/下x左/中/右)将重复的符号放置在一条线上,并根据该线的斜率旋转该符号那一点。在一条直线上,斜率不会从一个符号位置变化到下一个符号位置,每个符号将与前一个符号完美对齐。但是,在曲线上,一个符号上的任何点都不会完美匹配下一个符号上的对应点。
因此,如果红线本身就是线,则沿该线重复符号会导致沿曲线外部的符号之间出现间隙,并在曲线内部重叠。
为了完全消除间隙和重叠,每个符号正方形都需要重塑为大小不同的菱形,这类似于将拱上的石头倒角以匹配曲线的方式。据我所知,不可能模拟这样的东西。但是,您可以通过使线的几何形状致密和平滑化来减少变形,以使角度的变化不太极端。该泛化插件可以与帮助(请尝试使用制作柴肯算法)。
另外,将符号分成较小的段并连续放置,这样可以再次减小每个后续标记之间的角度。例如,将V
符号分解为a \
和a /
,将它们同时加载到标记线上,并分别将x偏移设置为其宽度的一半,一个为正,另一个为负。
最后,稍粗的带有圆形末端的符号笔划将有助于掩盖轻微的失真。
这仍然是一个小技巧-很想听听其他人是否有更可靠的方法。
另一种想法:由于符号沿曲线的旋转而引起的从一个符号到另一个符号的不对齐在符号的顶部/底部最大,而在中间则不明显。因此,与在顶部/底部开始/终止的模式相比,在符号中心开始和终止的模式将具有较小的间隙。例如
...仍然是黑客-仍然不是万无一失