Skip to content

Commit 4cb0e1d

Browse files
author
Régis Haubourg
committed
Version 1.0
publication version 1. First stable version with full functions working - activates callout modifications even after project load with Memory Layer plugin On - solves NoneType errors on project closing when some uncommited edits remain
1 parent 05a4eef commit 4cb0e1d

3 files changed

Lines changed: 107 additions & 33 deletions

File tree

EasyCustomLabeling/EasyCustomLabeling.py

Lines changed: 97 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,18 @@ def __init__(self, iface):
5959
translationPath = userPluginPath + "/i18n/"+pluginName+"_" + localeFullName + ".qm"
6060
else:
6161
translationPath = systemPluginPath + "/i18n/"+pluginName+"_" + localeFullName + ".qm"
62-
print translationPath
62+
# print translationPath
6363
self.localePath = translationPath
64+
6465
if QFileInfo(self.localePath).exists():
6566
self.translator = QTranslator()
6667
self.translator.load(self.localePath)
6768
QCoreApplication.installTranslator(self.translator)
68-
print('localepath exists')
69+
# print('localepath exists')
6970
# print('translation debug info :' + ' overrideLocale=' + str(overrideLocale) + '; localeFullName=' +localeFullName + '; translationPath=' + translationPath )
7071

72+
73+
7174
def initGui(self):
7275
#Create actions triggered by the plugin
7376
self.actionLabel = QAction( QIcon( ":/plugins/EasyCustomLabeling/icon.png" ), QtGui.QApplication.translate("EasyCustomLabeling", "Generates a layer ready for custom labeling tools", None, QtGui.QApplication.UnicodeUTF8), self.iface.mainWindow() )
@@ -107,15 +110,70 @@ def initGui(self):
107110
self.iface.addPluginToMenu( "&" + QtGui.QApplication.translate("EasyCustomLabeling", "Easy Custom labeling", None, QtGui.QApplication.UnicodeUTF8), self.actionLabel)
108111
self.iface.addPluginToMenu( "&" + QtGui.QApplication.translate("EasyCustomLabeling", "Easy Custom labeling", None, QtGui.QApplication.UnicodeUTF8), self.actionAbout)
109112

110-
113+
#connects labelLayerCheck class to QgisInterface::currentLayerChanged signal (QgsMapLayer * layer)
114+
#self.iface.currentLayerChanged.connect(self.labelLayerChecked)
115+
proj = QgsProject.instance()
116+
proj.readProject.connect(self.labelLayerChecked)
117+
# QObject.connect(self.iface, SIGNAL("currentLayerChanged ( QgsMapLayer *)"), self.labelLayerChecked)
118+
119+
#disconnects if label layers closed?
120+
121+
def labelLayerChecked(self):
122+
123+
print 'projet chargé: '
124+
# Checks if some labeling layers are already there, and replug, if not already labelLayerModified events
125+
layers = self.iface.legendInterface().layers()
126+
if layers :
127+
for layer in layers:
128+
if not layer:
129+
return
130+
# layer = self.iface.layer()
131+
# print 'labelLayerCheck triggered for ' + str(layer)
132+
133+
dp = layer.dataProvider()
134+
135+
LblXok = False
136+
LblYok = False
137+
LblAlignHok= False
138+
LblAlignVok= False
139+
LblShowCOok= False
140+
LblShowok= False
141+
142+
for f in dp.fields():
143+
if f.name() == 'LblX':
144+
LblXok = True
145+
# print 'LblXok'
146+
elif f.name() == 'LblY':
147+
LblYok = True
148+
# print 'LblYok'
149+
elif f.name() == 'LblAlignH':
150+
LblAlignHok = True
151+
# print 'LblAlignHok'
152+
elif f.name() == 'LblAlignV':
153+
LblAlignVok = True
154+
# print 'LblAlignVok'
155+
elif f.name() == 'LblShowCO':
156+
LblShowCOok = True
157+
# print 'LblShowCOok'
158+
elif f.name() == 'LblShow':
159+
LblShowok = True
160+
# print 'LblShowok'
161+
162+
if LblXok and LblYok and LblAlignHok and LblAlignVok and LblShowCOok and LblShowok :
163+
# print '-- label layer ok '
164+
layer.attributeValueChanged.connect(self.labelLayerModified)
165+
166+
167+
168+
111169
def labelLayerModified(self, FeatureId, idx, variant):
112170
editedLayer = self.iface.activeLayer()
113-
#print 'signal caught by labelLayerModified: layer: '+str(editedLayer.id())+'; FeatureId ' + str(FeatureId) + ' ; idx ' + str(idx) + ' const: ' + str(variant)
171+
# print 'signal caught by labelLayerModified: layer: '+str(editedLayer.id())+'; FeatureId ' + str(FeatureId) + ' ; idx ' + str(idx) + ' const: ' + str(variant)
114172

