500 CSV फ़ाइलों को कुशलतापूर्वक और आसानी से QGIS का उपयोग करके कैसे पुनर्प्रकाशन करें?


11

मुझे पता है, मेरा सवाल इस साइट पर कुछ पुराने लोगों के समान है।

मैंने बहुत सी CSV फ़ाइलों (जियो निर्देशांक) को qgis में आयात करने के लिए (और फिर उन्हें परिवर्तित करने के लिए), और सामान्य तरीके से इसे करने का सबसे अच्छा तरीका नहीं है (बहुत लंबा)।

मेरे पास लगभग 500 CSV फाइलें (wgs84 निर्देशांक) हैं और यही मैं करना चाहता हूं:

  1. सभी CSV फ़ाइलों को एक बार QGIS में आयात करें
  2. उन्हें प्रोजेक्ट करें
  3. उन्हें CSV फ़ाइलों में निर्यात करें (फिर से) लेकिन विभिन्न निर्देशांक (UTM33N में रूपांतरण) के साथ

मैं समझने की कोशिश कर रहा हूं कि अजगर कंसोल का उपयोग कैसे करें लेकिन मैं आगे नहीं बढ़ रहा हूं :(

क्या कोई मुझे समझा सकता है कि मैं इसे कैसे प्राप्त करूं?


मेरा जवाब नीचे देखें। समस्या पहले ही हल हो गई थी और समझाया गया
जेनेरिक वीवर्स

2
और वह डुप्लिकेट एक चिह्नित के साथ क्यों है? हो सकता है कि ओपी ने पाइकगिस सीखने की कोशिश की हो और अगर आप उसके बल्ड्स पर विचार करते हैं तो पाइथन का उपयोग कैसे करें।
निकलता है

कृपया अपना प्रश्न निर्दिष्ट करें। क्या आप उन्हें QGIS में मैन्युअल लोड नहीं करना चाहते हैं? क्या आप उन्हें दूसरे प्रारूप में बदलना चाहते हैं? आपका सवाल क्या है?
Bugmenot123

1. सभी फ़ाइलों को एक प्रक्रिया में qgis में आयात करें। उन्हें प्रोजेक्ट करें 3. उन सभी को फिर से csv के रूप में निर्यात करें, लेकिन utm निर्देशांक में
Raquel Ribeiro

cat * .csv> one_file.csv (या जो भी विंडोज़ समतुल्य है) आपकी सभी सीएसवी फ़ाइलों को एक में मिला देगा। 500 वास्तव में इतनी बड़ी संख्या नहीं है :-)
जॉन पॉवेल

जवाबों:


15

यदि आप QGIS में पायथन कंसोल से सीएसवी फ़ाइलों को फिर से देखना चाहते हैं तो आप निम्न स्क्रिप्ट का उपयोग कर सकते हैं। आपको केवल उन तीन रास्तों को बदलना होगा जो टिप्पणियों में उल्लिखित हैं।

अनिवार्य रूप से, स्क्रिप्ट आपके सीएसवी फाइलों को क्यूजीआईएस में आकृतिफाइल्स के रूप में आयात करता है (यह मानते हुए कि आपके ज्यामितीय क्षेत्र का नाम Xऔर है Y)। इसके बाद प्रसंस्करण टूलबॉक्स से qgis:reprojectlayerऔर qgis:fieldcalculatorएल्गोरिदम का उपयोग करता है और नए निर्देशांकों के साथ और फ़ील्ड्स को रीप्रोजेक्ट और अपडेट करता है । यह तब इन्हें एक फोल्डर में सेव करता है और इन्हें आपके द्वारा निर्दिष्ट पथ में सीएसवी फाइलों में परिवर्तित करता है। इसलिए अंत में, आपने अलग-अलग फ़ोल्डरों में शेपफाइल्स और सीएसवी फाइलें अपडेट की हैं।XY

import glob, os, processing

path_to_csv = "C:/Users/You/Desktop/Testing//"  # Change path to the directory of your csv files
shape_result = "C:/Users/You/Desktop/Testing/Shapefile results//"  # Change path to where you want the shapefiles saved

