Exemple #1
0
 def __init__(self,
              name,
              writable=0,
              lockfile=0,
              dsn=None,
              layer=None,
              attribute_cols='',
              **args):
     DataSource.__init__(self, name, **args)
     if int(writable) and lockfile:
         self.lock = Lock(lockfile)
     else:
         self.lock = None
     self.ds = ogr.Open(dsn, int(writable))
     if layer:
         self.layer = self.ds.GetLayerByName(layer)
     else:
         self.layer = self.ds.GetLayer(0)
     self.defn = self.layer.GetLayerDefn()
     self.fields = [
         self.defn.GetFieldDefn(i) for i in range(self.defn.GetFieldCount())
     ]
     if attribute_cols:
         self.attribute_cols = [
             x.lower() for x in attribute_cols.split(',')
         ]
     else:
         self.attribute_cols = None
Exemple #2
0
 def __init__(self, name, writable=0, lockfile=None, unique=None, **args):
     DataSource.__init__(self, name, **args)
     self.db = Recno(args["file"])
     self.append = self.db.append
     self.writable = int(writable)
     self.unique = unique
     if self.writable and lockfile:
         self.lock = Lock(lockfile)
     else:
         self.lock = None
Exemple #3
0
 def __init__(self, name, writable = 0, lockfile = None, **args):
     DataSource.__init__(self, name, **args)
     self.db = Recno( args["file"] )
     self.append = self.db.append
     self.writable = int(writable)
     if self.writable and lockfile:
         self.lock = Lock(lockfile)
     else:
         self.lock = None
Exemple #4
0
 def __init__(self, name, writable = 0, lockfile = 0, 
                          dsn = None, layer = None, **args):
     DataSource.__init__(self, name, **args)
     if int(writable) and lockfile: 
         self.lock = Lock(lockfile)
     else:
         self.lock = None
     self.ds     = ogr.Open( dsn, int(writable) )
     if layer:
         self.layer  = self.ds.GetLayerByName(layer)
     else:
         self.layer  = self.ds.GetLayer(0)
     self.defn   = self.layer.GetLayerDefn()
     self.fields = [self.defn.GetFieldDefn(i)
                     for i in range(self.defn.GetFieldCount())]
Exemple #5
0
 def __init__(self, name, writable=0, lockfile=0, dsn=None, layer=None, attribute_cols="", **args):
     DataSource.__init__(self, name, **args)
     if int(writable) and lockfile:
         self.lock = Lock(lockfile)
     else:
         self.lock = None
     self.ds = ogr.Open(dsn, int(writable))
     if layer:
         self.layer = self.ds.GetLayerByName(layer)
     else:
         self.layer = self.ds.GetLayer(0)
     self.defn = self.layer.GetLayerDefn()
     self.fields = [self.defn.GetFieldDefn(i) for i in range(self.defn.GetFieldCount())]
     if attribute_cols:
         self.attribute_cols = [x.lower() for x in attribute_cols.split(",")]
     else:
         self.attribute_cols = None
Exemple #6
0
class DBM (DataSource):
    """Simple datasource using the anydbm module and pickled datastructures."""
    def __init__(self, name, writable = 0, lockfile = None, unique = None, **args):
        DataSource.__init__(self, name, **args)
        self.db = Recno( args["file"] )
        self.append = self.db.append
        self.writable = int(writable)
        self.unique = unique
        if self.writable and lockfile:
            self.lock = Lock(lockfile)
        else:
            self.lock = None

    def __iter__ (self):
        return self.db.__iter__()

    def begin (self):
        if self.lock: return self.lock.lock()

    def commit (self):
        if hasattr(self.db, "sync"): self.db.sync()
        if self.lock: self.lock.unlock()

    def rollback (self):
        if self.lock: self.lock.unlock()

    def insert (self, action):
        if self.unique:
            action.id = self.insertUnique(action.feature)
        else:
            thunk = self.freeze_feature(action.feature)
            action.id = self.append(thunk)
        return self.select(action)
    
    def insertUnique(self, feature):
        if not feature.properties.has_key(self.unique):
           raise Exception("Unique key (%s) missing from feature." % self.unique)
        action = Action()
        action.attributes[self.unique] = feature.properties[self.unique]
        features = self.select(action)
        if len(features) > 1:
            raise Exception("There are two features with the unique key %s. Something's wrong with that." % feature.properties[self.unique])
        thunk = self.freeze_feature(feature)
        if len(features) == 0:
            return self.append(thunk)
        else:
            self.db[features[0].id] = thunk
            return features[0].id
    
    def update (self, action):
        self.db[action.id] = self.freeze_feature(action.feature)
        return self.select(action)
        
    def delete (self, action):
        feature = action.feature
        if action.id:
            del self.db[action.id]
        elif action.attributes:
            for feat in self.select(action):
                del self.db[feat.id]
        return []

    def select (self, action):
        def _overlap (a, b):
            return a[2] >= b[0] and \
                   b[2] >= a[0] and \
                   a[3] >= b[1] and \
                   b[3] >= a[1]

        if action.id is not None:
            feature = self.thaw_feature( self.db[action.id] )
            feature.id = action.id
            return [feature]
        else:
            result = []
            count  = action.maxfeatures
            counter = 0
            for id in self:
                if counter < action.startfeature:
                    counter += 1
                    continue
                thunk = self.db[id]
                feature = self.thaw_feature(thunk)
                feature.id = id
                if action.bbox and not _overlap(action.bbox, feature.bbox):
                    continue
                if action.attributes:
                    props = feature.properties
                    skip  = False
                    for key, val in action.attributes.items():
                        if (key not in props and val is not None) or \
                           (key in props and str(props[key]) != val):
                            skip = True
                            break
                    if skip: continue
                result.append(feature)
                if count is not None:
                    count -= 1
                    if not count: break
            return result

    def freeze_feature (self, feature):
        feature.bbox = feature.get_bbox()
        return pickle.dumps(feature)

    def thaw_feature (self, thunk):
        return pickle.loads(thunk)
