วิธีเพิ่มฟิลด์แอททริบิวไปยัง Shapefile ที่มีอยู่ผ่าน Python โดยไม่ต้องใช้ ArcGIS


24

ฉันมีสคริปต์ Python ที่เพิ่มฟิลด์คุณสมบัติให้กับ Shapefile หากไม่มีอยู่ นี่เป็นเรื่องง่ายที่จะทำกับ ArcGIS (แบบกราฟิกหรือผ่าน Python) แต่ฉันกำลังมองหาบางอย่างที่ไม่ได้ขึ้นอยู่กับ ArcGIS

ฉันพยายามนี้ไม่ประสบความสำเร็จกับ OGR ตั้งแต่ Shapefile ของฉันมีคุณสมบัติ

ฉันดูที่pyshpแต่ในทำนองเดียวกันไม่มีวิธีแก้ไข schema หลังจากสร้างแล้ว ฉันไม่ได้ลองกับshapefile (สำหรับ Python)แต่ฉันไม่เห็นคุณลักษณะนี้ที่โฆษณา ฉันยังไม่สามารถดูวิธีนี้สามารถทำได้โดยการ tinkering กับไฟล์ DBF ผ่านdbfpy

ไม่มีใครมีความคิดใด ๆ


มันจะเป็นที่ยอมรับได้หรือไม่ที่จะโคลนโครงสร้าง Shapefile ที่มีอยู่เพิ่มคอลัมน์ใหม่แล้วเติมมันขึ้นอยู่กับ Shapefile เดิม?
DavidF


คำถามนี้ควรจะปิดเป็นซ้ำของgis.stackexchange.com/q/3623/664
whuber

ใช่เป็นหลักเดียวกัน ฉันดู แต่ไม่เห็น
Mike T

คำตอบ:


8

คุณควรดูคำถามเหล่านี้เนื่องจากได้รับคำตอบแล้ว: วิธีการเพิ่มคุณสมบัติที่กำหนดเองไปยัง Shapefile โดยใช้ Python ได้อย่างไร

/programming/4215658/adding-custom-feature-attributes-to-esri-shapefile-with-python

หากคุณต้องการผลลัพธ์ให้หนึ่งรูปร่างไฟล์เพียงแค่ลบไฟล์อินพุตที่ท้ายสคริปต์ของคุณ


ซึ่งก็คล้ายกับgis.stackexchange.com/questions/3623/…ขอบคุณที่ขุดขึ้นมา
Mike T


4

ด้วยรูปแบบที่ค่อนข้างจะทำให้สมองตายที่เรียกว่า DBF การเพิ่มเขตข้อมูลลงใน shapefiles ด้วยข้อมูลคุณลักษณะที่มีอยู่นั้นเป็นไปไม่ได้โดยไม่ต้องเขียนใหม่หรือเพิ่มการขยายไปยัง DBF ฉันไม่รู้โซลูชันสำเร็จรูป แต่สิ่งที่ฉันจะทำคือเขียนสคริปต์เพื่อสร้างรูปร่างไฟล์ใหม่โดยใช้ไฟล์ที่มีอยู่แล้วเพิ่มฟิลด์พิเศษลงในรูปร่างไฟล์ใหม่ จากนั้นคัดลอกข้อมูลรูปทรงเรขาคณิต / คุณสมบัติจากเก่าไปยังรูปร่างไฟล์ใหม่ และเป็นขั้นตอนสุดท้ายให้ลบไฟล์เก่าและเปลี่ยนชื่อไฟล์ใหม่ ทั้งหมดนี้ทำได้โดยง่ายโดยใช้การผูก Python ของ OGR

อีกวิธีหนึ่งคุณสามารถใช้ dbfpy เพื่อทำข้างต้นด้วยไฟล์ DBF ลำดับขั้นตอนยังคงเหมือนเดิม:

  1. สร้าง DBF ใหม่ที่มีโครงสร้างเหมือนกันกับต้นฉบับ
  2. สร้างฟิลด์แอททริบิวใหม่ใน DBF ใหม่
  3. คัดลอกข้อมูลจาก DBF ดั้งเดิมไปยัง DBF ใหม่
  4. ลบ DBF เก่าเปลี่ยนชื่อ DBF ใหม่เป็น DBF เก่า

