|
|
@@ -0,0 +1,115 @@
|
|
|
+'''
|
|
|
+
|
|
|
+@author: olivier.massot, 2018
|
|
|
+'''
|
|
|
+from osgeo import ogr
|
|
|
+from path import Path
|
|
|
+
|
|
|
+GEOM_UNKNOWN = 0
|
|
|
+GEOM_POINT = 1
|
|
|
+GEOM_LINE = 2
|
|
|
+GEOM_POLYGON = 3
|
|
|
+GEOM_MULTIPOINT = 4
|
|
|
+GEOM_MULTILINE = 5
|
|
|
+GEOM_MULTIPOLYGON = 6
|
|
|
+
|
|
|
+GEOM_NAMES = {0: "(AUCUN)",
|
|
|
+ 1: "POINT",
|
|
|
+ 2: "LIGNE",
|
|
|
+ 3: "POLYGONE",
|
|
|
+ 4: "MULTI-POINT",
|
|
|
+ 5:"MULTI-LIGNE",
|
|
|
+ 6:"MULTI-POLYGONE",
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+class Datasource():
|
|
|
+ DRIVER_NAME = "ESRI Shapefile"
|
|
|
+ def __init__(self, filename, readonly=True):
|
|
|
+ self.filename = Path(filename)
|
|
|
+ driver = ogr.GetDriverByName(self.DRIVER_NAME)
|
|
|
+ self._ogr_datasource = driver.Open(filename, 0 if readonly else 1)
|
|
|
+ if not self._ogr_datasource:
|
|
|
+ raise IOError("Unable to read the file {}".format(filename))
|
|
|
+
|
|
|
+ @property
|
|
|
+ def layer(self):
|
|
|
+ return Layer(self._ogr_datasource.GetLayer())
|
|
|
+
|
|
|
+
|
|
|
+class LayerField():
|
|
|
+ def __init__(self, ogr_field):
|
|
|
+ self.name = ogr_field.GetName()
|
|
|
+ self.type_ = ogr_field.GetType()
|
|
|
+ self.type_name = ogr_field.GetFieldTypeName(self.type_)
|
|
|
+ self.width = ogr_field.GetWidth()
|
|
|
+ self.precision = ogr_field.GetPrecision()
|
|
|
+
|
|
|
+ def __repr__(self):
|
|
|
+ return "<Field: nom={}, type={}, longueur={}>".format(self.name, self.type_name, self.width)
|
|
|
+
|
|
|
+class Layer():
|
|
|
+ def __init__(self, ogr_layer):
|
|
|
+ self._ogr_layer = ogr_layer
|
|
|
+
|
|
|
+ self.name = ogr_layer.GetName()
|
|
|
+ self.srid = ogr_layer.GetSpatialRef().GetAttrValue('AUTHORITY',1)
|
|
|
+ self.geom_type = ogr_layer.GetGeomType()
|
|
|
+ _layer_def = self._ogr_layer.GetLayerDefn()
|
|
|
+ self.fields = [LayerField(_layer_def.GetFieldDefn(i)) for i in range(_layer_def.GetFieldCount())]
|
|
|
+
|
|
|
+ @property
|
|
|
+ def geom_name(self):
|
|
|
+ return GEOM_NAMES[self._ogr_layer.GetGeomType()]
|
|
|
+
|
|
|
+ def __len__(self):
|
|
|
+ return self._ogr_layer.GetFeatureCount()
|
|
|
+
|
|
|
+ def __iter__(self):
|
|
|
+ for f in self._ogr_layer.__iter__():
|
|
|
+ yield Feature(f)
|
|
|
+ self._ogr_layer.ResetReading()
|
|
|
+
|
|
|
+ def __getitem__(self, i):
|
|
|
+ return Feature(self._ogr_layer.GetFeature(i))
|
|
|
+
|
|
|
+class Feature():
|
|
|
+ def __init__(self, ogr_feature):
|
|
|
+ self._ogr_feature = ogr_feature
|
|
|
+
|
|
|
+ self.geom = self._ogr_feature.GetGeometryRef()
|
|
|
+ self.geom_type = self.geom.GetGeometryType()
|
|
|
+ self.bounding_box = self.geom.GetEnvelope()
|
|
|
+
|
|
|
+ _def = ogr_feature.GetDefnRef()
|
|
|
+ self.fields = [LayerField(_def.GetFieldDefn(i)) for i in range(_def.GetFieldCount())]
|
|
|
+
|
|
|
+ @property
|
|
|
+ def geom_name(self):
|
|
|
+ return GEOM_NAMES[self.geom.GetGeometryType()]
|
|
|
+
|
|
|
+ def fields(self):
|
|
|
+ layerDefinition = self._ogr_layer.GetLayerDefn()
|
|
|
+ return [LayerField(layerDefinition.GetFieldDefn(i)) for i in range(layerDefinition.GetFieldCount())]
|
|
|
+
|
|
|
+ def __repr__(self):
|
|
|
+ return "<Feature: type={}, bounding_box={}>".format(self.geom_name, self.bounding_box)
|
|
|
+
|
|
|
+ def points(self):
|
|
|
+ return [p for p in self.geom.GetPoints()]
|
|
|
+
|
|
|
+ def __getattr__(self, key):
|
|
|
+ return self._ogr_feature.__getattr__(key)
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ ds = Datasource(r"C:\dev\python\datacheck\work\STURNO_178AP1_REC_171121_OK\ARTERE_GEO.shp")
|
|
|
+ layer = ds.layer
|
|
|
+ print(layer.fields)
|
|
|
+# for f in layer:
|
|
|
+# print(f)
|
|
|
+ f = layer[4]
|
|
|
+ print(f)
|
|
|
+ print(f.fields)
|
|
|
+ print(f.geom)
|
|
|
+ print(f.AR_ID_INSE)
|
|
|
+
|