def test_joined_layers_conversion(self): v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory") self.assertEqual(v1.isValid(), True) v2 = QgsVectorLayer("Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory") self.assertEqual(v2.isValid(), True) v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory") self.assertEqual(v3.isValid(), True) QgsProject.instance().addMapLayers([v1, v2, v3]) joinInfo = QgsVectorLayerJoinInfo() joinInfo.setTargetFieldName("b_id") joinInfo.setJoinLayer(v2) joinInfo.setJoinFieldName("id") #joinInfo.setPrefix("B_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) # with a field subset v1.removeJoin(v2.id()) joinInfo.setJoinFieldNamesSubset(["bname"]) v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 5) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setJoinFieldNamesSubset(None) # add a table prefix to the join v1.removeJoin(v2.id()) joinInfo.setPrefix("BB_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS BB_bname, j1.bfield AS BB_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setPrefix("") v1.removeJoin(v2.id()) v1.addJoin(joinInfo) # add another join joinInfo2 = QgsVectorLayerJoinInfo() joinInfo2.setTargetFieldName("c_id") joinInfo2.setJoinLayer(v3) joinInfo2.setJoinFieldName("id") v1.addJoin(joinInfo2) self.assertEqual(len(v1.fields()), 7) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), ('SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield, j2.cname AS C_cname FROM {} AS t ' + 'LEFT JOIN {} AS j1 ON t."b_id"=j1."id" ' + 'LEFT JOIN {} AS j2 ON t."c_id"=j2."id"').format(v1.id(), v2.id(), v3.id())) QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id()])
def test_joined_layers_conversion(self): v1 = QgsVectorLayer( "Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory") self.assertEqual(v1.isValid(), True) v2 = QgsVectorLayer( "Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory") self.assertEqual(v2.isValid(), True) v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory") self.assertEqual(v3.isValid(), True) QgsProject.instance().addMapLayers([v1, v2, v3]) joinInfo = QgsVectorLayerJoinInfo() joinInfo.setTargetFieldName("b_id") joinInfo.setJoinLayer(v2) joinInfo.setJoinFieldName("id") #joinInfo.setPrefix("B_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual( df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"' .format(v1.id(), v2.id())) # with a field subset v1.removeJoin(v2.id()) joinInfo.setJoinFieldNamesSubset(["bname"]) v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 5) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual( df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"' .format(v1.id(), v2.id())) joinInfo.setJoinFieldNamesSubset(None) # add a table prefix to the join v1.removeJoin(v2.id()) joinInfo.setPrefix("BB_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual( df.query(), 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS BB_bname, j1.bfield AS BB_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"' .format(v1.id(), v2.id())) joinInfo.setPrefix("") v1.removeJoin(v2.id()) v1.addJoin(joinInfo) # add another join joinInfo2 = QgsVectorLayerJoinInfo() joinInfo2.setTargetFieldName("c_id") joinInfo2.setJoinLayer(v3) joinInfo2.setJoinFieldName("id") v1.addJoin(joinInfo2) self.assertEqual(len(v1.fields()), 7) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), ( 'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield, j2.cname AS C_cname FROM {} AS t ' + 'LEFT JOIN {} AS j1 ON t."b_id"=j1."id" ' + 'LEFT JOIN {} AS j2 ON t."c_id"=j2."id"').format( v1.id(), v2.id(), v3.id())) QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id()])
def test_joined_layers_conversion(self): v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory") self.assertEqual(v1.isValid(), True) v2 = QgsVectorLayer("Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory") self.assertEqual(v2.isValid(), True) v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory") self.assertEqual(v3.isValid(), True) tl1 = QgsVectorLayer("NoGeometry?field=id:integer&field=e_id:integer&field=0name:string", "D", "memory") self.assertEqual(tl1.isValid(), True) tl2 = QgsVectorLayer("NoGeometry?field=id:integer&field=ena me:string", "E", "memory") self.assertEqual(tl2.isValid(), True) QgsProject.instance().addMapLayers([v1, v2, v3, tl1, tl2]) joinInfo = QgsVectorLayerJoinInfo() joinInfo.setTargetFieldName("b_id") joinInfo.setJoinLayer(v2) joinInfo.setJoinFieldName("id") #joinInfo.setPrefix("B_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) # with a field subset v1.removeJoin(v2.id()) joinInfo.setJoinFieldNamesSubset(["bname"]) v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 5) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setJoinFieldNamesSubset(None) # add a table prefix to the join v1.removeJoin(v2.id()) joinInfo.setPrefix("BB_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "BB_bname", j1."bfield" AS "BB_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setPrefix("") v1.removeJoin(v2.id()) v1.addJoin(joinInfo) # add another join joinInfo2 = QgsVectorLayerJoinInfo() joinInfo2.setTargetFieldName("c_id") joinInfo2.setJoinLayer(v3) joinInfo2.setJoinFieldName("id") v1.addJoin(joinInfo2) self.assertEqual(len(v1.fields()), 7) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), ('SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield", j2."cname" AS "C_cname" FROM "{}" AS t ' + 'LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id" ' + 'LEFT JOIN "{}" AS j2 ON t."c_id"=j2."id"').format(v1.id(), v2.id(), v3.id())) # test NoGeometry joined layers with field names starting with a digit or containing white spaces joinInfo3 = QgsVectorLayerJoinInfo() joinInfo3.setTargetFieldName("e_id") joinInfo3.setJoinLayer(tl2) joinInfo3.setJoinFieldName("id") tl1.addJoin(joinInfo3) self.assertEqual(len(tl1.fields()), 4) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(tl1) self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t."id", t."e_id", t."0name", j1."ena me" AS "E_ena me" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."e_id"=j1."id"'.format(tl1.id(), tl2.id())) QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id(), tl1.id(), tl2.id()])
def run(self): project_id = self.settings.value("project/id") epsg = self.settings.value("project/epsg") locale = QSettings().value('locale/userLocale')[ 0:2] # this is for multilingual legends # If locale is different to frence or italian, german will be used. # Otherwise we get into troubles with the legends, e.g. locale = "en" # but # there is no english legend (qml file). if locale == "fr": pass elif locale == "it": pass else: locale = "de" if not project_id: self.message_bar.pushCritical( "Error", _translate("VeriSO_V+D_FP2", "project_id not set", None)) return QApplication.setOverrideCursor(Qt.WaitCursor) try: group = _translate("VeriSO_V+D_FP2", "FixpunkteKategorie2", None) group += " (" + str(project_id) + ")" # Lagefixpunkte 2 layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP2", "LFP2 Nachführung", None), "featuretype": "fixpunktekategorie2_lfp2nachfuehrung", "geom": "perimeter", "key": "ogc_fid", "sql": "", "readonly": True, "group": group } # Visibility and if legend and/or groupd should be collapsed can # be set with parameters in the self.layer_loader.load() # method: # load(layer, visibility=True, collapsed_legend=False, # collapsed_group=False) vlayer_lfp2_nf = self.layer_loader.load(layer, False, True) layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP2", "LFP2", None), "featuretype": "fixpunktekategorie2_lfp2", "geom": "geometrie", "key": "ogc_fid", "sql": "", "readonly": True, "group": group, "style": "fixpunkte/lfp2.qml" } vlayer_lfp2 = self.layer_loader.load(layer) # Join two layers (lfp2 and lfp2nachfuehrung) lfp2_field = "entstehung" lfp2_nf_field = "ogc_fid" join_obj = QgsVectorLayerJoinInfo() join_obj.setJoinLayerId(vlayer_lfp2_nf.id()) join_obj.setJoinFieldName(lfp2_nf_field) join_obj.setTargetFieldName(lfp2_field) join_obj.setUsingMemoryCache(True) join_obj.setPrefix("lfp2_nf_") vlayer_lfp2.addJoin(join_obj) # This is how WMS layer work. layer = { "type": "wms", "title": _translate("VeriSO_V+D_FP2", "LFP2 Schweiz (WMS)", None), "url": "http://wms.geo.admin.ch/", "layers": "ch.swisstopo.fixpunkte-lfp2", "format": "image/png", "crs": "EPSG:" + str(epsg), "group": group } vlayer = self.layer_loader.load(layer, False, True) # Höhenfixpunkte 2 layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP2", "HFP2 Nachführung", None), "featuretype": "fixpunktekategorie2_hfp2nachfuehrung", "geom": "perimeter", "key": "ogc_fid", "sql": "", "readonly": True, "group": group } vlayer_hfp2_nf = self.layer_loader.load(layer, False, True) layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP2", "HFP2", None), "featuretype": "fixpunktekategorie2_hfp2", "geom": "geometrie", "key": "ogc_fid", "sql": "", "readonly": True, "group": group, "style": "fixpunkte/hfp2.qml" } vlayer_hfp2 = self.layer_loader.load(layer) # Join two layers (hfp2 and hfp2nachfuehrung) hfp2_field = "entstehung" hfp2_nf_field = "ogc_fid" join_obj = QgsVectorLayerJoinInfo() join_obj.setJoinLayerId(vlayer_hfp2_nf.id()) join_obj.setJoinFieldName(hfp2_nf_field) join_obj.setTargetFieldName(hfp2_field) join_obj.setUsingMemoryCache(True) join_obj.setPrefix("hfp2_nf_") vlayer_hfp2.addJoin(join_obj) layer = { "type": "wms", "title": _translate("VeriSO_V+D_FP2", "HFP2 Schweiz (WMS)", None), "url": "http://wms.geo.admin.ch/", "layers": "ch.swisstopo.fixpunkte-hfp2", "format": "image/png", "crs": "EPSG:" + str(epsg), "group": group } vlayer = self.layer_loader.load(layer, False, True) # Business as usual: Gemeindegrenzen layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP2", "Gemeindegrenze", None), "featuretype": "gemeindegrenzen_gemeindegrenze", "geom": "geometrie", "key": "ogc_fid", "sql": "", "readonly": True, "group": group, "style": "global_qml/gemeindegrenze/gemgre_strichliert.qml" } gemgrelayer = self.layer_loader.load(layer) # Change map extent. # Bug (?) in QGIS: http://hub.qgis.org/issues/10980 # Closed for the lack of feedback. Upsi... # Still a problem? (sz / 2015-04-12) if gemgrelayer: rect = gemgrelayer.extent() rect.scale(5) self.iface.mapCanvas().setExtent(rect) self.iface.mapCanvas().refresh() # Sometimes it does make much more sense # to zoom to maximal extent: # self.iface.mapCanvas().zoomToFullExtent() except Exception: QApplication.restoreOverrideCursor() exc_type, exc_value, exc_traceback = sys.exc_info() self.message_bar.pushMessage( "Error", str(traceback.format_exc(exc_traceback)), level=Qgis.Critical, duration=0) QApplication.restoreOverrideCursor()
def test_joined_layers_conversion(self): v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory") self.assertEqual(v1.isValid(), True) v2 = QgsVectorLayer("Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory") self.assertEqual(v2.isValid(), True) v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory") self.assertEqual(v3.isValid(), True) tl1 = QgsVectorLayer("NoGeometry?field=id:integer&field=e_id:integer&field=0name:string", "D", "memory") self.assertEqual(tl1.isValid(), True) tl2 = QgsVectorLayer("NoGeometry?field=id:integer&field=ena me:string", "E", "memory") self.assertEqual(tl2.isValid(), True) QgsProject.instance().addMapLayers([v1, v2, v3, tl1, tl2]) joinInfo = QgsVectorLayerJoinInfo() joinInfo.setTargetFieldName("b_id") joinInfo.setJoinLayer(v2) joinInfo.setJoinFieldName("id") #joinInfo.setPrefix("B_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) # with a field subset v1.removeJoin(v2.id()) joinInfo.setJoinFieldNamesSubset(["bname"]) v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 5) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setJoinFieldNamesSubset(None) # add a table prefix to the join v1.removeJoin(v2.id()) joinInfo.setPrefix("BB_") v1.addJoin(joinInfo) self.assertEqual(len(v1.fields()), 6) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "BB_bname", j1."bfield" AS "BB_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id())) joinInfo.setPrefix("") v1.removeJoin(v2.id()) v1.addJoin(joinInfo) # add another join joinInfo2 = QgsVectorLayerJoinInfo() joinInfo2.setTargetFieldName("c_id") joinInfo2.setJoinLayer(v3) joinInfo2.setJoinFieldName("id") v1.addJoin(joinInfo2) self.assertEqual(len(v1.fields()), 7) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1) self.assertEqual(df.query(), ('SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield", j2."cname" AS "C_cname" FROM "{}" AS t ' + 'LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id" ' + 'LEFT JOIN "{}" AS j2 ON t."c_id"=j2."id"').format(v1.id(), v2.id(), v3.id())) # test NoGeometry joined layers with field names starting with a digit or containing white spaces joinInfo3 = QgsVectorLayerJoinInfo() joinInfo3.setTargetFieldName("e_id") joinInfo3.setJoinLayer(tl2) joinInfo3.setJoinFieldName("id") tl1.addJoin(joinInfo3) self.assertEqual(len(tl1.fields()), 4) df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(tl1) self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t."id", t."e_id", t."0name", j1."ena me" AS "E_ena me" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."e_id"=j1."id"'.format(tl1.id(), tl2.id())) QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id(), tl1.id(), tl2.id()])
def run(self): project_id = self.settings.value("project/id") epsg = self.settings.value("project/epsg") self.project_dir = self.settings.value("project/projectdir") self.project_id = self.settings.value("project/id") locale = QSettings().value('locale/userLocale')[ 0:2] # this is for multilingual legends # If locale is different to frence or italian, german will be used. # Otherwise we get into troubles with the legends, e.g. locale = "en" # but # there is no english legend (qml file). if locale == "fr": pass elif locale == "it": pass else: locale = "de" if not project_id: self.message_bar.pushCritical("Error", _translate("VeriSO_V+D_FP3", "project_id not set", None)) return QApplication.setOverrideCursor(Qt.WaitCursor) try: group = _translate("VeriSO_V+D_FP3", "FixpunkteKategorie3", None) group += " (" + str(project_id) + ")" layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP3", "Toleranzstufen", None), "featuretype": "tseinteilung_toleranzstufe", "geom": "geometrie", "key": "ogc_fid", "sql": "", "readonly": True, "group": group, "style": "tseinteilung/toleranzstufe_" + locale + ".qml" } # Visibility and if legend and/or groupd should be collapsed can # be set with parameters in the self.layer_loader.load() # method: # load(layer, visibility=True, collapsed_legend=False, # collapsed_group=False) vlayer = self.layer_loader.load(layer) layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP3", "LFP3 Nachführung", None), "featuretype": "fixpunktekategorie3_lfp3nachfuehrung", "geom": "perimeter", "key": "ogc_fid", "sql": "", "readonly": True, "group": group } vlayer_lfp3_nf = self.layer_loader.load(layer, False, True) layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP3", "LFP3", None), "featuretype": "fixpunktekategorie3_lfp3", "geom": "geometrie", "key": "ogc_fid", "sql": "", "readonly": True, "group": group, "style": "fixpunkte/lfp3_" + locale + ".qml" } vlayer_lfp3 = self.layer_loader.load(layer) # Join two layers (lfp3 and lfp3nachfuehrung) lfp3_field = "entstehung" lfp3_nf_field = "ogc_fid" join_obj = QgsVectorLayerJoinInfo() join_obj.setJoinLayerId(vlayer_lfp3_nf.id()) join_obj.setJoinFieldName(lfp3_nf_field) join_obj.setTargetFieldName(lfp3_field) join_obj.setUsingMemoryCache(True) join_obj.setPrefix("lfp3_nf_") vlayer_lfp3.addJoin(join_obj) layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP3", "LFP3 ausserhalb " "Gemeinde", None), "featuretype": "t_lfp3_ausserhalb_gemeinde", "geom": "geometrie", "key": "ogc_fid", "sql": "", "readonly": True, "group": group, "style": "fixpunkte/lfp3ausserhalb.qml" } vlayer = self.layer_loader.load(layer) layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP3", "LFP3 pro TS", None), "featuretype": "t_lfp3_pro_ts", "key": "ogc_fid", "sql": "", "readonly": True, "group": group } vlayer_lfp3_pro_ts = self.layer_loader.load(layer) layer = { "type": "postgres", "title": _translate("VeriSO_V+D_FP3", "Gemeindegrenze", None), "featuretype": "gemeindegrenzen_gemeindegrenze", "geom": "geometrie", "key": "ogc_fid", "sql": "", "readonly": True, "group": group, "style": "global_qml/gemeindegrenze/gemgre_strichliert.qml" } gemgrelayer = self.layer_loader.load(layer) # Change map extent. # Bug (?) in QGIS: http://hub.qgis.org/issues/10980 # Closed for the lack of feedback. Upsi... # Still a problem? (sz / 2015-04-12) # sz / 2015-04-20: # Aaaah: still a problem. Some really strange combination of # checked/unchecked-order-of-layers-thing? # If wms is addes after gemgre then is scales (rect.scale(5))?! # So it seems that the last added layer HAS TO BE unchecked? # No not exactly. Only if a wms is added before? # rect.scale(5) has no effect? # I reopened the ticket / 2015-04-20 / sz if gemgrelayer: rect = gemgrelayer.extent() rect.scale(5) self.iface.mapCanvas().setExtent(rect) self.iface.mapCanvas().refresh() # Sometimes it does make much more sense # to zoom to maximal extent: # self.iface.mapCanvas().zoomToFullExtent() self.export_to_excel(vlayer_lfp3_pro_ts) except Exception: QApplication.restoreOverrideCursor() exc_type, exc_value, exc_traceback = sys.exc_info() self.message_bar.pushMessage("Error", str( traceback.format_exc(exc_traceback)), level=Qgis.Critical, duration=0) QApplication.restoreOverrideCursor()
def fusionnerJointure(self, cheminCompletParcelle, jointureChoisie): """ Selon les tables déja ouverte dans le projet : ouverture si necessaire des différents cas de délimiteurs Jointure par QGIS """ # Vérification du projet ouverte monProjet = QgsProject.instance() if monProjet.fileName() == None or monProjet.fileName() == "": monPrint("Projet en cours de création", T_WAR) else: monPrint("Projet ouvert {}".format(monProjet.fileName())) root = monProjet.layerTreeRoot() # Création du groupe jointure_date dateMaintenant = datetime.now() nomGroupe = MonParcellaire_JOI + " du " + dateMaintenant.strftime( "%d %b à %Hh%M:%S") temporaireGroupe = QgsLayerTreeGroup(nomGroupe) # Positionner en haut de root root.addChildNode(temporaireGroupe) nouveauGroupe = temporaireGroupe.clone() root.insertChildNode(0, nouveauGroupe) root.removeChildNode(temporaireGroupe) # Ouverture du vecteur parcelle parcelle = QgsVectorLayer( cheminCompletParcelle, MonParcellaire_PAR + SEP_U + MonParcellaire_JOI, 'ogr') monProjet.addMapLayer(parcelle, False) nouveauGroupe.addLayer(parcelle) # Recherche delimiteur delimiteur, csv, nomCsv = self.rechercherDelimiteurJointure( jointureChoisie, "No Pandas") nomCourtJointure = os.path.basename(jointureChoisie) monPrint( "Délimiteur identifié {0} pour {1}".format(delimiteur, nomCourtJointure), T_OK) monProjet.addMapLayer(csv, False) nouveauGroupe.addLayer(csv) # Jointure attributsSelectionnes = self.AttributsAJoindre_listWidget.selectedItems( ) attributsAJoindre = [] for positionAttribut in range(len(attributsSelectionnes)): attributsAJoindre.append( str(self.AttributsAJoindre_listWidget.selectedItems() [positionAttribut].text())) #monPrint( "Attributs à joindre {}".format( attributsAJoindre)) # Liste des champs dans csv nomColonnes, _ = self.lireAttributsJointure(jointureChoisie) attributsAJoindreOrdonne = [] for col in nomColonnes: if col in attributsAJoindre: if col != MonParcellaireNomAttribut: attributsAJoindreOrdonne.append(col) #monPrint( "Attributs à joindre ordonné {}".format( attributsAJoindreOrdonne)) champVecteur = MonParcellaireNomAttribut maJointure = QgsVectorLayerJoinInfo() champCsv = self.AttributJointure_comboBox.currentText() maJointure.setJoinFieldName(champCsv) maJointure.setTargetFieldName(champVecteur) maJointure.setUsingMemoryCache(True) maJointure.setPrefix("") maJointure.setJoinLayer(csv) # Récupérer les champs de jointure maJointure.setJoinFieldNamesSubset(attributsAJoindreOrdonne) parcelle.addJoin(maJointure) return jointureChoisie, attributsAJoindreOrdonne
def testJoinedFieldIsEditableRole(self): layer = QgsVectorLayer("Point?field=id_a:integer", "addfeat", "memory") layer2 = QgsVectorLayer("Point?field=id_b:integer&field=value_b", "addfeat", "memory") QgsProject.instance().addMapLayers([layer, layer2]) # editable join join_info = QgsVectorLayerJoinInfo() join_info.setTargetFieldName("id_a") join_info.setJoinLayer(layer2) join_info.setJoinFieldName("id_b") join_info.setPrefix("B_") join_info.setEditable(True) join_info.setUpsertOnEdit(True) layer.addJoin(join_info) m = QgsFieldModel() m.setLayer(layer) self.assertIsNone( m.data(m.indexFromName('id_a'), QgsFieldModel.JoinedFieldIsEditable)) self.assertTrue( m.data(m.indexFromName('B_value_b'), QgsFieldModel.JoinedFieldIsEditable)) self.assertIsNone( m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable)) self.assertIsNone( m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable)) m.setAllowExpression(True) m.setExpression('an expression') self.assertIsNone( m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable)) m.setAllowEmptyFieldName(True) self.assertIsNone( m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable)) proxy_m = QgsFieldProxyModel() proxy_m.setFilters(QgsFieldProxyModel.AllTypes | QgsFieldProxyModel.HideReadOnly) proxy_m.sourceFieldModel().setLayer(layer) self.assertEqual(proxy_m.rowCount(), 2) self.assertEqual(proxy_m.data(proxy_m.index(0, 0)), 'id_a') self.assertEqual(proxy_m.data(proxy_m.index(1, 0)), 'B_value_b') # not editable join layer3 = QgsVectorLayer("Point?field=id_a:integer", "addfeat", "memory") QgsProject.instance().addMapLayers([layer3]) join_info = QgsVectorLayerJoinInfo() join_info.setTargetFieldName("id_a") join_info.setJoinLayer(layer2) join_info.setJoinFieldName("id_b") join_info.setPrefix("B_") join_info.setEditable(False) layer3.addJoin(join_info) m = QgsFieldModel() m.setLayer(layer3) self.assertIsNone( m.data(m.indexFromName('id_a'), QgsFieldModel.JoinedFieldIsEditable)) self.assertFalse( m.data(m.indexFromName('B_value_b'), QgsFieldModel.JoinedFieldIsEditable)) self.assertIsNone( m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable)) self.assertIsNone( m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable)) m.setAllowExpression(True) m.setExpression('an expression') self.assertIsNone( m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable)) m.setAllowEmptyFieldName(True) self.assertIsNone( m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable)) proxy_m = QgsFieldProxyModel() proxy_m.sourceFieldModel().setLayer(layer3) proxy_m.setFilters(QgsFieldProxyModel.AllTypes | QgsFieldProxyModel.HideReadOnly) self.assertEqual(proxy_m.rowCount(), 1) self.assertEqual(proxy_m.data(proxy_m.index(0, 0)), 'id_a')
def add_joined_layer( source_layer: Union[FeatureLayer, StandaloneTable], # pylint: disable=too-many-branches input_file, base_layer: QgsVectorLayer, context: Context): """ Adds joined layers """ if not source_layer.join: return None if isinstance(source_layer.join, MemoryRelationshipClassName): if isinstance(source_layer.join.origin_name, RelQueryTableName): if context.unsupported_object_callback: context.unsupported_object_callback( '{}: Nested joins are not supported in QGIS'.format( context.layer_name), level=Context.CRITICAL) return None join_info = QgsVectorLayerJoinInfo() join_info.setJoinFieldName(source_layer.join.origin_primary_key) join_info.setTargetFieldName(source_layer.join.origin_foreign_key) base, _ = os.path.split(input_file) source_layer_props = DatasetNameConverter.convert( name=source_layer.join.destination_name, base=base, crs=QgsCoordinateReferenceSystem(), context=context) context.layer_type_hint = source_layer_props.wkb_type name = 'join' if hasattr(source_layer.join.destination_name, 'name'): name = source_layer.join.destination_name.name join_info.setPrefix(name + '.') if Qgis.QGIS_VERSION_INT >= 30800: opts = QgsVectorLayer.LayerOptions() if source_layer_props.wkb_type is not None: opts.fallbackWkbType = source_layer_props.wkb_type vl = QgsVectorLayer(source_layer_props.uri, name, source_layer_props.provider, opts) else: vl = QgsVectorLayer(source_layer_props.uri, name, source_layer_props.provider) if not vl.isValid() and Qgis.QGIS_VERSION_INT < 30600: if source_layer_props.provider == 'ogr' and not os.path.exists( source_layer_props.file_name ) and context.invalid_layer_resolver: res = context.invalid_layer_resolver( source_layer.join.name, source_layer_props.uri, source_layer_props.wkb_type) source_layer_props.uri = res.uri source_layer_props.provider = res.providerKey vl = QgsVectorLayer(source_layer_props.uri, 'join', source_layer_props.provider) # todo layer name vl.setRenderer(QgsNullSymbolRenderer()) try: vl.setFlags(vl.flags() | QgsMapLayer.Private) except AttributeError: pass join_info.setJoinLayer(vl) base_layer.addJoin(join_info) return vl else: if context.unsupported_object_callback: context.unsupported_object_callback( '{}: Join layers of type {} are not yet supported'.format( context.layer_name, source_layer.join.__class__.__name__), level=Context.CRITICAL) return None
def processAlgorithm(self, parameters, context, feedback): self.layers = self.parameterAsLayerList(parameters, self.INPUTS, context) self.drop = self.parameterAsBool(parameters, self.DROP_EXISTING_JOINS, context) # return {} # def postProcess(self, context, feedback): # # We try to use postProcess instead of processAlgorithm to propagate joins in the project. # layers = self.layers # drop = self.drop total = len(self.layers) failed = [] feedback.pushDebugInfo('{} layer(s) have been selected.'.format(total)) for i, layer in enumerate(self.layers): # Just trying on more time to get the real layer layer = context.project().mapLayer(layer.id()) if not layer: feedback.reportError( 'Layer {} has not been found in the project. Skipping…'. format(layer.name())) continue feedback.pushInfo('Processing layer \'{}\' with ID {}'.format( layer.name(), layer.id())) joined_fields = [] if self.drop: for vector_join in layer.vectorJoins(): feedback.pushInfo('Removing join \'{}\''.format( vector_join.joinFieldName())) layer.removeJoin(vector_join.joinLayerId()) for field in layer.fields(): widget = field.editorWidgetSetup() if not widget.type() == 'ValueRelation': continue config = widget.config() target_layer = config['Layer'] target_field = config['Key'] source_field = field.name() join_layer = context.project().mapLayer(target_layer) if not join_layer: feedback.reportError( "The layer \"{}\" linked to the field \"{}\" has not been found in the project. " "Skipping this ValueRelation…".format( target_layer, source_field)) continue join = QgsVectorLayerJoinInfo() join.setJoinLayerId(target_layer) join.setJoinFieldName(target_field) join.setTargetFieldName(source_field) join.setUsingMemoryCache(True) feedback.pushInfo( 'Adding join on \'{}\' with prefix \'{}\''.format( field.name(), self.prefix.format(join_layer.name()))) join.setPrefix(self.prefix.format(join_layer.name())) if not layer.addJoin(join): failed.append(layer.name()) feedback.reportError( 'Failed to add the join on {} {}'.format( layer.name(), field.name())) continue for join_field in join_layer.fields(): joined_fields.append( self.prefix.format(join_layer.name()) + join_field.name()) # Uncheck WMS feedback.pushInfo('Unchecking WMS fields') # if Qgis.QGIS_VERSION_INT < 31800: layer.setExcludeAttributesWms(joined_fields) # else: # # Fix for QGIS >= 3.16 # for field in joined_fields: # layer.setFieldConfigurationFlag( # layer.fields().indexFromName(field), QgsField.HideFromWms, True) feedback.pushDebugInfo(', '.join(layer.excludeAttributesWms())) # Uncheck WFS for ids id_fields = [ f for f in joined_fields if f.endswith('_fid') or f.endswith('_id') ] feedback.pushInfo('Unchecking WFS fields') # if Qgis.QGIS_VERSION_INT < 31800: layer.setExcludeAttributesWfs(id_fields) # else: # # Fix for QGIS >= 3.16 # for field in id_fields: # layer.setFieldConfigurationFlag( # layer.fields().indexFromName(field), QgsField.HideFromWfs, True) feedback.pushDebugInfo(', '.join(layer.excludeAttributesWfs())) feedback.setProgress((i + 1) / total * 100) # layer.reload() It does nothing, not enough to propagate the join if failed: msg = 'Some joins failed to be added for : {}'.format( ', '.join(failed)) raise QgsProcessingException(msg) feedback.reportError( 'Everything went fine, BUT you must save your project and reopen it. Joins, WMS and WFS are ' 'not appearing otherwise.') return {}