txt2shp.py

A segitsegeteket szeretnem kerni 1 python script megirasahoz.

A feladatom a kovetkezo:
Van tobb szaz, ezer .dat kiterjeszteso ASCII file, amik meteorologiai allomasok mert homersekleti adatait tartalmazzak, foldrajzi kordinataval.
http://pastebin.ca/1238508
Ebbol szeretnek csinalni 1 vektoros terkepet es (dBase) adatbazist (ArcGIShez).

Hogyan lehet automatizalni a konvertalast 1 python script segitsegevel?

Epp csak most ismerkedtem meg a python nyelv alapjaival, igy minden otletet, javaslatot szivesen veszek.
A segitseget elore is koszonom.

Hozzászólások

tudod, hogy milyen a forrás, tudod, hogy milyen a cél. Mi kell még?
Van konkrét kérdésed?

--
Ami elől menekülnek, az után szaladnak.

Én úgy kezdeném, hogy megnézem a cél fájl felépítését, kicsit szerkesztgetném, hogy jobban megismerjem. Ezt követően megnézném, hogy milyen adatok vannak a forrás fájlban és hova kell őket írni a cél fájlban.

Ha ez megvan, akkor a kódolásban szívesen segítünk :)

----
Ha szeretted a DOS-os játékokat, ezt imádni fogod. livedosgames.com

#!/usr/bin/python
f=open('ff.dat', 'r')
while True:
line = f.readline()
print line.rstrip()
if not line:
break

Ez belovassa a line-ba a soraidat.
--
Ami elől menekülnek, az után szaladnak.

Fuss neki a Python dokumentacionak, olvasd el a tutorialt, nezegesd a nyelvi referenciakat, hasznald az interaktiv parancssort, nezegess python kodokat. Es persze Google a baratod, Wiki a baratnod.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Ha megmondod, hogy pontosan milyen bemenetről milyen kimenetet vársz, akkor a kódolás nem nagy ügy. Segítek szívesen akár.
--
Ami elől menekülnek, az után szaladnak.

Utanaolvastam es sokat keresgeltem a neten.

A bemenet a mar peldakent linkelt .dat file(ok).
A kimenet pedig 1 shape file es 1 .dbf, ami tartalmazza a homersekleti adatokat es egyeb metaadatokat (meroallomas neve, szam stb.).

Kb. ugy szeretnem megcsinalni, mint itt:
http://www.perrygeo.net/wordpress/?p=5
http://pastebin.ca/1239408
Csak az input teljesen mas.

Matthew Perry az OGR modult hasznalja, ami jo otlet. En is ugy szeretnem megirni a scriptet,h ne csak windowson es ne csak arcgis programmmal mukodjon.
Nemetorszagban es Ausztiaban ezek a homersekleti adatokat tartalmazo fileok mindig igy neznek ki. Ez a standard formaja. Tehat barki tudna hasznalni, akinek ilyenekkel akad dolga.

A python oldalan kezdoknek levo tutorialokat mind atolvastam, tehat az alapok megvannak. Talaltam meg 1 konyvet, de ez tul nehez meg nekem:
http://gnosis.cx/TPiP/
Ismeri valaki? Talan hasznos lehet.

Megkoszonom ha segitetek a kodolasban.

Figyi, a segitseg ugy mukodik, hogy elindulsz valamerre, es segitunk, ha elakadsz. Az nem mukodik, hogy megirjuk helyetted - illetve mukodik, megfelelo ellenszolgaltatasert (pl. penzert, sorert) cserebe. Szoval akkor dontsd el, mit szeretnel, es lepj aszerint.

Ha ugy allsz neki, hogy ugyse fog menni, akkor nem is fog menni. Kezdj bele, nem baj, ha az irany rossz, az is egy tapasztalat.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

A dbfpy modul segitsegevel sikerult letrehozni egy dbf fajlt:
http://dbfpy.sourceforge.net/


#!/usr/bin/python

from dbfpy import dbf

# create empty DBF, set fields
db = dbf.Dbf("dbfpy_example_temp.dbf", new=True)
db.addField(
    ("MESSSTELLE", "C", 15),
    ("HZBNummer", "N", 10),
    ("HDNummer", "C", 10),
    ("DBMSNummer", "N", 10),)

