nhueffme: thuban/Extensions/ogr __init__.py, 1.1, 1.2 ogrshapes.py, 1.3, 1.4 ogrstart.py, 1.2, 1.3

cvs@intevation.de cvs at intevation.de
Wed Jan 26 10:17:04 CET 2005


Author: nhueffme

Update of /thubanrepository/thuban/Extensions/ogr
In directory doto:/tmp/cvs-serv21822/Extensions/ogr

Modified Files:
	__init__.py ogrshapes.py ogrstart.py 
Log Message:
Ogr extension works now for shapefiles, GML files and DGN files. Files can be viewed and tables can be shown. For unknown shapetypes the identify mode does not work yet.



Index: __init__.py
===================================================================
RCS file: /thubanrepository/thuban/Extensions/ogr/__init__.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- __init__.py	8 Dec 2004 15:43:10 -0000	1.1
+++ __init__.py	26 Jan 2005 09:17:01 -0000	1.2
@@ -0,0 +1,33 @@
+# Copyright (C) 2004 by Intevation GmbH
+# Authors:
+# Nina Hueffmeyer <nhueffme at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+__version__ = "$Revision$"
+# $Source$
+# $Id$
+
+# import the actual modules
+from os import environ
+try:
+    dummy = environ["DISPLAY"]
+    import OGR
+    import maplegend
+except:
+    pass # we don't have a DISPLAY, so don't import the modules
+         # (we probably are in test-mode)
+         # Not sure whether this is the best method to avoid problems
+         # in the global test routine.
+
+# perform the registration of the extension
+from Thuban import _
+from Thuban.UI.extensionregistry import ExtensionDesc, ext_registry
+
+ext_registry.add(ExtensionDesc(
+    name = 'OGRstart',
+    version = '0.9.0',
+    authors= [ 'Nina Hüffmeyer' ],
+    copyright = '2004 Intevation GmbH',
+    desc = _("Open a file supported by ogr.")))

Index: ogrshapes.py
===================================================================
RCS file: /thubanrepository/thuban/Extensions/ogr/ogrshapes.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- ogrshapes.py	20 Dec 2004 14:13:57 -0000	1.3
+++ ogrshapes.py	26 Jan 2005 09:17:01 -0000	1.4
@@ -26,6 +26,7 @@
 from Thuban.Model.data import SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
 from Thuban.Model.data import RAW_PYTHON, RAW_SHAPEFILE, RAW_WKT
 
