Outdated version of the documentation. Find the latest one here.

Folosirea suportului de hartă

Widget-ul suportului de hartă este, probabil, cel mai important în QGIS, deoarece prezintă o hartă compusă din straturi suprapuse și permite atât interacțiunea cu harta cât și cu straturile. Suportul arată întotdeauna o parte a hărții definită de caseta de încadrare curentă. Interacțiunea se realizează prin utilizarea unor instrumente pentru hartă: există instrumente de panoramare, de mărire, de identificare a straturilor, de măsurare, de editare vectorială și altele. Similar altor programe de grafică, există întotdeauna un instrument activ, iar utilizatorul poate comuta între instrumentele disponibile.

Map canvas is implemented as QgsMapCanvas class in qgis.gui module. The implementation is based on the Qt Graphics View framework. This framework generally provides a surface and a view where custom graphics items are placed and user can interact with them. We will assume that you are familiar enough with Qt to understand the concepts of the graphics scene, view and items. If not, please make sure to read the overview of the framework.

Ori de câte ori harta a fost deplasată, mărită/micșorată (sau alte acțiuni care declanșează o recitire), harta este randată iarăși în interiorul granițelor curente. Straturile sunt transformate într-o imagine (folosind clasa QgsMapRenderer) iar acea imagine este afișată pe suport. Elementul grafic (în termeni ai cadrului de lucru Qt Graphics View) responsabil pentru a afișarea hărții este QgsMapCanvasMap. Această clasă controlează, de asemenea, recitirea hărții randate. În afară de acest element, care acționează ca fundal, pot exista mai multe elemente ale suportului hărții. Elementele tipice suportului de hartă sunt benzile elastice (utilizate pentru măsurare, editare vectorială etc) sau marcajele nodurilor. Elementele suportului sunt de obicei utilizate pentru a oferi un răspuns vizual pentru instrumentele hărții, de exemplu, atunci când se creează un nou poligon, instrumentul corespunzător creează o bandă elastică de forma actuală a poligonului. Toate elementele suportului de hartă reprezintă subclase ale QgsMapCanvasItem care adaugă mai multe funcționalități obiectelor de bază QGraphicsItem.

Pentru a rezuma, arhitectura suportului pentru hartă constă în trei concepte:

  • suportul de hartă — pentru vizualizarea hărții

  • elementele — elemente suplimentare care pot fi afișate în suportul hărții

  • instrumentele hărții — pentru interacțiunea cu suportul hărții

Încapsularea suportului de hartă

Canevasul hărții este un widget ca orice alt widget Qt, așa că utilizarea este la fel de simplă ca și crearea și afișarea lui

canvas = QgsMapCanvas()
canvas.show()

Acest cod va produce o fereastră de sine stătătoare cu suport pentru hartă. Ea poate fi, de asemenea, încorporată într-un widget sau într-o fereastră deja existente. Atunci când se utilizează fișiere .ui și Qt Designer, puneți un QWidget pe formă pe care, ulterior, o veți promova la o nouă clasă: setați QgsMapCanvas ca nume de clasă și stabiliți qgis.gui ca fișier antet. Utilitarul ``pyuic4 `` va avea grijă de ea. Acesta este un mod foarte convenabil de încapsulare a suportului. Cealaltă posibilitate este de a scrie manual codul pentru a construi suportul hărții și alte widget-uri (în calitate de copii ai ferestrei principale sau de dialog), apoi creați o așezare în pagină.

În mod implicit, canevasul hărții are un fundal negru și nu utilizează anti-zimțare. Pentru a seta fundalul alb și pentru a permite anti-zimțare pentru o redare mai bună

canvas.setCanvasColor(Qt.white)
canvas.enableAntiAliasing(True)

(În cazul în care vă întrebați, Qt vine de la modulul PyQt4.QtCore iar Qt.white este una dintre instanțele QColor predefinite.)

Now it is time to add some map layers. We will first open a layer and add it to the map layer registry. Then we will set the canvas extent and set the list of layers for canvas

layer = QgsVectorLayer(path, name, provider)
if not layer.isValid():
  raise IOError, "Failed to open the layer"

# add layer to the registry
QgsMapLayerRegistry.instance().addMapLayer(layer)

# set extent to the extent of our layer
canvas.setExtent(layer.extent())

