มีฟังก์ชั่นหรือปลั๊กอิน QGIS เพื่อวาดเส้น wiggly หรือไม่?
ฉันใช้เครื่องมือ Spline เพื่อวาดคลื่นด้วยตนเอง แต่ใช้เวลานาน ถ้าเป็นไปได้ฉันต้องการวาดสิ่งที่ชอบ:
Inkscape Function Plotter
( sin(x)
เส้นโค้ง)
มีฟังก์ชั่นหรือปลั๊กอิน QGIS เพื่อวาดเส้น wiggly หรือไม่?
ฉันใช้เครื่องมือ Spline เพื่อวาดคลื่นด้วยตนเอง แต่ใช้เวลานาน ถ้าเป็นไปได้ฉันต้องการวาดสิ่งที่ชอบ:
Inkscape Function Plotter
( sin(x)
เส้นโค้ง)
คำตอบ:
ฉันเสนอวิธีแก้ปัญหาโดยใช้ PyQGIS ควรทำงานได้ทั้งกับเลเยอร์ Linestring และ MultiLineString
วิธีการแก้ปัญหานี้ขึ้นอยู่กับการสร้างวงแหวนแบบวงกลมดังนั้นคุณต้องตั้งค่าสำหรับเส้นผ่านศูนย์กลาง (เช่นstep
ตัวแปรในรหัสด้านล่าง) ขั้นตอนที่คุณเลือกจะไม่เป็นขั้นตอนจริงเพราะจะถูกปรับตามความยาวบรรทัด (แต่จะคล้ายกับค่าที่ตั้งไว้ในตอนแรก) คุณต้องพยายามก่อนที่จะหาค่าที่ดีที่สุดสำหรับstep
ตัวแปร
รหัสยังต้องใช้พารามิเตอร์ตัวที่สอง (เรียกว่าcrv_angle
) ซึ่งช่วยลดหรือเพิ่มความโค้งของวงแหวน (ฉันทำการทดสอบสองสามครั้งดังนั้นฉันขอแนะนำให้ปล่อย 45 องศาเป็นมุมเริ่มต้นเนื่องจากมันจะนำไปสู่วงกลมจริง แหวน)
คุณจะต้องเรียกใช้รหัสนี้จาก Python Console เท่านั้น:
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
ไปไม่มีปากกา :)