os.chdir(path_to_csv)  # Sets current directory to path of csv files
for fname in glob.glob("*.csv"):  # Finds each .csv file and applies following actions
        uri = "file:///" + path_to_csv + fname + "?delimiter=%s&crs=epsg:4326&xField=%s&yField=%s" % (",", "x", "y")
        name = fname.replace('.csv', '')
        lyr = QgsVectorLayer(uri, name, 'delimitedtext')
        QgsMapLayerRegistry.instance().addMapLayer(lyr)  # Imports csv files to QGIS canvas (assuming 'X' and 'Y' fields exist)

crs = 'EPSG:32633'  # Set crs
shapefiles = QgsMapLayerRegistry.instance().mapLayers().values()  # Identifies loaded layers before transforming and updating 'X' and 'Y' fields
for shapes in shapefiles:
        outputs_0 = processing.runalg("qgis:reprojectlayer", shapes, crs, None)
        outputs_1 = processing.runalg("qgis:fieldcalculator", outputs_0['OUTPUT'], 'X', 0, 10, 10, False, '$x', None)
        outputs_2 = processing.runalg("qgis:fieldcalculator", outputs_1['OUTPUT_LAYER'], 'Y', 0, 10, 10, False, '$y', shape_result + shapes.name())

os.chdir(shape_result)  # Sets current directory to path of new shapefiles
for layer in glob.glob("*.shp"):  # Finds each .shp file and applies following actions
        new_layer = QgsVectorLayer(layer, os.path.basename(layer), "ogr")
        new_name = layer.replace('.shp', '')
        csvpath = "C:/Users/You/Desktop/Testing/CSV results/" + new_name + ".csv"  # Change path to where you want the csv(s) saved
        QgsVectorFileWriter.writeAsVectorFormat(new_layer, csvpath, 'utf-8', None, "CSV")   

उम्मीद है की यह मदद करेगा!


2
महान जवाब - आप यह सब वहाँ है !. एक सवाल अगर आपको कोई आपत्ति नहीं है: आपको अभी भी QgsMapLayerRegistry में परतों को जोड़ना / हटाना है, भले ही आप अजगर कंसोल से चीजें करते हों?
निकलता है

1
@ निक्की - बहुत धन्यवाद दोस्त! हम्म मुझे परतें जोड़ने / हटाने की जरूरत नहीं है (मुझे यकीन है कि स्क्रिप्ट नाटकीय रूप से कम की जा सकती है)। मैं कोई विशेषज्ञ नहीं हूं, लेकिन मैं बाद में इसका परीक्षण करूंगा और आपके पास वापस आ जाऊंगा। जब तक आप एक बहुत ही नट स्क्रिप्ट प्रदान नहीं कर सकते हैं जिस स्थिति में आपको इसे उत्तर के रूप में पोस्ट करना चाहिए, मैं इसे बढ़ा दूंगा :)
जोसेफ

@nickves - आपके सुझाव के लिए फिर से धन्यवाद दोस्त! दूसरी बार परतों को जोड़ने / हटाने से बचने के लिए कोड को संपादित किया गया है :)
जोसेफ

@RaquelRibeiro - सबसे स्वागत है! खुशी है कि यह मददगार था :)
यूसुफ

@ जोसेफ मैं आपसे कुछ फिर से पूछ सकता हूं? 14 और 15 की पंक्तियों में, संख्या: 0, 10, 10 वास्तव में क्या परिभाषित कर रही हैं? (आउटपुट निर्देशांक सही पर बहुत अधिक शून्य हैं और मैं उन्हें कम से कम करना चाहता हूं)
राकेल रिबेरो

8

WGS84 में UTM33N के लिए "lon lat" युक्त एक अलग-अलग फ़ाइल को बदलने के लिए एक त्वरित समाधान लेकिन आपको कोई अन्य जानकारी नहीं मिलती है:

#!/bin/bash
#
for i in $( ls *.csv ); do
    gdaltransform -s_srs EPSG:4326 -t_srs EPSG:32633 < ${i} > utm${i}
done

यह काम करता है और यह डेटा के क्रम को संरक्षित रखता है, इसलिए हो सकता है कि उदाहरणों के साथ वर्णनात्मक डेटा को संयोजित करने के लिए awk का उपयोग कर रहा हो?

संपादित करें। नीचे दी गई गन्दी टिप्पणियों के कारण मैं इसके स्थान पर उत्तर को संपादित करूँगा।

