วิธีเพิ่มตารางเส้นทางและระยะทางไปยังแอตทริบิวต์


18

ใครก็ตามที่สามารถช่วยได้ ฉันแค่ต้องการเพิ่มทิศทาง (แบริ่ง: เช่น N 25 35 E) และระยะทาง (ความยาว: 125 เมตร) เป็นสนามใหม่ของฉันในข้อมูลโพลีไลน์ / สาย มีปลั๊กอินในการสร้างเขตข้อมูลเหล่านี้หรือไม่ ฉันพยายามใช้ "ส่งออก / เพิ่มคอลัมน์รูปทรงเรขาคณิต" ในข้อมูลบรรทัดของฉัน แต่เพิ่มเฉพาะค่า "ความยาว" เท่านั้น


จนถึงตอนนี้ฉันสามารถใช้ปลั๊กอิน mmqgis เพื่อให้ระยะทางกับฉันได้ กำลังสำรวจปัญหาเกี่ยวกับทิศทาง
Willy

1
ข้อมูล polyline ของคุณมีลักษณะอย่างไร ระยะทางนั้นค่อนข้างง่ายในการคำนวณอย่างไรก็ตาม 'การแบก' อาจเปลี่ยนไปตามความยาวของโพลีไลน์ คุณกำลังมองหาแบริ่งจากจุดเริ่มต้นถึงจุดสิ้นสุด ?
Simbamangu

ใช่ฉันกำลังมองหาการแบกจากจุดเริ่มต้นถึงจุดสิ้นสุด ... ขอบคุณ
arzandia

1
คุณต้องการให้ระยะทางตรงจากจุดเริ่มต้นไปยังจุดสิ้นสุดหรือความยาวของเส้นตามเส้นทางของเส้นหรือไม่? สิ่งเหล่านี้อาจแตกต่างกันอย่างกว้างขวางหากส่วนของเส้นตรงมีเส้นโค้งกลางหรือการเปลี่ยนแปลงทิศทางอื่น ๆ
RyanKDalton-OffTheGridMaps

คำตอบ:


42

คุณสามารถคำนวณการแบกใน Field Calculator ใน QGIS สิ่งนี้ใช้งานได้ในพิกัด UTM (ตัวชี้วัด) ในระยะทางเล็ก ๆ (หลายร้อยกม.) แต่สิ่งที่ซับซ้อนกว่านี้จะจำเป็นสำหรับระยะทางขนาดใหญ่หรือองศาทศนิยม

เปิดตารางแอตทริบิวต์สำหรับเลเยอร์บรรทัดของคุณสลับการแก้ไขและคลิกปุ่ม Field Calculator เพื่อเปิดกล่องโต้ตอบ:

ป้อนคำอธิบายรูปภาพที่นี่

สร้างเขตข้อมูลใหม่เป็นทศนิยมด้วยความแม่นยำ 1 หรือ 2

วางรหัสนี้ลงในกล่อง "Expression" และคลิก "ตกลง": (atan((xat(-1)-xat(0))/(yat(-1)-yat(0)))) * 180/3.14159 + (180 *(((yat(-1)-yat(0)) < 0) + (((xat(-1)-xat(0)) < 0 AND (yat(-1) - yat(0)) >0)*2)))

ส่วนแรกจะคำนวณแทนเจนต์ผกผันของความแตกต่างของ x และ y และแปลงเป็นองศา (180 / pi) ส่วนที่สองจะเพิ่ม 180 หรือ 360 ลงในผลลัพธ์ที่ได้เพื่อให้ได้แบริ่งตั้งแต่ 0-360 °


2
คำตอบที่สง่างามที่สุดขอบคุณ ฉันจะพูดถึงว่าถ้าคุณต้องการกำหนดตลับลูกปืนสำหรับแต่ละส่วนของโพลีไลน์คุณสามารถทำได้โดยการแยกไฟล์ shapefile ด้วยปลั๊กอิน 'คุณสมบัติแยก' จากนั้นโหลดรูปร่างไฟล์ (แยก) ใหม่และทำตามขั้นตอนด้านบน
nhopton

1
@arzandia - โปรดทราบว่าคุณต้องใช้QGIS 1.9 (ดูหน้าแรกสำหรับการดาวน์โหลดเบต้า) เป็นฟังก์ชัน xat () และ yat () ไม่ทำงานใน 1.7 ซึ่งคุณใช้อยู่!
Simbamangu

ฉันใช้ปลั๊กอินที่คุณพูดถึงไปแล้ว อย่างที่คุณเห็นภาพชื่อของเลเยอร์คือ "splitted" ...
arzandia

1
เพื่อตอบคำถามของฉันเอง "ใช่คุณสามารถแทรกค่าฟิลด์สำหรับ yat (0) / yat (-1) และ xat (0) / xat (-1)"
cbunn