+SHAPETYPE_UNKNOWN = "unknown"
 
 def has_ogr_support():
     """Return whether this Thuban instance supports ogr file formats
@@ -39,7 +40,8 @@
     # mapping from ogr-lib shapetype and table constants to our constants
     ogrlib_shapetypes = {ogr.wkbPolygon: SHAPETYPE_POLYGON,
                 ogr.wkbLineString: SHAPETYPE_ARC,
-                ogr.wkbPoint: SHAPETYPE_POINT}
+                ogr.wkbPoint: SHAPETYPE_POINT,
+                ogr.wkbUnknown: SHAPETYPE_UNKNOWN}
 
     fieldtype_map = {ogr.OFTString: table.FIELDTYPE_STRING,
                 ogr.OFTInteger: table.FIELDTYPE_INT,
@@ -66,16 +68,28 @@
     def ShapeID(self):
         return self.shapeid
 
-    # diese Methode funktioniert vielleicht noch nicht für andere Formate 
-    #als shp
-    #(wenn ein polygon aus mehreren
-    # Ringen besteht o.ä., hat ein Geometry-Objekt mehr als einen 
-    #GeometryRef().---------
     def Points(self):
         """Return the coordinates of the shape as a list of lists of pairs"""
+        print "FID: %s" %(self.shapeid)
+        shape = []
+        #spatialFilter = self.ogrlayer.GetSpatialFilter()
+        
+#        if spatialFilter is not None:
+        self.ogrlayer.SetSpatialFilter(None)
+  #          feature = self.ogrlayer.GetFeature(self.shapeid)
+   #         self.ogrlayer.SetSpatialFilter(spatialFilter)
+    #    else:
         feature = self.ogrlayer.GetFeature(self.shapeid)
+      
+        if feature is None:
+	    print "feature is none.........................."
+            return shape.append([])
         geom = feature.GetGeometryRef()
-        shape = []
+
+        if geom is None:
+	    print "geom is none................................"
+            return shape.append([])
+
         # if geometry object is of type point or line
         if geom.GetGeometryCount() == 0:
             points =[]
@@ -83,12 +97,13 @@
                 x = geom.GetX(point)
                 y = geom.GetY(point)
                 points.append((x, y))
+            print points
             return [points]
         # if geometry object is of type polygon or multipolygon
         for i in range(geom.GetGeometryCount()):
             points = []
-	    geometry = geom.GetGeometryRef(i)
-	    # if geometry object is polygon
+            geometry = geom.GetGeometryRef(i)
+            # if geometry object is polygon
             if geometry.GetGeometryCount() == 0:
                 for point in range(geometry.GetPointCount()):
                     x = geometry.GetX(point)
@@ -96,7 +111,7 @@
                     points.append((x, y))
                 shape.append(points)
             # if geometry object is of type multipolygon
-	    else:
+            else:
                 for j in range(geometry.GetGeometryCount()):
                     points = []
                     subgeom = geometry.GetGeometryRef(j)
@@ -105,6 +120,7 @@
                         y = subgeom.GetY(point)
                         points.append((x, y))
                     shape.append(points)
+	print shape
         return shape
 
     def RawData(self):
@@ -128,26 +144,38 @@
         # session we need to compare absolute paths and it's usually
         # safer to always work with absolute paths.
 
-        self.filename = os.path.abspath(filename)
+        self.filename = filename
         self.layername = layername
 
-        self.ogrdatasource = ogr.Open(self.filename)
+        self.ogrdatasource = ogr.Open(filename)
         self.ogrlayer = (self.ogrdatasource).GetLayerByName(layername)
-        self.table = OGRTable(self.ogrdatasource, self.ogrlayer)
+
+        driver = self.ogrdatasource.GetDriver().GetName()
+        if driver == 'PostgreSQL':
+            self.id_column = 'gid'
+        else:
+            self.id_column = 'fid'
+
+        self.table = OGRTable(self.ogrdatasource, self.ogrlayer, self.id_column)
 
         self._open_ogrlayer(layername)
 
     def _open_ogrlayer(self, layername):
         self.numshapes = self.ogrlayer.GetFeatureCount()
         self.shapetype = self.ogrlayer.GetLayerDefn().GetGeomType()
-        extent = self.ogrlayer.GetExtent()
 
+        extent = self.ogrlayer.GetExtent()
         if extent:
             self.bbox = [extent[0], extent[2], extent[1], extent[3]]
         else:
             self.bbox = None
 
-        self.shapetype = ogrlib_shapetypes[self.shapetype]
+        if self.shapetype is not ogr.wkbUnknown:
+            self.shapetype = ogrlib_shapetypes[self.shapetype]
+        #else:
+            # this should be ogr.wkbUnknown, but Thuban does not know how 
+	    # to handle an unknown shapetype (e.g. Session Tree)
+            #self.shapetype = ogrlib_shapetypes[ogr.wkbPoint]
 
     def OGRLayer(self):
         """Return the OGRLayer object"""
@@ -195,7 +223,10 @@
         ogrlayer = self.ogrlayer
 
         left, bottom, right, top = bbox
-
+	print "features in bbox: "
+	print ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
+                                 %(left, bottom, left, top, right, top, 
+                                  right, bottom, left, bottom))
         # create a geometry which can be passed to the layer as spatial filter
         bboxpolygon = ogr.CreateGeometryFromWkt(
                       ('Polygon((%s %s, %s %s, %s %s,%s %s, %s %s))'
@@ -206,8 +237,10 @@
             bboxpolygon.AssignSpatialReference(ogrlayer.GetSpatialRef())
 
         ogrlayer.ResetReading()
+        #ogrlayer.SetSpatialFilterRect(left, bottom, right, top)
         ogrlayer.SetSpatialFilter(bboxpolygon)
         numFeatures = ogrlayer.GetFeatureCount()
+	print numFeatures
         for feature in range(numFeatures):
             nextFeature = ogrlayer.GetNextFeature()
             yield cls(ogrlayer, nextFeature.GetFID())
@@ -216,8 +249,11 @@
 
     def AllShapes(self):
         """Return an iterable over the shapes in the shape store."""
-        for i in xrange(self.NumShapes()):
-            yield OGRShape(self.ogrlayer, i)
+        self.ogrlayer.ResetReading()
+        nextFeature = self.ogrlayer.GetNextFeature()
+        while nextFeature is not None:
+            yield OGRShape(self.ogrlayer, nextFeature.GetFID())
+            nextFeature = self.ogrlayer.GetNextFeature()
 
     def Shape(self, index):
         """Return the shape with index index"""
@@ -241,7 +277,7 @@
     """A Table for an ogr file
     """
 
-    def __init__(self, ds, layer):
+    def __init__(self, ds, layer, id_column):
         """Initialize the OGRTable.
 
         ds should be an instance of OGRDatasource.
