Beispiel #1
0
    def __init__(self, graphics_item, slot, use_this_polyline=None):
        self.graphics_item = graphics_item
        self.graphics_item.setVisible(False)

        road_item = graphics_item.road_item
        graphics_scene = graphics_item.scene()

        self.balls = list()
        if use_this_polyline:
            polyline = use_this_polyline
        else:
            polyline = road_item.polyline
        for i, point in enumerate(polyline):
            ball = Ball(point.x, point.y, Observer(slot, i))
            ball.is_selectable = False
            graphics_scene.addItem(ball)
            self.balls.append(ball)

        self.chains = list()
        for i in range(len(self.balls) - 1):
            ball1 = self.balls[i]
            ball2 = self.balls[i + 1]
            chain = Chain(ball1, ball2)
            chain.is_selectable = False
            graphics_scene.addItem(chain)
            self.chains.append(chain)
Beispiel #2
0
 def set_ball_and_chain(self):
     if len(self.polyline) == 1:
         point = self.polyline[0]
         self.ball = Ball(point.x, point.y)
         self.ball.is_selectable = False
         #self.graphics_scene.addItem(self.ball)
         self.chain = Chain(self.ball, None)
         self.chain.is_selectable = False
         self.graphics_scene.addItem(self.chain)
         return
     self.set_fixed_end(self.polyline[-1])
Beispiel #3
0
 def set_ball_and_chain(self):
     if len(self.polyline) == 1:
         point = self.polyline[0]
         self.ball = Ball(point.x, point.y)
         #self.ball_is_selectable = False
         # Do not add the ball to the graphics_scene so that it is not shown to prevent the
         # user from moving it.
         self.chain = Chain(self.ball, None)
         self.chain.is_selectable = False
         self.main_window.scene.addItem(self.chain)
         return
     self.set_fixed_end(self.polyline[-1])
Beispiel #4
0
    def draw_lane_edge(self, lane_edge, tool_box):
        color = QtCore.Qt.blue
        group = tool_box.lane_edge_type(lane_edge.type)
        info = "lane-edge section=%d index=%d type=%s" \
               % (lane_edge.section_id, lane_edge.index, lane_edge.type)
        balls = list()
        for i, point in enumerate(lane_edge.polyline):
            ball = Ball(point.x, point.y, color)
            if i:
                ball.info = info
            else:
                ball.info = info + " polyline-first-point"
            ball.road_item = lane_edge
            ball.lane_edge = lane_edge
            ball.point_index = i
            ball.setZValue(1)
            ball.is_a_line = False
            ball.is_selectable = True
            self.addItem(ball)
            balls.append(ball)
            group.items.append(ball)

        ball0 = balls[0]
        for ball in balls:
            chain = Chain(ball0, ball, color)
            ball0 = ball
            chain.info = info
            chain.road_item = lane_edge
            chain.lane_edge = lane_edge
            chain.setZValue(1)
            chain.is_a_line = True
            chain.is_selectable = True
            self.addItem(chain)
            group.items.append(chain)
Beispiel #5
0
    def draw_balls_and_chains(self, lane_edge_or_center_line, info, group,
                              color):
        balls = list()
        for i, point in enumerate(lane_edge_or_center_line.polyline):
            ball = Ball(point.x, point.y, color)
            if i:
                ball.info = info
            else:
                ball.info = info + "polyline-first-point"
            ball.road_item = lane_edge_or_center_line
            ball.lane_edge = lane_edge_or_center_line
            ball.point_index = i
            ball.setZValue(1)
            ball.is_a_line = False
            ball.is_selectable = True
            self.addItem(ball)
            balls.append(ball)
            group.items.append(ball)

        ball0 = balls[0]
        for ball in balls:
            chain = Chain(ball0, ball, color)
            ball0 = ball
            chain.info = info
            chain.road_item = lane_edge_or_center_line
            chain.lane_edge = lane_edge_or_center_line
            chain.setZValue(1)
            chain.is_a_line = True
            chain.is_selectable = True
            self.addItem(chain)
            group.items.append(chain)
