Share on: Diaspora*TwitterFacebookLinkedInHackerNewsEmailReddit

H διαθεσιμότητα δεδομένων από το Πανεπιστήμιο Ιωαννίνων, μεταξύ αυτών και γεωγραφικών, για τα πέτρινα γεφύρια της Ηπείρου στο διαδίκτυο (http://www.petrinagefiria.uoi.gr/) δίνει την δυνατότητα χαρτογράφησης αυτής της πληροφορίας με λογισμικό ανοικτού κώδικα αλλά και τον περαιτέρω έλεγχο της εγκυρότητας των δεδομένων. Με την βοήθεια της γλώσσας Το γεφύρι της Άρταςπρογραμματισμού Python και με δεδομένο ότι οι σχετικές ιστοσελίδες για τα γεφύρια δημιουργούνται δυναμικά μέσω της γλώσσας PHP και κατά συνέπεια διατηρούν μια κοινή δομή, είναι δυνατή η προσπέλαση τους και η απόσπαση συγκεκριμένων πληροφοριών με την βιβλιοθήκη urllib2. Στην συνέχεια με την χρήση της βιβλιοθήκης OSGeo μετατρέψαμε τις απαραίτητες πληροφορίες σε αρχείο shapefile όπου αποθηκεύτηκαν τα απαραίτητα χωρικά και περιγραφικά δεδομένα.

Παρακάτω διατίθεται ο κώδικας:

# -*- coding: utf-8 -*-
import html5lib
from html5lib import treebuilders
import urllib2,  re
from osgeo import ogr
from osgeo import osr
import os
def writeshp(path,  SRS,  gefiria):
    outShapeFile = path
    drv = ogr.GetDriverByName('ESRI Shapefile')    
    errors=[]
    if os.path.exists(str(outShapeFile)):
        drv.DeleteDataSource(str(outShapeFile))
        print "Deleting shapefile that already exists: " + outShapeFile
 
    # Create SpatialReference
    t_srs = osr.SpatialReference()
 
    if SRS=='Greek Grid':
        print "Greek Grid is the GRS for the shapefile"
        t_srs.ImportFromProj4("+proj=tmerc +lon_0=24 +k=.9996 +x_0=500000 +towgs84=-199.72,74.03,246.02+ellps=GRS80")#Greek Grid  
    else:
        t_srs.SetFromUserInput('WGS84')
        print "WGS84 is the GRS for the shapefile"
 
    ds = drv.CreateDataSource(outShapeFile)
    print "Creating shapefile: " + outShapeFile
    layer = ds.CreateLayer(ds.GetName(), geom_type = ogr.wkbPoint, srs = t_srs)
 
#Τα πεδία με το όνομα τους και τις ιδιότητές τους    
    fields=[['NAME',  ogr.OFTString, 255],
           ['GEFYRIID',  ogr.OFTInteger] ,  
           ['lamda',  ogr.OFTReal] ,  
           ['phi',  ogr.OFTReal] ,  
           ['RIVERCODE',  ogr.OFTString, 20],  
           ['NOMOS',  ogr.OFTString, 25],  
           ['KOINOTHTA',  ogr.OFTString, 100],  
           ['PLACE',  ogr.OFTString, 255],  
           ['RIVER',  ogr.OFTString, 100],  
           ['HEIGHT',  ogr.OFTInteger],  
           ['ODIKO',  ogr.OFTString, 255],
           ['PARAKEIM',  ogr.OFTString, 255],
           ['DATE',  ogr.OFTString, 15],
           ['BUILDERS',  ogr.OFTString, 255],
           ['XORIGOS',  ogr.OFTString, 255],
           ['DAPANI',  ogr.OFTString, 255],
           ['SINTIRISI',  ogr.OFTString, 255],
           ['ALLA',  ogr.OFTString, 255],
           ['MORFI',  ogr.OFTString, 255],
           ['MEGETHOS',  ogr.OFTString, 255],
           ['YLIKA',  ogr.OFTString, 255],
           ['KATASTASH',  ogr.OFTString, 255],
           ['EPIGRAFH',  ogr.OFTString, 255],
           ['ISTOR_LAO',  ogr.OFTString, 500],
           ['BIBLIOG',  ogr.OFTString, 500],
           ['MARTIRIES',  ogr.OFTString, 255]
            ]
#Δύο ειδικά πεδία για τις συντεταγμένες στο ΕΓΣΑ '87 
    if SRS=='Greek Grid':
        print "Creating Field X..."
        layer.CreateField(ogr.FieldDefn('X', ogr.OFTReal))
        print "Creating Field Y..."
        layer.CreateField(ogr.FieldDefn('Y', ogr.OFTReal))
 
#Δημιουργία πεδίων
    for field in fields:
#        print field[0]
        fieldname=field[0]
        fieldproperty=field[1]
        print "Creating Field "  + fieldname
        ofield  = ogr.FieldDefn(fieldname, fieldproperty)
        if fieldproperty ==4:#Ειδικό property αν είναι string
            print "string is"
            fieldlen=field[2]
            ofield.SetWidth(fieldlen)
        layer.CreateField(ofield)
 
    print "Creating geometry object..."
    geom = ogr.Geometry(type=ogr.wkbPoint)      
 
    print "Adding shapes to shapefile..."
    for gefyri in gefyria:
        #print gefyri[6]
 
        try:
            coods= converttoDD(gefyri[7])#Get the sixth field, coordinates
        except:
            print "Error at coordinates for gefyri:" + str(gefyri[1]) + "with ID:" +  str(gefyri[0])
            errors.append([gefyri[0] , gefyri[1]] )
            continue
        print "Adding point with coordinates " + str(coods[0] )+ "," + str(coods[1])
        geom.AddPoint(coods[0],coods[1])#Add a point with the Coordinates
 
        #Μετατροπή των συντεταγμένων σε περίπτωση που έχει επιλεγθεί το ΕΓΣΑ '87
        if SRS=='Greek Grid':
            sourceSR = osr.SpatialReference()
            sourceSR.SetFromUserInput('WGS84') #Geo WGS84
            targetSR = osr.SpatialReference()
            targetSR.ImportFromProj4("+proj=tmerc +lon_0=24 +k=.9996 +x_0=500000 +towgs84=-199.72,74.03,246.02+ellps=GRS80")
            #targetSR.SetFromUserInput('EPSG:2100') #Greek Grid
            coordTrans = osr.CoordinateTransformation(sourceSR, targetSR)
            print "Converting point coordinates to Greek Grid...."
            geom.Transform(coordTrans)        
            print "The coordinates in Greek Grid are " + str(geom.GetX()) +"," + str(geom.GetY())
 
        feat = ogr.Feature(feature_def=layer.GetLayerDefn())
        print "Importing shape into feature."
        feat.SetGeometry(geom)
        print "Importing attributes into feature."
        if SRS=='Greek Grid':
            feat.SetField('X',geom.GetX() )
            feat.SetField('Y',geom.GetY() )
 
        feat.SetField('NAME',gefyri[1] )
        feat.SetField('GEFYRIID', gefyri[0] )
        feat.SetField('lamda',coods[0] )
        feat.SetField('phi',coods[1] )
        feat.SetField('MORFI',gefyri[16] )
        feat.SetField('RIVERCODE',checkrivers(gefyri[6]) )
        feat.SetField('NOMOS',gefyri[3])
        feat.SetField('KOINOTHTA',gefyri[4])
        feat.SetField('PLACE',gefyri[5] )
        feat.SetField('RIVER',gefyri[6])
        feat.SetField('HEIGHT',gefyri[8] )     
        feat.SetField('PARAKEIM',gefyri[9] )     
        feat.SetField('DATE',gefyri[10] )           
        feat.SetField('BUILDERS',gefyri[11] )           
        feat.SetField('XORIGOS',gefyri[12] )          
        feat.SetField('DAPANI',gefyri[13] )  
        feat.SetField('SINTIRISI',gefyri[14] )     
        feat.SetField('ALLA',gefyri[15] )    
        feat.SetField('MORFI',gefyri[16] )     
        feat.SetField('MEGETHOS',gefyri[17] )     
        feat.SetField('YLIKA',gefyri[18] ) 
        feat.SetField('KATASTASH',gefyri[19] )     
        feat.SetField('EPIGRAFH',gefyri[20] )     
        feat.SetField('ISTOR_LAO',gefyri[21] )      
        feat.SetField('BIBLIOG',gefyri[22] )     
        feat.SetField('MARTIRIES',gefyri[23] )
        feat.SetField('ODIKO',gefyri[24] )
 
        layer.CreateFeature(feat)
 
    #Clean up objects  
    feat.Destroy()
    ds.Destroy()
 
    if len(errors)>0:
        print "There are " + str(len(errors) )+"errors"
        for gefyri in errors:
            print "Errors in coordinates for:" +gefyri[1] + " with id:" + gefyri[0]
 
def getdata (www):
    parser=html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))
    id = www[47:len(www)]
 
    print  "Parsing data from " + www
    tree=parser.parse(urllib2.urlopen(www))
    data=tree.findAll("td")
    cells=data[0:]#convert to list
 