115173
#gets new attrib and geom > retune WKT with new label XY
116174
editFeature = QgsFeature()
117-
if editedLayer.getFeatures(QgsFeatureRequest().setFilterFid(FeatureId)).nextFeature(editFeature) is False:
118-
return False, "Could not fetch feature at ID %u." % featureId
175+
if editedLayer == None or editedLayer.getFeatures(QgsFeatureRequest().setFilterFid(FeatureId)).nextFeature(editFeature) is False :
176+
return
119177
else:
120178
# print 'traitement signal'
121179
editGeom = editFeature.geometry()
@@ -177,6 +235,7 @@ def labelLayerModified(self, FeatureId, idx, variant):
177235

178236

179237

238+
180239

181240

182241
if newFinalX < originX and newFinalY > originY and deltaY < deltaX : # cas quandran ul 1 ok
@@ -222,20 +281,20 @@ def labelLayerModified(self, FeatureId, idx, variant):
222281
coscreenlength = 100* coLength / scale
223282

224283
if coscreenlength < radius_threshold :
225-
print 'under radius_threshold'
284+
# print 'under radius_threshold'
226285
editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblShowCO'), '0')
227286
else :
228287
editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblShowCO'), '1')
229288

230-
#If Y label bigger than Yorigin, update Valign
231-
if newFinalY < originY and coscreenlength >= radius_threshold :
232-
editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblAlignV'), 'Top')
289+
# #If Y label bigger than Yorigin, update Valign
290+
# if newFinalY < originY and coscreenlength >= radius_threshold :
291+
# editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblAlignV'), 'Top')
233292

234-
elif newFinalY > originY and coscreenlength >= radius_threshold:
235-
editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblAlignV'), 'Base')
293+
# elif newFinalY > originY and coscreenlength >= radius_threshold:
294+
# editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblAlignV'), 'Base')
236295

237-
else :
238-
editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblAlignV'), 'Half')
296+
# else :
297+
#editedLayer.changeAttributeValue(FeatureId, editLayerProvider.fieldNameIndex('LblAlignV'), 'Half')
239298

240299

241300

@@ -248,7 +307,7 @@ def labelLayerModified(self, FeatureId, idx, variant):
248307

249308
# change visibility status of Callout if modified in attributes
250309
elif fieldname == 'LblShowCO': # change visibility status of Callout if modified in attributes
251-
print 'LblShowCO modifié '
310+
print 'LblShowCO modifié '
252311

253312
else :
254313
return False, "fieldname not in LblX or LblY."
@@ -257,14 +316,19 @@ def labelLayerModified(self, FeatureId, idx, variant):
257316

258317

259318
def unload( self):
260-
319+
# disconnects signals todo
320+
# self.iface.currentLayerChanged.disconnect()
321+
261322
# Remove the plugin menu item and icon
262323
self.toolBar.removeAction( self.actionLabel)
263324
self.iface.removePluginMenu( "&" + QtGui.QApplication.translate("EasyCustomLabeling", "Easy Custom labeling", None, QtGui.QApplication.UnicodeUTF8), self.actionLabel)
264325
self.iface.removePluginMenu( "&" + QtGui.QApplication.translate("EasyCustomLabeling", "Easy Custom labeling", None, QtGui.QApplication.UnicodeUTF8), self.actionAbout)
265326

