Beispiel #1
0
    def split_geom(row):
        # Get related line
        rel_line = lines[row[lineIdInPntShp]]

        if type(rel_line["GEOM"]) != list:
            line_geom = fix_line(rel_line["GEOM"], row.geometry)

            split_lines = split(line_geom, row.geometry)

            lines[row[lineIdInPntShp]]["GEOM"] = [l for l in split_lines]

        else:
            for i in range(len(rel_line["GEOM"])):
                if rel_line["GEOM"][i].distance(row.geometry) < 1e-8:
                    line_geom = fix_line(rel_line["GEOM"][i], row.geometry)
                    split_lines = split(line_geom, row.geometry)
                    split_lines = [l for l in split_lines]

                    lines[row[lineIdInPntShp]]["GEOM"][i] = split_lines[0]
                    lines[row[lineIdInPntShp]]["GEOM"] += split_lines[1:]

                    break

                else:
                    continue
        return row
Beispiel #2
0
    def transform(self, image, target):
        orig_size = image.size
        image = self.head_transforms(image)
        if not is_bitonal(image):
            self.im_mode = image.mode
        image = self.tail_transforms(image)
        scale = image.shape[2] / orig_size[0]
        t = torch.zeros((self.num_classes, ) + image.shape[1:])
        start_sep_cls = self.class_mapping['aux']['_start_separator']
        end_sep_cls = self.class_mapping['aux']['_end_separator']

        for key, lines in target['baselines'].items():
            cls_idx = self.class_mapping['baselines'][key]
            for line in lines:
                # buffer out line to desired width
                line = [k for k, g in groupby(line)]
                line = np.array(line) * scale
                shp_line = geom.LineString(line)
                split_offset = min(5, shp_line.length / 2)
                line_pol = np.array(shp_line.buffer(self.line_width / 2,
                                                    cap_style=2).boundary,
                                    dtype=np.int)
                rr, cc = polygon(line_pol[:, 1],
                                 line_pol[:, 0],
                                 shape=image.shape[1:])
                t[cls_idx, rr, cc] = 1
                split_pt = shp_line.interpolate(split_offset).buffer(0.001)
                start_sep = np.array((split(shp_line, split_pt)[0].buffer(
                    self.line_width, cap_style=3).boundary),
                                     dtype=np.int)
                rr_s, cc_s = polygon(start_sep[:, 1],
                                     start_sep[:, 0],
                                     shape=image.shape[1:])
                t[start_sep_cls, rr_s, cc_s] = 1
                t[start_sep_cls, rr, cc] = 0
                split_pt = shp_line.interpolate(-split_offset).buffer(0.001)
                end_sep = np.array((split(shp_line, split_pt)[-1].buffer(
                    self.line_width, cap_style=3).boundary),
                                   dtype=np.int)
                rr_s, cc_s = polygon(end_sep[:, 1],
                                     end_sep[:, 0],
                                     shape=image.shape[1:])
                t[end_sep_cls, rr_s, cc_s] = 1
                t[end_sep_cls, rr, cc] = 0
        for key, regions in target['regions'].items():
            cls_idx = self.class_mapping['regions'][key]
            for region in regions:
                region = np.array(region) * scale
                rr, cc = polygon(region[:, 1],
                                 region[:, 0],
                                 shape=image.shape[1:])
                t[cls_idx, rr, cc] = 1
        target = t
        if self.aug:
            image = image.permute(1, 2, 0).numpy()
            target = target.permute(1, 2, 0).numpy()
            o = self.aug(image=image, mask=target)
            image = torch.tensor(o['image']).permute(2, 0, 1)
            target = torch.tensor(o['mask']).permute(2, 0, 1)
        return image, target
Beispiel #3
0
def split_intersection(a, b):
    """Return geometry collections of line a split by line b and line b split by line a.

    :param a:
    :type a: shapely.geometry.linestring.LineString
    :param b:
    :type b: shapely.geometry.linestring.LineString
    :return:
    :rtype: tuple
    """
    split_a = split(a, b)
    split_b = split(b, a)
    return split_a, split_b
