예제 #1
0
    def testSingleTileEncode(self):
        """ Test vector tile encoding from python
        """
        vlPoints = QgsVectorLayer(str(TEST_DATA_PATH / "points.shp"), "points", "ogr")
        vlLines = QgsVectorLayer(str(TEST_DATA_PATH / "lines.shp"), "lines", "ogr")
        vlPolys = QgsVectorLayer(str(TEST_DATA_PATH / "polys.shp"), "polys", "ogr")

        layers = [QgsVectorTileWriter.Layer(vl) for vl in (vlPoints, vlLines, vlPolys)]

        writer = QgsVectorTileWriter()
        writer.setMaxZoom(3)
        writer.setLayers(layers)

        data = writer.writeSingleTile(QgsTileXYZ(0, 0, 0))

        ds = QgsDataSourceUri()
        ds.setParam("type", "xyz")
        ds.setParam("url", (self.tempdir / "{z}-{x}-{y}.pbf").as_uri())

        # Create pbf files
        writer.setDestinationUri(ds.encodedUri().data().decode())
        res = writer.writeTiles()
        self.assertEqual(writer.errorMessage(), "")
        self.assertTrue(res)

        # Compare encoded data to written file
        # Read data from file
        with (self.tempdir / "0-0-0.pbf").open("rb") as fp:
            output = fp.read()

        # Compare binary data
        self.assertEqual(ascii(data.data()), ascii(output))