# fill DBF with some records
for messstelle, hzbnummer, hdnummer, dbmsnummer in (
    ("Fuschl", (105353), "HD5000080", (5000080)),):
    rec = db.newRecord()
    rec["MESSSTELLE"] = messstelle
    rec["HZBNummer"] = hzbnummer
    rec["HDNummer"] = hdnummer
    rec["DBMSNummer"] = dbmsnummer
    rec.store()
db.close()

# read DBF and print records
db = dbf.Dbf("dbfpy_example_temp.dbf")
for rec in db:
    print rec
print

Elso lepesnek nem rossz, de en az szeretnem,h a script a mar fentebb linkelt .dat fajlbol olvassa ki az adatokat.

igy probalkoztam:


#!/usr/bin/python
openFile = open(r'E:\LT105353.dat','r')
while True:
    line = openFile.readline()
    if "02.02.1997" in line:
        valueList=line.split()
        print valueList
    if not line:
        break
# close txt file...
openFile.close()

Kozel sem tokeletes, de haladas:)

Hogyan tudom az adatokat 1 dBase fajlba kiirni ugy,h 2 mezot tartalmazzon:
1. datum
2. homerseklet
?

A segitseget elore is köszönöm.

itt tartok:


openFile = open(r'E:\LT105353.dat','r')
while True:
    line = openFile.readline()
    if 'Zeitraum' in line:
        valueList=line.split()
        del valueList[:]
        continue
    if '00:00:00' in line:
        valueList=line.split()
        del valueList[1]
        print valueList
    if not line:
        break
# close txt file...
openFile.close()

Eredmenykent kapok 1 listat, a kivant adatokkal.
Hogyan tudom ezt a listat 1 .dbf fajlba irni? (Vagy elso lepesnek akar csak 1 text fajlba?)
Segitsetek picit, mert nagyon nehezen jutok elore...

Sikerult a listat 1 text fajlba irni:


import string
openFile = open(r'E:\LT105353.dat','r')
f=open('date_temp.txt', 'w')
while True:
    line = openFile.readline()
    if 'Zeitraum' in line:
        valueList=line.split()
        del valueList[:]
        continue
    if '00:00:00' in line:
        valueList=line.split()
        del valueList[1]
        #print valueList
        if  valueList[1] == 'L\xfccke':
            valueList[1] = "nodata"
        valueString=string.join(valueList)
        f.write(valueString + "\n")
    if not line:
        break
f.close()
openFile.close()

Hogyan tudom ezt a valueList-et vagy a date_temp.txt-t .dbf-be varazsolni???
Ha tudtok, kerlek segitsetek.

Sziasztok!

most ott tartok,h sikerult 1db record-ot kitolteni a dbf-ben:


from dbfpy import dbf

## create empty DBF, set fields
db = dbf.Dbf('list2dbf.dbf', new=True)
db.addField(('date','D'),('temp','N',3,1),)

## read date, temp from .dat file
openFile=open(r'E:\LT105353.dat','r')

while True:
    line = openFile.readline()
    if '02.02.1997' in line:
        valueList=line.split()     
    if not line:
        break

rawDate = valueList[0].split(".")
newDate = rawDate[2]+rawDate[1]+rawDate[0]

## fill DBF with date, temp record
for date,temp in ((newDate,float(valueList[2])),):
    rec = db.newRecord()
    rec['date']=date
    rec['temp']=temp
    rec.store()
db.close()
    
openFile.close()

## read DBF and print records
db = dbf.Dbf('list2dbf.dbf')

Azthiszem latszik,h elindultam es lassan de biztosan haladok. A kerdes konkret es jol latszik,h mit is szeretnek csinalni.
Azt mondtatok,h a kodolasban szivesen segitetek.

A kerdesem tehat a kovetkezo: hogyan csinaljak 1 olyan loop-ot, ami letrehoz annyi record-ot, ahany homersekleti adat a .dat faljban van, es be is irja az?
A 2 utoljara postolt script-et kene valahogy osszehozni, de hogyan?

Tombiteralas pythonban (vazlatos kod):


arr = ['ize', 'mize', 'foo', 'bar']

for e in arr:
    print "%s\n" % e

