Example #1
0
def make_valid_polygon(geom, precision=2):
    if geom.is_valid == True or isinstance(geom, (Polygon, MultiPolygon)) == False:
        return geom

    if isinstance(geom, Polygon):
        area = geom.area
        buff_geom = geom.buffer(0)
        buff_area = buff_geom.area
        if round(area, precision) == round(buff_area, precision):
            return buff_geom
        else:

            exterior = geom.exterior
            interiors = geom.interiors
            exterior = exterior.intersection(exterior)
            interiors = [MultiPolygon(polygonize(i.intersection(i)))[0].exterior for i in interiors]
            result = MultiPolygon([Polygon(i.exterior, interiors) for i in polygonize(exterior)])
            return result
    elif isinstance(geom, MultiPolygon):
        result = [make_valid_polygon(poly) for poly in geom]
        result = MultiPolygon(flatten([[i for i in j] if isinstance(j, MultiPolygon) else j for j in result]))
        if len(result) == 1:
            return result[0]
        else:
            return result
Example #2
0
def merge_vor(vor1, vor2):
    ax = plt.subplot(1, 1, 1)
    lines1 = [
        geometry.LineString(vor1.vertices[line])
        for line in vor1.ridge_vertices if -1 not in line
    ]
    lines2 = [
        geometry.LineString(vor2.vertices[line])
        for line in vor2.ridge_vertices if -1 not in line
    ]

    for coords in vor1.points:
        ax.scatter(coords[0], coords[1])

    for coords in vor2.points:
        ax.scatter(coords[0], coords[1])
    #points1 = vor1.points.tolist()
    #for x,y in points1:
    #    ax.scatter(x,y)

    #points2 = vor2.points.tolist()
    #for x,y in points2:
    #    ax.scatter(x,y)
    shape1 = ops.unary_union(list(ops.polygonize(lines1)))
    x1, y1 = shape1.exterior.xy
    ax.plot(x1, y1)

    shape2 = ops.unary_union(list(ops.polygonize(lines2)))
    x2, y2 = shape2.exterior.xy
    ax.plot(x2, y2)
    plt.show()
Example #3
0
def doPolygonize():
  blocks = polygonize(lines)
  writeBlocks(blocks, args[0] + '-blocks.geojson')

  blocks = polygonize(lines)
  bounds = Polygon([
    [minlng, minlat],
    [minlng, maxlat],
    [maxlng, maxlat],
    [maxlng, minlat],
    [minlng, minlat]
  ])
  # Geometry transform function based on pyproj.transform
  project = partial(
    pyproj.transform,
    pyproj.Proj(init='EPSG:3785'),
    pyproj.Proj(init='EPSG:4326'))
  print bounds
  print transform(project, bounds)

  print 'finding holes'
  for index, block in enumerate(blocks):
    if index % 1000 == 0:
      print "diff'd  %s" % (index)
    if not block.is_valid:
      print explain_validity(block)
      print transform(project, block)
    else:
      bounds = bounds.difference(block)
  print bounds
Example #4
0
    def pfr_lines(self, inp, core):

        c = QuadContourGenerator.from_rectilinear(core.psi_data.R[0], core.psi_data.Z[:, 0], core.psi_data.psi_norm)
        contours = c.contour(0.999)

        if len(contours) == 1:
            # then we're definitely dealing with a surface inside the seperatrix
            raise ValueError("Did not find PFR flux surface. Stopping.")
        else:
            # we need to find the surface that is contained within the private flux region
            for j, contour in enumerate(contours):
                # if the contour is entirely below the x-point and contour extends to both the left and the
                # right of the x-point horizontally, then the contour is almost certainly the desired PFR contour
                if np.amax(contour[:, 1]) < core.pts.xpt[1] and \
                        np.amin(contour[:, 0]) < core.pts.xpt[0] < np.amax(contour[:, 0]):
                    # then it's a probably a pfr flux surface, might need to add additional checks later

                    # make sure the line goes from inboard to outboard
                    if contour[-1, 0] < contour[0, 0]:
                        contour = np.flipud(contour)

                    # find cut points
                    cut_pt_ib = LineString(contour).intersection(inp.wall_line)[0]
                    cut_pt_ob = LineString(contour).intersection(inp.wall_line)[1]

                    dist1 = LineString(contour).project(cut_pt_ib, normalized=True)
                    cutline_temp = cut(LineString(contour), dist1)[1]

                    # reverse line point order so we can reliably find the second intersection point
                    cutline_temp_rev = LineString(np.flipud(np.asarray(cutline_temp.coords)))

                    dist2 = cutline_temp_rev.project(cut_pt_ob, normalized=True)
                    cutline_final_rev = cut(cutline_temp_rev, dist2)[1]

                    # reverse again for final pfr flux line
                    pfr_flux_line = LineString(np.flipud(np.asarray(cutline_final_rev.coords)))

                    # add pfr_line intersection points on inboard side
                    # for some reason, union freaks out when I try to do inboard and outboard
                    # at the same time.
                    union = inp.wall_line.union(cut(LineString(contour), 0.5)[0])
                    result = [geom for geom in polygonize(union)][0]
                    inp.wall_line = LineString(result.exterior.coords)

                    # add pfr line intersection points on outboard side
                    union = inp.wall_line.union(cut(LineString(contour), 0.5)[1])
                    result = [geom for geom in polygonize(union)][0]
                    inp.wall_line = LineString(result.exterior.coords)

                    # cut out pfr section of wall line
                    wall_pts = np.asarray(inp.wall_line.xy).T

                    wall_start_pos = np.where((wall_pts == cut_pt_ob).all(axis=1))[0][0]
                    wall_line_rolled = LineString(np.roll(wall_pts, -wall_start_pos, axis=0))
                    wall_line_cut_pfr = cut(wall_line_rolled,
                                            wall_line_rolled.project(cut_pt_ib, normalized=True))[0]

                    # create LineString with pfr line and section of wall line
                    self.pfr_line = linemerge((pfr_flux_line, wall_line_cut_pfr))
                    break
def create_union(in_ply1, in_ply2, result_geojson):
    """
    Create union polygon
    :param in_ply1: first input shapely polygon
    :param in_ply2: second input shapely polygon
    :param result_geojson: output geojson file including full file path
    :return: shapely MultiPolygon
    """
    # union the polygon outer linestrings together
    outer_bndry = in_ply1.boundary.union(in_ply2.boundary)

    # rebuild linestrings into polygons
    output_poly_list = polygonize(outer_bndry)

    out_geojson = dict(type='FeatureCollection', features=[])

    # generate geojson file output
    for (index_num, ply) in enumerate(output_poly_list):
        feature = dict(type='Feature', properties=dict(id=index_num))
        feature['geometry'] = ply.__geo_interface__
        out_geojson['features'].append(feature)

    # create geojson file on disk
    json.dump(out_geojson, open(result_geojson, 'w'))

    # create shapely MultiPolygon
    ply_list = []
    for fp in polygonize(outer_bndry):
        ply_list.append(fp)

    out_multi_ply = MultiPolygon(ply_list)

    return out_multi_ply
def create_union(in_ply1, in_ply2, result_geojson):
    """
    Create union polygon
    :param in_ply1: first input shapely polygon
    :param in_ply2: second input shapely polygon
    :param result_geojson: output geojson file including full file path
    :return: shapely MultiPolygon
    """
    # union the polygon outer linestrings together
    outer_bndry = in_ply1.boundary.union(in_ply2.boundary)

    # rebuild linestrings into polygons
    output_poly_list = polygonize(outer_bndry)

    out_geojson = dict(type='FeatureCollection', features=[])

    # generate geojson file output
    for (index_num, ply) in enumerate(output_poly_list):
        feature = dict(type='Feature', properties=dict(id=index_num))
        feature['geometry'] = ply.__geo_interface__
        out_geojson['features'].append(feature)

    # create geojson file on disk
    json.dump(out_geojson, open(result_geojson, 'w'))

    # create shapely MultiPolygon
    ply_list = []
    for fp in polygonize(outer_bndry):
        ply_list.append(fp)

    out_multi_ply = MultiPolygon(ply_list)

    return out_multi_ply
Example #7
0
def print_cid_count(node_array_x, node_array_y):
  
  gridx = np.linspace(300000, 800000, 5)
  gridy = np.linspace(3700000, 5500000, 5)
  grid, _, _ = np.histogram2d(node_array_x, node_array_y, bins=[gridx, gridy])
  
  # plotting
  # plt.figure(figsize=(9, 7), dpi=90, facecolor='w', edgecolor='k')
  # plt.plot(node_array_x, node_array_y, 'ro')
  # plt.grid(True)
  # plt.figure(figsize=(9, 7), dpi=90, facecolor='w', edgecolor='k')
  # plt.pcolormesh(gridx, gridy, grid)
  # plt.plot(node_array_x, node_array_y, 'ro')
  # plt.colorbar()
  # plt.show()

  points = gpd.GeoDataFrame({"x":node_array_x,"y":node_array_y})
  points['geometry'] = points.apply(lambda p: Point(p.x, p.y), axis=1)
  # print(points.head(2))

  # np mesh-grid to shapely polygons
  hlines = [((x1, yi), (x2, yi)) for x1, x2 in list(zip(gridx[:-1], gridx[1:])) for yi in gridy]
  vlines = [((xi, y1), (xi, y2)) for y1, y2 in zip(gridy[:-1], gridy[1:]) for xi in gridx]
  polys = list(polygonize(MultiLineString(hlines + vlines)))
  grids = list(polygonize(MultiLineString(hlines + vlines)))
  cid = [i for i in range(len(grids))]
  grid = gpd.GeoDataFrame({"cid":cid,"geometry":polys})
  # print(grid.head(2))

  # number of points in polygons
  pointInPolys = sjoin(points, grid, how='left')
  print(pointInPolys.groupby(['cid']).size().reset_index(name='count'))
Example #8
0
    def sol_lines(self, inp, R, Z, core):
        #find value of psi at outside of what we're going to call the SOL
        self.sol_lines = []
        self.sol_lines_cut = []

        sol_width_obmp = 0.02
        psi_pts = np.linspace(1,
                              inp.sollines_psi_max,
                              inp.num_sollines + 1,
                              endpoint=True)[1:]
        for i, v in enumerate(psi_pts):
            num_lines = int(
                len(cntr.Cntr(R, Z, core.psi_norm_raw).trace(v)) / 2)
            if num_lines == 1:
                #then we're definitely dealing with a surface inside the seperatrix
                x, y = draw_line(R, Z, core.psi_norm_raw, v, 0)
                self.sol_lines.append(LineString(np.column_stack((x, y))))
            else:
                #TODO:
                pass
        for line in self.sol_lines:
            #find intersection points with the wall
            int_pts = line.intersection(inp.wall_line)
            #cut line at intersection points
            cut_line = cut(line, line.project(int_pts[0], normalized=True))[1]
            cut_line = cut(cut_line,
                           cut_line.project(int_pts[1], normalized=True))[0]
            self.sol_lines_cut.append(cut_line)

        #add wall intersection points from divertor legs and sol lines to wall_line.
        #This is necessary to prevent thousands of tiny triangles from forming if the
        #end of the flux line isn't exactly on top of the wall line.

        #add inboard seperatrix strike point
        union = inp.wall_line.union(core.ib_div_line)
        result = [geom for geom in polygonize(union)][0]
        inp.wall_line = LineString(result.exterior.coords)

        #add outboard seperatrix strike point
        union = inp.wall_line.union(core.ob_div_line)
        result = [geom for geom in polygonize(union)][0]
        inp.wall_line = LineString(result.exterior.coords)

        #add sol line intersection points on inboard side
        #for some reason, union freaks out when I try to do inboard and outboard
        #at the same time.
        for num, line in enumerate(self.sol_lines):
            union = inp.wall_line.union(cut(line, 0.5)[0])
            result = [geom for geom in polygonize(union)][0]
            inp.wall_line = LineString(result.exterior.coords)

        #add sol line intersection points on outboard side
        for num, line in enumerate(self.sol_lines):
            union = inp.wall_line.union(cut(line, 0.5)[1])
            result = [geom for geom in polygonize(union)][0]
            inp.wall_line = LineString(result.exterior.coords)
