def setUpClass(cls):
        """Run before all tests"""
        # Create test layer
        srcpath = os.path.join(TEST_DATA_DIR, 'provider')
        cls.basetestfile = os.path.join(srcpath, 'delimited_wkt.csv')

        url = QUrl.fromLocalFile(cls.basetestfile)
        url.addQueryItem("crs", "epsg:4326")
        url.addQueryItem("type", "csv")
        url.addQueryItem("wktField", "wkt")
        url.addQueryItem("spatialIndex", "no")
        url.addQueryItem("subsetIndex", "no")
        url.addQueryItem("watchFile", "no")

        cls.vl = QgsVectorLayer(url.toString(), u'test', u'delimitedtext')
        assert cls.vl.isValid(), "{} is invalid".format(cls.basetestfile)
        cls.provider = cls.vl.dataProvider()

        cls.basetestpolyfile = os.path.join(srcpath, 'delimited_wkt_poly.csv')

        url = QUrl.fromLocalFile(cls.basetestpolyfile)
        url.addQueryItem("crs", "epsg:4326")
        url.addQueryItem("type", "csv")
        url.addQueryItem("wktField", "wkt")
        url.addQueryItem("spatialIndex", "no")
        url.addQueryItem("subsetIndex", "no")
        url.addQueryItem("watchFile", "no")

        cls.vl_poly = QgsVectorLayer(url.toString(), u'test_polygon', u'delimitedtext')
        assert cls.vl_poly.isValid(), "{} is invalid".format(cls.basetestpolyfile)
        cls.poly_provider = cls.vl_poly.dataProvider()
Example #2
0
    def test_geometry_conversion(self):
        query = QUrl.toPercentEncoding("select geomfromtext('multipoint((0 0),(1 1))') as geom")
        l = QgsVectorLayer("?query=%s&geometry=geom:multipoint:0" % query, "tt", "virtual", False)
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().exportToWkt().lower().startswith("multipoint"), True)
            self.assertEqual("),(" in f.geometry().exportToWkt(), True)  # has two points

        query = QUrl.toPercentEncoding(
            "select geomfromtext('multipolygon(((0 0,1 0,1 1,0 1,0 0)),((0 1,1 1,1 2,0 2,0 1)))') as geom"
        )
        l = QgsVectorLayer("?query=%s&geometry=geom:multipolygon:0" % query, "tt", "virtual", False)
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().exportToWkt().lower().startswith("multipolygon"), True)
            self.assertEqual(")),((" in f.geometry().exportToWkt(), True)  # has two polygons

        query = QUrl.toPercentEncoding(
            "select geomfromtext('multilinestring((0 0,1 0,1 1,0 1,0 0),(0 1,1 1,1 2,0 2,0 1))') as geom"
        )
        l = QgsVectorLayer("?query=%s&geometry=geom:multilinestring:0" % query, "tt", "virtual", False)
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().exportToWkt().lower().startswith("multilinestring"), True)
            self.assertEqual("),(" in f.geometry().exportToWkt(), True)  # has two linestrings
Example #3
0
    def query(self, query):
        """
        Perform a nominatim query

        @param query: Query to execute
        @type query: str

        @raise NetWorkErrorException

        @return: the result of the query
        @rtype: str
        """

        url_query = QUrl(self.__url)

        # query = QUrl.toPercentEncoding(query)
        query_string = QUrlQuery()
        query_string.addQueryItem('q', query)
        query_string.addQueryItem('format', 'json')
        query_string.addQueryItem('info', 'QgisQuickOSMPlugin')
        url_query.setQuery(query_string)

        request = QNetworkRequest(url_query)
        # request.setRawHeader("User-Agent", "QuickOSM")
        self.network_reply = self.network.get(request)
        self.loop = QEventLoop()
        self.network.finished.connect(self._end_of_request)
        self.loop.exec_()

        if self.network_reply.error() == QNetworkReply.NoError:
            return json.loads(self.data)
        else:
            raise NetWorkErrorException(suffix="Nominatim API")
Example #4
0
    def prepare_url(self):
        """Prepare a query to be as an URL.

        if the query is not ready to be URL prepared, a None is returned.

        :return: The URL encoded with the query.
        :rtype: basestring
        """
        if not self._query_is_ready:
            return None

        if self._output_format:
            query = re.sub(
                r'output="[a-z]*"',
                'output="%s"' % self._output_format,
                self._query_prepared)
            query = re.sub(
                r'\[out:[a-z]*',
                '[out:%s' % self._output_format,
                query)
        else:
            query = self._query_prepared

        url_query = QUrl(self._overpass)
        query_string = QUrlQuery()
        query_string.addQueryItem('data', query)
        query_string.addQueryItem('info', 'QgisQuickOSMPlugin')
        url_query.setQuery(query_string)
        return url_query.toString()
    def currentItemChanged(self):
        item = self.lessonsTree.currentItem()
        if item:
            if hasattr(item, "lesson"):
                self.btnRemove.setText("Uninstall lesson")
                self.btnRemove.setEnabled(True)
                self.btnRunLesson.setEnabled(True)
                if os.path.exists(item.lesson.description):
                    with codecs.open(item.lesson.description, encoding="utf-8") as f:
                        html = "".join(f.readlines())
                        if item.lesson.description.endswith(".md"):
                            html = markdown.markdown(html)
                    self.webView.document().setMetaInformation(QTextDocument.DocumentUrl,
                                                               QUrl.fromUserInput(item.lesson.description).toString())
                    self.webView.setHtml(html)
                else:
                    self.webView.setHtml("<p>{}</p>".format(item.lesson.description))
            else:
                self.btnRunLesson.setEnabled(False)
                self.btnRemove.setText("Uninstall lessons group")
                self.btnRemove.setEnabled(True)
                if os.path.exists(item.description):
                    with codecs.open(item.description, encoding="utf-8") as f:
                        html = "".join(f.readlines())
                    if item.description.endswith(".md"):
                        html = markdown.markdown(html)
                    self.webView.document().setMetaInformation(QTextDocument.DocumentUrl,
                                                               QUrl.fromUserInput(item.description).toString())
                else:
                    html = item.description
                self.webView.setHtml(html)

        else:
            self.btnRemove.setEnabled(False)
            self.btnRunLesson.setEnabled(False)
Example #6
0
 def test_rowid(self):
     source = QUrl.toPercentEncoding(os.path.join(self.testDataDir, "france_parts.shp"))
     query = QUrl.toPercentEncoding("select rowid as uid, * from vtab limit 1 offset 3")
     l = QgsVectorLayer("?layer=ogr:%s:vtab&query=%s" % (source, query), "vtab2", "virtual", False)
     # the last line must have a fixed rowid (not an autoincrement)
     for f in l.getFeatures():
         lid = f.attributes()[0]
     self.assertEqual(lid, 3)
Example #7
0
    def test_filter_rect(self):
        source = QUrl.toPercentEncoding(os.path.join(self.testDataDir, "france_parts.shp"))

        query = QUrl.toPercentEncoding("select * from vtab where _search_frame_=BuildMbr(-2.10,49.38,-1.3,49.99,4326)")
        l2 = QgsVectorLayer("?layer=ogr:%s:vtab&query=%s&uid=objectid" % (source, query), "vtab2", "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().featureCount(), 1)
        a = [fit.attributes()[4] for fit in l2.getFeatures()]
        self.assertEqual(a, [u"Basse-Normandie"])
Example #8
0
    def test_sql2(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False)
        self.assertEqual(l2.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayer(l2)

        query = QUrl.toPercentEncoding("SELECT * FROM france_parts")
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual")
        self.assertEqual(l4.isValid(), True)

        self.assertEqual(l4.dataProvider().wkbType(), 3)
        self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326)

        n = 0
        r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086))
        for f in l4.getFeatures(r):
            self.assertEqual(f.geometry() is not None, True)
            self.assertEqual(f.attributes()[0], 2661)
            n += 1
        self.assertEqual(n, 1)

        # use uid
        query = QUrl.toPercentEncoding("SELECT * FROM france_parts")
        l5 = QgsVectorLayer("?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query, "tt", "virtual")
        self.assertEqual(l5.isValid(), True)

        idSum = sum(f.id() for f in l5.getFeatures())
        self.assertEqual(idSum, 10659)

        r = QgsFeatureRequest(2661)
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)

        r = QgsFeatureRequest()
        r.setFilterFids([2661, 2664])
        self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664)

        # test attribute subset
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.SubsetOfAttributes)
        r.setSubsetOfAttributes([1])
        s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)]
        self.assertEqual(sum(map(lambda x: x[0], s)), 10659)
        self.assertEqual(sum(map(lambda x: x[1], s)), 3064.0)

        # test NoGeometry
        # by request flag
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.NoGeometry)
        self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]), True)

        # test subset
        self.assertEqual(l5.dataProvider().featureCount(), 4)
        l5.setSubsetString("ObjectId = 2661")
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)
        self.assertEqual(l5.dataProvider().featureCount(), 1)
