पायथन के साथ जेजेन्सन का निर्माण


16

मैं प्रोग्रामेटिक रूप से एक आकृति से बहुभुज का उपयोग करके एक जेजेन्सन फ़ाइल बनाना चाहता हूं, लेकिन अपने स्वयं के एप्लिकेशन से विशेषताओं को जोड़ना।

यह आसानी से एक आकृति के लिए किया जाता है:

def create_data_dayer(self,varlist, data):
    """
    Creates a new shape to contain data about nodes.
    varlist is the list of fields names associated with
    the nodes.
    data is a list of lists whose first element is the geocode
    and the remaining elements are values of the fields, in the
    same order as they appear in varlist.
    """
    if os.path.exists(os.path.join(self.outdir,'Data.shp')):
        os.remove(os.path.join(self.outdir,'Data.shp'))
        os.remove(os.path.join(self.outdir,'Data.shx'))
        os.remove(os.path.join(self.outdir,'Data.dbf'))
    # Creates a new shape file to hold the data
    if not self.datasource:
        dsd = self.driver.CreateDataSource(os.path.join(self.outdir,'Data.shp'))
        self.datasource = dsd
        dl = dsd.CreateLayer("sim_results",geom_type=ogr.wkbPolygon)
    #Create the fields
    fi1 = ogr.FieldDefn("geocode",field_type=ogr.OFTInteger)
    dl.CreateField(fi1)
    for v in varlist:
        #print "creating data fields"
        fi = ogr.FieldDefn(v,field_type=ogr.OFTString)
        fi.SetPrecision(12)
        dl.CreateField(fi)

    #Add the features (points)
    for n,l in enumerate(data):
        #Iterate over the lines of the data matrix.
        gc = l[0]
        try:
            geom = self.geomdict[gc]
            if geom.GetGeometryType() != 3: continue
            #print geom.GetGeometryCount()
            fe = ogr.Feature(dl.GetLayerDefn())
            fe.SetField('geocode',gc)
            for v,d in zip (varlist,l[1:]):
                #print v,d
                fe.SetField(v,str(d))
            #Add the geometry
            #print "cloning geometry"
            clone = geom.Clone()
            #print geom
            #print "setting geometry"
            fe.SetGeometry(clone)
            #print "creating geom"
            dl.CreateFeature(fe)
        except: #Geocode not in polygon dictionary
            pass
        dl.SyncToDisk()

चूँकि मेरे पास जियोकोड (self.geomdict) के शब्दकोश में सभी ज्यामिति हैं, मैं केवल सुविधाएँ बनाता हूँ, फ़ील्ड सेट करता हूँ और ज्यामितीयों को पहले से मौजूद परत से कोडित करता हूँ (कोड लोडिंग कि परत सरलता के लिए छोड़ दी जाती है)। सभी को अब मुझे खेतों और भू-भागों के संयोजन से स्वाभाविक रूप से जेजेन्सन उत्पन्न करने का एक तरीका है, स्वाभाविक रूप से ओजीआर की मदद से शेष फ़ाइल अधिकार (सीआरएस, आदि जैसे स्रोत मानचित्र से) प्राप्त करने के लिए

उपरोक्त के रूप में उत्पन्न फीचर संग्रह को कैसे निर्यात करें?

जवाबों:


14

खुशी से OGR आपके लिए ऐसा कर सकता है क्योंकि दोनों वस्तुओं ogr.Featureऔर विधियों ogr.Geometryमें ExportToJson()विधियां हैं। आपके कोड में;

fe.ExportToJson()

और चूंकि GeoJSON FeatureCollection वस्तुओं बस शब्दकोशों हैं एक साथ typeकी FeatureCollectionऔर एक featuresफ़ीचर वस्तुओं की एक सूची से युक्त वस्तु।

feature_collection = {"type": "FeatureCollection",
                      "features": []
                      }

feature_collection["features"].append(fe.ExportToJson())