Beispiel #6
0
class Scraping(QtCore.QObject):
    # The user can add the entire lane-marking or individual points (usually of the kerb-line)
    # to the Scraping.
    def __init__(self, main_window):
        super(Scraping, self).__init__()
        self.main_window = main_window
        self.polyline = list()
        self.road_items = list()
        self.graphics_items = list()
        self.direction_is_confirmed = True
        self.chain = None

    def add(self, point_item, line_item, lane_edge_item, snap_to_line):
        if lane_edge_item:
            if self.extend_to_meet(lane_edge_item):
                return True
        elif line_item:
            if self.extend_to_meet(line_item):
                return True

        if snap_to_line:
            if line_item:
                self.add_line_item(line_item)
            return True
        else:
            if point_item:
                self.add_point_item(point_item)
            return True

        return False

    def add_point_item(self, graphics_item):
        self.add_road_item(graphics_item)

        pos = graphics_item.pos()
        self.add_point(Point(pos.x(), pos.y()))

    def add_line_item(self, graphics_item):
        self.add_road_item(graphics_item)

        polyline = graphics_item.road_item.polyline
        if len(self.polyline) == 0:
            for point in polyline:
                self.add_point(point)
            self.direction_is_confirmed = False
            return

        if not self.direction_is_confirmed:
            self.set_both_directions(polyline)
        else:
            set_direction(polyline, self.polyline[-1])
        for point in polyline:
            self.add_point(point)

    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

    def adjust(self, x, y):
        if self.chain:
            self.chain.adjust_free_end(x, y)

    def finish(self):
        self.main_window.scene.removeItem(self.chain)
        for graphics_item in self.road_items:
            graphics_item.is_selectable = True
        for graphics_item in self.graphics_items:
            self.main_window.scene.removeItem(graphics_item)

        if len(self.polyline) < 2:
            return

        polyline = simplify_polyline(self.polyline)
        self.lane_edge = self.main_window.road_network.add_lane_edge(
            "e", polyline)
        self.main_window.scene.draw_lane_edge(self.lane_edge)

        self.lane_edge.visual_item.setPen(QtCore.Qt.red)
        self.edit_form = Edit_form(self.lane_edge, self.main_window)
        self.connect(self.edit_form, QtCore.SIGNAL("finish_editing"),
                     self.finish_editing)
        self.edit_form.setVisible(True)

    def finish_editing(self):
        #if self.edit_form.result() == QtGui.QDialog.DialogCode.Accepted:
        if self.edit_form.result() == QtGui.QDialog.Accepted:
            self.lane_edge.visual_item.setPen(QtCore.Qt.blue)
            self.main_window.wanderlust.load_lane_edge(self.lane_edge)
        else:
            self.main_window.scene.removeItem(self.lane_edge.visual_item)
            self.main_window.road_network.expunge(self.lane_edge)
        self.emit(QtCore.SIGNAL("finish_scraping"))
        self.edit_form = None

    def add_road_item(self, graphics_item):
        self.road_items.append(graphics_item)
        graphics_item.is_selectable = False

    def add_point(self, point):
        if not self.direction_is_confirmed:
            self.determine_direction(point)

        if len(self.polyline):
            self.draw_line(self.polyline[-1], point)
        self.polyline.append(point)

        self.set_ball_and_chain()

    def determine_direction(self, point):
        if set_direction(self.polyline, point):
            pass
        self.direction_is_confirmed = True

    def set_both_directions(self, polyline):
        if set_direction(self.polyline, polyline[0], False):
            pass
        set_direction(polyline, self.polyline[-1])
        self.direction_is_confirmed = True

    def draw_line(self, p1, p2):
        path = QtGui.QPainterPath(QtCore.QPointF(p1.x, p1.y))
        path.lineTo(p2.x, p2.y)
        graphics_item = QtGui.QGraphicsPathItem(path)
        graphics_item.setPen(QtCore.Qt.red)
        graphics_item.is_selectable = False
        self.graphics_items.append(graphics_item)
        self.main_window.scene.addItem(graphics_item)

    def set_ball_and_chain(self):
        if len(self.polyline) == 1:
            point = self.polyline[0]
            self.ball = Ball(point.x, point.y)
            #self.ball_is_selectable = False
            # Do not add the ball to the graphics_scene so that it is not shown to prevent the
            # user from moving it.
            self.chain = Chain(self.ball, None)
            self.chain.is_selectable = False
            self.main_window.scene.addItem(self.chain)
            return
        self.set_fixed_end(self.polyline[-1])

    def set_fixed_end(self, point):
        self.ball.setPos(point.x, point.y)
