Exemplo n.º 1
0
    def calc_stop_line(self, ref_point, crossing, kerb_lines):
        stop_line = list()

        vec = crossing.polyline[-1] - crossing.polyline[0]
        p3 = ref_point
        p4 = p3 + vec

        for kerb_line in kerb_lines:
            for i in range(len(kerb_line.polyline) - 1):
                p1 = kerb_line.polyline[i]
                p2 = kerb_line.polyline[i + 1]
                p = intersection_point(p1, p2, p3, p4)
                if is_between(p, p1, p2):
                    stop_line.append(p)
                    break

        if len(stop_line) < 2:
            raise RuntimeError("stop-line has only %d point" % len(stop_len))
        if len(stop_line) == 2:
            return stop_line

        stop_line.sort(key=lambda point: point.x)
        if is_between(ref_point, stop_line[0], stop_line[1]):
            return (stop_line[0], stop_line[1])
        return (stop_line[1], stop_line[2])
Exemplo n.º 2
0
    def extend_to_meet(self, position):
        road_item = None
        w = 2
        h = 2
        for graphics_item in self.scene().items(position.x() - w / 2.0,
                                                position.y() - h / 2.0, w, h):
            if graphics_item == self:
                continue
            if not graphics_item.is_selectable:
                continue
            road_item = graphics_item.road_item
            if hasattr(road_item, "polyline"):
                break

        if not road_item:
            return self.restricted_to_straight_line(position)

        line = self.chains[0].line()
        p1 = Point(line.x1(), line.y1())
        p2 = Point(line.x2(), line.y2())
        polyline = road_item.polyline
        for i in range(len(polyline) - 1):
            p3 = polyline[i]
            p4 = polyline[i + 1]
            p = intersection_point(p1, p2, p3, p4)
            if is_between(p, p3, p4):
                return QtCore.QPointF(p.x, p.y)

        return self.restricted_to_straight_line(position)
Exemplo n.º 3
0
    def get_reference_point(self, lane_marking, crossing):
        polyline = self.get_polyline(lane_marking, crossing)

        p1 = polyline[-1]
        p2 = polyline[-2]
        p3 = crossing.polyline[0]
        p4 = crossing.polyline[-1]
        p = intersection_point(p1, p2, p3, p4)

        vec = p2 - p
        p = p + (2.5 / abs(vec)) * vec
        return p
Exemplo n.º 4
0
    def extend_to_meet(self, graphics_item):
        if len(self.polyline) < 2:
            return False

        polyline = graphics_item.road_item.polyline
        p = polyline[0]
        if polyline[0].distance(self.polyline[0]) < polyline[0].distance(
                self.polyline[-1]):
            p3 = self.polyline[0]
            p4 = self.polyline[1]
            for i in range(len(polyline) - 1):
                p1 = polyline[i]
                p2 = polyline[i + 1]
                p = intersection_point(p1, p2, p3, p4)
                if is_between(p, p1, p2):
                    angle = angle_between_2_lines(p1, p, p4)
                    if angle > 30 and angle < 150:
                        if p3.distance(p) < 3:
                            self.draw_line(self.polyline[0], p)
                            self.polyline[0] = p
                            return True
        else:
            p3 = self.polyline[-1]
            p4 = self.polyline[-2]
            for i in range(len(polyline) - 1):
                p1 = polyline[i]
                p2 = polyline[i + 1]
                p = intersection_point(p1, p2, p3, p4)
                if is_between(p, p1, p2):
                    angle = angle_between_2_lines(p1, p, p4)
                    if angle > 30 and angle < 150:
                        if p3.distance(p) < 3:
                            self.draw_line(self.polyline[-1], p)
                            self.polyline[-1] = p
                            return True
        return False