1
สำหรับฉันฉันต้องทำการเปลี่ยนแปลงบางอย่างกับสคริปต์เพื่อให้มันทำงาน: (atan ((xat (0) -xat (1)) / (yat (0) -yat (1)))) * 180 / 3.14159 + (180 * (((yat (0) -yat (1)) <0) + ((xat (0) -xat (1)) <0 AND (yat (0) - yat (1))> 0) * 2)))
oskarlin

21

คุณไม่จำเป็นต้องมีปลั๊กอิน ทุกอย่างอยู่ในระดับ QgsPoint ของ PyQGIS

หากคุณตรวจสอบเนื้อหาของคลาสจุด QGIS ด้วยฟังก์ชัน Python ในตัว Python () ใน Python Console

dir(point])
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__'
, '__getitem__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'azimuth', 
'multiply', 'set', 'setX', 'setY', 'sqrDist', 'sqrDistToSegment', 'toDegreesMinutesSeconds', 'toString', 'wellKnownText', 'x', 'y']

คุณสามารถเห็นว่ามีฟังก์ชั่นazimuthและsqrDistและหลังจากพยายามสองสามครั้ง:

- xy[0].azimuth(xy[1]) or xy[1].azimuth(xy[0]) gives the azimuth direction between two points(in degrees, +/- 180°)
- xy[0].sqrDist(xy[1]) give the square distance between two points (in the unit of the project)

ปัญหา ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นในคอนโซล Python

def select_all(layer):
     layer.select([])
     layer.setSelectedFeatures([obj.id() for obj in layer])

myline = qgis.utils.iface.activeLayer()
select_all(myline)
for elem in myline.selectedFeatures():
      xy = elem.geometry().asPolyline()

ตอนนี้ xy มีโหนดทั้งหมด (จุด) ของบรรทัด

# first point
print "x=%2d y=%2d" % (xy[0].x(),xy[0].y())
x=112935 y=117784
# and others...

ใช้จุดโหนทั้งหมดของบรรทัด:

1) จุด azimuth i ไปยังจุด i + 1 (+/- 180 °) (โหนดของบรรทัด)

for i in range(len(xy)-1):
     print "x=%2d y=%2d azim=%6.1f azim2=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].azimuth(xy[i+1]), xy[i+1].azimuth(xy[i]))

x=112935 y=117784 azim= 168.4 azim2= -11.6
x=113032 y=117312 azim=-167.5 azim2=  12.5
x=112926 y=116835 azim= 177.3 azim2=  -2.7
x=112943 y=116472 azim= 145.1 azim2= -34.9
[...]

2) ระยะทางแบบยุคลิดระหว่างจุด i และจุด i + 1

for i in range(len(xy)-1):
     print "x=%2d y=%2d dist=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].sqrDist(xy[i+1]))

x=112935 y=117784 dist=232533.9
x=113032 y=117311 dist=238243.6
x=112926 y=116835 dist=131839.8
x=112943 y=116472 dist=209268.1
[...]

หลังจากนั้นไม่ยากที่จะเพิ่มค่าเหล่านี้ลงในตารางคุณลักษณะ

ฉันใช้เทคนิคนี้ในการวิเคราะห์ lineaments (ธรณีวิทยา) ด้วย matplotlib และปลั๊กอิน Script Runner

ป้อนคำอธิบายรูปภาพที่นี่


5
+1 - ทางออกที่ดี! ต้อง ... เรียนรู้ ... Python ...
Simbamangu

นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยมและมีค่ายิ่งสำหรับนักธรณีวิทยา .. แต่ก็ซับซ้อนเช่นกัน
Shawn

10

วิธีการแก้ปัญหาของ @Simbamangu นั้นค่อนข้างมีประสิทธิภาพ แต่ไม่ครอบคลุมในทุกกรณี ตัวอย่างเช่นการใช้สูตรที่มีการเปลี่ยนแนวนอนจะทำให้ผลลัพธ์เป็นโมฆะดังนั้นคุณต้องใช้สูตรนี้ใน Field Calculator ของ QGIS

case
when yat(-1)-yat(0) < 0 or yat(-1)-yat(0) > 0 then 
(atan((xat(-1)-xat(0))/(yat(-1)-yat(0)))) * 180/3.14159 + 
(180 *
(((yat(-1)-yat(0)) < 0) + 
(((xat(-1)-xat(0)) < 0 AND (yat(-1) - yat(0)) >0)*2)
))
when ((yat(-1)-yat(0)) = 0 and (xat(-1) - xat(0)) >0) then 90
when ((yat(-1)-yat(0)) = 0 and (xat(-1) - xat(0)) <0) then 270
end
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.