Beispiel #7
0
class Scrapings:
    def __init__(self, graphics_scene):
        self.graphics_scene = graphics_scene
        self.polyline = list()
        self.point_items = list()
        self.line_items = list()
        self.direction_is_confirmed = True
        self.ball = None
        self.chain = None

    def add_point(self, point):
        if not self.direction_is_confirmed:
            self.determine_direction(point)

        self.polyline.append(point)
        info = "scrapings"
        graphics_item = self.graphics_scene.draw_point(point,
                                                       color=QtCore.Qt.red,
                                                       info=info)
        graphics_item.is_selectable = False
        self.point_items.append(graphics_item)

        self.add_line()
        self.set_ball_and_chain()

    def add_polyline(self, polyline):
        if len(self.polyline) == 0:
            for point in polyline:
                self.add_point(point)
            self.direction_is_confirmed = False
            return

        if not self.direction_is_confirmed:
            self.set_both_directions(polyline)
        else:
            set_direction(polyline, self.polyline[-1])
        for point in polyline:
            self.add_point(point)

    def add_line(self):
        if len(self.polyline) == 1:
            return

        info = "scrapings"
        graphics_item = self.graphics_scene.draw_line(self.polyline[-2:],
                                                      color=QtCore.Qt.red,
                                                      info=info)
        graphics_item.is_selectable = False
        self.line_items.append(graphics_item)

    def determine_direction(self, point):
        if set_direction(self.polyline, point):
            self.point_items.reverse()
        self.direction_is_confirmed = True

    def set_both_directions(self, polyline):
        if set_direction(self.polyline, polyline[0], False):
            self.point_items.reverse()
        set_direction(polyline, self.polyline[-1])
        self.direction_is_confirmed = True

    def set_ball_and_chain(self):
        if len(self.polyline) == 1:
            point = self.polyline[0]
            self.ball = Ball(point.x, point.y)
            self.ball.is_selectable = False
            #self.graphics_scene.addItem(self.ball)
            self.chain = Chain(self.ball, None)
            self.chain.is_selectable = False
            self.graphics_scene.addItem(self.chain)
            return
        self.set_fixed_end(self.polyline[-1])

    def set_fixed_end(self, point):
        self.ball.setPos(point.x, point.y)

    def adjust(self, x, y):
        self.chain.adjust_free_end(x, y)

    def finish(self):
        #self.graphics_scene.removeItem(self.ball)
        self.graphics_scene.removeItem(self.chain)

        edge = Lane_edge(self.polyline, 'e')
        lane_edge_dialog = dialog.Dialogs.lane_edge_dialog
        lane_edge_dialog.set_lane_edge(edge)
        result = None
        if lane_edge_dialog.exec_():
            lane_edge_dialog.update(edge)
            result = edge

        for item in self.point_items:
            self.graphics_scene.removeItem(item)
        for item in self.line_items:
            self.graphics_scene.removeItem(item)

        return result
