Clase QgsDistanceArea en PyQGIS

El PyQGIS Cook Book sugiere emplear la clase QgsDistanceArea cuando se requiera más precisión a la hora de determinar áreas y distancias, en lugar de emplear QgsGeometry o QgsPoint, porque estas últimas están basadas en el plano; no en el esferoide. Sin embargo, los ejemplos que refiere el PyQGIS Cook Book no han sido actualizados en cuanto a los métodos de esta clase (QgsDistanceArea). Para ejemplificar su uso se va a emplear un raster (ver imagen) donde, sólo a modo ilustrativo, se le coloca un shapefile de puntos para visualizar aquellos que van a ser manipulados desde la Python Console.

rectangle

Primero, se selecciona el ráster como capa activa y se crea una referencia al objeto mediante iface. Después, se utiliza el método ‘extent’ de la clase QgsRasterLayer para acceder a los métodos de la clase QgsRectangle y así obtener las coordenadas (como objetos de la clase QgsPoint) del vértice inferior derecho (vértice mínimo), del vértice superior derecho (vértice máximo) y el centroide del raster; tal como se ejemplifica abajo.

>>>raster=iface.activeLayer()
>>>point_min=QgsPoint(raster.extent().xMinimum(), raster.extent().yMinimum())
>>>point_max=QgsPoint(raster.extent().xMaximum(), raster.extent().yMaximum())
>>>centroid=QgsPoint(raster.extent().center())
>>>point_min
(354971,4.4149e+06)
>>>point_max
(479272,4.47343e+06)
>>>centroid
(417122,4.44417e+06)

En la clase QgsPoint se tiene el método ‘sqrDist’ (distancia al cuadrado) que permite determinar la distancia entre dos puntos. Vamos a calcularla entre point_min y point_max. Por tanto:

>>>from math import sqrt
>>>dist =sqrt(point_min.sqrDist(point_max))
>>>dist
137389.7277000894

Para hacer lo mismo con la clase QgsDistanceArea se tiene que usar el constructor de la clase para crear un objeto (lo llamamos d) y comprobamos que efectivamente ha sido creado. A continuación, con dir(QgsDistanceArea), observamos los métodos que pueden ser usados.

>>>d = QgsDistanceArea()
>>>d
<qgis.core.QgsDistanceArea object at 0x219567C8>
>>>dir(QgsDistanceArea)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', 
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bearing', 
'convertMeasurement', 'ellipsoid', 'ellipsoidInverseFlattening', 
'ellipsoidSemiMajor', 'ellipsoidSemiMinor', 'ellipsoidalEnabled', 
'geographic', 'measure', 'measureLine', 'measurePerimeter', 
'measurePolygon', 'setEllipsoid', 'setEllipsoidalMode', 
'setSourceAuthId', 'setSourceCrs', 'sourceCrs', 'textUnit']

Vamos a emplear el método ‘measureLine’ a ver que ocurre.

>>>d.measureLine(point_min,point_max)
137389.7277000894

Se obtiene el mismo resultado anterior. Era previsible porque todavía no se ha habilitado la proyección. Sin embargo, se hace de manera diferente a lo ejemplificado en el PyQGIS Cook Book porque los métodos de clase han cambiado. Primero, averiguamos que elipsoide se está usando (la respuesta parece obvia: ‘ninguno’). Luego establecemos el elipsoide ‘WGS84’ y habilitamos el modo elipsoidal (y lo comprobamos). Finalmente, calculamos la distancia.

>>>d.ellipsoid()
u'NONE'
>>>d.setEllipsoid('WGS84')
True
>>>d.setEllipsoidalMode(True)
>>>d.ellipsoidalEnabled() #comprueba habilitacion)
True
>>>d.measureLine(point_min,point_max)
6031213.960311541

La nueva “distancia” es exageradamente diferente a la anterior. La razón estriba en que al habilitar el modo elipsoidal las coordenadas a ser usadas deben estar en coordenadas geográficas. Hay que apelar primero a los métodos de las clases QgsCoordinateReferenceSystem y QgsCoordinateTransform. Por tanto:

>>>crsSrc = QgsCoordinateReferenceSystem(32612) #WGS84/UTM12N
>>>crsDest = QgsCoordinateReferenceSystem(4326) #WGS84/long/lat
>>>xform = QgsCoordinateTransform(crsSrc, crsDest)
>>>list_points=[point_min, point_max]
>>>p_transf=[]
>>>for item in list_points:
...    p_transf.append(xform.transform(item))
>>>p_transf
[(-112.696,39.8718), (-111.244,40.4112)]
>>>d.measureLine(p_transf)
137430.90149954

El resultado final es del orden esperado y la distancia entre los dos puntos está sobre la superficie del elipsoide.

Esta entrada fue publicada en Código Python, PyQGIS, SIG, Software Libre. Guarda el enlace permanente.

Una respuesta a Clase QgsDistanceArea en PyQGIS

  1. Pingback: Clase QgsDistanceArea en PyQGIS | NOSOLOSIG | ...

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s