是否有QGIS功能或插件来画一条摇摆的线?
我已经使用样条工具手动绘制了一些波形,但是这很耗时。如果可能的话,我想画些类似的东西:
Inkscape Function Plotter
(sin(x)
曲线)。
是否有QGIS功能或插件来画一条摇摆的线?
我已经使用样条工具手动绘制了一些波形,但是这很耗时。如果可能的话,我想画些类似的东西:
Inkscape Function Plotter
(sin(x)
曲线)。
Answers:
我提出了使用PyQGIS的解决方案。它应同时适用于Linestring和MultiLineString图层。
该解决方案基于半圆形环的创建,因此您需要为直径设置一个值(即step
下面代码中的变量)。您选择的步骤将不是实际使用的步骤,因为它是根据行长进行调整的(但实际上与初始设置的值相似)。您需要进行一些尝试,然后才能找到step
变量的最佳值。
该代码还需要第二个(可选)参数(称为crv_angle
),该参数有助于减小或增加圆环的曲率(我对其进行了一些测试,因此建议保留45度作为默认角度,因为它会导致形成实圆戒指)。
您只需要从Python控制台运行以下代码:
from math import sin, cos, radians
step = 3 # choose the proper value (e.g. meters or degrees) with reference to the CRS used
crv_angle = 45 # degrees
def segment(polyline):
for x in range(0, len(polyline) - 1):
first_point = polyline[x]
second_point = polyline[x +1]
seg = QgsGeometry.fromPolyline([first_point, second_point])
tmp_azim = first_point.azimuth(second_point)
len_feat = seg.length()
parts = int(len_feat/step)
real_step = len_feat/parts # this is the real step applied
points = []
current = 0
up = True
while current < len_feat:
if up:
round_angle = radians(90 - (tmp_azim - crv_angle))
up = False
else:
round_angle = radians(90 - (tmp_azim + crv_angle))
up = True
first = seg.interpolate(current)
coord_x, coord_y = (first.asPoint().x(), first.asPoint().y())
p1=QgsPointV2(coord_x, coord_y)
dist_x, dist_y = ((real_step*sin(rad_crv_angle))* cos(round_angle), (real_step*sin(rad_crv_angle)) * sin(round_angle))
p2 = QgsPointV2(coord_x + dist_x, coord_y + dist_y)
points.extend([p1, p2])
current += real_step
second = seg.interpolate(current + real_step)
p3=QgsPointV2(second.asPoint().x(), second.asPoint().y())
points.append(p3)
circularRing = QgsCircularStringV2()
circularRing.setPoints(points) # set points for circular rings
fet = QgsFeature()
fet.setGeometry(QgsGeometry(circularRing))
prov.addFeatures([fet])
layer = iface.activeLayer() # load the input layer as you want
crs = layer.crs().toWkt()
rad_crv_angle = radians(crv_angle)
# Create the output layer
outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'wiggly_line' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields()
prov.addAttributes(fields)
outLayer.updateFields()
for feat in layer.getFeatures():
geom = feat.geometry()
polyline = geom.asPolyline()
segment(polyline)
# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)
它将创建一个具有预期结果的新行存储层:
简短的答案:您可以使用自定义SVG来获取它。请参阅这篇文章的底部。
长答案:
我认为代表它比修改线的几何形状更好。如果要移动边缘或对几何图形执行其他操作,管理摆动是否是几何图形的一部分而不只是直线的表示将是一场噩梦。
您可以使用样式标记线。有一种方法可以轻松地接近您所需要的内容,而稍加努力,就有可能准确地得到它。
为此,您可以使用两条标记线设置线条样式。每条标记线均由一个简单标记(半圆)组成。第一个旋转180。两者都设置为透明。
在“标记”行上,指示其中之一要偏移,这样两个符号不会彼此并排绘制,而是并排绘制。如果使用offest = 1/2 *间隔大小,则输出将是正弦曲线。我建议您使用间隔大小,偏移量和符号大小。
这种方法的主要局限性是半圆的直径线,其总和为原始线。如果您的背景是白色(或任何纯色),则可以使用背景色添加第3条简单线。
** 编辑 **
摆脱中心线的另一种方法是创建一个新的SVG符号。我修改了半曲线,只保留了圆形部分。它可以工作,尽管1/2椭圆可能更有吸引力。屏幕截图使用符号大小10(间隔4,偏移2)完成。
将下面的代码保存在文件half_circle_line.svg中,并确保将svg的路径设置为 QGIS // Settings / Options / System / SVG Paths
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="11.2889mm" height="11.2889mm"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.2" baseProfile="tiny">
<title>Qt Svg Document</title>
<desc>Generated with Qt</desc>
<defs>
</defs>
<g fill="none" stroke="black" stroke-width="1" fill-rule="evenodd" stroke-linecap="square" stroke-linejoin="bevel" >
<g fill="#ffffff" fill-opacity="0" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M19.1181,16 C19.1181,16 19.1181,14.2779 17.7221,12.8819 16,12.8819 C14.2779,12.8819 12.8819,14.2779 12.8819,16"/>
</g>
</g>
</svg>
Pen style
为No Pen :)