A dbf cucc gondolom tartalmaz dbf kezelo fuggvenyeket (nem ismerem)
Valojaban az kell neked, hogy ossze kell allitanod egy puffert, amiben mar felig feldolgozott adat van (kivalasztod azt a sort, melyben az aktualisan erdekes adat van, majd elteszed egy tombbe), majd vegigiteralsz a pufferen, kiveszed az adatot (ajanlom neked a re modult, mely regex alapu kivalasztast tesz lehetove nagyon sokfele modon), osszeallitod a dbf query-t es vegrehajtod.
A kodolast mar rad biznam..

Tipp: ha nem tul nagy a fajl, a readlines() fuggveny egy tombbe beolvassa az osszes sorat a fajlnak.
Arra figyelj, hogy python alatt minden sorolvaso fuggveny a sor veget jelzo \r\n vagy \n karaktereket is bemasolja a sor vegere, igy a feldolgozas elott erdemes lehet levagni azt.

--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

#!/usr/bin/python

from dbfpy import dbf

## create empty DBF, set fields
db = dbf.Dbf('tempdata.dbf', new=True)
db.addField(('date','D'),('temp','N',3,1),)

## read date, temp from .dat file
openFile=open('1.dat', 'r')

for line in openFile:
    cols = line.split()
    if len(cols) == 3  and cols[1] == '00:00:00':
        date = cols[0].split('.')
        date = date[2] + date[1] + date[0]
        try:
            temp = float(cols[2])
        except ValueError:
            break
        rec = db.newRecord()
        rec['date']=date
        rec['temp']=temp
        rec.store()

db.close()
openFile.close()

#!/usr/bin/python
from dbfpy import dbf
import sys, os
def usage():
    print ''
    print 'Convert a delimited dat file with date and temperature into a dbf file'
    print 'Usage: list2dbf3.py input=input.dat output=output.dbf'
    sys.exit()

inputFile=None
outputFile=None

try:
   for i in range(len(sys.argv)):
      p = sys.argv[i].split('=')
      if p[0] == 'input':
         inputFile = str(p[1])
      if p[0] == 'output':
         outputFile = str(p[1])
except:usage()
if not inputFile or not outputFile:usage()
if not os.path.exists(inputFile):
    print ''
    print 'Input File', inputFile, "doesn't exist"
    sys.exit()

db = dbf.Dbf(outputFile, new=True)
db.addField(('date','D'),('temp','N',4,1),)

openFile=open(inputFile, 'r')

for line in openFile:
    cols = line.split()
    if len(cols) == 3 and cols[1] == '00:00:00':
        date = cols[0].split('.')
        date = date[2] + date[1] + date[0]
        try:
            temp = float(cols[2])
        except:
            temp = int(9999)
        rec = db.newRecord()
        rec['date'] = date
        rec['temp'] = temp
        rec.store()
openFile.close()
db.close()
if os.path.exists(outputFile):
    print
    print 'Output file', outputFile, 'created successfully'

Egesz jol haladok. Mostmar terminalban/dos promptban lehet megadni az input-output fajlt es hibauzi is van:)
Azzal kinlodok, hogy szeretnek megadni tobb input-ot, output-ot, vesszovel elvalasztva.
Hogy modositsam a script elejen levo 'try' reszt,h ez lehetseges legyen?
a segitseget elore is koszonom.

kepzeld el,h a felhasznalonak van tobb szaz ugyan ilyen .dat fajlja, amibol elso korben dbf-et(, majd shape fajlt) akar kapni.
ha egyszerre csak 1 inputot lehet megadni, 100x kell dosban/terminalban kiadni a parancsot. E helyett szeretnek valami jobb megoldast talalni.
peldaul ugy lenne talan a legjobb ha user megadja a mappat amiben a .datok sorakoznak es a script beolvassa az elso .dat-ot, kiveszi a kivant adatot, beirja 1 dbf fajlba, majd beolvassa a masodik .dat-ot... es igy tovabb, mig el nem fogy.
lehetseges ez? (tuti, csak meg nem tudom hogyan)
koszi,h segitesz.

2 hete nem hittem volna,h ilyet fogok tudni irni:


