示例#1
0
    def intersectsLine(self, line, path_rect):
        scene_translation = self.startSocket().sceneTransform()
        connection_rect = scene_translation.mapRect(self._rect)

        if connection_rect.contains(path_rect) or path_rect.contains(connection_rect) \
                or path_rect.intersects(connection_rect):

            connection_path = scene_translation.map(self._path)
            simplified_path = connection_path.simplified()

            element_count = simplified_path.elementCount() - 1

            # In case path is linear
            if element_count == -1:
                simplified_path = connection_path
                element_count = simplified_path.elementCount()

            previous_point = None
            for i in range(element_count):
                element = simplified_path.elementAt(i)

                point = QPointF(element.x, element.y)
                if previous_point is not None:
                    segment = QLineF(previous_point, point)

                    intersect_point = QPointF()
                    intersect_type = segment.intersect(line, intersect_point)

                    if intersect_type == QLineF.BoundedIntersection:
                        return True

                previous_point = point
示例#2
0
    def pxToDeg(self, x, y):
        """Transforms pixel coordinates of point to Geographic coordinate system.
		Args:
			x, y -- X and Y coordinates of point to process.
		Returns:
			QPointF(long, lat) -- longitude and latitude coordinates of given point
		"""
        # Please check comments in __stepThree() where we converting step in degrees to pixels in order to understand what we're doing here.
        # Convert given coordinates to degrees relative to the sides.
        topX = self.xTL + self.topX * x
        bottomX = self.xBL + self.bottomX * x
        # We subtract because Y and lat are not codirectional by default
        leftY = self.yTL - self.leftY * y
        rightY = self.yTR - self.rightY * y

        # Find another coordinate for each side by drawing straight line with calculated coordinate for both points.
        # Intersection of this line and side will give needed point.
        # Looks like this:
        # Y
        # ^
        # | \ <- This is side
        # |  \
        # |---*-----  <- This line is crossing point relative to the side
        # |    \
        # |     \
        # |------------------> X
        # Containers for points and result.
        top, bottom, left, right, res = QPointF(), QPointF(), QPointF(
        ), QPointF(), QPointF()

        QLineF.intersect(QLineF(topX, 0, topX, 1), self.top, top)
        QLineF.intersect(QLineF(bottomX, 0, bottomX, 1), self.bottom, bottom)
        QLineF.intersect(QLineF(0, leftY, 1, leftY), self.left, left)
        QLineF.intersect(QLineF(0, rightY, 1, rightY), self.right, right)

        # We've got coordinates for each side where given point should lie.
        # Let's draw lines throgh them like this:
        #  ________________________
        # |    \                   |
        # |_____\__________________|
        # |      \                 |
        # |_______\________________|
        # Lines are drawn in geographic system, not in pixels.
        # Their intersection will return given point in geographic system.
        QLineF.intersect(QLineF(top, bottom), QLineF(left, right), res)
        return res
示例#3
0
    def paint(self, painter, option, widget=None):
        if self.start_item.collidesWithItem(self.end_item):
            return

        start_item = self.start_item
        end_item = self.end_item
        color = self.color
        pen = self.pen()
        pen.setColor(color)
        arrow_size = 10.0
        painter.setPen(pen)
        painter.setBrush(color)

        center_line = QLineF(start_item.pos(), end_item.pos())
        end_polygon = end_item.polygon
        p1 = end_polygon.first() + end_item.pos()

        intersect_point = QPointF()
        for i in end_polygon:
            p2 = i + end_item.pos()
            poly_line = QLineF(p1, p2)
            intersect_type = poly_line.intersect(center_line, intersect_point)
            if intersect_type == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersect_point, start_item.pos()))
        line = self.line()

        angle = math.acos(line.dx() / max(1, line.length()))
        if line.dy() >= 0:
            angle = (math.pi * 2.0) - angle

        arrow_p1 = (line.p1() + QPointF(
            math.sin(angle + math.pi / 3.0) * arrow_size,
            math.cos(angle + math.pi / 3.0) * arrow_size,
        ))

        arrow_p2 = (line.p1() + QPointF(
            math.sin(angle + math.pi - math.pi / 3.0) * arrow_size,
            math.cos(angle + math.pi - math.pi / 3.0) * arrow_size,
        ))

        self.arrow_head.clear()
        for point in [line.p1(), arrow_p1, arrow_p2]:
            self.arrow_head.append(point)

        painter.drawLine(line)
        painter.drawPolygon(self.arrow_head)

        if self.isSelected():
            painter.setPen(QPen(color, 1, Qt.DashLine))
            line = QLineF(line)
            line.translate(0, 4.0)
            painter.drawLine(line)
            line.translate(0, -8.0)
            painter.drawLine(line)