Beispiel #4
0
def split_flowline(intersectionPoint, flowlines):

    # Convert the flowline to a geometry colelction to be exported
    nhdGeom = flowlines['features'][0]['geometry']
    nhdFlowline = GeometryCollection([shape(nhdGeom)])[0]
    nhdFlowline = LineString([xy[0:2] for xy in list(nhdFlowline[0].coords)
                              ])  # Convert xyz to xy

    # If the intersectionPoint is on the NHD Flowline, split the flowline at the point
    if nhdFlowline.intersects(intersectionPoint) is True:
        NHDFlowlinesCut = split(nhdFlowline, intersectionPoint)

    # If they don't intersect (weird right?), buffer the intersectionPoint and then split the flowline
    if nhdFlowline.intersects(intersectionPoint) is False:
        buffDist = intersectionPoint.distance(nhdFlowline) * 1.01
        buffIntersectionPoint = intersectionPoint.buffer(buffDist)
        NHDFlowlinesCut = split(nhdFlowline, buffIntersectionPoint)
        # print('NHDFlowlinesCut: ', len(NHDFlowlinesCut), NHDFlowlinesCut)

    # If the NHD Flowline was split, then calculate measure
    try:
        NHDFlowlinesCut[1]
    except AssertionError as error:  # If NHDFlowline was not split, then the intersectionPoint is either the first or last point on the NHDFlowline
        startPoint = Point(nhdFlowline[0].coords[0][0],
                           nhdFlowline[0].coords[0][1])
        lastPointID = len(nhdFlowline[0].coords) - 1
        lastPoint = Point(nhdFlowline[0].coords[lastPointID][0],
                          nhdFlowline[0].coords[lastPointID][1])
        if (intersectionPoint == startPoint):
            upstreamFlowline = GeometryCollection()
            downstreamFlowline = NHDFlowlinesCut
            error = 'The point of intersection is the first point on the NHD Flowline.'
        if (intersectionPoint == lastPoint):
            downstreamFlowline = GeometryCollection()
            upstreamFlowline = NHDFlowlinesCut
            error = 'The point of intersection is the last point on the NHD Flowline.'
        if (intersectionPoint != startPoint
                and intersectionPoint != lastPoint):
            error = 'Error: NHD Flowline measure not calculated'
            downstreamFlowline = GeometryCollection()
            upstreamFlowline = GeometryCollection()
        print(error)
    else:
        lastLineID = len(NHDFlowlinesCut) - 1
        upstreamFlowline = NHDFlowlinesCut[0]
        downstreamFlowline = NHDFlowlinesCut[lastLineID]
    print('split NHD Flowline')

    return upstreamFlowline, downstreamFlowline
Beispiel #5
0
 def run_part2(self):
     g1 = self.make_geom(self.w1)
     g2 = self.make_geom(self.w2)
     intshape = g1.intersection(g2)
     min_steps = 1000000000
     for point in intshape:
         if point.x == 0 and point.y == 0:
             continue
         # split the lines at the intersection and take the lengths
         s1 = split(g1, point)
         s2 = split(g2, point)
         steps = s1[0].length + s2[0].length
         if steps < min_steps:
             min_steps = steps
     return min_steps
def is_underlapping(
    geom: LineString,
    trace: LineString,
    endpoint: Point,
    snap_threshold: float,
    snap_threshold_error_multiplier: float,
) -> Optional[bool]:
    """
    Determine if a geom is underlapping.
    """
    split_results = list(split(geom, trace).geoms)
    if len(split_results) == 1:
        # Do not intersect
        return True
    if len(split_results) > 1:
        for segment in split_results:
            if (
                segment.distance(endpoint)
                < snap_threshold * snap_threshold_error_multiplier
            ):
                # Dangling end, overlapping
                return False
    logging_prints = {
        "geom": geom,
        "trace": trace,
        "endpoint": endpoint,
        "snap_threshold": snap_threshold,
        "snap_threshold_error_multiplier": snap_threshold_error_multiplier,
    }
    logging.error(
        f"Expected is_underlapping to be resolvable.\nvalues:{logging_prints}"
    )
    return None
