Nivologie

Automatisation QGIS des cartes dynamiques3D au moyen d'un script pyton

 

Objectif

l'automatisation  de QGIS par des scripts pytrhon améliore sensiblement la vitesse d'exécution et évite les erreurs dûes aux tâches répétitives  et fastidieuses. L'élaboration d'une carte 3D est réalisée manuellement en 5 mn avec un peu de pratique. Ce script va remplacer avantagement ces enchainements répétitifs et creer  5 cartes dynamiques  couvrant les Alpes du Sud du Mercantour aux Ecrins en quelques secondes. Ces cartes pretes à lempoi sont utilisables par un simple lien sur le fichier de type "bassinFSCaaaammjj.HTML"

Principe

En prenant comme base le programme python Qgis2threejs export

Les  commandes sucessives sont lancées a partir du panneau Python de Qgis qui par défaut initialise la  variable iface, instance de QgisInterface.

Les enchainements suivants sont éxécutés

  • Phase d'initialisation :importation du fichier des paramètres de reglage de Qgis2threejs,et desactivation de toutes les cartes FSC dans la liste des couches
  • Chargement d'une carte FSC (fractional Snow Cover) au format TIF  avec un systeme de projection  WGS84 .Ces cartes proviennent du site cryoland. Elles sont stockées localement dans le répertoire QGis/FSC et renomées FSCaaaammjj.TIF
  • Redimensionnement des  bassin ( vesubie, ubaye ,tinéee Ubaye,Guil, Queyras, Ecrin)  pour être entièrement contenu dans le canevas.Cette opération va modifier l'échelle de la carte en fonction de la fenêtre ecran disponible.
  • Sauvegarde de l'écan au format JPEG après rafraîchissement complet des couches. Cette image nommée par convention "bassinFSCaaaammjj.JPEG"  va remplacer avantageusement  la carte base64 PNG  calculée par Qgis2ThreeJs qui a pour principal inconvénient sa taille de 2 Mo
  • Calcul des dimensions du canevas comme  données d'entrée du script Qgis2ThreeJs.Exportation.
  • Modifications dans le fichier FSCaaaammjj.JS elaboré par le script Qgis2ThreeJs. Remplacement de  la portion de code  "data:image/png;base64......." par l'adresse URI " bassinFSCaaaammjj.JPEG"

 

Detail du Fichier python FSC3D.py et commentaires

 

#modules d'importation

import os
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from Qgis2threejs.api import Exporter

#chargement du fichier FSC a partir du repertoire /home/knobuntu/QGis/FSC
#initialisation
#desactiver toutes les cartes FSC
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
print layer
couchename= layer.name()
print couchename
x = couchename.find ('FSC')
if x >-1 :

iface.legendInterface().setLayerVisible(layer,False)
x=couchename .find('dem')
if x> -1:
iface.setActiveLayer(layer)
print couchename


#importation d'un FSC au format TIF
qfd=QFileDialog()
title='ouvrir un fichierraster FSC'
path="/home/knobuntu/QGis/FSC"
f=QFileDialog.getOpenFileName(qfd,title,path)
print f
liste=f.split('/')
inter=liste[-1]
liste=inter.split('.')
fscusuel=liste[0]
print fscusuel

layer= iface.addRasterLayer(f,fscusuel)

#chargement du fichier stylefsc.qml des distinction des couches de neige
layer.loadNamedStyle('/home/knobuntu/QGis/styles/stylefsc.qml')
layer.triggerRepaint()

# fichier de configuration dans /home/knobuntu/QGis/cryoland/config/config.qto3settings a reexporter lors de changements
settingsPath = "/home/knobuntu/QGis/cryoland/config/config.qto3settings"

 

#grandboucle
listebassin=['vesubie','tinee','ubaye']

for bassin in listebassin:


print bassin
# centrage et ajustement  de la couche vectorielle 'bassin" dans la fenêtre de l'écran (canvas)
layer = QgsMapLayerRegistry.instance().mapLayersByName(bassin)[0]
layer.updateExtents()
canvas=iface.mapCanvas()
canvas.setExtent(layer.extent())
canvas.refresh()
w=QWidget()
info="Attendre le rafraichissement et le repositionnement sur "+ bassin
QMessageBox.information(w, "Rafraichissement en cours","attendre le rafraichissement complet des couches")
#mesures du canvas
canvas=iface.mapCanvas()
e= canvas.extent()
xmax=e.xMaximum()
xmin= e.xMinimum()
ymin=e.yMinimum()
ymax=e.yMaximum()
print xmax/2
centrex= xmin+(xmax-xmin)/2
centrey=ymin+(ymax-ymin)/2
etendueX=(xmax-xmin)
etendueY=(ymax-ymin)
xpixel=canvas.size().width()
ypixel=canvas.size().height()

#sauvegarde  l image écran au format JPEG
couvertureUri="/home/knobuntu/QGis/cryoland/FSC3D/" + bassin + fscusuel +".jpeg"
canvas.saveAsImage( couvertureUri,None,"JPEG")
print couvertureUri
# tableau des lieux a exporter
places = [(bassin, QgsPoint(centrex,centrey))]
# fichier de sortie html par convention "Bassin + fscusuel+.html
path_tmpl = "/home/knobuntu/QGis/cryoland/FSC3D/" +bassin+fscusuel+ ".html"
print path_tmpl

# Coordonnees de transformation de wgs en lambert (non utilise lesysteme de reference est deja 2154)
wgs84 = QgsCoordinateReferenceSystem(2154, QgsCoordinateReferenceSystem.EpsgCrsId)
wgskno = QgsCoordinateReferenceSystem(2154, QgsCoordinateReferenceSystem.EpsgCrsId)
transform = QgsCoordinateTransform(wgskno,wgs84)

# Make sure that map canvas CRS is EPSG:2154
canvas = iface.mapCanvas()
canvas.setCrsTransformEnabled(True)
canvas.setDestinationCrs(wgskno)

# Get map settings from the map canvas
mapSettings = canvas.mapSettings()

# dimension du canvas
canvasSize = QSize(xpixel, ypixel)
mapSettings.setOutputSize(canvasSize)

# Etendue du canvas en coordonnees lambert pas de rotation
width = etendueX
height = etendueY
rotation = 0

# Creer et exporter
exporter = Exporter(iface, settingsPath)
exporter.setMapSettings(mapSettings)

for name, point in places:


# Coordinate transform
center = transform.transform(point)
# Set extent
exporter.setExtent(center, width, height, rotation)
# Output HTML file path
filepath = path_tmpl.format(name)
# Export
err = exporter.export(filepath, openBrowser=False)
if err == Exporter.NO_ERROR:


print "{0} has been exported to {1}".format(name, filepath)


else:


print "Failed to export {0}: {1}".format(name, err)

#remplacement du recouvrement PNG en base64 par le fichier "bassin+fscusuel+".JPEG"

fichier="/home/knobuntu/QGis/cryoland/FSC3D/"+bassin+fscusuel+".js"

ficsortie="/home/knobuntu/QGis/cryoland/sortie.js"
ficjs=open(fichier,'r')
ficsid=open(ficsortie,'w')

for ligne in ficjs:
x=0
print '1'
x=ligne.find ("data:image/png;base64")
if x>0 :
txt=ligne[:x]+bassin+fscusuel+'.jpeg"}'
ficsid.write(txt)
print 'trouve'
else:
ficsid.write(ligne)


ficjs.close()
ficsid.close()
os.rename(ficsortie,fichier)


#message e fin
QMessageBox.information(w, "Fin", "Les fichiers .HTML, .JS et .JPEG sont a transferer  du repertoire local ../ QGis/cryoland/FSC3D vers le serveur  ../images/cryoland/cartes3d" )