#    Αν δεν υπάρχουν καθόλου κελιά με φωτογραφίες τότε ο συνολικός αριθμός των κελιών είναι 83
    if len(cells) == 79 :
        plus = -4
    if len(cells) == 80 :
        plus = -3
    if len(cells) == 81 :
        plus = -2
    if len(cells) == 82 :
        plus = -1
    if len(cells) == 83 :
        plus = 0
#    Αν δεν υπάρχει ένα κελίμε φωτογραφίες τότε ο συνολικός αριθμός των κελιών είναι 84 κτλ.     
    if len(cells) == 84 :
        plus = 1
 
    if len(cells) == 85 :
        plus = 2
 
    if len(cells) == 86 :
        plus = 3
    if len(cells) == 87 :
        plus = 4
 
    if len(cells) == 88 :
        plus = 5
 
    if len(cells) == 89 :
        plus = 6    
    if len(cells) == 90 :
        plus = 7
    if len(cells) == 91 :
        plus = 8
#Η εύρεση των απαραίτητων κελιών γίνεται δυναμικά καθώς ο αριθμός των κελιών με τις φωτογραφίες δεν είναι πάντα σταθερός
    td=[id, cells[16],  cells[18],   cells[25+plus],  cells[27+plus],  cells[29+plus],  cells[31+plus], cells[33+plus], cells[35+plus], cells[39+plus], cells[42+plus], cells[44+plus], cells[46+plus], cells[48+plus],  cells[50+plus],  cells[52+plus], cells[55+plus],  cells[57+plus],   cells[59+plus],   cells[61+plus],   cells[63+plus],   cells[66+plus],   cells[68+plus],   cells[70+plus],  cells[37+plus],]
    p = re.compile(r'<.*?>')#αφαιρούμε τα html tags και κρατάμε μόνο τα περιεχόμενα του κελιού
 
    data=[]
 
    for i in td:
        cellcontents = p.sub('', str(i)).strip()#αφαιρούμε περιττά κενά στην αρχή και το τελός των περιεχομένων του κελιού
        cleancellcontents=cellcontents.replace("n", "") #αφαιρούμε περιττούς χαρακτήρες που ορίζουν νέες γραμμές
        cleancellcontents=cleancellcontents.replace("t", "") #αφαιρούμε περιττούς χαρακτήρες tab
        cleancellcontents=cleancellcontents.strip()
        data.append(cleancellcontents)
 
    return data
 
