Kaba çizgi çizmek için bir QGIS işlevi veya eklentisi var mı?
Spline Tool'u bazı dalgaları elle çizmek için kullandım, ancak zaman alıyor. Mümkünse, şöyle bir şey çizmek istiyorum:
Inkscape Function Plotter
( sin(x)
eğri).
Kaba çizgi çizmek için bir QGIS işlevi veya eklentisi var mı?
Spline Tool'u bazı dalgaları elle çizmek için kullandım, ancak zaman alıyor. Mümkünse, şöyle bir şey çizmek istiyorum:
Inkscape Function Plotter
( sin(x)
eğri).
Yanıtlar:
PyQGIS kullanarak bir çözüm öneriyorum. Hem Linestring hem de MultiLineString katmanları için çalışmalıdır.
Bu çözüm yarım daire halkaların oluşturulmasına dayanmaktadır, bu nedenle çap için bir değer belirlemeniz gerekir (örn step
. Aşağıdaki koddaki değişken). Seçtiğiniz adım, kullanılan gerçek adım olmayacaktır, çünkü satır uzunluğuna göre ayarlanır (ancak başlangıçta ayarlanan değere gerçekten benzerdir). step
Değişken için en iyi değeri bulmadan önce bazı denemeler yapmanız gerekir .
Kod ayrıca crv_angle
, halkaların eğriliğini azaltmaya veya arttırmaya yardımcı olan ikinci bir (isteğe bağlı) parametre gerektirir ( bunun için birkaç test yaptım, bu nedenle gerçek dairesel oluşacağından 45 dereceyi varsayılan açı olarak bırakmanızı öneririm) halkalar).
Bu kodu yalnızca Python Konsolundan çalıştırmanız gerekir:
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)
ve beklenen sonuç ile yeni bir satır bellek katmanı yaratacaktır:
Kısa cevap: Özel bir SVG kullanarak elde edebilirsiniz. Biri için bu yazının altına bakın.
Uzun cevap:
Bunu temsil etmenin çizgi geometrisini değiştirmekten daha iyi olduğuna inanıyorum. Bir kenarı hareket ettirmek veya geometri üzerinde başka bir işlem yapmak istiyorsanız, kıpırdatmanın sadece düz bir çizginin temsili yerine geometrinin bir parçası olup olmadığını idare etmek kabus olurdu.
Stil işaretleyici çizgisiyle oynayabilirsiniz. İhtiyacınız olan şeylere kolayca yaklaşmanın bir yolu var ve biraz daha fazla çaba ile tam olarak onu elde etmeniz mümkün.
Bunu elde etmek için çizgiyi iki Marker çizgisi ile stillendirirsiniz. Her Marker çizgisi, yarım daireli bir Basit Marker'den yapılmıştır. Birincisi 180 derece döndürülür. Her ikisi de saydam olarak ayarlanır.
İşaretçi satırında, bir tanesine ofset yapılmasını söylersiniz, böylece iki sembol birbirinin önüne değil, yan yana çizilir. En kapalı = 1/2 * aralık boyutu kullanırsanız, çıktı sinüzoidal bir eğri olur. Aralık, ofset ve sembol boyutlarıyla oynamanızı öneririm.
Bu yaklaşımla ilgili ana sınırlama, yarım dairenin çap çizgisidir ve orijinal çizgiyi oluşturur. Arka planınız beyazsa (veya herhangi bir düz renkte), arka plan rengini kullanarak 3. basit bir çizgi ekleyebilirsiniz.
** EDIT **
Orta çizgiden kurtulmak için başka bir seçenek yeni bir SVG sembolü oluşturmaktır. Yarım eğriyi değiştirdim, sadece yuvarlak kısmı yaşadım. 1/2 elips daha çekici olsa da işe yarıyor. Ekran görüntüsü, sembol boyutu 10, aralık 4, ofset 2 kullanılarak yapıldı.
aşağıdaki kodu half_circle_line.svg dosyasına kaydedin ve svg yolunun içinde ayarlandığından emin olun. 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
e değiştirebilirsiniz :)