Exemple #7
0
class DBM(DataSource):
    """Simple datasource using the anydbm module and pickled datastructures."""
    def __init__(self, name, writable=0, lockfile=None, unique=None, **args):
        DataSource.__init__(self, name, **args)
        self.db = Recno(args["file"])
        self.append = self.db.append
        self.writable = int(writable)
        self.unique = unique
        if self.writable and lockfile:
            self.lock = Lock(lockfile)
        else:
            self.lock = None

    def __iter__(self):
        return self.db.__iter__()

    def begin(self):
        if self.lock: return self.lock.lock()

    def commit(self):
        if hasattr(self.db, "sync"): self.db.sync()
        if self.lock: self.lock.unlock()

    def rollback(self):
        if self.lock: self.lock.unlock()

    def insert(self, action):
        if self.unique:
            action.id = self.insertUnique(action.feature)
        else:
            thunk = self.freeze_feature(action.feature)
            action.id = self.append(thunk)
        return self.select(action)

    def insertUnique(self, feature):
        if not feature.properties.has_key(self.unique):
            raise Exception("Unique key (%s) missing from feature." %
                            self.unique)
        action = Action()
        action.attributes[self.unique] = feature.properties[self.unique]
        features = self.select(action)
        if len(features) > 1:
            raise Exception(
                "There are two features with the unique key %s. Something's wrong with that."
                % feature.properties[self.unique])
        thunk = self.freeze_feature(feature)
        if len(features) == 0:
            return self.append(thunk)
        else:
            self.db[features[0].id] = thunk
            return features[0].id

    def update(self, action):
        self.db[action.id] = self.freeze_feature(action.feature)
        return self.select(action)

    def delete(self, action):
        feature = action.feature
        if action.id:
            del self.db[action.id]
        elif action.attributes:
            for feat in self.select(action):
                del self.db[feat.id]
        return []

    def select(self, action):
        def _overlap(a, b):
            return a[2] >= b[0] and \
                   b[2] >= a[0] and \
                   a[3] >= b[1] and \
                   b[3] >= a[1]

        if action.id is not None:
            feature = self.thaw_feature(self.db[action.id])
            feature.id = action.id
            return [feature]
        else:
            result = []
            count = action.maxfeatures
            counter = 0
            for id in self:
                if counter < action.startfeature:
                    counter += 1
                    continue
                thunk = self.db[id]
                feature = self.thaw_feature(thunk)
                feature.id = id
                if action.bbox and not _overlap(action.bbox, feature.bbox):
                    continue
                if action.attributes:
                    props = feature.properties
                    skip = False
                    for key, val in action.attributes.items():
                        if (key not in props and val is not None) or \
                           (key in props and str(props[key]) != val):
                            skip = True
                            break
                    if skip: continue
                result.append(feature)
                if count is not None:
                    count -= 1
                    if not count: break
            return result

    def freeze_feature(self, feature):
        feature.bbox = feature.get_bbox()
        return pickle.dumps(feature)

    def thaw_feature(self, thunk):
        return pickle.loads(thunk)