Exemplo n.º 5
0
    def order_lane_edges(self, lane_edges, stop_line):
        p1 = stop_line.polyline[0]
        p2 = stop_line.polyline[-1]
        for lane_edge in lane_edges:
            if p1.distance(lane_edge.polyline[0]) < p1.distance(
                    lane_edge.polyline[-1]):
                # The lane-edge's first point is closer to the closer to the stop-line than its
                # last point.  Reverse its polyline so that it points towards the stop-line.
                lane_edge.polyline.reverse()
            lane_edge.stop_line = stop_line

            p3 = lane_edge.polyline[-1]
            p4 = lane_edge.polyline[-2]
            # Extends the lane-edge so that it touches the stop-line.
            lane_edge.polyline[-1] = intersection_point(p1, p2, p3, p4)
        # Re-arrange the order of the lane-edges, although at this point we do not know if the
        # ordering is from left to right or vice versa.
        stop_line.lane_edges.sort(
            key=lambda lane_edge: lane_edge.polyline[-1].x)

        # Make sure that the order of the lane-edges is from right to left when looking at the
        # stop-line while standing before the lane-edges' last points.  Also make sure that the
        # stop-line's polyline moves from right to left.
        if p1.distance(lane_edges[0].polyline[-1]) < p1.distance(
                lane_edges[-1].polyline[-1]):
            # The stop-line's first point is closer to lane_edges[0] than to the last lane_edge.
            p2 = stop_line.polyline[1]
            vec1 = p2 - p1
            p4 = lane_edges[0].polyline[-1]
            p3 = lane_edges[0].polyline[-2]
            vec2 = p4 - p3
            if cross_product(vec1, vec2) > 0:
                lane_edges.reverse()
                stop_line.polyline.reverse()
        else:
            p2 = stop_line.polyline[1]
            vec1 = p2 - p1
            p4 = lane_edges[-1].polyline[-1]
            p3 = lane_edges[-1].polyline[-2]
            vec2 = p4 - p3
            if cross_product(vec1, vec2) < 0:
                lane_edges.reverse()
            else:
                stop_line.polyline.reverse()
        # Extends the stop-line so that the stop-line touches the first and last lane-edges.
        stop_line.polyline[0] = lane_edges[0].polyline[-1]
        stop_line.polyline[-1] = lane_edges[-1].polyline[-1]
Exemplo n.º 6
0
    def create_missing_stop_line(self, path):
        crossings, lane_markings, kerb_lines = self.items_in_selection_region(
            path)
        if len(kerb_lines) < 2:
            show_error_message(
                "The selection region must include at least 2 kerb-lines.")
            return

        important_marking_types = ("B", "C", "A", "L", "S", "S1", "A1")
        for lane_marking in lane_markings:
            if lane_marking.marking_type in important_marking_types:
                break
        else:
            msg = "The selection region must contain at least one lane-marking of the types: "
            msg = msg + "'%s'" % important_marking_types[0]
            for type in important_marking_types[1:]:
                msg = msg + ", '%s'" % type
            show_error_message(msg)
            return

        crossing = crossings[0]
        ref_point = self.get_reference_point(lane_marking, crossing)
        stop_line = self.calc_stop_line(ref_point, crossing, kerb_lines)

        for lane_marking in lane_markings:
            polyline = self.get_polyline(lane_marking, crossing)
            p1 = polyline[-1]
            p2 = polyline[-2]
            p = intersection_point(p1, p2, stop_line[0], stop_line[-1])
            if is_between(p, stop_line[0], stop_line[-1]) and is_between(
                    p, p1, p2):
                polyline[-1] = p
                self.adjust_lane_marking(lane_marking, polyline)

        lane_marking = self.main_window.digital_map.add_lane_marking(
            "M", "discard", stop_line)
        self.main_window.scene.draw_lane_marking(lane_marking)
        self.load_lane_marking(lane_marking)