266327
#remove action from mLabelToolBar if exists
267328
toolbars = self.iface.mainWindow().findChildren(QToolBar)
329+
330+
331+
268332
for toolbar in toolbars:
269333
if toolbar.objectName() == "mLabelToolBar":
270334
self.toolBar = toolbar
@@ -277,6 +341,7 @@ def unload( self):
277341
for a in actions:
278342
self.toolBar.addAction(actions[i])
279343
i=i+1
344+
280345

281346

282347
#main action that duplicates the layer
@@ -292,11 +357,11 @@ def runLabel(self):
292357
if not sourceLayer.type() == sourceLayer.VectorLayer:
293358
iface.messageBar().pushMessage("Error", QtGui.QApplication.translate("EasyCustomLabeling", "Current active layer is not a vector layer. \n Please click on the vector layer you need to label", None, QtGui.QApplication.UnicodeUTF8), level=0, duration=3)
294359
return
295-
print 'ligne 142 a traduire'
360+
296361
# detect if selection exists on that layer
297362
#debug
298363
nbSelectedObjects = sourceLayer.selectedFeatureCount()
299-
print '# nbSelectedObjects: ' + str(nbSelectedObjects)
364+
# print '# nbSelectedObjects: ' + str(nbSelectedObjects)
300365
ret = 0
301366
if not nbSelectedObjects == 0 :
302367
#dialog to ask if user wants to use current selection or not
@@ -327,7 +392,7 @@ def runLabel(self):
327392
msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
328393
msgBox.setDefaultButton(QMessageBox.Ok) # This function was introduced in Qt 4.3.
329394
ret = msgBox.exec_() #ret_val = 1024 si OK, 4194304 sinon
330-
print 'dialog many objects: ' + str(ret)
395+
# print 'dialog many objects: ' + str(ret)
331396

332397

333398

@@ -340,12 +405,12 @@ def runLabel(self):
340405
#asks for default field to use as labeling (thanks to Victor Axbom Layer to labeled layer plugin)
341406
# create the dialog
342407
self.dlg = EasyCustomLabelingDialog(sourceLayerProvider)
343-
408+
self.dlg.exec_()
344409
# show the dialog
345-
if self.dlg.exec_():
346-
print 'dialog execution'
347-
else:
348-
return
410+
# if self.dlg.exec_():
411+
# return True# print 'dialog execution'
412+
# else :
413+
# return
349414