Beispiel #7
0
def polygon_vertical_split(p, cut_x):
    assert p.type == 'Polygon'

    min_x, min_y, max_x, max_y = p.bounds
    assert min_x < cut_x < max_x

    return ops.split(p, LineString([(cut_x, min_y), (cut_x, max_y)]))
def _split_linestring_by_point(linestring, points):
    """
    Function to split a linestring geometry by multiple inner points

    Parameters
    ----------
    lstring : LineString
        Linestring of the line to be splitted
    points : list
        List of points to split the linestring

    Return
    ------
    list_lines : list
        List of linestring to split the line
    """

    list_linestrings = [linestring]

    for p in points:
        # execute split to all lines and store results
        temp_list = [split(l, p) for l in list_linestrings]
        # nest all geometries
        list_linestrings = [
            lstring for tval in temp_list for lstring in tval.geoms
        ]

    return list_linestrings
def connect_nodes_to_closest_edges(edges_df, nodes_df,
                                   edges_geom='individual_linestring',
                                   nodes_geom='point_geometry'):
    """fdas
    """
    for i in range(len(prag_points)):
        point = prag_points.loc[i,nodes_geom]
        shortest_distance = 100000
        closest_street_index = None
        original_street_id = None
        for j in range(len(edges_df)):
            line = edges_df.loc[j,edges_geom]
            if line.distance(point) < shortest_distance:
                shortest_distance = line.distance(point)
                print(shortest_distance)
                closest_street_index = j
                original_street_id = edges_df.loc[j,'kod']
                intersect_point = line.interpolate(line.project(point))
                closest_line = line
        # write results - both to points and to streets
        # new street split at the closest point
        new_line = add_point_to_linestring(closest_line, intersect_point)
        print(new_line, '\n',
              closest_line, '\n',
              LineString([point, intersect_point]), '\n',
              original_street_id, '\n',
              shortest_distance, '\n',
              line == split(line, intersect_point))
        edges_df.loc[closest_street_index, edges_geom] = new_line     
        nodes_df.loc[i,'shortest_path'] = LineString([point, intersect_point])
        nodes_df.loc[i,'closest_street_id'] = original_street_id
        nodes_df.loc[i,'street_distance'] = point.distance(intersect_point)
        nodes_df.loc[i,'intersect_point'] = intersect_point
    return(edges_df, nodes_df)
Beispiel #10
0
def getShapelySectors(v_type, trajectory, shapely_dist, shapely_ang):

    sectors = []

    if v_type == "person":
        for i in range(1, len(trajectory.coords)):
            p1 = Point(trajectory.coords[0])
            p1b = Point(trajectory.coords[i - 1])
            p2 = Point(trajectory.coords[i])
            dist = p1.distance(p2)
            circle = p1.buffer(dist)

            line = LineString([trajectory.coords[0], trajectory.coords[i]])
            left_border = rotate(line, -shapely_ang, origin=p1b)
            right_border = rotate(line, shapely_ang, origin=p1b)
            splitter = LineString([
                *left_border.coords, line.coords[-1],
                *right_border.coords[::-1]
            ])
            polygon = split(circle, splitter)
            if len(polygon) > 1:
                sectors.append(polygon[1])
    else:
        for i in range(1, len(trajectory.coords)):
            line = LineString([trajectory.coords[i - 1], trajectory.coords[i]])
            lineB = line.buffer(shapely_dist, cap_style=1)
            sectors.append(lineB)

    return sectors
Beispiel #11
0
def refinedConvexHull(shapesInRegion, borderGeoms):
    """
        tries to cut the convex hull based on the borders
    """
    regionShape = shapesInRegion.convex_hull
    # TODO: this does not work yet as linesegments are not complete (maybe need to union street segments into one)
    shapesForRefinement = unary_union(borderGeoms)
    if isinstance(shapesForRefinement, LineString):
        shapesForRefinement = [shapesForRefinement]
    elif not isinstance(shapesForRefinement, BaseMultipartGeometry):
        raise ValueError(type(shapesForRefinement))
    for singleLine in shapesForRefinement:
        polygonSplits = split(regionShape, singleLine)
        # as the region contains every buildingGroup
        regionPolygons = [
            s for s in polygonSplits if s.contains(shapesInRegion[0])
        ]

        if len(regionPolygons) == 1:
            regionShape = regionPolygons[0]
        else:
            raise ValueError(
                "Borders should not split a region into more than one valid region"
            )
    return regionShape
