zoukankan      html  css  js  c++  java
  • 生成凹包

    import time
    from struct import *
    import subprocess
    import fiona
    import math
    import numpy as np
    import pylab as pl
    from osgeo import ogr, gdal
    import shapely.geometry as geometry
    from shapely.geometry import polygon, multipolygon
    from geojson import Feature, Point, FeatureCollection, dumps
    from descartes import PolygonPatch
    from shapely.ops import cascaded_union, polygonize
    from scipy.spatial import Delaunay
    
    #
    input_shapefile = 'E:/test/pointNoRepeat.shp'
    shapefile = fiona.open(input_shapefile)
    points = [geometry.shape(point['geometry']) for point in shapefile]
    x = [p.coords.xy[0] for p in points]
    y = [p.coords.xy[1] for p in points]
    
    
    '''
    point_collection = geometry.MultiPoint(list(points))
    point_collection.envelope
    
    def plot_polygon(polygon):
        fig = pl.figure(figsize=(10,10))
        ax = fig.add_subplot(111)
        margin = .3
        x_min, y_min, x_max, y_max = polygon.bounds
        ax.set_xlim([x_min-margin, x_max+margin])
        ax.set_ylim([y_min-margin, y_max+margin])
        #print(str(x_min) + "  " + str(y_min) + "  " + str(x_max) + "  " + str(y_max))
        #print(polygon)
        patch = PolygonPatch(polygon, fc='#999999', ec='#000000', fill=True, zorder=-1)
        ax.add_patch(patch)
        return fig
    
    plot_polygon(point_collection.envelope)
    pl.plot(x,y,'o', color='#f16824')
    '''
    
    
    #
    def alpha_shape(points, alpha):
        """
        Compute the alpha shape (concave hull) of a set of points.
        @param points: Iterable container of points.
        @param alpha: alpha value to influence the gooeyness of the border. Smaller numbers don't fall inward as much as larger numbers.
            Too large, and you lose everything!
        """
        if len(points) < 4:
            # When you have a triangle, there is no sense in computing an alpha shape.
            return geometry.MultiPoint(list(points)).convex_hull
        def add_edge(edges, edge_points, coords, i, j):
            """
            Add a line between the i-th and j-th points, if not in the list already
            """
            if (i, j) in edges or (j, i) in edges:
                # already added
                return
            edges.add( (i, j) )
            edge_points.append(coords[ [i, j] ])
        coords = np.array([point.coords[0] for point in points])
        #print(coords)
        tri = Delaunay(coords)
        edges = set()
        edge_points = []
        # loop over triangles:
        # ia, ib, ic = indices of corner points of the triangle
        for ia, ib, ic in tri.vertices:
            pa = coords[ia]
            pb = coords[ib]
            pc = coords[ic]
            # Lengths of sides of triangle
            a = math.sqrt((pa[0]-pb[0])**2 + (pa[1]-pb[1])**2)
            b = math.sqrt((pb[0]-pc[0])**2 + (pb[1]-pc[1])**2)
            c = math.sqrt((pc[0]-pa[0])**2 + (pc[1]-pa[1])**2)
            # Semiperimeter of triangle
            s = (a + b + c)/2.0
            # Area of triangle by Heron's formula
            area = math.sqrt(s*(s-a)*(s-b)*(s-c))
            if area <= 0:
                continue;
            circum_r = a*b*c/(4.0*area)
            # Here's the radius filter.
            #print circum_r
            if circum_r < 1.0/alpha:
                add_edge(edges, edge_points, coords, ia, ib)
                add_edge(edges, edge_points, coords, ib, ic)
                add_edge(edges, edge_points, coords, ic, ia)
        m = geometry.MultiLineString(edge_points)
        triangles = list(polygonize(m))
        #
        return cascaded_union(triangles), edge_points
    
    #
    concave_hull, edge_points = alpha_shape(points, alpha=0.38)
    #
    featCollection = FeatureCollection([])
    featCollection["crs"] = {"type":"name","properties":{"name":"EPSG:2385"}}
    if hasattr(concave_hull, "geoms"):
        polys = concave_hull.geoms
        fig = pl.figure(figsize=(10,10))
        ax = fig.add_subplot(111)
        margin = .3
        if len(concave_hull.bounds)>0:
            #
            x_min, y_min, x_max, y_max = concave_hull.bounds
            ax.set_xlim([x_min-margin, x_max+margin])
            ax.set_ylim([y_min-margin, y_max+margin])
            for poly in polys:
                patch = PolygonPatch(poly, fc='#999999', ec='#000000', fill=True, zorder=-1)
                ax.add_patch(patch)
                #
                geojs_geom = poly.__geo_interface__
                hull_poly = dict(type='Feature', properties=dict(id=1))
                hull_poly['geometry'] = geojs_geom
                #print(hull_poly)
                my_feature = Feature(geometry=geojs_geom)
                featCollection["features"].append(my_feature)
            print(featCollection)
            pl.plot(x,y,'o', color='#f16824')
        #
        #print(concave_hull.geoms)
    else:
        fig = pl.figure(figsize=(10,10))
        ax = fig.add_subplot(111)
        margin = .3
        x_min, y_min, x_max, y_max = concave_hull.bounds
        ax.set_xlim([x_min-margin, x_max+margin])
        ax.set_ylim([y_min-margin, y_max+margin])
        patch = PolygonPatch(concave_hull, fc='#999999', ec='#000000', fill=True, zorder=-1)
        ax.add_patch(patch)
        pl.plot(x, y, 'o', color='#f16824')
        geojs_geom = concave_hull.__geo_interface__
        my_feature = Feature(geometry=geojs_geom)
        featCollection["features"].append(my_feature)
    #
    file_object = open('e:\test\result\result.json', 'w')
    file_object.write(dumps(featCollection))
    file_object.close()
    subprocess.call(["ogr2ogr", "-t_srs", "EPSG:2385", "-f", "ESRI Shapefile", "e:\test\result\ConcaveEnvelope.shp", "e:\test\result\result.json"])
    pl.show()

    image

    image

  • 相关阅读:
    thinkphp redis实现文章点赞功能并同步入mysql
    phpstorm2020.1最新版永久破解
    mysql修改sql_mode为宽松模式
    用为知发布博客到博客园、使用Wiz编写和发布博客园(cnblogs)博客
    Vim命令大全
    Vim教程
    GDB教程详解
    TCMalloc 对MYSQL 性能 优化的分析
    TCMalloc 安装和使用
    使用Tcmalloc进行堆栈分析
  • 原文地址:https://www.cnblogs.com/gispathfinder/p/5826236.html
Copyright © 2011-2022 走看看