Example #9
0
def st_polygon(draw, n=10, num_holes=None, xmid=0, ymid=0):
    # Handle defaults
    if num_holes is None:
        num_holes = draw(st.integers(0, 4))

    # Build outer shell
    tries = 50
    poly = None
    while tries > 0:
        tries -= 1
        points = (np.random.rand(n, 2) - 0.5) * 100
        points[:, 0] = points[:, 0] + xmid
        points[:, 1] = points[:, 1] + ymid

        vor = Voronoi(points)
        mls = sg.MultiLineString([
            vor.vertices[s] for s in vor.ridge_vertices
            if all(np.array(s) >= 0)
        ])

        poly = cascaded_union(list(polygonize(mls)))
        poly = poly.intersection(sg.box(-50, -50, 50, 50))
        if isinstance(poly, sg.Polygon) and not poly.is_empty:
            break

    if not isinstance(poly, sg.Polygon):
        raise ValueError("Failed to construct polygon")

    # Build holes
    remaining_holes = num_holes
    tries = 50
    while remaining_holes > 0 and tries > 0:
        tries -= 1
        points = (np.random.rand(n, 2) - 0.5) * 50
        points[:, 0] = points[:, 0] + xmid
        points[:, 1] = points[:, 1] + ymid
        vor = Voronoi(points)
        mls = sg.MultiLineString([
            vor.vertices[s] for s in vor.ridge_vertices
            if all(np.array(s) >= 0)
        ])
        hole_components = [p for p in polygonize(mls) if poly.contains(p)]
        if hole_components:
            hole = cascaded_union(
                [p for p in polygonize(mls) if poly.contains(p)])
            if isinstance(hole, sg.MultiPolygon):
                hole = hole[0]

            new_poly = poly.difference(hole)
            if isinstance(new_poly, sg.Polygon):
                poly = new_poly
                remaining_holes -= 1

    return poly
Example #10
0
def circle_group_area(radiuses, positions):
    circles = []
    for i in range(len(radiuses)):
        circles.append(
            point.Point(positions[i][0], positions[i][1]).buffer(radiuses[i]))

    union = ops.unary_union(circles)
    result = [geom for geom in ops.polygonize(union)]

    completeareas = [list(ops.polygonize(g.exterior))[0].area for g in result]
    max_index = np.argmax(completeareas)
    result_area = result[max_index].area

    return result_area
Example #11
0
    def alpha_shape(self, 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])

        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 = sqrt((pa[0] - pb[0])**2 + (pa[1] - pb[1])**2)
            b = sqrt((pb[0] - pc[0])**2 + (pb[1] - pc[1])**2)
            c = 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 = sqrt(s * (s - a) * (s - b) * (s - c))
            try:
                circum_r = a * b * c / (4.0 * area)
            except (ZeroDivisionError):
                circum_r = 0

            # 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
Example #12
0
    def _try_build_poly(self, points):
        poly = Polygon(points)
        # Everything is OK, points are valid polygon
        if poly.is_valid:
            return poly

        # Polygon contains small bowties, we can fix them (https://stackoverflow.com/questions/13062334/polygon-intersection-error-in-shapely-shapely-geos-topologicalerror-the-opera)
        fixed_poly = poly.buffer(0)
        if not fixed_poly.geom_type == 'MultiPolygon' and self._area_close(
                fixed_poly, poly):
            return fixed_poly

        # Trying to build multiple polygons from self intersected polygon
        line_non_simple = LineString(points)
        mls = unary_union(line_non_simple)
        polygons = list(polygonize(mls))
        multi_poly = MultiPolygon(polygons)
        if len(polygons) and multi_poly.is_valid:
            return multi_poly

        # Trying to draw convex hull
        convex_hull = poly.convex_hull
        if self._area_close(convex_hull, poly):
            return convex_hull

        # We are failing to build polygon, this shall be reported via error log
        raise ValueError(f'Fail to build polygon from {points}')
Example #13
0
File: trip.py Project: mklucz/drogi
 def __init__(self, way_map, start, end):
     """
     Args:
         way_map(WayMap): the map the trip takes place on
         start(2-tuple): starting point
         end(2-tuple): destination
     """
     self.way_map = way_map
     self.start = start
     self.end = end
     try:
         self.list_of_nodes = astar_path(self.way_map.graph,
                                         self.start,
                                         self.end)
     except NetworkXNoPath:
         self.list_of_nodes = []
     self.linestring = LineString(self.list_of_nodes)
     self.straightline_length = Path.straightline_distance(self.start,
                                                           self.end)
     self.straightline = LineString([self.start, self.end])
     self.deviation_factor = (self.linestring.length /
                              self.straightline_length)
     self.obstacles = []
     for polygon in list(polygonize([self.linestring,
                                     self.straightline])):
         self.obstacles.append(Obstacle(self.way_map,
                                        self.start,
                                        self.end,
                                        polygon))
Example #14
0
def difference(line1, line2, close_ends=False):
    """ Create polygons from two LineString objects.

    Parameters:
        line1 (LineString) : a line representing the initial condition.
        line2 (LineString) : a line representing the final condition.
        close_ends (bool) : option to close open line ends with vertical line segments.

    Returns:
        intersections (Point array) : the intersections between the LineString objects.
        polygons (Polygon array) : the polygons between the lines.
        signs (int array) : contains values of +1 or -1 to identify polygons as cut or fill.

    """
    if close_ends==True:
        line1, line2 = close(line1, line2)

    intersections = line1.intersection(line2)

    segs1 = cut_by_points([line1], intersections)
    segs2 = cut_by_points([line2], intersections)

    polygons = polygonize([segs1, segs2])

    signs = sign(linemerge(segs1), linemerge(segs2))

    # can't pass the polygonize generator to my class so convert the polygons into an array
    polygontxt = []
    areas = []
    for i, poly in enumerate(polygons):
        polygontxt.append(poly)
        areas.append(poly.area*signs[i])
    cutfill = pnd.Series(asarray(areas), name='area')

    return intersections, polygontxt, cutfill
Example #15
0
def alpha_shape(points, alpha):
    def add_edge(points, i, j):
        if (i, j) in edges or (j, i) in edges:
            return
        edges.add((i, j))
        edge_points.append((points[i], points[j]))

    tri = DelaunayTri(points)
    edges = set()
    edge_points = []
    for i1, i2, i3 in tri.vertices:
        x1, y1 = tri.points[i1]
        x2, y2 = tri.points[i2]
        x3, y3 = tri.points[i3]
        a = hypot(x1 - x2, y1 - y2)
        b = hypot(x2 - x3, y2 - y3)
        c = hypot(x3 - x1, y3 - y1)
        s = (a + b + c) / 2.0
        area = sqrt(s * (s - a) * (s - b) * (s - c))
        radius = a * b * c / (4 * area)
        if radius < 1.0 / alpha:
            add_edge(tri.points, i1, i2)
            add_edge(tri.points, i2, i3)
            add_edge(tri.points, i3, i1)
    shape = cascaded_union(list(polygonize(MultiLineString(edge_points))))
    return shape
Example #16
0
def voronoi_diagram(points, plot=False, size=None, method='box'):

    multi = shapely.geometry.multipoint.MultiPoint(points)
    if method == 'box':
        g = shapely.geometry.box(*multi.bounds)
    elif method == 'convex_hull':
        g = multi.convex_hull

    size = size if size else pow(g.area, 0.5)
    buffer = g.buffer(size)
    points_and_bound = points + [
        shapely.geometry.point.Point(c) for c in buffer.boundary.coords
    ][:-1]

    vor = Voronoi([list(g.coords)[0] for g in points_and_bound])

    lines = [
        shapely.geometry.LineString(vor.vertices[line])
        for line in vor.ridge_vertices if -1 not in line
    ]

    polygons = [
        poly.intersection(g.buffer(size / 10)) for poly in polygonize(lines)
    ]

    if plot:
        voronoi_plot_2d(vor)

    ridges = pd.DataFrame(vor.ridge_points, columns=['a', 'b'])
    ridges = ridges[(ridges['a'] < len(points)) & (ridges['b'] < len(points))]
    ridges['geometry'] = ridges.apply(lambda r: shapely.geometry.LineString(
        [points[r['a']], points[r['b']]]),
                                      axis=1)
    return polygons, ridges[['a', 'b', 'geometry']].values.tolist()
Example #17
0
def polygon_shapes_from_voronoi_lines(poly_lines, geo_shape=None, shapes_from_diff_with_min_area=None):
    """
    Form shapely Polygons objects from a list of shapely LineString objects in `poly_lines` by using
    [`polygonize`](http://toblerity.org/shapely/manual.html#shapely.ops.polygonize). If `geo_shape` is not None, then
    the intersection between any generated polygon and `geo_shape` is taken in case they overlap (i.e. the Voronoi
    regions at the border are "cut" to the `geo_shape` polygon that represents the geographic area holding the
    Voronoi regions). Setting `shapes_from_diff_with_min_area` fixes rare errors where the Voronoi shapes do not fully
    cover `geo_shape`. Set this to a small number that indicates the minimum valid area of "fill up" Voronoi region
    shapes.
    Returns a list of shapely Polygons objects.
    """

    # generate shapely Polygon objects from the LineStrings of the Voronoi shapes in `poly_lines`
    poly_shapes = []
    for p in polygonize(poly_lines):
        if geo_shape is not None and not geo_shape.contains(p):    # if `geo_shape` contains polygon `p`,
            p = p.intersection(geo_shape)                          # intersect it with `geo_shape` (i.e. "cut" it)

        if not p.is_empty:
            poly_shapes.append(p)

    if geo_shape is not None and shapes_from_diff_with_min_area is not None:
        # fix rare cases where the generated polygons of the Voronoi regions don't fully cover `geo_shape`
        vor_polys_union = cascaded_union(poly_shapes)   # union of Voronoi regions
        diff = np.array(geo_shape.difference(vor_polys_union), dtype=object)    # "gaps"
        diff_areas = np.array([p.area for p in diff])    # areas of "gaps"
        # use only those "gaps" bigger than `shapes_from_diff_with_min_area` because very tiny areas are generated
        # at the borders due to floating point errors
        poly_shapes.extend(diff[diff_areas >= shapes_from_diff_with_min_area])

    return poly_shapes