def converttoDD(coords):
        #Καθαρίζω τις συντεταγμένες από περιττούς χαρακτήρες και κενά
        coords= coords.replace(' ', '')
        coords= coords.replace('N', '')
        coords= coords.replace('E', '')
        coords= coords.replace('Ν', '')#Ν με ελληνικούς χαρακτήρες
        coords= coords.replace('Ε', '')#Ε με ελληνικούς χαρακτήρες
        coords= coords.replace(',', '')
        coords= coords.replace('΄', '')
        coords= coords.replace(';', '')
        coords= coords.replace('°', '')
        coords= coords.replace('.', '')
        coords= coords.replace('`', '')
 
        y= float( coords[0:2]) + (float( coords[2:4])/60)  + ((  float(coords[4:6] ) +  float(coords[6:7])/10)  /3600)
        x= float( coords[8:10]) + (float( coords[10:12])/60)  + ((  float(coords[12:14] ) +  float(coords[14:15])/10)  /3600)
 
        xy=[x, y]
 
        return xy
 
def checkrivers(river):
    if river.find("Αχέροντας") >= 0:
        return "axerontas"
    if river.find("ραχθος") >= 0:
        return "araxthos"
    if river.find("Αώος") >= 0:
        return "aoos"
    if river.find("Δρίνος") >= 0:
        return "drinos"
    if river.find("Καλαμάς") >= 0:
        return "kalamas"
    if river.find("Ξάνθος") >= 0:
        return "ksanthos"
 