#!/usr/bin/python
# txt2dbf_xyz.py
# 07/11/2008
'''
en-hu-de
Latitude - szelesseg kor - Breite
Longitude - hosszusagi kor - Laenge
'''
from dbfpy import dbf
import sys,os
from string import maketrans

def usage():
    print ''
    print 'Usage: txt2dbf_xyz.py path=folder with data output=output.dbf'
    sys.exit()

path = None
outputFile = None

try:
   for i in range(len(sys.argv)):
      p = sys.argv[i].split('=')
      if p[0] == 'path':
         path = str(p[1])
      if p[0] == 'output':
         outputFile = str(p[1])
except: usage()

if not path or not outputFile: usage()

if not os.path.exists(path):
    print ''
    print 'Folder', path, "doesn't exist"
    sys.exit()

library = os.listdir(path)
db = dbf.Dbf(outputFile, new=True)
db.addField(('hzbnummer','C',6),('cpname','C',12),('latitude','N',6),('longitude','N',6),('altitude','N',4)),
decX = 0
decY = 0
for dat in library:
    file = os.path.join(path, dat)
    openFile = open(file, "r")
    for line in openFile:
        cols = line.split()
        if cols[0] == 'Messstelle:':
            table = maketrans('\xdf\xe4\xf6\xfc\xc4\xd6\xdc', 'saouAOU')
            cpname = cols[1].translate(table)
        if cols[0] == 'HZB-Nummer:':
            hzbnummer=cols[1]
        if decX == 2:
            if not 'Geographische Koordinaten:' in line:
                 altitude=float(cols[1])
            decX = 0
        if decX == 1:
            altitude=float(cols[1])
            decX = 2
        if decY == 2:
            if not 'Exportzeitreihe:' in line:
                latitude=int(cols[4]+cols[5]+cols[6])
                longitude=int(cols[1]+cols[2]+cols[3])
            decY=0
        if decY == 1:
            latitude=int(cols[4]+cols[5]+cols[6])
            longitude=int(cols[1]+cols[2]+cols[3])
            decY=2
        if '[m \xfc.A.]' in line:
            decX = 1
        if '(Grad,Min,Sek)' in line:
            decY = 1
            
    rec = db.newRecord()
    rec['hzbnummer']=hzbnummer
    rec['cpname']=cpname
    rec['altitude']=altitude
    rec['latitude']=latitude
    rec['longitude']=longitude
    rec.store()
    
openFile.close()
db.close()

if os.path.exists(outputFile):
    print
    print 'Output file', outputFile, 'created successfully'

es mukodik:) persze akad meg tennivalo boven.

Hogyan tudom kicserelni az umlautos nemet karaktereket? pl ö->oe,Ü->Ue.
A translate nem tokeletes, mert csak 1 karakterre tud cserelni. re modul?

Hogyan modositsam a kodot,h ne 1 kimenetre irja a kivant adatokat, hanem 1 input->1 output?
A loop resze kene legyen,h uj dbf-et hoz letre,de nem sikerul.
A segitseget elore is koszonom.

"Hogyan tudom kicserelni az umlautos nemet karaktereket? pl ö->oe,Ü->Ue.
A translate nem tokeletes, mert csak 1 karakterre tud cserelni. re modul?"


>>> x='Szöged'
>>> print x.replace('ö','ou')
Szouged

"Hogyan modositsam a kodot,h ne 1 kimenetre irja a kivant adatokat, hanem 1 input->1 output?
A loop resze kene legyen,h uj dbf-et hoz letre,de nem sikerul."

Ne (output)fájl legyen a második arg, hanem könytár, és a *.dat fájlokból csinálj *.dbf fájlokat.
Az új db létrehozást meg rakd az első for cikluson belülre (a végén a db.close()-t is).

hogyan tudok atlagot szamolni pythonnal?
igy probalkoztam, de nem mukodik:


# doesn't work !!!
from __future__ import division
import re, operator
openFile = open(r'LT105353.dat')
def average(seq): return reduce(operator.add, seq) / len(seq)
for line in openFile:
    cols = line.split()
    pat = re.compile('[0-9]{2}.[0-9]{2}.[0-9]{2}')
    if pat.match(line):
        try: temp = float(cols[2])
        except ValueError: continue
        temp_average = average(temp)
        print temp_average
openFile.close()