Example #18
0
    def SplitDomainByFault(self):
        # Extend fault line to remove the hanging point
        # hanging point is not intersect with other fault and boundary
        #https://gis.stackexchange.com/questions/232771/splitting-polygon-by-linestring-in-geodjango
        #https://gis.stackexchange.com/questions/283352/most-efficient-way-to-split-a-polygon-with-lines-c-api

        #Extend Fault lines
        BoundaryLine_Splitted,FaultLine_Extend, NewIntersectPts=self.extendFaultLines()
        
        #Find the 2D sub domain
        results = polygonize(MultiLineString(BoundaryLine_Splitted+FaultLine_Extend))
        self.SplitPolygons=Shapely2List_MultiPolygon(results)

        for i,p in enumerate(self.SplitPolygons):#Remove unnecessary points in polygon
            self.SplitPolygons[i]=simplify_Polygon(p)
        
        for i,poly in enumerate(self.SplitPolygons):#Convert float to int
            poly=list(reversed(poly)) #Reverse to anti-clock wise order
            for j,node in enumerate(poly):
                self.SplitPolygons[i][j]=(int(node[0]),int(node[1]))

        print('[FaultProcess] Domain is splitted as %d polygons.'%(len(self.SplitPolygons)))

        #debug
        #self.plotLines(BoundaryLine_Splitted,FaultLine_Extend,NewIntersectPts)
        
        self.plotSplittedDomain()
Example #19
0
def isNonAeroDynamic(index, cordpt, globaldata, wallpoints):
    main_pointx,main_pointy = getPoint(index, globaldata)
    cordptx = float(cordpt.split(",")[0])
    cordpty = float(cordpt.split(",")[1])
    line = shapely.geometry.LineString([[main_pointx, main_pointy], [cordptx, cordpty]])
    responselist = []
    for item in wallpoints:
        polygonpts = []
        for item2 in item:
            polygonpts.append([float(item2.split(",")[0]), float(item2.split(",")[1])])
        polygontocheck = shapely.geometry.Polygon(polygonpts)
        merged = linemerge([polygontocheck.boundary, line])
        borders = unary_union(merged)
        polygons = polygonize(borders)
        i = 0
        for p in polygons:
            i = i + 1
        if i == 1:
            responselist.append(False)
        else:
            responselist.append(True)
    if True in responselist:
        return True
    else:
        return False
Example #20
0
def alpha_shape(x, y, alpha):
    coords = np.c_[x, y]
    tri = scipy.spatial.Delaunay(coords)
    
    # edges = []
    edge_coords = []
    for ia, ib, ic in tri.vertices:
        ab = math.sqrt((coords[ia,0]-coords[ib,0])**2 + (coords[ia,1]-coords[ib,1])**2)
        bc = math.sqrt((coords[ib,0]-coords[ic,0])**2 + (coords[ib,1]-coords[ic,1])**2)
        ac = math.sqrt((coords[ia,0]-coords[ic,0])**2 + (coords[ia,1]-coords[ic,1])**2)
        
        semiperim = 0.5*(ab+bc+ac)
        area = math.sqrt(semiperim*(semiperim-ab)*(semiperim-bc)*(semiperim-ac))
        radius = 0.25*ab*bc*ac/area
        
        if radius < 1.0/alpha:
            # edges.append((tuple(coords[ia]), tuple(coords[ib])))
            # edges.append((tuple(coords[ib]), tuple(coords[ic])))
            # edges.append((tuple(coords[ia]), tuple(coords[ic])))
            edge_coords.append(coords[[ia, ib]])
            edge_coords.append(coords[[ib, ic]])
            edge_coords.append(coords[[ia, ic]])
            
    # edges = set(edges)
    m = MultiLineString(edge_coords)
    return cascaded_union(list(polygonize(m))), edge_coords
Example #21
0
def create_grids(shape, meters):
    '''
    purpose
    # create grids within a shape
    
    inputs
    # shape: the shape that forms the exterior of grids
    # meters: the width and heigh of each grid
    
    outputs
    pd.DataFrame(grids): a dataframe with all the grids
    '''

    x_grids = np.arange(shape.bounds[0] - meters, shape.bounds[2] + meters,
                        meters)
    y_grids = np.arange(shape.bounds[1] - meters, shape.bounds[3] + meters,
                        meters)

    x_lines = [((x1, yi), (x2, yi))
               for x1, x2 in zip(x_grids[:-1], x_grids[1:]) for yi in y_grids]
    y_lines = [((xi, y1), (xi, y2))
               for y1, y2 in zip(y_grids[:-1], y_grids[1:]) for xi in x_grids]

    grids = list(polygonize(MultiLineString(x_lines + y_lines)))

    return (pd.DataFrame.from_dict({'shape': grids}))