示例#4
0
    def paint(self, painter, option, widget=None):
        if self.myStartItem.collidesWithItem(self.myEndItem):
            return

        myStartItem = self.myStartItem
        myEndItem = self.myEndItem
        myColor = self.myColor
        myPen = self.pen()
        myPen.setColor(self.myColor)
        arrowSize = 20.0
        painter.setPen(myPen)
        painter.setBrush(self.myColor)

        centerLine = QLineF(myStartItem.pos(), myEndItem.pos())
        endPolygon = myEndItem.polygon()
        p1 = endPolygon.first() + myEndItem.pos()

        intersectPoint = QPointF()
        for i in endPolygon:
            p2 = i + myEndItem.pos()
            polyLine = QLineF(p1, p2)
            intersectType = polyLine.intersect(centerLine, intersectPoint)
            if intersectType == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersectPoint, myStartItem.pos()))
        line = self.line()

        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (math.pi * 2.0) - angle

        arrowP1 = line.p1() + QPointF(
            math.sin(angle + math.pi / 3.0) * arrowSize,
            math.cos(angle + math.pi / 3) * arrowSize,
        )
        arrowP2 = line.p1() + QPointF(
            math.sin(angle + math.pi - math.pi / 3.0) * arrowSize,
            math.cos(angle + math.pi - math.pi / 3.0) * arrowSize,
        )

        self.arrowHead.clear()
        for point in [line.p1(), arrowP1, arrowP2]:
            self.arrowHead.append(point)

        painter.drawLine(line)
        painter.drawPolygon(self.arrowHead)
        if self.isSelected():
            painter.setPen(QPen(myColor, 1, Qt.DashLine))
            myLine = QLineF(line)
            myLine.translate(0, 4.0)
            painter.drawLine(myLine)
            myLine.translate(0, -8.0)
            painter.drawLine(myLine)
示例#5
0
    def paint(self, painter, option, widget=None):
        if self.my_start_item.collidesWithItem(self.my_end_item):
            return

        my_start_item = self.my_start_item
        my_end_item = self.my_end_item
        my_color = self.my_color
        my_pen = self.pen()
        my_pen.setColor(self.my_color)
        arrow_size = 20.0
        painter.setPen(my_pen)
        painter.setBrush(my_color)

        center_line = QLineF(my_start_item.pos(), my_end_item.pos())
        end_polygon = my_end_item.polygon

        p1 = end_polygon.first() + my_end_item.pos()

        intersect_point = QPointF()
        for i in end_polygon:
            p2 = i + my_end_item.pos()
            poly_line = QLineF(p1, p2)
            intersect_type = poly_line.intersect(center_line, intersect_point)
            if intersect_type == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersect_point, my_start_item.pos()))
        line = self.line()

        angle = math.acos(line.dx() / line.length())

        if line.dy() >= 0:
            angle = (math.pi * 2) - angle

        arrow_p1 = line.p1() + QPointF(math.sin(angle + math.pi / 3.0) * arrow_size,
                                       math.cos(angle + math.pi / 3) * arrow_size)
        arrow_p2 = line.p1() + QPointF(math.sin(angle + math.pi - math.pi / 3.0) * arrow_size,
                                       math.cos(angle + math.pi - math.pi / 3.0) * arrow_size)

        self.arrowHead.clear()
        for point in [line.p1(), arrow_p1, arrow_p2]:
            self.arrowHead.append(point)

        painter.drawLine(line)
        painter.drawPolygon(self.arrowHead)
        if self.isSelected():
            painter.setPen(QPen(my_color, 1, Qt.DashLine))
            my_line = QLineF(line)
            my_line.translate(0, 4.0)
            painter.drawLine(my_line)
            my_line.translate(0, -8.0)
            painter.drawLine(my_line)