gefiriid=1
gefyria=[]
while gefiriid

Αφού εκτελέστηκε το script εντοπίστηκαν 18 εγγραφές (γεφύρια) με λανθασμένες ή ελλειπώς καταγεγγραμένες συντεταγμένες. Στον επόμενο πίνακα παρατίθενται τα γεφύρια αυτά μαζί με τα ID τους.

Πίνακας 1. Γεφύρια με λανθασμένες συντεταγμένες

ID Ονομασία γεφυριού
15 Γεφύρι στο Μεγάλο Λαγκάδι
24 Γεφύρι του Βουρκοπόταμου
36 Γεφύρι του Στέργιου
47 Γεφύρι της Θεοτόκου
82 Καλογερικό γεφύρι ή Πλακίδα
84 Γεφύρι στη Βρύση του Δεσπότη
85 Γεφύρι του Μύλου
95 Γεφύρι στον Λάκκο Ρωμιάς ή Γεφύρι στις Μιάσες
105 Γεφύρι του Μύλου (Κήπων)
108 Γεφύρι στον Άγιο
110 Γεφύρι του Πετσώνη
128 Γεφύρι του Κώτη
130 Γεφύρι της Γκούρας
136 Γεφύρι της Γκάνας
141 Γεφύρι του Λώλη ή του Λάκκου
142 Γεφύρι στον Άγιο Νικόλαο
143 Γεφύρι της Πλάκας
149 Γεφύρι της Άρτας


Το shapefile με τις θέσεις των γεφυριών εντάχθηκε σε ένα σύστημα γεωγραφικών πληροφοριών με σκοπό την χαρτογράφησή του όπου περιλαμβάνει του ψηφιακό μοντέλο εδάφους, το υδρογραφικό δίκτυο, τις λίμνες και τα διοικητικά όρια των νομών. Το λογισμικό ΣΓΠ που χρησιμοποιήθηκε είναι το QGIS (ανοικτού κώδικα). Τα πεδία που περιέχει η σχετική ιστοσελίδα για κάθε γεφύρι μετατρέπονται σε πεδία του αρχείου shapefile όπου ο χρήστης μπορεί να αναζητήσει πληροφορίες καθώς πλοηγείται στο QGIS (μέσω του εργαλείου Identify) ή να εκτελέσει ερωτήματα τύπου SQL (π.χ. αναζήτησε τα γεφύρια που εντοπίζονται στον Καλαμά και είναι δίτοξα).

Εικόνα 1. Αναγνώριση γεφυριού στο QGIS με το εργαλείο Identify


Εικόνα 2. Αναζήτηση δεδομένων με την σύνταξη ερωτημάτων μορφής SQL


O παρακάτω χάρτης συντάχθηκε με την χρήση του λογισμικού ανοικτού κώδικα Qgis ενώ η περαιτέρω γραφιστική επιμέλεια (υπομνήμα, σελιδοποίηση) έγινε με την βοήθεια των λογισμικών Scribus και Inkscape.

Άμεσα εντοπίστηκαν και τα πρώτα σφάλματα καταγραφής στις θέσεις κάποιων γεφυριών. Έτσι το Γεφύρι του Τρίστενου, το οποίο εντοπίζεται στον νομό Ιωαννίνων, χαρτογραφήθηκε στην Αλβανία, βόρεια του Βουθρωτού. Αλλά και το Γεφύρι της Σκαρβένας που βρίσκεται στο ρέμα Κουίτσας στον Ν. Ιωαννίνων χαρτογραφήθηκε στον Αμβρακικό κόλπο! Επιπλέον έλεγχος στον χάρτη ενδέχεται να αποκαλύψει και άλλα σφάλματα που οφείλονται στην λανθασμένη καταγραφή της γεωγραφικής πληροφορίας.

