Beispiel #1
0
def unpack_segments(segments: Sequence[Segment],
                    context: Context) -> Union[Empty, Multisegment, Segment]:
    return ((context.multisegment_cls(segments)
             if len(segments) > 1
             else segments[0])
            if segments
            else context.empty)
Beispiel #2
0
def _symmetric_subtract_segments_overlap(minuend: Segment,
                                         subtrahend: Segment,
                                         context: Context) -> Multisegment:
    left_start, left_end, right_start, right_end = sorted([
        minuend.start, minuend.end, subtrahend.start, subtrahend.end])
    return context.multisegment_cls([context.segment_cls(left_start, left_end),
                                     context.segment_cls(right_start,
                                                         right_end)])
Beispiel #3
0
def _unite_segments_cross(first: Segment,
                          second: Segment,
                          context: Context) -> Multisegment:
    cross_point = context.segments_intersection(first, second)
    segment_cls = context.segment_cls
    return context.multisegment_cls([segment_cls(first.start, cross_point),
                                     segment_cls(second.start, cross_point),
                                     segment_cls(cross_point, first.end),
                                     segment_cls(cross_point, second.end)])
Beispiel #4
0
def unite_segments(first: Segment,
                   second: Segment,
                   context: Context) -> Union_[Multisegment, Segment]:
    relation = context.segments_relation(first, second)
    if relation is Relation.DISJOINT:
        return context.multisegment_cls([first, second])
    elif relation is Relation.EQUAL or relation is Relation.COMPOSITE:
        return first
    elif relation is Relation.COMPONENT:
        return second
    else:
        return (_unite_segments_touch
                if relation is Relation.TOUCH
                else (_unite_segments_cross
                      if relation is Relation.CROSS
                      else _unite_segments_overlap))(first, second, context)
Beispiel #5
0
def _subtract_segments_composite(minuend: Segment,
                                 subtrahend: Segment,
                                 context: Context
                                 ) -> Union_[Multisegment, Segment]:
    left_start, left_end, right_start, right_end = sorted([
        minuend.start, minuend.end, subtrahend.start, subtrahend.end])
    return (context.segment_cls(right_start, right_end)
            if left_start == subtrahend.start or left_start == subtrahend.end
            else (((context.segment_cls(left_start, left_end)
                    if right_start == right_end
                    else
                    context.multisegment_cls([context.segment_cls(left_start,
                                                                  left_end),
                                              context.segment_cls(right_start,
                                                                  right_end)]))
                   if (right_start == subtrahend.start
                       or right_start == subtrahend.end)
                   else context.segment_cls(left_start, left_end))
                  if left_end == subtrahend.start or left_end == subtrahend.end
                  else context.segment_cls(left_start, right_start)))
Beispiel #6
0
def symmetric_subtract_segments(first: Segment,
                                second: Segment,
                                context: Context
                                ) -> Union_[Empty, Multisegment, Segment]:
    relation = context.segments_relation(first, second)
    if relation is Relation.DISJOINT:
        return context.multisegment_cls([first, second])
    elif relation is Relation.EQUAL:
        return context.empty
    else:
        return (_unite_segments_touch(first, second, context)
                if relation is Relation.TOUCH
                else
                (_unite_segments_cross(first, second, context)
                 if relation is Relation.CROSS
                 else
                 (_symmetric_subtract_segments_overlap(first, second, context)
                  if relation is Relation.OVERLAP
                  else (_subtract_segments_composite(first, second, context)
                        if relation is Relation.COMPOSITE
                        else _subtract_segments_composite(second, first,
                                                          context)))))
Beispiel #7
0
def _unite_segments_touch(first: Segment,
                          second: Segment,
                          context: Context) -> Union_[Multisegment, Segment]:
    return (context.multisegment_cls([first, second])
            if ((first.start != second.start
                 or (context.angle_orientation(first.start, first.end,
                                               second.end)
                     is not Orientation.COLLINEAR))
                and (first.start != second.end
                     or (context.angle_orientation(first.start, first.end,
                                                   second.start)
                         is not Orientation.COLLINEAR))
                and (first.end != second.start
                     or (context.angle_orientation(first.end, first.start,
                                                   second.end)
                         is not Orientation.COLLINEAR))
                and (first.end != second.end
                     or (context.angle_orientation(first.end, first.start,
                                                   second.start)
                         is not Orientation.COLLINEAR)))
            else context.segment_cls(min(first.start, first.end,
                                         second.start, second.end),
                                     max(first.start, first.end,
                                         second.start, second.end)))
Beispiel #8
0
def merge_segments(segments: Sequence[Segment], *,
                   context: Context) -> Multisegment:
    return context.multisegment_cls(_merge_segments(segments, context=context))
Beispiel #9
0
def relate_segment(multiregion: Multiregion, segment: Segment,
                   context: Context) -> Relation:
    return _relate_multisegment(multiregion,
                                context.multisegment_cls([segment]),
                                context.segment_box(segment), context)
Beispiel #10
0
def relate_segment(multipolygon: Multipolygon, segment: Segment,
                   context: Context) -> Relation:
    return relate_multisegment(multipolygon,
                               context.multisegment_cls([segment]), context)