Exemplo n.º 7
0
    def get_crossing_at_start_of_lane_edges(self, lane_edges, crossings):
        distances = list()
        for i, crossing in enumerate(crossings):
            d = 0.0
            n = 0
            p = crossing.polyline[0]
            for lane_edge in lane_edges:
                d = d + p.distance(lane_edge.polyline[0])
                n = n + 1
            p = crossing.polyline[-1]
            for lane_edge in lane_edges:
                d = d + p.distance(lane_edge.polyline[0])
                n = n + 1
            distances.append(d / n)

        the_crossing = None
        big_number = 999999
        for i, d in enumerate(distances):
            if big_number > d:
                big_number = d
                the_crossing = crossings[i]

        p1 = the_crossing.polyline[0]
        p2 = the_crossing.polyline[-1]
        for lane_edge in lane_edges:
            discard, distance = nearest_point(p1, lane_edge.polyline[0], p2)
            if distance < 3.0:
                lane_edge.crossing = the_crossing
                p3 = lane_edge.polyline[0]
                p4 = lane_edge.polyline[1]
                lane_edge.polyline[0] = intersection_point(p1, p2, p3, p4)

        if p2.distance(lane_edges[0].polyline[0]) < p2.distance(
                lane_edges[-1].polyline[0]):
            the_crossing.polyline.reverse()
        the_crossing.polyline[-1] = lane_edges[-1].polyline[0]
        the_crossing.lane_edges = lane_edges
Exemplo n.º 8
0
    def extend_stop_lines_to_kerb(self, stop_lines):
        for stop_line in stop_lines:
            kerb_lines = list()
            p1 = stop_line.polyline[0]
            p2 = stop_line.polyline[-1]
            # There should be only 2 kerb-lines, but if there is a road-divider, which is usually
            # only one meter wide, then the following search may be too wide and return the other
            # side of the road-divider, thus adding a third kerb-line.
            for road_item in self.tracing_paper.road_items_around_line(
                    p1, p2, 2, 0.1):
                if isinstance(road_item, Kerb_line):
                    kerb_lines.append(road_item)

            if len(kerb_lines) < 2:
                continue
            if len(kerb_lines) > 3:
                print "found a stop-line (%s, %s) that cuts more than 3 kerb-lines" % (
                    p1, p2)
                continue

            stop_line_polyline = list()
            for p in stop_line.polyline:
                stop_line_polyline.append(p)

            polyline = list()
            for kerb_line in kerb_lines:
                for i in range(len(kerb_line.polyline) - 1):
                    p3 = kerb_line.polyline[i]
                    p4 = kerb_line.polyline[i + 1]
                    p = intersection_point(p3, p4, p1, p2)
                    if is_between(p, p3, p4):
                        # A long kerb-line may be folded like the letter 'U'.  Just like a
                        # horizontal line may intersect 'U' at 2 places, the stop-line may also
                        # intersect the kerb-line at 2 places.  We ignore the intersection that
                        # is too far away from the stop-line.
                        if p.distance(p1) < 2 or p.distance(p2) < 2:
                            polyline.append(p)
                            # The 'U'-shaped kerb-line may represent the road-divider, which is
                            # usually one meter wide, enough room for someone to stand on.  It is
                            # possible that the latter part of the kerb-line is nearer to the
                            # stop-line (we don't know which side of the 'U'-shaped kerb-line is
                            # the stop-line.  Therefore, we cannot break out of the for-loop; we
                            # have to check the other "stem" of the 'U'.

            re_arrange_co_linear_points(polyline)
            if polyline[0].distance(p1) > polyline[0].distance(p2):
                # The first point is closer to the last point of the stop-line.  We reverse the
                # polyline so that it is in the same direction as the stop-line's polyline.
                polyline.reverse()
            if len(polyline) < 2:
                continue
            if len(polyline) == 2:
                stop_line_polyline[0] = polyline[0]
                stop_line_polyline[-1] = polyline[-1]
            elif len(polyline) == 3:
                if polyline[1].distance(p1) < polyline[1].distance(p2):
                    # The middle point is closer to the stop-line's first point.
                    stop_line_polyline[0] = polyline[1]
                    stop_line_polyline[-1] = polyline[2]
                else:
                    stop_line_polyline[0] = polyline[0]
                    stop_line_polyline[-1] = polyline[1]
            else:
                print "found a stop-line (%s, %s) that cuts at more than 3 places" % (
                    p1, p2)
                continue
            stop_line.polyline = stop_line_polyline

            point = stop_line_polyline[0]
            path = QtGui.QPainterPath(QtCore.QPointF(point.x, point.y))
            for point in stop_line_polyline:
                path.lineTo(point.x, point.y)
            stop_line.visual_item.setPath(path)