示例#6
0
 def intersectLineGeometry(self, lineGeo, breakShape):
     """
     Try to break lineGeo with the given breakShape. Will return the intersection points of lineGeo with breakShape.
     """
     # TODO geos should be abs
     intersections = []
     line = QLineF(lineGeo.Ps.x, lineGeo.Ps.y, lineGeo.Pe.x, lineGeo.Pe.y)
     for breakGeo in breakShape.geos.abs_iter():
         if isinstance(breakGeo, LineGeo):
             breakLine = QLineF(breakGeo.Ps.x, breakGeo.Ps.y, breakGeo.Pe.x, breakGeo.Pe.y)
             intersection = QPointF(0, 0)  # values do not matter
             res = line.intersect(breakLine, intersection)
             if res == QLineF.BoundedIntersection:
                 intersections.append(Point(intersection.x(), intersection.y()))
     return intersections
示例#7
0
 def intersectLineGeometry(self, lineGeo, breakShape):
     """
     Try to break lineGeo with the given breakShape. Will return the intersection points of lineGeo with breakShape.
     """
     # TODO geos should be abs
     intersections = []
     line = QLineF(lineGeo.Ps.x, lineGeo.Ps.y, lineGeo.Pe.x, lineGeo.Pe.y)
     for breakGeo in breakShape.geos.abs_iter():
         if isinstance(breakGeo, LineGeo):
             breakLine = QLineF(breakGeo.Ps.x, breakGeo.Ps.y, breakGeo.Pe.x, breakGeo.Pe.y)
             intersection = QPointF(0, 0)  # values do not matter
             res = line.intersect(breakLine, intersection)
             if res == QLineF.BoundedIntersection:
                 intersections.append(Point(intersection.x(), intersection.y()))
     return intersections
示例#8
0
    def intersection(self, line):
        """
        Returns the intersection of the shape with the given line (in scene coordinates).
        :type line: QLineF
        :rtype: QPointF
        """
        intersection = QPointF()
        path = self.painterPath()
        polygon = self.mapToScene(path.toFillPolygon(self.transform()))

        for i in range(0, polygon.size() - 1):
            polyline = QLineF(polygon[i], polygon[i + 1])
            if polyline.intersect(line, intersection) == QLineF.BoundedIntersection:
                return intersection

        return None
示例#9
0
    def intersection(self, line):
        """
        Returns the intersection of the shape with the given line (in scene coordinates).
        :type line: QLineF
        :rtype: QPointF
        """
        intersection = QPointF()
        path = self.painterPath()
        polygon = self.mapToScene(path.toFillPolygon(self.transform()))

        for i in range(0, polygon.size() - 1):
            polyline = QLineF(polygon[i], polygon[i + 1])
            if polyline.intersect(line,
                                  intersection) == QLineF.BoundedIntersection:
                return intersection

        return None
示例#10
0
 def __findRectIntersectionPoint(self, item, p1, p2):
     """
     Private method to find the intersetion point of a line with a
     rectangle.
     
     @param item item to check against
     @param p1 first point of the line (QPointF)
     @param p2 second point of the line (QPointF)
     @return the intersection point (QPointF)
     """
     rect = self.__mapRectFromItem(item)
     lines = [
         QLineF(rect.topLeft(), rect.topRight()),
         QLineF(rect.topLeft(), rect.bottomLeft()),
         QLineF(rect.bottomRight(), rect.bottomLeft()),
         QLineF(rect.bottomRight(), rect.topRight()),
     ]
     intersectLine = QLineF(p1, p2)
     intersectPoint = QPointF(0, 0)
     for line in lines:
         if intersectLine.intersect(line, intersectPoint) == QLineF.BoundedIntersection:
             return intersectPoint
     return QPointF(-1.0, -1.0)
示例#11
0
 def __findRectIntersectionPoint(self, item, p1, p2):
     """
     Private method to find the intersetion point of a line with a
     rectangle.
     
     @param item item to check against
     @param p1 first point of the line (QPointF)
     @param p2 second point of the line (QPointF)
     @return the intersection point (QPointF)
     """
     rect = self.__mapRectFromItem(item)
     lines = [
         QLineF(rect.topLeft(), rect.topRight()),
         QLineF(rect.topLeft(), rect.bottomLeft()),
         QLineF(rect.bottomRight(), rect.bottomLeft()),
         QLineF(rect.bottomRight(), rect.topRight())
     ]
     intersectLine = QLineF(p1, p2)
     intersectPoint = QPointF(0, 0)
     for line in lines:
         if intersectLine.intersect(line, intersectPoint) == \
            QLineF.BoundedIntersection:
             return intersectPoint
     return QPointF(-1.0, -1.0)