@@ -251,10 +287,14 @@
         self.datasource = ds
         self.layer = layer
         self.tablename = layer.GetName()
+        self.id_column = id_column
 
         # Map column names and indices to column objects.
         self.column_map = {}
 
+        # Map feature ids to ordinals.
+        self._map_ords_and_ids()
+
         self._fetch_table_information()
 
     def _fetch_table_information(self):
@@ -275,6 +315,24 @@
             self.column_map[col.name] = col
             self.column_map[col.index] = col
 
+    def _map_ords_and_ids(self):
+        self.ordinals = {}
+        self.ids = {}
+
+        lay = self.datasource.ExecuteSQL(
+                "SELECT %s from %s"
+                %(self.id_column, self.tablename))
+        lay.ResetReading()
+        nextFeature = lay.GetNextFeature()
+        ord = 0
+        while nextFeature is not None:
+            id = nextFeature.GetFID()
+            self.ordinals[ord] = id
+            self.ids[id] = ord
+            nextFeature = lay.GetNextFeature()
+            ord = ord + 1
+        self.datasource.ReleaseResultSet(lay)
+
     def TableName(self):
         """Return the name of the table, which is the name of the layer"""
         return self.tablename
@@ -282,7 +340,7 @@
     def Title(self):
         """Return the title of the table.
 
-        The title is currently fixed and equal to the tablename
+        The title is currently
         """
         return self.tablename
 
@@ -316,20 +374,48 @@
 
     def RowIdToOrdinal(self, gid):
         """Return the row ordinal given its id"""
-        return self.layer.GetFeature(gid).GetFID()
+        if gid < 0:
+            return gid
+        else:
+            ord = self.ids[gid]
+            return ord
+#        lay = self.datasource.ExecuteSQL(
+ #               "SELECT COUNT(%s) From %s where FID < %s"
+  #              %(self.id_column, self.tablename, gid))
+   #     ord = lay.GetFeature(0).GetField(0)
+    #    self.datasource.ReleaseResultSet(lay)
+ #       return ord
 
     def RowOrdinalToId(self, num):
         """Return the rowid for given its ordinal"""
-        return self.layer.GetFeature(num).GetFID()
+#        lay = self.datasource.ExecuteSQL(
+ #               "SELECT FID From %s"
+  #              %(self.tablename))
+   #     for i in range(num):
+    #        lay.GetNextFeature()
+     #   id = lay.GetNextFeature().GetField(0)
+      #  self.datasource.ReleaseResultSet(lay)
+        if num >= 0:
+            id = self.ordinals[num]
+            return id
+        else:
+            return num
 
     def ReadRowAsDict(self, row, row_is_ordinal = 0):
         """Return a dictionary which contains all the fields."""
+        if row_is_ordinal == 1:
+            rowId = self.RowOrdinalToId(row)
+        else:
+            rowId = row
         layerdef = self.layer.GetLayerDefn()
-        feature = self.layer.GetFeature(row)
+        feature = self.layer.GetFeature(rowId)
         result = {}
-        for i in range(feature.GetFieldCount()):
+        for i in range(len(self.columns)):
             fielddef = layerdef.GetFieldDefn(i)
-            result[fielddef.GetName()] = feature.GetField(i)
+            if feature is not None:
+                result[self.columns[i].name] = feature.GetField(i)
+            else:
+                result[fielddef.GetName()] = None
         return result
 
     def ReadValue(self, row, col, row_is_ordinal = 0):
@@ -383,8 +469,9 @@
         else:
             right_template = right
 
-        query = ("SELECT FID FROM %s WHERE '%s' %s %s ORDER BY FID"
-                % (self.tablename,left.name, comparison, right_template))
+        query = ("SELECT %s FROM %s WHERE '%s' %s %s ORDER BY FID"
+                % (self.id_column, self.tablename,left.name, comparison, 
+                   right_template))
 
         lay = self.datasource.ExecuteSQL(query)
         result = []
@@ -393,7 +480,8 @@
             if feature is None:
                 break
             result.append(feature.GetField(0))
-        self.datasource.ReleaseResultSet(lay)
+        if lay is not None:
+            self.datasource.ReleaseResultSet(lay)
         return result
 
 

