Example #1
0
def relate_polygon(multipolygon: Multipolygon, polygon: Polygon,
                   context: Context) -> Relation:
    polygon_bounding_box = context.polygon_box(polygon)
    all_disjoint, none_disjoint, multipolygon_max_x, events_queue = (True,
                                                                     True,
                                                                     None,
                                                                     None)
    for sub_polygon in multipolygon.polygons:
        sub_polygon_bounding_box = context.polygon_box(sub_polygon)
        if box.disjoint_with(sub_polygon_bounding_box, polygon_bounding_box):
            if none_disjoint:
                none_disjoint = False
        else:
            if all_disjoint:
                all_disjoint = False
                multipolygon_max_x = sub_polygon_bounding_box.max_x
                events_queue = CompoundEventsQueue(context)
                events_queue.register(polygon_to_oriented_segments(
                    polygon, context),
                                      from_test=True)
            else:
                multipolygon_max_x = max(multipolygon_max_x,
                                         sub_polygon_bounding_box.max_x)
            events_queue.register(polygon_to_oriented_segments(
                sub_polygon, context),
                                  from_test=False)
    if all_disjoint:
        return Relation.DISJOINT
    relation = process_compound_queue(
        events_queue, min(multipolygon_max_x, polygon_bounding_box.max_x))
    return (relation if none_disjoint else (
        Relation.COMPONENT if relation is Relation.EQUAL else
        (Relation.OVERLAP if relation in (Relation.COVER, Relation.ENCLOSES,
                                          Relation.COMPOSITE) else relation)))
Example #2
0
def relate_multisegment(polygon: Polygon, multisegment: Multisegment,
                        context: Context) -> Relation:
    polygon_bounding_box = context.polygon_box(polygon)
    multisegment_bounding_box = context.segments_box(multisegment.segments)
    if box.disjoint_with(polygon_bounding_box, multisegment_bounding_box):
        return Relation.DISJOINT
    events_queue = CompoundEventsQueue(context)
    events_queue.register(to_oriented_edges_endpoints(polygon, context),
                          from_test=False)
    events_queue.register(to_segments_endpoints(multisegment), from_test=True)
    return process_linear_compound_queue(
        events_queue,
        min(multisegment_bounding_box.max_x, polygon_bounding_box.max_x))
Example #3
0
def relate_contour(multipolygon: Multipolygon, contour: Contour,
                   context: Context) -> Relation:
    contour_bounding_box = context.contour_box(contour)
    disjoint, multipolygon_max_x, events_queue = True, None, None
    for polygon in multipolygon.polygons:
        polygon_bounding_box = context.polygon_box(polygon)
        if not box.disjoint_with(polygon_bounding_box, contour_bounding_box):
            if disjoint:
                disjoint = False
                multipolygon_max_x = polygon_bounding_box.max_x
                events_queue = CompoundEventsQueue(context)
                events_queue.register(contour_to_edges_endpoints(contour),
                                      from_test=True)
            else:
                multipolygon_max_x = max(multipolygon_max_x,
                                         polygon_bounding_box.max_x)
            events_queue.register(polygon_to_oriented_segments(
                polygon, context),
                                  from_test=False)
    return (Relation.DISJOINT if disjoint else process_linear_compound_queue(
        events_queue, min(contour_bounding_box.max_x, multipolygon_max_x)))