예제 #2
0
    def testCreateLayer(self):
        # create vector
        options = QgsMapLayerFactory.LayerOptions(
            QgsCoordinateTransformContext())
        ml = QgsMapLayerFactory.createLayer(
            os.path.join(unitTestDataPath(), 'lines.shp'), 'lines',
            QgsMapLayerType.VectorLayer, options, 'ogr')
        self.assertTrue(ml.isValid())
        self.assertIsInstance(ml, QgsVectorLayer)
        self.assertEqual(ml.name(), 'lines')

        # create raster
        ml = QgsMapLayerFactory.createLayer(
            os.path.join(unitTestDataPath(), 'landsat.tif'), 'rl',
            QgsMapLayerType.RasterLayer, options, 'gdal')
        self.assertTrue(ml.isValid())
        self.assertIsInstance(ml, QgsRasterLayer)
        self.assertEqual(ml.name(), 'rl')

        # create mesh
        ml = QgsMapLayerFactory.createLayer(
            os.path.join(unitTestDataPath(), 'mesh', 'lines.2dm'), 'ml',
            QgsMapLayerType.MeshLayer, options, 'mdal')
        self.assertTrue(ml.isValid())
        self.assertIsInstance(ml, QgsMeshLayer)
        self.assertEqual(ml.name(), 'ml')

        # create point cloud
        ml = QgsMapLayerFactory.createLayer(
            os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'rgb',
                         'ept.json'), 'pcl', QgsMapLayerType.PointCloudLayer,
            options, 'ept')
        self.assertTrue(ml.isValid())
        self.assertIsInstance(ml, QgsPointCloudLayer)
        self.assertEqual(ml.name(), 'pcl')

        # annotation layer
        ml = QgsMapLayerFactory.createLayer('', 'al',
                                            QgsMapLayerType.AnnotationLayer,
                                            options)
        self.assertTrue(ml.isValid())
        self.assertIsInstance(ml, QgsAnnotationLayer)
        self.assertEqual(ml.name(), 'al')

        # vector tile layer
        ds = QgsDataSourceUri()
        ds.setParam("type", "xyz")
        ds.setParam(
            "url", "file://{}/{{z}}-{{x}}-{{y}}.pbf".format(
                os.path.join(unitTestDataPath(), 'vector_tile')))
        ds.setParam("zmax", "1")
        ml = QgsMapLayerFactory.createLayer(ds.encodedUri().data().decode(),
                                            'vtl',
                                            QgsMapLayerType.VectorTileLayer,
                                            options)
        self.assertTrue(ml.isValid())
        self.assertIsInstance(ml, QgsVectorTileLayer)
        self.assertEqual(ml.name(), 'vtl')
 def getCoverageLayer(self):
     XYZuri = QgsDataSourceUri()
     XYZuri.setParam("type", "xyz")
     XYZuri.setParam('url', 'http://d2cd86j8eqns9s.cloudfront.net/tiles/{z}/{x}/{y}.png')
     XYZuri.setParam("zmin", "0")
     XYZuri.setParam("zmax", "15")
     layer = QgsRasterLayer(str(XYZuri.encodedUri()), 'Mapillary coverage', 'wms')
     self.coverageLayerId = layer.id()
     print (self.coverageLayerId)
     return layer
     '''
예제 #4
0
def render_wms_to_image(xyz=True, extent=EXTENT, width=64, height=60):
    """
    :type xyz: bool
    :type extent: tuple
    :type width: int
    :type height: int
    :rtype: QImage
    """
    # p = QgsProject.instance()
    # p = QgsProject()
    uri = QgsDataSourceUri()
    if xyz:
        uri.setParam('type', 'xyz')
        uri.setParam('crs', 'EPSG:3857')
        uri.setParam('format', '')
        # uri.setParam('zmin', '0')
        # uri.setParam('zmax', '18')
        uri.setParam('url', XYZ_URL)
    else:
        uri.setParam('tileMatrixSet', 'GoogleMapsCompatible23')
        uri.setParam('crs', 'EPSG:3857')
        uri.setParam('format', 'image/png')
        uri.setParam('styles', '')
        uri.setParam('layers', 'Combined scene layer')
        uri.setParam('url', WMS_URL)

    # Important to do this conversion, else WMS provider will double encode;
    #   instead of just `str(uri.encodedUri())`, which outputs "b'uri'"
    # This coerces QByteArray -> str ... assuming UTF-8 is valid.
    final_uri = bytes(uri.encodedUri()).decode("utf-8")
    layer = QgsRasterLayer(final_uri, "scene_layer", "wms")

    if not layer.isValid():
        print('Layer is not valid')
        return QImage()
    # p.addMapLayer(layer)

    settings = QgsMapSettings()
    settings.setExtent(QgsRectangle(*extent))
    settings.setOutputSize(QSize(width, height))
    settings.setLayers([layer])

    job = QgsMapRendererParallelJob(settings)
    job.start()

    # This blocks...
    # It should really be a QEventLoop or QTimer that checks for finished()
    # Any intermediate image can safely be pulled from renderedImage()
    job.waitForFinished()

    return job.renderedImage()
예제 #5
0
def _loadWcs():
    valid = {}
    urls = os.getenv(TEST_URLS).split(",")
    for url in urls:
        try:
            url = url.strip() + "/wcs"
            uri = QgsDataSourceUri()
            uri.setParam('url',url )
            uri.setParam("identifier", "testlayer")
            layer = QgsRasterLayer(str(uri.encodedUri()), 'testlayer', 'wcs')
            valid[url] = layer.isValid()
        except:
            valid[url] = False
    failed = [k for k,v in valid.items() if not v]
    if failed:
        raise AssertionError("Test failed for the following URLs: " + str(failed))
예제 #6
0
def _loadWcs():
    valid = {}
    urls = os.getenv(TEST_URLS).split(",")
    for url in urls:
        try:
            url = url.strip() + "/wcs"
            uri = QgsDataSourceUri()
            uri.setParam('url', url)
            uri.setParam("identifier", "testlayer")
            layer = QgsRasterLayer(str(uri.encodedUri()), 'testlayer', 'wcs')
            valid[url] = layer.isValid()
        except:
            valid[url] = False
    failed = [k for k, v in valid.items() if not v]
    if failed:
        raise AssertionError("Test failed for the following URLs: " +
                             str(failed))
예제 #7
0
def parse_uri(meta):
    uri = QgsDataSourceUri()
    uri.setParam("type", "xyz")
    for k, v in meta.items():
        uri.setParam(k, v)
    return bytes(uri.encodedUri()).decode("utf-8")
예제 #8
0
    def addWms(self, wms_name, url, layers, mime_type, epsg_code, protocol):
        """
            # Slot for exposing the same-name function to Javascript. #
            Adding the WMS to the QGis TOC.
            :param wms_name: The WMS name to add in TOC as group
            :type wms_name: str
            :param url: The WMS URL
            :type url: str
            :param layers: The list of the WMS layers to add
            :type layers: list of str
            :param mime_type: The image MIME TYPE (e.g. image/png)
            :type mime_type: str
            :param epsg_code: The EPSG code (e.g. the number 32632)
            :type epsg_code: int
            :param protocol: The protocol (i.e. should be 'ba' for applying basic authentication). Not yet managed.
            :type protocol: str
        """
        qgs_logger = QgsApplication.messageLog()
        qgs_logger.logMessage('addWms: wms_name = {}'.format(wms_name),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: url = {}'.format(url),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: layers = {}'.format(layers),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: mime_type = {}'.format(mime_type),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: epsg_code = {}'.format(epsg_code),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('addWms: protocol = {}'.format(protocol),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)

        # For storing the URI data
        uri = QgsDataSourceUri()

        # Split the host with the request data
        pieces = url.split("?")
        if len(pieces) == 1:
            qgs_logger.logMessage('len(pieces) == 1',
                                  tag=configuration.LOGGER_TAG,
                                  level=Qgis.Info)
        elif len(pieces) == 2:
            qgs_logger.logMessage('len(pieces) == 2',
                                  tag=configuration.LOGGER_TAG,
                                  level=Qgis.Info)
            # Overriding the URL
            url = "{}{}".format(pieces[0], "?")
            parameters_values = pieces[1].split("=")
            if len(parameters_values) == 2:
                qgs_logger.logMessage('len(parameters) == 2',
                                      tag=configuration.LOGGER_TAG,
                                      level=Qgis.Info)
                uri.setParam(parameters_values[0], parameters_values[1])
                qgs_logger.logMessage('uri.param({}): {}'.format(
                    parameters_values[0], uri.param(parameters_values[0])),
                                      tag=configuration.LOGGER_TAG,
                                      level=Qgis.Info)
            else:
                qgs_logger.logMessage('len(p) != 2',
                                      tag=configuration.LOGGER_TAG,
                                      level=Qgis.Info)
        else:
            qgs_logger.logMessage('len(pieces) > 2 Not yet managed!',
                                  tag=configuration.LOGGER_TAG,
                                  level=Qgis.Warning)

        # Setting the URL to the URI
        uri.setParam("url", url)

        # Process the layers accordingly if just an element or a list of elements
        layers_list = []
        if "," in layers:
            layers_list = layers.split(",")
        else:
            layers_list.append(layers)

        # Setting the parameter 'layers' in the URI
        for val in layers_list:
            uri.setParam("layers", val)

        # Setting the other parameters
        # Styles seems required: https://gis.stackexchange.com/questions/183485/load-wms-with-pyqgis
        uri.setParam("styles", "")
        uri.setParam("format", mime_type)
        uri.setParam("crs", "EPSG:{}".format(epsg_code))

        # https://docs.qgis.org/3.4/en/docs/pyqgis_developer_cookbook/loadlayer.html#raster-layers
        # Ignore GetCoverage URL advertised by GetCapabilities. May be necessary if a server is not configured properly.
        uri.setParam("IgnoreGetMapUrl", "1")

        # Adding the parameters for the basic authentication
        qgs_logger.logMessage('Applying Basic-Authentication',
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        uri.setParam("username", self.session_user)
        uri.setParam("password", self.session_password)

        # Logging the parameters for debugging
        qgs_logger.logMessage('uri.param(url): {}'.format(uri.param("url")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.param(layers): {}'.format(
            uri.param("layers")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.param(format): {}'.format(
            uri.param("format")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.param(crs): {}'.format(uri.param("crs")),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.service(): {}'.format(uri.service()),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('encodedUri: {}'.format(str(uri.encodedUri())),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)
        qgs_logger.logMessage('uri.uri(): {}'.format(uri.uri()),
                              tag=configuration.LOGGER_TAG,
                              level=Qgis.Info)

        # Generating the WMS layer
        wms_layer = QgsRasterLayer(str(uri.encodedUri()), wms_name, 'wms')

        # If the WMS is correctly generated, add to the QGis TOC
        if wms_layer.isValid():
            QgsProject.instance().addMapLayer(wms_layer)
        else:
            qgs_logger.logMessage(
                'Impossibile aggiungere il WMS: {}'.format(wms_name),
                tag=configuration.LOGGER_TAG,
                level=Qgis.Warning)
            self.show_message(
                "Attenzione!",
                "Impossibile aggiungere il WMS " + wms_name + " al progetto")