Ejemplo n.º 1
0
    def getIntersection(self, p1, p2):
        """
        Get intersection on segment
        :param p1: QgsPointV2
        :param p2: QgsPointV2
        :param inter: QgsPointV2 reference
        :return: bool
        """
        q1 = self.idxFrom.point()
        q2 = self.idxTo.point()
        v = QgsVector(p2.x() - p1.x(), p2.y() - p1.y())
        w = QgsVector(q2.x() - q1.x(), q2.y() - q1.y())
        vl = v.length()
        wl = w.length()

        if self.isclose(vl, 0.) or self.isclose(wl, 0.):
            return None

        v = v / vl
        w = w / wl

        d = v.y() * w.x() - v.x() * w.y()

        if d == 0:
            return None

        dx = q1.x() - p1.x()
        dy = q1.y() - p1.y()
        k = (dy * w.x() - dx * w.y()) / d

        inter = QgsPointV2(p1.x() + v.x() * k, p1.y() + v.y() * k)

        lambdav = QgsVector(inter.x() - p1.x(), inter.y() - p1.y()) * v
        if lambdav < 0. + 1E-8 or lambdav > vl - 1E-8:
            return None

        lambdaw = QgsVector(inter.x() - q1.x(), inter.y() - q1.y()) * w
        if lambdaw < 0. + 1E-8 or lambdaw >= wl - 1E-8:
            return None

        return inter
Ejemplo n.º 2
0
    def compute_compatibilty_matrix(self, feedback):
        """
        Compatibility is stored in a matrix (rows = edges, columns = edges).
        Every coordinate in the matrix tells whether the two edges (r,c)/(c,r)
        are compatible, or not. The diagonal is always zero, and the other fields
        are filled with either -1 (not compatible) or 1 (compatible).
        The matrix is symmetric.
        """
        feedback.setProgressText("Compute compatibility matrix")
        edges_as_geom = []
        edges_as_vect = []
        for e_idx, edge in enumerate(self.edges):
            if feedback.isCanceled(): return
            geom = edge.geometry()
            edges_as_geom.append(geom)
            edges_as_vect.append(
                QgsVector(
                    geom.vertexAt(1).x() - geom.vertexAt(0).x(),
                    geom.vertexAt(1).y() - geom.vertexAt(0).y()))
            self.edge_lengths.append(edges_as_vect[e_idx].length())

        progress = 0
        for i in range(self.E - 1):
            if feedback.isCanceled(): return
            feedback.setProgress(100.0 * (i + 1) / (self.E - 1))
            for j in range(i + 1, self.E):
                if feedback.isCanceled(): return
                # Parameters
                lavg = (self.edge_lengths[i] + self.edge_lengths[j]) / 2.0
                dot = edges_as_vect[i].normalized(
                ) * edges_as_vect[j].normalized()

                # Angle compatibility
                angle_comp = abs(dot)

                # Scale compatibility
                scale_comp = 2.0 / (
                    lavg / min(self.edge_lengths[i], self.edge_lengths[j]) +
                    max(self.edge_lengths[i], self.edge_lengths[j]) / lavg)

                # Position compatibility
                i0 = edges_as_geom[i].vertexAt(0)
                i1 = edges_as_geom[i].vertexAt(1)
                j0 = edges_as_geom[j].vertexAt(0)
                j1 = edges_as_geom[j].vertexAt(1)
                e1_mid = QgsPoint((i0.x() + i1.x()) / 2.0,
                                  (i0.y() + i1.y()) / 2.0)
                e2_mid = QgsPoint((j0.x() + j1.x()) / 2.0,
                                  (j0.y() + j1.y()) / 2.0)
                diff = QgsVector(e2_mid.x() - e1_mid.x(),
                                 e2_mid.y() - e1_mid.y())
                pos_comp = lavg / (lavg + diff.length())

                # Visibility compatibility
                mid_E1 = edges_as_geom[i].centroid()
                mid_E2 = edges_as_geom[j].centroid()
                #dist = mid_E1.distance(mid_E2)
                I0 = MiscUtils.project_point_on_line(j0, edges_as_geom[i])
                I1 = MiscUtils.project_point_on_line(j1, edges_as_geom[i])
                mid_I = QgsGeometry.fromPolyline([I0, I1]).centroid()
                dist_I = I0.distance(I1)
                if dist_I == 0.0:
                    visibility1 = 0.0
                else:
                    visibility1 = max(
                        0, 1 - ((2 * mid_E1.distance(mid_I)) / dist_I))
                J0 = MiscUtils.project_point_on_line(i0, edges_as_geom[j])
                J1 = MiscUtils.project_point_on_line(i1, edges_as_geom[j])
                mid_J = QgsGeometry.fromPolyline([J0, J1]).centroid()
                dist_J = J0.distance(J1)
                if dist_J == 0.0:
                    visibility2 = 0.0
                else:
                    visibility2 = max(
                        0, 1 - ((2 * mid_E2.distance(mid_J)) / dist_J))
                visibility_comp = min(visibility1, visibility2)

                # Compatibility score
                comp_score = angle_comp * scale_comp * pos_comp * visibility_comp

                # Fill values into the matrix (1 = yes, -1 = no) and use matrix symmetry (i/j = j/i)
                if comp_score >= self.compatibility:
                    self.compatibility_matrix[i, j] = 1
                    self.compatibility_matrix[j, i] = 1
                else:
                    self.compatibility_matrix[i, j] = -1
                    self.compatibility_matrix[j, i] = -1

                # Store direction
                distStart1 = j0.distance(i0)
                distStart2 = j1.distance(i0)
                if distStart1 > distStart2:
                    self.direction_matrix[i, j] = -1
                    self.direction_matrix[j, i] = -1
                else:
                    self.direction_matrix[i, j] = 1
                    self.direction_matrix[j, i] = 1