Example #4
0
def relate_polygon(goal: Polygon, test: Polygon, context: Context) -> Relation:
    goal_bounding_box, test_bounding_box = (context.polygon_box(goal),
                                            context.polygon_box(test))
    goal_border, goal_holes = goal.border, goal.holes
    test_border, test_holes = test.border, test.holes
    borders_relation = relate_regions(goal_border, test_border,
                                      goal_bounding_box, test_bounding_box,
                                      context)
    if borders_relation in (Relation.DISJOINT, Relation.TOUCH,
                            Relation.OVERLAP):
        return borders_relation
    elif borders_relation is Relation.EQUAL:
        if goal_holes and test_holes:
            holes_relation = relate_multiregions(test_holes, goal_holes,
                                                 context)
            if holes_relation in (Relation.DISJOINT, Relation.TOUCH,
                                  Relation.OVERLAP):
                return Relation.OVERLAP
            elif holes_relation in (Relation.COVER, Relation.ENCLOSES,
                                    Relation.COMPOSITE):
                return Relation.ENCLOSES
            elif holes_relation is Relation.EQUAL:
                return borders_relation
            else:
                return Relation.ENCLOSED
        else:
            return (Relation.ENCLOSES if goal_holes else
                    (Relation.ENCLOSED if test_holes else Relation.EQUAL))
    elif borders_relation in (Relation.WITHIN, Relation.ENCLOSED,
                              Relation.COMPONENT):
        if goal_holes:
            none_touch = True
            subsets_holes_indices = []
            for hole_index, hole in enumerate(goal_holes):
                hole_relation = relate_regions(test_border, hole,
                                               test_bounding_box,
                                               context.contour_box(hole),
                                               context)
                if hole_relation is Relation.TOUCH:
                    if none_touch:
                        none_touch = False
                elif hole_relation is Relation.OVERLAP:
                    return hole_relation
                elif hole_relation is Relation.COVER:
                    return Relation.DISJOINT
                elif hole_relation in (Relation.ENCLOSES, Relation.COMPOSITE,
                                       Relation.EQUAL):
                    return Relation.TOUCH
                elif hole_relation is not Relation.DISJOINT:
                    subsets_holes_indices.append(hole_index)
            if subsets_holes_indices:
                holes_relation = (relate_multiregions(
                    test_holes, goal_holes
                    if len(subsets_holes_indices) == len(goal_holes) else
                    [goal_holes[index] for index in subsets_holes_indices],
                    context) if test_holes else Relation.DISJOINT)
                if holes_relation is Relation.EQUAL:
                    return (Relation.ENCLOSED
                            if borders_relation is Relation.WITHIN else
                            borders_relation)
                elif (holes_relation is Relation.COMPONENT
                      or holes_relation is Relation.ENCLOSED):
                    return Relation.ENCLOSED
                elif holes_relation is Relation.WITHIN:
                    return borders_relation
                else:
                    return Relation.OVERLAP
            else:
                return (borders_relation if none_touch else Relation.ENCLOSED)
        else:
            return (Relation.ENCLOSED
                    if test_holes and borders_relation is Relation.COMPONENT
                    else borders_relation)
    elif test_holes:
        none_touch = True
        subsets_holes_indices = []
        for hole_index, hole in enumerate(test_holes):
            hole_relation = relate_regions(goal_border, hole,
                                           goal_bounding_box,
                                           context.contour_box(hole), context)
            if hole_relation is Relation.TOUCH:
                if none_touch:
                    none_touch = False
            elif hole_relation is Relation.OVERLAP:
                return hole_relation
            elif hole_relation is Relation.COVER:
                return Relation.DISJOINT
            elif hole_relation in (Relation.ENCLOSES, Relation.COMPOSITE,
                                   Relation.EQUAL):
                return Relation.TOUCH
            elif hole_relation is not Relation.DISJOINT:
                subsets_holes_indices.append(hole_index)
        if subsets_holes_indices:
            holes_relation = (relate_multiregions(
                goal_holes,
                test_holes if len(subsets_holes_indices) == len(test_holes)
                else [test_holes[index]
                      for index in subsets_holes_indices], context)
                              if goal_holes else Relation.DISJOINT)
            if holes_relation is Relation.EQUAL:
                return (Relation.ENCLOSES if borders_relation is Relation.COVER
                        else borders_relation)
            elif (holes_relation is Relation.COMPONENT
                  or holes_relation is Relation.ENCLOSED):
                return Relation.ENCLOSES
            elif holes_relation is Relation.WITHIN:
                return borders_relation
            else:
                return Relation.OVERLAP
        else:
            return (borders_relation if none_touch else Relation.ENCLOSES)
    else:
        return (Relation.ENCLOSES
                if goal_holes and borders_relation is Relation.COMPOSITE else
                borders_relation)