Beispiel #12
0
def _remove_halfplane(polygon, origin, normal):
    """
    :param polygon: Polygon to cut
    :param origin: Point that defines the half-plane with `normal`
    :param normal: Vector that defines the half-plane with `origin`
    """
    unit_normal = _normalize(normal)
    cut_direction = _rotate_2d(unit_normal, pi / 2)

    # Assuming that `origin` is inside the polygon, we can use this length
    # (*2 even) and stretch the line from there to construct a line that cuts
    # the entire polygon.
    safe_length = 3 * _diagonal_length(polygon.bounds)
    cut_line = LineString([
        origin - safe_length * cut_direction,
        origin + safe_length * cut_direction
    ])

    parts = split(polygon, cut_line)
    # Assumes `split` returns a collection of two geometries (I think it does):
    # one on the one side of the line, and one on the other side.
    for part in parts:
        if not _in_halfplane(part.representative_point().coords[0], origin,
                             unit_normal):
            return part
    return Point()  # The empty feature (nothing is left!)
    def findBoundaryLines(self):
        #Find the bounary line which will cut by faults lines
        #ACTNUM is not considered here
        NX, NY = self.GRDECL_Data.NX, self.GRDECL_Data.NY

        if (self.NumFaultLines == 0):
            print(
                "Please find the Fault lines first! Boundary Lines cutted by it"
            )
            return

        #Raw boundary lines (currently only support straight boundary)
        Edge1 = ((0, 0), (NX, 0))
        Edge2 = ((NX, 0), (NX, NY))
        Edge3 = ((NX, NY), (0, NY))
        Edge4 = ((0, NY), (0, 0))
        RawBoundaryLines = MultiLineString([Edge1, Edge2, Edge3,
                                            Edge4])  #Shapely object

        #Split boundary lines
        unique_intersectPts = list(set(self.IntersectPts))
        #print(unique_intersectPts)
        pts = MultiPoint(unique_intersectPts)  #Shapely object
        result = split(RawBoundaryLines, pts)  #Shapely function

        #Convert shapely object to list of tuple
        self.BoundaryLines = Shapely2List_MultiLineString(result)
def Taxi(centroids, minMaxXY):
    vertRegions = dict()
    polies = list()
    for c in centroids:
        mesh = sg.box(*minMaxXY)
        others = list(set(centroids) - {c})
        for other in NearestFirst(c, others):
            pp = sg.LineString(TaxiPP(c, other, minMaxXY))
            r = rSide(c, other, ops.split(mesh, pp))
            if r: mesh = r

            finished = True
            for p in mesh.exterior.coords:
                if not p in vertRegions:
                    vertRegions[p] = RegionsAt(p, centroids)
                if len(vertRegions[p]) == 1: finished = False
            if finished:
                break
                # region mesh verts are all bordering 2 or 3 regions

        if mesh.is_empty: oopes()
        polies.append(mesh)

    # remove invalid verts
    #vertRegions = {v:vertRegions[v] for v in vertRegions if len(vertRegions[v])>1}

    return polies
Beispiel #15
0
 def scale(self, xfact=1, yfact=1, origin='center', inplace=True):
     if type(origin) is int:
         sides = split(self.polygon.boundary,
                       MultiPoint(self.polygon.exterior.coords))
         origin = sides[origin].centroid
     return self.affine_transform('scaling', inplace,
                                  (xfact, yfact, origin))
Beispiel #16
0
def split_to_lines(polygon):
    """Split a square-ish polygon into 4 lines.

    :param polygon:
    :type polygon: shapely.geometry.polygon.Polygon
    :return:
    """
    breakpoints = []
    vertices = polygon.exterior.coords

    for i in range(1, len(vertices) + 1):
        a = vertices[i - 1]
        try:
            b = vertices[i]
        except IndexError:
            break
        try:
            c = vertices[i + 1]
        except IndexError:
            c = vertices[1]
        angle = calculate_angle(a, b, c)
        if MIN_ANGLE < angle < MAX_ANGLE:
            logging.debug("Adding breakpoint: {}".format(angle))
            breakpoints.append(b)
    if len(breakpoints) != 4:
        raise Exception(
            "Expecting 4 breakpoints for polygon, found {}!".format(
                len(breakpoints)))
    logging.debug(breakpoints)
    lines = split(asLineString(polygon.exterior.coords),
                  MultiPoint(breakpoints))
    return lines