350415
# self.iface.mapCanvas().refresh()
351416
# returns self.dlg.labelfield.currentText()
@@ -357,10 +422,11 @@ def runLabel(self):
357422
labelLayer.setCrs(sourceLayer.crs())
358423
labelLayerProvider = labelLayer.dataProvider()
359424
labelLayerFields = labelLayerProvider.fields()
360-
print 'nom du champ 1 : ' + str(sourceLayerFields[1].name())
425+
# print 'nom du champ 1 : ' + str(sourceLayerFields[1].name())
361426
#convert field map to a list
362427
sourceLayerFieldsList =[]
363428
for f in sourceLayerFields:
429+
# print 'debug date : champ: ' + str(f.name()) + 'type_champ ' + str(f.typeName())
364430
if f.type() == 14:
365431
f.setType(10)
366432
sourceLayerFieldsList.append(f)
@@ -372,7 +438,6 @@ def runLabel(self):
372438
# # adds specific fields for data driven custom labeling
373439
labelFields = [
374440
QgsField( "LblField", QVariant.String, "varchar", 255),
375-
QgsField( "LblId", QVariant.Int, "integer", 1),
376441
QgsField( "LblX", QVariant.String, "varchar", 255) ,
377442
QgsField( "LblY", QVariant.String, "varchar", 255) ,
378443
QgsField( "LblAlignH", QVariant.String, "varchar", 12),
@@ -392,12 +457,12 @@ def runLabel(self):
392457

393458
r=labelLayerProvider.addAttributes(labelFields)
394459

395-
print 'ajout des champs de labeling: ' + str(r)
460+
# print 'ajout des champs de labeling: ' + str(r)
396461

397462
labelFields = labelLayerProvider.fields() # replace labelFields with source FIELDS + labelingFields
398463

399464
# iterate objects of layer to load new destination labelLayerProvider
400-
print 'start loop on source layer attributes'
465+
# print 'start loop on source layer attributes'
401466

402467
if ret == 16384 :
403468
selectedFeatures = sourceLayer.selectedFeatures()
@@ -430,6 +495,7 @@ def runLabel(self):
430495
labelFeature['LblShow'] = 1
431496
labelFeature['LblSize'] = 9
432497
labelFeature['LblAShow'] = 1
498+
labelFeature['LblAlignV'] = 'Half'
433499

434500
# displayFieldName = sourceLayer.displayField()
435501
# if displayFieldName :
@@ -506,7 +572,7 @@ def runLabel(self):
506572
iface.messageBar().pushMessage("Avertissement", QtGui.QApplication.translate("EasyCustomLabeling", "Turn on editing mode on label layer to start customizing labels"), level=0, duration=3)
507573

508574
except:
509-
print 'runLabel exception loop '
575+
# print 'runLabel exception loop '
510576
# if sourceLayer and not keepUserSelection :
511577
# sourceLayer.removeSelection()
512578
raise
@@ -519,8 +585,8 @@ def runLabel(self):
519585
self.iface.mapCanvas().freeze(0)
520586
self.iface.mapCanvas().refresh()
521587

522-
#QMessageBox.warning( None, "Avertissement", 'Pensez a enregistrer les editions de votre couche d étiquettes avant de quitter')
523-
print 'end of runlabel Action'
588+
#QMessageBox.warning( None, "Avertissement", 'Pensez a enregistrer les editions de votre couche d étiquettes avant de quitter')
589+
# print 'end of runlabel Action'
524590

525591
def runAbout(self):
526592
#QMessageBox.about(None, QtGui.QApplication.translate("EasyCustomLabeling", "texte about", None, QtGui.QApplication.UnicodeUTF8), QtGui.QApplication.translate("EasyCustomLabeling", "<strong>Easy custom labeling v. 0.4, Regis Haubourg (AEAG) - 2012. \n \n Action 1:This plugin duplicate a layer, transforming geometries into centroids, \n and adds all required fields for custom labeling. \n \n Action 2 - Arrow function draws lines between label and original object \n \n WARNING! This plugin requires to use Memory Layer Saver plugin if you want to save labels with project. \n Plugin memory layer saver 2.0 or higher is needed because of new gml behaviour (GDAL 1.9) \n \n Please send bugs or features requests here : http://hub.qgis.org/projects/easycustomlabeling </strong>", None, QtGui.QApplication.UnicodeUTF8))
2.02 KB
Binary file not shown.

EasyCustomLabeling/metadata.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,17 @@
99
name=EasyCustomLabeling
1010
qgisMinimumVersion=2.0
1111
description=Allows to quickly duplicate layer into memory layer ready for data defined labeling
12-
version=0.7
12+
version=1.0
1313
changelog=
14-
0.7: - solves date types bug
14+
1.0: First stable version with full functions working
15+
- activates callout modifications even after project load with Memory Layer plugin On
16+
- solves NoneType errors on project closing when some uncommited edits remain
17+
18+
fr:
19+
- permet la modification des traits de rappel après la réouverture d'un projet enregistré
20+
- résoud les erreurs à la fermeture de projet lorsqu'il reste des éditions non enregistrées.
21+
22+
0.7: - solves date types bug
1523
corrige le bug si la couche source contient des champs date
1624

1725
0.6: - better French translation

0 commit comments

Comments
 (0)