# set the map canvas layer set
canvas.setLayerSet( [ QgsMapCanvasLayer(layer) ] )

După executarea acestor comenzi, suportul ar trebui să arate stratul pe care le-ați încărcat.

Folosirea instrumentelor în suportul de hartă

The following example constructs a window that contains a map canvas and basic map tools for map panning and zooming. Actions are created for activation of each tool: panning is done with QgsMapToolPan, zooming in/out with a pair of QgsMapToolZoom instances. The actions are set as checkable and later assigned to the tools to allow automatic handling of checked/unchecked state of the actions – when a map tool gets activated, its action is marked as selected and the action of the previous map tool is deselected. The map tools are activated using setMapTool() method.

from qgis.gui import *
from PyQt4.QtGui import QAction, QMainWindow
from PyQt4.QtCore import SIGNAL, Qt, QString

class MyWnd(QMainWindow):
  def __init__(self, layer):
    QMainWindow.__init__(self)

    self.canvas = QgsMapCanvas()
    self.canvas.setCanvasColor(Qt.white)

    self.canvas.setExtent(layer.extent())
    self.canvas.setLayerSet( [ QgsMapCanvasLayer(layer) ] )

    self.setCentralWidget(self.canvas)

    actionZoomIn = QAction(QString("Zoom in"), self)
    actionZoomOut = QAction(QString("Zoom out"), self)
    actionPan = QAction(QString("Pan"), self)

    actionZoomIn.setCheckable(True)
    actionZoomOut.setCheckable(True)
    actionPan.setCheckable(True)

    self.connect(actionZoomIn, SIGNAL("triggered()"), self.zoomIn)
    self.connect(actionZoomOut, SIGNAL("triggered()"), self.zoomOut)
    self.connect(actionPan, SIGNAL("triggered()"), self.pan)

    self.toolbar = self.addToolBar("Canvas actions")
    self.toolbar.addAction(actionZoomIn)
    self.toolbar.addAction(actionZoomOut)
    self.toolbar.addAction(actionPan)

    # create the map tools
    self.toolPan = QgsMapToolPan(self.canvas)
    self.toolPan.setAction(actionPan)
    self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in
    self.toolZoomIn.setAction(actionZoomIn)
    self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out
    self.toolZoomOut.setAction(actionZoomOut)

    self.pan()

  def zoomIn(self):
    self.canvas.setMapTool(self.toolZoomIn)

  def zoomOut(self):
    self.canvas.setMapTool(self.toolZoomOut)

  def pan(self):
    self.canvas.setMapTool(self.toolPan)

You can put the above code to a file, e.g. mywnd.py and try it out in Python console within QGIS. This code will put the currently selected layer into newly created canvas

import mywnd
w = mywnd.MyWnd(qgis.utils.iface.activeLayer())
w.show()

Just make sure that the mywnd.py file is located within Python search path (sys.path). If it isn’t, you can simply add it: sys.path.insert(0, '/my/path') — otherwise the import statement will fail, not finding the module.

Benzile elastice și marcajele nodurilor

To show some additional data on top of the map in canvas, use map canvas items. It is possible to create custom canvas item classes (covered below), however there are two useful canvas item classes for convenience: QgsRubberBand for drawing polylines or polygons, and QgsVertexMarker for drawing points. They both work with map coordinates, so the shape is moved/scaled automatically when the canvas is being panned or zoomed.

Pentru a afișa o polilinie

r = QgsRubberBand(canvas, False)  # False = not a polygon
points = [ QgsPoint(-1,-1), QgsPoint(0,1), QgsPoint(1,-1) ]
r.setToGeometry(QgsGeometry.fromPolyline(points), None)

Pentru a afișa un poligon

r = QgsRubberBand(canvas, True)  # True = a polygon
points = [ [ QgsPoint(-1,-1), QgsPoint(0,1), QgsPoint(1,-1) ] ]
r.setToGeometry(QgsGeometry.fromPolygon(points), None)

Rețineți că punctele pentru poligon nu reprezintă o simplă listă: în fapt, aceasta este o listă de inele conținând inele liniare ale poligonului: primul inel reprezintă granița exterioară, în plus (opțional) inelele corespund găurilor din poligon.

Benzile elastice acceptă unele personalizări, și anume schimbarea culorii și a lățimii liniei

r.setColor(QColor(0,0,255))
r.setWidth(3)