Beispiel #17
0
def cut_line_between_fractions(
        line: shp.linestring, start_fraction: float,
        end_fraction: float) -> shp.LineString:  # todo refactor
    """Cut a line at 2 fractions and return the region between them.

    :param line: Linestring to cut
    :param start_fraction: Fraction 1 (0 < f1 < f2)
    :param end_fraction: Fraction 2 (f1 < f2 < 1)
    :return: Linestring that was cut out
    """
    assert 0 <= start_fraction <= end_fraction
    assert start_fraction <= end_fraction <= 1

    # point a fraction on the line
    p1 = line.interpolate(start_fraction, normalized=True)
    p2 = line.interpolate(end_fraction, normalized=True)

    # Cut the line: this returns the target cut but also returns several little chunks (<< 1e-6 in length)
    # small buffer includes rounding errors
    cut_lines = ops.split(line, shp.MultiPoint([p1, p2]).buffer(1e-12))

    # Filter out the tiny pieces
    filter_function = partial(filter_line_length, line, start_fraction,
                              end_fraction)
    valid_line = filter(filter_function, cut_lines)

    # There should be a single item in this list
    return list(valid_line)[0]
Beispiel #18
0
        def shift_geom(shift, gdataframe, plotQ=False):
            # this code is adapted from answer found in SO
            # will be credited here: ???
            shift -= 180
            moved_geom = []
            splitted_geom = []
            border = LineString([(shift, 90), (shift, -90)])

            for row in gdataframe["geometry"]:
                splitted_geom.append(split(row, border))
            for element in splitted_geom:
                items = list(element)
                for item in items:
                    minx, miny, maxx, maxy = item.bounds
                    if minx >= shift:
                        moved_geom.append(translate(item, xoff=-180 - shift))
                    else:
                        moved_geom.append(translate(item, xoff=180 - shift))

            # got `moved_geom` as the moved geometry
            moved_geom_gdf = gpd.GeoDataFrame({"geometry": moved_geom})

            # can change crs here
            if plotQ:
                fig1, ax1 = plt.subplots(figsize=[8, 6])
                moved_geom_gdf.plot(ax=ax1)
                plt.show()

            return moved_geom_gdf
Beispiel #19
0
def clip_geometry_to_tile(geometry, tile):
    tile_geom = box(*mercantile.bounds(tile))

    # Geometry collection of split objects
    split_gc = split(geometry, tile_geom)

    return [g for g in split_gc if tile_geom.contains(g)]
Beispiel #20
0
def divide_bbox(rectangle, nrows, ncols):
    '''
    Divides a rectangular bounding box in
    rows and columns

    Reference: https://stackoverflow.com/questions/58283684/how-to-divide-a-rectangle-in-specific-number-of-rows-and-columns
    '''

    minx, miny, maxx, maxy = rectangle.bounds

    dx = (maxx - minx) / nrows  # width of a small part

    dy = (maxy - miny) / ncols  # height of a small part

    horizontal_splitters = [
        LineString([(minx, miny + i * dy), (maxx, miny + i * dy)])
        for i in range(ncols)
    ]

    vertical_splitters = [
        LineString([(minx + i * dx, miny), (minx + i * dx, maxy)])
        for i in range(nrows)
    ]

    splitters = horizontal_splitters + vertical_splitters

    for splitter in splitters:
        rectangle = MultiPolygon(split(rectangle, splitter))

    return [split_rectangle for split_rectangle in rectangle]
	def get_exterior_lines(self,as_the_line=True,show=0):
		lines=list()
		if as_the_line: line_getter=lambda _line:TheLine(_line)
		else: line_getter=lambda _line:_line

		if self.is_multilinestring:
			is_ok=False
			for _ in self.polygon.boundary:
				is_ok=True
				break
			if not is_ok:
				simple_logger.critical('self.geometry:\n%s',self.geometry)
				for p in self.points: p.plot()
				simple_logger.critical('len(self.points): %s',len(self.points))
				plt.show()

		current_chunk=self.polygon.boundary[0] if self.is_multilinestring else self.polygon.boundary
		for xy in self.xy[1:-1]:
			# ThePoint(xy).plot()
			line,current_chunk=shops.split(current_chunk,shg.Point(xy))
			lines.append(line_getter(line))
		lines.append(line_getter(current_chunk))
		if show:
			for i,line in enumerate(lines):
				if as_the_line: line.plot()
				else: TheLine(line).plot()

		# TheLine(line=line).plot(**plot_kwargs)
		# simple_logger.debug('line.xy: %s',line.xy)
		# plt.plot(*line.xy,**plot_kwargs)
		# plt.plot(*line.parallel_offset(5).xy)
		return lines