示例#12
0
    def __stepThree(self):
        """Step 3 -- Do basically everything.
		"""

        # Validate data
        def setError(e):
            """Displays string e.
			"""
            self.lblDataError.setText("<html><head/><body><div>" +
                                      self.lang.errData + e +
                                      "</div></body></html>")

        # Try to read data. We need to create fields, because this will be used later in other functions.
        self.xTL = self.__sfloat(self.xTopLeft.text())
        self.xTR = self.__sfloat(self.xTopRight.text())
        self.xBL = self.__sfloat(self.xBottomLeft.text())
        self.xBR = self.__sfloat(self.xBottomRight.text())

        self.yTL = self.__sfloat(self.yTopLeft.text())
        self.yTR = self.__sfloat(self.yTopRight.text())
        self.yBL = self.__sfloat(self.yBottomLeft.text())
        self.yBR = self.__sfloat(self.yBottomRight.text())

        self.xD = self.__sfloat(self.xDelimiter.text())
        self.yD = self.__sfloat(self.yDelimiter.text())

        # Convert delimiters to pixels.
        # Value of another coordinate doesn't matter.
        # If you'll draw a random line and draw crossing lines parallel to one of axes with same distance between these lines by another axis, you'll split your random line into equal pieces.
        # See for yourself:
        # Y
        # ^ ___\_____
        # | ____\____
        # | _____\___
        # |       \
        # |-----------> X
        # You can try it on paper or prove this "theorem" doing some math.
        try:
            self.xDTop = self.width / abs(self.xTL - self.xTR) * self.xD
            self.xDBottom = self.width / abs(self.xBL - self.xBR) * self.xD
            self.yDLeft = self.height / abs(self.yTL - self.yBL) * self.yD
            self.yDRight = self.height / abs(self.yTR - self.yBR) * self.yD
        except ZeroDivisionError:
            setError(self.lang.errCorners)
            return

        # Now do the same stuff, but find how much pixels in one degree.
        # We won't find absolute value for subtraction because axes of image in geographic system may be not codirectional to axes of image in Qt system.
        self.topX = (self.xTR - self.xTL) / self.width
        self.bottomX = (self.xBR - self.xBL) / self.width
        self.leftY = (self.yTL - self.yBL) / self.height
        self.rightY = (self.yTR - self.yBR) / self.height

        # Sides of image in geographic system
        self.top = QLineF(self.xTL, self.yTL, self.xTR, self.yTR)
        self.bottom = QLineF(self.xBL, self.yBL, self.xBR, self.yBR)
        self.left = QLineF(self.xTL, self.yTL, self.xBL, self.yBL)
        self.right = QLineF(self.xTR, self.yTR, self.xBR, self.yBR)

        errors = ""
        if self.xDTop > self.width:
            errors += self.lang.errLongTop + "<br>"
        if self.xDBottom > self.width:
            errors += self.lang.errLongBottom + "<br>"
        if self.yDLeft > self.height:
            errors += self.lang.errLatLeft + "<br>"
        if self.yDRight > self.height:
            errors += self.lang.errLatRight + "<br>"

        if errors != "":
            setError(self.lang.errSides + "<br>" + errors)
            return

        # Check if given coordinates form 8-shaped figure
        if (self.xTL > self.xTR and self.xBL < self.xBR) or (
                self.xTL < self.xTR and self.xBL > self.xBR) or (
                    self.yTL > self.yBL
                    and self.yTR < self.yBR) or (self.yTL < self.yBL
                                                 and self.yTR > self.yTL):
            choice = QMessageBox(QMessageBox.Warning, "AerialWare",
                                 self.lang.warningCoordinates,
                                 QMessageBox.Yes | QMessageBox.No).exec()
            if choice == QMessageBox.No:
                return

        # Draw grid

        # Set points for grid
        # Points will look like:
        # [point, point, ...],
        # [point, point, ...], ...
        pointRows = []
        # Let x1, y1; x2, y2 be vertical line
        # and x3, y3; x4, y4 be horizontal line.
        # Thus, y1 and y2 should be always on top and bottom;
        # x3, x4 -- on left and right
        y1, y2, x3, x4 = 0, self.height, 0, self.width
        # So we have to change:
        #	for vertical line: x1, x2
        #	for horizontal line: y3, y4

        y3 = y4 = 0  # Initial values for horizontal line
        # Move horizontal line
        while y3 <= self.height + self.yDLeft / 2 or y4 <= self.height + self.yDRight / 2:
            x1 = x2 = 0  # Initial values for vertical line
            # Move vertical line
            points = []
            while x1 <= self.width + self.xDTop / 2 or x2 <= self.width + self.xDBottom / 2:
                point = QPointF()
                QLineF.intersect(QLineF(x1, y1, x2, y2),
                                 QLineF(x3, y3, x4, y4), point)
                points.append(point)
                x1 += self.xDTop
                x2 += self.xDBottom
            if points != []:
                pointRows.append(points)
            y3 += self.yDLeft
            y4 += self.yDRight

        # If nothing has been added
        if points == []:
            setError(self.lang.errPoints)
            return

        # Get scene geometry to preserve scene expanding
        rect = self.scene.sceneRect()
        # And add bounds for the grid
        self.bounds = QGraphicsRectItem(rect)
        self.bounds.setFlag(self.bounds.ItemClipsChildrenToShape)
        self.scene.addItem(self.bounds)
        # Create polygons from points
        # We'll recheck previous item
        i = 1  # Rows
        while i < len(pointRows):
            j = 1  # Points
            while j < len(pointRows[i]):
                # Add points in following order: top left, top right, bottom right, bottom left
                points = [
                    pointRows[i - 1][j - 1], pointRows[i - 1][j],
                    pointRows[i][j], pointRows[i][j - 1]
                ]
                # We're assigning self.bounds as parent implicitly, so we shouldn't add polygon to scene by ourselves.
                poly = _QCustomGraphicsPolygonItem(QPolygonF(points),
                                                   self.bounds)
                poly.setRowCol(i - 1, j - 1)
                j += 1
            i += 1
        # Restore scene geometry
        self.scene.setSceneRect(rect)

        self.__turnPage()
        self.btnNext.disconnect()
        self.btnNext.clicked.connect(self.__stepFour)