Exemple #8
0
class OGR (DataSource):
    """Uses the ogr Python bindings to query/update/delete an OGR 
       datasource. Feature support is limited in the same way as 
       OGR's underlying datasource.""" 
    freeze_type = {
        ogr.wkbPoint            : "Point",
        ogr.wkbLineString       : "Line",
        ogr.wkbPolygon          : "Polygon",
        ogr.wkbMultiPoint       : "Point",
        ogr.wkbMultiLineString  : "Line",
        ogr.wkbMultiPolygon     : "Polygon"
    }
    # thaw_type = dict(map(lambda (x,y): (y,x), freeze_type.items()))
    thaw_type = {
        "Point"     : ogr.wkbPoint,
        "Line"      : ogr.wkbLineString,
        "Polygon"   : ogr.wkbPolygon
    }
    error_msgs = [
        "OK",
        "Not enough data",
        "Not enough memory",
        "Unsupported geometry type",
        "Unsupported operation",
        "Corrupt data",
        "Unknown failure",
        "Unsupported SRS"
    ]

    def __init__(self, name, writable = 0, lockfile = 0, 
                             dsn = None, layer = None, **args):
        DataSource.__init__(self, name, **args)
        if int(writable) and lockfile: 
            self.lock = Lock(lockfile)
        else:
            self.lock = None
        self.ds     = ogr.Open( dsn, int(writable) )
        if layer:
            self.layer  = self.ds.GetLayerByName(layer)
        else:
            self.layer  = self.ds.GetLayer(0)
        self.defn   = self.layer.GetLayerDefn()
        self.fields = [self.defn.GetFieldDefn(i)
                        for i in range(self.defn.GetFieldCount())]
    
    def create (self, action):
        feature = self.thaw_feature(action.feature)
        err = self.layer.CreateFeature(feature)
        if err:
            raise ogr.OGRError("Create error: %s" % self.error_msgs[err])
        action.id = feature.GetFID()
        feature.Destroy()
        if action.id > 0: # because the OGR PostGIS driver sux
            return self.select(action)
        else:
            action.feature.id = action.id
            return [action.feature]

    def update (self, action):
        feature = self.thaw_feature(action.feature)
        feature.SetFID(action.id)
        err = self.layer.SetFeature(feature)
        if err:
            raise ogr.OGRError("Update error on FID %d: %s"
                                % (action.id, self.error_msgs[err]))
        feature.Destroy()
        return self.select(action)
        
    def delete (self, action):
        err = self.layer.DeleteFeature(action.id)
        if err:
            raise ogr.OGRError("Delete error on FID %d: %s"
                                % (action.id, self.error_msgs[err]))
        return []

    def select (self, action):
        result = []
        if action.id:
            result.append( self.layer.GetFeature(action.id) )
        else:
            if action.bbox:
                self.layer.SetSpatialFilterRect(*action.bbox)
            else:
                self.layer.SetSpatialFilter(None)
            if action.attributes:
                query = []
                for keyval in action.attributes.items():
                    query.append("( %s = '%s' )" % keyval)
                query = " AND ".join(query)
            else:
                query = None
            self.layer.SetAttributeFilter(query)

            feature = True
            count   = action.maxfeatures
            counter = 0
            self.layer.ResetReading()
            while feature:
                feature = self.layer.GetNextFeature()
                if not feature: break
                if counter < action.startfeature:
                    counter += 1
                    continue
                result.append(feature)
                if count is not None:
                    count -= 1
                    if not count: break
                

        return self.freeze_features(result)

    def begin (self):
        if self.lock: return self.lock.lock()

    def commit (self):
        self.layer.SyncToDisk()
        if self.lock: self.lock.unlock()

    def thaw_feature (self, feature):
        def thaw_points (ogrgeom, coords):
            for coord in coords: ogrgeom.AddPoint(*coord)

        geom = feature.geometry
        if geom["type"] not in self.thaw_type:
            raise ogr.OGRError(
                "Geometry type %d not supported by FeatureServer"
                % geom["type"]);

        geomtype = self.thaw_type[geom["type"]]
        ogrgeom = ogr.Geometry( type = geomtype )

        coordinates = geom["coordinates"]
        if geomtype in (ogr.wkbPoint, ogr.wkbLineString):
            thaw_points( ogrgeom, coordinates )
        elif geomtype == ogr.wkbPolygon:
            for coords in coordinates:
                ring = ogr.Geometry( type = ogr.wkbLinearRing )
                thaw_points( ring, coords )
                ogrgeom.AddRingDirectly(ring)
            ogrgeom.closeRings()
        else:
            raise Exception("Unsupported geometry type")
        
        ogrfeature = ogr.Feature(self.defn)
        ogrfeature.SetGeometryDirectly(ogrgeom)
        for key, val in feature.properties.items():
            key = ogrfeature.GetFieldIndex(key)
            ogrfeature.SetField( key, val )

        return ogrfeature

    def _freeze_geometry (self, geom):
        def freeze_points (geom):
            coords = []
            for i in range(geom.GetPointCount()):
                coords.append([geom.GetX(i), geom.GetY(i)])
            return coords
            
        geomtype = geom.GetGeometryType() & ~ogr.wkb25Bit
        # throw away all but the first geometry in a multigeom
        # sorry!
        if geomtype in (ogr.wkbMultiPoint,
                        ogr.wkbMultiLineString,
                        ogr.wkbMultiPolygon):
            geom = geom.GetGeometryRef(0)

        if geomtype not in self.freeze_type:
            raise ogr.OGRError(
                "Geometry type %d not supported by FeatureServer"
                % geomtype);
                
        frozen_type = self.freeze_type[geomtype]
        if frozen_type in ("Point", "Line"):
            coords = freeze_points(geom)
        elif frozen_type in "Polygon":
            coords = []
            for i in range(geom.GetGeometryCount()):
                coords.append( freeze_points( geom.GetGeometryRef(i) ) )

        return {'type': frozen_type, 'coordinates': coords}

    freeze_geometry = classmethod(_freeze_geometry)

    def freeze_features (self, features):
        result = []
        for ogrfeat in features:
            feat = Feature(ogrfeat.GetFID())

            geom = ogrfeat.GetGeometryRef()
            feat.geometry = OGR.freeze_geometry(geom)

            for n, defn in enumerate(self.fields):
                value = ogrfeat.GetField(n)
                if isinstance(value, str): value = unicode(value, "utf-8")
                feat.properties[defn.GetName()] = value 

            result.append(feat)
            ogrfeat.Destroy() 

        return result