Beispiel #22
0
def cutOutline(point, linestring):
    """
    Given a point finds an entity in (multi)linestring which goes through the
    point. Then returns the string starting and ending in that point
    """
    LEN_LIMIT = 40 # Should be roughly equal to half the circular segments,
                    # may prevent from finding a solution
    if isinstance(linestring, LineString):
        geom = [linestring]
    elif isinstance(linestring, MultiLineString):
        geom = linestring.geoms
    else:
        raise RuntimeError("Unknown geometry '{}' passed".format(type(linestring)))
    for string in geom:
        if not string.intersects(point):
            continue
        splitted = split(string, point)
        if len(splitted) > 1:
            string = LineString(list(splitted[1].coords) + splitted[0].coords[1:])
        else:
            string = splitted[0]
        limit1 = max(1, len(string.coords) - LEN_LIMIT)
        limit2 = min(LEN_LIMIT, len(string.coords) - 1)
        return LineString(string.coords[limit1:]), LineString(string.coords[:limit2])
    return None, None
Beispiel #23
0
def snap_points(points, lines, crs):
    tolerance = 0.5
    length = lines.shape[0]
    for i in range(length):
        for point in points.geometry:
            line = lines.loc[i, "geometry"]
            line._crs = crs
            point._crs = crs
            point_inline_projection = line.interpolate(line.project(point))
            point_inline_projection._crs = crs
            distance_to_line = point.distance(point_inline_projection)
            if (point.x, point.y) in line.coords:
                x = "nothing"
            else:
                if  distance_to_line < tolerance:
                    buff = point.buffer(0.1)
                    ### Split the line on the buffer
                    geometry = split(line, buff)
                    geometry._crs = crs
                    line_1_points = [tuple(xy) for xy in geometry[0].coords[:-1]]
                    line_1_points.append((point.x, point.y))
                    line_2_points = []
                    line_2_points.append((point.x, point.y))
                    line_2_points.extend([x for x in geometry[-1].coords[1:]])
                    ### Stitch together the first segment, the interpolated point, and the last segment
                    new_line = linemerge((LineString(line_1_points), LineString(line_2_points)))
                    lines.loc[i, "geometry"] = new_line

    G = points["geometry"].apply(lambda geom: geom.wkb)
    points = points.loc[G.drop_duplicates().index]

    G = lines["geometry"].apply(lambda geom: geom.wkb)
    lines = lines.loc[G.drop_duplicates().index]

    return points, lines
Beispiel #24
0
def test1():
    polygon = [[40, 20], [150, 50], [240, 130], [80, 120]]
    shapely_poly = Polygon(polygon)

    line = [(10, 20), (220, 180)]
    shapely_line = LineString(line)

    # intersection_line = list(shapely_poly.intersection(shapely_line).coords)
    # print(intersection_line.area)

    splited1, splited2 = split(shapely_poly, shapely_line)
    area1 = splited1.area
    area2 = splited2.area

    if area1 > area2:
        big_split_polygon = splited1.exterior.coords
    else:
        big_split_polygon = splited2.exterior.coords
    # print(list(big_split_polygon))
    big_split_polygon = np.array(list(big_split_polygon), np.int32)

    image = np.full((400, 400, 3), 255)

    image = cv2.polylines(image, [np.array(polygon)], True, (0, 0, 255), 2)
    image = cv2.fillPoly(image, [big_split_polygon], (0, 0, 255))
    image = cv2.line(image, line[0], line[1], (255, 0, 0), 2)
    return image
