ShapeData.py 4.9 KB
# coding=utf-8
#author:        4N
#createtime:    2022/3/15
#email:         nheweijun@sina.com


from osgeo import ogr
from osgeo.ogr import *
import math
import os
import copy

class ShapeData:

    driver = ogr.GetDriverByName("ESRI Shapefile")

    def __init__(self,path):

        self.ds: DataSource = self.driver.Open(path, 1)
        if not self.ds:
            raise Exception("打开数据失败!")
        self.layer: Layer = self.ds.GetLayer(0)


    def get_polygons(self):

        polygons = []
        for feature in self.layer:
            f:Feature = feature
            geom : Geometry = copy.deepcopy(f.GetGeometryRef())
            if geom is None:
                continue
            if geom.GetGeometryType() in [3,-2147483645,3001]:
                polygons.append(ogr.ForceToPolygon(geom))
            if geom.GetGeometryType() in [6 ,-2147483642 ,3006]:
                for i in range(geom.GetGeometryCount()):
                    polygons.append(ogr.ForceToPolygon(geom.GetGeometryRef(i)))

        # p_cs = []
        # for p in polygons:
        #     polygon_line: Geometry = self.get_polygon_lines(p)
        #     print(polygon_line)
        #     p_cs.append(self.create_polygon(polygon_line.GetPoints()))
        #
        # return p_cs
        return polygons


    def get_polygon_lines(self,polygon):
        #无孔Polygon
        if polygon.GetGeometryCount() in [0,1]:
            polygon_line : Geometry = ogr.ForceToLineString(polygon)
        # 有孔Polygon
        else:
            polygon_line : Geometry = ogr.ForceToLineString(polygon.GetGeometryRef(0))

        return polygon_line


    def create_polygon(self,ps):

        ring = ogr.Geometry(ogr.wkbLinearRing)
        for p in ps:
            ring.AddPoint(p[0], p[1],0)
        poly = ogr.Geometry(ogr.wkbPolygon)
        poly.AddGeometry(ring)
        return poly



    def close(self):
        self.ds.Destroy()




    @classmethod
    def create_by_layer(cls,path,layer:Layer):
        data_source: DataSource = cls.driver.CreateDataSource(path)
        data_source.CopyLayer(layer,layer.GetName())
        data_source.Destroy()

    @classmethod
    def create_by_scheme(cls,path,name,sr,geo_type,scheme,features):
        data_source: DataSource = cls.driver.CreateDataSource(path)
        layer :Layer = data_source.CreateLayer(name, sr, geo_type)
        if scheme:
            layer.CreateFields(scheme)
        for feature in features:
            layer.CreateFeature(feature)
        data_source.Destroy()

    @classmethod
    def create_point(cls,path,name,point):
        data_source: DataSource = cls.driver.CreateDataSource(path)
        layer :Layer = data_source.CreateLayer(name, None, ogr.wkbPoint)

        feat_new = ogr.Feature(layer.GetLayerDefn())
        feat_new.SetGeometry(point)
        layer.CreateFeature(feat_new)
        data_source.Destroy()

    @classmethod
    def create_shp_fromwkts(cls,path,name,wkts):

        geo_type = None
        geoms = []
        for wkt in wkts:
            geom : Geometry = ogr.CreateGeometryFromWkt(wkt)
            if geo_type is None:
                geo_type = geom.GetGeometryType()
            geoms.append(geom)

        if os.path.exists(path):

            pre_name = ".".join(path.split(".")[0:-1])
            for bac in ["dbf","prj","cpg","shp","shx","sbn","sbx"]:
                try:
                    os.remove(pre_name+"."+bac)
                except Exception as e:
                    pass

        data_source: DataSource = cls.driver.CreateDataSource(path)
        layer :Layer = data_source.CreateLayer(name, None, geo_type)

        for geom in geoms:
            feat_new = ogr.Feature(layer.GetLayerDefn())
            feat_new.SetGeometry(geom)
            layer.CreateFeature(feat_new)
        data_source.Destroy()


if __name__ == '__main__':
    sd = ShapeData(r"J:\Data\制图综合result\test.shp")
    # polygons = sd.get_polygons()
    # wkts = []
    # for p in polygons:
    #     # print(p.ExportToWkt())
    #     wkts.append(p.ExportToWkt())
    # result = r"J:\Data\制图综合result\zhongshan_ronghe.shp"
    # ShapeData.create_shp_fromwkts(result,"zh",wkts)

    layer = sd.layer

    fn = "PG: user=postgres password=chinadci host=172.26.60.101 port=5432 dbname=ceshi "
    driver = ogr.GetDriverByName("PostgreSQL")
    if driver is None:
        raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!")
    ds:DataSource = driver.Open(fn, 1)


    pg_layer = ds.CreateLayer("test", layer.GetSpatialRef(), layer.GetGeomType(), ["overwrite=yes"])
    schema =  layer.schema
    pg_layer.CreateFields(schema)
    for feature in layer:
        out_feature: Feature = copy.copy(feature)
        out_feature.SetFID(out_feature.GetFID() + 1)
        pg_layer.CreateFeature(out_feature)


    ds.Destroy()