Exemple #1
0
    def checkRemovingLabeledLayerInvalidatesLabelCache(self, job_type):
        """ removing a previously labeled layer should invalidate any previous label caches"""
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                "layer2", "memory")
        layer2.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer2.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer, layer2])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        self.assertEqual(set(cache.dependentLayers('_labels_')), {layer, layer2})

        # remove a previously labeled layer
        settings.setLayers([layer2])

        # second job should not be able to use label cache, since a labeled layer was removed
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # shouldn't use cache
        self.assertFalse(job.usedCachedLabels())
        # but results should have been cached
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertEqual(set(cache.dependentLayers('_labels_')), {layer2})
        self.assertTrue(job.takeLabelingResults())
Exemple #2
0
    def checkLabeledLayerWithBlendModesCannotBeCached(self, job_type):
        """ any labeled layer utilising blending modes cannot be cached"""
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                "layer2", "memory")
        labelSettings2 = QgsPalLayerSettings()
        labelSettings2.fieldName = "fldtxt"
        format2 = QgsTextFormat()
        format2.setBlendMode(QPainter.CompositionMode_SourceIn)
        labelSettings2.setFormat(format2)
        layer2.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings2))
        layer2.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer, layer2])

        # with cache - cache should not be populated!
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertFalse(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        # second job should also not be able to use label cache
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # shouldn't use cache
        self.assertFalse(job.usedCachedLabels())
        # and results should not have been cached
        self.assertFalse(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())
Exemple #3
0
    def checkAddingNewNonLabeledLayerKeepsLabelCache(self, job_type):
        """ adding a new non-labeled layer should keep any previous label caches"""
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        self.assertEqual(cache.dependentLayers('_labels_'), [layer])

        # add another, non-labeled layer
        layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                "layer2", "memory")
        settings.setLayers([layer, layer2])

        # second job should use label cache, since new layer was not labeled
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # should use cache
        self.assertTrue(job.usedCachedLabels())
        # results should have been cached
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertEqual(set(cache.dependentLayers('_labels_')), {layer})
        self.assertTrue(job.takeLabelingResults())
Exemple #4
0
    def checkAddingNewNonLabeledLayerKeepsLabelCache(self, job_type):
        """ adding a new non-labeled layer should keep any previous label caches"""
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        self.assertEqual(cache.dependentLayers('_labels_'), [layer])

        # add another, non-labeled layer
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        settings.setLayers([layer, layer2])

        # second job should use label cache, since new layer was not labeled
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # should use cache
        self.assertTrue(job.usedCachedLabels())
        # results should have been cached
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertEqual(set(cache.dependentLayers('_labels_')), {layer})
        self.assertTrue(job.takeLabelingResults())
Exemple #5
0
    def saveToLayer(self):
        units = self.unitDesignator()
        canvasCrs = self.canvas.mapSettings().destinationCrs()
        fields = QgsFields()
        fields.append(QgsField("label", QVariant.String))
        fields.append(QgsField("value", QVariant.Double))
        fields.append(QgsField("units", QVariant.String))
        fields.append(QgsField("heading_to", QVariant.Double))
        fields.append(QgsField("heading_from", QVariant.Double))

        layer = QgsVectorLayer("LineString?crs={}".format(canvasCrs.authid()),
                               "Measurements", "memory")
        dp = layer.dataProvider()
        dp.addAttributes(fields)
        layer.updateFields()

        num = len(self.capturedPoints)
        for i in range(1, num):
            (distance, startA,
             endA) = self.calcParameters(self.capturedPoints[i - 1],
                                         self.capturedPoints[i])
            pts = self.getLinePts(distance, self.capturedPoints[i - 1],
                                  self.capturedPoints[i])
            distance = self.unitDistance(distance)
            feat = QgsFeature(layer.fields())
            feat.setAttribute(0, "{:.2f} {}".format(distance, units))
            feat.setAttribute(1, distance)
            feat.setAttribute(2, units)
            feat.setAttribute(3, startA)
            feat.setAttribute(4, endA)
            feat.setGeometry(QgsGeometry.fromPolylineXY(pts))
            dp.addFeatures([feat])

        label = QgsPalLayerSettings()
        label.fieldName = 'label'
        label.placement = QgsPalLayerSettings.AboveLine
        labeling = QgsVectorLayerSimpleLabeling(label)
        layer.setLabeling(labeling)
        layer.setLabelsEnabled(True)

        layer.updateExtents()
        QgsProject.instance().addMapLayer(layer)
Exemple #6
0
    def checkRepaintLabeledLayerInvalidatesLabelCache(self, job_type):
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        self.assertEqual(cache.dependentLayers('_labels_'), [layer])

        # trigger repaint on layer - should invalidate cache and block use of cached labels
        layer.triggerRepaint()
        self.assertFalse(cache.hasCacheImage('_labels_'))

        # second job should not use label cache, since layer was repainted
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # shouldn't use cache
        self.assertFalse(job.usedCachedLabels())
        # but results should have been cached
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())
Exemple #7
0
    def checkRepaintLabeledLayerInvalidatesLabelCache(self, job_type):
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        self.assertEqual(cache.dependentLayers('_labels_'), [layer])

        # trigger repaint on layer - should invalidate cache and block use of cached labels
        layer.triggerRepaint()
        self.assertFalse(cache.hasCacheImage('_labels_'))

        # second job should not use label cache, since layer was repainted
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # shouldn't use cache
        self.assertFalse(job.usedCachedLabels())
        # but results should have been cached
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())
    def createLayer(self):
        '''Create a memory layer from the zoom to locations'''
        rowcnt = self.resultsTable.rowCount()
        if rowcnt == 0:
            return
        attr = []
        for item, label in enumerate(LABELS[0:self.numCol]):
            label = label.lower()
            if item <= 1:
                attr.append(QgsField(label, QVariant.Double))
            else:
                attr.append(QgsField(label, QVariant.String))
        ptLayer = QgsVectorLayer("Point?crs=epsg:4326", u"Lat Lon Locations", "memory")
        provider = ptLayer.dataProvider()
        provider.addAttributes(attr)
        ptLayer.updateFields()

        for id in range(rowcnt):
            item = self.resultsTable.item(id, 0).data(Qt.UserRole)
            feature = QgsFeature()
            feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(item.lon, item.lat)))
            attr = [item.lat, item.lon, item.label]
            for i in range(3, self.numCol):
                attr.append(item.data[i - 3])
            feature.setAttributes(attr)
            provider.addFeatures([feature])

        ptLayer.updateExtents()
        if self.settings.multiZoomStyleID == 1:
            settings = QgsPalLayerSettings()
            settings.fieldName = 'label'
            settings.placement = QgsPalLayerSettings.AroundPoint
            labeling = QgsVectorLayerSimpleLabeling(settings)
            ptLayer.setLabeling(labeling)
            ptLayer.setLabelsEnabled(True)
        elif self.settings.multiZoomStyleID == 2 and os.path.isfile(self.settings.customQMLFile()):
            ptLayer.loadNamedStyle(self.settings.customQMLFile())

        QgsProject.instance().addMapLayer(ptLayer)
 def createLayer(self):
     '''Create a memory layer from the zoom to locations'''
     rowcnt = self.resultsTable.rowCount()
     if rowcnt == 0:
         return
     attr = []
     for item, label in enumerate(LABELS[0:self.numCol]):
         label = label.lower()
         if item <= 1:
             attr.append(QgsField(label, QVariant.Double))
         else:
             attr.append(QgsField(label, QVariant.String))
     ptLayer = QgsVectorLayer("Point?crs=epsg:4326", u"Lat Lon Locations", "memory")
     provider = ptLayer.dataProvider()
     provider.addAttributes(attr)
     ptLayer.updateFields()
     
     for id in range(rowcnt):
         item = self.resultsTable.item(id, 0).data(Qt.UserRole)
         feature = QgsFeature()
         feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(item.lon, item.lat)))
         attr = [item.lat, item.lon, item.label]
         for i in range(3, self.numCol):
             attr.append(item.data[i-3])
         feature.setAttributes(attr)
         provider.addFeatures([feature])
     
     ptLayer.updateExtents()
     if self.settings.multiZoomStyleID == 1:
         settings = QgsPalLayerSettings()
         settings.fieldName = 'label'
         settings.placement = QgsPalLayerSettings.AroundPoint
         labeling = QgsVectorLayerSimpleLabeling(settings)
         ptLayer.setLabeling(labeling)
         ptLayer.setLabelsEnabled(True)
     elif self.settings.multiZoomStyleID == 2 and os.path.isfile(self.settings.customQMLFile()):
         ptLayer.loadNamedStyle(self.settings.customQMLFile())
         
     QgsProject.instance().addMapLayer(ptLayer)