Beispiel #25
0
def split_line_at_point(line, point):
    """Splits the `line` at the `point` on the line and returns it's two parts.

    Parameters
    ----------
    line : shapely.geometry.LineString
    point : shapely.geometry.Point

    Returns
    -------
    line_before: shapely.geometry.LineString
        Part of `line` before `point`
    line_after: shapely.geometry.LineString
        Part of `line` after `point`

    """

    if line.distance(point) > 1e-8:
        raise ValueError('Point not on line')

    # Use small buffer polygon instead of point to deal with floating point precision
    circle = point.buffer(1e-8)
    line_split = ops.split(line, circle)
    line_before = line_split[0]
    line_after = line_split[-1]

    return line_before, line_after
Beispiel #26
0
def split_line_by_nearest_points(gdf_line, gdf_points, tolerance, crs):
    """
    Split the union of lines with the union of points resulting

    :param GeoDataFrame gdf_line:  GeoDataFrame with multiple rows of connecting line segments
    :param GeoDataFrame gdf_points: geodataframe with multiple rows of single points

    :returns: ``gdf_segments`` (GeoDataFrame of segments)
    :rtype: GeoDataFrame

    https://github.com/ojdo/python-tools/blob/master/shapelytools.py#L144
    """

    # union all geometries
    line = gdf_line.geometry.unary_union
    line._crs = crs
    snap_points = gdf_points.geometry.unary_union
    snap_points._crs = crs

    # snap and split coords on line
    # returns GeometryCollection
    # snap_points = snap(coords, line, tolerance)
    # snap_points._crs = crs
    split_line = split(line, snap(snap_points, line, tolerance))
    split_line._crs = crs
    segments = [feature for feature in split_line if feature.length > 0.01]

    gdf_segments = gdf(geometry=segments, crs=crs)
    # gdf_segments.columns = ['index', 'geometry']

    return gdf_segments
Beispiel #27
0
def simple_line_cut(linestring, point1, dist_thres, tol, trace=True):
    from shapely.ops import nearest_points
    from shapely.ops import split
    from shapely.geometry import MultiPoint, LineString

    #Find nearest points on line:
    np1 = nearest_points(linestring, point1)

    # Return error message if points are too far away from line:
    dist1 = np1[0].distance(np1[1])
    if dist1 > dist_thres:
        if trace:
            print(
                'Point1 is', dist1,
                'units apart from line which is more than the specified distance threshold of',
                dist_thres)
        return None

    #Do split:
    split_1 = split(linestring, np1[0].buffer(tol))
    if len(list(split_1)) == 1:
        if trace:
            print('Splitting at mapped point 1 did not work')
        return None

    return list(split_1)
def split_country_superseded(country_polygon):
    '''This works for countries when a single split results in only two areas (not more than two areas)'''
    # Split the country if its area is greater than 250 degree square
    max_area = 250
    n_splits = math.ceil(country_polygon.area / max_area)
    if n_splits == 1:
        return country_polygon
    else:
        centroid = country_polygon.centroid.coords[0]
        boundary_points = [
            pt for i, pt in enumerate(country_polygon.exterior.coords) if i %
            math.ceil(len(country_polygon.exterior.coords) / n_splits) == 0
        ]

        # original selected boundary points
        boundary_points_org = boundary_points.copy()
        # Roll the list to the left
        boundary_points.append(boundary_points.pop(0))
        line_dict = dict()
        for i, (a, b) in enumerate(zip(boundary_points_org, boundary_points)):
            line_dict[i] = LineString([a, centroid, b])
        # Create a dictionary where each value is a segment of the country
        country_segment_dict = dict()
        remaining = country_polygon
        for s in range(n_splits - 1):
            area_area = split(remaining, line_dict[s])
            country_segment_dict[s] = area_area[0]
            remaining_iter = iter(area_area)
            next(remaining_iter)
            remaining = next(remaining_iter)
        country_segment_dict[n_splits - 1] = remaining
        return list(country_segment_dict.values())
