Con base en esta respuesta de gis.stackexchange.com, modifiqué la clase para incorporar como funcionalidades adicionales la posibilidad de visualizar e imprimir no sólo los values de los ráster sino también los atributos de vectoriales tipo punto, línea o polígono. El código completo se encuentra a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | from qgis.core import QgsRasterLayer, QgsRaster from qgis.gui import QgsMapToolEmitPoint from PyQt4.QtCore import QTimer from PyQt4.QtGui import QToolTip import itertools import numpy as np class TooltipLayerMapTool(QgsMapToolEmitPoint): def __init__(self, canvas): self.canvas = canvas QgsMapToolEmitPoint.__init__(self, self.canvas) self.timerMapTips = QTimer( self.canvas ) self.timerMapTips.timeout.connect( self.showMapTip ) def canvasPressEvent( self, e ): point = self.toMapCoordinates(self.canvas.mouseLastXY()) print '(' + str(point[0]) + ', ' + str(point[1]) + ')' if self.canvas.underMouse(): rLayer = iface.activeLayer() if type(rLayer) is QgsRasterLayer: ident = rLayer.dataProvider().identify( self.toMapCoordinates(self.canvas.mouseLastXY()), QgsRaster.IdentifyFormatValue ) if ident.isValid(): text = ", ".join(['{0:g}'.format(r) for r in ident.results().values() if r is not None] ) else: text = "Non valid value" print text if type(rLayer) is QgsVectorLayer: feats_ids = rLayer.fields().allAttributesList() names = [ rLayer.fields().field(id).name() for id in feats_ids ] feats = [ feat for feat in rLayer.getFeatures() ] point = self.toMapCoordinates(self.canvas.mouseLastXY()) text = "no layer features" if rLayer.geometryType() == QGis.Polygon: for feat in feats: if QgsGeometry.fromPoint(point).within(feat.geometry()): text = ", ".join(['{}: {}'.format(names[i], r) for i, r in enumerate(feat.attributes()) if r is not None] ) break else: n = len(feats) distances = [ [] for i in range(n) ] indices = [] for i, feat in enumerate(feats): dist = feat.geometry().distance(QgsGeometry.fromPoint(point)) if dist < 500: distances[i].append(dist) indices.append(i) new_dist = [] new_indx = [] for j, group in enumerate(distances): if group: new_dist.append(group[0]) new_indx.append(j) try: j = new_indx[new_dist.index(np.min(new_dist))] except ValueError: pass i = len(names) text = ", ".join(['{}: {}'.format(names[i],r) for i, r in enumerate(feats[j].attributes()) if r is not None] ) try: print text except UnboundLocalError: pass def canvasReleaseEvent(self, e): pass def canvasMoveEvent(self, e): if self.canvas.underMouse(): # Only if mouse is over the map QToolTip.hideText() self.timerMapTips.start( 700 ) # time in milliseconds def showMapTip( self ): self.timerMapTips.stop() if self.canvas.underMouse(): rLayer = iface.activeLayer() if type(rLayer) is QgsRasterLayer: ident = rLayer.dataProvider().identify( self.toMapCoordinates(self.canvas.mouseLastXY()), QgsRaster.IdentifyFormatValue ) if ident.isValid(): text = ", ".join(['{0:g}'.format(r) for r in ident.results().values() if r is not None] ) else: text = "Non valid value" QToolTip.showText( self.canvas.mapToGlobal( self.canvas.mouseLastXY() ), text, self.canvas ) if type(rLayer) is QgsVectorLayer: feats_ids = rLayer.fields().allAttributesList() names = [ rLayer.fields().field(id).name() for id in feats_ids ] feats = [ feat for feat in rLayer.getFeatures() ] point = self.toMapCoordinates(self.canvas.mouseLastXY()) text = "no layer features" if rLayer.geometryType() == QGis.Polygon: for feat in feats: if QgsGeometry.fromPoint(point).within(feat.geometry()): text = ", ".join(['{}: {}'.format(names[i], r) for i, r in enumerate(feat.attributes()) if r is not None] ) break else: n = len(feats) distances = [ [] for i in range(n) ] indices = [] for i, feat in enumerate(feats): dist = feat.geometry().distance(QgsGeometry.fromPoint(point)) if dist < 500: distances[i].append(dist) indices.append(i) new_dist = [] new_indx = [] for j, group in enumerate(distances): if group: new_dist.append(group[0]) new_indx.append(j) try: j = new_indx[new_dist.index(np.min(new_dist))] except ValueError: pass i = len(names) text = ", ".join(['{}: {}'.format(names[i],r) for i, r in enumerate(feats[j].attributes()) if r is not None] ) try: QToolTip.showText( self.canvas.mapToGlobal( self.canvas.mouseLastXY() ), text, self.canvas ) except UnboundLocalError: pass tooltipRaster = TooltipLayerMapTool( iface.mapCanvas() ) iface.mapCanvas().setMapTool( tooltipRaster ) # Use your Map Tool! |
Después de ejecutado en la Python Console de QGIS, al posicionar la cruz del cursor sobre cualquier rasgo del vectorial aparecerá la tooltip; tal como se presenta en la imagen siguiente:
Si se hace click con el mouse del ratón, los valores de la tooltip, conjuntamente con las coordenadas del punto, aparecerán impresos en la Python Console. Esto se visualiza a continuación:
Para los que todavía no han captado una posible utilidad de esto, imaginen lo fácil que sería aprender geografía empleando el shapefile world_borders; tal como se señala a continuación con el continente africano (cuántos sabran que el país señalado en la imagen es Zaire?):
No hay comentarios:
Publicar un comentario