Example #22
0
File: pcc.py Project: vecoveco/gpm
def alpha_shape(points, alpha):
    from shapely.ops import cascaded_union, polygonize
    from scipy.spatial import Delaunay
    import numpy as np
    import math
    import shapely.geometry as geometry
    """
    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])
    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))
        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
Example #23
0
def create_voronoi_gdf(coordinates, input_gdf):
    """Create a voronoi gdf given a list of coordinates and an input image.

    The exterior of the floorplan image will be used as an outer limit for the geodataframe.

    Args:
        coordinates (list): List of tuples containing points.
        input_gdf (gpd.GeoDataFrame): original b&w input image gdf.

    Returns:
        Geodataframe with voronoi areas, clipped to the input image.
    """
    BUFFER_SIZE = 20
    edge_coordinates = create_exterior_points(input_gdf.buffer(BUFFER_SIZE,
                                                               join_style=2),
                                              number_points_along_line=10)

    vor = Voronoi(coordinates + edge_coordinates)

    lines = [
        LineString(vor.vertices[line]) for line in vor.ridge_vertices
        if -1 not in line
    ]
    all_polygons = list(ops.polygonize(lines))

    areas = gpd.GeoDataFrame(geometry=all_polygons)

    clipped_gdf = gpd.clip(areas, input_gdf, keep_geom_type=True)
    return clipped_gdf
Example #24
0
def alpha_shape(points, alpha):
    def add_edge(points, i, j):
        if (i, j) in edges or (j, i) in edges:
            return
        edges.add((i, j))
        edge_points.append((points[i], points[j]))
    tri = DelaunayTri(points)
    edges = set()
    edge_points = []
    for i1, i2, i3 in tri.vertices:
        x1, y1 = tri.points[i1]
        x2, y2 = tri.points[i2]
        x3, y3 = tri.points[i3]
        a = hypot(x1 - x2, y1 - y2)
        b = hypot(x2 - x3, y2 - y3)
        c = hypot(x3 - x1, y3 - y1)
        s = (a + b + c) / 2.0
        area = sqrt(s * (s - a) * (s - b) * (s - c))
        radius = a * b * c / (4 * area)
        if radius < 1.0 / alpha:
            add_edge(tri.points, i1, i2)
            add_edge(tri.points, i2, i3)
            add_edge(tri.points, i3, i1)
    shape = cascaded_union(list(polygonize(MultiLineString(edge_points))))
    return shape
Example #25
0
def alpha_shape(points, alpha):
    # No alpha shape for a triangle.
    if len(points) < 4:
        return geometry.MultiPoint(list(points)).convex_hull
    coords = np.array([point.coords[0] for point in points])
    tri = Delaunay(coords)
    triangles = coords[tri.vertices]
    a = ((triangles[:, 0, 0] - triangles[:, 1, 0])**2 +
         (triangles[:, 0, 1] - triangles[:, 1, 1])**2)**0.5
    b = ((triangles[:, 1, 0] - triangles[:, 2, 0])**2 +
         (triangles[:, 1, 1] - triangles[:, 2, 1])**2)**0.5
    c = ((triangles[:, 2, 0] - triangles[:, 0, 0])**2 +
         (triangles[:, 2, 1] - triangles[:, 0, 1])**2)**0.5
    s = (a + b + c) / 2.0
    areas = (s * (s - a) * (s - b) * (s - c))**0.5
    circums = a * b * c / (4.0 * areas)
    filtered = triangles[circums < (1.0 / alpha)]
    edge1 = filtered[:, (0, 1)]
    edge2 = filtered[:, (1, 2)]
    edge3 = filtered[:, (2, 0)]
    edge_points = np.unique(np.concatenate((edge1, edge2, edge3)),
                            axis=0).tolist()
    m = geometry.MultiLineString(edge_points)
    triangles = list(polygonize(m))
    return cascaded_union(triangles), edge_points
Example #26
0
def save(datasource, filename):
    """ Save a Datasource instance to a named OGR datasource.
    """
    ext = splitext(filename)[1]

    out_driver = ogr.GetDriverByName(drivers.get(ext))
    out_source = out_driver.CreateDataSource(filename)

    if out_source is None:
        raise Exception('Failed creation of %s - is there one already?' %
                        filename)

    out_layer = out_source.CreateLayer('default', datasource.srs,
                                       ogr.wkbMultiPolygon)

    for field in datasource.fields:
        field_defn = ogr.FieldDefn(field.name, field.type)
        field_defn.SetWidth(field.width)
        out_layer.CreateField(field_defn)

    for i in datasource._indexes():

        segments = datasource.db.execute(
            """SELECT x1, y1, x2, y2
                                            FROM segments
                                            WHERE (src1_id = ? OR src2_id = ?)
                                              AND removed = 0""", (i, i))

        lines = [
            datasource.memo_line(x1, y1, x2, y2)
            for (x1, y1, x2, y2) in segments
        ]

        try:
            poly = polygonize(lines).next()

        except StopIteration:
            lost_area = datasource.shapes[i].area
            lost_portion = lost_area / (datasource.tolerance**2)

            if lost_portion < 4:
                # It's just small.
                print >> stderr, 'Skipped small feature #%(i)d' % locals()
                continue

            # This is a bug we don't understand yet.
            raise Exception(
                'Failed to get a meaningful polygon out of large feature #%(i)d'
                % locals())

        feat = ogr.Feature(out_layer.GetLayerDefn())

        for (j, field) in enumerate(datasource.fields):
            feat.SetField(field.name, datasource.values[i][j])

        geom = ogr.CreateGeometryFromWkb(dumps(poly))

        feat.SetGeometry(geom)

        out_layer.CreateFeature(feat)
Example #27
0
    def segment(self, intersect=True):
        """
        Segments the input detection object with the Voronoi segmentation algorithm.

        :param intersect: If true, intersects with the bounding box of the height model.
        """
        from scipy.spatial import Voronoi
        from shapely.geometry import LineString
        from shapely.ops import polygonize

        vor = Voronoi(self._centered_coords)
        lines = [
            LineString(vor.vertices[line]) for line in vor.ridge_vertices
            if -1 not in line
        ]
        poly_generator = polygonize(lines)

        series = gpd.GeoSeries(poly_generator)
        series = self.translate(series)
        series.crs = self.detection_base.height_model.crs

        if intersect:
            series = series.intersection(
                self.detection_base.height_model._bounding_box_poly)

        return series
Example #28
0
def side_based_procedure(terrain, image):
    line = terrain.center_line.coords
    con = terrain.poly.boundary.coords
    mer = linemerge([con, line])
    uni = unary_union(mer)
    left_side, right_side = polygonize(uni)
    draw = ImageDraw.Draw(image)
    # draw.polygon(convert_to_map(v[0].boundary.coords), fill="#ff0000")
    # draw.polygon(convert_to_map(v[1].boundary.coords), fill="#00ff00")

    center_l = helpers.points_located_on_center_line(
        terrain.center_line, max(1, 1 / TIME_CONSUMPTION))

    left_points = helpers.uniformly_distribute_points(8 / TIME_CONSUMPTION,
                                                      terrain.poly)
    left_points += random_points_in_polygon(int(3 * TIME_CONSUMPTION),
                                            left_side)
    right_points = helpers.uniformly_distribute_points(8 / TIME_CONSUMPTION,
                                                       terrain.poly)
    right_points += random_points_in_polygon(int(3 * TIME_CONSUMPTION),
                                             right_side)

    image = put_rotated_sprites_onto_image(image, False, left_points,
                                           "mountains_side", left_side,
                                           center_l)
    image = put_rotated_sprites_onto_image(image, True, right_points,
                                           "mountains_side", right_side,
                                           center_l)

    if center_l:
        image = put_rotated_sprites_onto_image(image, False, center_l,
                                               "mountains", terrain.poly,
                                               center_l)
    return image
Example #29
0
    def _floor2obsts(self,tin,floor):# {{{
        ''' 
        For a roomX we create a roomX_ghost, we move it by self.walls_width,
        which must match the width of hvents. Then we create walls via logical
        operations. Finally doors cut the openings in walls.

        '''
        if self.fire_model=='FDS':
            return []

        walls=[]
        for i in self.s.query("SELECT * FROM {} WHERE floor=? AND type_pri='COMPA' ORDER BY name".format(tin), (floor,)):

            walls.append((i['x0']+self.walls_width , i['y0']            , i['x0']+i['width']                  , i['y0']+self.walls_width)                )
            walls.append((i['x0']+i['width']       , i['y0']            , i['x0']+i['width']+self.walls_width , i['y0']+i['depth']+self.walls_width)     )
            walls.append((i['x0']+self.walls_width , i['y0']+i['depth'] , i['x0']+i['width']                  , i['y0']+i['depth']+self.walls_width)     )
            walls.append((i['x0']                  , i['y0']            , i['x0']+self.walls_width            , i['y0']+i['depth']+self.walls_width)     )

        walls_polygons=([box(ii[0],ii[1],ii[2],ii[3]) for ii in set(walls)])

        doors_polygons=[]
        for i in self.s.query("SELECT * FROM {} WHERE floor=? AND type_tri='DOOR' ORDER BY name".format(tin), (floor,)):
            doors_polygons.append(box(i['x0'], i['y0'], i['x0']+i['width'], i['y0']+i['depth']))
            
        obsts=[]
        for wall in walls_polygons:
            for door in doors_polygons:
                wall=wall.difference(door)
            if isinstance(wall, MultiPolygon):
                for i in polygonize(wall):
                    obsts.append(i)
            elif isinstance(wall, Polygon):
                obsts.append(wall)
        return obsts 
Example #30
0
File: MD.py Project: JonahY/AE
def voronoi(points, save=False):
    """
    生成德劳内三角网和泰森多边形
    :param points: 要生成德劳内三角网和泰森多边形的点
    :param save: 默认不保存本地文件
    :return:
    """
    pointlength = len(points)
    array = np.array(points)

    # 泰森多边形
    vor = Voronoi(array,
                  furthest_site=False,
                  incremental=True,
                  qhull_options=None)

    if save:
        # 泰森多边形的顶点
        vertices = vor.vertices
        with open('voronoi_vertices.txt', 'w', encoding='utf-8') as f:
            for index, v in enumerate(vertices):
                f.write(
                    str(index) + '\t' + 'POINT(' + str(v[0]) + ' ' +
                    str(v[1]) + ')' + '\n')

        # 泰森多边形的面,-1代表无穷索引
        regions = vor.regions
        with open('voronoi_regions.txt', 'w', encoding='utf-8') as f:
            for index, r in enumerate(regions):
                if len(r) == 0:
                    continue
                if -1 in r:
                    continue
                angulars = []
                for id in r:
                    angulars.append(vertices[id])
                angulars.append(vertices[r[0]])
                polygon = Polygon(angulars)
                f.write(str(index) + '\t' + str(polygon.wkt) + '\n')

        # 德劳内三角形的边,用原始的点数量
        vorOriginal = Voronoi(array[0:pointlength],
                              furthest_site=False,
                              incremental=True,
                              qhull_options=None)
        ridge_points = vorOriginal.ridge_points
        polylines = []
        for ridge in ridge_points:
            polyline = LineString([points[ridge[0]], points[ridge[1]]])
            polylines.append(polyline)
        # 德劳内三角形构面
        delaunays = polygonize(polylines)
        with open(r'voronoi_delaunays.txt', 'w', encoding='utf-8') as f:
            for index, p in enumerate(delaunays):
                f.write(str(index) + '\t' + str(p.wkt) + '\n')

    fig = voronoi_plot_2d(vor)
    plt.gca().xaxis.set_major_locator(plt.NullLocator())
    plt.gca().yaxis.set_major_locator(plt.NullLocator())
    plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
def convert_linestring_to_polygon(geom):

    """Convert (Multi)LineString to (Multi)Polygon

    Use shapely.ops.polygonize to transform (Multi)LineString
    into Multi(Polygon). The function merges all (Multi)Polygons
    into one geometry.

    Args:
        geom: Multi(LineString) geometry

    Returns:
        merged_geom: Multi(Polygon) geometry
    """

    # Check that geometry is (Multi)LineString
    assert isinstance(geom, (LineString, MultiLineString)),\
        "geometry is not (Multi)LineString"

    # Use shapely.ops.polygonize to transform
    # (Multi)LineString into (Multi)Polygon(s)
    # Note that the output is a generator yielding
    # (Multi)Polygon geometries
    polygonized_geom = polygonize(geom)

    # Merge the Multi(Polygon) geometry(ies)
    merged_geom = unary_union(list(polygonized_geom))

    return merged_geom
Example #32
0
    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

        coords = np.array([point.coords[0] for point in points])
        tri = Delaunay(coords)
        triangles = coords[tri.vertices]
        a = ((triangles[:,0,0] - triangles[:,1,0]) ** 2 + (triangles[:,0,1] - triangles[:,1,1]) ** 2) ** 0.5
        b = ((triangles[:,1,0] - triangles[:,2,0]) ** 2 + (triangles[:,1,1] - triangles[:,2,1]) ** 2) ** 0.5
        c = ((triangles[:,2,0] - triangles[:,0,0]) ** 2 + (triangles[:,2,1] - triangles[:,0,1]) ** 2) ** 0.5
        s = ( a + b + c ) / 2.0
        areas = (s*(s-a)*(s-b)*(s-c)) ** 0.5
        circums = a * b * c / (4.0 * areas)
        filtered = triangles[circums < (1.0 / alpha)]
        edge1 = filtered[:,(0,1)]
        edge2 = filtered[:,(1,2)]
        edge3 = filtered[:,(2,0)]
        edge_points = np.unique(np.concatenate((edge1,edge2,edge3)), axis = 0).tolist()
        m = geometry.MultiLineString(edge_points)
        triangles = list(polygonize(m))
        return cascaded_union(triangles), edge_points
 def calculate_iou(predicted, gt):
     if not checkPolygon(predicted, gt):
         assert 1 == 0, 'gt or predicted cannot form polygon'
         return 0
     gt_x = [i[0] for i in gt]
     gt_y = [i[1] for i in gt]
     predicted = Polygon(predicted)
     gt = Polygon(gt)
     assert predicted.is_valid, 'prediction is not valid' + str(predicted)
     if gt.is_valid:
         iou = predicted.intersection(gt).area / predicted.union(gt).area
     else:
         # original data
         ls = LineString(np.c_[gt_x, gt_y])
         # closed, non-simple
         lr = LineString(ls.coords[:] + ls.coords[0:1])
         assert lr.is_simple is False, 'lr is simple'
         mls = unary_union(lr)
         #mls.geom_type  # MultiLineString'
         gt = MultiPolygon(list(polygonize(mls)))
         intersection = 0
         union = predicted
         for gt_polygons in gt:
             intersection += predicted.intersection(gt_polygons).area
             union = union.union(gt_polygons)
         iou = intersection / union.area
     return iou
def polygon_from_points(points):
    num_points = len(points)

    if num_points == 0:
        return Point()

    if num_points == 1:
        return Point(points[0])

    if num_points == 2:
        return LineString(points)

    polygon = Polygon(points)
    if polygon.is_valid:
        return polygon

    raw_edges = polygon_edges(polygon)
    split_edges = split_at_intersections(raw_edges)
    deduplicated_edges = remove_duplicates(split_edges)
    polygons = list(polygonize(deduplicated_edges))

    if len(polygons) > 0:
        return largest_polygon(polygons)

    return Polygon()
Example #35
0
    def get_boundingpolygon(self):
        """
            TODO: Implement ncell bbox

            order of lines creation (assumes 0,0 is x)
            -----3-----
            |         |
            4         2
            |         |
            x----1-----
        """

        if self._ndim == 2: # CGRID
            nx,ny = self._xarray.shape
            one = MultiLineString([((self._xarray[i][0],self._yarray[i][0]),(self._xarray[i+1][0],self._yarray[i+1][0])) for i in range(nx-1)])
            two = MultiLineString([((self._xarray[nx-1][j],self._yarray[nx-1][j]),(self._xarray[nx-1][j+1],self._yarray[nx-1][j+1])) for j in range(ny-1)])
            three = MultiLineString([((self._xarray[i][ny-1],self._yarray[i][ny-1]),(self._xarray[i-1][ny-1],self._yarray[i-1][ny-1])) for i in reversed(list(range(1,nx)))])
            four = MultiLineString([((self._xarray[0][j],self._yarray[0][j]),(self._xarray[0][j-1],self._yarray[0][j-1])) for j in reversed(list(range(1,ny)))])
            m = one.union(two).union(three).union(four)
        else: # RGRID
            nx,ny = self._xarray.shape[0], self._yarray.shape[0]
            one = LineString([(self._xarray[i], self._yarray[0]) for i in range(nx)])
            two = LineString([(self._xarray[-1], self._yarray[i]) for i in range(ny)])
            three = LineString([(self._xarray[i], self._yarray[-1]) for i in reversed(list(range(nx)))])
            four = LineString([(self._xarray[0], self._yarray[i]) for i in reversed(list(range(ny)))])
            m = MultiLineString([one,two,three,four])

        polygons = list(polygonize(m))
        # -- polygonize returns a list of polygons, including interior features, the largest in area "should" be the full feature
        assert len(polygons) > 0, "Could not determine a polygon"
        polygon = sorted(polygons, key=lambda x: x.area)[-1]
        return polygon
def merge_vor(vor, com_points, lim):
    points_coord = []
    #region_indices = []
    lines = []
    for p in com_points:
        if(int(p) < lim):
            points_coord.append(vor.points[int(p)])
        #region_indices.append(vor.point_region[int(p)])
        #r = vor.point_region[int(p)]
        region = vor.regions[vor.point_region[int(p)]]
        for i in range(0, len(region)-1):
            for j in range(1, len(region)):
                v1 = region[i]
                v2 = region[j]
                if(v1 == -1 or v2 == -1): continue
                try:
                    line = geometry.LineString(vor.vertices[[v1, v2]])
                    
                except:
                    try:
                        line = geometry.LineString(vor.vertices[[v2, v1]])
                    except: continue
                lines.append(line)
    print(len(lines))
    shape = ops.unary_union(list(ops.polygonize(lines)))

    return points_coord, shape
Example #37
0
def procesaLineaInterna(featuresExternas, featuresInternas, featuresCentroide, featureDefn):
	#print "Procedemos a procesar las lineas internas"
	
	centroides = []
	for centroide in featuresCentroide:
		#obtenemos la altura y el rotulo del estilo de cada centroide
		for n in centroide.GetStyleString().split(','):
			if n.startswith('s'):
				altura = float(n.replace('s:', '').replace('g', ''))
			elif n.startswith('t'):
				rotulo = n.split('"')[1]
		punto = centroide.GetGeometryRef()
		x = punto.GetX()
		y = punto.GetY()
		longitudRotulo = len(rotulo)
		factor = 0.15 * (altura * 3.3333)
		desfaseX = longitudRotulo * factor - 0.05
		punto.SetPoint(point = 0, x = x + desfaseX, y = y - 0.20)
		
		centroides.append((rotulo, punto))
	
	featuresProceso = featuresExternas + featuresInternas
	
	outFeature = []
	if len(featuresProceso) > 1:
		geometry_out = None
		for inFeature in featuresProceso:
			geometry_in = inFeature.GetGeometryRef()
			if geometry_out is None:
				geometry_out = geometry_in
				geometry_out = ogr.ForceToMultiLineString(geometry_out)
			else:
				geometry_out = geometry_out.Union(geometry_in) 
		
		lineasInternasShapely = loads(geometry_out.ExportToWkt())
		polygonsShapely = polygonize(lineasInternasShapely)
	
		polygonGeom = []
		for polygon in polygonsShapely:
			polygonGeom.append(ogr.CreateGeometryFromWkt(dumps(polygon)))
		
		for pol in polygonGeom:
			for cen in centroides:
				if pol.Contains(cen[1]):
					feature = ogr.Feature(featureDefn)
					feature.SetGeometry(pol)
					feature.SetField('rotulo', cen[0])
					outFeature.append(feature.Clone())
					feature.Destroy()
	else:
		feature = ogr.Feature(featureDefn)
		geometryPoly = ogr.BuildPolygonFromEdges(ogr.ForceToMultiLineString(featuresProceso[0].GetGeometryRef()), dfTolerance = 0)
		feature.SetGeometry(geometryPoly)
		feature.SetField('rotulo', centroides[0][0])
		outFeature.append(feature.Clone())
		feature.Destroy()
	
	
	return outFeature
Example #38
0
    def _cont_to_polys(self, cont_lats, cont_lons):
        polys = []

        start_idx = 0
        splits = []
        while True:
            try:
                split_idx = cont_lats[start_idx:].index(99.99)
                splits.append(start_idx + split_idx)
                start_idx += split_idx + 1
            except ValueError:
                break

        splits = [ -1 ] + splits + [ len(cont_lats) + 1 ]
        poly_lats = [ cont_lats[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]
        poly_lons = [ cont_lons[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]

        # Intersect with the US boundary shape file.
        for plat, plon in zip(poly_lats, poly_lons):
            cont = LineString(zip(plon, plat))

            if plat[0] != plat[-1] or plon[0] != plon[-1]:
                # If the line is not a closed contour, then it intersects with the edge of the US. Extend
                #   the ends a little bit to make sure it's outside the edge.
                dln = np.diff(plon)
                dlt = np.diff(plat)

                pre = [ (plon[0] - 0.5 * dln[0], plat[0] - 0.5 * dlt[0]) ]
                post = [ (plon[-1] + 0.5 * dln[-1], plat[-1] + 0.5 * dlt[-1]) ]

                cont.coords = pre + list(cont.coords) + post 

            # polygonize() will split the country into two parts: one inside the outlook and one outside.
            #   Construct test_ln that is to the right of (inside) the contour and keep only the polygon
            #   that contains the line
            test_ln = cont.parallel_offset(0.05, 'right')

            for poly in polygonize(self._conus.boundary.union(cont)):
                if (poly.crosses(test_ln) or poly.contains(test_ln)) and self._conus.contains(poly.buffer(-0.01)):
                    polys.append(poly)

        # Sort the polygons by area so we intersect the big ones with the big ones first.
        polys.sort(key=lambda p: p.area, reverse=True)

        # If any polygons intersect, replace them with their intersection.
        intsct_polys = []
        while len(polys) > 0:
            intsct_poly = polys.pop(0)
            pops = []
            for idx, poly in enumerate(polys):
                if intsct_poly.intersects(poly):
                    intsct_poly = intsct_poly.intersection(poly)
                    pops.append(idx)

            for pop_idx in pops[::-1]:
                polys.pop(pop_idx)

            intsct_polys.append(intsct_poly)
        return intsct_polys
Example #39
0
def get_convex_hull(points):
    """ Find the convex hull of points, return as Shapely polygon """
    log.info("Finding convex hull of %i points", len(points))
    hull = ConvexHull(points)
    log.info("Found convex hull with %i facets", len(hull.simplices))
    hull_edges = []
    for simplex in hull.simplices:
        hull_edges.append(
            zip(points[simplex, 0], points[simplex, 1]))
    polygon = list(polygonize(hull_edges))
    assert(len(polygon) == 1)
    return polygon[0]
Example #40
0
def get_shapes(filelike):
    shapes = []
    node_cache = {}
    way_cache = {}
    for thing in iter_osm_file(filelike):
        if type(thing) == Node:
            pt = (thing.lon, thing.lat)
            shape = Point(pt)

            node_cache[thing.id] = pt

            if thing.tags:
                shapes.append((thing, shape))

        elif type(thing) == Way:
            points = []
            for nd in thing.nds:
                node_loc = node_cache.get(nd)
                if node_loc:
                    points.append(node_loc)
                else:
                    raise Exception("Way %s references node %s which is not parsed yet." % (thing.id, nd))

            if way_is_polygon(thing):
                shape = Polygon(points)
            else:
                shape = LineString(points)

            way_cache[thing.id] = points

            if any(thing.tags):
                # Only include tagged things at this point. Otherwise,
                # the shapes that are part of multipolygon relations
                # will be included twice.
                shapes.append((thing, shape))

        elif type(thing) == Relation:
            if any([t.key == 'type' and t.value == 'multipolygon' for t in thing.tags]):
                parts = []
                for member in thing.members:
                    if member.type == 'way':
                        shape = way_cache.get(member.ref)
                        if not shape:
                            raise Exception("Relation %s references way %s which is not parsed yet." % (thing.id, member.ref))

                        parts.append(shape)

                # Polygonize will return all the polygons created, so the
                # inner parts of the multipolygons will be returned twice
                # we only want the first one
                shapes.append((thing, next(polygonize(parts))))

    return shapes
Example #41
0
 def test_polygonize(self):
     lines = [
         LineString(((0, 0), (1, 1))),
         LineString(((0, 0), (0, 1))),
         LineString(((0, 1), (1, 1))),
         LineString(((1, 1), (1, 0))),
         LineString(((1, 0), (0, 0))),
         LineString(((5, 5), (6, 6))),
         Point(0, 0),
         ]
     result = list(polygonize(lines))
     self.assertTrue(all([isinstance(x, Polygon) for x in result]))
Example #42
0
def save(datasource, filename):
    """ Save a Datasource instance to a named OGR datasource.
    """
    ext = splitext(filename)[1]
    
    out_driver = ogr.GetDriverByName(drivers.get(ext))
    out_source = out_driver.CreateDataSource(filename)
    
    if out_source is None:
        raise Exception('Failed creation of %s - is there one already?' % filename)
    
    out_layer = out_source.CreateLayer('default', datasource.srs, ogr.wkbMultiPolygon)
    
    for field in datasource.fields:
        field_defn = ogr.FieldDefn(field.name, field.type)
        field_defn.SetWidth(field.width)
        out_layer.CreateField(field_defn)
    
    for i in datasource._indexes():
    
        segments = datasource.db.execute("""SELECT x1, y1, x2, y2
                                            FROM segments
                                            WHERE (src1_id = ? OR src2_id = ?)
                                              AND removed = 0""", (i, i))
    
        lines = [datasource.memo_line(x1, y1, x2, y2) for (x1, y1, x2, y2) in segments]
        
        try:
            poly = polygonize(lines).next()
    
        except StopIteration:
            lost_area = datasource.shapes[i].area
            lost_portion = lost_area / (datasource.tolerance ** 2)
            
            if lost_portion < 4:
                # It's just small.
                print >> stderr, 'Skipped small feature #%(i)d' % locals()
                continue
    
            # This is a bug we don't understand yet.
            raise Exception('Failed to get a meaningful polygon out of large feature #%(i)d' % locals())
        
        feat = ogr.Feature(out_layer.GetLayerDefn())
        
        for (j, field) in enumerate(datasource.fields):
            feat.SetField(field.name, datasource.values[i][j])
        
        geom = ogr.CreateGeometryFromWkb(dumps(poly))
        
        feat.SetGeometry(geom)
    
        out_layer.CreateFeature(feat)
Example #43
0
def intersect(a, b):
    ap, bp = [orient_offset_polygon(p) for p in [a,b]]
    overlap = ap.intersection(bp)

    if overlap.is_empty:
        return []

    if not hasattr(overlap, 'exterior'):
        return [Poly(p.exterior.coords, p.centroid.coords[0], 0)
                for p in polygonize(overlap)]
    
    return [Poly(overlap.exterior.coords,
                 overlap.centroid.coords[0], 0)]
Example #44
0
 def processAlgorithm(self, progress):
     try:
         from shapely.ops import polygonize
         from shapely.geometry import Point, MultiLineString
     except ImportError:
         raise GeoAlgorithmExecutionException(
                 'Polygonize algorithm requires shapely module!')
     vlayer = dataobjects.getObjectFromUri(
             self.getParameterValue(self.INPUT))
     output = self.getOutputFromName(self.OUTPUT)
     vprovider = vlayer.dataProvider()
     if self.getParameterValue(self.FIELDS):
         fields = vprovider.fields()
     else:
         fields = QgsFields()
     if self.getParameterValue(self.GEOMETRY):
         fieldsCount = fields.count()
         fields.append(QgsField('area', QVariant.Double, 'double', 16, 2))
         fields.append(QgsField('perimeter', QVariant.Double,
                                'double', 16, 2))
     allLinesList = []
     features = vector.features(vlayer)
     current = 0
     total = 40.0 / float(len(features))
     for inFeat in features:
         inGeom = inFeat.geometry()
         if inGeom.isMultipart():
             allLinesList.extend(inGeom.asMultiPolyline())
         else:
             allLinesList.append(inGeom.asPolyline())
         current += 1
         progress.setPercentage(int(current * total))
     progress.setPercentage(40)
     allLines = MultiLineString(allLinesList)
     allLines = allLines.union(Point(0, 0))
     progress.setPercentage(45)
     polygons = list(polygonize([allLines]))
     progress.setPercentage(50)
     writer = output.getVectorWriter(fields, QGis.WKBPolygon, vlayer.crs())
     outFeat = QgsFeature()
     current = 0
     total = 50.0 / float(len(polygons))
     for polygon in polygons:
         outFeat.setGeometry(QgsGeometry.fromWkt(polygon.wkt))
         if self.getParameterValue(self.GEOMETRY):
             outFeat.setAttributes([None] * fieldsCount + [polygon.area,
                                   polygon.length])
         writer.addFeature(outFeat)
         current += 1
         progress.setPercentage(50 + int(current * total))
     del writer
Example #45
0
    def processAlgorithm(self, progress):
        vlayer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
        output = self.getOutputFromName(self.OUTPUT)
        vprovider = vlayer.dataProvider()
        if self.getParameterValue(self.FIELDS):
            fields = vprovider.fields()
        else:
            fields = QgsFields()
        if self.getParameterValue(self.GEOMETRY):
            fieldsCount = fields.count()
            fields.append(QgsField('area', QVariant.Double, 'double', 16, 2))
            fields.append(QgsField('perimeter', QVariant.Double,
                                   'double', 16, 2))
        allLinesList = []
        features = vector.features(vlayer)
        progress.setInfo(self.tr('Processing lines...'))
        total = 40.0 / len(features)
        for current, inFeat in enumerate(features):
            inGeom = inFeat.geometry()
            if inGeom.isMultipart():
                allLinesList.extend(inGeom.asMultiPolyline())
            else:
                allLinesList.append(inGeom.asPolyline())
            progress.setPercentage(int(current * total))

        progress.setPercentage(40)
        allLines = MultiLineString(allLinesList)

        progress.setInfo(self.tr('Noding lines...'))
        allLines = unary_union(allLines)

        progress.setPercentage(45)
        progress.setInfo(self.tr('Polygonizing...'))
        polygons = list(polygonize([allLines]))
        if not polygons:
            raise GeoAlgorithmExecutionException(self.tr('No polygons were created!'))
        progress.setPercentage(50)

        progress.setInfo('Saving polygons...')
        writer = output.getVectorWriter(fields, QgsWkbTypes.Polygon, vlayer.crs())
        outFeat = QgsFeature()
        total = 50.0 / len(polygons)
        for current, polygon in enumerate(polygons):
            outFeat.setGeometry(QgsGeometry.fromWkt(polygon.wkt))
            if self.getParameterValue(self.GEOMETRY):
                outFeat.setAttributes([None] * fieldsCount + [polygon.area,
                                                              polygon.length])
            writer.addFeature(outFeat)
            progress.setPercentage(50 + int(current * total))
        del writer
def create_union(in_ply1, in_ply2):
    """
    Create union polygon
    :param in_ply1: first input polygon
    :param in_ply2: second input polygon
    :return: shapely polgon
    """
    # union the polygon outer linestrings together
    outer_bndry = in_ply1.boundary.union(in_ply2.boundary)

    # rebuild linestrings into polygons
    output_poly = polygonize(outer_bndry)
    # pprint(list(polygonize(outer_bndry)))
    return output_poly
Example #47
0
    def _cont_to_polys(self, cont_lats, cont_lons, cont_val):
        """
        Take the lat/lon contours, split them into their different segments, and create polygons out of them. Contours
        that stretch from border to border will end up covering large sections of the country. That's okay; we'll take
        care of that later.
        """
        polys = {}

        start_idx = 0
        splits = []
        while True:
            try:
                split_idx = cont_lats[start_idx:].index(99.99)
                splits.append(start_idx + split_idx)
                start_idx += split_idx + 1
            except ValueError:
                break

        splits = [ -1 ] + splits + [ len(cont_lats) + 1 ]
        poly_lats = [ cont_lats[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]
        poly_lons = [ cont_lons[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]

        # Intersect with the US boundary shape file.
        for plat, plon in zip(poly_lats, poly_lons):
            cont = LineString(zip(plon, plat))

            if plat[0] != plat[-1] or plon[0] != plon[-1]:
                # If the line is not a closed contour, then it intersects with the edge of the US. Extend
                #   the ends a little bit to make sure it's outside the edge.
                dln = np.diff(plon)
                dlt = np.diff(plat)

                pre = [ (plon[0] - 0.03 * dln[0], plat[0] - 0.03 * dlt[0]) ]
                post = [ (plon[-1] + 0.03 * dln[-1], plat[-1] + 0.03 * dlt[-1]) ]

                cont.coords = pre + list(cont.coords) + post 

            # polygonize() will split the country into two parts: one inside the outlook and one outside.
            #   Construct test_ln that is to the right of (inside) the contour and keep only the polygon
            #   that contains the line
            test_ln = cont.parallel_offset(0.05, 'right')

            polys[cont] = []

            for poly in polygonize(self._conus.boundary.union(cont)):
                if (poly.crosses(test_ln) or poly.contains(test_ln)) and self._conus.contains(poly.buffer(-0.01)):
                    polys[cont].append(poly)

        return polys
Example #48
0
  def union(self):
    '''new method using Union function'''
    global polyCount
    inFeat = QgsFeature()

    progress = 0.

    self.emit(SIGNAL('progress'), 0)

    self.parent.layer = getMapLayerByName(self.ui.cmbLayer.currentText())
    provider = self.parent.layer.dataProvider()
    #user can't toggle edit mode of line layer while polygonizing, plugin automatically turn it off 
    QObject.connect(self.parent.layer,SIGNAL("editingStarted()"), self.parent.startEditing)
    allAttrs = provider.attributeIndexes()
    provider.select(allAttrs)

    provider.select()

    step = 45. / self.parent.layer.featureCount()
    allLinesList = []
    allLinesListExtend = allLinesList.extend
    allLinesListAppend = allLinesList.append

    while provider.nextFeature(inFeat):
      geom = inFeat.geometry()
      if geom.isMultipart():
        allLinesListExtend(geom.asMultiPolyline() )
      else:
        allLinesListAppend(geom.asPolyline())

      progress += step
      self.emit(SIGNAL('progress'), progress)

    allLines = MultiLineString(allLinesList)
    allLines = allLines.union(Point(0,0))

    polygons = list(polygonize([allLines]))

    polyCount = len(polygons)
    #if no polygons where created then exit from thread
    if polyCount == 0:
      QObject.disconnect(self.parent.polygonizeThread,SIGNAL("finished()"), self.parent.threadFinished)
      self.emit(SIGNAL('noPolygons'))
      return
    else:
      if self.ui.cbOutput.isChecked():
        self.saveAsFile(polygons, progress)
      else:
        self.saveInMemory(polygons, progress)
Example #49
0
    def _geometric_process(self):

        if len(self._entries) != 1:
            merged_union = linemerge(unary_union(self._entries))
        else:
            merged_union = MultiLineString(self._entries)

        self._edges = [ Edge(tuple(g.coords)) for g in merged_union.geoms ]

        edges = map(lambda e: e._geom, self._edges)

        if self._bnode:
            xyset = set([edge.coords[i] for edge in edges for i in (0,-1)])
            self._nodes = map(lambda xy: Node(xy),xyset)

        if self._bface:
            self._faces = [Face(poly.exterior,poly.interiors) for poly in polygonize(edges)]
Example #50
0
    def _topological_process(self):

        # initialisation des arcs (géométrie calculée, autres attributs à None)

        init_None = dict.fromkeys(('start_node','end_node','left_face','right_face'),None)
        if len(self._entries) != 1:
            merged_union = linemerge(unary_union(self._entries))
        else:
            merged_union = MultiLineString(self._entries)
        self._edges = [ Edge(tuple(g.coords),**init_None) for g in merged_union.geoms ]
        del merged_union


        # liste des géométries Shapely des Edge (arcs du graphe) et index spatial
        # (facilité d'écriture par la suite + fait une seule fois)

        edges   = map(lambda e: e._geom,self._edges)
        edge_si = geometry_spatial_index(edges)

        # construction des noeuds, mise à jour des noeuds départ et fin des arcs

        self._nodes, already_done = list(), dict()
        for edge in self._edges:
            for i,attname in ((0,'_start_node'),(-1,'_end_node')):
                xy = edge._geom.coords[i]
                inode = already_done.get(xy,None)
                if inode is None:
                    already_done[xy] = inode = len(self._nodes)
                    self._nodes.append(Node(xy))
                setattr(edge,attname,inode)
        del already_done

        # création des faces du graphe planaire

        self._faces = list()
        for polygon in polygonize(edges):
            new_face = Face(polygon.exterior,polygon.interiors,extring=None,intrings=list())
            self._faces.append(new_face)

        # liste des géométries Shapely des Face (faces du graphe et index spatial)
        # (facilité d'écriture par la suite + fait une seule fois)
        faces   = map(lambda pgf: pgf._geom,self._faces)
        face_si = geometry_spatial_index(faces)

        self._process_rings(edges,faces,edge_si,face_si)
Example #51
0
def polygonizeFeatures(features, fields=None):
    lineList = []
    for inFeat in features:
        inGeom = inFeat.geometry()
        if inGeom is None:
            pass
        elif inGeom.isMultipart():
            lineList.extend(inGeom.asMultiPolyline())
        else:
            lineList.append(inGeom.asPolyline())
    allLines = MultiLineString(lineList)
    allLines = unary_union(allLines)
    polygons = list(polygonize([allLines]))
    outList = []
    for polygon in polygons:
        outFeat = QgsFeature(fields)
        outFeat.setGeometry(QgsGeometry.fromWkt(polygon.wkt))
        outList.append(outFeat)
    return outList
Example #52
0
def clipped_polygon(azimuth,polygon,line1,line2):
    merged_line = linemerge([line1, line2])
    merged = linemerge([polygon.boundary, merged_line])
    borders = unary_union(merged)
    polygons = polygonize(borders)
    polygon_list = list(polygons)
    if len(polygon_list)>1:
        polygon1 = polygon_list[0]
        polygon2 = polygon_list[1]
        polygon1_area = polygon_area_calculator(polygon=polygon1)
        polygon2_area=polygon_area_calculator(polygon=polygon2)
        polygon_areas = (polygon1_area, polygon2_area)
        polygon_dict = {polygon1_area:polygon1, polygon2_area:polygon2}
        if azimuth >= 180:
            result = polygon_dict[max(polygon_areas)]
        elif azimuth == 0 or azimuth == 360:
            result = polygon_dict[max(polygon_areas)]
        else:
            result = polygon_dict[min(polygon_areas)]
        return result
    else:
        return polygon
Example #53
0
def fix_invalid_polygon(p):
    if not p.is_valid:
        p_buffer_0 = p.buffer(0)
        # If the polygon cross itself the .buffer(0) operation
        # will return only half of the polygon (the other half
        # may be considered negative)
        # This is not what we want, so we check resulting area 
        # to detect this didn't happen:
        if p_buffer_0.area >= p.area*0.99:
            p = p_buffer_0
        else:
            # Compute the list of all segments of the polygon, add  missing points
            # at the position they cross each others, and use
            # polygonize() tool function to rebuild a MultiPolygon
            assert(len(p.interiors) == 0)
            coords = p.exterior.coords
            segments = [ LineString([coords[i], coords[i+1]]) for i in xrange(len(coords)-1)]
            crosses = [set() for i in xrange(len(segments))]
            for i in xrange(len(segments)):
                for j in xrange(i):
                  if segments[i].crosses(segments[j]):
                      intersection = segments[i].intersection(segments[j])
                      assert(type(intersection)== ShapelyPoint)
                      intersection = intersection.coords[0]
                      crosses[i].add(intersection)
                      crosses[j].add(intersection)
            result_segments = []
            for i in xrange(len(segments)):
                if crosses[i]:
                    points = list(crosses[i])
                    points.sort(key = lambda c : ShapelyPoint(segments[i].coords[0]).distance(ShapelyPoint(c)))
                    points = [segments[i].coords[0]] + points + [segments[i].coords[1]]
                    for j in xrange(len(points) - 1):
                        result_segments.append((points[j], points[j+1]))
                else:
                    result_segments.append((segments[i].coords[0], segments[i].coords[1]))
            p = MultiPolygon(list(polygonize(result_segments)))
    return p
Example #54
0
def tesselation(regionlocs):
    """Function to create a tesselation from the regionlocs.

    Parameters
    ----------
    regionlocs: array_like
        the spatial locations that define each region considered.

    Returns
    -------
    polygons: shapely.Polygon
        the polygon object which contains the information to define it as
        a polygon.

    """
    vor = Voronoi(regionlocs)
    lines = []
    for line in vor.ridge_vertices:
        if -1 not in line:
            lines.append(shapely.geometry.LineString(vor.vertices[line]))
    pols = ops.polygonize(lines)
    polygons = [poly for poly in pols]
    return polygons
Example #55
0
    def Polygonize(self):
        if self.ui.cmbLayer.currentText() == "":
            QMessageBox.critical(self, "Polygonizer", "Select line layer first!")
        elif getMapLayerByName(self.ui.cmbLayer.currentText()).dataProvider().featureCount() == 0:
            QMessageBox.critical(self, "Polygonizer", "Selected layer has no lines!")
        elif self.ui.eOutput.text() == "":
            QMessageBox.critical(self, "Polygonizer", "Choose output file!")
        else:
            sys.setcheckinterval(10000)
            setValue = self.ui.pbProgress.setValue
            SetWidgetsEnabled(self.ui, False)

            setValue(0)

            self.t1 = time()

            if self.ui.rbNew.isChecked():
                inFeat = QgsFeature()
                outFeat = QgsFeature()
                layer = QgsVectorLayer()

                layer = getMapLayerByName(self.ui.cmbLayer.currentText())

                progress = 0.0

                provider = layer.dataProvider()
                allAttrs = provider.attributeIndexes()
                provider.select(allAttrs)
                fields = provider.fields()

                provider.select()

                step = 30.0 / layer.featureCount()
                allLinesList = []
                allLinesListExtend = allLinesList.extend
                allLinesListAppend = allLinesList.append

                while provider.nextFeature(inFeat):
                    geom = inFeat.geometry()

                    if geom.isMultipart():
                        allLinesListExtend(geom.asMultiPolyline())
                    else:
                        allLinesListAppend(geom.asPolyline())

                    progress += step
                    setValue(progress)

                allLines = MultiLineString(allLinesList)
                allLines = allLines.union(Point(0, 0))

                polygons = list(polygonize([allLines]))

                self.polyCount = len(polygons)
                if self.polyCount == 0:
                    QMessageBox.critical(self, "Polygonizer", "Sorry, I don't see any polygon!")
                    SetWidgetsEnabled(self.ui, True)
                    setValue(0)
                    return
                else:
                    step = 65.0 / self.polyCount

                    # addFeature = writer.addFeature
                    setGeometry = outFeat.setGeometry  # ok
                    setAttributeMap = outFeat.setAttributeMap  # ok

                    if self.ui.cbGeometry.isChecked():
                        fields[len(fields)] = QgsField("area", QVariant.Double, "double", 16, 2)
                        fields[len(fields)] = QgsField("perimeter", QVariant.Double, "double", 16, 2)
                        nrArea = len(fields) - 2
                        nrPerimeter = len(fields) - 1

                        writer = QgsVectorFileWriter(
                            self.ui.eOutput.text(), provider.encoding(), fields, QGis.WKBPolygon, layer.srs()
                        )

                        for polygon in polygons:
                            # QInputDialog.getText( self, "m", "e",   QLineEdit.Normal,  str(fields) )
                            setGeometry(QgsGeometry.fromWkt(polygon.wkt))
                            setAttributeMap({nrArea: polygon.area, nrPerimeter: polygon.length})
                            writer.addFeature(outFeat)

                            progress += step
                            setValue(progress)

                        setValue(100)
                        del writer

                    else:
                        writer = QgsVectorFileWriter(
                            self.ui.eOutput.text(), provider.encoding(), fields, QGis.WKBPolygon, layer.srs()
                        )
                        for polygon in polygons:
                            setGeometry(QgsGeometry.fromWkt(polygon.wkt))
                            writer.addFeature(outFeat)

                            progress += step
                            setValue(progress)

                        setValue(100)
                        del writer

            else:
                inFeat = QgsFeature()
                inFeatB = QgsFeature()
                outFeat = QgsFeature()
                layer = QgsVectorLayer()
                layer = self.getMapLayerByName(self.ui.cmbLayer.currentText())
                progress = 0.0

                provider = layer.dataProvider()

                allAttrs = provider.attributeIndexes()
                provider.select(allAttrs)
                fields = provider.fields()

                new_path = self.ui.eOutput.text()
                if new_path.contains("\\"):
                    out_name = new_path.right((new_path.length() - new_path.lastIndexOf("\\")) - 1)
                else:
                    out_name = new_path.right((new_path.length() - new_path.lastIndexOf("/")) - 1)
                if out_name.endsWith(".shp"):
                    out_name = out_name.left(out_name.length() - 4)

                step = 20.0 / float(provider.featureCount())

                # to single lines and without duplicate lines
                provider.select()
                lines = []
                while provider.nextFeature(inFeat):

                    inGeom = inFeat.geometry()
                    if inFeat.geometry().isMultipart():
                        for line in inFeat.geometry().asMultiPolyline():
                            self.splitline(line, lines)
                    else:
                        self.splitline(inFeat.geometry().asPolyline(), lines)
                    progress += step
                    setValue(progress)

                # QMessageBox.critical(self.iface.mainWindow(), "d", str(len(lines)))

                single_lines = QgsVectorLayer("LineString", "single", "memory")
                single_provider = single_lines.dataProvider()

                step = 20.0 / float(len(lines))
                for line in lines:
                    outFeat.setGeometry(QgsGeometry.fromPolyline(line))
                    single_provider.addFeatures([outFeat])
                    single_lines.updateExtents()
                    progress += step
                    setValue(progress)

                # intersections
                index = createIndex(single_provider)
                lines = []
                single_provider.select()
                step = 50.0 / float(single_provider.featureCount())
                while single_provider.nextFeature(inFeat):
                    pointList = []
                    inGeom = inFeat.geometry()
                    lineList = index.intersects(inGeom.boundingBox())
                    if len(lineList) > 0:
                        for i in lineList:
                            single_provider.featureAtId(int(i), inFeatB, True, allAttrs)
                            tmpGeom = QgsGeometry(inFeatB.geometry())
                            if inGeom.intersects(tmpGeom):
                                pointGeom = inGeom.intersection(tmpGeom)
                                if pointGeom.type() == QGis.Point:
                                    if pointGeom.asPoint() not in pointList:
                                        pointList.append(pointGeom.asPoint())
                        linePoints = []
                        linePoints = inGeom.asPolyline()
                        s = [i for i in pointList + linePoints if i not in linePoints]
                        if len(s) > 1:
                            l = sortPoints(linePoints[0], s)
                        else:
                            l = s

                        tempLine = []
                        tempLine.append(linePoints[0])
                        tempLine.extend(l)
                        tempLine.append(linePoints[1])

                        countSubLines = len(tempLine) - 1
                        for p in range(countSubLines):
                            lines.append([tempLine[p], tempLine[p + 1]])
                    progress += step
                    setValue(progress)

                del single_lines
                del single_provider

                # create polygons

                polygons = list(polygonize(lines))

                self.polyCount = 0
                self.polyCount = len(polygons)
                # QMessageBox.critical(self.iface.mainWindow(), "d", str(fields))

                setValue(95)

                setGeometry = outFeat.setGeometry  # ok
                setAttributeMap = outFeat.setAttributeMap  # ok

                if self.ui.cbGeometry.isChecked():
                    fields[len(fields)] = QgsField("area", QVariant.Double, "double", 16, 2)
                    fields[len(fields)] = QgsField("perimeter", QVariant.Double, "double", 16, 2)
                    nrArea = len(fields) - 2
                    nrPerimeter = len(fields) - 1

                    writer = QgsVectorFileWriter(new_path, provider.encoding(), fields, QGis.WKBPolygon, layer.srs())

                    for polygon in polygons:
                        # QInputDialog.getText( self.parent, "m", "e",   QLineEdit.Normal,  str(polygon))
                        setGeometry(QgsGeometry.fromWkt(polygon.wkt))
                        setAttributeMap({nrArea: polygon.area, nrPerimeter: polygon.length})
                        writer.addFeature(outFeat)

                        progress += step
                        setValue(progress)

                    del writer
                    setValue(100)
                else:
                    writer = QgsVectorFileWriter(new_path, provider.encoding(), fields, QGis.WKBPolygon, layer.srs())

                    for polygon in polygons:
                        # QInputDialog.getText( self.parent, "m", "e",   QLineEdit.Normal,  str(polygon))
                        setGeometry(QgsGeometry.fromWkt(polygon.wkt))
                        writer.addFeature(outFeat)

                        progress += step
                        setValue(progress)

                    del writer
                    setValue(100)

            # koniec
            self.t2 = time()

            # self.ui.pbProgress.setValue(0)
            SetWidgetsEnabled(self.ui, True)

            msg = QMessageBox.question(
                self,
                "Polygonizer",
                "Polygonization finished in %03.2f seconds. \n %d polygons were crested. \n Load created layer?"
                % ((self.t2 - self.t1), self.polyCount),
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.Yes,
            )
            if msg == QMessageBox.Yes:
                new_path = self.ui.eOutput.text()
                if new_path.contains("\\"):
                    out_name = new_path.right((new_path.length() - new_path.lastIndexOf("\\")) - 1)
                else:
                    out_name = new_path.right((new_path.length() - new_path.lastIndexOf("/")) - 1)
                if out_name.endsWith(".shp"):
                    out_name = out_name.left(out_name.length() - 4)

                self.iface.addVectorLayer(self.ui.eOutput.text(), out_name, "ogr")

            self.close()
#####################################
#             second plot
#  display sample intersection
# ###################################

ax = fig.add_subplot(122)

# convert circle polygon to linestring of circle boundary
cirle_as_line = polygon.boundary

# combine new boundary lines with the input set of lines
result_union_lines = cirle_as_line.union(line)

# re-create polygons from unioned lines
new_polygons = polygonize(result_union_lines)

# stores the final split up polygons
new_cut_ply = []

# identify which new polygon we want to keep
for poly in new_polygons:
    # check if new poly is inside original otherwise ignore it
    if poly.centroid.within(polygon):
        # center_pt = poly.centroid
        # ax.plot(center_pt.x, center_pt.y, 'o', color='#999999')
        print "creating new split polygon"
        patch3 = PolygonPatch(poly, fc='purple',
                              alpha=0.5, zorder=2)
        ax.add_patch(patch3)
        # add only polygons that overlap original for export
    def track(self, original_img, filtered_img, prev_data):
        n_objects = self.nObjectsSpinBox.value()
        n_k_means = self.nKmeansSpinBox.value()

        non_zero_pos = np.transpose(np.nonzero(filtered_img.T))

        contours = [None for i in range(n_objects)]

        # FIXME: 真っ黒な画像が入力されたときのためアドホックに対処.
        if self.gmm is None:
            gmm = GroupTrackerGMM(
                n_components=n_objects,
                covariance_type='full',
                n_iter=1000,
                init_params='wc',
                params='wc'
            )
            gmm.set_likelihood_diff_threshold(
                self.likelihoodDiffThresholdSpinBox.value()
            )
        else:
            gmm = self.gmm

        try:
            gmm._fit(non_zero_pos, n_k_means=n_k_means)
            self.gmm = gmm
            res = self.gmm.means_

            predict = self.gmm.predict(non_zero_pos)
            skeletons = []
            for i in range(n_objects):
                p_data = non_zero_pos[predict == i]

                ch_vtx_list = skeletonize2D.get_concave_hull(
                    p_data.astype(np.int32)
                )
                ch_poly = unary_union(list(
                    polygonize(geometry.MultiLineString(ch_vtx_list))
                ))
                if ch_poly.type == 'Polygon':
                    ch = np.array(ch_poly.exterior.coords)
                elif ch_poly.type == 'MultiPolygon':
                    try:
                        new_poly = cascaded_union(
                            ch_poly.buffer(10).buffer(-10)
                        )
                        if new_poly.type == 'MultiPolygon':
                            new_poly = new_poly[np.argmax([
                                poly.area
                                for poly in new_poly
                            ])]
                        ch = np.array(new_poly.exterior.coords)
                    except:
                        ch = contours[i]

                contours[i] = ch

                edges, vertices = skeletonize2D.get_skeleton_from_polygon(
                    ch.astype(np.float64)
                )
                G = nx.Graph()
                G.add_weighted_edges_from(edges)

                init_nodes = list(filter(
                    lambda n: G.degree(n) == 1, G.nodes_iter()
                ))
                longest_path_list = get_longest_paths(init_nodes, G)

                optimal_path = skeletonize2D.find_optimal_path(
                    longest_path_list,
                    vertices
                )
                skeletons.append(vertices[optimal_path[1:-1], :])
                # tck, u = splprep([unique[path, 0], unique[path, 1]])
                # t = 0.0
                # t_list = []
                # while t<1:
                #     t_list.append(t)
                #     t += 1.0/ np.linalg.norm(splev(t, tck, der=1))
                #
                # interpolated = splev(t_list,tck)
                # skeletons.append(np.array([
                #     [x,y] for x,y in zip(*interpolated)
                # ]))

                # plt.plot(unique[path, 0], unique[path, 1])
                # plt.scatter(interpolated[0], interpolated[1])

            # plt.show()
        except Exception as e:
            if self.gmm is None:
                res = np.full((n_objects, 2), np.nan)
                skeletons = np.full((n_objects, 3, 2), np.nan)
                contours = np.full((n_objects, 3, 2), np.nan)
            else:
                if prev_data['ignore_error']:
                    res = prev_data['position']
                    skeletons = prev_data['path']
                    contours = prev_data['polygon']
                else:
                    raise RuntimeError(
                        '{}\n'
                        'Please check "Ignore mis-detection error" on '
                        'if you want to ignore tracking errors.'.format(e)
                    )

        return {'position': res, 'path': skeletons, 'polygon': contours}
Example #58
0
def _overlay_old(df1, df2, how, use_sindex=True, **kwargs):
    """Perform spatial overlay between two polygons.

    Currently only supports data GeoDataFrames with polygons.
    Implements several methods that are all effectively subsets of
    the union.

    Parameters
    ----------
    df1 : GeoDataFrame with MultiPolygon or Polygon geometry column
    df2 : GeoDataFrame with MultiPolygon or Polygon geometry column
    how : string
        Method of spatial overlay: 'intersection', 'union',
        'identity', 'symmetric_difference' or 'difference'.
    use_sindex : boolean, default True
        Use the spatial index to speed up operation if available.

    Returns
    -------
    df : GeoDataFrame
        GeoDataFrame with new set of polygons and attributes
        resulting from the overlay

    """
    allowed_hows = [
        'intersection',
        'union',
        'identity',
        'symmetric_difference',
        'difference',  # aka erase
    ]

    if how not in allowed_hows:
        raise ValueError("`how` was \"%s\" but is expected to be in %s" % \
            (how, allowed_hows))

    if isinstance(df1, GeoSeries) or isinstance(df2, GeoSeries):
        raise NotImplementedError("overlay currently only implemented for GeoDataFrames")

    # Collect the interior and exterior rings
    rings1 = _extract_rings(df1)
    rings2 = _extract_rings(df2)
    mls1 = MultiLineString(rings1)
    mls2 = MultiLineString(rings2)

    # Union and polygonize
    mm = unary_union([mls1, mls2])
    newpolys = polygonize(mm)

    # determine spatial relationship
    collection = []
    for fid, newpoly in enumerate(newpolys):
        cent = newpoly.representative_point()

        # Test intersection with original polys
        # FIXME there should be a higher-level abstraction to search by bounds
        # and fall back in the case of no index?
        if use_sindex and df1.sindex is not None:
            candidates1 = [x.object for x in
                           df1.sindex.intersection(newpoly.bounds, objects=True)]
        else:
            candidates1 = [i for i, x in df1.iterrows()]

        if use_sindex and df2.sindex is not None:
            candidates2 = [x.object for x in
                           df2.sindex.intersection(newpoly.bounds, objects=True)]
        else:
            candidates2 = [i for i, x in df2.iterrows()]

        df1_hit = False
        df2_hit = False
        prop1 = None
        prop2 = None
        for cand_id in candidates1:
            cand = df1.loc[cand_id]
            if cent.intersects(cand[df1.geometry.name]):
                df1_hit = True
                prop1 = cand
                break  # Take the first hit
        for cand_id in candidates2:
            cand = df2.loc[cand_id]
            if cent.intersects(cand[df2.geometry.name]):
                df2_hit = True
                prop2 = cand
                break  # Take the first hit

        # determine spatial relationship based on type of overlay
        hit = False
        if how == "intersection" and (df1_hit and df2_hit):
            hit = True
        elif how == "union" and (df1_hit or df2_hit):
            hit = True
        elif how == "identity" and df1_hit:
            hit = True
        elif how == "symmetric_difference" and not (df1_hit and df2_hit):
            hit = True
        elif how == "difference" and (df1_hit and not df2_hit):
            hit = True

        if not hit:
            continue

        # gather properties
        if prop1 is None:
            prop1 = pd.Series(dict.fromkeys(df1.columns, None))
        if prop2 is None:
            prop2 = pd.Series(dict.fromkeys(df2.columns, None))

        # Concat but don't retain the original geometries
        out_series = pd.concat([prop1.drop(df1._geometry_column_name),
                                prop2.drop(df2._geometry_column_name)])

        out_series.index = _uniquify(out_series.index)

        # Create a geoseries and add it to the collection
        out_series['geometry'] = newpoly
        collection.append(out_series)

    # Return geodataframe with new indices
    return GeoDataFrame(collection, index=range(len(collection)))
Example #59
0
def get_concave_hull(points, cut):
    """ Find the concave hull for a set of points
    """
    max_x, max_y = np.max(points, axis=0)
    min_x, min_y = np.min(points, axis=0)
    log.info("Found %i nodes, bounded in x by (%i, %i)"
             " and y by (%i, %i)",
             len(points), min_x, max_x, min_y, max_y)
    size = max(max_x - min_x, max_y - min_y)
    tri = Delaunay(points)
    log.info("Found %i Delaunay triangles", len(tri.vertices))

    edges = Counter()

    def add_edge(i, j):
        """Count the occurences of each edge. """
        edges[(i, j) if i > j else (j, i)] += 1
    # loop over triangles:
    # ia, ib, ic = indices of corner points of the triangle
    for ia, ib, ic in tri.vertices:

        pa = points[ia]
        pb = points[ib]
        pc = points[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

        argument = s*(s-a)*(s-b)*(s-c)
        if argument < 0:
            continue

        # Area of triangle by Heron's formula
        area = math.sqrt(argument)

        if area <= 0:
            continue

        circum_r = a*b*c/(4.0*area)

        # Here's the radius filter.
        if circum_r / size < 1.0 / cut:
            add_edge(ia, ib)
            add_edge(ib, ic)
            add_edge(ic, ia)

    log.info("After filter, %i edges remain", len(edges))
    if not edges:
        log.warning("No edges remain, concave hull is not defined!")
        return None

    # Exterior edges are only owned by one triangle.
    exterior_edges = [
        points[list(edge)] for edge, count
        in edges.iteritems() if count == 1]

    m = MultiLineString(exterior_edges)
    log.info("Polygonizing")
    triangles = list(polygonize(m))
    log.info("Unionizing")
    polygon = cascaded_union(triangles)

    best_polygon = polygon
    best_area = polygon.area

    if isinstance(polygon, MultiPolygon):
        best_area = 0
        log.info("Multi polygons detected")
        for ip, subpoly in enumerate(polygon):
            #log.info("Poly %i - area: %f", ip, subpoly.area)
            if subpoly.area > best_area:
                best_polygon = subpoly
                best_area = subpoly.area
    log.info("Found main polygon with area: %f", best_area)
    return best_polygon