Beispiel #29
0
    def split_precise(linestring, splitter):
        """
        Shapely's split() function will only split LineStrings at vertices.
        This returns the split LineStrings exactly at the point of intersection.
        Assumes a single intersection.
        """

        # If there is no intersection, return the linestring
        if linestring.intersects(splitter) is False:
            return linestring

        ssplit = split(linestring, splitter)
        split_pt = linestring.intersection(splitter)

        splits = []
        for s in ssplit:
            if Point(s.coords[0]).distance(split_pt) < Point(
                    s.coords[-1]).distance(split_pt):
                splits.append(
                    LineString(list(split_pt.coords) + list(s.coords)))
            else:
                splits.append(
                    LineString(list(s.coords) + list(split_pt.coords)))

        return splits
def split_line_at_MultiPoint(line_geometry, intersection):   

    """
    The function checks whether the coordinates of Point(s) in a Point Collections coordinate are part of the sequence of coordinates of a LineString.
    When this has been ascerted or fixed, the LineString line_geometry is split at each of the intersecting points in the collection.
    
    The input intersection, must be an actual intersection.
               
    Parameters
    ----------
    line_geometry: LineString
        the LineString which has to be split
    intersection: MultiPoint
        the intersecting points
        
    Returns
    -------
    MultiLineString
    """
    for point in intersection:
        new_line_coords = list(line_geometry.coords)
        for n, v in enumerate(new_line_coords):
            if n == 0: 
                continue
            line = LineString([Point(new_line_coords[n-1]), Point(v)])
            if ((point.intersects(line)) | (line.distance(point) < 1e-8)):
                new_line_coords.insert(n, point.coords[0])
                break
        line_geometry = LineString([coor for coor in new_line_coords])
                     
    lines = split(line_geometry, intersection)   
    return lines
Beispiel #31
0
	def test_split_closed_ring_with_point(self):
		splitter = Point([0.0, 0.0])
		self.helper(self.ls, splitter, 1)

		splitter = Point([0.0, 0.5])
		self.helper(self.ls, splitter, 2)
		result = split(self.ls, splitter)
		assert result[0].coords[:] == [(0, 0), (0.0, 0.5)]
		assert result[1].coords[:] == [(0.0, 0.5), (0, 1), (1, 1), (1, 0), (0, 0)]

		# previously failed, see GH#585
		splitter = Point([0.5, 0.0])
		self.helper(self.ls, splitter, 2)
		result = split(self.ls, splitter)
		assert result[0].coords[:] == [(0, 0), (0, 1), (1, 1), (1, 0), (0.5, 0)]
		assert result[1].coords[:] == [(0.5, 0), (0, 0)]

		splitter = Point([2.0, 2.0])
		self.helper(self.ls, splitter, 1)
Beispiel #32
0
	def test_split_poly_with_other(self):
		with self.assertRaises(ValueError):
			split(self.poly_simple, Point(1, 1))
		with self.assertRaises(ValueError):
			split(self.poly_simple, MultiPoint([(1, 1), (3, 4)]))
		with self.assertRaises(ValueError):
			split(self.poly_simple, self.poly_hole)
Beispiel #33
0
	def helper(self, geom, splitter, expected_chunks):
		s = split(geom, splitter)
		self.assertEqual(s.type, "GeometryCollection")
		self.assertEqual(len(s), expected_chunks)
		if expected_chunks > 1:
			# split --> expected collection that when merged is again equal to original geometry
			if s.geoms[0].type == 'LineString':
				self.assertTrue(linemerge(s).simplify(0.000001).equals(geom))
			elif s.geoms[0].type == 'Polygon':
				union = cascaded_union(s).simplify(0.000001)
				self.assertTrue(union.equals(geom))
				self.assertEqual(union.area, geom.area)
			else:
				raise ValueError
		elif expected_chunks == 1:
			# not split --> expected equal to line
			self.assertTrue(s[0].equals(geom))