निम्न स्क्रिप्ट को कई सीएसवी फ़ाइलों को पढ़ने का काम करना चाहिए, प्रत्येक फ़ाइल में नए समन्वय कॉलम जोड़ना चाहिए।

#!/bin/bash
#
for i in $( ls *.csv ); do
 paste -d',' ${i} <(awk -v OFS="," -F " " 'NR>1 {print $1 " " $2}' ${i} | gdaltransform -s_srs EPSG:4326 -t_srs EPSG:32633 | awk '{gsub(" ",",",$0); print $0}' | /usr/local/bin/sed "1i\X,Y,Z") > utm${i}
#
 #paste -d',' ${i} <(awk -v OFS="," -F " " 'NR>1 {print $1 " " $2}' ${i} | gdaltransform -s_srs EPSG:4326 -t_srs EPSG:32633 | awk '{gsub(" ",",",$0); print $0}' |sed "1i\X,Y,Z") > utm${i}
#
done

OSX पर आपको sed के नवीनतम (2009) संस्करण को स्थापित करना होगा और लूप में पहली, सीधी लाइन का उपयोग करना होगा। लिनक्स टिप्पणी के लिए पहले और दूसरे का उपयोग करें। -F " "अपनी सीएसवी फ़ाइलों में विभाजक के प्रारूप के अनुसार समायोजित करें जैसे -F ","अल्पविराम के लिए अलग। यह भी ध्यान दें कि उत्थान परिवर्तन दीर्घवृत्त के लिए होता है, कि भू-आकृति पर, इसलिए ऊंचाइयों को तदनुसार बदलना सुनिश्चित करें।


मुझे अभी कुछ समय पहले ऐसा ही कुछ याद आया और मैंने अपने ब्लॉग पर एक समाधान पोस्ट किया। यह मैक के लिए लिखा गया है, लेकिन बैश आधारित है। सबसे बड़ा अंतर ओएस एक्स पर सीड के साथ मुद्दा है, जिसे मैं पोस्ट के अंत में निपटाता हूं
mercergeoinfo

आखिरी टिप्पणी थोड़ी गड़बड़ थी। paste -d',' ${i} <(awk -v OFS="," -F " " 'NR>1 {print $1 " " $2}' ${i} | gdaltransform -s_srs EPSG:4326 -t_srs EPSG:32633 | awk '{gsub(" ",",",$0); print $0}' | /usr/local/bin/sed "1i\X,Y,Z") > utm${i}यदि आप OSX पर नहीं हैं, तो सभी फ़ाइलों के माध्यम से लूप के लिए उपरोक्त बैश स्क्रिप्ट का उपयोग करें । यह आदर्श नहीं है यदि आपकी सीएसवी फाइलें अलग हो जाती हैं, जैसा कि उपरोक्त पंक्ति मानती है, लेकिन यह काम करता है। यदि आप अल्पविराम से अलग हो गए हैं, तो बदल -F " "जाएं-F ","
mercergeoinfo

मुझे आश्चर्य है कि टिप्पणियों में अपडेटेड कोड क्यों है और आपने ऊपर अपना जवाब अपडेट नहीं किया है। टिप्पणी में कोड वास्तव में पढ़ने के लिए मुश्किल है। क्या आप अपने उत्तर के नीचे संपादित लिंक देखते हैं?
मिरो

हाँ, लेकिन तब यह वास्तव में एक अतिरिक्त की तरह एक अद्यतन नहीं था। बहुत गन्दा, मैं सहमत हूँ। मुझे लगता है कि मुझे मूल उत्तर को अपडेट करना चाहिए। धन्यवाद
mercergeoinfo

7

