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)
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_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 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)
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)
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)
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
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)