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 (π.χ. αναζήτησε τα γεφύρια που εντοπίζονται στον Καλαμά και είναι δίτοξα).
O παρακάτω χάρτης συντάχθηκε με την χρήση του λογισμικού ανοικτού κώδικα Qgis ενώ η περαιτέρω γραφιστική επιμέλεια (υπομνήμα, σελιδοποίηση) έγινε με την βοήθεια των λογισμικών Scribus και Inkscape.
Άμεσα εντοπίστηκαν και τα πρώτα σφάλματα καταγραφής στις θέσεις κάποιων γεφυριών. Έτσι το Γεφύρι του Τρίστενου, το οποίο εντοπίζεται στον νομό Ιωαννίνων, χαρτογραφήθηκε στην Αλβανία, βόρεια του Βουθρωτού. Αλλά και το Γεφύρι της Σκαρβένας που βρίσκεται στο ρέμα Κουίτσας στον Ν. Ιωαννίνων χαρτογραφήθηκε στον Αμβρακικό κόλπο! Επιπλέον έλεγχος στον χάρτη ενδέχεται να αποκαλύψει και άλλα σφάλματα που οφείλονται στην λανθασμένη καταγραφή της γεωγραφικής πληροφορίας.
Εντάσσοντας στο χαρτογραφικό υπόβαθρο τις λεκάνες απορροής των ποταμών (βλέπε Εικόνα 3) εντοπίστηκαν λανθασμένες ή αμφίβολες πληροφορίες όσον αφορά την κατάταξη των γεφυριών με βάση τον ποταμό στον οποίο εντοπίζονται. Με την χρήση του εργαλείου “Join attributes by Location” της εργαλειοθήκης fTools ταυτοποιήθηκε σε ποιά λεκάνη απορροής ανήκει. Στην συνέχεια έγινε σύγκριση με τα δεδομένα της ιστοσελίδας όπως αυτά μεταφέρθηκαν και παραμετροποιήθηκαν στον πίνακα των περιγραφικών δεδομένων του shapefile. Για παράδειγμα το Γεφύρι του Γκούμου στην Αγία Κυριακή (Πόποβο) Θεσπρωτίας εμπεριέχεται στην λεκάνη απορροής του ποταμού Καλαμά και όχι του ποταμού Αχέροντα όπως αναφέρεται στην σχετική ιστοσελίδα (βλέπε Εικόνα 4).
Εντοπίστηκαν τα εξής σφάλματα:
Πίνακας 2. Σφάλματα κατάταξης των γεφυριών ως προς τον ποταμό που εντάσσονται.
Ονομασία γεφυριού | Ποταμός που αναφέρεται στην ιστοσελίδα | Εντάσσεται στην λεκάνη απορροής του ποταμού |
---|---|---|
Γεφύρι στο Κορφίτο | Άραχθος | Άλλο |
Γεφύρι του Γκούμου | Αχέροντας | Καλαμάς |
Γεφύρι του Μεζάνη | Αχέροντας | Άλλο |
Γεφύρι του Παπά | Καλαμάς | Αώος |
Γεφύρι στην Ποταμιά | Καλαμάς | Αώος |
Γεφύρι της Γκούρας | Ξάνθος | Καλαμάς |
Γεφύρι του Κουβαρά | Ξάνθος | Αώος |
Γεφύρι της Γκούμανης | Άραχθος | Καλαμάς |
Με την βοήθεια του εργαλείο 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.
Comments
comments powered by Disqus