Exemple #10
0
    def testBlockingItems(self):
        """
        Test rendering map item with blocking items
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(20)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'X'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl",
                            "memory")
        vl.setRenderer(QgsNullSymbolRenderer())
        f = QgsFeature(vl.fields(), 1)
        for x in range(15):
            for y in range(15):
                f.setGeometry(QgsPoint(x, y))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        engine_settings = QgsLabelingEngineSettings()
        engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly,
                                True)
        p.setLabelingEngineSettings(engine_settings)

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(True)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        map.setId('map')
        layout.addLayoutItem(map)

        map2 = QgsLayoutItemMap(layout)
        map2.attemptSetSceneRect(QRectF(0, 5, 50, 80))
        map2.setFrameEnabled(True)
        map2.setBackgroundEnabled(False)
        map2.setId('map2')
        layout.addLayoutItem(map2)

        map3 = QgsLayoutItemMap(layout)
        map3.attemptSetSceneRect(QRectF(150, 160, 50, 50))
        map3.setFrameEnabled(True)
        map3.setBackgroundEnabled(False)
        map3.setId('map3')
        layout.addLayoutItem(map3)

        map.addLabelBlockingItem(map2)
        map.addLabelBlockingItem(map3)
        map.setMapFlags(QgsLayoutItemMap.MapItemFlags())
        checker = QgsLayoutChecker('composermap_label_blockers', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        doc = QDomDocument("testdoc")
        elem = layout.writeXml(doc, QgsReadWriteContext())

        l2 = QgsLayout(p)
        self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext()))
        map_restore = [
            i for i in l2.items()
            if isinstance(i, QgsLayoutItemMap) and i.id() == 'map'
        ][0]
        map2_restore = [
            i for i in l2.items()
            if isinstance(i, QgsLayoutItemMap) and i.id() == 'map2'
        ][0]
        map3_restore = [
            i for i in l2.items()
            if isinstance(i, QgsLayoutItemMap) and i.id() == 'map3'
        ][0]
        self.assertTrue(map_restore.isLabelBlockingItem(map2_restore))
        self.assertTrue(map_restore.isLabelBlockingItem(map3_restore))
Exemple #11
0
    def testPartialLabels(self):
        """
        Test rendering map item with a show partial labels flag
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(20)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'X'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl",
                            "memory")
        vl.setRenderer(QgsNullSymbolRenderer())
        f = QgsFeature(vl.fields(), 1)
        for x in range(15):
            for y in range(15):
                f.setGeometry(QgsPoint(x, y))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        engine_settings = QgsLabelingEngineSettings()
        engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates,
                                False)
        engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly,
                                True)
        p.setLabelingEngineSettings(engine_settings)

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(True)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        # default should always be to hide partial labels
        self.assertFalse(map.mapFlags() & QgsLayoutItemMap.ShowPartialLabels)

        # hiding partial labels (the default)
        map.setMapFlags(QgsLayoutItemMap.MapItemFlags())
        checker = QgsLayoutChecker('composermap_label_nomargin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # showing partial labels
        map.setMapFlags(QgsLayoutItemMap.ShowPartialLabels)
        checker = QgsLayoutChecker('composermap_show_partial_labels', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)
Exemple #12
0
    def testLabelMargin(self):
        """
        Test rendering map item with a label margin set
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(20)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'X'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl",
                            "memory")
        vl.setRenderer(QgsNullSymbolRenderer())
        f = QgsFeature(vl.fields(), 1)
        for x in range(15):
            for y in range(15):
                f.setGeometry(QgsPoint(x, y))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        engine_settings = QgsLabelingEngineSettings()
        engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates,
                                False)
        engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly,
                                True)
        p.setLabelingEngineSettings(engine_settings)

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(True)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        checker = QgsLayoutChecker('composermap_label_nomargin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        map.setLabelMargin(
            QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters))
        checker = QgsLayoutChecker('composermap_label_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        map.setLabelMargin(
            QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters))
        checker = QgsLayoutChecker('composermap_label_cm_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        map.setMapRotation(45)
        map.zoomToExtent(vl.extent())
        map.setScale(map.scale() * 1.2)
        checker = QgsLayoutChecker('composermap_rotated_label_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # data defined
        map.setMapRotation(0)
        map.zoomToExtent(vl.extent())
        map.dataDefinedProperties().setProperty(
            QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3'))
        map.refresh()
        checker = QgsLayoutChecker('composermap_dd_label_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)
    def testBlockingItems(self):
        """
        Test rendering map item with blocking items
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(20)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'X'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory")
        vl.setRenderer(QgsNullSymbolRenderer())
        f = QgsFeature(vl.fields(), 1)
        for x in range(15):
            for y in range(15):
                f.setGeometry(QgsPoint(x, y))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        engine_settings = QgsLabelingEngineSettings()
        engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True)
        p.setLabelingEngineSettings(engine_settings)

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(True)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        map.setId('map')
        layout.addLayoutItem(map)

        map2 = QgsLayoutItemMap(layout)
        map2.attemptSetSceneRect(QRectF(0, 5, 50, 80))
        map2.setFrameEnabled(True)
        map2.setBackgroundEnabled(False)
        map2.setId('map2')
        layout.addLayoutItem(map2)

        map3 = QgsLayoutItemMap(layout)
        map3.attemptSetSceneRect(QRectF(150, 160, 50, 50))
        map3.setFrameEnabled(True)
        map3.setBackgroundEnabled(False)
        map3.setId('map3')
        layout.addLayoutItem(map3)

        map.addLabelBlockingItem(map2)
        map.addLabelBlockingItem(map3)
        map.setMapFlags(QgsLayoutItemMap.MapItemFlags())
        checker = QgsLayoutChecker('composermap_label_blockers', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        doc = QDomDocument("testdoc")
        elem = layout.writeXml(doc, QgsReadWriteContext())

        l2 = QgsLayout(p)
        self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext()))
        map_restore = [i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map'][0]
        map2_restore = [i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map2'][0]
        map3_restore = [i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map3'][0]
        self.assertTrue(map_restore.isLabelBlockingItem(map2_restore))
        self.assertTrue(map_restore.isLabelBlockingItem(map3_restore))
    def testPartialLabels(self):
        """
        Test rendering map item with a show partial labels flag
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(20)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'X'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory")
        vl.setRenderer(QgsNullSymbolRenderer())
        f = QgsFeature(vl.fields(), 1)
        for x in range(15):
            for y in range(15):
                f.setGeometry(QgsPoint(x, y))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        engine_settings = QgsLabelingEngineSettings()
        engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False)
        engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True)
        p.setLabelingEngineSettings(engine_settings)

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(True)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        # default should always be to hide partial labels
        self.assertFalse(map.mapFlags() & QgsLayoutItemMap.ShowPartialLabels)

        # hiding partial labels (the default)
        map.setMapFlags(QgsLayoutItemMap.MapItemFlags())
        checker = QgsLayoutChecker('composermap_label_nomargin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # showing partial labels
        map.setMapFlags(QgsLayoutItemMap.ShowPartialLabels)
        checker = QgsLayoutChecker('composermap_show_partial_labels', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)
class BulkNominatimDialog(QDialog, FORM_CLASS):
    def __init__(self, iface, parent, settings):
        '''Initialize the bulk nominatim dialog box'''
        super(BulkNominatimDialog, self).__init__(parent)
        self.setupUi(self)
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.settings = settings
        self.addressMapLayerComboBox.setFilters(
            QgsMapLayerProxyModel.VectorLayer)
        self.addressMapLayerComboBox.layerChanged.connect(self.findFields)
        self.mMapLayerComboBox.setFilters(QgsMapLayerProxyModel.PointLayer)

    def accept(self):
        '''process and geocode the addresses'''
        selected_tab = self.tabWidget.currentIndex()
        # Clear the Results Dialog box
        self.resultsTextEdit.clear()
        if selected_tab == 0:
            self.processAddressTable()
        elif selected_tab == 1:
            self.processFreeFormData()
        else:
            self.reverseGeocode()

    def showEvent(self, event):
        '''The dialog is being shown. We need to initialize it.'''
        super(BulkNominatimDialog, self).showEvent(event)
        self.findFields()

    def request(self, url):
        fetcher = QgsNetworkContentFetcher()
        fetcher.fetchContent(QUrl(url))
        evloop = QEventLoop()
        fetcher.finished.connect(evloop.quit)
        evloop.exec_(QEventLoop.ExcludeUserInputEvents)
        fetcher.finished.disconnect(evloop.quit)
        return fetcher.contentAsString()

    def reverseGeocode(self):
        layer = self.mMapLayerComboBox.currentLayer()
        if not layer:
            self.iface.messageBar().pushMessage(
                "",
                "No valid point vector layer to reverse geocode",
                level=QgsMessageBar.WARNING,
                duration=2)
            return

        showDetails = int(self.detailedAddressCheckBox.isChecked())
        self.numAddress = layer.featureCount()
        self.numErrors = 0
        if self.numAddress > self.settings.maxAddress:
            self.iface.messageBar().pushMessage(
                "",
                "Maximum geocodes to process were exceeded. Please reduce the number and try again.",
                level=QgsMessageBar.WARNING,
                duration=4)
            return

        layername = self.layerLineEdit.text()
        self.createPointLayerReverse()

        layerCRS = layer.crs()
        epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326")
        transform = QgsCoordinateTransform(layerCRS, epsg4326,
                                           QgsProject.instance())

        iter = layer.getFeatures()

        for feature in iter:
            # already know that this is a point vector layer
            pt = feature.geometry().asPoint()
            # make sure the coordinates are in EPSG:4326
            pt = transform.transform(pt.x(), pt.y())
            newfeature = QgsFeature()
            newfeature.setGeometry(QgsGeometry.fromPointXY(pt))
            lat = str(pt.y())
            lon = str(pt.x())
            url = '{}?format=json&lat={}&lon={}&zoom=18&addressdetails={}'.format(
                self.settings.reverseURL(), lat, lon, showDetails)
            jsondata = self.request(url)
            # print(jsondata)
            address = ''
            try:
                jd = json.loads(jsondata)
                if len(jd) == 0:
                    raise ValueError('')
                display_name = self.fieldValidate(jd, 'display_name')
                if showDetails:
                    osm_type = self.fieldValidate(jd, 'osm_type')
                    osm_id = self.fieldValidate(jd, 'osm_id')
                    house_number = ''
                    road = ''
                    neighbourhood = ''
                    locality = ''
                    town = ''
                    city = ''
                    county = ''
                    state = ''
                    postcode = ''
                    country = ''
                    country_code = ''
                    if 'address' in jd:
                        house_number = self.fieldValidate(
                            jd['address'], 'house_number')
                        road = self.fieldValidate(jd['address'], 'road')
                        neighbourhood = self.fieldValidate(
                            jd['address'], 'neighbourhood')
                        locality = self.fieldValidate(jd['address'],
                                                      'locality')
                        town = self.fieldValidate(jd['address'], 'town')
                        city = self.fieldValidate(jd['address'], 'city')
                        county = self.fieldValidate(jd['address'], 'county')
                        state = self.fieldValidate(jd['address'], 'state')
                        postcode = self.fieldValidate(jd['address'],
                                                      'postcode')
                        country = self.fieldValidate(jd['address'], 'country')
                        country_code = self.fieldValidate(
                            jd['address'], 'country_code')
                    feature.setAttributes([
                        osm_type, osm_id, display_name, house_number, road,
                        neighbourhood, locality, town, city, county, state,
                        postcode, country, country_code
                    ])
                    self.provider.addFeatures([feature])
                else:
                    feature.setAttributes([display_name])
                    self.provider.addFeatures([feature])
            except Exception:
                self.numErrors += 1

        self.pointLayer.updateExtents()
        QgsProject.instance().addMapLayer(self.pointLayer)
        if self.numAddress > 0:
            self.resultsTextEdit.appendPlainText('Total Points Processed: ' +
                                                 str(self.numAddress))
            self.resultsTextEdit.appendPlainText('Processing Complete!')

    def findFields(self):
        if not self.isVisible():
            return
        layer = self.addressMapLayerComboBox.currentLayer()
        if not layer:
            self.clearLayerFields()
        else:
            header = [u"--- Select Column ---"]
            fields = layer.fields()
            for field in fields.toList():
                # force it to be lower case - makes matching easier
                name = field.name()
                header.append(name)
            self.configureLayerFields(header)

    def processAddressTable(self):
        layer = self.addressMapLayerComboBox.currentLayer()
        if not layer:
            self.iface.messageBar().pushMessage(
                "",
                "No valid table or vector layer to reverse geocode",
                level=QgsMessageBar.WARNING,
                duration=4)
            return
        self.numAddress = layer.featureCount()
        if not self.numAddress:
            self.iface.messageBar().pushMessage("",
                                                "No addresses to geocode",
                                                level=QgsMessageBar.WARNING,
                                                duration=4)
            return

        self.numErrors = 0
        if self.numAddress > self.settings.maxAddress:
            self.iface.messageBar().pushMessage(
                "",
                "Maximum geocodes to process were exceeded. Please reduce the number and try again.",
                level=QgsMessageBar.WARNING,
                duration=4)
            return

        maxResults = self.maxResultsSpinBox.value()
        showDetails = int(self.detailedAddressCheckBox.isChecked())
        self.pointLayer = None
        self.createPointLayer()

        iter = layer.getFeatures(QgsFeatureRequest().setFlags(
            QgsFeatureRequest.NoGeometry))
        full_address_idx = self.fullAddressComboBox.currentIndex() - 1
        street_num_idx = self.numberComboBox.currentIndex() - 1
        street_name_idx = self.streetNameComboBox.currentIndex() - 1
        city_idx = self.cityComboBox.currentIndex() - 1
        county_idx = self.countyComboBox.currentIndex() - 1
        state_idx = self.stateComboBox.currentIndex() - 1
        country_idx = self.countryComboBox.currentIndex() - 1
        postal_idx = self.postalCodeComboBox.currentIndex() - 1

        for feature in iter:
            self.isfirst = True
            if full_address_idx >= 0:
                address = feature[full_address_idx].strip()
                address2 = re.sub('\s+', '+', address)
                url = self.settings.searchURL() + '?q=' + address2
            else:
                address = ','.join(
                    [str(x) if x else '' for x in feature.attributes()])
                url = self.settings.searchURL() + '?'
                if street_name_idx >= 0:
                    num = ''
                    name = ''
                    if street_num_idx >= 0 and feature[street_num_idx]:
                        num = ('{}'.format(feature[street_num_idx])).strip()
                    if feature[street_name_idx]:
                        name = ('{}'.format(feature[street_name_idx])).strip()
                    street = num + ' ' + name
                    street = street.strip()
                    if street:
                        url += self.formatParam('street', street)
                if city_idx >= 0:
                    url += self.formatParam('city', feature[city_idx])
                if county_idx >= 0:
                    url += self.formatParam('county', feature[county_idx])
                if state_idx >= 0:
                    url += self.formatParam('state', feature[state_idx])
                if country_idx >= 0:
                    url += self.formatParam('country', feature[country_idx])
                if postal_idx >= 0:
                    url += self.formatParam('postalcode', feature[postal_idx])

            url += '&format=json&limit={}&polygon=0&addressdetails={}'.format(
                maxResults, showDetails)
            jsondata = self.request(url)

            try:
                jd = json.loads(jsondata)
                if len(jd) == 0:
                    raise ValueError(address)
                for addr in jd:
                    try:
                        lat = addr['lat']
                        lon = addr['lon']
                    except:
                        raise ValueError(address)

                    newfeature = QgsFeature()
                    newfeature.setGeometry(
                        QgsGeometry.fromPointXY(
                            QgsPointXY(float(lon), float(lat))))
                    display_name = self.fieldValidate(addr, 'display_name')

                    if self.detailedAddressCheckBox.checkState():
                        osm_type = self.fieldValidate(addr, 'osm_type')
                        osm_id = self.fieldValidate(addr, 'osm_id')
                        osm_class = self.fieldValidate(addr, 'class')
                        type = self.fieldValidate(addr, 'type')
                        house_number = ''
                        road = ''
                        neighbourhood = ''
                        locality = ''
                        town = ''
                        city = ''
                        county = ''
                        state = ''
                        postcode = ''
                        country = ''
                        country_code = ''
                        if 'address' in addr:
                            house_number = self.fieldValidate(
                                addr['address'], 'house_number')
                            road = self.fieldValidate(addr['address'], 'road')
                            neighbourhood = self.fieldValidate(
                                addr['address'], 'neighbourhood')
                            locality = self.fieldValidate(
                                addr['address'], 'locality')
                            town = self.fieldValidate(addr['address'], 'town')
                            city = self.fieldValidate(addr['address'], 'city')
                            county = self.fieldValidate(
                                addr['address'], 'county')
                            state = self.fieldValidate(addr['address'],
                                                       'state')
                            postcode = self.fieldValidate(
                                addr['address'], 'postcode')
                            country = self.fieldValidate(
                                addr['address'], 'country')
                            country_code = self.fieldValidate(
                                addr['address'], 'country_code')
                        newfeature.setAttributes([
                            osm_type, osm_id, osm_class, type, address,
                            display_name, house_number, road, neighbourhood,
                            locality, town, city, county, state, postcode,
                            country, country_code
                        ])
                        self.provider.addFeatures([newfeature])
                    else:
                        # Display only the resulting output address
                        newfeature.setAttributes([display_name])
                        self.provider.addFeatures([newfeature])
            except Exception as e:
                if self.numErrors == 0:
                    self.resultsTextEdit.appendPlainText('Address Errors')
                self.numErrors += 1
                self.resultsTextEdit.appendPlainText(str(e))

        if self.numAddress > 0:
            self.pointLayer.updateExtents()
            QgsProject.instance().addMapLayer(self.pointLayer)
            self.resultsTextEdit.appendPlainText(
                'Number of Addresses Processed: ' + str(self.numAddress))
            self.resultsTextEdit.appendPlainText('Number of Successes: ' +
                                                 str(self.numAddress -
                                                     self.numErrors))
            self.resultsTextEdit.appendPlainText('Number of Errors: ' +
                                                 str(self.numErrors))
            self.resultsTextEdit.appendPlainText('Processing Complete!')

    def formatParam(self, tag, value):
        if value:
            value = ('{}'.format(value)).strip()
            value = re.sub('\s+', '%20', value)
        else:
            value = ''
        if self.isfirst:
            url = '{}={}'.format(tag, value)
            self.isfirst = False
        else:
            url = '&{}={}'.format(tag, value)
        return url

    def processFreeFormData(self):
        addresses = []

        # Get the text for the Address Query Box an dgo through line by line to geocode it
        inputtext = str(self.addressTextEdit.toPlainText())
        lines = inputtext.splitlines()
        self.pointLayer = None
        self.numAddress = 0
        self.numErrors = 0

        # Create a list of all the Addresses. We want to get an accurate count
        for address in lines:
            # Get rid of beginning and end space
            address = address.strip()
            # Skip any blank lines
            if not address:
                continue
            self.numAddress += 1
            addresses.append(address)

        if self.numAddress > self.settings.maxAddress:
            self.iface.messageBar().pushMessage(
                "",
                "Maximum addresses to process were exceeded. Please reduce the number and try again.",
                level=QgsMessageBar.WARNING,
                duration=4)
            return

        if self.numAddress:
            self.createPointLayer()
        maxResults = self.maxResultsSpinBox.value()
        showDetails = int(self.detailedAddressCheckBox.isChecked())

        for address in addresses:
            # Replace internal spaces with + signs
            address2 = re.sub('\s+', '+', address)
            url = '{}?q={}&format=json&limit={}&polygon=0&addressdetails={}'.format(
                self.settings.searchURL(), address2, maxResults, showDetails)
            jsondata = self.request(url)
            # print(jsondata)
            try:
                jd = json.loads(jsondata)
                if len(jd) == 0:
                    raise ValueError(address)
                for addr in jd:
                    try:
                        lat = addr['lat']
                        lon = addr['lon']
                    except:
                        raise ValueError(address)

                    feature = QgsFeature()
                    feature.setGeometry(
                        QgsGeometry.fromPointXY(
                            QgsPointXY(float(lon), float(lat))))
                    display_name = self.fieldValidate(addr, 'display_name')

                    if self.detailedAddressCheckBox.checkState():
                        osm_type = self.fieldValidate(addr, 'osm_type')
                        osm_id = self.fieldValidate(addr, 'osm_id')
                        osm_class = self.fieldValidate(addr, 'class')
                        type = self.fieldValidate(addr, 'type')
                        house_number = ''
                        road = ''
                        neighbourhood = ''
                        locality = ''
                        town = ''
                        city = ''
                        county = ''
                        state = ''
                        postcode = ''
                        country = ''
                        country_code = ''
                        if 'address' in addr:
                            house_number = self.fieldValidate(
                                addr['address'], 'house_number')
                            road = self.fieldValidate(addr['address'], 'road')
                            neighbourhood = self.fieldValidate(
                                addr['address'], 'neighbourhood')
                            locality = self.fieldValidate(
                                addr['address'], 'locality')
                            town = self.fieldValidate(addr['address'], 'town')
                            city = self.fieldValidate(addr['address'], 'city')
                            county = self.fieldValidate(
                                addr['address'], 'county')
                            state = self.fieldValidate(addr['address'],
                                                       'state')
                            postcode = self.fieldValidate(
                                addr['address'], 'postcode')
                            country = self.fieldValidate(
                                addr['address'], 'country')
                            country_code = self.fieldValidate(
                                addr['address'], 'country_code')
                        feature.setAttributes([
                            osm_type, osm_id, osm_class, type, address,
                            display_name, house_number, road, neighbourhood,
                            locality, town, city, county, state, postcode,
                            country, country_code
                        ])
                        self.provider.addFeatures([feature])
                    else:
                        # Display only the resulting output address
                        feature.setAttributes([display_name])
                        self.provider.addFeatures([feature])
            except Exception as e:
                if self.numErrors == 0:
                    self.resultsTextEdit.appendPlainText('Address Errors')
                self.numErrors += 1
                self.resultsTextEdit.appendPlainText(str(e))

        if self.numAddress > 0:
            self.pointLayer.updateExtents()
            QgsProject.instance().addMapLayer(self.pointLayer)
            self.resultsTextEdit.appendPlainText(
                'Number of Addresses Processed: ' + str(self.numAddress))
            self.resultsTextEdit.appendPlainText('Number of Successes: ' +
                                                 str(self.numAddress -
                                                     self.numErrors))
            self.resultsTextEdit.appendPlainText('Number of Errors: ' +
                                                 str(self.numErrors))
            self.resultsTextEdit.appendPlainText('Processing Complete!')

    def fieldValidate(self, data, name):
        if name in data:
            return str(data[name])
        return ''

    def createPointLayerReverse(self):
        layername = self.layerLineEdit.text()
        self.pointLayer = QgsVectorLayer("point?crs=epsg:4326", layername,
                                         "memory")
        self.provider = self.pointLayer.dataProvider()
        if self.detailedAddressCheckBox.checkState():
            self.provider.addAttributes([
                QgsField("osm_type", QVariant.String),
                QgsField("osm_id", QVariant.String),
                QgsField("display_name", QVariant.String),
                QgsField("house_number", QVariant.String),
                QgsField("road", QVariant.String),
                QgsField("neighbourhood", QVariant.String),
                QgsField("locality", QVariant.String),
                QgsField("town", QVariant.String),
                QgsField("city", QVariant.String),
                QgsField("county", QVariant.String),
                QgsField("state", QVariant.String),
                QgsField("postcode", QVariant.String),
                QgsField("country", QVariant.String),
                QgsField("country_code", QVariant.String)
            ])
        else:
            self.provider.addAttributes(
                [QgsField("display_name", QVariant.String)])
        self.pointLayer.updateFields()
        if self.showLabelCheckBox.checkState():
            # Display labels
            label = QgsPalLayerSettings()
            label.fieldName = 'display_name'
            label.placement = QgsPalLayerSettings.AroundPoint
            labeling = QgsVectorLayerSimpleLabeling(label)
            self.pointLayer.setLabeling(labeling)
            self.pointLayer.setLabelsEnabled(True)

    def createPointLayer(self):
        layername = self.layerLineEdit.text()
        self.pointLayer = QgsVectorLayer("point?crs=epsg:4326", layername,
                                         "memory")
        self.provider = self.pointLayer.dataProvider()
        if self.detailedAddressCheckBox.checkState():
            self.provider.addAttributes([
                QgsField("osm_type", QVariant.String),
                QgsField("osm_id", QVariant.String),
                QgsField("class", QVariant.String),
                QgsField("type", QVariant.String),
                QgsField("source_addr", QVariant.String),
                QgsField("display_name", QVariant.String),
                QgsField("house_number", QVariant.String),
                QgsField("road", QVariant.String),
                QgsField("neighbourhood", QVariant.String),
                QgsField("locality", QVariant.String),
                QgsField("town", QVariant.String),
                QgsField("city", QVariant.String),
                QgsField("county", QVariant.String),
                QgsField("state", QVariant.String),
                QgsField("postcode", QVariant.String),
                QgsField("country", QVariant.String),
                QgsField("country_code", QVariant.String)
            ])
        else:
            self.provider.addAttributes(
                [QgsField("display_name", QVariant.String)])
        self.pointLayer.updateFields()
        if self.showLabelCheckBox.checkState():
            # Display labels
            label = QgsPalLayerSettings()
            label.fieldName = 'display_name'
            label.placement = QgsPalLayerSettings.AroundPoint
            labeling = QgsVectorLayerSimpleLabeling(label)
            self.pointLayer.setLabeling(labeling)
            self.pointLayer.setLabelsEnabled(True)

    def configureLayerFields(self, header):
        self.clearLayerFields()
        self.fullAddressComboBox.addItems(header)
        self.numberComboBox.addItems(header)
        self.streetNameComboBox.addItems(header)
        self.cityComboBox.addItems(header)
        self.countyComboBox.addItems(header)
        self.stateComboBox.addItems(header)
        self.countryComboBox.addItems(header)
        self.postalCodeComboBox.addItems(header)

        street_num_col = street_name_col = city_col = county_col = state_col = country_col = postal_col = -1
        for x, item in enumerate(header):
            # Skip the header line
            if x == 0:
                continue
            # force it to be lower case - makes matching easier
            item = item.lower()
            if bool(re.search('num', item)):
                street_num_col = x
            elif bool(re.search('name', item)) or item.startswith('road'):
                street_name_col = x
            elif item.startswith('city'):
                city_col = x
            elif item.startswith('county'):
                county_col = x
            elif item.startswith('state'):
                state_col = x
            elif item.startswith('country'):
                country_col = x
            elif item.startswith('postal'):
                postal_col = x
        if street_num_col != -1:
            self.numberComboBox.setCurrentIndex(street_num_col)
        if street_name_col != -1:
            self.streetNameComboBox.setCurrentIndex(street_name_col)
        if city_col != -1:
            self.cityComboBox.setCurrentIndex(city_col)
        if county_col != -1:
            self.countyComboBox.setCurrentIndex(county_col)
        if state_col != -1:
            self.stateComboBox.setCurrentIndex(state_col)
        if country_col != -1:
            self.countryComboBox.setCurrentIndex(country_col)
        if postal_col != -1:
            self.postalCodeComboBox.setCurrentIndex(postal_col)
        self.fullAddressComboBox.setCurrentIndex(0)

    def clearLayerFields(self):
        self.fullAddressComboBox.clear()
        self.numberComboBox.clear()
        self.streetNameComboBox.clear()
        self.cityComboBox.clear()
        self.countyComboBox.clear()
        self.stateComboBox.clear()
        self.countryComboBox.clear()
        self.postalCodeComboBox.clear()
Exemple #16
0
class geometryHelper(object):
    def __init__(self , iface ):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.adreslayerid = ''
    
    @staticmethod
    def getGetMapCrs(iface):
        return iface.mapCanvas().mapSettings().destinationCrs() 
        
    def prjPtToMapCrs( self, xy , fromCRS=4326 ):
        point = QgsPointXY( list(xy)[0], list(xy)[1] ) if isinstance( xy, Iterable) else QgsPointXY(xy)
        fromCrs = QgsCoordinateReferenceSystem(fromCRS)
        toCrs = self.getGetMapCrs(self.iface)
        xform = QgsCoordinateTransform( fromCrs, toCrs, QgsProject.instance() )
        return   xform.transform( point )
    
    def prjPtFromMapCrs( self, xy , toCRS=31370 ):
        point = QgsPointXY( list(xy)[0], list(xy)[1] ) if isinstance( xy, Iterable) else QgsPointXY(xy)
        toCrs = QgsCoordinateReferenceSystem(toCRS)
        fromCrs = self.getGetMapCrs(self.iface)
        xform = QgsCoordinateTransform( fromCrs, toCrs, QgsProject.instance() )
        return   xform.transform( point )

    def prjLineFromMapCrs(self, lineString, toCRS=4326 ):
        fromCrs = self.getGetMapCrs(self.iface)
        toCrs = QgsCoordinateReferenceSystem(toCRS)
        xform = QgsCoordinateTransform(fromCrs, toCrs, QgsProject.instance() )
        if isinstance(lineString, QgsGeometry):
            wgsLine = [ QgsPoint( xform.transform( QgsPointXY(xy) ) ) for xy in  lineString.asPolyline()]
        if isinstance( lineString, Iterable ):
            wgsLine = [ QgsPoint( xform.transform( QgsPointXY(list(xy)[0], list(xy)[1]) ) ) for xy in  lineString]
        return QgsGeometry.fromPolyline( wgsLine )

    def prjLineToMapCrs(self, lineString, fromCRS=4326 ):
        fromCrs = QgsCoordinateReferenceSystem(fromCRS)
        toCrs = self.getGetMapCrs(self.iface)
        xform = QgsCoordinateTransform(fromCrs, toCrs, QgsProject.instance() )
        if isinstance(lineString, QgsGeometry):
            wgsLine = [ QgsPoint( xform.transform( QgsPointXY(xy) ) ) for xy in  lineString.asPolyline()]
        if isinstance( lineString, Iterable ):
            wgsLine = [ QgsPoint( xform.transform( QgsPointXY(list(xy)[0], list(xy)[1]) ) ) for xy in  lineString]
        return QgsGeometry.fromPolyline( wgsLine )

    def zoomtoRec(self, xyMin, xyMax , crs=None):
        """zoom to rectangle from 2 points with given crs, default= mapCRS"""
        if crs is None:
            crs = self.getGetMapCrs(self.iface)
        
        #convert list ed. to QgsPointXY
        if isinstance( xyMax, Iterable ): xyMax = QgsPointXY( list(xyMax)[0], list(xyMax)[1])
        if isinstance( xyMin, Iterable ): xyMin = QgsPointXY( list(xyMin)[0], list(xyMin)[1])
        
        pmaxpoint = self.prjPtToMapCrs(xyMax, crs)
        pminpoint = self.prjPtToMapCrs(xyMin, crs)
        
        # Create a rectangle to cover the new extent
        rect = QgsRectangle( pmaxpoint, pminpoint )
    
        # Set the extent to our new rectangle
        self.iface.mapCanvas().setExtent(rect)
        # Refresh the map
        self.iface.mapCanvas().refresh()
    
    def zoomtoRec2(self, bounds, crs=None):
        "zoom to rectangle from a list containing: [xmin,ymin,xmax,ymax] with given crs, default= mapCRS"
        if crs is None:
            crs = self.getGetMapCrs(self.iface)
            
        maxpoint = QgsPointXY( bounds[0], bounds[1])
        minpoint = QgsPointXY( bounds[2], bounds[3])
        
        pmaxpoint = self.prjPtToMapCrs(maxpoint, crs)
        pminpoint = self.prjPtToMapCrs(minpoint, crs)
      
        # Create a rectangle to cover the new extent
        rect = QgsRectangle( pmaxpoint, pminpoint )
    
        # Set the extent to our new rectangle
        self.iface.mapCanvas().setExtent(rect)
        # Refresh the map
        self.iface.mapCanvas().refresh()

    def save_adres_point(self, point, address, typeAddress='', layername="Geopunt_adres", saveToFile=False, sender=None, startFolder=None ):
        attributes = [QgsField("adres", QVariant.String), QgsField("type", QVariant.String)]
        mapcrs = self.getGetMapCrs(self.iface)
        
        if not QgsProject.instance().mapLayer(self.adreslayerid):
            self.adreslayer = QgsVectorLayer("Point", layername, "memory")
            self.adresProvider = self.adreslayer.dataProvider()
            self.adresProvider.addAttributes(attributes)
            self.adreslayer.updateFields()

        # add a feature
        fields= self.adreslayer.fields()
        fet = QgsFeature(fields)

        #set geometry and project from mapCRS
        xform = QgsCoordinateTransform( mapcrs, self.adreslayer.crs(), QgsProject.instance() )
        prjPoint = xform.transform( point )
        fet.setGeometry(QgsGeometry.fromPointXY(prjPoint))

        #populate fields
        fet['adres'] = address
        fet['type'] = typeAddress
        self.adresProvider.addFeatures([ fet ])
        ""
        # update layer's extent when new features have been added
        # because change of extent in provider is not propagated to the layer
        self.adreslayer.updateExtents()
        
        # save memoryLAYER to file and replace all references    
        if saveToFile and not QgsProject.instance().mapLayer(self.adreslayerid): 
          save = self._saveToFile( sender, startFolder )
          if save:
            fpath, flType = save                
            error, msg = QgsVectorFileWriter.writeAsVectorFormat(self.adreslayer, fileName=fpath, fileEncoding="utf-8", driverName=flType)
            if error == QgsVectorFileWriter.NoError:
              self.adreslayer = QgsVectorLayer( fpath, layername, "ogr")
              self.adresProvider = self.adreslayer.dataProvider()
            else: 
              del self.adreslayer, self.adresProvider 
              return
          else: 
            del self.adreslayer, self.adresProvider 
            return
          
        #  add to map
        QgsProject.instance().addMapLayer(self.adreslayer)
        
        #labels
        text_format = QgsTextFormat()
        text_format.setSize(12)
        buffer_settings = QgsTextBufferSettings()
        buffer_settings.setEnabled(True)
        buffer_settings.setSize(1)
        buffer_settings.setColor(QColor("white"))
        
        palyr = QgsPalLayerSettings() 
        text_format.setBuffer(buffer_settings)
        palyr.setFormat(text_format)
        
        palyr.enabled = True 
        palyr.fieldName = 'adres' 
        palyr.placement = QgsPalLayerSettings.Free 

        self.adreslayer.setLabelsEnabled(True)
        self.adreslayer.setLabeling( QgsVectorLayerSimpleLabeling(palyr) )
       
        # store layer id and refresh      
        self.adreslayerid = self.adreslayer.id()
        self.canvas.refresh()
      
    def _saveToFile( self, sender, startFolder=None ):
        'save to file'
        filter = "OGC GeoPackage (*.gpkg);;ESRI Shape Files (*.shp);;SpatiaLite (*.sqlite);;Geojson File (*.geojson);;GML ( *.gml);;Comma separated value File (excel) (*.csv);;MapInfo TAB (*.TAB);;Any File (*.*)" 
        Fdlg = QFileDialog()
        Fdlg.setFileMode(QFileDialog.AnyFile)
        fName, __ = QFileDialog.getSaveFileName(sender, "open file", filter=filter, directory=startFolder)
        if fName:
          ext = os.path.splitext( fName )[1]
          if "GPKG" in ext.upper():
            flType = "GPKG"
          elif "SHP" in ext.upper():
            flType = "ESRI Shapefile"
          elif "SQLITE" in ext.upper():
            flType = "SQLite" 
          elif "GEOJSON" in ext.upper():  #no update possible -> hidden
            flType = "GeoJSON"
          elif "GML" in ext.upper():
            flType = "GML"
          elif 'TAB' in ext.upper():
            flType = 'MapInfo File'
          elif 'CSV' in ext.upper():
            flType = 'CSV'
          else:
            fName = fName + ".shp"
            flType = "ESRI Shapefile"
          return (fName , flType )
        else:
            return None
      
    def addPointGraphic(self, xy, color="#FFFF00", size=1, pen=10, markerType=QgsVertexMarker.ICON_BOX ):
        "create a point Graphic at location xy and return it"
        pt = QgsPointXY(xy[0], xy[1]) if isinstance( xy, Iterable) else QgsPointXY(xy)
        m = QgsVertexMarker(self.canvas)
        m.setCenter(pt)
        m.setColor(QColor(color))
        m.setIconSize(size)
        m.setIconType(markerType) 
        m.setPenWidth(pen)
        return m

    @staticmethod
    def getBoundsOfPointArray( pointArray, delta=100):
        minX = 1.7976931348623157e+308
        maxX = -1.7976931348623157e+308
        minY = 1.7976931348623157e+308
        maxY = -1.7976931348623157e+308
    
        for xy in pointArray:
            x, y = list(xy)[:2]
            if x > maxX: maxX = x
            if x < minX: minX = x
            if y > maxY: maxY = y
            if y < minY: minY = y
          
        Xdelta = (maxX - minX) /delta
        Ydelta = (maxY - minY) /delta
        
        return [ minX - Xdelta, minY - Ydelta, maxX + Xdelta, maxY + Ydelta]
    
    @staticmethod
    def getBoundsOfPoint( x, y, delta=None):
      if delta is None:
        if x >= 360:
            delta = 300 #x bigger then 360 -> meters
        else:
            delta = 0.0025 #x smaller then 360 -> degrees
      
        xmax = x + delta
        xmin = x - delta
        ymax = y + delta
        ymin = y - delta
        
        return [xmin, ymin, xmax,ymax]
Exemple #17
0
    def saveToLayer(self):
        units = self.unitDesignator()
        canvasCrs = self.canvas.mapSettings().destinationCrs()
        fields = QgsFields()
        fields.append(QgsField("label", QVariant.String))
        fields.append(QgsField("value", QVariant.Double))
        fields.append(QgsField("units", QVariant.String))
        fields.append(QgsField("heading_to", QVariant.Double))
        fields.append(QgsField("heading_from", QVariant.Double))
        fields.append(QgsField("total_dist", QVariant.Double))

        layer = QgsVectorLayer("LineString?crs={}".format(canvasCrs.authid()),
                               "Measurements", "memory")
        dp = layer.dataProvider()
        dp.addAttributes(fields)
        layer.updateFields()

        num = len(self.capturedPoints)
        total = 0.0
        for i in range(1, num):
            (distance, startA,
             endA) = self.calcParameters(self.capturedPoints[i - 1],
                                         self.capturedPoints[i])
            total += distance
        total = self.unitDistance(total)
        for i in range(1, num):
            (distance, startA,
             endA) = self.calcParameters(self.capturedPoints[i - 1],
                                         self.capturedPoints[i])
            pts = self.getLinePts(distance, self.capturedPoints[i - 1],
                                  self.capturedPoints[i])
            distance = self.unitDistance(distance)
            feat = QgsFeature(layer.fields())
            feat.setAttribute(
                0, "{:.{prec}f} {}".format(
                    distance,
                    units,
                    prec=settings.saveToLayerSignificantDigits))
            feat.setAttribute(1, distance)
            feat.setAttribute(2, units)
            feat.setAttribute(3, startA)
            feat.setAttribute(4, endA)
            feat.setAttribute(5, total)
            feat.setGeometry(QgsGeometry.fromPolylineXY(pts))
            dp.addFeatures([feat])

        label = QgsPalLayerSettings()
        label.fieldName = 'label'
        try:
            label.placement = QgsPalLayerSettings.Line
        except Exception:
            label.placement = QgsPalLayerSettings.AboveLine
        format = label.format()
        format.setColor(settings.measureTextColor)
        format.setNamedStyle('Bold')
        label.setFormat(format)
        labeling = QgsVectorLayerSimpleLabeling(label)
        layer.setLabeling(labeling)
        layer.setLabelsEnabled(True)
        renderer = layer.renderer()
        renderer.symbol().setColor(settings.measureLineColor)
        renderer.symbol().setWidth(0.5)

        layer.updateExtents()
        QgsProject.instance().addMapLayer(layer)
Exemple #18
0
def my_shortest_path(pointTool):
    try:
        #reading the coordinate of the points clicked
        #and writing in a string format to call shortest path algorithm

        startPoint = str(pointTool.x()) + "," + str(
            pointTool.y()) + " [EPSG:4326-WGS84]"
        endPoint = "144.963403,-37.808179 [EPSG:4326-WGS84]"  #coordinate of RMIT

        #path to the road network data (please change accordingly)
        roads_path = r"/Users/chhanda/Desktop/GIS_Programming/Major_project/Street_network_2018/shp/road.shp"
        #set outputfile directory
        outputfilepath = r"Users/chhanda/Desktop/GIS_Programming/Major_project/"

        #setting up the shortest path parameters
        shortestpathParam = {
            'DEFAULT_DIRECTION': 2,
            'DEFAULT_SPEED': 50,
            'DIRECTION_FIELD': None,
            'END_POINT': endPoint,
            'ENTRY_COST_CALCULATION_METHOD': 0,
            'INPUT': roads_path,
            'OUTPUT': outputfilepath + "shortestpath_output",
            'SPEED_FIELD': None,
            'START_POINT': startPoint,
            'STRATEGY': 0,
            'TOLERANCE': 0,
            'VALUE_BACKWARD': '',
            'VALUE_BOTH': '',
            'VALUE_FORWARD': ''
        }
        processing.run("qneat3:shortestpathpointtopoint", shortestpathParam)

        #loading the shortest path layer from the poutput of the previous processing run
        sp_file_path = outputfilepath + "shortestpath_output.gpkg"
        sp_layer = QgsVectorLayer(sp_file_path, "shortest_path", "ogr")
        if not sp_layer.isValid():
            print("Shortest Path Layer failed to load!")

        #loading road network layer
        road_layer = QgsVectorLayer(roads_path, "roads", "ogr")
        if not road_layer.isValid():
            print("road Layer failed to load!")

        #setting the url of the base layer from ESRI
        base_layer = QgsRasterLayer(
            "http://server.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer?f=json&pretty=true",
            "raster")

        #styling the shortest path layer (color and line width)
        sp_layer.renderer().symbol().setWidth(0.6)
        sp_layer.renderer().symbol().setColor(QColor("red"))

        #creating a point layer to show the start point and the end point
        point_layer = QgsVectorLayer("Point", "temporary_points", "memory")
        pr = point_layer.dataProvider()
        #enter editing mode
        point_layer.startEditing()
        #add a field to display the labels
        pr.addAttributes([QgsField("name", QVariant.String)])
        point_layer.updateFields()
        #add features
        fet = QgsFeature()
        fet.setGeometry(
            QgsGeometry.fromPointXY(QgsPointXY(pointTool.x(), pointTool.y())))
        pr.addFeatures([fet])
        point_layer.changeAttributeValue(1, 0, "Your Home")
        fet.setGeometry(
            QgsGeometry.fromPointXY(QgsPointXY(144.963403, -37.808179)))
        pr.addFeatures([fet])
        point_layer.changeAttributeValue(2, 0, "RMIT UNIVERSITY")
        # Commit changes
        point_layer.commitChanges()

        #styling the point layer (size and color)
        point_layer.renderer().symbol().setSize(6)
        point_layer.renderer().symbol().setColor(QColor("red"))

        #styling the labels to make them appear with white background
        layer_settings = QgsPalLayerSettings()
        text_format = QgsTextFormat()

        background_color = QgsTextBackgroundSettings()
        background_color.setFillColor(QColor('white'))
        background_color.setEnabled(True)

        text_format.setFont(QFont("Arial", 12))
        text_format.setSize(12)
        text_format.setBackground(background_color)

        buffer_settings = QgsTextBufferSettings()
        buffer_settings.setEnabled(True)
        buffer_settings.setSize(0.10)
        buffer_settings.setColor(QColor("black"))

        text_format.setBuffer(buffer_settings)
        layer_settings.setFormat(text_format)

        layer_settings.fieldName = "name"
        layer_settings.placement = 4

        layer_settings.enabled = True

        layer_settings = QgsVectorLayerSimpleLabeling(layer_settings)
        point_layer.setLabelsEnabled(True)
        point_layer.setLabeling(layer_settings)

        #initialising an output fgrame
        output_canvas = QgsMapCanvas()
        #chosing the layers to display
        output_canvas.setLayers([sp_layer, point_layer, base_layer])
        #getting the extent of the shortest path layer to zoom into the path
        ext = sp_layer.extent()
        xmin = ext.xMinimum()
        xmax = ext.xMaximum()
        ymin = ext.yMinimum()
        ymax = ext.yMaximum()
        #setting extent of the output to that of a box slightly larger than the shortest path layer
        #such that the labels don't get chopped
        output_canvas.setExtent(
            QgsRectangle(xmin - 0.01, ymin - 0.01, xmax + 0.01, ymax + 0.01))
        output_canvas.show()

        #the function raises an error because eiting without error causes the output window to disappear
        raise

    except AttributeError:
        pass
    def run(self):
        """Run method that performs all the real work"""

        # 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.first_start = False
            self.dlg = ReanalysisVisualizationDialog()

        project = QgsProject.instance()
        if not project.mapLayersByName('back'):
            layer = QgsVectorLayer(
                './background/ne_110m_admin_0_countries.shp', "back", "ogr")
            project.addMapLayer(layer)

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            params, variables, drawStyle, need_slideshow = self.dlg.prepare_form_data()
            try:
                root = QgsProject.instance().layerTreeRoot()

                group = root.findGroup('contours')
                if group:
                    group.removeAllChildren()
                else:
                    group = root.addGroup("contours")

                root.insertChildNode(-1,
                                     QgsLayerTreeLayer(project.mapLayersByName('back')[0]))
                root.removeLayer(project.mapLayersByName('back')[0])
                data_grid = DataGrid(params, variables)
                geojsons = Isolines(data_grid, drawStyle).get_geojsons()

                for geojson in geojsons:
                    layer = QgsVectorLayer(
                        geojson['geojson'], "leadTime = " + str(geojson['leadTime']), "ogr")
                    layer.setOpacity(0.87)
                    # apply contour style properties
                    symbol_layer = layer.renderer().symbol().symbolLayers()[0]
                    symbol_layer.setDataDefinedProperty(
                        QgsSymbolLayer.PropertyStrokeColor, QgsProperty.fromField("stroke"))
                    symbol_layer.setDataDefinedProperty(
                        QgsSymbolLayer.PropertyFillColor, QgsProperty.fromField("fill"))
                    symbol_layer.setDataDefinedProperty(
                        QgsSymbolLayer.PropertyStrokeWidth, QgsProperty.fromField("stroke-width"))

                    # add labels
                    pal_layer = QgsPalLayerSettings()
                    pal_layer.fieldName = 'title'
                    pal_layer.enabled = True
                    pal_layer.placement = QgsPalLayerSettings.PerimeterCurved
                    pal_layer.placementFlags = QgsPalLayerSettings.OnLine

                    labeler = QgsVectorLayerSimpleLabeling(pal_layer)

                    layer.setLabeling(labeler)
                    layer.setLabelsEnabled(True)

                    # add vector layer with isolines
                    QgsProject.instance().addMapLayer(layer, False)
                    group.insertChildNode(-1, QgsLayerTreeLayer(layer))
                group.setIsMutuallyExclusive(True, 0)
                if need_slideshow:
                    slideshow = threading.Thread(
                        target=self.__change_active_layer, args=(group,))
                    slideshow.start()
            except Exception as e:
                error_text = ''

                if (params['east'] > 180 or params['east'] < -180 or params['west'] > 180 or params['west'] < -180 or params['south'] > 90 or params['south'] < -90 or params['north'] > 90 or params['north'] < -90):
                    error_text += "Ошибка: Некорректно заданы координаты области"
                else:
                    error_text += "Ошибка: \n" + str(e)
                error_dialog = QErrorMessage()
                error_dialog.showMessage(error_text)
                error_dialog.exec_()
Exemple #20
0
    def run(self):
        print("paso por el run")

        #coloco el puntero arriba del todo
        QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint(
            QgsProject.instance().layerTreeRoot(), 0)

        def haceelcruce(x1, y1, ang1, x2, y2, ang2):
            #saco las pendientes
            m1 = (1 / math.tan(math.radians(ang1 + 0.000001)))
            m2 = (1 / math.tan(math.radians(ang2 + 0.000001)))
            #print ("m1")
            #print (m1)
            #print("m2")
            #print (m2)

            #saco las coordenadas de x e y
            x = ((y2 - y1) + (m1 * x1) - (m2 * x2)) / ((m1 - m2) + 0.000001)
            y = m1 * x + y1 - m1 * x1

            #compruebo que el cruce no es erroneo
            if ang1 > 0 and ang1 < 180 and x < x1:
                iface.messageBar().pushMessage(
                    "OJO: LAS VISUALES NO SE CRUZAN", qgisCore.Qgis.Info, 5)
                x, y, error = 0, 0, 0
            if ang1 > 180 and ang1 < 360 and x > x1:
                iface.messageBar().pushMessage(
                    "OJO: LAS VISUALES NO SE CRUZAN", qgisCore.Qgis.Info, 5)
                x, y, error = 0, 0, 0
            if ang1 > 0 and ang1 < 90 and y < y1:
                iface.messageBar().pushMessage(
                    "OJO: LAS VISUALES NO SE CRUZAN", qgisCore.Qgis.Info, 5)
                x, y, error = 0, 0, 0
            if ang1 > 270 and ang1 < 360 and y < y1:
                iface.messageBar().pushMessage(
                    "OJO: LAS VISUALES NO SE CRUZAN", qgisCore.Qgis.Info, 5)
                x, y, error = 0, 0, 0
            if ang1 > 90 and ang1 < 270 and y > y1:
                iface.messageBar().pushMessage(
                    "OJO: LAS VISUALES NO SE CRUZAN", qgisCore.Qgis.Info, 5)
                x, y, error = 0, 0, 9999999999999999999999999
            else:

                #calculo el error
                d1a = math.sqrt((x - x1)**2 + (y - y1)**2)
                d2a = math.sqrt((x - x2)**2 + (y - y2)**2)
                d12 = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
                A = math.acos((d1a**2 + d2a**2 - d12**2) / (2 * d1a * d2a))
                if math.degrees(A) > 90:
                    A = math.pi - A
                distancias = [d1a, d2a]
                distancias.sort(reverse=True)
                mayordistancia = distancias[0]

                error = mayordistancia * erroralidada / (math.sin(A / 2) +
                                                         0.000001)
                #print (ang1,ang2)
                #print (x,y,error)
            return x, y, error

        def generapunto(x, y):
            #creo una capa de puntos temporal con los resultados
            # create layer
            vl = QgsVectorLayer("Point?crs=epsg:25830", "Pto_Cruce", "memory")
            pr = vl.dataProvider()
            #print ("ok creada la capa")
            vl.startEditing()
            # add fields
            pr.addAttributes([
                QgsField("error", QVariant.Int),
                QgsField("x", QVariant.Int),
                QgsField("y", QVariant.Double)
            ])
            vl.updateFields()
            # tell the vector layer to fetch changes from the provider
            #print ("ok creados los campos")
            # add a feature
            fet = QgsFeature()
            fet.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))

            fet.setAttributes([error, x, y])
            pr.addFeatures([fet])
            #print ("ok, anadido el elemento con error "+str(error))
            #cambio la simbologia
            symbol = QgsMarkerSymbol.createSimple({
                'name': 'circle',
                'color': 'orange',
                'size': '5',
            })
            vl.renderer().setSymbol(symbol)

            # update layer's extent when new features have been added
            # because change of extent in provider is not propagated to the layer
            #vl.updateExtents()
            vl.commitChanges()
            #vl.updateExtents()
            # show the point
            if x != 0 and y != 0:
                QgsProject.instance().addMapLayers([vl])
                canvas = self.iface.mapCanvas()
            #canvas.setExtent(vl.extent())
            #vl.updateFieldMap()

        def generalinea(x, y, angulo):
            m = (1 / math.tan(math.radians(angulo + 0.000001)))
            x1 = x + 100000 * math.sin(math.radians(angulo + 0.0000001))
            y1 = y - m * (x - x1)

            line_start = QgsPoint(x, y)
            line_end = QgsPoint(x1, y1)
            #print (m)

            # create a new memory layer
            v_layer = QgsVectorLayer("LineString?crs=epsg:25830", "visual",
                                     "memory")
            pr = v_layer.dataProvider()
            # create a new feature
            seg = QgsFeature()
            # add the geometry to the feature,
            seg.setGeometry(QgsGeometry.fromPolyline([line_start, line_end]))
            # add the geometry to the layer
            pr.addFeatures([seg])
            # update extent of the layer (not necessary)
            v_layer.updateExtents()
            #cambio la simbologia
            symbol3 = QgsLineSymbol.createSimple({
                'penstyle': 'solid',
                'color': 'yellow',
                'width': '2'
            })
            v_layer.renderer().setSymbol(symbol3)
            # show the line
            QgsProject.instance().addMapLayers([v_layer])

        def deg_to_dms(deg, type='lat'):
            decimals, number = math.modf(deg)
            d = int(number)
            m = int(decimals * 60)
            s = (deg - d - m / 60) * 3600.00
            compass = {'lat': ('N', 'S'), 'lon': ('E', 'W')}
            compass_str = compass[type][0 if d >= 0 else 1]
            return '{}º{}\'{:.2f}"{}'.format(abs(d), abs(m), abs(s),
                                             compass_str)

        erroralidada = 1
        #selecciono la capa de las torretas
        global rutapuestosvigiancia
        layer = QgsVectorLayer(rutapuestosvigiancia,
                               '42_Puestos_vigilancia_etrs89', 'ogr')
        time.sleep(1)
        #layer = iface.activeLayer()
        ## ojo comprobar que layer existe
        """if layer is None or (layer.type() == RasterLayer):
            iface.messageBar().pushMessage("Warning:",  u"Seleciona la capa de los puestos de vigilancia",  QgsMessageBar.WARNING, 10) """
        #genero una lista con las torres y ls coordenadas
        misdatos = []
        feats = [feat for feat in layer.getFeatures()]
        for feature in feats:
            if feature.geometry().type(
            ) != 0:  #0 es ptos, 1 lineas y 2 poligonos QGis.Point:
                iface.messageBar().pushMessage(
                    "Warning:", u"Debe selecionar una capa de puntos",
                    QgsMessageBar.WARNING, 10)
            point = []

            idTM = layer.dataProvider().fieldNameIndex('Nombre')
            idx = layer.dataProvider().fieldNameIndex('x')
            idy = layer.dataProvider().fieldNameIndex('y')

            point = [
                feature.attributes()[idTM],
                feature.attributes()[idx],
                feature.attributes()[idy]
            ]
            misdatos.append(point)
        #trato de rellenar el desplegable con las torretas
        #self.dlg.cb1.clear()

        #ordeno por el primer elemento
        misdatos.sort(key=lambda x: x[0])
        #anado un elemneto enblanco en el desplegable
        self.dlg.cb1.clear()
        self.dlg.cb2.clear()
        self.dlg.cb3.clear()
        self.dlg.cb4.clear()
        self.dlg.cb1.addItem("")
        self.dlg.cb2.addItem("")
        self.dlg.cb3.addItem("")
        self.dlg.cb4.addItem("")
        for element in misdatos:
            self.dlg.cb1.addItem(element[0])
            self.dlg.cb2.addItem(element[0])
            self.dlg.cb3.addItem(element[0])
            self.dlg.cb4.addItem(element[0])
        #count vertices if there is layer in project in order to show it when dialog is loaded
        #layer = self.dlg.cb1.itemData(self.cb1.currentIndex())
        """Run method that performs all the real work"""

        # 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.first_start = False
            #self.dlg = SilvilidarDialog()
            #la siguiente linea inicia el boton de cargar carpetas, peta al cerrar el qgis, deberia poner algun close o algo
            #self.dlg.pushButton_select_path.clicked.connect(self.select_laz_folder)
            #print("inicio el boton en el gui")
            #self.dlg.pushButton_select_path.setEnabled(True)
            #print ("pone le boton como habiltado")

        # show the dialog
        self.dlg.show()

        #self.dlg.pushButton_select_path.clicked.connect(self.select_laz_folder)

        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            #print ("lo imprime si le doy a aceptar en el dialogo")

            #la carpeta la he cogido al pulsar el boton de la carpeta

            #meto aqui variables que luego deberan estar en la cajita   OJO
            torret1 = self.dlg.cb1.currentIndex()
            torret2 = self.dlg.cb2.currentIndex()
            torret3 = self.dlg.cb3.currentIndex()
            torret4 = self.dlg.cb4.currentIndex()
            angulo1 = self.dlg.ang1.text()  ##displayText()
            angulo2 = self.dlg.ang2.text()  ##displayText()
            angulo3 = self.dlg.ang3.text()  ##displayText()
            angulo4 = self.dlg.ang4.text()  ##displayText()
            if angulo2 == "":
                angulo2 = 9999
            if angulo3 == "":
                angulo3 = 9999
            if angulo4 == "":
                angulo4 = 9999
            try:
                ang1 = float(angulo1)
                ang2 = float(angulo2)
                ang3 = float(angulo3)
                ang4 = float(angulo4)
            except:
                pass
            #print (misdatos)

            torre1 = misdatos[int(torret1) - 1][0]
            x1 = float(misdatos[int(torret1) - 1][1])
            y1 = float(misdatos[int(torret1) - 1][2])
            torre2 = misdatos[int(torret2) - 1][0]
            x2 = float(misdatos[int(torret2) - 1][1])
            y2 = float(misdatos[int(torret2) - 1][2])
            torre3 = misdatos[int(torret3) - 1][0]
            x3 = float(misdatos[int(torret3) - 1][1])
            y3 = float(misdatos[int(torret3) - 1][2])
            torre4 = misdatos[int(torret4) - 1][0]
            x4 = float(misdatos[int(torret4) - 1][1])
            y4 = float(misdatos[int(torret4) - 1][2])

            #print (angulo1, angulo2, angulo3, angulo4)
            #print (torret1)
            #print (torre1, x1, y1)
            #print (torret2)
            #print (torre2, x2, y2)
            #print (torret3)
            #print (torret4)

            generalinea(x1, y1, ang1)
            resultado = []
            if angulo2 != 9999:
                generalinea(x2, y2, ang2)
                x, y, error = haceelcruce(x1, y1, ang1, x2, y2, ang2)
                #print ("hecho el cruce")
                #print  (x,y, error)

                generapunto(x, y)
                resultado = []
                resultado.append(x)
                resultado.append(y)
                resultado.append(error)
            if angulo3 != 9999:
                generalinea(x3, y3, ang3)
                x, y, error = haceelcruce(x1, y1, ang1, x3, y3, ang3)

                generapunto(x, y)
                if error < resultado[2]:
                    resultado = []
                    resultado.append(x)
                    resultado.append(y)
                    resultado.append(error)
                x, y, error = haceelcruce(x2, y2, ang2, x3, y3, ang3)

                generapunto(x, y)
                if error < resultado[2]:
                    resultado = []
                    resultado.append(x)
                    resultado.append(y)
                    resultado.append(error)
            if angulo4 != 9999:
                generalinea(x4, y4, ang4)
                #print ("empiezo el angulo4")
                x, y, error = haceelcruce(x1, y1, ang1, x4, y4, ang4)

                generapunto(x, y)
                if error < resultado[2]:
                    resultado = []
                    resultado.append(x)
                    resultado.append(y)
                    resultado.append(error)
                x, y, error = haceelcruce(x2, y2, ang2, x4, y4, ang4)

                generapunto(x, y)

                if error < resultado[2]:
                    resultado = []
                    resultado.append(x)
                    resultado.append(y)
                    resultado.append(error)
                x, y, error = haceelcruce(x3, y3, ang3, x4, y4, ang4)

                generapunto(x, y)

                if error < resultado[2]:
                    resultado = []
                    resultado.append(x)
                    resultado.append(y)
                    resultado.append(error)

            #hago una nueva capa con el mejor resultado
            if resultado != []:
                x, y, error = resultado[0], resultado[1], resultado[2]

                if x != 0 and y != 0:
                    #creo una capa temporal con los resultados
                    # create layer
                    vl2 = QgsVectorLayer("Point?crs=epsg:25830",
                                         "MejorResultado", "memory")
                    pr2 = vl2.dataProvider()
                    #print ("ok creada la capa resultado final")
                    vl2.startEditing()
                    #calculo las coordenadas geograficas
                    huso = 30
                    origenProj = pyproj.Proj(proj="utm",
                                             zone=huso,
                                             ellps="WGS84",
                                             units="m")
                    destinoProj = pyproj.Proj(proj='longlat',
                                              ellps='WGS84',
                                              datum='WGS84')
                    xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                    xx = (deg_to_dms(xxx, 'lon'))
                    yy = (deg_to_dms(yyy))

                    # add fields
                    pr2.addAttributes([
                        QgsField("error", QVariant.Int),
                        QgsField("x", QVariant.Double),
                        QgsField("y", QVariant.Double),
                        QgsField("xx", QVariant.String),
                        QgsField("yy", QVariant.String)
                    ])
                    vl2.updateFields()
                    # tell the vector layer to fetch changes from the provider
                    #print ("ok creados los campos")
                    #$add a feature
                    fet = QgsFeature()
                    fet.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
                    fet.setAttributes([error, x, y, xx, yy])
                    pr2.addFeatures([fet])
                    print("MEJOR RESULTADO")
                    print(int(resultado[0]), int(resultado[1]))
                    #print ("ok, creda la capa con el resultado final")
                    #cambio la simbologia
                    symbol = QgsMarkerSymbol.createSimple({
                        'name': 'circle',
                        'color': 'red',
                        'size': '10',
                    })
                    vl2.renderer().setSymbol(symbol)

                    #etiqueto con la x e y
                    layer_settings = QgsPalLayerSettings()
                    text_format = QgsTextFormat()

                    text_format.setFont(QFont("Arial", 12))
                    text_format.setSize(12)
                    text_format.setColor(QColor("Orange"))

                    # meto un buffer a la etiqueta
                    buffer_settings = QgsTextBufferSettings()
                    buffer_settings.setEnabled(True)
                    buffer_settings.setSize(1)
                    buffer_settings.setColor(QColor("white"))

                    text_format.setBuffer(buffer_settings)
                    layer_settings.setFormat(text_format)
                    #myexp=QgsExpression('''concat('X: ',"X",' Y: ',"Y")''')
                    layer_settings.fieldName = '''concat('X: ',round("X",0),' Y: ',round("Y",0),'\n','Lat: ',"yy",' Lon: ',"xx")'''
                    layer_settings.isExpression = True
                    #layer_settings.placement = 7
                    #layer_settings.quadOffset = QgsPalLayerSettings.QuadrantBelow
                    #layer_settings.yOffset = 1

                    layer_settings.enabled = True

                    layer_settings = QgsVectorLayerSimpleLabeling(
                        layer_settings)
                    vl2.setLabelsEnabled(True)
                    vl2.setLabeling(layer_settings)
                    vl2.triggerRepaint()

                    # update layer's extent when new features have been added
                    # because change of extent in provider is not propagated to the layer
                    vl2.updateExtents()
                    vl2.commitChanges()
                    vl2.updateExtents()
                    canvas = self.iface.mapCanvas()
                    canvas.setExtent(vl2.extent())
                    self.iface.mapCanvas().zoomScale(100000)

                    #QgsProject.instance().addMapLayer(vl)
                    QgsProject.instance().addMapLayer(vl2)

            pass
Exemple #21
0
    def testClippingHideClipSource(self):
        """
        When an item is set to be the clip source, it shouldn't render anything itself
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(30)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'XXXX'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl",
                            "memory")

        props = {
            "color": "127,255,127",
            'outline_style': 'solid',
            'outline_width': '1',
            'outline_color': '0,0,255'
        }
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        vl.setRenderer(renderer)

        f = QgsFeature(vl.fields(), 1)
        for x in range(0, 15, 3):
            for y in range(0, 15, 3):
                f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(False)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        shape = QgsLayoutItemShape(layout)
        layout.addLayoutItem(shape)
        shape.setShapeType(QgsLayoutItemShape.Ellipse)
        shape.attemptSetSceneRect(QRectF(10, 10, 180, 180))

        map.itemClippingSettings().setEnabled(True)
        map.itemClippingSettings().setSourceItem(shape)
        map.itemClippingSettings().setForceLabelsInsideClipPath(False)
        map.itemClippingSettings().setFeatureClippingType(
            QgsMapClippingRegion.FeatureClippingType.ClipToIntersection)

        checker = QgsLayoutChecker('composermap_itemclip_nodrawsource', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        TestQgsLayoutMap.report += checker.report()
        self.assertTrue(result, message)
Exemple #22
0
class poiHelper(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.poilayerid = ''
        self.minPoilayerid = ''

    def save_minPois_points(self,
                            points,
                            layername="Geopunt_poi",
                            saveToFile=None,
                            sender=None,
                            startFolder=None):
        attributes = [
            QgsField("id", QVariant.Int),
            QgsField("type", QVariant.String),
            QgsField("name", QVariant.String),
            QgsField("straat", QVariant.String),
            QgsField("huisnr", QVariant.String),
            QgsField("busnr", QVariant.String),
            QgsField("postcode", QVariant.String),
            QgsField("gemeente", QVariant.String),
            QgsField("link", QVariant.String),
            QgsField("count", QVariant.Int)
        ]

        if not QgsProject.instance().mapLayer(self.minPoilayerid):
            self.minpoilayer = QgsVectorLayer("Point", layername, "memory")
            self.minpoiProvider = self.minpoilayer.dataProvider()
            self.minpoiProvider.addAttributes(attributes)
            self.minpoilayer.updateFields()

        fields = self.minpoilayer.fields()

        for point in points["pois"]:
            pt = QgsPointXY(
                point['location']['points'][0]['Point']['coordinates'][0],
                point['location']['points'][0]['Point']['coordinates'][1])
            poiId = point["id"]

            if "address" in point['location']:
                if "street" in point['location']["address"]:
                    straat = point['location']["address"]["street"]
                else:
                    straat = ''
                if "streetnumber" in point['location']["address"]:
                    huisnr = point['location']["address"]["streetnumber"]
                else:
                    huisnr = ''
                if "boxnumber" in point['location']["address"]:
                    busnr = point['location']["address"]["boxnumber"]
                else:
                    busnr = ''
                postcode = point['location']["address"]["postalcode"]
                gemeente = point['location']["address"]["municipality"]
            else:
                straat = ""
                huisnr = ""
                busnr = ""
                postcode = ""
                gemeente = ""

            if "categories" in point and len(point["categories"]) > 0:
                poiType = point["categories"][0]["value"]
            else:
                poiType = ''
            if "labels" in point and len(point["labels"]) > 0:
                name = point["labels"][0]["value"]
            else:
                name = ''
            if "links" in point:
                link = point["links"][0]["href"]
            else:
                link = ''

            # add a feature
            fet = QgsFeature(fields)

            #set geometry
            fromCrs = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform(fromCrs, self.minpoilayer.crs(),
                                           QgsProject.instance())
            prjPt = xform.transform(pt)
            fet.setGeometry(QgsGeometry.fromPointXY(prjPt))

            fet['id'] = int(poiId)
            fet['straat'] = straat
            fet['huisnr'] = huisnr
            fet['busnr'] = busnr
            fet['postcode'] = postcode
            fet['gemeente'] = gemeente
            fet['type'] = poiType
            fet['name'] = name
            fet['link'] = link

            self.minpoiProvider.addFeatures([fet])

        for point in points["clusters"]:
            pt = QgsPointXY(point['point']['Point']['coordinates'][0],
                            point['point']['Point']['coordinates'][1])
            poiType = point['point']['type']
            count = point['count']

            # add a feature
            fet = QgsFeature(fields)

            #set geometry
            fromCrs = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform(fromCrs, self.minpoilayer.crs(),
                                           QgsProject.instance())
            prjPt = xform.transform(pt)
            fet.setGeometry(QgsGeometry.fromPointXY(prjPt))

            fet['type'] = poiType
            fet['count'] = count

            self.minpoiProvider.addFeatures([fet])

        if saveToFile and not QgsProject.instance().mapLayer(
                self.minPoilayerid):
            save = self._saveToFile(sender, startFolder)
            if save:
                fpath, flType = save
                error, msg = QgsVectorFileWriter.writeAsVectorFormat(
                    self.minpoilayer,
                    fileName=fpath,
                    fileEncoding="utf-8",
                    driverName=flType)
                if error == QgsVectorFileWriter.NoError:
                    self.minpoilayer = QgsVectorLayer(fpath, layername, "ogr")
                    self.minpoiProvider = self.minpoilayer.dataProvider()
                else:
                    del self.minpoilayer, self.minpoiProvider
                    raise Exception(msg)
            else:
                del self.minpoilayer, self.minpoiProvider
                return

        # add layer if not already
        QgsProject.instance().addMapLayer(self.minpoilayer)

        # store layer id and refresh
        self.minPoilayerid = self.minpoilayer.id()
        self.minpoilayer.updateExtents()
        self.canvas.refresh()

    def save_pois_points(self,
                         points,
                         layername="Geopunt_poi",
                         saveToFile=None,
                         sender=None,
                         startFolder=None):
        attributes = [
            QgsField("id", QVariant.Int),
            QgsField("thema", QVariant.String),
            QgsField("categorie", QVariant.String),
            QgsField("type", QVariant.String),
            QgsField("naam", QVariant.String),
            QgsField("telefoon", QVariant.String),
            QgsField("email", QVariant.String),
            #address
            QgsField("straat", QVariant.String),
            QgsField("huisnr", QVariant.String),
            QgsField("busnr", QVariant.String),
            QgsField("postcode", QVariant.String),
            QgsField("gemeente", QVariant.String),
            QgsField("link", QVariant.String),
            QgsField("lastupdate", QVariant.String),
            QgsField("owner", QVariant.String)
        ]

        if not QgsProject.instance().mapLayer(self.poilayerid):
            self.poilayer = QgsVectorLayer("Point", layername, "memory")
            self.poiProvider = self.poilayer.dataProvider()
            self.poiProvider.addAttributes(attributes)
            self.poilayer.updateFields()

        fields = self.poilayer.fields()

        for point in points:
            pt = QgsPointXY(
                point['location']['points'][0]['Point']['coordinates'][0],
                point['location']['points'][0]['Point']['coordinates'][1])
            poiId = point["id"]
            if "categories" in list(
                    point.keys()) and len(point["categories"]) > 0:
                theme = point["categories"][0]['value']
            else:
                theme = ''
            if "categories" in list(
                    point.keys()) and len(point["categories"]) > 1:
                category = point["categories"][1]['value']
            else:
                category = ''
            if "categories" in point and len(point["categories"]) > 2:
                poiType = point["categories"][2]['value']
            else:
                poiType = ''

            name = point["labels"][0]["value"]
            if "phone" in list(point.keys()):
                phone = point["phone"]
            else:
                phone = ""
            if "email" in list(point.keys()):
                email = point["email"]
            else:
                email = ""
            #address
            if "address" in list(point['location'].keys()):
                if "street" in list(point['location']["address"].keys()):
                    straat = point['location']["address"]["street"]
                else:
                    straat = ''
                if "streetnumber" in list(point['location']["address"].keys()):
                    huisnr = point['location']["address"]["streetnumber"]
                else:
                    huisnr = ''
                if "boxnumber" in list(point['location']["address"].keys()):
                    busnr = point['location']["address"]["boxnumber"]
                else:
                    boxnr = ''
                postcode = point['location']["address"]["postalcode"]
                gemeente = point['location']["address"]["municipality"]
            else:
                straat = ""
                huisnr = ""
                busnr = ""
                postcode = ""
                gemeente = ""

            if "links" in point:
                link = point["links"][0]['href']
            else:
                link = ""
            tijd = point["updated"]
            if "authors" in point:
                owner = point["authors"][0]["value"]
            else:
                owner = ""

            # add a feature
            fet = QgsFeature(fields)

            #set geometry
            fromCrs = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform(fromCrs, self.poilayer.crs(),
                                           QgsProject.instance())
            prjPt = xform.transform(pt)
            fet.setGeometry(QgsGeometry.fromPointXY(prjPt))

            fet['id'] = int(poiId)
            fet['thema'] = theme
            fet['categorie'] = category
            fet['type'] = poiType
            fet['naam'] = name
            fet["email"] = email
            fet["telefoon"] = phone
            #address
            fet['straat'] = straat
            fet['huisnr'] = huisnr
            fet['busnr'] = busnr
            fet['postcode'] = postcode
            fet['gemeente'] = gemeente

            fet['link'] = link
            fet['lastupdate'] = tijd
            fet['owner'] = owner

            self.poiProvider.addFeatures([fet])
            self.poilayer.updateExtents()

        if saveToFile and not QgsProject.instance().mapLayer(self.poilayerid):
            save = self._saveToFile(sender, startFolder)
            if save:
                fpath, flType = save
                error, msg = QgsVectorFileWriter.writeAsVectorFormat(
                    self.poilayer,
                    fileName=fpath,
                    fileEncoding="utf-8",
                    driverName=flType)
                if error == QgsVectorFileWriter.NoError:
                    self.poilayer = QgsVectorLayer(fpath, layername, "ogr")
                    self.poiProvider = self.poilayer.dataProvider()
                else:
                    del self.poilayer, self.poiProvider
                    raise Exception(msg)
            else:
                del self.poilayer, self.poiProvider
                return

        # add Labels
        text_format = QgsTextFormat()
        text_format.setSize(12)
        buffer_settings = QgsTextBufferSettings()
        buffer_settings.setEnabled(True)
        buffer_settings.setSize(1)
        buffer_settings.setColor(QColor("white"))

        palyr = QgsPalLayerSettings()
        text_format.setBuffer(buffer_settings)
        palyr.setFormat(text_format)

        palyr.enabled = True
        palyr.fieldName = 'naam'
        palyr.placement = QgsPalLayerSettings.Free

        self.poilayer.setLabelsEnabled(True)
        self.poilayer.setLabeling(QgsVectorLayerSimpleLabeling(palyr))

        # add layer if not already
        QgsProject.instance().addMapLayer(self.poilayer)

        # store layer id and refresh
        self.poilayerid = self.poilayer.id()
        self.canvas.refresh()

    def _saveToFile(self, sender, startFolder=None):
        'save to file'
        filter = "OGC GeoPackage (*.gpkg);;ESRI Shape Files (*.shp);;SpatiaLite (*.sqlite);;Geojson File (*.geojson);;GML ( *.gml);;Comma separated value File (excel) (*.csv);;MapInfo TAB (*.TAB);;Any File (*.*)"
        Fdlg = QFileDialog()
        Fdlg.setFileMode(QFileDialog.AnyFile)
        fName, __ = QFileDialog.getSaveFileName(sender,
                                                "open file",
                                                filter=filter,
                                                directory=startFolder)
        if fName:
            ext = os.path.splitext(fName)[1]

            if "GPKG" in ext.upper():
                flType = "GPKG"
            elif "SHP" in ext.upper():
                flType = "ESRI Shapefile"
            elif "SQLITE" in ext.upper():
                flType = "SQLite"
            elif "GEOJSON" in ext.upper():  #no update possible -> hidden
                flType = "GeoJSON"
            elif "GML" in ext.upper():
                flType = "GML"
            elif 'TAB' in ext.upper():
                flType = 'MapInfo File'
            elif 'CSV' in ext.upper():
                flType = 'CSV'
            else:
                fName = fName + ".shp"
                flType = "ESRI Shapefile"
            return (fName, flType)
        else:
            return None
Exemple #23
0
class poiHelper(object):
    def __init__(self , iface ):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.poilayerid = ''
        self.minPoilayerid =  ''

    def save_minPois_points(self, points, layername="Geopunt_poi", saveToFile=None, sender=None, startFolder=None ):       
        attributes = [ QgsField("id", QVariant.Int),
            QgsField("type", QVariant.String),
            QgsField("name", QVariant.String),
            QgsField("straat", QVariant.String),
            QgsField("huisnr", QVariant.String),
            QgsField("busnr", QVariant.String),
            QgsField("postcode", QVariant.String),
            QgsField("gemeente", QVariant.String),
            QgsField("link", QVariant.String),
            QgsField("count", QVariant.Int) ]
    
        if not QgsProject.instance().mapLayer(self.minPoilayerid) :
            self.minpoilayer = QgsVectorLayer("Point", layername, "memory")
            self.minpoiProvider = self.minpoilayer.dataProvider()
            self.minpoiProvider.addAttributes(attributes)
            self.minpoilayer.updateFields()    
        
        fields=self.minpoilayer.fields()
        
        for point in points["pois"]:
            pt = QgsPointXY( point['location']['points'][0]['Point']['coordinates'][0], 
                           point['location']['points'][0]['Point']['coordinates'][1]  )
            poiId = point["id"]
            
            if "address" in point['location']: 
              if "street" in point['location']["address"]: 
                straat = point['location']["address"]["street"]
              else:  straat = ''
              if "streetnumber" in point['location']["address"]: 
                huisnr = point['location']["address"]["streetnumber"]
              else:  huisnr = ''
              if "boxnumber" in point['location']["address"]: 
                busnr = point['location']["address"]["boxnumber"]
              else:  busnr = ''
              postcode = point['location']["address"]["postalcode"]
              gemeente = point['location']["address"]["municipality"]
            else: 
              straat = ""
              huisnr = ""
              busnr = ""
              postcode = ""
              gemeente = ""
              
            if "categories" in point and len(point["categories"]) > 0: 
              poiType = point["categories"][0]["value"]
            else: poiType = ''
            if "labels" in point and len(point["labels"]) > 0:
              name = point["labels"][0]["value"]
            else: name = ''
            if "links" in point: 
              link = point["links"][0]["href"]
            else: link = ''

            # add a feature
            fet = QgsFeature(fields)

            #set geometry
            fromCrs = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform( fromCrs, self.minpoilayer.crs(), QgsProject.instance() )
            prjPt = xform.transform( pt )
            fet.setGeometry(QgsGeometry.fromPointXY(prjPt))
      
            fet['id'] = int( poiId )
            fet['straat'] = straat
            fet['huisnr'] = huisnr
            fet['busnr'] = busnr
            fet['postcode'] = postcode
            fet['gemeente'] = gemeente
            fet['type'] = poiType
            fet['name'] = name
            fet['link'] = link

            self.minpoiProvider.addFeatures([ fet ])
            
        for point in points["clusters"]:
            pt = QgsPointXY( point['point']['Point']['coordinates'][0], 
                           point['point']['Point']['coordinates'][1]  )
            poiType = point['point']['type']
            count = point['count']

            # add a feature
            fet = QgsFeature(fields)

            #set geometry
            fromCrs = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform( fromCrs, self.minpoilayer.crs(), QgsProject.instance() )
            prjPt = xform.transform( pt )
            fet.setGeometry(QgsGeometry.fromPointXY(prjPt))

            fet['type'] = poiType
            fet['count'] = count

            self.minpoiProvider.addFeatures([ fet ])
        
        if saveToFile and not QgsProject.instance().mapLayer(self.minPoilayerid):
            save = self._saveToFile( sender, startFolder )
            if save:
              fpath, flType = save
              error, msg = QgsVectorFileWriter.writeAsVectorFormat(self.minpoilayer, fileName=fpath, fileEncoding="utf-8", driverName=flType ) 
              if error == QgsVectorFileWriter.NoError:
                  self.minpoilayer = QgsVectorLayer( fpath , layername, "ogr")
                  self.minpoiProvider = self.minpoilayer.dataProvider()
              else: 
                  del self.minpoilayer, self.minpoiProvider 
                  raise Exception(msg) 
            else:
              del self.minpoilayer, self.minpoiProvider 
              return 

        # add layer if not already
        QgsProject.instance().addMapLayer(self.minpoilayer)

        # store layer id and refresh
        self.minPoilayerid = self.minpoilayer.id()
        self.minpoilayer.updateExtents()
        self.canvas.refresh()
    
    def save_pois_points(self, points, layername="Geopunt_poi", saveToFile=None, sender=None, startFolder=None ):       
        attributes = [ QgsField("id", QVariant.Int),
            QgsField("thema", QVariant.String), 
            QgsField("categorie", QVariant.String),
            QgsField("type", QVariant.String),

            QgsField("naam", QVariant.String),
            QgsField("telefoon", QVariant.String),  
            QgsField("email", QVariant.String) ,
            #address
            QgsField("straat", QVariant.String),
            QgsField("huisnr", QVariant.String),
            QgsField("busnr", QVariant.String),
            QgsField("postcode", QVariant.String),
            QgsField("gemeente", QVariant.String),
            
            QgsField("link", QVariant.String),
            QgsField("lastupdate", QVariant.String),
            QgsField("owner", QVariant.String) ]
    
        if not QgsProject.instance().mapLayer(self.poilayerid) :
            self.poilayer = QgsVectorLayer("Point", layername, "memory")
            self.poiProvider = self.poilayer.dataProvider()
            self.poiProvider.addAttributes(attributes)
            self.poilayer.updateFields()    
        
        fields=self.poilayer.fields()
        
        for point in points:
            pt = QgsPointXY( point['location']['points'][0]['Point']['coordinates'][0], 
                           point['location']['points'][0]['Point']['coordinates'][1]  )
            poiId = point["id"]
            if "categories" in list(point.keys()) and len(point["categories"]) > 0: 
               theme = point["categories"][0]['value']
            else: theme = ''
            if "categories" in  list(point.keys()) and len(point["categories"]) > 1: 
               category = point["categories"][1]['value']
            else: category = ''
            if "categories" in  point and len(point["categories"]) > 2: 
               poiType =  point["categories"][2]['value']
            else: poiType = ''
            
            name = point["labels"][0]["value"]
            if "phone" in list(point.keys()): 
               phone = point["phone"]
            else: phone= ""
            if "email" in list(point.keys()): 
               email = point["email"]
            else: email= ""
            #address
            if "address" in list(point['location'].keys()): 
              if "street" in list(point['location']["address"].keys()): 
                 straat = point['location']["address"]["street"]
              else:  straat = ''
              if "streetnumber" in list(point['location']["address"].keys()): 
                 huisnr = point['location']["address"]["streetnumber"]
              else:  huisnr = ''
              if "boxnumber" in list(point['location']["address"].keys()): 
                 busnr = point['location']["address"]["boxnumber"]
              else:  boxnr = ''
              postcode = point['location']["address"]["postalcode"]
              gemeente = point['location']["address"]["municipality"]
            else: 
              straat = ""
              huisnr = ""
              busnr = ""
              postcode = ""
              gemeente = ""
            
            if "links" in point: 
              link = point["links"][0]['href']
            else: link = ""
            tijd =  point["updated"] 
            if "authors" in point: 
              owner = point["authors"][0]["value"]
            else: owner= ""
            
            # add a feature
            fet = QgsFeature(fields)

            #set geometry
            fromCrs = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform( fromCrs, self.poilayer.crs(), QgsProject.instance() )
            prjPt = xform.transform( pt )
            fet.setGeometry(QgsGeometry.fromPointXY(prjPt))
      
            fet['id'] = int( poiId )
            fet['thema'] = theme
            fet['categorie'] = category
            fet['type'] = poiType
            fet['naam'] = name
            fet["email"] = email
            fet["telefoon"] = phone
            #address
            fet['straat'] = straat
            fet['huisnr'] = huisnr
            fet['busnr'] = busnr
            fet['postcode'] = postcode
            fet['gemeente'] = gemeente
            
            fet['link'] = link
            fet['lastupdate'] = tijd
            fet['owner'] = owner
      
            self.poiProvider.addFeatures([ fet ])
            self.poilayer.updateExtents()
    
        if saveToFile and not QgsProject.instance().mapLayer(self.poilayerid):
            save = self._saveToFile( sender, startFolder )
            if save:
              fpath, flType = save
              error, msg = QgsVectorFileWriter.writeAsVectorFormat(self.poilayer,fileName=fpath, fileEncoding="utf-8", driverName=flType ) 
              if error == QgsVectorFileWriter.NoError:
                  self.poilayer = QgsVectorLayer( fpath , layername, "ogr")
                  self.poiProvider = self.poilayer.dataProvider()
              else: 
                  del self.poilayer, self.poiProvider 
                  raise Exception( msg )
            else:
              del self.poilayer, self.poiProvider 
              return 

        # add Labels
        text_format = QgsTextFormat()
        text_format.setSize(12)
        buffer_settings = QgsTextBufferSettings()
        buffer_settings.setEnabled(True)
        buffer_settings.setSize(1)
        buffer_settings.setColor(QColor("white"))
        
        palyr = QgsPalLayerSettings() 
        text_format.setBuffer(buffer_settings)
        palyr.setFormat(text_format)
        
        palyr.enabled = True 
        palyr.fieldName = 'naam' 
        palyr.placement = QgsPalLayerSettings.Free 

        self.poilayer.setLabelsEnabled(True)
        self.poilayer.setLabeling( QgsVectorLayerSimpleLabeling(palyr) )

        # add layer if not already
        QgsProject.instance().addMapLayer(self.poilayer)

        # store layer id and refresh
        self.poilayerid = self.poilayer.id()
        self.canvas.refresh()
    
    def _saveToFile( self, sender, startFolder=None ):
        'save to file'
        filter = "OGC GeoPackage (*.gpkg);;ESRI Shape Files (*.shp);;SpatiaLite (*.sqlite);;Geojson File (*.geojson);;GML ( *.gml);;Comma separated value File (excel) (*.csv);;MapInfo TAB (*.TAB);;Any File (*.*)" 
        Fdlg = QFileDialog()
        Fdlg.setFileMode(QFileDialog.AnyFile)
        fName, __ = QFileDialog.getSaveFileName(sender, "open file", filter=filter, directory=startFolder)
        if fName:
          ext = os.path.splitext( fName )[1]
          
          if "GPKG" in ext.upper():
            flType = "GPKG"
          elif "SHP" in ext.upper():
            flType = "ESRI Shapefile"
          elif "SQLITE" in ext.upper():
            flType = "SQLite" 
          elif "GEOJSON" in ext.upper():  #no update possible -> hidden
            flType = "GeoJSON"
          elif "GML" in ext.upper():
            flType = "GML"
          elif 'TAB' in ext.upper():
            flType = 'MapInfo File'
          elif 'CSV' in ext.upper():
            flType = 'CSV'
          else:
            fName = fName + ".shp"
            flType = "ESRI Shapefile"
          return (fName , flType )
        else:
            return None
Exemple #24
0
    def run(self):

        global almacen
        #coloco el puntero arriba del todo
        QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint(
            QgsProject.instance().layerTreeRoot(), 0)

        #genero una lista con los sistemas de referencia
        misdatos = [["Etrs89 Zona30 (25830)", "25830"],
                    ["Etrs89 Zona29 (25829)", "25829"],
                    ["ED50 Zona30 (23030)", "23030"],
                    ["ED50_Zona29 (23029)", "23029"],
                    ["WGS84 geograficas sexagesimales(4326)", "4326"],
                    ["WGS84 geograficas centesimales(4326)", "4258"]]
        self.dlg.comboBox_src.clear()
        for element in misdatos:
            self.dlg.comboBox_src.addItem(element[0])
        """Run method that performs all the real work"""

        # 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.first_start = False

        #leo la cache
        rutacache = os.path.join(QgsApplication.qgisSettingsDirPath(),
                                 r"python\plugins\zoomSigmena\cache.txt")
        if os.path.isfile(rutacache) == True:
            filecache = open(rutacache, "r")
            filecacheleido = filecache.readlines()
            try:
                import ast
                almacen = ast.literal_eval((filecacheleido[0].replace(
                    '\n', '')).replace(" [[",
                                       "[[").replace("]] ",
                                                     "]]"))  #.split(','))
                cache_utm = int(almacen[0])
                cache_geo = int(almacen[1])
                cache_escala = almacen[2]

                print(cache_escala)
                print(almacen)
                #miscomarcas=(filecacheleido[3].replace('\n','')).strip('][').split(',') #convierto una str en una list
                #mismunicipios=ast.literal_eval((filecacheleido[4].replace('\n','')).replace(" [[","[[").replace("]] ","]]"))#.split(',')) #convierto una str en una list
                filecache.close()

            except:
                print("esta no encuentra el file cache")
            self.dlg.lineEdit_escala.setText(str(cache_escala))
            self.dlg.checkBox_utm.setChecked(cache_utm)
            self.dlg.checkBox_geo.setChecked(cache_geo)
        # show the dialog
        self.dlg.show()

        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            # Do something useful here - delete the line containing pass and
            # substitute with your code.

            def deg_to_dms(deg, type='lat'):
                decimals, number = math.modf(deg)
                d = int(number)
                m = int(decimals * 60)
                s = (deg - d - m / 60) * 3600.00
                compass = {'lat': ('N', 'S'), 'lon': ('E', 'W')}
                compass_str = compass[type][0 if d >= 0 else 1]
                return '{}º{}\'{:.2f}"{}'.format(abs(d), abs(m), abs(s),
                                                 compass_str)

            #saco de  aqui variables que estan en las cajitas
            src_seleccionado = self.dlg.comboBox_src.currentIndex()

            # Get the coordinates and scale factor from the dialog
            x = self.dlg.XX.text()  ##displayText()
            y = self.dlg.YY.text()  ##displayText()
            escala = self.dlg.lineEdit_escala.text()

            x = x.replace(',', '.')
            y = y.replace(',', '.')
            escala = int(escala.replace('.', ''))
            src = misdatos[int(src_seleccionado)][1]

            if src == "4326":
                latext = y
                longtext = x

                lag = float(latext.split()[0])
                lam = float(latext.split()[1])
                las = float(latext.split()[2])
                log = float(longtext.split()[0])
                lom = float(longtext.split()[1])
                los = float(longtext.split()[2])

                lon = -1 * (log + (lom / 60) + (los / 3600))
                lat = lag + (lam / 60) + (las / 3600)

                x = float(lon)
                y = float(lat)
                print(x)
                print(y)
                huso = 30
                destinoProj = pyproj.Proj(proj="utm",
                                          zone=huso,
                                          ellps="WGS84",
                                          units="m")
                origenProj = pyproj.Proj(proj='longlat',
                                         ellps='WGS84',
                                         datum='WGS84')
                UTM_X, UTM_Y = pyproj.transform(origenProj, destinoProj, lon,
                                                lat)

            if src == "4258":
                print("por el camino adecuado")
                lat = float(y)
                lonn = float(x)
                lon = -1.0 * lonn

                print(lat)
                print(lon)

                huso = 30
                destinoProj = pyproj.Proj(proj="utm",
                                          zone=huso,
                                          ellps="WGS84",
                                          units="m")
                origenProj = pyproj.Proj(proj='longlat',
                                         ellps='WGS84',
                                         datum='WGS84')
                UTM_X, UTM_Y = pyproj.transform(origenProj, destinoProj, lon,
                                                lat)
                print(UTM_X)
                print(UTM_Y)
                x = lon
                y = lat

            #creo una capa temporal con las coordenadas

            # create layer
            vl2 = QgsVectorLayer("Point?crs=EPSG:" + src, "Zoom", "memory")
            pr2 = vl2.dataProvider()

            vl2.startEditing()
            # add fields

            pr2.addAttributes([
                QgsField("x", QVariant.Double),
                QgsField("y", QVariant.Double),
                QgsField("xx", QVariant.String),
                QgsField("yy", QVariant.String),
                QgsField("xxx", QVariant.Double),
                QgsField("yyy", QVariant.Double)
            ])
            vl2.updateFields()
            # tell the vector layer to fetch changes from the provider

            #$add a feature
            fet = QgsFeature()
            print("punto")
            print(x)
            print(y)
            fet.setGeometry(
                QgsGeometry.fromPointXY(QgsPointXY(float(x), float(y))))
            if src == "25830":
                huso = 30
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="WGS84",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            if src == "25829":
                huso = 29
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="WGS84",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            if src == "23030":
                huso = 30
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="intl",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            if src == "23029":
                huso = 29
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="intl",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            #para que lo pase a utms en pantalla
            if src == "4326":
                x = int(UTM_X)
                y = int(UTM_Y)
                #xx=longtext
                #yy=latext
                huso = 30
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="intl",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)
                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))
            #para que lo pase a utms en pantalla
            if src == "4258":
                x = int(UTM_X)
                y = int(UTM_Y)

                xxx = lon
                yyy = lat
                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))
            fet.setAttributes(
                [float(x),
                 float(y),
                 str(xx),
                 str(yy),
                 float(xxx),
                 float(yyy)])
            pr2.addFeatures([fet])

            #cambio la simbologia
            symbol = QgsMarkerSymbol.createSimple({
                'name': 'circle',
                'color': 'red',
                'size': '3',
            })
            vl2.renderer().setSymbol(symbol)

            # update layer's extent when new features have been added
            # because change of extent in provider is not propagated to the layer

            layer_settings = QgsPalLayerSettings()
            text_format = QgsTextFormat()

            text_format.setFont(QFont("Arial", 12))
            text_format.setSize(12)
            text_format.setColor(QColor("Orange"))

            layer_settings.setFormat(text_format)
            layer_settings.placement = 1
            layer_settings.xOffset = 0.0
            layer_settings.yOffset = 10.0
            mostrar = True
            if self.dlg.checkBox_utm.isChecked(
            ) and self.dlg.checkBox_geo.isChecked():
                layer_settings.fieldName = '''concat('X: ',"X",' Y: ',"Y",'\n','Lon: ',"xx",' Lat: ',"yy" )'''
                almacen = [1, 1]

            else:
                if self.dlg.checkBox_utm.isChecked():
                    layer_settings.fieldName = '''concat('X: ',"X",' Y: ',"Y" )'''
                    almacen = [1, 0]
                    print("caso1")
                if self.dlg.checkBox_geo.isChecked():
                    layer_settings.fieldName = '''concat('Lon: ',"xx",' Lat: ',"yy" )'''
                    almacen = [0, 1]
                    print("caso2")
                if not self.dlg.checkBox_utm.isChecked(
                ) and not self.dlg.checkBox_geo.isChecked():
                    mostrar = False
                    almacen = [0, 0]
                    print("caso3")
            print("almacen despues de etiquetar", almacen)
            layer_settings.isExpression = True

            print(mostrar)
            layer_settings.enabled = mostrar

            layer_settings = QgsVectorLayerSimpleLabeling(layer_settings)
            vl2.setLabelsEnabled(True)
            vl2.setLabeling(layer_settings)
            vl2.triggerRepaint()

            # update layer's extent when new features have been added
            # because change of extent in provider is not propagated to the layer
            vl2.updateExtents()
            vl2.commitChanges()
            vl2.updateExtents()
            canvas = self.iface.mapCanvas()
            canvas.setExtent(vl2.extent())

            crsSrc = QgsCoordinateReferenceSystem('EPSG:' + str(src))
            crsDest = QgsProject.instance().crs()

            if crsSrc != crsDest:

                xform = QgsCoordinateTransform(crsSrc, crsDest,
                                               QgsProject.instance())
                canvas.setExtent(xform.transform(vl2.extent()))

            self.iface.mapCanvas().zoomScale(escala)
            #self.limpiar_pressed()
            almacen.append(escala)
            #lo escribo en el txt, mavhacando lo que ya tenia
            f = open(rutacache, "w")
            escribir = str(almacen)
            f.write(escribir)
            f.close()
            print(almacen)
            QgsProject.instance().addMapLayer(vl2)
    def testLabelMargin(self):
        """
        Test rendering map item with a label margin set
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(20)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'X'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory")
        vl.setRenderer(QgsNullSymbolRenderer())
        f = QgsFeature(vl.fields(), 1)
        for x in range(15):
            for y in range(15):
                f.setGeometry(QgsPoint(x, y))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        engine_settings = QgsLabelingEngineSettings()
        engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False)
        engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True)
        p.setLabelingEngineSettings(engine_settings)

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(True)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        checker = QgsLayoutChecker('composermap_label_nomargin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        map.setLabelMargin(QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters))
        checker = QgsLayoutChecker('composermap_label_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        map.setLabelMargin(QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters))
        checker = QgsLayoutChecker('composermap_label_cm_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        map.setMapRotation(45)
        map.zoomToExtent(vl.extent())
        map.setScale(map.scale() * 1.2)
        checker = QgsLayoutChecker('composermap_rotated_label_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # data defined
        map.setMapRotation(0)
        map.zoomToExtent(vl.extent())
        map.dataDefinedProperties().setProperty(QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3'))
        map.refresh()
        checker = QgsLayoutChecker('composermap_dd_label_margin', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)
Exemple #26
0
text_format.setSize(12)
text_format.setBackground(background_color)

buffer_settings = QgsTextBufferSettings()
buffer_settings.setEnabled(True)
buffer_settings.setSize(0.10)
buffer_settings.setColor(QColor("black"))

text_format.setBuffer(buffer_settings)
layer_settings.setFormat(text_format)

layer_settings.fieldName = "name"
layer_settings.placement = 4

layer_settings.enabled = True

layer_settings = QgsVectorLayerSimpleLabeling(layer_settings)
point_layer.setLabelsEnabled(True)
point_layer.setLabeling(layer_settings)

#creating a window to display the map of Melbourne and the RMIT location
canvas = QgsMapCanvas()
canvas.setLayers([point_layer, base_layer])
canvas.setExtent(road_layer.extent())
canvas.show()

#setup click trigger to capture the clicked location and then call the shortest path calculator function
pointTool = QgsMapToolEmitPoint(canvas)
pointTool.canvasClicked.connect(my_shortest_path)
canvas.setMapTool(pointTool)
Exemple #27
0
    def layer_to_QgsVectorLayer(
            source_layer,  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
            input_file,
            context: Context,
            fallback_crs=QgsCoordinateReferenceSystem(),
            defer_layer_uri_set: bool = False):
        """
        Converts a vector layer
        """
        if source_layer.__class__.__name__ == 'CadFeatureLayer':
            layer = source_layer.layer
        else:
            layer = source_layer

        crs = CrsConverter.convert_crs(
            layer.layer_extent.crs,
            context) if layer.layer_extent else QgsCoordinateReferenceSystem()
        if not crs.isValid():
            crs = fallback_crs

        subset_string = ''
        if layer.selection_set:
            subset_string = 'fid in ({})'.format(','.join(
                [str(s) for s in layer.selection_set]))
        elif layer.definition_query:
            subset_string = ExpressionConverter.convert_esri_sql(
                layer.definition_query)

        base, _ = os.path.split(input_file)

        uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri(
            source_layer=source_layer,
            obj=layer,
            base=base,
            crs=crs,
            subset=subset_string,
            context=context)

        if wkb_type is None or wkb_type == QgsWkbTypes.Unknown:
            wkb_type = VectorLayerConverter.layer_to_wkb_type(layer)
        context.layer_type_hint = wkb_type

        if Qgis.QGIS_VERSION_INT >= 31600:
            # try to get the layer name so that we can remove it from field references.
            # e.g. if layer name is polys then qgis won't support to arcgis style "polys.field" format
            parts = QgsProviderRegistry.instance().decodeUri(provider, uri)
            context.main_layer_name = parts.get('layerName')
            if not context.main_layer_name and provider == 'ogr':
                context.main_layer_name = Path(parts['path']).stem

            if context.main_layer_name:
                subset_string = subset_string.replace(
                    context.main_layer_name + '.', '')
        else:
            context.main_layer_name = None

        if provider == 'ogr' and (not file_name
                                  or not os.path.exists(file_name)
                                  ) and context.invalid_layer_resolver:
            res = context.invalid_layer_resolver(layer.name, uri, wkb_type)
            uri = res.uri
            provider = res.providerKey

        if Qgis.QGIS_VERSION_INT >= 31000:
            opts = QgsVectorLayer.LayerOptions()
            if wkb_type is not None:
                opts.fallbackWkbType = wkb_type

            if provider == 'ogr' and subset_string:
                uri += '|subset={}'.format(subset_string)

            original_uri = uri
            if defer_layer_uri_set:
                uri = 'xxxxxxxxx' + uri

            vl = QgsVectorLayer(uri, layer.name, provider, opts)
            if defer_layer_uri_set:
                vl.setCustomProperty('original_uri', original_uri)
        else:
            vl = QgsMemoryProviderUtils.createMemoryLayer(
                layer.name, QgsFields(), wkb_type, crs)

        # context.style_folder, _ = os.path.split(output_file)
        if layer.renderer:
            renderer = VectorRendererConverter.convert_renderer(
                layer.renderer, context)
            try:
                if not renderer.usingSymbolLevels():
                    renderer.setUsingSymbolLevels(
                        layer.use_advanced_symbol_levels)
            except AttributeError:
                pass

            if layer.use_page_definition_query:
                filter_expression = '"{}" {} @atlas_pagename'.format(
                    layer.page_name_field, layer.page_name_match_operator)
                root_rule = QgsRuleBasedRenderer.Rule(None)

                # special case -- convert a simple renderer
                if isinstance(renderer, QgsSingleSymbolRenderer):
                    filter_rule = QgsRuleBasedRenderer.Rule(
                        renderer.symbol().clone())
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel(layer.name)
                    filter_rule.setDescription(layer.name)
                    root_rule.appendChild(filter_rule)
                else:
                    source_rule_renderer = QgsRuleBasedRenderer.convertFromRenderer(
                        renderer)
                    filter_rule = QgsRuleBasedRenderer.Rule(None)
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel('Current Atlas Page')
                    filter_rule.setDescription('Current Atlas Page')
                    root_rule.appendChild(filter_rule)
                    for child in source_rule_renderer.rootRule().children():
                        filter_rule.appendChild(child.clone())

                renderer = QgsRuleBasedRenderer(root_rule)

            if renderer:
                vl.setRenderer(renderer)
                vl.triggerRepaint()
        else:
            vl.setRenderer(QgsNullSymbolRenderer())
            vl.triggerRepaint()

        metadata = vl.metadata()
        metadata.setAbstract(layer.description)
        vl.setMetadata(metadata)  #

        # layer.zoom_max = "don't show when zoomed out beyond"
        zoom_max = layer.zoom_max
        # layer.zoom_min = "don't show when zoomed in beyond"
        zoom_min = layer.zoom_min

        enabled_scale_range = bool(zoom_max or zoom_min)
        if zoom_max and zoom_min and zoom_min > zoom_max:
            # inconsistent scale range -- zoom_max should be bigger number than zoom_min
            zoom_min, zoom_max = zoom_max, zoom_min

        # qgis minimum scale = don't show when zoomed out beyond, i.e. ArcGIS zoom_max
        vl.setMinimumScale(
            zoom_max if enabled_scale_range else layer.stored_zoom_max)
        # qgis maximum scale = don't show when zoomed in beyond, i.e. ArcGIS zoom_min
        vl.setMaximumScale(
            zoom_min if enabled_scale_range else layer.stored_zoom_min)
        vl.setScaleBasedVisibility(enabled_scale_range)

        vl.setOpacity(1.0 - (layer.transparency or 0) / 100)

        if layer.display_expression_properties and layer.display_expression_properties.expression and layer.display_expression_properties.expression_parser is not None:
            vl.setDisplayExpression(
                ExpressionConverter.convert(
                    layer.display_expression_properties.expression,
                    layer.display_expression_properties.expression_parser,
                    layer.display_expression_properties.advanced, context))

        if Qgis.QGIS_VERSION_INT < 31000:
            vl.setDataSource(uri, layer.name, provider)

        if encoding:
            vl.dataProvider().setEncoding(encoding)

        if subset_string:
            vl.setSubsetString(subset_string)

        vl.setCrs(crs)

        for e in layer.extensions:
            if e.__class__.__name__ == 'ServerLayerExtension':
                if 'CopyrightText' in e.properties.properties:
                    layer_credits = e.properties.properties['CopyrightText']
                    metadata = vl.metadata()
                    rights = metadata.rights()
                    rights.append(layer_credits)
                    metadata.setRights(rights)
                    vl.setMetadata(metadata)

        LabelConverter.convert_annotation_collection(
            layer.annotation_collection, dest_layer=vl, context=context)
        vl.setLabelsEnabled(layer.labels_enabled)

        DiagramConverter.convert_diagrams(layer.renderer,
                                          dest_layer=vl,
                                          context=context)

        # setup joins
        join_layer = VectorLayerConverter.add_joined_layer(
            source_layer=layer,
            input_file=input_file,
            base_layer=vl,
            context=context)

        context.dataset_name = ''

        vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl))

        if layer.hyperlinks:
            VectorLayerConverter.convert_hyperlinks(layer.hyperlinks, vl)

        vl.setDisplayExpression(
            QgsExpression.quotedColumnRef(layer.display_field))

        res = [vl]
        if join_layer:
            res.append(join_layer)

        context.main_layer_name = None
        return res