示例#13
0
    def paint(self, painter, options, widget=None):
        """
        Painter implementation for the arrow.
        First it draws the line and then the triangle on the end

        :param painter: The painter, which draws the node
        :param options: options for the paint job
        :param widget: widget of the Item
        """

        if self.start.collidesWithItem(self.dst):
            return

        myPen = self.pen()
        arrowSize = 10
        painter.setPen(myPen)
        painter.setBrush(myPen.color())
        """
        Calculation for the line
        """
        centerLine = QLineF(QPointF(self.start.x() + self.start.boundingRect().center().x() + self.offset,
                                    self.start.y() + self.start.boundingRect().bottom()),
                            QPointF(self.dst.x() + self.dst.boundingRect().center().x(), self.dst.y()))
        endPolygon = self.dst.mapFromItem(self.dst, self.dst.boundingRect())
        p1 = endPolygon.first() + self.dst.pos()
        p2 = None
        intersectPoint = QPointF()

        for i in endPolygon:
            p2 = i + self.dst.pos()

            polyLine = QLineF(p1, p2)

            intersectType = polyLine.intersect(centerLine, intersectPoint)
            if intersectType == QLineF.BoundedIntersection:
                break
            p1 = p2

        self.setLine(QLineF(intersectPoint,
                            QPointF(self.start.x() + self.start.boundingRect().center().x() + self.offset,
                                    self.start.y() + self.start.boundingRect().bottom())))

        """
        Calculation for the arrow
        It calculates an left and an right part of the arrow
        """
        angle = math.atan2(-self.line().dy(), self.line().dx())
        arrowP1 = self.line().p1() + QPointF(math.sin(angle + math.pi / 3) * arrowSize,
                                             math.cos(angle + math.pi / 3) * arrowSize)
        arrowP2 = self.line().p1() + QPointF(math.sin(angle + math.pi - math.pi / 3) * arrowSize,
                                             math.cos(angle + math.pi - math.pi / 3) * arrowSize)

        self.arrowHead.clear()
        self.arrowHead << self.line().p1() << arrowP1 << arrowP2

        painter.drawLine(self.line())
        painter.drawPolygon(self.arrowHead)
        if self.isSelected():
            painter.setPen(QPen(Qt.black, 1, Qt.DashLine))
            myLine = self.line()
            myLine.translate(0, 4.0)
            painter.drawLine(myLine)
            myLine.translate(0, -8.0)
            painter.drawLine(myLine)