changeset 2798:5a654f2e35bc

Added a python tool to import shapefiles into database. flys-backend/trunk@4127 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 07 Mar 2012 20:37:03 +0000
parents e41d03bf9807
children 501f00e355eb
files flys-backend/ChangeLog flys-backend/contrib/shpimporter/shpimporter.py flys-backend/contrib/shpimporter/uesg.py flys-backend/contrib/shpimporter/utils.py
diffstat 4 files changed, 197 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/flys-backend/ChangeLog	Wed Mar 07 20:27:20 2012 +0000
+++ b/flys-backend/ChangeLog	Wed Mar 07 20:37:03 2012 +0000
@@ -1,4 +1,13 @@
-2012-03-06  Ingo Weinzierl <ingo@intevation.de>
+2012-03-07  Ingo Weinzierl <ingo@intevation.de>
+
+	* contrib/shpimporter/shpimporter.py,
+	  contrib/shpimporter/utils.py,
+	  contrib/shpimporter/uesg.py: A python based tool for importing
+	  shapefiles into a database. This tool is based on python because it
+	  makes use of GDAL OGR to read shapefiles and write features into
+	  database.
+
+2012-03-07  Ingo Weinzierl <ingo@intevation.de>
 
 	* doc/schema/postgresql-spatial.sql: Adapted the PostgreSQL schema for
 	  floodmaps.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/contrib/shpimporter/shpimporter.py	Wed Mar 07 20:37:03 2012 +0000
@@ -0,0 +1,30 @@
+import ogr
+import utils
+from uesg import UESG
+
+DBCONN='PG:dbname=flystest1 host=localhost user=flys password=flys port=5432'
+PATH='/**/**/**/flys3-testdaten/Saar/Hydrologie/UeSG/Berechnung'
+
+
+def getImporter():
+    return UESG(DBCONN)
+
+
+if __name__ == '__main__':
+    shapes = utils.findShapefiles(PATH)
+    print "Found %i Shapefiles" % len(shapes)
+
+    types = {}
+    importer = getImporter()
+
+    for shpTuple in shapes:
+        geomType = importer.walkOverShapes(shpTuple)
+        try:
+            num = types[geomType]
+            types[geomType] = num+1
+        except:
+            types[geomType] = 1
+
+    for key in types:
+        print "%i x geometry type %s" % (types[key], key)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/contrib/shpimporter/uesg.py	Wed Mar 07 20:37:03 2012 +0000
@@ -0,0 +1,137 @@
+import ogr
+
+TABLE_NAME="floodmaps"
+
+class UESG:
+
+    def __init__(self, dbconn):
+        self.dbconn = dbconn
+
+
+    def isGeometryValid(self, geomType):
+        if geomType == 3 or geomType == 6:
+            return True
+        else:
+            return False
+
+
+    def getKind(self, path):
+        kind = 0
+        if path.find("Berechnung") > 0:
+            kind = kind + 100
+
+            if path.find("Aktuell") > 0:
+                kind = kind + 10
+            else:
+                kind = kind + 20
+
+            if path.find("Land") > 0:
+                kind = kind + 2
+            else:
+                kind = kind + 1
+        else:
+            kind = kind + 200
+
+        return kind
+
+
+    def walkOverShapes(self, shape):
+        (name, path) = shape
+        shp = ogr.Open(shape[1])
+        if shp is None:
+            print "Shapefile '%s' could not be opened!" % path
+            return
+
+        print "Opened shapefile '%s'" % path
+        srcLayer = shp.GetLayerByName(name)
+
+        if srcLayer is None:
+            print "Layer '%s' was not found!" % name
+            return
+
+        return self.shape2Database(srcLayer, name, self.getKind(path))
+
+
+    def shape2Database(self, srcLayer, name, kind):
+        table = ogr.Open(self.dbconn)
+        destLayer = table.GetLayerByName(TABLE_NAME)
+
+        if srcLayer is None:
+            print "Shapefile is None!"
+            return -1
+
+        if destLayer is None:
+            print "No destination layer given!"
+            return -1
+
+        count = srcLayer.GetFeatureCount()
+        print "Try to add %i features to database." % count
+
+        srcLayer.ResetReading()
+
+        geomType = -1
+
+        featureDef = destLayer.GetLayerDefn()
+
+        for feat in srcLayer:
+            geom = feat.GetGeometryRef()
+            geomType = geom.GetGeometryType()
+
+            newFeat = self.createNewFeature(featureDef, feat)
+            newFeat.SetField("kind", kind)
+            newFeat.SetField("name", name)
+
+            if self.isGeometryValid(geomType):
+                res = destLayer.CreateFeature(newFeat)
+                if res is None or res > 0:
+                    print "Error while inserting feature: %r" % res
+            else:
+                print "Geometry type not supported: %i" % geomType
+
+        try:
+            destLayer.CommitTransaction()
+        except e:
+            print "Exception while committing transaction."
+
+        return geomType
+
+
+    def createNewFeature(self, featureDef, feat):
+        newFeat = ogr.Feature(featureDef)
+        newFeat.SetGeometry(feat.GetGeometryRef())
+
+        if feat.IsFieldSet("river_id"):
+            riverId = feat.GetField("river_id")
+        else:
+            riverId = 1
+
+        if feat.IsFieldSet("diff"):
+            diff = feat.GetFieldAsDouble("diff")
+        else:
+            diff = 0
+
+        if feat.IsFieldSet("count"):
+            count = feat.GetFieldAsInteger("count")
+        else:
+            count = 0
+
+        if feat.IsFieldSet("area"):
+            area = feat.GetFieldAsDouble("area")
+        else:
+            area = 0
+
+        if feat.IsFieldSet("perimeter"):
+            perimeter = feat.GetFieldAsDouble("perimeter")
+        else:
+            perimeter = 0
+
+        groupId = 2
+
+        newFeat.SetField("river_id", riverId)
+        newFeat.SetField("diff", diff)
+        newFeat.SetField("count", count)
+        newFeat.SetField("area", area)
+        newFeat.SetField("perimeter", perimeter)
+
+        return newFeat
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-backend/contrib/shpimporter/utils.py	Wed Mar 07 20:37:03 2012 +0000
@@ -0,0 +1,20 @@
+import os
+
+SHP='.shp'
+
+def findShapefiles(path):
+    shapes = []
+
+    for root, dirs, files in os.walk(path):
+        if len(files) == 0:
+            continue
+
+        print "Processing directory '%s' with %i files " % (root, len(files))
+
+        for f in files:
+            idx = f.find(SHP)
+            if (idx+len(SHP)) == len(f):
+                shapes.append((f.replace(SHP, ''), root + "/" + f))
+
+    return shapes
+

http://dive4elements.wald.intevation.org