Beispiel #8
0
    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Plus:
            self.scale(1.1, 1.1)
        # too lazy to press the <Shift> to get '+'.  So let Key_Equal do the same thing.
        elif event.key() == QtCore.Qt.Key_Equal:
            self.scale(1.1, 1.1)
        elif event.key() == QtCore.Qt.Key_Minus:
            self.scale(0.91, 0.91)
        # Make it difficult to rotate the view by assigning capital 'C', 'A", and 'O' (letter O)
        elif event.key() == QtCore.Qt.Key_C and event.modifiers() == QtCore.Qt.ShiftModifier:
            # Rotate the view clockwise by 1 degree
            self.rotate(-1)
            self.orientation -= 1
        elif event.key() == QtCore.Qt.Key_A and event.modifiers() == QtCore.Qt.ShiftModifier:
            # Rotate the view anti-clockwise by 1 degree
            self.rotate(1)
            self.orientation += 1
        elif event.key() == QtCore.Qt.Key_O and event.modifiers() == QtCore.Qt.ShiftModifier:
            # Revert back to the original orientation
            self.rotate(-self.orientation)
            self.orientation = 0
        elif event.key() == QtCore.Qt.Key_E:
            # Edit the data of the selected lane edges or center lines, such as their
            # section-id and types.
            while len(self.selected_lane_edges):
                selected_lane_edge = self.selected_lane_edges.pop()
                lane_edge = selected_lane_edge.lane_edge
                if isinstance(lane_edge, edge.Lane_edge):
                    lane_edge_dialog = Dialogs.lane_edge_dialog
                    lane_edge_dialog.set_lane_edge(lane_edge)
                    if lane_edge_dialog.exec_():
                        lane_edge_dialog.update(lane_edge)
                        info = "lane-edge section=%d index=%d type=%s" \
                               % (lane_edge.section_id, lane_edge.index, lane_edge.type)
                        for item in selected_lane_edge.graphics_items:
                            item.info = info
                    selected_lane_edge.clear(lane_edge)
                elif isinstance(lane_edge, edge.Center_line):
                    center_line_dialog = Dialogs.center_line_dialog
                    center_line_dialog.set_center_line(lane_edge)
                    if center_line_dialog.exec_():
                        center_line_dialog.update(lane_edge)
                        info = "center-line section=%d index=%d type=%s" \
                               % (lane_edge.section_id, lane_edge.index, lane_edge.type)
                        for item in selected_lane_edge.graphics_items:
                            item.info = info
                    selected_lane_edge.clear(lane_edge)
        elif event.key() == QtCore.Qt.Key_D:
            # Delete the selected lane edges or center lines from the graphics view as well as
            # the road network.
            while len(self.selected_lane_edges):
                selected_lane_edge = self.selected_lane_edges.pop()
                for item in selected_lane_edge.graphics_items:
                    self.scene().removeItem(item)
                lane_edge = selected_lane_edge.lane_edge
                if isinstance(lane_edge, edge.Lane_edge):
                    self.road_network.lane_edges.remove(lane_edge)
                elif isinstance(lane_edge, edge.Center_line):
                    self.road_network.lane_center_lines.remove(lane_edge)
        elif event.key() == QtCore.Qt.Key_G:
            # Generate the lane's center line from the lane's 2 edges.
            if len(self.selected_lane_edges) == 2:
                selected_lane_edge = self.selected_lane_edges.pop()
                edge1 = selected_lane_edge.lane_edge
                selected_lane_edge.clear(selected_lane_edge.lane_edge)
                selected_lane_edge = self.selected_lane_edges.pop()
                edge2 = selected_lane_edge.lane_edge
                selected_lane_edge.clear(selected_lane_edge.lane_edge)
                polyline = generate_center_line(edge1, edge2);
                items = list()
                self.scene().draw_polyline(polyline, None, "center-line", items, QtCore.Qt.red)

                center_line_dialog = Dialogs.center_line_dialog
                center_line = edge.Center_line(polyline)
                center_line_dialog.set_center_line(center_line)
                if center_line_dialog.exec_():
                    center_line_dialog.update(center_line)
                    self.road_network.add_center_line(center_line)
                    self.scene().draw_center_line(center_line, self.tool_box)
                for item in items:
                    self.scene().removeItem(item)
        elif event.key() == QtCore.Qt.Key_H:
            Ball.toggle_ball_visibility()
        elif event.key() == QtCore.Qt.Key_S:
            print "saving road network"
            self.road_network.save()
        elif event.key() == QtCore.Qt.Key_N:
            self.scene().toggle_node_visibility()
        elif event.key() == QtCore.Qt.Key_B:
            # Use the selected lane edge as a cut-line to bisect all lane edges and center lines
            # in its path.
            if len(self.selected_lane_edges) != 1:
                print "select one line as the cutting line to bisect lane edges and center lines"
                return
            selected_lane_edge = self.selected_lane_edges.pop()
            bisect(selected_lane_edge.lane_edge, self.road_network, self)
            selected_lane_edge.clear(selected_lane_edge.lane_edge)
        elif event.key() == QtCore.Qt.Key_X:
            # Output the edited road network to an XML file.
            output_xml_dialog = Dialogs.output_xml_dialog
            if output_xml_dialog.exec_():
                network_name = str(output_xml_dialog.network_name_line_edit.text())
                output_file_name = str(output_xml_dialog.output_file_name_line_edit.text())
                output(self.road_network, network_name, output_file_name)