Exemple #9
0
class OGR(DataSource):
    """Uses the ogr Python bindings to query/update/delete an OGR 
       datasource. Feature support is limited in the same way as 
       OGR's underlying datasource."""
    freeze_type = {
        ogr.wkbPoint: "Point",
        ogr.wkbLineString: "LineString",
        ogr.wkbPolygon: "Polygon",
        ogr.wkbMultiPoint: "Point",
        ogr.wkbMultiLineString: "LineString",
        ogr.wkbMultiPolygon: "Polygon"
    }
    # thaw_type = dict(map(lambda (x,y): (y,x), freeze_type.items()))
    thaw_type = {
        "Point": ogr.wkbPoint,
        "LineString": ogr.wkbLineString,
        "Polygon": ogr.wkbPolygon
    }
    error_msgs = [
        "OK", "Not enough data", "Not enough memory",
        "Unsupported geometry type", "Unsupported operation", "Corrupt data",
        "Unknown failure", "Unsupported SRS"
    ]

    def __init__(self,
                 name,
                 writable=0,
                 lockfile=0,
                 dsn=None,
                 layer=None,
                 attribute_cols='',
                 **args):
        DataSource.__init__(self, name, **args)
        if int(writable) and lockfile:
            self.lock = Lock(lockfile)
        else:
            self.lock = None
        self.ds = ogr.Open(dsn, int(writable))
        if layer:
            self.layer = self.ds.GetLayerByName(layer)
        else:
            self.layer = self.ds.GetLayer(0)
        self.defn = self.layer.GetLayerDefn()
        self.fields = [
            self.defn.GetFieldDefn(i) for i in range(self.defn.GetFieldCount())
        ]
        if attribute_cols:
            self.attribute_cols = [
                x.lower() for x in attribute_cols.split(',')
            ]
        else:
            self.attribute_cols = None

    def insert(self, action):
        feature = self.thaw_feature(action.feature)
        err = self.layer.CreateFeature(feature)
        if err:
            raise ogr.OGRError("Create error: %s" % self.error_msgs[err])
        action.id = feature.GetFID()
        feature.Destroy()
        if action.id > 0:  # because the OGR PostGIS driver sux
            return self.select(action)
        else:
            action.feature.id = action.id
            return [action.feature]

    def update(self, action):
        feature = self.thaw_feature(action.feature)
        feature.SetFID(action.id)
        err = self.layer.SetFeature(feature)
        if err:
            raise ogr.OGRError("Update error on FID %d: %s" %
                               (action.id, self.error_msgs[err]))
        feature.Destroy()
        return self.select(action)

    def delete(self, action):
        err = self.layer.DeleteFeature(action.id)
        if err:
            raise ogr.OGRError("Delete error on FID %d: %s" %
                               (action.id, self.error_msgs[err]))
        return []

    def select(self, action):
        result = []
        if action.id is not None:
            feature = self.layer.GetFeature(action.id)
            if not feature:
                raise Exception("No such feature. (%s)" % action.id)
            result.append(feature)
        else:
            if action.bbox:
                self.layer.SetSpatialFilterRect(*action.bbox)
            else:
                self.layer.SetSpatialFilter(None)
            if action.attributes:
                query = []
                for keyval in action.attributes.items():
                    query.append("( %s = '%s' )" % keyval)
                query = " AND ".join(query)
            else:
                query = None
            self.layer.SetAttributeFilter(query)

            feature = True
            count = action.maxfeatures
            if not count:
                count = 1000
            counter = 0
            self.layer.ResetReading()
            while feature:
                feature = self.layer.GetNextFeature()
                if not feature: break
                if counter < action.startfeature:
                    counter += 1
                    continue
                result.append(feature)
                if count is not None:
                    count -= 1
                    if not count: break

        return self.freeze_features(result)

    def begin(self):
        if self.lock: return self.lock.lock()

    def commit(self):
        self.layer.SyncToDisk()
        if self.lock: self.lock.unlock()

    def thaw_feature(self, feature):
        def thaw_points(ogrgeom, coords):
            for coord in coords:
                ogrgeom.AddPoint(*coord)

        geom = feature.geometry
        if geom["type"] not in self.thaw_type:
            raise ogr.OGRError(
                "Geometry type %d not supported by FeatureServer" %
                geom["type"])

        geomtype = self.thaw_type[geom["type"]]
        ogrgeom = ogr.Geometry(type=geomtype)

        coordinates = geom["coordinates"]
        if geomtype == ogr.wkbPoint:
            thaw_points(ogrgeom, [coordinates])
        elif geomtype == ogr.wkbLineString:
            thaw_points(ogrgeom, coordinates)
        elif geomtype == ogr.wkbPolygon:
            for coords in coordinates:
                ring = ogr.Geometry(type=ogr.wkbLinearRing)
                thaw_points(ring, coords)
                ogrgeom.AddRingDirectly(ring)
            ogrgeom.closeRings()
        else:
            raise Exception("Unsupported geometry type")

        ogrfeature = ogr.Feature(self.defn)
        ogrfeature.SetGeometryDirectly(ogrgeom)
        for key, val in feature.properties.items():
            key = ogrfeature.GetFieldIndex(key)
            ogrfeature.SetField(key, val)

        return ogrfeature

    def _freeze_geometry(self, geom):
        def freeze_points(geom):
            coords = []
            for i in range(geom.GetPointCount()):
                coords.append([geom.GetX(i), geom.GetY(i)])
            return coords

        geomtype = geom.GetGeometryType() & ~ogr.wkb25Bit
        # throw away all but the first geometry in a multigeom
        # sorry!
        if geomtype in (ogr.wkbMultiPoint, ogr.wkbMultiLineString,
                        ogr.wkbMultiPolygon):
            geom = geom.GetGeometryRef(0)

        if geomtype not in self.freeze_type:
            raise ogr.OGRError(
                "Geometry type %d not supported by FeatureServer" % geomtype)

        frozen_type = self.freeze_type[geomtype]
        if frozen_type == "Point":
            points = freeze_points(geom)
            if len(points) == 1:
                coords = points[0]
        elif frozen_type == "LineString":
            coords = freeze_points(geom)
        elif frozen_type == "Polygon":
            coords = []
            for i in range(geom.GetGeometryCount()):
                coords.append(freeze_points(geom.GetGeometryRef(i)))

        return {'type': frozen_type, 'coordinates': coords}

    freeze_geometry = classmethod(_freeze_geometry)

    def freeze_features(self, features):
        result = []
        for ogrfeat in features:
            feat = Feature(ogrfeat.GetFID())

            geom = ogrfeat.GetGeometryRef()
            feat.geometry = OGR.freeze_geometry(geom)

            for n, defn in enumerate(self.fields):
                key = defn.GetName()
                if self.attribute_cols and not key.lower(
                ) in self.attribute_cols:
                    continue
                value = ogrfeat.GetField(n)
                if isinstance(value, str): value = unicode(value, "utf-8")
                feat.properties[key] = value

            result.append(feat)
            ogrfeat.Destroy()

        return result