#1 Thu 05 March 2015 12:09
- simeric
- Participant assidu
- Date d'inscription: 10 Mar 2009
- Messages: 255
QGIS : Export KML avec information temporelle "TimeSpan"
Bonjour
Quelqu'un aurait-il une astuce pour exporter des données depuis Qgis en KML en enregistrant des infos temporelles dans la balise spécifique "TimeSpan" (afin que l'info soit exploitable dans la barre temporelle de Google Earth) ?
..ou bien un outil libre permettant de faire ça à partir d'un shapefile ?
Merci
Hors ligne
#2 Thu 05 March 2015 23:38
Re: QGIS : Export KML avec information temporelle "TimeSpan"
Si tu connais Python, tu pourrais créer un plugin. J'ai déjà eu il y a quelques temps à exporter un projet QGIS en KML un peu spécifique donc si tu le souhaites je peux te fournir un bout de code que tu pourrais customiser (notamment l'ajout de la balise TimeSpan).
Hors ligne
#3 Fri 06 March 2015 09:38
- simeric
- Participant assidu
- Date d'inscription: 10 Mar 2009
- Messages: 255
Re: QGIS : Export KML avec information temporelle "TimeSpan"
avec plaisir !
Je pense que ça peut intéresser la communauté.
Hors ligne
#4 Fri 06 March 2015 11:40
Re: QGIS : Export KML avec information temporelle "TimeSpan"
Voici une classe (adaptée de mon projet). J'espère que ça peut t'aider.
Code:
from qgis.core import * from qgis.gui import * import logging logging.getLogger('fastkml.config').addHandler(logging.NullHandler()) from fastkml import kml import shapely.wkt import os import re import zipfile from xml.etree import ElementTree class KmlExport(object): def __init__(self): self.ns='{http://www.opengis.net/kml/2.2}' ElementTree.register_namespace('',"http://www.opengis.net/kml/2.2") def projectToKml(self, projectId, outputDirectory, prettyprint=False): root=QgsProject.instance().layerTreeRoot() k = kml.KML() d = kml.Document(self.ns, projectId, projectId) k.append(d) self._addLayersInFolder(root, d, "") self._outputToKmlAndKmz(outputDirectory, k, projectId, prettyprint) def _addLayersInFolder(self,folder,kmlContainer, baseName): for node in folder.children(): if QgsLayerTree.isGroup(node): folderName=node.name() folderName=baseName+folderName f = kml.Folder(self.ns, folderName, folderName) kmlContainer.append(f) self._addLayersInFolder(node, f, folderName+"_") else: layerName=node.layerName() layerName=baseName+layerName f = kml.Folder(self.ns, layerName, layerName) kmlContainer.append(f) self._addFeaturesInLayer(node.layer(), f) def _addFeaturesInLayer(self, layer, kmlContainer): nameField=self._nameField(layer.name()) idLayer="#%s"%self._toId(layer.name()) fieldNames=map(lambda x:x.name(),layer.dataProvider().fields().toList()) nameFieldIndex=layer.fieldNameIndex(nameField) for feature in layer.getFeatures(): try: attributes=feature.attributes() geometry=feature.geometry() if not geometry: qDebug("Invalid geometry in layer %s (id='%s',geometry='%s')"%(layer.name(), attributes[nameFieldIndex],geometry.exportToWkt())) continue p=kml.Placemark(self.ns) p.name=attributes[nameFieldIndex] p.geometry=shapely.wkt.loads(geometry.exportToWkt()) data=self._dataElementsFromAttributes(fieldNames,attributes ) if len(data) > 0: p.extended_data = kml.ExtendedData(self.ns, [kml.SchemaData(self.ns, idLayer, data)]) kmlContainer.append(p) except Exception: qDebug("Error in layer %s (id='%s',geometry='%s')"%(layer.name(), attributes[nameFieldIndex],geometry.exportToWkt())) raise def _outputToKmlAndKmz(self, outputDirectory, kmlData, base, prettyprint): if prettyprint: # etree does not support prettyprint. Do it ourselves content=self._prettyPrint(kmlData.etree_element()) else: content=kmlData.to_string().encode('utf-8') kmlFileName=base+".kml" with open(os.path.join(outputDirectory,kmlFileName),"wb") as f: f.write(content) kmzFileName=base+".kmz" with zipfile.ZipFile(os.path.join(outputDirectory,kmzFileName), 'w', zipfile.ZIP_DEFLATED) as kmz: kmz.writestr("content.kml", content) def _nameField(layerName): # FIXME add some logic return "ID" def _dataElementsFromAttributes(self, fieldNames, attributes, removeNullValues=False): data=zip(fieldNames,attributes) if removeNullValues: data=filter(lambda x:x[1] <> None, data) return map(lambda x:(x[0], self._toKmlValue(x[1])),data) def _toKmlValue(self, value): if isinstance(value, str) or isinstance(value, unicode): return value else: return str(value) def _toId(self, name): return re.sub(r'[^a-zA-Z_0-9\-]','_',name) def _prettyPrint(self, elem): self._indent(elem) return ElementTree.tostring(elem,"utf-8") def _indent(self,elem, level=0): i = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: self._indent(elem, level+1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = i
Il faut installer les librairies Python fastkml et pygeoif.
Quand projectToKml est appelée (par exemple depuis un plugin QGIS), les couches du projet QGIS sont parcourues et une arborescence KML correspondante est créée avec les objets de chaque couche. Finalement un KML et un KMZ sont exportés. Une limitation du code ci-dessus est que le style de la couche n'est pas exporté (juste les données) donc si c'est important pour toi c'est qqch de plus à modifier.
Pour ton besoin, une fois que tu as un Placemark, tu peux utiliser placemark.begin et placemark.end pour setter le TimeSpan.
Dernière modification par gvellut (Fri 06 March 2015 11:52)
Hors ligne
#5 Fri 06 March 2015 11:41
- simeric
- Participant assidu
- Date d'inscription: 10 Mar 2009
- Messages: 255
Re: QGIS : Export KML avec information temporelle "TimeSpan"
merci !
Hors ligne