इसके लिए qgis या OGR का उपयोग करना ओवरकिल है।
उपयोग करें pyproj( https://pypi.python.org/pypi/pyproj ) अजगर सीएसवी लेखक और कुछ मानक लाइब्रेरी ट्रिक्स के साथ। इसके लिए आपको कुछ और स्थापित करने की आवश्यकता नहीं है pyproj!

import csv
import pyproj
from functools import partial
from os import listdir, path

#Define some constants at the top
#Obviously this could be rewritten as a class with these as parameters

lon = 'lon' #name of longitude field in original files
lat = 'lat' #name of latitude field in original files
f_x = 'x' #name of new x value field in new projected files
f_y = 'y' #name of new y value field in new projected files
in_path = u'D:\\Scripts\\csvtest\\input' #input directory
out_path = u'D:\\Scripts\\csvtest\\output' #output directory
input_projection = 'epsg:4326' #WGS84
output_projecton = 'epsg:32633' #UTM33N

#Get CSVs to reproject from input path
files= [f for f in listdir(in_path) if f.endswith('.csv')]

#Define partial function for use later when reprojecting
project = partial(
    pyproj.transform,
    pyproj.Proj(init=input_projection),
    pyproj.Proj(init=output_projecton))

for csvfile in files:
    #open a writer, appending '_project' onto the base name
    with open(path.join(out_path, csvfile.replace('.csv','_project.csv')), 'wb') as w:
        #open the reader
        with open(path.join( in_path, csvfile), 'rb') as r:
            reader = csv.DictReader(r)
            #Create new fieldnames list from reader
            # replacing lon and lat fields with x and y fields
            fn = [x for x in reader.fieldnames]
            fn[fn.index(lon)] = f_x
            fn[fn.index(lat)] = f_y
            writer = csv.DictWriter(w, fieldnames=fn)
            #Write the output
            writer.writeheader()
            for row in reader:
                x,y = (float(row[lon]), float(row[lat]))
                try:
                    #Add x,y keys and remove lon, lat keys
                    row[f_x], row[f_y] = project(x, y)
                    row.pop(lon, None)
                    row.pop(lat, None)
                    writer.writerow(row)
                except Exception as e:
                    #If coordinates are out of bounds, skip row and print the error
                    print e

मुझे पता है कि पोस्टर अजगर के साथ बहुत अनुभवहीन है। मैं नियमित रूप से क्यूजीआईएस का उपयोग नहीं करता हूं, तो क्या कोई व्यक्ति उस मंच के साथ अधिक अनुभव के साथ समझा सकता है जहां अजगर स्थापित है? पोस्टर को इसे एक स्टैंडअलोन स्क्रिप्ट बनाना चाहिए और शायद इसे आईडीएलई से चलाया जाए। मेरे पास वर्तमान इंस्टॉलेशन नहीं है, इसलिए मुझे नहीं पता pyprojकि पोस्टर के लिए अलग से स्थापित करने की आवश्यकता है या पहले से ही है।
ब्लेक-कैस्टिलो

1
पहले कभी आंशिक कार्य नहीं किया। अभी से करेंगे। +1
निकोटस

4

आपको अजगर की जरूरत नहीं है। बस कमांड लाइन और ogr2ogr का उपयोग करें। आपके मामले में सबसे महत्वपूर्ण है -t_srs srs_def पैरामीटर।

यह पहले से ही से समझाया गया है इस उत्तर के लिए मैं कैसे किसी शेपफ़ाइल को एक्स के साथ excel फ़ाइल, वाई कॉलम में बदल सकते हैं?

अद्यतन मुझे आपके पास अपना पूरा कोड लिखने का समय नहीं है। लेकिन समस्या यह होगी कि आपको लगता है कि यह अजगर से थोड़ा अधिक कोड की आवश्यकता है।

आपकी मुख्य समस्या यह होगी कि सीएसवी फाइलों के साथ काम करना शेपफाइल्स का उपयोग करने में उतना आसान नहीं है। इस प्रकार आपको सबसे पहले सीएसवी को आकार में बदलने की आवश्यकता होगी, जिसे वीआरटी फ़ाइल की आवश्यकता है। यह पहली कड़ी में बताया गया है। यहां आपको अपनी फ़ाइलों के माध्यम से एक पायथन स्क्रिप्ट लिखनी होगी जो स्वचालित रूप से vrt फ़ाइलों को उत्पन्न करती है।

यह एक स्क्रिप्ट है जिसका मैंने खुद इस्तेमाल किया। आपको परीक्षण करना है कि यह आपके लिए काम करता है या नहीं। मैंने पहले ही WGS 84 से UTM 33N में रूपांतरण शामिल कर लिया

from os import listdir, stat, mkdir, system
path = "your path here"
out_path = "your output path here"
files = filter(listdir(path), '*.csv') #for Python 3.x
# files= [f for f in listdir(path) if f.endswith('.csv')] #for Python 2.7

for x in range(len(files)):
    name = files[x].replace('.csv', '')
    # 2. create vrt file for reading csv
    outfile_path1 = out_path + name + '.vrt'
    text_file = open(outfile_path1, "w")
    text_file.write('<OGRVRTDataSource> \n')
    text_file.write('    <OGRVRTLayer name="' + str(name) + '"> \n')
    text_file.write('        <SrcDataSource relativeToVRT="1">' + name + '.csv</SrcDataSource> \n')
    text_file.write('        <GeometryType>wkbPoint</GeometryType> \n')
    text_file.write('        <LayerSRS>WGS84</LayerSRS> \n')
    text_file.write('        <GeometryField encoding="PointFromColumns" x="Lon" y="Lat"/> \n')
    text_file.write('        <Field name="Name" src="Name" type="String" /> \n')
    text_file.write('    </OGRVRTLayer> \n')
    text_file.write('</OGRVRTDataSource> \n')
    # 3. convert csv/vrt to point shapefile
    outfile_path2 = out_path + name + '.shp'
    command = ('ogr2ogr -f "ESRI Shapefile" -t_srs EPSG:32633' + outfile_path2 + ' ' +  outfile_path1)
    system(command)

आपको अपनी सीएसवी फ़ाइल के अनुसार फ़ील्ड नाम , src , x और y के मापदंडों को समायोजित करने की आवश्यकता है ।

UPDATE2

कुछ सोच के बाद, मैं अपने आप से पूछता हूं कि आप क्यूजीआईएस का उपयोग क्यों करना चाहते हैं? आप अपने निर्देशांक को सीधे WGS से UTM में परिवर्तित करने के लिए इस तरह एक अजगर स्क्रिप्ट का उपयोग कर सकते हैं । इस मामले में यह एक सरल ओपन सीएसवी है, समन्वय पढ़ें, समन्वय को रूपांतरित करें और इसे एक नई फ़ाइल में सहेजें।


मुझे लगता है कि यह वह नहीं है जिसकी मुझे तलाश है ... मेरे पास लगभग 500 सीएसवी फाइलें (wgs84 निर्देशांक) हैं और यही वह है जो मैं करना चाहता हूं: 1. एक बार q gis में सभी सीएसवी फाइलों को आयात करें। उन्हें 3 प्रोजेक्ट करें। सीएसवी फ़ाइलों (फिर) में उन्हें निर्यात करें, लेकिन अलग-अलग निर्देशांक (utm33N में रूपांतरण) के साथ
Raquel Ribeiro

मुझे लगता है कि मुझे ऐसा करने के लिए बैच प्रक्रिया या किसी चीज़ की आवश्यकता है ...
राकेल रिबेरो

4
लेकिन आप ऐसा क्यों करना चाहते हैं? 1. आप qgis के बिना कमांड लाइन से वही (जो आपने वर्णित किया है) कर सकते हैं। 2. आप इसे बैच मोड में कर सकते हैं। 3. अजगर में यह लगभग समान है। आप ogr2ogr
जेनेरिक

2
"बस" कमांड लाइन का उपयोग करना वास्तव में एक जवाब नहीं है। कमांड लाइन का उपयोग करना कभी भी आसान नहीं है यदि आपको पता नहीं है कि इसे कैसे करना है। और मैं वास्तव में लिंक किए गए उत्तर में समाधान नहीं ढूंढ सकता। क्यों न केवल गरीब साथी को ogr2ogr के साथ एक उदाहरण बैच दिया जाए, और सब कुछ ठीक हो जाएगा?
बेरंड वी।

1
ठीक है, 1. आप gis.stackexchange.com/help/how-to-ask पढ़ सकते हैं । उसके बाद और 5 मिनट की गूगलिंग पर आप स्वीकार करेंगे कि इस प्रश्न पर बहुत खराब शोध किया गया है और पहले से दिए गए उत्तरों से हल किया जा सकता है। 2. यदि यह अभी भी हल नहीं किया जा सकता है, तो मुझे लगता है कि हर कोई मदद करने के लिए प्रसन्न होगा। लेकिन जैसा कि मैं एक अच्छा व्यक्ति हूं, मैं कुछ और संकेत दूंगा।
जेनेरिक वीवर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.