Example #9
0
    def test_reopen2(self):
        source = QUrl.toPercentEncoding(os.path.join(self.testDataDir, "france_parts.shp"))
        tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString()
        l = QgsVectorLayer("%s?layer=ogr:%s:vtab&nogeometry" % (tmp, source), "vtab2", "virtual", False)
        self.assertEqual(l.isValid(), True)

        l2 = QgsVectorLayer(tmp, "tt", "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 100)
        self.assertEqual(l2.dataProvider().featureCount(), 4)
Example #10
0
    def test_DynamicGeometry(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/testextpt.txt")).toString() + "?type=csv&delimiter=%7C&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual(l1.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayer(l1)

        query = QUrl.toPercentEncoding("select *,makepoint(x,y) as geom from vtab1")
        l2 = QgsVectorLayer("?layer_ref=%s&query=%s&geometry=geom:point:0&uid=id" % (l1.id(), query), "vtab", "virtual", False)
        self.assertEqual(l2.isValid(), True)

        QgsMapLayerRegistry.instance().removeMapLayer(l1)
Example #11
0
    def test_refLayers2(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        # referenced layers cannot be stored !
        tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString()
        l2 = QgsVectorLayer("%s?layer_ref=%s" % (tmp, l1.id()), "tt", "virtual", False)
        self.assertEqual(l2.isValid(), False)
        self.assertEqual("Cannot store referenced layers" in l2.dataProvider().error().message(), True)
    def test_resolve_path(self):
        """Test resolving the path works correctly."""
        collection_path = test_data_path('collections', 'test_collection')
        search_paths = []

        # Test case 1: local path
        img_path = test_data_path(
            'collections', 'test_collection', 'svg', 'blastoise.svg')
        fixed_path = resolve_path(img_path, collection_path, search_paths)
        self.assertEqual(img_path, fixed_path)

        # Test case 2: local url
        img_path = test_data_path(
            'collections', 'test_collection', 'svg', 'blastoise.svg')
        img_url = QUrl.fromLocalFile(img_path)
        fixed_path = resolve_path(
            img_url.toString(), collection_path, search_paths)
        self.assertEqual(fixed_path, img_path)

        # Test case 3:  http url
        img_path = 'http://qgis.org/test/image.svg'
        img_url = QUrl(img_path)
        fixed_path = resolve_path(
            img_url.toString(), collection_path, search_paths)
        self.assertEqual(fixed_path, img_path)

        # Test case 4: checking in the svg local collection path
        img_path = '/you/would/not/find/this/charizard.svg'
        fixed_path = resolve_path(img_path, collection_path, search_paths)
        expected_path = test_data_path(
            'collections', 'test_collection', 'svg', 'charizard.svg')
        self.assertEqual(fixed_path, expected_path)

        # Test case 5: checking in the image local collection path
        img_path = '/you/would/not/find/this/pikachu.png'
        fixed_path = resolve_path(img_path, collection_path, search_paths)
        expected_path = test_data_path(
            'collections', 'test_collection', 'image', 'pikachu.png')
        self.assertEqual(fixed_path, expected_path)

        # Test case 6: checking in the search paths
        search_paths = [
            test_data_path(
                'collections', 'test_collection', 'preview')
        ]
        img_path = 'prev_1.png'
        fixed_path = resolve_path(img_path, collection_path, search_paths)
        expected_path = test_data_path(
            'collections', 'test_collection', 'preview', 'prev_1.png')
        self.assertEqual(fixed_path, expected_path)

        # Test case 7: not finding anywhere (return the original path)
        img_path = '/you/would/not/find/this/anywhere.png'
        fixed_path = resolve_path(img_path, collection_path, search_paths)
        self.assertEqual(fixed_path, img_path)
    def test1(self):
        d = QgsVirtualLayerDefinition()
        self.assertEqual(d.toString(), "")
        d.setFilePath("/file")
        self.assertEqual(d.toString(), "file:///file")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), "/file")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).filePath(), "/file")
        d.setFilePath(os.path.join('C:/', 'file'))
        self.assertEqual(d.toString(), "file:///C:/file")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).filePath(), os.path.join('C:/', 'file'))
        d.setQuery("SELECT * FROM mytable")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), "SELECT * FROM mytable")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).query(), "SELECT * FROM mytable")

        q = u"SELECT * FROM tableéé /*:int*/"
        d.setQuery(q)
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).query(), q)
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).query(), q)

        s1 = u"file://foo&bar=okié"
        d.addSource("name", s1, "provider", "utf8")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[0].source(), s1)
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).sourceLayers()[0].source(), s1)

        n1 = u"éé ok"
        d.addSource(n1, s1, "provider")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[1].name(), n1)
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).sourceLayers()[1].name(), n1)

        d.addSource("ref1", "id0001")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[2].reference(), "id0001")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).sourceLayers()[2].reference(), "id0001")

        s = "dbname='C:\\tt' table=\"test\" (geometry) sql="
        d.addSource("nn", s, "spatialite")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).sourceLayers()[3].source(), s)
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).sourceLayers()[3].source(), s)

        d.setGeometryField("geom")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryField(), "geom")
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).geometryField(), "geom")

        d.setGeometryWkbType(QgsWKBTypes.Point)
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(d.toUrl()).geometryWkbType(), QgsWKBTypes.Point)
        self.assertEqual(QgsVirtualLayerDefinition.fromUrl(QUrl.fromEncoded(d.toString())).geometryWkbType(), QgsWKBTypes.Point)

        f = QgsFields()
        f.append(QgsField("a", QVariant.Int))
        f.append(QgsField("f", QVariant.Double))
        f.append(QgsField("s", QVariant.String))
        d.setFields(f)
        f2 = QgsVirtualLayerDefinition.fromUrl(d.toUrl()).fields()
        self.assertEqual(f[0].name(), f2[0].name())
        self.assertEqual(f[0].type(), f2[0].type())
        self.assertEqual(f[1].name(), f2[1].name())
        self.assertEqual(f[1].type(), f2[1].type())
        self.assertEqual(f[2].name(), f2[2].name())
        self.assertEqual(f[2].type(), f2[2].type())