सुविधा संग्रह में CRS ऑब्जेक्ट दो प्रकारों में से एक हो सकता है:

  • एक नामित सीआरएस (उदाहरण के लिए एक ओजीसी यूआरएन या एक ईपीएसजी कोड)
  • एक URI के साथ एक लिंक ऑब्जेक्ट और एक प्रकार जैसे "proj4"

आपके डेटा प्रारूप के आधार पर यह काफी संभावना है कि नाम OGR से प्राप्त होने वाला है। इसके बजाय अगर हम डिस्क पर एक फ़ाइल को प्रक्षेपण लिखते हैं जिसे हम यूआरआई के साथ संदर्भित कर सकते हैं। हम परत वस्तु से प्रक्षेपण को पकड़ सकते हैं (जिसमें कई निर्यात कार्य हैं)

spatial_reference = dl.GetSpatialRef()

with open("data.crs", "wb") as f:
    f.write(spatial_reference.ExportToProj4())

feature_collection["crs"] = {"type": "link",
                             "properties": {
                                 "href": "data.crs",
                                 "type": "proj4"
                                 }
                             }

यह एक अच्छा समाधान है, क्योंकि यह मेरी परियोजना की तरह एक अतिरिक्त निर्भरता को नहीं जोड़ता है (@sgillies का अच्छा समाधान)
fccoelho

मैंने इस समाधान के साथ अपना परीक्षण समाप्त कर दिया और यह अच्छी तरह से काम किया। हालाँकि, मुझे फीचर्स को मैन्युअल रूप से हैंडल करना था जब फीचर्स में फील्ड के नाम के यूनिकोड कैरेक्टर थे, क्योंकि ऑगोरोमो ने उन्हें ठीक से हैंडल नहीं किया था।
fccoelho

मुझे नहीं पता कि कार्यक्षमता कब से बदल गई है, लेकिन fe.ExportToJson()एक स्ट्रिंग लौटाता है, इसलिए आपको इसमें लपेटने की आवश्यकता है json.loads(...)। अन्यथा, यह सुपर सहायक है!
jon_two

35

आप एक GDAL / OGR देव पर्यावरण (हेडर, libs) मिल गया है, तो आप मौलिक का उपयोग करके अपने कोड को आसान बनाने में कर सकता है फियोना । एक आकृति से सुविधाओं को पढ़ने के लिए, नई विशेषताएँ जोड़ें, और उन्हें लिखें जैसे कि GeoJSON केवल कुछ मुट्ठी भर लाइनें हैं:

import fiona
import json

features = []
crs = None
with fiona.collection("docs/data/test_uk.shp", "r") as source:
    for feat in source:
        feat['properties'].update(...) # with your attributes
        features.append(feat)
    crs = " ".join("+%s=%s" % (k,v) for k,v in source.crs.items())

my_layer = {
    "type": "FeatureCollection",
    "features": features,
    "crs": {
        "type": "link", 
        "properties": {"href": "my_layer.crs", "type": "proj4"} }}

with open("my_layer.json", "w") as f:
    f.write(json.dumps(my_layer))
with open("my_layer.crs", "w") as f:
    f.write(crs)

4
फियोना डॉक्स किलर हैं!
चाड कूपर

1
अगर मैं कर सकता था एक से अधिक बार वोट!
om_henners

2
क्या GeoJSON में crs परिभाषा को शामिल करने का कोई तरीका नहीं है?
fccoelho

2

यह फियोना में सबसे सरल और आसान है। आप आउटपुट GeoJSON के लिए SRS सेट कर सकते हैं।

import fiona
from fiona.crs import from_epsg

source= fiona.open('shp/second_shp.shp', 'r', encoding = 'utf-8')

with fiona.open('tool_shp_geojson/geojson_fiona.json','w',  driver ="GeoJSON", schema=source.schema, encoding = 'utf-8', crs=fiona.crs.from_epsg(4326)) as geojson:
     geojson.write(feat)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.