Esempio n. 1
0
def determine_nodes_intersecting_sets(
    trace_series_two_sets: Tuple[gpd.GeoSeries, gpd.GeoSeries],
    set_names_two_sets: Tuple[str, str],
    node_series_xy: gpd.GeoSeries,
    buffer_value: float,
) -> List[bool]:
    """
    Conduct a spatial intersect between nodes and traces.

    Node GeoDataFrame contains only X- and Y-nodes and the trace GeoDataFrame
    only two sets. Returns boolean array of based on intersections.

    E.g.

    >>> traces = gpd.GeoSeries([LineString([(0, 0), (1, 1)])]), gpd.GeoSeries(
    ...     [LineString([(0, 1), (0, -1)])]
    ... )
    >>> set_names_two_sets = ("1", "2")
    >>> nodes_xy = gpd.GeoSeries([Point(0, 0), Point(1, 1), Point(0, 1), Point(0, -1)])
    >>> buffer_value = 0.001
    >>> determine_nodes_intersecting_sets(
    ...     traces, set_names_two_sets, nodes_xy, buffer_value
    ... )
    [True, False, False, False]

    """
    def _intersects_both(
        point: Point,
        prep_traces_first: prepared.PreparedGeometry,
        prep_traces_second: prepared.PreparedGeometry,
        buffer_value: float,
    ):
        return prep_traces_first.intersects(
            point.buffer(buffer_value)) and prep_traces_second.intersects(
                point.buffer(buffer_value))

    assert len(set_names_two_sets) == 2
    trace_series_first_set = trace_series_two_sets[0]
    trace_series_second_set = trace_series_two_sets[1]

    prep_traces_first = prepare_geometry_traces(trace_series_first_set)
    prep_traces_second = prepare_geometry_traces(trace_series_second_set)
    intersects_both_sets = [
        _intersects_both(point,
                         prep_traces_first,
                         prep_traces_second,
                         buffer_value=buffer_value)
        for point in node_series_xy.geometry.values
    ]
    return intersects_both_sets
Esempio n. 2
0
def test_prepare_geometry_traces(trace_series: gpd.GeoSeries):
    """
    Test prepare_geometry_traces.
    """
    prepared_traces = prepare_geometry_traces(trace_series)
    assert isinstance(prepared_traces, PreparedGeometry)
    assert isinstance(prepared_traces.context, MultiLineString)
    assert all(
        [prepared_traces.intersects(trace) for trace in trace_series.geometry.values]
    )
Esempio n. 3
0
def determine_intersects(
    trace_series_two_sets: Tuple[gpd.GeoSeries, gpd.GeoSeries],
    set_names_two_sets: Tuple[str, str],
    node_series_xy_intersects: gpd.GeoSeries,
    node_types_xy_intersects: np.ndarray,
    buffer_value: float,
) -> pd.DataFrame:
    """
    Determine how abutments and crosscuts occur between two sets.

    E.g.

    >>> traces = gpd.GeoSeries([LineString([(0, 0), (1, 1)])]), gpd.GeoSeries(
    ...     [LineString([(0, 1), (0, -1)])]
    ... )
    >>> set_names_two_sets = ("1", "2")
    >>> node_series_xy_intersects = gpd.GeoSeries([Point(0, 0)])
    >>> node_types_xy_intersects = np.array(["Y"])
    >>> buffer_value = 0.001
    >>> determine_intersects(
    ...     traces,
    ...     set_names_two_sets,
    ...     node_series_xy_intersects,
    ...     node_types_xy_intersects,
    ...     buffer_value,
    ... )
              node nodeclass    sets  error
    0  POINT (0 0)         Y  (1, 2)  False

    """
    # TODO: No DataFrames -> Refactor to something else
    # TODO: Refactor intersect logic (but it works for now)
    intersectframe = pd.DataFrame(
        columns=["node", "nodeclass", "sets", "error"])
    if len(node_series_xy_intersects) == 0:
        # No intersections between sets
        logging.debug("No intersections between sets.")
        return intersectframe

    first_set, second_set = (
        set_names_two_sets[0],
        set_names_two_sets[1],
    )  # sets for comparison

    trace_series_first_set = trace_series_two_sets[0]
    trace_series_second_set = trace_series_two_sets[1]

    first_set_prep = prepare_geometry_traces(trace_series_first_set)
    second_set_prep = prepare_geometry_traces(trace_series_second_set)
    # Creates a rtree from all start- and endpoints of set 1
    # Used in deducting in which set a trace abuts (Y-node)
    first_set_points = list(
        chain(*list(
            trace_series_first_set.geometry.apply(
                get_trace_endpoints).values)))
    assert all(isinstance(p, Point) for p in first_set_points)
    first_setpointtree = STRtree(first_set_points)
    node: Point
    node_class: str
    for node, node_class in zip(node_series_xy_intersects,
                                node_types_xy_intersects):
        assert isinstance(node, Point)
        assert isinstance(node_class, str)
        # for idx, row in intersecting_nodes_frame.iterrows():
        # node = row.geometry
        # c = row.c

        l1 = first_set_prep.intersects(node.buffer(
            buffer_value))  # Checks if node intersects set 1 traces.
        l2 = second_set_prep.intersects(node.buffer(
            buffer_value))  # Checks if node intersects set 2 traces.

        if (l1 is False) and (l2 is False):  # DEBUGGING
            raise ValueError(
                f"Node {node} does not intersect both sets"
                f" {first_set} and {second_set}\n l1 is {l1} and l2 is {l2}")

        try:
            addition = determine_intersect(
                node=node,
                node_class=node_class,
                l1=l1,
                l2=l2,
                first_set=first_set,
                second_set=second_set,
                first_setpointtree=first_setpointtree,
                buffer_value=buffer_value,
            )
        except ValueError:
            # NO RELATIONS FOR NODE IS GIVEN AS ERROR == TRUE (ERROR).
            # addition gets overwritten if there are no errors
            addition = {
                "node": node,
                "nodeclass": node_class,
                "sets": set_names_two_sets,
                "error": True,
            }  # DEBUGGING

        intersectframe = intersectframe.append(
            addition, ignore_index=True)  # Append frame with result

    return intersectframe