Εντάσσοντας στο χαρτογραφικό υπόβαθρο τις λεκάνες απορροής των ποταμών (βλέπε Εικόνα 3) εντοπίστηκαν λανθασμένες ή αμφίβολες πληροφορίες όσον αφορά την κατάταξη των γεφυριών με βάση τον ποταμό στον οποίο εντοπίζονται. Με την χρήση του εργαλείου “Join attributes by Location” της εργαλειοθήκης fTools ταυτοποιήθηκε σε ποιά λεκάνη απορροής ανήκει. Στην συνέχεια έγινε σύγκριση με τα δεδομένα της ιστοσελίδας όπως αυτά μεταφέρθηκαν και παραμετροποιήθηκαν στον πίνακα των περιγραφικών δεδομένων του shapefile. Για παράδειγμα το Γεφύρι του Γκούμου στην Αγία Κυριακή (Πόποβο) Θεσπρωτίας εμπεριέχεται στην λεκάνη απορροής του ποταμού Καλαμά και όχι του ποταμού Αχέροντα όπως αναφέρεται στην σχετική ιστοσελίδα (βλέπε Εικόνα 4).

Εντοπίστηκαν τα εξής σφάλματα:

Πίνακας 2. Σφάλματα κατάταξης των γεφυριών ως προς τον ποταμό που εντάσσονται.

Ονομασία γεφυριού Ποταμός που αναφέρεται στην ιστοσελίδα Εντάσσεται στην λεκάνη απορροής του ποταμού
Γεφύρι στο Κορφίτο Άραχθος Άλλο
Γεφύρι του Γκούμου Αχέροντας Καλαμάς
Γεφύρι του Μεζάνη Αχέροντας Άλλο
Γεφύρι του Παπά Καλαμάς Αώος
Γεφύρι στην Ποταμιά Καλαμάς Αώος
Γεφύρι της Γκούρας Ξάνθος Καλαμάς
Γεφύρι του Κουβαρά Ξάνθος Αώος
Γεφύρι της Γκούμανης Άραχθος Καλαμάς



Εικόνα 3. Οι λεκάνες απορροής

Εικόνα 4. Το γεφύρι του Γκούμου σε σχέση με τις λεκάνες απορροής

Με την βοήθεια του εργαλείο ogr2ogr είναι δυνατή η μετατροπή του αρχείου shapefile σε kml και η προβολή των δεδομένων στο Google Earth. Η σχετική εντολή συντάσσεται ως εξής :

ogr2ogr -f "KML" -s_srs "EPSG:2100" -t_srs "EPSG:4326" gefyria.kml gf.shp

Το -f "KML" ορίζει ότι θέλουμε το αρχείο προορισμού να είναι kml.

Με το -s_srs "EPSG:2100" ορίζουμε ότι το προβολικό σύστημα του αρχείου προέλευσης είναι το ΕΓΣΑ ’87 (ο κωδικός EPSG του ΕΓΣΑ ’87 είναι 2100).

Με το -t_srs "EPSG:4326" ορίζουμε ότι το προβολικό σύστημα του αρχείου προέλευσης είναι το WGS84 (το προβολικό σύστημα δηλαδή που χρησιμοποιεί και το Google Earth).

Τέλος, τα αρχεία gefyria.kml gefyria.shp είναι τα αρχεία προορισμού και προέλευσης αντίστοιχα.

Το αποτέλεσμα φαίνεται στον παρακάτω χάρτη

Ενδεικτικά αναρτώνται δύο εικόνες με την απεικόνιση του αρχείου kml στο Google Earth.

Εικόνα 5. Το γεφύρι της Τύριας.
Εικόνα 6. Γενική άποψη των γεφυριών στον Ν. Ιωαννίνων

Comments

comments powered by Disqus