Example #14
0
    def test_sql_field_types(self):
        query = QUrl.toPercentEncoding("SELECT 42 as t, 'ok'||'ok' as t2, GeomFromText('') as t3, 3.14*2 as t4")
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "t")
        self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.Int)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2")
        self.assertEqual(l4.dataProvider().fields().at(1).type(), QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(2).name(), "t3")
        self.assertEqual(l4.dataProvider().fields().at(2).type(), QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(3).name(), "t4")
        self.assertEqual(l4.dataProvider().fields().at(3).type(), QVariant.Double)

        # with type annotations
        query = QUrl.toPercentEncoding(
            "SELECT '42.0' as t /*:real*/, 3 as t2/*:text  */, GeomFromText('') as t3 /*:multiPoInT:4326 */, 3.14*2 as t4/*:int*/"
        )
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "t")
        self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.Double)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2")
        self.assertEqual(l4.dataProvider().fields().at(1).type(), QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(2).name(), "t4")
        self.assertEqual(l4.dataProvider().fields().at(2).type(), QVariant.Int)
        self.assertEqual(l4.dataProvider().wkbType(), 4)  # multipoint

        # test value types (!= from declared column types)
        for f in l4.getFeatures():
            self.assertEqual(f.attributes()[0], "42.0")
            self.assertEqual(f.attributes()[1], 3)
            self.assertEqual(f.attributes()[2], 6.28)

        # with type annotations and url options
        query = QUrl.toPercentEncoding(
            "SELECT 1 as id /*:int*/, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/"
        )
        l4 = QgsVectorLayer("?query=%s&geometry=geometry" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().wkbType(), 1)  # point

        # with type annotations and url options (2)
        query = QUrl.toPercentEncoding(
            "SELECT 1 as id /*:int*/, 3.14 as f, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/"
        )
        l4 = QgsVectorLayer("?query=%s&geometry=geometry&field=id:text" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "id")
        self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "f")
        self.assertEqual(l4.dataProvider().fields().at(1).type(), QVariant.Double)
        self.assertEqual(l4.dataProvider().wkbType(), 1)  # point
