| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- '''
- @author: olivier.massot, 2018
- '''
- from osgeo import ogr, osr
- 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()
-
- xmin, xmax, ymin, ymax = self.geom.GetEnvelope()
- self.bounding_box = (xmin, ymin, xmax, ymax)
-
- _def = ogr_feature.GetDefnRef()
- for i in range(_def.GetFieldCount()):
- field = _def.GetFieldDefn(i)
- value = ogr_feature[i]
- if value is None and field.GetType() == ogr.OFTString:
- value = ""
- self.__setattr__(field.GetName(), value)
-
- @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())]
-
- @property
- def valid(self):
- return self.geom.IsValid()
-
- def __repr__(self):
- return "<Feature: type={}, bounding_box={}>".format(self.geom_name, self.bounding_box)
-
- @property
- def points(self):
- return [p for p in self.geom.GetPoints()]
- def almost_equal(self, feature, buffer_dist=1):
- if feature.geom_type == self.geom_type:
- buffer = self.geom.Buffer(buffer_dist)
- if buffer.Contains(feature.geom):
- return True
- return False
-
- @classmethod
- def union(cls, features):
- g = features[0].geom.Clone()
- for f in features[1:]:
- g = g.Union(f.geom)
- return g
-
- @classmethod
- def buffered_union(cls, features, buffer_dist=1):
- multi = ogr.Geometry(ogr.wkbMultiPolygon)
- for f in features:
- multi.AddGeometry(f.geom.Buffer(buffer_dist))
- return multi.UnionCascaded()
-
- 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]
- f2 = layer[5]
- f3 = layer[4]
- print(f)
- print(f.geom)
- print(f.AR_ID_INSE)
-
- gf = Feature.union(list(layer))
- print(gf)
- # gf = Feature.buffered_union(list(layer), 0.5)
- # print(gf)
-
- # save to file
- result_file = Path(r"C:\dev\python\datacheck\work\result.shp")
- driver = ogr.GetDriverByName("ESRI Shapefile")
- if result_file.exists():
- driver.DeleteDataSource(result_file)
-
- data_source = driver.CreateDataSource(result_file)
- srs = osr.SpatialReference()
- srs.ImportFromEPSG(3949)
-
- layer = data_source.CreateLayer("result", srs, gf.GetGeometryType())
- feature = ogr.Feature(layer.GetLayerDefn())
- feature.SetGeometry(gf)
- layer.CreateFeature(feature)
-
-
-
|