Elementele suportului sunt legate de suportul hărții. Pentru a le ascunde temporar (și a le arăta din nou, folosiți combinația hide() și show(). Pentru a elimina complet elementul, trebuie să-l eliminăm de pe scena canevasului

canvas.scene().removeItem(r)

(În C + + este posibilă ștergerea doar a elementului, însă în Python del r ar șterge doar referința iar obiectul va exista în continuare, acesta fiind deținut de suport)

Banda elastică poate fi de asemenea utilizată pentru desenarea de puncte, însă, clasa QgsVertexMarker este mai potrivită pentru aceasta (QgsRubberBand ar trasa doar un dreptunghi în jurul punctului dorit). Cum să utilizați simbolul nodului

m = QgsVertexMarker(canvas)
m.setCenter(QgsPoint(0,0))

În acest mod se va desena o cruciuliță roșie pe poziția [0,0]. Este posibilă personalizarea tipului pictogramei, dimensiunea, culoarea și lățimea instrumentului de desenare

m.setColor(QColor(0,255,0))
m.setIconSize(5)
m.setIconType(QgsVertexMarker.ICON_BOX) # or ICON_CROSS, ICON_X
m.setPenWidth(3)

Pentru ascunderea temporară a markerilor vertex și pentru eliminarea lor de pe suport, același lucru este valabil și pentru benzile elastice.

Dezvoltarea instrumentelor personalizate pentru suportul de hartă

Puteți crea propriile instrumente, pentru a implementa un comportament personalizat pentru acțiunile executate de către utilizatori pe canevas.

Instrumentele de hartă ar trebui să moștenească clasa QgsMapTool sau orice altă clasă derivată, și să fie selectate ca instrumente active pe suport, folosindu-se metoda setMapTool(), așa cum am văzut deja.

Iată un exemplu de instrument pentru hartă, care permite definirea unei limite dreptunghiulare, făcând clic și trăgând cursorul mouse-ului pe canevas. După ce este definit dreptunghiul, coordonatele sale sunt afișate în consolă. Se utilizează elementele benzii elastice descrise mai înainte, pentru a arăta dreptunghiul selectat, așa cum a fost definit.

class RectangleMapTool(QgsMapToolEmitPoint):
  def __init__(self, canvas):
      self.canvas = canvas
      QgsMapToolEmitPoint.__init__(self, self.canvas)
      self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon)
      self.rubberBand.setColor(Qt.red)
      self.rubberBand.setWidth(1)
      self.reset()

  def reset(self):
      self.startPoint = self.endPoint = None
      self.isEmittingPoint = False
      self.rubberBand.reset(QGis.Polygon)

  def canvasPressEvent(self, e):
      self.startPoint = self.toMapCoordinates(e.pos())
      self.endPoint = self.startPoint
      self.isEmittingPoint = True
      self.showRect(self.startPoint, self.endPoint)

  def canvasReleaseEvent(self, e):
      self.isEmittingPoint = False
      r = self.rectangle()
      if r is not None:
        print "Rectangle:", r.xMin(), r.yMin(), r.xMax(), r.yMax()

  def canvasMoveEvent(self, e):
      if not self.isEmittingPoint:
        return

      self.endPoint = self.toMapCoordinates( e.pos() )
      self.showRect(self.startPoint, self.endPoint)

  def showRect(self, startPoint, endPoint):
      self.rubberBand.reset(QGis.Polygon)
      if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
        return

      point1 = QgsPoint(startPoint.x(), startPoint.y())
      point2 = QgsPoint(startPoint.x(), endPoint.y())
      point3 = QgsPoint(endPoint.x(), endPoint.y())
      point4 = QgsPoint(endPoint.x(), startPoint.y())

      self.rubberBand.addPoint(point1, False)
      self.rubberBand.addPoint(point2, False)
      self.rubberBand.addPoint(point3, False)
      self.rubberBand.addPoint(point4, True)    # true to update canvas
      self.rubberBand.show()

  def rectangle(self):
      if self.startPoint is None or self.endPoint is None:
        return None
      elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y():
        return None

      return QgsRectangle(self.startPoint, self.endPoint)

  def deactivate(self):
      QgsMapTool.deactivate(self)
      self.emit(SIGNAL("deactivated()"))

Dezvoltarea elementelor personalizate pentru suportul de hartă

DE EFECTUAT:
how to create a map canvas item