Example #15
0
    def test_refLayers(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual(l1.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayer(l1)

        # cf qgis bug #12266
        for i in range(10):
            q = QUrl.toPercentEncoding("select * from t" + str(i))
            l2 = QgsVectorLayer("?layer_ref=%s:t%d&query=%s&uid=id" % (l1.id(), i, q), "vtab", "virtual", False)
            QgsMapLayerRegistry.instance().addMapLayer(l2)
            self.assertEqual(l2.isValid(), True)
            s = sum([f.id() for f in l2.dataProvider().getFeatures()])  # NOQA
            self.assertEqual(sum([f.id() for f in l2.getFeatures()]), 21)
            QgsMapLayerRegistry.instance().removeMapLayer(l2.id())
Example #16
0
def clean_ows_url(url):
    """clean an OWS URL of added basic service parameters"""

    url = QUrl(url)
    query_string = url.query()

    if query_string:
        query_string = QUrlQuery(query_string)
        query_string.removeQueryItem('service')
        query_string.removeQueryItem('SERVICE')
        query_string.removeQueryItem('request')
        query_string.removeQueryItem('REQUEST')
        url.setQuery(query_string)

    return url.toString()
Example #17
0
    def test_reopen4(self):
        source = QUrl.toPercentEncoding(os.path.join(self.testDataDir, "france_parts.shp"))
        tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString()
        query = QUrl.toPercentEncoding("SELECT * FROM vtab")
        l = QgsVectorLayer("%s?layer=ogr:%s:vtab&query=%s&uid=objectid&nogeometry" % (tmp, source, query), "vtab2", "virtual", False)
        self.assertEqual(l.isValid(), True)

        l2 = QgsVectorLayer(tmp, "tt", "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().geometryType(), 100)
        self.assertEqual(l2.dataProvider().featureCount(), 4)
        sumid = sum([f.id() for f in l2.getFeatures()])
        self.assertEqual(sumid, 10659)
        suma = sum([f.attributes()[1] for f in l2.getFeatures()])
        self.assertEqual(suma, 3064.0)
Example #18
0
    def test_embeddedLayer(self):
        source = QUrl.toPercentEncoding(os.path.join(self.testDataDir, "france_parts.shp"))
        l = QgsVectorLayer("?layer=ogr:%s" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)

        l = QgsVectorLayer("?layer=ogr:%s:nn" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)
Example #19
0
    def test_sql3b(self):
        query = QUrl.toPercentEncoding("SELECT GeomFromText('POINT(0 0)') as geom")
        l4 = QgsVectorLayer("?query=%s&geometry=geom" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().wkbType(), 1)

        # forced geometry type
        query = QUrl.toPercentEncoding("SELECT GeomFromText('POINT(0 0)') as geom")
        l4 = QgsVectorLayer("?query=%s&geometry=geom:point:0" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().wkbType(), 1)

        query = QUrl.toPercentEncoding("SELECT CastToPoint(GeomFromText('POINT(0 0)')) as geom")
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().wkbType(), 1)
Example #20
0
    def __init__(self, url, output_path, progress_dialog=None):
        """Constructor of the class.

        .. versionchanged:: 3.3 removed manager parameter.

        :param url: URL of file.
        :type url: str

        :param output_path: Output path.
        :type output_path: str

        :param progress_dialog: Progress dialog widget.
        :type progress_dialog: QWidget
        """
        # noinspection PyArgumentList
        self.manager = QgsNetworkAccessManager.instance()
        self.url = QUrl(url)
        self.output_path = output_path
        self.progress_dialog = progress_dialog
        if self.progress_dialog:
            self.prefix_text = self.progress_dialog.labelText()
        self.output_file = None
        self.reply = None
        self.downloaded_file_buffer = None
        self.finished_flag = False
Example #21
0
 def onHelp(self):
     helpPath = Utils.getHelpPath()
     if helpPath == '':
         url = QUrl("http://www.gdal.org/" + self.helpFileName)
     else:
         url = QUrl.fromLocalFile(helpPath + '/' + self.helpFileName)
     QDesktopServices.openUrl(url)
Example #22
0
    def help(self):
        localDoc = None
        html = self.grass7Name + ".html"
        if system.isWindows():
            # For MS-Windows, use the configured GRASS7 path
            localPath = os.path.join(Grass7Utils.grassPath(), "docs/html", html)
            if os.path.exists(localPath):
                localDoc = os.path.abspath(localPath)
        elif system.isMac():
            # For MacOSX official package
            localPath = os.path.join("/Applications/GRASS-7.0.app/Contents/MacOS/docs/html", html)
            if os.path.exists(localPath):
                localDoc = os.path.abspath(localPath)
        else:
            # For GNU/Linux distributions
            searchPaths = ["/usr/share/doc/grass-doc/html", "/opt/grass/docs/html", "/usr/share/doc/grass/docs/html"]
            for path in searchPaths:
                localPath = os.path.join(path, html)
                if os.path.exists(localPath):
                    localDoc = os.path.abspath(localPath)

        # Found the local documentation
        if localDoc:
            localDoc = QUrl.fromLocalFile(localDoc).toString()
            return False, localDoc

        # Return the URL if local doc is not found
        return False, "http://grass.osgeo.org/grass70/manuals/" + self.grass7Name + ".html"
Example #23
0
 def test_source_escaping(self):
     # the source contains ':'
     source = QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no"
     d = QgsVirtualLayerDefinition()
     d.addSource("t", source, "delimitedtext")
     l = QgsVectorLayer(d.toString(), "vtab", "virtual", False)
     self.assertEqual(l.isValid(), True)
Example #24
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        q = QUrl.toPercentEncoding(c.sql)
        p = QgsVectorLayer("%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual")
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != Qgis.WKBNoGeometry:
            gn = getQueryGeometryName(tmp)
            if gn:
                f += [gn]
        return f
def test_repository_url():
    """Return the test repository URL on file system.

    :return: The test repository URL string
    :rtype: str
    """
    return QUrl.fromLocalFile(test_data_path()).toString()
Example #26
0
    def test_Join(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "points.shp"), "points", "ogr", False)
        self.assertEqual(l1.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayer(l1)
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "points_relations.shp"), "points_relations", "ogr", False)
        self.assertEqual(l2.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayer(l2)
        ref_sum = sum(f.attributes()[1] for f in l2.getFeatures())

        # use a temporary file
        query = QUrl.toPercentEncoding(
            "select id,Pilots,vtab1.geometry from vtab1,vtab2 where intersects(vtab1.geometry,vtab2.geometry)"
        )
        l3 = QgsVectorLayer(
            "?layer_ref=%s&layer_ref=%s&uid=id&query=%s&geometry=geometry:1:4326" % (l1.id(), l2.id(), query),
            "vtab",
            "virtual",
            False,
        )
        self.assertEqual(l3.isValid(), True)
        self.assertEqual(l3.dataProvider().wkbType(), 1)
        self.assertEqual(l3.dataProvider().fields().count(), 2)
        ref_sum2 = sum(f.id() for f in l3.getFeatures())
        self.assertEqual(ref_sum, ref_sum2)

        QgsMapLayerRegistry.instance().removeMapLayer(l1)
        QgsMapLayerRegistry.instance().removeMapLayer(l2)
Example #27
0
 def openScriptFileExtEditor(self):
     tabWidget = self.tabEditorWidget.currentWidget()
     path = tabWidget.path
     import subprocess
     try:
         subprocess.Popen([os.environ['EDITOR'], path])
     except KeyError:
         QDesktopServices.openUrl(QUrl.fromLocalFile(path))
Example #28
0
    def helpUrl(self):
        helpPath = Grass7Utils.grassHelpPath()
        if helpPath == '':
            return None

        if os.path.exists(helpPath):
            return QUrl.fromLocalFile(os.path.join(helpPath, '{}.html'.format(self.grass7Name))).toString()
        else:
            return helpPath + '{}.html'.format(self.grass7Name)
Example #29
0
    def helpUrl(self):
        helpPath = GdalUtils.gdalHelpPath()
        if helpPath == '':
            return None

        if os.path.exists(helpPath):
            return QUrl.fromLocalFile(os.path.join(helpPath, '{}.html'.format(self.commandName()))).toString()
        else:
            return helpPath + '{}.html'.format(self.commandName())
Example #30
0
    def test_CsvNoGeometry(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        l2 = QgsVectorLayer("?layer_ref=" + l1.id(), "vtab", "virtual", False)
        self.assertEqual(l2.isValid(), True)

        QgsProject.instance().removeMapLayer(l1.id())
Example #31
0
 def openURL(self):
     curindex = self.proxyModel.mapToSource(
         self.geoClassList.selectionModel().currentIndex())
     concept = self.geoClassListModel.itemFromIndex(curindex).data(1)
     url = QUrl(concept)
     QDesktopServices.openUrl(url)
Example #32
0
def getVideoLocationInfo(videoPath,
                         islocal=False,
                         klv_folder=None,
                         klv_index=0):
    """ Get basic location info about the video """
    location = []
    try:
        if islocal:
            dataFile = os.path.join(klv_folder, "0.0.klv")
            f = open(dataFile, 'rb')
            stdout_data = f.read()
        else:
            p = _spawn([
                '-i', videoPath, '-ss', '00:00:00', '-to', '00:00:01', '-map',
                '0:d:' + str(klv_index), '-f', 'data', '-'
            ])

            stdout_data, _ = p.communicate()
            # qgsu.showUserAndLogMessage("Video Loc info raw result", stdout_data, onlyLog=True)
        if stdout_data == b'':
            # qgsu.showUserAndLogMessage("Error interpreting klv data, metadata cannot be read.", "the parser did not recognize KLV data", level=QGis.Warning)
            return
        for packet in StreamParser(stdout_data):
            if isinstance(packet, UnknownElement):
                qgsu.showUserAndLogMessage(
                    "Error interpreting klv data, metadata cannot be read.",
                    "the parser did not recognize KLV data",
                    level=QGis.Warning)
                continue
            packet.MetadataList()
            centerLat = packet.FrameCenterLatitude
            centerLon = packet.FrameCenterLongitude
            # Target maybe unavailable because of horizontal view
            if centerLat is None and centerLon is None:
                centerLat = packet.SensorLatitude
                centerLon = packet.SensorLongitude
            loc = "-"

            if Reverse_geocoding_url != "":
                try:
                    url = QUrl(
                        Reverse_geocoding_url.format(str(centerLat),
                                                     str(centerLon)))
                    request = QNetworkRequest(url)
                    reply = QgsNetworkAccessManager.instance().get(request)
                    loop = QEventLoop()
                    reply.finished.connect(loop.quit)
                    loop.exec_()
                    reply.finished.disconnect(loop.quit)
                    loop = None
                    result = reply.readAll()
                    data = json.loads(result.data())

                    if "village" in data["address"] and "state" in data[
                            "address"]:
                        loc = data["address"]["village"] + \
                            ", " + data["address"]["state"]
                    elif "town" in data["address"] and "state" in data[
                            "address"]:
                        loc = data["address"]["town"] + \
                            ", " + data["address"]["state"]
                    else:
                        loc = data["display_name"]

                except Exception:
                    qgsu.showUserAndLogMessage(
                        "",
                        "getVideoLocationInfo: failed to get address from reverse geocoding service.",
                        onlyLog=True)

            location = [centerLat, centerLon, loc]

            qgsu.showUserAndLogMessage("",
                                       "Got Location: lon: " + str(centerLon) +
                                       " lat: " + str(centerLat) +
                                       " location: " + str(loc),
                                       onlyLog=True)

            break
        else:

            qgsu.showUserAndLogMessage(
                QCoreApplication.translate(
                    "QgsFmvUtils", "This video doesn't have Metadata ! : "))

    except Exception as e:
        qgsu.showUserAndLogMessage(
            QCoreApplication.translate("QgsFmvUtils",
                                       "Video info callback failed! : "),
            str(e))

    return location
Example #33
0
    def xmlDownloaded(self):
        """ populate the plugins object with the fetched data """
        reply = self.sender()
        reposName = reply.property('reposName')
        if reply.error() != QNetworkReply.NoError:  # fetching failed
            self.mRepositories[reposName]["state"] = 3
            self.mRepositories[reposName]["error"] = reply.errorString()
            if reply.error() == QNetworkReply.OperationCanceledError:
                self.mRepositories[reposName][
                    "error"] += "\n\n" + QCoreApplication.translate(
                        "QgsPluginInstaller",
                        "If you haven't canceled the download manually, it was most likely caused by a timeout. In this case consider increasing the connection timeout value in QGIS options window."
                    )
        elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 301:
            redirectionUrl = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)
            if redirectionUrl.isRelative():
                redirectionUrl = reply.url().resolved(redirectionUrl)
            redirectionCounter = reply.property('redirectionCounter') + 1
            if redirectionCounter > 4:
                self.mRepositories[reposName]["state"] = 3
                self.mRepositories[reposName][
                    "error"] = QCoreApplication.translate(
                        "QgsPluginInstaller", "Too many redirections")
            else:
                # Fire a new request and exit immediately in order to quietly destroy the old one
                self.requestFetching(reposName, redirectionUrl,
                                     redirectionCounter)
                reply.deleteLater()
                return
        else:
            reposXML = QDomDocument()
            content = reply.readAll()
            # Fix lonely ampersands in metadata
            a = QByteArray()
            a.append("& ")
            b = QByteArray()
            b.append("&amp; ")
            content = content.replace(a, b)
            reposXML.setContent(content)
            pluginNodes = reposXML.elementsByTagName("pyqgis_plugin")
            if pluginNodes.size():
                for i in range(pluginNodes.size()):
                    fileName = pluginNodes.item(i).firstChildElement(
                        "file_name").text().strip()
                    if not fileName:
                        fileName = QFileInfo(
                            pluginNodes.item(i).firstChildElement(
                                "download_url").text().strip().split("?")
                            [0]).fileName()
                    name = fileName.partition(".")[0]
                    experimental = False
                    if pluginNodes.item(i).firstChildElement(
                            "experimental").text().strip().upper() in [
                                "TRUE", "YES"
                            ]:
                        experimental = True
                    deprecated = False
                    if pluginNodes.item(i).firstChildElement(
                            "deprecated").text().strip().upper() in [
                                "TRUE", "YES"
                            ]:
                        deprecated = True
                    trusted = False
                    if pluginNodes.item(i).firstChildElement(
                            "trusted").text().strip().upper() in [
                                "TRUE", "YES"
                            ]:
                        trusted = True
                    icon = pluginNodes.item(i).firstChildElement(
                        "icon").text().strip()
                    if icon and not icon.startswith("http"):
                        icon = "http://{}/{}".format(
                            QUrl(self.mRepositories[reposName]["url"]).host(),
                            icon)

                    if pluginNodes.item(i).toElement().hasAttribute(
                            "plugin_id"):
                        plugin_id = pluginNodes.item(i).toElement().attribute(
                            "plugin_id")
                    else:
                        plugin_id = None

                    plugin = {
                        "id":
                        name,
                        "plugin_id":
                        plugin_id,
                        "name":
                        pluginNodes.item(i).toElement().attribute("name"),
                        "version_available":
                        pluginNodes.item(i).toElement().attribute("version"),
                        "description":
                        pluginNodes.item(i).firstChildElement(
                            "description").text().strip(),
                        "about":
                        pluginNodes.item(i).firstChildElement(
                            "about").text().strip(),
                        "author_name":
                        pluginNodes.item(i).firstChildElement(
                            "author_name").text().strip(),
                        "homepage":
                        pluginNodes.item(i).firstChildElement(
                            "homepage").text().strip(),
                        "download_url":
                        pluginNodes.item(i).firstChildElement(
                            "download_url").text().strip(),
                        "category":
                        pluginNodes.item(i).firstChildElement(
                            "category").text().strip(),
                        "tags":
                        pluginNodes.item(i).firstChildElement(
                            "tags").text().strip(),
                        "changelog":
                        pluginNodes.item(i).firstChildElement(
                            "changelog").text().strip(),
                        "author_email":
                        pluginNodes.item(i).firstChildElement(
                            "author_email").text().strip(),
                        "tracker":
                        pluginNodes.item(i).firstChildElement(
                            "tracker").text().strip(),
                        "code_repository":
                        pluginNodes.item(i).firstChildElement(
                            "repository").text().strip(),
                        "downloads":
                        pluginNodes.item(i).firstChildElement(
                            "downloads").text().strip(),
                        "average_vote":
                        pluginNodes.item(i).firstChildElement(
                            "average_vote").text().strip(),
                        "rating_votes":
                        pluginNodes.item(i).firstChildElement(
                            "rating_votes").text().strip(),
                        "icon":
                        icon,
                        "experimental":
                        experimental,
                        "deprecated":
                        deprecated,
                        "trusted":
                        trusted,
                        "filename":
                        fileName,
                        "installed":
                        False,
                        "available":
                        True,
                        "status":
                        "not installed",
                        "error":
                        "",
                        "error_details":
                        "",
                        "version_installed":
                        "",
                        "zip_repository":
                        reposName,
                        "library":
                        "",
                        "readonly":
                        False,
                        "plugin_dependencies":
                        pluginNodes.item(i).firstChildElement(
                            "plugin_dependencies").text().strip(),
                    }
                    qgisMinimumVersion = pluginNodes.item(i).firstChildElement(
                        "qgis_minimum_version").text().strip()
                    if not qgisMinimumVersion:
                        qgisMinimumVersion = "2"
                    qgisMaximumVersion = pluginNodes.item(i).firstChildElement(
                        "qgis_maximum_version").text().strip()
                    if not qgisMaximumVersion:
                        qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
                    # if compatible, add the plugin to the list
                    if not pluginNodes.item(i).firstChildElement(
                            "disabled").text().strip().upper() in [
                                "TRUE", "YES"
                            ]:
                        if isCompatible(pyQgisVersion(), qgisMinimumVersion,
                                        qgisMaximumVersion):
                            # add the plugin to the cache
                            plugins.addFromRepository(plugin)
                self.mRepositories[reposName]["state"] = 2
            else:
                # no plugin metadata found
                self.mRepositories[reposName]["state"] = 3
                if reply.attribute(
                        QNetworkRequest.HttpStatusCodeAttribute) == 200:
                    self.mRepositories[reposName][
                        "error"] = QCoreApplication.translate(
                            "QgsPluginInstaller",
                            "Server response is 200 OK, but doesn't contain plugin metatada. This is most likely caused by a proxy or a wrong repository URL. You can configure proxy settings in QGIS options."
                        )
                else:
                    self.mRepositories[reposName][
                        "error"] = QCoreApplication.translate(
                            "QgsPluginInstaller",
                            "Status code:") + " {} {}".format(
                                reply.attribute(
                                    QNetworkRequest.HttpStatusCodeAttribute),
                                reply.attribute(
                                    QNetworkRequest.HttpReasonPhraseAttribute))

        self.repositoryFetched.emit(reposName)

        # is the checking done?
        if not self.fetchingInProgress():
            self.checkingDone.emit()

        reply.deleteLater()
 def helpUrl(self):
     file = os.path.dirname(__file__) + '/index.html'
     if not os.path.exists(file):
         return ''
     return QUrl.fromLocalFile(file).toString(QUrl.FullyEncoded)
Example #35
0
 def test_requestUrl(self):
     """Test url"""
     request = QgsServerRequest('http://somesite.com/somepath', QgsServerRequest.GetMethod)
     self.assertEqual(request.url().toString(), 'http://somesite.com/somepath')
     request.setUrl(QUrl('http://someother.com/someotherpath'))
     self.assertEqual(request.url().toString(), 'http://someother.com/someotherpath')
Example #36
0
 def updateDescription(self, current, previous):
     if isinstance(current, TreeResultItem):
         html = '<b>Algorithm</b>: {}<br><b>File path</b>: <a href="{}">{}</a>'.format(current.algorithm, QUrl.fromLocalFile(current.filename).toString(), QDir.toNativeSeparators(current.filename))
         self.txtDescription.setHtml(html)
Example #37
0
 def openResult(self, item, column):
     QDesktopServices.openUrl(QUrl.fromLocalFile(item.filename))
Example #38
0
    def saveModel(self, saveAs):
        if not self.can_save():
            return
        self.model.setName(str(self.textName.text()))
        self.model.setGroup(str(self.textGroup.text()))
        if self.model.sourceFilePath() and not saveAs:
            filename = self.model.sourceFilePath()
        else:
            filename, filter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model'),
                                                           ModelerUtils.modelsFolders()[0],
                                                           self.tr('Processing models (*.model3 *.MODEL3)'))
            if filename:
                if not filename.endswith('.model3'):
                    filename += '.model3'
                self.model.setSourceFilePath(filename)
        if filename:
            if not self.model.toFile(filename):
                if saveAs:
                    QMessageBox.warning(self, self.tr('I/O error'),
                                        self.tr('Unable to save edits. Reason:\n {0}').format(str(sys.exc_info()[1])))
                else:
                    QMessageBox.warning(self, self.tr("Can't save model"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', (
                        "This model can't be saved in its original location (probably you do not "
                        "have permission to do it). Please, use the 'Save as…' option."))
                    )
                return
            self.update_model.emit()
            if saveAs:
                self.bar.pushMessage("", self.tr("Model was correctly saved to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
            else:
                self.bar.pushMessage("", self.tr("Model was correctly saved"), level=Qgis.Success, duration=5)

            self.hasChanged = False
 def help(self):
     '''Display a help page'''
     url = QUrl.fromLocalFile(os.path.dirname(__file__) + "/index.html").toString()
     webbrowser.open(url, new=2)
Example #40
0
    def exportAsPython(self):
        filename, filter = QFileDialog.getSaveFileName(self,
                                                       self.tr('Save Model As Python Script'), '',
                                                       self.tr('Processing scripts (*.py *.PY)'))
        if not filename:
            return

        if not filename.lower().endswith('.py'):
            filename += '.py'

        text = self.model.asPythonCode()
        with codecs.open(filename, 'w', encoding='utf-8') as fout:
            fout.write(text)

        self.bar.pushMessage("", self.tr("Successfully exported model as python script to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
Example #41
0
    def exportAsSvg(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As SVG'), '',
                                                           self.tr('SVG files (*.svg *.SVG)'))
        if not filename:
            return

        if not filename.lower().endswith('.svg'):
            filename += '.svg'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        svgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        svg = QSvgGenerator()
        svg.setFileName(filename)
        svg.setSize(QSize(totalRect.width(), totalRect.height()))
        svg.setViewBox(svgRect)
        svg.setTitle(self.model.displayName())

        painter = QPainter(svg)
        self.scene.render(painter, svgRect, totalRect)
        painter.end()

        self.bar.pushMessage("", self.tr("Successfully exported model as SVG to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)
    def run(self):
        """Run method that performs all the real work"""

        # print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())

        # init run variable
        # self.canvas = QgsMapCanvas()

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.previewLayer = 0
            self.currentCheckLayer = [0, 0]
            self.first_start = False
            self.dlg = SimilarityPluginDialog()
            # self.dlg.setPKBtn.setVisible(False)
            self.simpleDialog = SimpleWarnDialog()
            # self.pkSelector = PkSelector()
            # set help documentation
            self.dlg.helpTextBrowser.load(
                QUrl(
                    'https://github.com/panickspa/SimilarityPlugin/wiki/User-Guide'
                ))
            self.dlg.nextHelpBtn.clicked.connect(
                self.dlg.helpTextBrowser.forward)
            self.dlg.previousHelpBtn.clicked.connect(
                self.dlg.helpTextBrowser.back)
            # filtering selection layer (empty layer not allowed)
            self.dlg.layerSel1.setAllowEmptyLayer(False)
            self.dlg.layerSel1.setAllowEmptyLayer(False)

            # self.pkSelector.okPushButton.clicked.connect(self.pkSelectorAccepted)
            # self.dlg.setPKBtn.clicked.connect(self.pkSelector.open)
            # method combobox initialiazation
            self.dlg.methodComboBox.clear()
            self.dlg.methodComboBox.addItems(
                ['Squential', 'Nearest Neightbour', 'Wilkerstat BPS'])

            # registering signal

            self.dlg.methodComboBox.currentIndexChanged.connect(
                self.methodChange)
            self.dlg.nextBtn.clicked.connect(self.nextPreview)
            self.dlg.previousBtn.clicked.connect(self.previousPreview)
            self.dlg.calcBtn.clicked.connect(self.calculateScore)
            self.dlg.saveBtn.clicked.connect(self.registerToProject)
            self.dlg.removeBtn.clicked.connect(self.rmWarn)
            self.dlg.stopBtn.clicked.connect(self.stopCalcThread)

            # intialize pan tool
            panTool = QgsMapToolPan(self.dlg.widgetCanvas)
            # set signal
            panTool.setAction(self.actionPan)
            # set map tool
            self.dlg.widgetCanvas.setMapTool(panTool)
            # set pan tool to be activate
            panTool.activate()

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            self.similarLayer = []
            self.dlg.widgetCanvas.setLayers([
                QgsVectorLayer("Polygon?crs=ESPG:4326", 'SimilarityLayer',
                               'memory')
            ])
            self.dlg.previewAttr.setText("")
            self.dlg.previewAttr_2.setText("")
            self.dlg.widgetCanvas.refresh()
            scoreLabel = "Score : 0"
            self.dlg.labelScore.setText(scoreLabel)
Example #43
0
    def exportAsImage(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As Image'), '',
                                                           self.tr('PNG files (*.png *.PNG)'))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        imgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, imgRect, totalRect)
        painter.end()

        img.save(filename)

        self.bar.pushMessage("", self.tr("Successfully exported model as image to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)
def strToUrl(s):
    return QUrl.fromEncoded(bytes(s, "utf8"))
    def setupUi(self):
        self.labels = {}
        self.widgets = {}
        self.checkBoxes = {}
        self.showAdvanced = False
        self.wrappers = {}
        self.valueItems = {}
        self.dependentItems = {}
        self.resize(650, 450)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        tooltips = self._alg.getParameterDescriptions()
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setMargin(20)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.verticalLayout.addWidget(self.bar)

        hLayout = QHBoxLayout()
        hLayout.setSpacing(5)
        hLayout.setMargin(0)
        descriptionLabel = QLabel(self.tr("Description"))
        self.descriptionBox = QLineEdit()
        self.descriptionBox.setText(self._alg.name)
        hLayout.addWidget(descriptionLabel)
        hLayout.addWidget(self.descriptionBox)
        self.verticalLayout.addLayout(hLayout)
        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.verticalLayout.addWidget(line)

        for param in self._alg.parameters:
            if param.isAdvanced:
                self.advancedButton = QPushButton()
                self.advancedButton.setText(
                    self.tr('Show advanced parameters'))
                self.advancedButton.clicked.connect(
                    self.showAdvancedParametersClicked)
                advancedButtonHLayout = QHBoxLayout()
                advancedButtonHLayout.addWidget(self.advancedButton)
                advancedButtonHLayout.addStretch()
                self.verticalLayout.addLayout(advancedButtonHLayout)
                break
        for param in self._alg.parameters:
            if param.hidden:
                continue
            desc = param.description
            if isinstance(param, ParameterExtent):
                desc += self.tr('(xmin, xmax, ymin, ymax)')
            if isinstance(param, ParameterPoint):
                desc += self.tr('(x, y)')
            if param.optional:
                desc += self.tr(' [optional]')
            label = QLabel(desc)
            self.labels[param.name] = label

            wrapper = param.wrapper(self)
            self.wrappers[param.name] = wrapper

            widget = wrapper.widget
            if widget is not None:
                self.valueItems[param.name] = widget
                if param.name in list(tooltips.keys()):
                    tooltip = tooltips[param.name]
                else:
                    tooltip = param.description
                label.setToolTip(tooltip)
                widget.setToolTip(tooltip)
                if param.isAdvanced:
                    label.setVisible(self.showAdvanced)
                    widget.setVisible(self.showAdvanced)
                    self.widgets[param.name] = widget

                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(widget)

        for output in self._alg.outputs:
            if output.hidden:
                continue
            if isinstance(output, (OutputRaster, OutputVector, OutputTable,
                                   OutputHTML, OutputFile, OutputDirectory)):
                label = QLabel(output.description + '<' +
                               output.__class__.__name__ + '>')
                item = QLineEdit()
                if hasattr(item, 'setPlaceholderText'):
                    item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME)
                self.verticalLayout.addWidget(label)
                self.verticalLayout.addWidget(item)
                self.valueItems[output.name] = item

        label = QLabel(' ')
        self.verticalLayout.addWidget(label)
        label = QLabel(self.tr('Parent algorithms'))
        self.dependenciesPanel = self.getDependenciesPanel()
        self.verticalLayout.addWidget(label)
        self.verticalLayout.addWidget(self.dependenciesPanel)
        self.verticalLayout.addStretch(1000)

        self.setPreviousValues()
        self.setWindowTitle(self._alg.name)
        self.verticalLayout2 = QVBoxLayout()
        self.verticalLayout2.setSpacing(2)
        self.verticalLayout2.setMargin(0)
        self.tabWidget = QTabWidget()
        self.tabWidget.setMinimumWidth(300)
        self.paramPanel = QWidget()
        self.paramPanel.setLayout(self.verticalLayout)
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(self.paramPanel)
        self.scrollArea.setWidgetResizable(True)
        self.tabWidget.addTab(self.scrollArea, self.tr('Parameters'))

        self.txtHelp = QTextBrowser()

        html = None
        isText, algHelp = self._alg.help()
        if algHelp is not None:
            algHelp = algHelp if isText else QUrl(algHelp)
            try:
                if isText:
                    self.txtHelp.setHtml(algHelp)
                else:
                    html = self.tr(
                        '<p>Downloading algorithm help... Please wait.</p>')
                    self.txtHelp.setHtml(html)
                    self.tabWidget.addTab(self.txtHelp, 'Help')
                    self.reply = QgsNetworkAccessManager.instance().get(
                        QNetworkRequest(algHelp))
                    self.reply.finished.connect(self.requestFinished)
            except:
                pass

        self.verticalLayout2.addWidget(self.tabWidget)
        self.verticalLayout2.addWidget(self.buttonBox)
        self.setLayout(self.verticalLayout2)
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)
        QMetaObject.connectSlotsByName(self)

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
Example #46
0
    def __init__(self, alg):
        super(AlgorithmDialogBase, self).__init__(iface.mainWindow())
        self.setupUi(self)

        self.settings = QSettings()
        self.restoreGeometry(
            self.settings.value("/Processing/dialogBase", QByteArray()))

        self.executed = False
        self.mainWidget = None
        self.alg = alg

        # Rename OK button to Run
        self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok)
        self.btnRun.setText(self.tr('Run'))

        self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)

        self.setWindowTitle(AlgorithmClassification.getDisplayName(self.alg))

        desktop = QDesktopWidget()
        if desktop.physicalDpiX() > 96:
            self.textHelp.setZoomFactor(desktop.physicalDpiX() / 96)

        algHelp = self.alg.shortHelp()
        if algHelp is None:
            self.textShortHelp.setVisible(False)
        else:
            self.textShortHelp.document().setDefaultStyleSheet(
                '''.summary { margin-left: 10px; margin-right: 10px; }
                                                    h2 { color: #555555; padding-bottom: 15px; }
                                                    a { text-decoration: none; color: #3498db; font-weight: bold; }
                                                    p { color: #666666; }
                                                    b { color: #333333; }
                                                    dl dd { margin-bottom: 5px; }'''
            )
            self.textShortHelp.setHtml(algHelp)

        self.textShortHelp.setOpenLinks(False)

        def linkClicked(url):
            webbrowser.open(url.toString())

        self.textShortHelp.anchorClicked.connect(linkClicked)

        self.textHelp.page().setNetworkAccessManager(
            QgsNetworkAccessManager.instance())

        isText, algHelp = self.alg.help()
        if algHelp is not None:
            algHelp = algHelp if isText else QUrl(algHelp)
            try:
                if isText:
                    self.textHelp.setHtml(algHelp)
                else:
                    self.textHelp.settings().clearMemoryCaches()
                    self.textHelp.load(algHelp)
            except:
                self.tabWidget.removeTab(2)
        else:
            self.tabWidget.removeTab(2)

        self.showDebug = ProcessingConfig.getSetting(
            ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
 def get_root_help(self):
     """
     home button set the default help page
     """
     self.webBrowser.load(QUrl(self.help_file))
Example #48
0
    def addDroppedDocument(self, fileUrl):

        if self.checkLayerEditingMode() is False:
            return

        # Workaround because of QGIS not resetting this property after linking features
        self.editorContext().vectorLayerTools().setForceSuppressFormPopup(
            False)

        layer = self.relation().referencingLayer()
        if self.nmRelation().isValid():
            layer = self.nmRelation().referencedLayer()

        default_documents_path = str()
        if self.documents_path:
            exp = QgsExpression(self.documents_path)
            context = QgsExpressionContext()
            context.appendScopes(
                QgsExpressionContextUtils.globalProjectLayerScopes(layer))
            default_documents_path = str(exp.evaluate(context))

        filename = QUrl(fileUrl).toLocalFile()
        if default_documents_path:
            filename = QDir(default_documents_path).relativeFilePath(filename)

        keyAttrs = dict()

        # Fields of the linking table
        fields = self.relation().referencingLayer().fields()

        # For generated relations insert the referenced layer field
        if self.relation().type() == QgsRelation.Generated:
            polyRel = self.relation().polymorphicRelation()
            keyAttrs[fields.indexFromName(
                polyRel.referencedLayerField())] = polyRel.layerRepresentation(
                    self.relation().referencedLayer())

        if self.nmRelation().isValid():
            # only normal relations support m:n relation
            if self.nmRelation().type() != QgsRelation.Normal:
                QMessageBox.critical(
                    self, self.tr("Add document"),
                    self.
                    tr("Invalid relation, Only normal relations support m:n relation."
                       ))
                return

            # Pre fill inserting document filepath
            attributes = {
                self.nmRelation().referencedLayer().fields().indexFromName(self.document_filename):
                filename
            }

            # n:m Relation: first let the user create a new feature on the other table
            # and autocreate a new linking feature.
            ok, feature = self.editorContext().vectorLayerTools().addFeature(
                self.nmRelation().referencedLayer(), attributes, QgsGeometry())
            if not ok:
                QMessageBox.critical(
                    self, self.tr("Add document"),
                    self.tr("Could not add a new linking feature."))
                return

            for key in self.relation().fieldPairs():
                keyAttrs[fields.indexOf(key)] = self.feature().attribute(
                    self.relation().fieldPairs()[key])

            for key in self.nmRelation().fieldPairs():
                keyAttrs[fields.indexOf(key)] = feature.attribute(
                    self.nmRelation().fieldPairs()[key])

            linkFeature = QgsVectorLayerUtils.createFeature(
                self.relation().referencingLayer(), QgsGeometry(), keyAttrs,
                self.relation().referencingLayer().createExpressionContext())

            if not self.relation().referencingLayer().addFeature(linkFeature):
                QMessageBox.critical(self, self.tr("Add document"),
                                     self.tr("Could not add a new feature."))
                return

        else:
            for key in self.relation().fieldPairs():
                keyAttrs[fields.indexFromName(key)] = self.feature().attribute(
                    self.relation().fieldPairs()[key])

            # Pre fill inserting document filepath
            keyAttrs[fields] = filename

            ok, feature = self.editorContext().vectorLayerTools().addFeature(
                self.relation().referencingLayer(), keyAttrs, QgsGeometry())
            if not ok:
                QMessageBox.critical(self, self.tr("Add document"),
                                     self.tr("Could not add a new feature."))
                return

        self.updateUi()
    def request(self,
                url,
                method="GET",
                body=None,
                headers=None,
                redirections=DEFAULT_MAX_REDIRECTS,
                connection_type=None,
                blocking=True):
        """
        Make a network request by calling QgsNetworkAccessManager.
        redirections argument is ignored and is here only for httplib2 compatibility.
        """
        self.msg_log(u'http_call request: {0}'.format(url))

        self.blocking_mode = blocking
        req = QNetworkRequest()
        # Avoid double quoting form QUrl
        url = urllib.parse.unquote(url)
        req.setUrl(QUrl(url))
        if headers is not None:
            # This fixes a wierd error with compressed content not being correctly
            # inflated.
            # If you set the header on the QNetworkRequest you are basically telling
            # QNetworkAccessManager "I know what I'm doing, please don't do any content
            # encoding processing".
            # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1
            try:
                del headers['Accept-Encoding']
            except KeyError:
                pass
            for k, v in list(headers.items()):
                self.msg_log("Setting header %s to %s" % (k, v))
                req.setRawHeader(k, v)
        if self.authid:
            self.msg_log("Update request w/ authid: {0}".format(self.authid))
            QgsAuthManager.instance().updateNetworkRequest(req, self.authid)
        if self.reply is not None and self.reply.isRunning():
            self.reply.close()
        if method.lower() == 'delete':
            func = getattr(QgsNetworkAccessManager.instance(),
                           'deleteResource')
        else:
            func = getattr(QgsNetworkAccessManager.instance(), method.lower())
        # Calling the server ...
        # Let's log the whole call for debugging purposes:
        self.msg_log("Sending %s request to %s" %
                     (method.upper(), req.url().toString()))
        self.on_abort = False
        headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()}
        for k, v in list(headers.items()):
            self.msg_log("%s: %s" % (k, v))
        if method.lower() in ['post', 'put']:
            if isinstance(body, file):
                body = body.read()
            self.reply = func(req, body)
        else:
            self.reply = func(req)
        if self.authid:
            self.msg_log("Update reply w/ authid: {0}".format(self.authid))
            QgsAuthManager.instance().updateNetworkReply(
                self.reply, self.authid)

        # necessary to trap local timout manage by QgsNetworkAccessManager
        # calling QgsNetworkAccessManager::abortRequest
        QgsNetworkAccessManager.instance().requestTimedOut.connect(
            self.requestTimedOut)

        self.reply.sslErrors.connect(self.sslErrors)
        self.reply.finished.connect(self.replyFinished)
        self.reply.downloadProgress.connect(self.downloadProgress)

        # block if blocking mode otherwise return immediatly
        # it's up to the caller to manage listeners in case of no blocking mode
        if not self.blocking_mode:
            return (None, None)

        # Call and block
        self.el = QEventLoop()
        self.reply.finished.connect(self.el.quit)

        # Catch all exceptions (and clean up requests)
        try:
            self.el.exec_(QEventLoop.ExcludeUserInputEvents)
        except Exception as e:
            raise e

        if self.reply:
            self.reply.finished.disconnect(self.el.quit)

        # emit exception in case of error
        if not self.http_call_result.ok:
            if self.http_call_result.exception and not self.exception_class:
                raise self.http_call_result.exception
            else:
                raise self.exception_class(self.http_call_result.reason)

        return (self.http_call_result, self.http_call_result.content)
Example #50
0
    def __init__(self, config, parent):
        super().__init__(config, parent)
        self._updateUiTimer = QTimer()
        self._updateUiTimer.setSingleShot(True)
        self._updateUiTimer.timeout.connect(self.updateUiTimeout)
        self.setupUi(self)

        print('DocumentRelationEditorFeatureSideWidget.__init__')

        self.documents_path = str()
        self.document_filename = str()

        self.model = DocumentModel()

        self._nmRelation = QgsRelation()
        self._layerInSameTransactionGroup = False

        self._currentDocumentId = None

        # Actions
        self.actionToggleEditing = QAction(
            QIcon(":/images/themes/default/mActionToggleEditing.svg"),
            self.tr("Toggle editing mode for child layers"))
        self.actionToggleEditing.setCheckable(True)
        self.actionSaveEdits = QAction(
            QIcon(":/images/themes/default/mActionSaveEdits.svg"),
            self.tr("Save child layer edits"))
        self.actionShowForm = QAction(
            QIcon(":/images/themes/default/mActionMultiEdit.svg"),
            self.tr("Show form"))
        self.actionAddFeature = QAction(
            QIcon(":/images/themes/default/symbologyAdd.svg"),
            self.tr("Add document"))
        self.actionDeleteFeature = QAction(
            QIcon(":/images/themes/default/mActionDeleteSelected.svg"),
            self.tr("Drop document"))
        self.actionLinkFeature = QAction(
            QIcon(":/images/themes/default/mActionLink.svg"),
            self.tr("Link document"))
        self.actionUnlinkFeature = QAction(
            QIcon(":/images/themes/default/mActionUnlink.svg"),
            self.tr("Unlink document"))

        # Tool buttons
        self.mToggleEditingToolButton.setDefaultAction(
            self.actionToggleEditing)
        self.mSaveEditsToolButton.setDefaultAction(self.actionSaveEdits)
        self.mShowFormToolButton.setDefaultAction(self.actionShowForm)
        self.mAddFeatureToolButton.setDefaultAction(self.actionAddFeature)
        self.mDeleteFeatureToolButton.setDefaultAction(
            self.actionDeleteFeature)
        self.mLinkFeatureToolButton.setDefaultAction(self.actionLinkFeature)
        self.mUnlinkFeatureToolButton.setDefaultAction(
            self.actionUnlinkFeature)

        self.mListViewToolButton.setIcon(
            QIcon(":/images/themes/default/mIconListView.svg"))
        self.mIconViewToolButton.setIcon(
            QIcon(":/images/themes/default/mActionIconView.svg"))
        self.mListViewToolButton.setChecked(self.currentView == str(
            RelationEditorFeatureSideWidget.LastView.ListView))
        self.mIconViewToolButton.setChecked(self.currentView == str(
            RelationEditorFeatureSideWidget.LastView.IconView))

        # Quick image providers
        self._previewImageProvider = PreviewImageProvider()
        self._fileTypeSmallIconProvider = FileTypeIconImageProvider(32)
        self._fileTypeBigIconProvider = FileTypeIconImageProvider(100)

        # Setup QML part
        self.view = QQuickWidget()
        self.view.rootContext().setContextProperty("documentModel", self.model)
        self.view.rootContext().setContextProperty("parentWidget", self)
        self.view.rootContext().setContextProperty(
            "CONST_LIST_VIEW",
            str(RelationEditorFeatureSideWidget.LastView.ListView))
        self.view.rootContext().setContextProperty(
            "CONST_ICON_VIEW",
            str(RelationEditorFeatureSideWidget.LastView.IconView))
        self.view.engine().addImageProvider("previewImageProvider",
                                            self._previewImageProvider)
        self.view.engine().addImageProvider("fileTypeSmallIconProvider",
                                            self._fileTypeSmallIconProvider)
        self.view.engine().addImageProvider("fileTypeBigIconProvider",
                                            self._fileTypeBigIconProvider)
        self.view.setSource(
            QUrl.fromLocalFile(
                os.path.join(os.path.dirname(__file__),
                             '../qml/DocumentList.qml')))
        self.view.setResizeMode(QQuickWidget.SizeRootObjectToView)
        self.layout().addWidget(self.view)

        # Set initial state for add / remove etc.buttons
        self.updateButtons()

        # Signal slots
        self.actionToggleEditing.triggered.connect(self.toggleEditing)
        self.actionSaveEdits.triggered.connect(self.saveChildLayerEdits)
        self.actionShowForm.triggered.connect(self.showDocumentForm)
        self.actionAddFeature.triggered.connect(self.addDocument)
        self.actionDeleteFeature.triggered.connect(self.dropDocument)
        self.actionLinkFeature.triggered.connect(self.linkDocument)
        self.actionUnlinkFeature.triggered.connect(self.unlinkDocument)
        self.mListViewToolButton.toggled.connect(
            self.listViewToolButtonToggled)
        self.mIconViewToolButton.toggled.connect(
            self.iconViewToolButtonToggled)
Example #51
0
 def loadUrl(self, url):
     self.dockwidget.webView.setUrl(QUrl((url)))
Example #52
0
 def fromLocalFile(cls, filename):
     return cls(QUrl.fromLocalFile(filename))
Example #53
0
 def on_help(self):
     QDesktopServices.openUrl(QUrl("https://github.com/aeag/mask/wiki"))
Example #54
0
def toPercent(s):
    return bytes(QUrl.toPercentEncoding(s)).decode()
 def open_help(self):
     """Open help."""
     doc_url = QUrl('http://qgis-contribution.github.io/' +
                    'QGIS-ResourceSharing/')
     QDesktopServices.openUrl(doc_url)
 def htmlUrl(self):
     """Helper to get the url of the html doc."""
     myPath = os.path.join(TEST_DATA_DIR, "test_html.html")
     myUrl = QUrl("file:///" + myPath)
     return myUrl
 def open_collection(self):
     """Slot called when the user clicks the 'Open' button."""
     collection_path = local_collection_path(self._sel_coll_id)
     directory_url = QUrl.fromLocalFile(str(collection_path))
     QDesktopServices.openUrl(directory_url)
Example #58
0
 def on_set_example_btn_clicked(self):
     qurl = QUrl(self.example_url.text())
     self.web_view.load(qurl)
Example #59
0
    def exportAsPdf(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As PDF'), '',
                                                           self.tr('PDF files (*.pdf *.PDF)'))
        if not filename:
            return

        if not filename.lower().endswith('.pdf'):
            filename += '.pdf'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(filename)
        printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel)
        printer.setFullPage(True)

        painter = QPainter(printer)
        self.scene.render(painter, printerRect, totalRect)
        painter.end()

        self.bar.pushMessage("", self.tr("Successfully exported model as PDF to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)
def strToUrl(s):
    if sys.version_info.major == 3:
        return QUrl.fromEncoded(bytes(s, "utf8"))
    else:
        return QUrl.fromEncoded(s)