ใช้ pyshp เพื่อแปลงไฟล์. csv เป็น. shp หรือไม่


10

ฉันพยายามที่จะเข้าใจว่าฉันสามารถใช้โมดูล csv ใน python เพื่อเปิดไฟล์ csv ในโฟลเดอร์เดียวกับสคริปต์ python ได้อย่างไรจากนั้นสร้าง shapefile โดยใช้ shapefile module pyshp

ไฟล์ csv มีลักษณะเช่นนี้ แต่สามารถมีเรคคอร์ดสองสามพันแถว:

id_nr;date;target;start_lat;start_lon
1;2012-05-21;navpoint 25x;55.123654;13.456954
1;2012-05-23;navpoint 11f;55.143654;12.456954

คำตอบ:


14

โมดูล pyshp นั้นยุ่งยากเล็กน้อยในการทำให้เป็นเรื่องง่าย แต่ก็มีประโยชน์จริงๆเมื่อคุณทำเสร็จ ฉันเขียนสคริปต์ที่อ่านใน csv ของข้อมูลตัวอย่างและเขียน shapefile ด้วยข้อมูลที่เก็บไว้เป็นแอตทริบิวต์ของประเภทข้อมูลที่ถูกต้อง pyshp / xbase datatyping นั้นค่อนข้างยุ่งยากสำหรับฉันจนกระทั่งฉันพบคู่มือผู้ใช้สำหรับรูปแบบ xbaseและจากคำถามนี้ฉันได้เขียนโน้ตเล็ก ๆ ลงในบล็อกของฉันเกี่ยวกับประเภทข้อมูล pyshp ที่เกี่ยวข้องซึ่งเป็นส่วนหนึ่งที่ฉันวางไว้ด้านล่าง :

  • C คืออักขระ ASCII
  • N เป็นจำนวนเต็มความแม่นยำสองเท่าจำกัดความยาวได้ประมาณ 18 อักขระ
  • D สำหรับวันที่ในรูปแบบ YYYYMMDD โดยไม่มีช่องว่างหรือยัติภังค์ระหว่างส่วน
  • F สำหรับตัวเลขจำนวนจุดลอยตัวที่มีการจำกัดความยาวเท่ากับ N
  • L สำหรับข้อมูลโลจิคัลที่เก็บอยู่ในตารางแอ็ตทริบิวต์ของ shapefile เป็นจำนวนเต็มแบบสั้นเป็น 1 (true) หรือ 0 (false) ค่าที่สามารถรับได้คือ 1, 0, y, n, Y, N, T, F หรือไพ ธ อนบิวด์อิน True และ False

รายชื่อเต็มมีดังนี้:

import shapefile as shp
import csv

out_file = 'GPS_Pts.shp'

#Set up blank lists for data
x,y,id_no,date,target=[],[],[],[],[]

#read data from csv file and store in lists
with open('input.csv', 'rb') as csvfile:
    r = csv.reader(csvfile, delimiter=';')
    for i,row in enumerate(r):
        if i > 0: #skip header
            x.append(float(row[3]))
            y.append(float(row[4]))
            id_no.append(row[0])
            date.append(''.join(row[1].split('-')))#formats the date correctly
            target.append(row[2])

#Set up shapefile writer and create empty fields
w = shp.Writer(shp.POINT)
w.autoBalance = 1 #ensures gemoetry and attributes match
w.field('X','F',10,8)
w.field('Y','F',10,8)
w.field('Date','D')
w.field('Target','C',50)
w.field('ID','N')

#loop through the data and write the shapefile
for j,k in enumerate(x):
    w.point(k,y[j]) #write the geometry
    w.record(k,y[j],date[j], target[j], id_no[j]) #write the attributes

#Save shapefile
w.save(out_file)

ฉันหวังว่านี่จะช่วยได้.


สคริปต์ที่ดีมาก ผมได้รับข้อผิดพลาดที่มันไม่ได้อ่านมันเป็นข้อความดังนั้นฉันเปลี่ยนแปลงบรรทัดนี้กับเปิด ( 'input.csv', 'RT) เป็น csvfile:
againstflow

1
ฉันคิดว่าคุณสามารถปรับปรุงประสิทธิภาพโดยใช้ next (r) ก่อนหน้า for for loop เพื่อข้ามส่วนหัวแทนที่จะตรวจสอบโดยใช้คำสั่ง if
rovyko

@sgrieve - สคริปต์นี้แปลง csv ด้วยฟิลด์ที่กำหนดไว้ล่วงหน้า ฉันต้องการสคริปต์ทั่วไปเพื่อแปลง csv ใด ๆ ให้เป็นคลาสคุณลักษณะ อาจจะมีฟังก์ชั่น arcpy ที่มีประโยชน์ในการทำสิ่งนี้?
ฝีพาย

2

เป็นอีกทางเลือกหนึ่งที่คุณไม่จำเป็นต้องเก็บข้อมูลไว้ในรายการ

# import libraries
import shapefile, csv

# create a point shapefile
output_shp = shapefile.Writer(shapefile.POINT)
# for every record there must be a corresponding geometry.
output_shp.autoBalance = 1
# create the field names and data type for each.
# you can insert or omit lat-long here
output_shp('Date','D')
output_shp('Target','C',50)
output_shp('ID','N')
# count the features
counter = 1
# access the CSV file
with open('input.csv', 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    # skip the header
    next(reader, None)
    #loop through each of the rows and assign the attributes to variables
    for row in reader:
        id= row[0]
        target= row[1]
        date = row[2]
        # create the point geometry
        output_shp.point(float(longitude),float(latitude))
        # add attribute data
        output_shp.record(id, target, date)
        print "Feature " + str(counter) + " added to Shapefile."
        counter = counter + 1
# save the Shapefile
output_shp.save("output.shp")

คุณสามารถค้นหาตัวอย่างการทำงานของการดำเนินงานนี้ที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.