คุณไม่จำเป็นต้องทำการเปลี่ยนแปลงใด ๆ กับ shapefile (.shp) ตัวมันเองหรือไฟล์อื่นใดเนื่องจากมันไม่ได้อ้างอิงข้อมูลคุณสมบัติที่มีอยู่ใน DBF อย่างไรก็ตามคุณจำเป็นต้องรักษาลำดับของเร็กคอร์ดที่เหมือนกันในฐานข้อมูลเก่าและ DBF ใหม่


3

DBFpy ควรทำงานสำหรับสิ่งนี้ คุณเคยเห็นตัวอย่างในหน้านี้แล้ว:

http://dbfpy.sourceforge.net/

ตรวจสอบให้แน่ใจว่าไม่มีการแก้ไข shapefile โดยแอปพลิเคชันอื่นรวมถึง ArcGIS ในขณะนี้เพราะอาจทำให้เกิดปัญหาผ่านการล็อก


ฉันไม่คิดว่ามันจะทำงานถ้าคุณมีข้อมูลในไฟล์ DBF แล้ว ฉันเคยดูมาก่อน แต่ฉันได้รับข้อผิดพลาด: "เพิ่มอย่างน้อยหนึ่งเร็กคอร์ดโครงสร้างไม่สามารถเปลี่ยนแปลงได้" คุณมีตัวอย่างที่เฉพาะเจาะจงในใจหรือไม่?
Mike T

ฉันจำได้แล้วตอนนี้ใช่ดังที่ Sasa บอกว่าจะต้องมีการสร้าง DBF ใหม่ คัดลอกสคีมา (เช่นเดียวกับในฟิลด์อื่น ๆ ) จากนั้นทำการเพิ่มเติมจากนั้นคัดลอกเรคคอร์ด DBF "ยอดเยี่ยม" ... :(
Rob Clark

@ ไมค์วิธีเพิ่มเรคคอร์ดเมื่อทุกสิ่งที่คุณต้องการคือเพิ่มฟิลด์ ? การเพิ่มเรคคอร์ดเป็นข้อผิดพลาดเนื่องจากมันทำให้การเชื่อมต่อระหว่างแอ็ตทริบิวต์และรูปร่างเสียหาย การเพิ่มฟิลด์ไม่มีอันตรายใด ๆ ไลบรารีใด ๆที่สามารถแก้ไขไฟล์ dbf จะทำงานได้อย่างถูกต้อง
whuber

@whuber: นั่นคือข้อผิดพลาดของพวกเขา เปิด dbf ที่มีอยู่ซึ่งมีข้อมูลและดู:from dbfpy import dbf; db = dbf.Dbf('my.dbf'); db.addField(("FOO", "C", 15))
Mike T

@ ไมค์ขอบคุณสำหรับการชี้แจงสถานการณ์ ฟังดูเหมือนผลลัพธ์ของข้อ จำกัด ที่ไม่จำเป็นใน dbfpy :-( ฉันสามารถเดาได้ว่าทำไม: การเพิ่มเขตข้อมูลในฐานข้อมูลที่ไม่ว่างต้องมีระเบียนทั้งหมดที่จะต้องอ่านขยายและเขียนกลับออกมาทางกายภาพทางออกที่ดีคือ เพื่อค้นหาไลบรารี dBase อื่นหรือใช้ซอฟต์แวร์อื่น ;-)
whuber

1

ผมพบว่าวิธีการแก้ปัญหาโดยใช้ OGR และขอขอบคุณความช่วยเหลือจากที่คำถามก่อนหน้านี้ นี่คือตัวอย่างที่สมบูรณ์:

from osgeo import ogr

# Open a Shapefile, and get field names
source = ogr.Open('my.shp', update=True)
layer = source.GetLayer()
layer_defn = layer.GetLayerDefn()
field_names = [layer_defn.GetFieldDefn(i).GetName() for i in range(layer_defn.GetFieldCount())]
print len(field_names), 'MYFLD' in field_names

# Add a new field
new_field = ogr.FieldDefn('MYFLD', ogr.OFTInteger)
layer.CreateField(new_field)

# Close the Shapefile
source = None

ปัญหาของฉันคือการที่ฉันใช้มากกว่าlayer_defn.AddFieldDefn(new_field) layer.CreateField(new_field)ขอบคุณมากสำหรับความช่วยเหลือและขออภัยที่ไม่ได้ตรวจสอบคำถามอื่นที่คล้ายกันอย่างสม่ำเสมอ

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