Index: ogrstart.py
===================================================================
RCS file: /thubanrepository/thuban/Extensions/ogr/ogrstart.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ogrstart.py	20 Dec 2004 14:13:57 -0000	1.2
+++ ogrstart.py	26 Jan 2005 09:17:01 -0000	1.3
@@ -20,23 +20,22 @@
 from Thuban import _
 
 from Thuban.Model.layer import Layer
+from Thuban.UI.dbdialog import DBDialog
 
 # Import ogr related classes
 from Extensions.ogr import ogrshapes, ogrdialog
+from Extensions.ogr.ogrdialog import ChooseOGRDBTableDialog
 
 def open_with_ogr(context):
-    '''Export data depending on the set properties.
-
-    This is the main export funcation.
+    '''Open a file supported by ogr.
     '''
     canvas = context.mainwindow.canvas
-    file = None
     map = canvas.Map()
 
     # Get the file to be opened
     dlg = wxFileDialog(canvas, _("Select a data file"),
                            ".", "",
-                           _("Shapefiles (*.shp)") + "|*.shp;*.SHP|" +
+                           _("Shape/GML files (*.shp/*.gml)") + "|*.shp;*.gml|" +
                            _("All Files (*.*)") + "|*.*",
                            wxOPEN | wxMULTIPLE)
 
@@ -45,14 +44,16 @@
         for filename in filenames:
             title = os.path.splitext(os.path.basename(filename))[0]
             has_layers = map.HasLayers()
-            layername = title
+            layerDlg = ogrdialog.ChooseLayer(canvas, filename)
+            if layerDlg.ShowModal() == wxID_OK:
+                layername = layerDlg.GetLayer()
             try:
                 session = context.application.Session()
                 store = ogrshapes.OGRShapeStore(session, filename, layername)
                 session.AddShapeStore(store)
-            except IOError:
+            except:
                 # the layer couldn't be opened
-                self.RunMessageBox(("Add Layer"),
+                context.mainwindow.RunMessageBox(("Add Layer"),
                                 ("Can't open the file '%s'.")%filename)
             else:
                 layer = Layer(title, store)
@@ -64,6 +65,55 @@
                 context.application.SetPath("data",filename)
         dlg.Destroy()
 
+def select_file_format(context):
+    ''' Display all available supported formats.
+    '''
+
+    canvas = context.mainwindow.canvas
+    file = None
+    map = canvas.Map()
+
+    session = context.application.Session()
+
+    dlg = ogrdialog.ChooseFileFormat(canvas, session)
+
+    if dlg.ShowModal() == wxID_OK:
+        context.mainwindow.RunMessageBox("dialog auf", "dialog auf")
+    dlg.Destroy()
+
+def open_db(context):
+    ''' Open a table in a database as a layer.
+    '''
+
+    canvas = context.mainwindow.canvas
+    map = canvas.Map()
+    
+    session = context.application.Session() 
+    dlg = ChooseOGRDBTableDialog(canvas, session)
+
+    if dlg.ShowModal() == wxID_OK:
+        dbconn, dbtable = dlg.GetTable()
+        try:
+            # Choose the correct Interface for the database type
+            filename = ('PG: host=%s user=%s dbname=%s port=%s' 
+                        %(dbconn.host, dbconn.user, dbconn.dbname, dbconn.port))
+
+            store = ogrshapes.OGRShapeStore(session, filename, dbtable)
+            session.AddShapeStore(store)
+
+            layer = Layer(dbtable, store)
+
+            has_layers = map.HasLayers()
+            map.AddLayer(layer)
+            if not has_layers:
+                canvas.FitMapToWindow()
+        except:
+            # Some error occured while initializing the layer
+            context.mainwindow.RunMessageBox(_("Add Layer from database"),
+                               _("Can't open the database table '%s'")
+                               % dbtable)
+    dlg.Destroy()
+
 
 
 # Thuban has named commands which can be registered in the central
@@ -80,7 +130,16 @@
 
 # find the ogr menu (create it a new if not found)
 ogr_menu = main_menu.FindOrInsertMenu('ogr', _('OGR'))
+registry.Add(Command('select_file_format', 'Select a file format', 
+                     select_file_format, 
+                     helptext = "Select a file format supported from ogr"))
+
+registry.Add(Command('open_db', 'Open a layer from a database',
+                     open_db,
+                     helptext = "Open a layer from a database, e.g. PostGIS"))
 
 # finally bind the new command with an entry in the extensions menu
 ogr_menu.InsertItem('open_ogr_files')
+ogr_menu.InsertItem('select_file_format')
+ogr_menu.InsertItem('open_db')
 





More information about the Thuban-devel mailing list

This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)