Suite

Krigeage à partir d'un raster avec des données manquantes dans ArcGIS

Krigeage à partir d'un raster avec des données manquantes dans ArcGIS


J'ai des images satellite MODIS qui représentent une gamme de températures de surface. Cependant, de nombreuses cellules contiennent des valeurs manquantes. Je pense que je dois effectuer un krigeage afin d'obtenir une valeur moyenne pour les cellules vides en fonction des valeurs des cellules environnantes. Je ne sais pas comment procéder car je travaille avec des données raster.


Si vous voulez la valeur moyenne, vous pouvez utiliser un filtre moyen (statistiques focales, en ignorant la valeur NoData). Ce sera beaucoup plus rapide que le krigeage, et cela fonctionnera directement à partir d'un raster.

Ensuite, vous utilisez la calculatrice raster pour remplacer les valeurs nodata par les valeurs moyennes :

Con(Isnull("input_raster"), "smoothed_raster", "input_raster")

À titre de remarque, ArcGIS n'a pas de krigeage à partir d'un raster, vous devrez donc faire "raster to point first"


Manipulation des données raster¶

Dans ce chapitre, les aspects généraux de la conception du paquetage raster sont discutés, notamment la structure des classes principales et ce qu'elles représentent. L'utilisation du package est illustrée dans les sections suivantes. raster a un grand nombre de fonctions, toutes ne sont pas abordées ici, et celles qui sont discutées ne sont mentionnées que brièvement. Voir les fichiers d'aide du package pour plus d'informations sur les fonctions individuelles et help("raster-package") pour un index des fonctions par sujet.


Transcription de la présentation

Stockage de données et édition d'amplis Instructeur GEOG370 : Christine Erlien

Aperçu • Stockage des bases de données SIG – tuilage • Types d'erreurs pouvant survenir • Erreurs d'entité • Erreurs d'attribut • Projection et erreur • Correspondance des contours • Conflation

Sous-système de stockage de données et d'édition d'amplis • Importance • Outils pour stocker et maintenir les données • Outils pour effectuer l'AQ/CQ sur les données  identifier les erreurs • Besoin d'être conscient des erreurs possibles pour savoir quoi rechercher dans les bases de données avec lesquelles vous travaillez

Sous-système de stockage de données et d'édition d'amplis • Types d'erreurs : • Erreur d'entité : Erreur de position • Erreur d'attribut : Attribution incorrecte • Erreur d'accord entité-attribut : Codes associés à des entités erronées

Stockage de données et édition d'amplis • Avant de commencer une analyse spatiale ou un projet de cartographie  vérifier les données • La détection et la correction des erreurs peuvent inclure : • Comparer les données avec le document d'entrée • Vérifier la topologie des objets spatiaux • Vérifier les attributs des objets spatiaux • Vérifier les objets spatiaux manquants

Stockage de base de données SIG Raster • Données • Valeurs d'attribut pour les cellules de la grille • Tables associées • Édition • Concerne la vérification des positions correctes des cellules de la grille • Examiner la position des colonnes et des lignes, le code d'attribut

Stockage de base de données SIG Vecteur • Données • Tables individuelles au sein d'une même base de données • Différentes bases de données, liées par des pointeurs • Édition • Entités • Objets manquants, objets mal placés, liens incomplets • Attributs • Typos, codes incorrects, attributs incorrectement associés à un champ • Entités et attributs ensemble • Codes associés à des entités incorrectes

Stockage de données vectorielles et édition d'amplis Mosaïque—stockage de la base de données en sous-sections • Réduit la surcharge de calcul, accélère l'analyse en diminuant le volume de données • Meilleur contrôle du processus d'édition From Fundamentals of Geographic Information Systems, Demers (2005)

L'importance d'éditer la base de données SIG • Sources d'erreur : • Matériel (numérisation, numérisation) • Personnes • Numérisation • Entrées d'attributs

Détection des erreurs d'édition & : Vector Identifier les erreurs d'entité • Construire la topologie • Consulter les statistiques de la base de données Vérifiez que : • Toutes les entités qui auraient dû être saisies sont présentes • Aucune entité supplémentaire n'a été numérisée • Les entités sont au bon endroit et de forme/taille correctes • La topologie est correcte • Polygones n'ont qu'un seul point d'étiquette • Les entités sont à l'intérieur de la limite du repère

Erreurs d'entité : vecteur Pseudo nœuds : Faux nœuds où une ligne se connecte à elle-même ou où deux lignes se croisent le long d'un chemin parallèle plutôt que de se croiser. De Fondamentaux des Systèmes d'Information Géographique, Demers (2005)

Erreurs d'entité : vecteur • Nœud suspendu (pendant) : nœud connecté à une seule entité linéaire (n'indique pas d'intersection) • Produit par : • Échec de fermeture d'un polygone • Échec de connexion du nœud à l'objet approprié (sous-dépassement) • Dépassement de l'entité le nœud doit être connecté (dépassement)

Erreurs d'entité : vecteur Undershoot Overshoot From Fundamentals of Geographic Information Systems, Demers (2005)

Erreurs d'entité : vecteur Numérisation de polygones • Le polygone nécessite un point à l'intérieur qui servira de localisateur pour une étiquette • Erreurs possibles : • Étiquettes manquantes • Trop d'étiquettes • Généralement causée par l'échec du suivi du processus de numérisation

Erreurs d'entité : vecteur De Fondamentaux des Systèmes d'Information Géographique, Demers (2005)

Erreurs d'entité : vecteur • Polygones rubans : petits polygones produits en numérisant des lignes adjacentes entre les polygones > une fois • Se produisent lorsque le logiciel de numérisation utilise un modèle vectoriel qui traite chaque polygone comme une entité distincte • Ce type de logiciel devient moins courant • Correctif : comparez le nombre de polygones de la carte d'entrée à la couverture numérique zoomer sur les zones suspectes http://www.ncgia.ucsb.edu/cctp/units/unit28/28.html

Erreurs d'entité : vecteur • Polygones étranges : polygones avec des nœuds manquants • Cause : point numérisé au mauvais endroit ou dans le mauvais ordre • Prévention : méthode de préparation ou de numérisation de la carte • Correction : Déplacement des lignes vers les emplacements corrects http://www-users.aston.ac.uk/

Erreurs d'attribut d'entité et d'amp : vecteur • Après avoir apporté des modifications : • Reconstruire la topologie • Les modifications ont modifié certaines relations spatiales  la topologie doit être mise à jour • Enregistrer !! • Attributs incorrects • Prévention : Gardez une trace des attributs lors de la saisie • Correctif : Corrigez-les ! Sauver!

Erreurs d'attribut : raster Raster : • Attributs manquants : ligne ou colonne entière (ou partie de) manquante • Attributs incorrects ou mal placés • Erreurs d'attributs se produisant le long des marges de zone les cellules peuvent être réaffectées au polygone voisin

Gérer les changements de projection • Conversion de coordonnées en tant qu'édition • Cartésien (numériseur)  monde réel • Projection produite à l'aide de transformations : • Échelle • Rotation • Traduction • Quelques erreurs : processus mathématique de projection et d'arrondi par ordinateur • Regardez la mesure d'erreur du logiciel  si elle est élevée, il peut avoir des problèmes avec la numérisation

Correspondance des bords Vecteur • Lier des cartes adjacentes (généralement le même thème) pour permettre l'analyse d'une zone d'étude plus vaste • Difficultés potentielles : • Même projection, mais numérisée séparément  discordances • Projection différente ou même projection, datum différent être relié

Correspondance des bords Raster • Produits de télédétection • Scènes horizontalement adjacentes collectées à différents moments  les coordonnées latitudinales peuvent différer légèrement • Inclinaison entre les images • Corrigable en déplaçant la grille jusqu'à ce qu'elle corresponde

Feuilles de caoutchouc Conflation & • Conflation : processus d'intégration de données cartographiques provenant de plusieurs sources • Nécessite généralement une feuille de caoutchouc • Feuille de caoutchouc/déformation • Dans une carte de référence, les entités pour lesquelles les coordonnées connues sont identifiées (points de contrôle) • Objectif : couches supplémentaires conçues pour se conformer à la couche de référence à l'aide points de contrôle

Conclusion : vous devez savoir • Qu'est-ce que la mosaïque et son objectif • 3 types d'erreur de base et comment les modifier • entité, attribut, attribut d'entité • Types d'erreur d'entité • Toutes les entités qui auraient dû être saisies sont présentes • Aucune entité supplémentaire n'a été numérisée • Entités sont au bon endroit et de forme/taille correctes • La topologie est correcte • Les polygones n'ont qu'un seul point d'étiquette • Les entités se trouvent dans la limite des graduations

Conclusion : vous devez savoir • Types d'erreur d'attribut vectoriel raster et amp • Comment ils se produisent • Comment détecté et corrigé • Comment la projection introduit une erreur • Le but de la correspondance des bords • Le but et le processus de la correspondance des bords


Syntaxe

Raster en entrée à reclasser.

Table contenant les champs définissant les plages de valeurs à reclasser et les valeurs qu'elles deviendront.

Champ contenant la valeur de début pour chaque plage de valeurs à reclasser.

Il s'agit d'un champ numérique de la table de remappage d'entrée.

Champ contenant la valeur de fin pour chaque plage de valeurs à reclasser.

Il s'agit d'un champ numérique de la table de remappage d'entrée.

Champ contenant les valeurs entières auxquelles chaque plage doit être modifiée.

Il s'agit d'un champ entier de la table de remappage d'entrée.

Le raster reclassé en sortie.

La sortie sera toujours de type entier.

Indique si les valeurs manquantes dans la table de reclassement conservent leur valeur ou sont mappées à NoData.


Abstrait

Les vagues de chaleur ont été les événements météorologiques extrêmes les plus meurtriers en Europe au cours des dernières décennies. Les personnes vivant dans les villes sont particulièrement sujettes à de tels événements en raison de l'effet d'îlot de chaleur urbain (ICU) qui augmente le stress thermique en milieu urbain, en particulier lors de situations synoptiques calmes, stables et à forte intensité de rayonnement. Étant donné que les stations de mesure officielles dans les villes sont rares, les études sur les modèles spatiaux des UHI reposent souvent sur des données satellitaires, des données de météorologues amateurs ou sur des sorties de modèles. De plus, les analyses des modèles spatiaux UHI à l'aide de mesures basées sur des points nécessitent des méthodes adéquates et rentables pour l'interpolation spatiale. Dans cette étude, les données de température de l'air récupérées par 60 appareils de mesure (LCD) à faible coût sont utilisées pour modéliser le modèle spatial de l'UHI avec une approche de régression de l'utilisation des terres (LUR) à Berne, en Suisse. À cette fin, 14 variables spatiales avec différents rayons tampons ont été calculées pour évaluer leur effet sur l'UHI et pour interpoler les données de température de l'air. Ainsi, trois modèles couvrant trois vagues de chaleur différentes la nuit ont été développés. Compte tenu des bonnes performances du modèle dans les différents scénarios, l'étude présentée ici démontre l'interpolation réussie des données de température à faible coût par la modélisation LUR basée sur des informations spatiales accessibles au public au sein d'une ville.


Krigeage à partir d'un raster avec des données manquantes dans ArcGIS - Systèmes d'information géographique

1Temp aster2 = ( 1.1000000000000001) Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyfloat/metadata.xml ==================== ================================================ -- - /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyfloat/metadata.xml (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyfloat/metadata.xml (révision 40) @@ -0,0 +1,3 @@ + + --> + 20070223 12513400 VRAI

CreateConstantRaster C:MGETMGETTrunkPythonPackagesrcGeoEcoArcGISToolboxRastersdummyfloat 1.1 FLOAT 1 "0 0 1 1"

Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyint/log ============================== ===================================== --- /MGET/Trunk/PythonPackage/src/GeoEco /ArcGISToolbox/Rasters/dummyint/log (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyint/log (révision 40) @@ -0,0 +1,1 @@ + 200702231250 0 0 0Jason C:DOCUME

1Temp aster2 = ( 1) Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyint/metadata.xml ==================== ================================================ -- - /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyint/metadata.xml (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/dummyint/metadata.xml (révision 40) @@ -0,0 +1,3 @@ + + --> + <66F2CFDE-F502-47B0-A12B-6F69828D66B4>20070223 12510000 VRAI

CreateConstantRaster C:MGETMGETTrunkPythonPackagesrcGeoEcoArcGISToolboxRastersdummyint 1 ENTIER 1 "0 0 1 1"

Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0000.dat ============================= ======================================= --- /MGET/Trunk/PythonPackage/src /GeoEco/ArcGISToolbox/Rasters/info/arc0000.dat (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0000.dat (révision 40) @@ -0,0 + 1,1 @@ +../dummyint/dblbnd.adf Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0001.dat =============== ================================================== === --- /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0001.dat (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/ arc0001.dat (révision 40) @@ -0,0 +1,1 @@ +../dummyint/sta.adf Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0002.dat ================================================== ================= --- /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0002.dat (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0002.dat (révision 40) @@ -0,0 +1,1 @@ +../dummyint/vat.adf Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0003.dat ============================== ===================================== --- /MGET/Trunk/PythonPackage/src/GeoEco /ArcGISToolbox/Rasters/info/arc0003.dat (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0003.dat (révision 40) @@ -0,0 +1, 1 @@ +../dummyfloat/dblbnd.adf Index : /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0004.dat ================= ================================================== = --- /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0004.dat (révision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/ArcGISToolbox/Rasters/info/arc0004. dat (révision 40) @@ -0,0 +1,1 @@ +../dummyfloat/sta.adf Index : /MGET/Trunk/PythonPackage/src/GeoEco/COM.py ========= ================================================== = ======== --- /MGET/Trunk/PythonPackage/src/GeoEco/COM.py (révision 39) +++ /MGET/Trunk/PythonPackage/src/GeoEco/COM.py (révision 40) @@ -16,4 +16,5 @@ import winerror + de GeoEco.DynamicDocString import DynamicDocString de GeoEco.Internationalization import _ de GeoEco.Metadata import * @@ -135,5 +136,5 @@ # list, convertit le argument à une liste. - if len(args) == 1 et isinstance(args[0], types.TupleType) et isinstance(memberMetadata.Type, PythonList): + si len(args) == 1 et isinstance(args[0], types. TupleType) et isinstance(memberMetadata.Type, ListTypeMetadata): args = (self._TuplesToLists(args[0], memberMetadata.Type),) argsChanged = True @@ -168,5 +169,5 @@ for i in range( len(memberMetadata.Arguments) - 1) : - si i 0 : + raster = None + tandis que raster est None ou os.path.exists(raster) : + raster = os.path.join(directory, "tmp%08X" % random.randint(0, sys.maxint)) + + # Si la création d'un raster d'entiers ne fait pas planter Arc, faites-le. + # Sinon, créez un raster à virgule flottante. + + si entréesNeeded != 4: + gp.CopyRaster_Management(os.path.join(os.path.dirname(sys.modules[u'GeoEco.ArcGIS'].__file__), u'ArcGISToolbox', u'Rasters', u'dummyint'), raster) + entryNeeded -= 3 + else : + gp.CopyRaster_Management(os.path.join(os.path.dirname(sys.modules[u'GeoEco.ArcGIS'].__file__), u' ArcGISToolbox', u'Rasters', u'dummyfloat'), raster) + elementsNeeded -= 2 + + rastersCreated.append(raster) + + Logger.Debug(_(u'%i rasters temporaires créés.') % len( rastersCreated)) + + # Renvoie la liste des rasters que nous avons créés. + + return rastersCreated + + @classmethod + def Delete(cls, raster): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + gp = GeoprocessorManager.GetWrappedGeoprocessor() + exist = gp.Exists(raster) + sinon existe : + return + d = gp.Describe(raster) + si d n'est pas None et d.DataType.lower() == u'rasterdataset': + gp.Delete_Management(raster) + else : + Logger.RaiseException(ValueError (_(u'Le chemin %s existe mais ArcGIS signale qu'il ne s'agit pas d'un raster.') % raster)) + sauf : + Logger.LogExceptionAsError(_(u'Could not delete raster %s') % raster) + raise + + @classmethod + def DeleteTemporaryRastersThatPreventedArcGISCrash(cls, rasters): + cls.__doc__.Obj.ValidateMethodInvocation() + pour raster dans les rasters: + cls.Delete(raster) + + @classmethod + def Move(cls, sourceRaster, destinationRaster , overwriteExisting=False): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + cls.Copy(sourceRaster, destinationRaster, overwriteExisting=overwriteExisting) + cls.Delete(sourceRaster) + sauf : + Logger.LogExceptionAsError(_(u'Impossible de déplacer le raster %(source)s vers %(dest)s') % ) + raise + + @classmethod + def MoveToDirectory(cls, sourceRaster, destinationDirectory, overwriteExisting=False): + cls.__doc__.Obj.ValidateMethodInvocation() + destinationRaster = os.path.join(destinationDirectory, os.path.basename(sourceRaster )) + cls.Move(sourceRaster=sourceRaster, destinationRaster=destinationRaster, overwriteExisting=overwriteExisting) + return destinationRaster + +## @classmethod +## def ProjectClipMaskAndOrMapAlgebra(cls, sourceRaster, destinationRaster, overwriteExisting=False): +## cls. __doc__.Obj.ValidateMethodInvocation() +## essayer : +## cls.Copy(sourceRaster, destinationRaster, overwriteExisting=overwriteExisting) +## cls.Delete(sourceRaster) +## sauf : +## Logger.LogExceptionAsError(_( u'Impossible de déplacer le raster %(source)s vers %(dest)s') % ) +## augmenter + + +########################################## #################################### +# Métadonnées : module +######## ##################################################### ###################### + +de l'import GeoEco.Metadata * +de l'import GeoEco.Types * + +AddModuleMetadata(shortDescription=_(u'Fournit des méthodes pour effectuer des opérations de gestion de données communes sur des rasters ArcGIS.')) + +#################################### ############################################ +# Métadonnées : classe ArcGISRaster + ##################################################### ############################## + +AddClassMetadata(ArcGISRaster, + shortDescription=_(u'Fournit des méthodes pour effectuer des opérations de gestion de données courantes sur les rasters ArcGIS.'), + longDescription=_( +u"""Cette classe offre un avantage significatif par rapport aux +outils de géotraitement ArcGIS pour la gestion des rasters : elle peut contourner un bogue dans ArcGIS qui la fait + planter lorsqu'un grand nombre de rasters sont stockés dans un seul répertoire."""), + isExposed AsCOMServer=True, + comIID=u'<82BD49EF-6F06-4AC0-8E91-4E6B2FB84EB1>', + comCLSID=u'<22C205A0-BE4C-4ECA-AF7C-BE496196C75F>') + +# Méthode publique : ArcGISRaster.Copy + +AddMethodMetadata(ArcGISRaster.Copy, + shortDescription=_(u'Copie un raster ArcGIS. Ne fait pas planter ArcGIS lorsque plusieurs rasters sont stockés dans un seul répertoire.'), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Copy Raster'), + arcGISToolCategory=_(u'Data Management ArcGIS Rasters'), + dependencies=[ArcGISDependency(9, 1)]) + +AddArgumentMetadata(ArcGISRaster.Copy, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster), + description=_(u'%s class ou une instance de celui-ci.') % ArcGISRaster.__name__) + +AddArgumentMetadata(ArcGISRaster.Copy, u'sourceRaster', + typeMetadata=ArcGISRasterTypeMetadata(mustExist=True), + description=_(u'Raster à copier.'), + arcGISDisplayName=_(u'Source raster')) + +AddArgumentMetadata(ArcGISRaster.Copy, u'destinationRaster', + typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArgument=u'sourceRaster', deleteIfParameterIsTrue +u=overwriteExisting), description=_( +u"""Copier pour créer. + +S'il s'agit d'un chemin de système de fichiers, les répertoires manquants dans le chemin seront créés ed +s'ils n'existent pas."""), + direction=u'Output', + arcGISDisplayName=_(u'Destination raster')) + +AddArgumentMetadata(ArcGISRaster.Copy, u'overwriteExisting', + typeMetadata=BooleanTypeMetadata (), + description=_( +u"""Si True, le raster de destination sera écrasé, s'il existe. + +Si False, une ValueError sera levée si le raster de destination existe. + +Si la classe GeoEco GeoprocessorManager contient une instance du +géoprocesseur ArcGIS, ce paramètre est ignoré et la propriété OverwriteOutput +du géoprocesseur détermine si les rasters de destination seront écrasés. Cela se produit +généralement si cette méthode est appelée à partir d'un script ou d'un +modèle de géotraitement ArcGIS. Vous pouvez toujours contrôler le comportement d'écrasement en définissant cette propriété du +géoprocesseur sur la valeur souhaitée, soit par programme, soit à partir de l'onglet +Géotraitement de la boîte de dialogue Options sous le menu Outils dans ArcCatalog."""), + overriddenByArcGISGeoprocessorVariable=u'OverwriteOutput' ) + +# Méthode publique : ArcGISRaster.CopyToDirectory + +AddMethodMetadata(ArcGISRaster.CopyToDirectory, + shortDescription=_(u'Copie un raster ArcGIS dans un répertoire. Ne plante pas ArcGIS lorsque de nombreux rasters sont stockés dans le répertoire.'), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Copy Raster To Directory'), + arcGISToolCategory=_(u'Data ManagementArcGIS Rasters'), + dependencies=[ArcGISDependency(9, 1)] ) + +AddArgumentMetadata(ArcGISRaster.CopyToDirectory, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster), + description=ArcGISRaster.Copy.__doc__.Obj.Arguments[0].Description) + +AddArgumentMetadata(ArcGISRaster.Copy.__doc__.Obj.Arguments[0].Description) + +AddArgumentMetadata(ArcGISRaster.Copy u'sourceRaster', + t ypeMetadata=ArcGISRasterTypeMetadata(mustExist=True), + description=ArcGISRaster.Copy.__doc__.Obj.Arguments[1].Description, + arcGISDisplayName=ArcGISRaster.Copy.__doc__.Obj.Arguments[1].ArcGISDisplayName) + +AddArgumentMetadata(ArcGISRaster .CopyToDirectory, u'destinationDirectory', + typeMetadata=DirectoryTypeMetadata(), + description=_( +u"""Répertoire pour recevoir le raster. + +Le répertoire sera créé s'il n'existe pas déjà."""), + arcGISDisplayName=_(u'Répertoire de destination')) + +AddArgumentMetadata(ArcGISRaster.CopyToDirectory, u'overwriteExisting', + typeMetadata=BooleanTypeMetadata() , + description=ArcGISRaster.Copy.__doc__.Obj.Arguments[3].Description, + overriddenByArcGISGeoprocessorVariable=u'OverwriteOutput') + +AddResultMetadata(ArcGISRaster.CopyToDirectory, u'destinationRaster', + typeMetadataType=ArcGISRaster) _(u"""Chemin vers le raster nouvellement créé."""), + arcGISDisplayName=_(u'Raster de destination')) + +# Méthode publique : ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash + +AddMethodMetadata(ArcGISRaster.CreateTemporaryRastersTo,+PreventArcGISDescription short =_(u'Crée suffisamment de rasters ArcGIS temporaires dans un répertoire pour empêcher ArcGIS de se bloquer lorsqu'un nombre spécifié de rasters est ajouté au répertoire.'), + longDescription=_( +u"""Un bogue dans ArcGIS 9.x le fait planter si plusieurs centaines de rast ers sont ajoutés +à un répertoire. Le fait que le plantage se produise dépend du nombre et des types de données +des rasters. Voir http://forums.esri.com/Thread.asp?c=93&f=1729&t=196716&mc=0 pour +une description complète du problème. Au moment de la rédaction de cette documentation, le problème était toujours présent dans ArcGIS 9.1 SP2 et 9.2 SP1. + +Cette fonction est conçue pour contourner le problème. Vous appelez cette fonction +avant d'ajouter des rasters à un répertoire et spécifiez le nombre de rasters + que vous allez ajouter. Cette fonction analyse le contenu actuel du répertoire +. S'il existe une possibilité que l'ajout de vos rasters touche la combinaison + nécessaire pour provoquer le plantage, cette fonction crée suffisamment de +rasters temporaires pour éviter le problème. + +Si cette fonction crée des rasters temporaires, elle vous renvoie une liste de +chemins complets. Vous devez les supprimer après avoir ajouté vos propres rasters. La fonction +DeleteTemporaryRastersThatPreventedArcGISCrash est fournie à cette +fin. +"""), + isExposedByCOM=True, + dependencies=[ArcGISDependency(9, 1)]) + +AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGIS_Raster), + description=ArcGIS_Raster (u'%s classe ou une instance de celle-ci.') % ArcGISRaster.__name__) + +AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'directory', + typeMetadata=DirectoryTypeMetadata(), + description=_( +u"""Répertoire dans lequel les rasters temporaires doivent être créés, en prévision de +rasters supplémentaires ajoutés par l'appelant après le retour de cette méthode.""")) + +AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'rastersToAdd', + typeMetadata=IntegerTypeMetadata(minValue=1 , maxValue=511), + description=_( +u"""Nombre de rasters que l'appelant ajoutera au répertoire après le retour de cette +méthode.""")) + +AddResultMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'temporaryRasters' , + typeMetadata=L istTypeMetadata(elementType=ArcGISRasterTypeMetadata()), + description=_(u"""Liste des rasters temporaires qui ont été créés.""")) + +# Méthode publique : ArcGISRaster.Delete + +AddMethodMetadata(ArcGISRaster.Delete, + shortDescription =_(u'Supprime un raster ArcGIS.'), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Delete Raster'), + arcGISToolCategory=_(u'Data ManagementArcGIS Rasters') , + dependencies=[ArcGISDependency(9, 1)]) + +AddArgumentMetadata(ArcGISRaster.Delete, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster), + description=_(u'%s classe ou une instance de it.') % ArcGISRaster.__name__) + +AddArgumentMetadata(ArcGISRaster.Delete, u'raster', + typeMetadata=ArcGISRasterTypeMetadata(), + description=_(u"""Raster à supprimer."""), + arcGISDisplayName= _(u'Raster')) + +# Méthode publique : ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash + +AddMethodMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash, + shortDescr iption=_(u'Supprime les rasters ArcGIS temporaires créés par la fonction CreateTemporaryRastersToPreventArcGISCrash.'), + isExposedByCOM=True, + dependencies=[ArcGISDependency(9, 1)]) + +AddArgumentMetadata(ArcGISRaster.DeleteTemporaryRastersThat,Preventedu'GISclCrash, + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster), + description=_(u'%s class ou une instance de celle-ci.') % ArcGISRaster.__name__) + +AddArgumentMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISMeta, u'rasters'=, + typeMetadata (elementType=ArcGISRasterTypeMetadata()), + description=_( +u"""Liste des rasters temporaires à supprimer, renvoyée par la fonction +CreateTemporaryRastersToPreventArcGISCrash.""")) + +# Méthode publique : ArcGISRaster.Move + +AddMethodMetadata( ArcGISRaster.Move, + shortDescription=_(u'Déplace un raster ArcGIS. Ne fait pas planter ArcGIS lorsque de nombreux rasters sont stockés dans un seul répertoire.'), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Move Raster'), + arcGISToolCategory=_(u'Data Management ArcGIS Rasters')) + +AddArgumentMetadata(ArcGISRaster.Move, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster), + description=ArcGISRaster.Copy.__doc__.Obj.Arguments[0].Description) + +AddArgumentMetadata( ArcGISRaster.Move, u'sourceRaster', + typeMetadata=ArcGISRasterTypeMetadata(mustExist=True), + description=_(u'Raster to move.'), + arcGISDisplayName=_(u'Source raster')) + +AddArgumentMetadata(ArcGISRaster .Move, u'destinationRaster', + typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArgument=u'sourceRaster', deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True), + description=_( +u"""Nouveau chemin pour le raster. + + S'il s'agit d'un chemin de système de fichiers, les répertoires manquants dans le chemin seront créés +s'ils n'existent pas."""), + direc tion=u'Output', + arcGISDisplayName=_(u'Destination Raster')) + +AddArgumentMetadata(ArcGISRaster.Move, u'overwriteExisting', + typeMetadata=BooleanTypeMetadata(), + description=ArcGISRaster.Copy.__doc__.Obj. Arguments[3].Description, + overriddenByArcGISGeoprocessorVariable=u'OverwriteOutput') + +# Méthode publique : ArcGISRaster.MoveToDirectory + +AddMethodMetadata(ArcGISRaster.MoveToDirectory, + shortDescription=_(u'Déplace un raster ArcGIS vers un répertoire. Ne plante pas ArcGIS lorsque de nombreux rasters sont stockés dans le répertoire.'), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Move Raster To Directory'), + arcGISToolCategory=_(u'Data Management ArcGIS Rasters')) + +AddArgumentMetadata(ArcGISRaster.MoveToDirectory, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster), + description=ArcGISRaster.Move.__doc__.Obj.Arguments[0].Description) + +AddArgumentMetadata (ArcGISRaster.MoveToDirectory, u'sourceRaster', + typeMetadata=ArcGISRasterTypeMetadata(mustExist=True), + description=ArcGISRaster.Move.__doc__.Obj.Arguments[1].Description, + arcGISDisplayName=ArcGISRaster.Move.__doc__.Obj.Arguments [1].ArcGISDisplayName) + +AddArgumentMetadata(ArcGISRaster.MoveToDirectory, u'destinationDirectory', + typeMetadata=DirectoryTypeMetadata(), + description=_( +u"""Répertoire pour recevoir le raster. + +Les répertoires manquants dans ce chemin être créés s'ils n'existent pas."""), + arcGISDisplayName=_(u'Destinatio n directory')) + +AddArgumentMetadata(ArcGISRaster.MoveToDirectory, u'overwriteExisting', + typeMetadata=BooleanTypeMetadata(), + description=ArcGISRaster.Move.__doc__.Obj.Arguments[3].Description, + overriddenByArcGISGeoprocessorOverwrite='u' ) + +AddResultMetadata(ArcGISRaster.MoveToDirectory, u'destinationRaster', + typeMetadata=ArcGISRasterTypeMetadata(), + description=_(u"""Chemin vers le raster de destination."""), + arcGISDisplayName=_(u'Raster de destination ')) + + +############################################ #################################### +# Noms exportés par ce module +######## ##################################################### ###################### + +__all__ = ['ArcGISRaster'] Index : /MGET/Trunk/PythonPackage/src/GeoEco/DataManagement/BinaryRasterUtils.cpp = ================================================== ================ --- /MGET/Trunk/PythonPackage/src/GeoEco/DataManagement/BinaryRasterUtils.cpp (révision 40) +++ /MGET/Trunk/PythonPackage/src /GeoEco/DataManagem ent/BinaryRasterUtils.cpp (révision 40) @@ -0,0 +1,491 @@ +#include "python.h" + +#include +#include + +enum DataType < Int8_DataType, Uint8_DataType, Int16_DataType, Uint16_DataType, Int32_DataType, Uint32_DataType , Float_DataType, Double_DataType > +const size_t DataTypeSizes[] = < 1, 1, 2, 2, 4, 4, 4, 8 > +const size_t BufferSize = 256*1024 + +static PyObject *SwapBytes(PyObject *self, PyObject * args) + < + // Récupère et valide les arguments d'entrée. + // + // Cette fonction n'effectue qu'une validation limitée des arguments d'entrée. + // L'appelant Python est responsable de la plupart des validations. + + char *pszInputFile = NULL + char *pszOutputFile = NULL + char *pszDataType = NULL + + if (!PyArg_ParseTuple(args, "sss", &pszInputFile, &pszOutputFile, &pszDataType) || + pszInputFile == NULL || pszOutputFile, &pszOutputFile, &pszDataType) || + pszInputFile == NULL || pszOutputFile NULL || pszDataType == NULL) + < + PyErr_SetString(PyExc_TypeError, "Arguments invalides.") + return NULL + >+ + DataType iDataType = Int8_DataType + + if (strcmp(pszDataType, "int8") == 0) + iDataType = Int8_DataType + else if (strcmp(pszDataType, "uint8") == 0) + iDataType = Uint8_DataType + else if (strcmp(pszDataType, "int16") == 0) + iDataType = Int16_DataType + else if (strcmp(pszDataType, "uint16") == 0) + iDataType = Uint16_DataType + else if (strcmp(pszDataType, "int32") == 0) + iDataType = Int32_DataType + else if (strcmp(pszDataType, "uint32") == 0) + iDataType = Uint32_DataType + else if (strcmp(pszDataType, "float") == 0) + iDataType = Float_DataType + else if (strcmp(pszDataType, "double") == 0) + iDataType = Double_DataType + else + < + PyErr_SetString(PyExc_Va lueError, "Invalid cell data type argument. The valid cell data types are "int8", "uint8", "int16", "uint16", "int32", "uint32", "float" and "double".") + return NULL + >+ + size_t iDataTypeSize = DataTypeSizes[iDataType] + + // Open the input file for reading. + + FILE *hInputFile = fopen(pszInputFile, "rbS") // read, binary, optimize for sequential-scan (Windows-specific flag) + if (hInputFile == NULL) + < + PyErr_SetFromErrnoWithFilename(PyExc_IOError, pszInputFile) + return NULL + >+ + // Open the output file for writing. + + FILE *hOutputFile = fopen(pszOutputFile, "wbS") // write, binary, optimize for sequential-scan (Windows-specific flag) + if (hOutputFile == NULL) + < + PyErr_SetFromErrnoWithFilename(PyExc_IOError, pszOutputFile) + fclose(hInputFile) + return NULL + >+ + // Read the input file and write the output file. + + char pBuffer[BufferSize] + size_t iBytesToRead = sizeof(pBuffer) + size_t iBytesRead = 0 + char cTemp = 0 + + while (!feof(hInputFile)) + < + // Read the input file into the buffer. + + iBytesRead = fread(pBuffer, 1, iBytesToRead, hInputFile) + + if (ferror(hInputFile)) + < + PyErr_SetFromErrnoWithFilename(PyExc_IOError, pszInputFile) + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ + if (iBytesRead % iDataTypeSize != 0) + < + PyErr_Format(PyExc_ValueError, "Input file %s is an improper size for the specified data type. Its size is not evenly divisible by the size of the data type.", pszInputFile) + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ + // Swap the bytes in the buffer. + + if (iDataTypeSize > 1) + for (size_t i = 0 i = iBytesRead) + < + iBytesRead = fread(pReadBuffer, 1, iBytesToRead, hInputFile) + + if (ferror(hInputFile)) + < + PyErr_SetFromErrnoWithFilename(PyExc_IOError, pszInputFile) + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ if (iBytesRead == 0) + < + PyErr_SetString(PyExc_EOFError, "Reached the end of the input file prematurely. It is too small for the specified number of rows, number of columns and cell data type.") + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ iReadIndex = 0 + > + + // If we exhausted the write buffer, write it to the asc + // file. + + if (iBytesToWrite >= sizeof(pWriteBuffer) - 1024) + < + fwrite(pWriteBuffer, 1, iBytesToWrite, hOutputFile) + + if (ferror(hOutputFile)) + < + PyErr_SetFromErrnoWithFilename(PyExc_IOEr ror, pszOutputFile) + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ + iBytesToWrite = 0 + > + + // Swap the bytes for this cell, if requested. + + if (bSwapBytes) + switch (iDataTypeSize) + < + case 2: + cTemp = pReadBuffer[iReadIndex] + pReadBuffer[iReadIndex] = pReadBuffer[iReadIndex + 1] + pReadBuffer[iReadIndex + 1] = cTemp + break + + case 4: + cTemp = pReadBuffer[iReadIndex] + pReadBuffer[iReadIndex] = pReadBuffer[iReadIndex + 3] + pReadBuffer[iReadIndex + 3] = cTemp + cTemp = pReadBuffer[iReadIndex + 1] + pReadBuffer[iReadIndex + 1] = pReadBuffer[iReadIndex + 2] + pReadBuffer[iReadIndex + 2] = cTemp + break + + case 8: + cTemp = pReadBuffer[iReadIndex] + pReadBuffer[iReadIndex] = pReadBuffer[iReadIndex + 7] + pReadBuffer[iReadIndex + 7] = cTemp + cTemp = pReadBuffer[iReadIndex + 1] + pReadBuffer[iReadIndex + 1] = pReadBuffer[iReadIndex + 6] + pReadBuffer[iReadIndex + 6] = cTemp + cTemp = pReadBuffer[iReadIndex + 2] + pReadBuffer[iReadIndex + 2] = pReadBuffer[iReadIndex + 5] + pReadBuffer[iReadIndex + 5] = cTemp + cTemp = pReadBuffer[iReadIndex + 3] + pReadBuffer[iReadIndex + 3] = pReadBuffer[iReadIndex + 4] + pReadBuff er[iReadIndex + 4] = cTemp + break + + default: + PyErr_SetString(PyExc_AssertionError, "Invalid data type size.") + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ + // Write this cell to the write buffer. + + if (col > 0) + < + pWriteBuffer[iBytesToWrite] = ' ' + iBytesToWrite++ + >+ + switch (iDataType) + < + case Int8_DataType: + iBytesToWrite += sprintf(pWriteBuffer + iBytesToWrite, "%i", (int) *((char *) (pReadBuffer + iReadIndex))) + iReadIndex++ + break + + case Uint8_DataType: + iBytesToWrite += sprintf(pWriteBuffer + iBytesToWrite, "%i", (int) *((unsigned char *) (pReadBuffer + iReadIndex))) + iReadIndex++ + break + + case Int16_DataType: + iBytesToWrite += sprintf(pWriteBuffer + iBytesToWrite, "%i", (int) *((short *) (pReadBuffer + iReadIndex))) + iReadIndex += 2 + break + + case Uint16_DataType: + iBytesToWrite += sprintf(pWriteBuffer + iBytesToWrite, "%i", (int) *((unsigned short *) (pReadBuffer + iReadIndex))) + iReadIndex += 2 + break + + case Int32_DataType: + iBytesToWrite += sprintf(pWriteBuffer + iBytesToWrite, "%i", *((int *) (pReadBuffer + iReadIndex))) + iReadIndex += 4 + break + + case Uint32_DataType: + iBytesToWrite += sprintf(pWriteBuffer + iBytesToWrite, "%u", * ((unsigned int *) (pReadBuffer + iReadIndex))) + iReadIndex += 4 + break + + case Float_DataType: + iBytesWritten = sprintf(pWriteBuffer + iBytesToWrite, "%.9g", (double) *((float *) (pReadBuffer + iReadIndex))) + if (strchr(pWriteBuffer + iBytesToWrite, 'N') || strchr(pWriteBuffer + iBytesToWrite, 'n')) + < + PyErr_Format(PyExc_ValueError, "The value at row %i, column %i of the input file is a floating point "infinity (INF)" or "not a number (NAN)" value. (Row 0, column 0 is the first cell in the file.) These values are not allowed in ArcInfo ASCII Grid format. Please remove these values from the input file and try again.", row, col) + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ iBytesToWrite += iBytesWritten + iReadIndex += 4 + break + + case Double_DataType: + iBytesWritten = sprintf(pWriteBuffer + iBytesToWrite, "%.17g", *((double *) (pReadBuffer + iReadIndex))) + if (strchr(pWriteBuffer + iBytesToWrite, 'N') || strchr(pWriteBuffer + iBytesToWrite, 'n')) + < + PyErr_Format(PyExc_ValueError, "The value at row %i, column %i of the input file is a floating point "infinity (INF)" or "not a number (NAN)" value. (Row 0, column 0 is the first cell in the file.) These values are not allowed in ArcInfo ASCII Grid format. Ple ase remove these values from the input file and try again.", row, col) + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ iBytesToWrite += iBytesWritten + iReadIndex += 8 + break + + default: + PyErr_SetString(PyExc_AssertionError, "Invalid data type size.") + fclose(hInputFile) + fclose(hOutputFile) + return NULL + > + > + + // We reached the end of a row. Write a newline. + + pWriteBuffer[iBytesToWrite] = ' ' + iBytesToWrite++ + > + + // If we exited the loop with some bytes still in the write buffer, + // write them to the output file. + + if (iBytesToWrite > 0) + < + fwrite(pWriteBuffer, 1, iBytesToWrite, hOutputFile) + + if (ferror(hOutputFile)) + < + PyErr_SetFromErrnoWithFilename(PyExc_IOError, pszOutputFile) + fclose(hInputFile) + fclose(hOutputFile) + return NULL + >+ > + + // Close the files and return successfully. + + fclose(hInputFile) + fclose(hOutputFile) + + Py_INCREF(Py_None) + return Py_None +> + +static PyMethodDef BinaryRasterUtilsMethods[] = +< + //<"convert_bin_to_asc", ConvertBinToAsc, 1, "Create an ArcInfo ASCII Grid (.ASC) file from a binary raster file.">, + //<"flip_bin_axes", FlipBinAxes, 1, "Create a copy of a binary raster file with flipped axes.">, + //<"convert_bin_data_type", ConvertBinDataType, 1, "Create a copy of an a binary raster file using a different data type.">, + <"SwapBytes", SwapBytes, METH_VARARGS, "Writes a copy of a binary raster with the byte order reversed.">, + <"ToArcInfoASCIIGrid", ToArcInfoASCIIGrid, METH_VARARGS, "Writes an ArcInfo ASCII Grid file for a binary raster.">, + +> + +PyMODINIT_FUNC initBinaryRasterUtils(void) + < + Py_InitModule("BinaryRasterUtils", BinaryRasterUtilsMethods) +>Index: /MGET/Trunk/PythonPackage/src/GeoEco/DataManagement/BinaryRasters.py =================================================================== --- /MGET/Trunk/PythonPackage/src/GeoEco/DataManagement/BinaryRasters.py (revision 40) +++ /MGET/Trunk/PythonPackage/src/GeoEco/DataManagement/BinaryRasters.py (revision 40) @@ -0,0 +1,639 @@ +import array +import operator +import os +import os.path + +from GeoEco.ArcGIS import GeoprocessorManager, ArcGISDependency +from GeoEco.DynamicDocString import DynamicDocString +from GeoEco.DataManagement.ArcGISRasters import ArcGISRaster +from GeoEco.DataManagement.Directories import TemporaryDirectory +from GeoEco.DataManagement.Files import File +from GeoEco.Internationalization import _ +from GeoEco.Logging import Logger + + +class BinaryRaster(object): + __doc__ = DynamicDocString() + + @classmethod + def SwapBytes(cls, inputFile, outputFile, dataTypeWidth, overwriteExisting=False): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + # Decompress the input file to a temporary directory. + + tempDir = TemporaryDirectory() + inputFileTemp = tempDir.DecompressInputArgument(u'inputFile') + + # Verify that the input file is a proper size. + + st = os.stat(inputFileTemp) + if operator.mod(st.st_size, dataTypeWidth) != 0: + Logger.RaiseException(ValueError(_(u'The size of the input file %(file)s, in bytes, must be evenly divisible by the data type width %(width)i.') % )) + + # Write the byte-swapped output file using a C++ function, which is + # 10x faster than any Python routine that I could write that only + # used the standard Python packages. + + outputFileTemp = os.path.join(tempDir.Path, u'swapped') + + if dataTypeWidth == 2: + dataType = 'int16' + elif dataTypeWidth == 4: + dataType = 'int32' + else: + dataType = 'double' + + Logger.Debug(_(u'Reading %(in)s, swapping bytes for %(width)i-byte values, and writing to %(out)s') % ) + import GeoEco.DataManagement.BinaryRasterUtils + GeoEco.DataManagement.BinaryRasterUtils.SwapBytes(str(inputFileTemp), str(outputFileTemp), str(dataType)) + + # Extract the output file from the temporary directory. + + File.Move(outputFileTemp, outputFile, overwriteExisting=overwriteExisting) + + except Exception, e: + Logger.LogExceptionAsError(_(u'Could not write a byte-swapped version of %(source)s to %(dest)s') % ) + raise + + @classmethod + def ToArcInfoASCIIGrid(cls, inputFile, outputFile, dataType, columnCount, rowCount, xLowerLeftCorner, yLowerLeftCorner, cellSize, nodataValue=None, swapBytes=False, overwriteExisting=False): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + # Decompress the input file to a temporary directory. + + tempDir = TemporaryDirectory() + inputFileTemp = tempDir.DecompressInputArgument(u'inputFile') + + # Verify that the input file is a proper size. + + if dataType == u'int8': + bytesPerCell = 1 + elif dataType == u'uint8': + bytesPerCell = 1 + elif dataType == u'int16': + bytesPerCell = 2 + elif dataType == u'uint16': + bytesPerCell = 2 + elif dataType == u'int32': + bytesPerCell = 4 + elif dataType == u'uint32': + bytesPerCell = 4 + elif dataType == u'float': + bytesPerCell = 4 + elif dataType == u'double': + bytesPerCell = 8 + else: + Logger.RaiseException(AssertionError(_(u'dataType %s is an unsupported value.') % dataType)) + + st = os.stat(inputFileTemp) + expectedSize = columnCount * rowCount * bytesPerCell + if st.st_size != expectedSize: + Logger.RaiseException(ValueError(_(u'The size of the input file %(file)s is inconsistent with the specified data type (%(type)s), number of columns (%(cols)i)), and number of rows (%(rows)i)). The file is expected to be %(expected)i bytes, but it is actually %(actual)i.') % )) + + # Write the output file using a C++ function, which is 10x faster + # than any Python routine that I could write that only uses the + # standard Python packages. + + outputFileTemp = os.path.join(tempDir.Path, u'output.asc') + + Logger.Debug(_(u'Converting %(in)s to ArcInfo ASCII Grid file %(out)s') % ) + import GeoEco.DataManagement.BinaryRasterUtils + if nodataValue is not None: + GeoEco.DataManagement.BinaryRasterUtils.ToArcInfoASCIIGrid(str(inputFileTemp), str(outputFileTemp), str(dataType), columnCount, rowCount, xLowerLeftCorner, yLowerLeftCorner, cellSize, int(bool(swapBytes)), 1, nodataValue) + else: + GeoEco.DataManagement.BinaryRasterUtils.ToArcInfoASCIIGrid(str(inputFileTemp), str(outputFileTemp), str(dataType), columnCount, rowCount, xLowerLeftCorner, yLowerLeftCorner, cellSize, int(bool(swapBytes))) + + # Extract the output file from the temporary directory. + + File.Move(outputFileTemp, outputFile, overwriteExisting=overwriteExisting) + + except Exception, e: + Logger.LogExceptionAsError(_(u'Could not convert %(source)s to ArcInfo ASCII Grid file %(dest)s') % ) + raise + + @classmethod + def ToArcGISRaster(cls, inputFile, outputRaster, dataType, columnCount, rowCount, xLowerLeftCorner, yLowerLeftCorner, cellSize, nodataValue=None, swapBytes=False, coordinateSystem=None, buildPyramids=False, overwriteExisting=False): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + # Convert the binary file to an ArcInfo ASCII Grid in a temporary + # directory. + + tempDir = TemporaryDirectory() + ascFileTemp = os.path.join(tempDir.Path, u'temp.asc') + cls.ToArcInfoASCIIGrid(inputFile, ascFileTemp, dataType=dataType, columnCount=columnCount, rowCount=rowCount, xLowerLeftCorner=xLowerLeftCorner, yLowerLeftCorner=yLowerLeftCorner, cellSize=cellSize, nodataValue=nodataValue, swapBytes=swapBytes) + + # Convert the ArcInfo ASCII Grid to a raster. + + outputRasterTemp = os.path.join(tempDir.Path, u'output') + if dataType == u'float' or dataType == u'double': + dataType2 = u'FLOAT' + else: + dataType2 = u'INTEGER' + gp = GeoprocessorManager.GetWrappedGeoprocessor() + gp.ASCIIToRaster_Conversion(ascFileTemp, outputRasterTemp, dataType2) + + # Define the projection and build the pyramids, if requested. + + if coordinateSystem is not None: + gp.DefineProjection_Management(outputRasterTemp, coordinateSystem) + + if buildPyramids: + gp.BuildPyramids_Management(outputRasterTemp) + + # Extract the output raster from the temporary directory. + + ArcGISRaster.Copy(outputRasterTemp, outputRaster, overwriteExisting=overwriteExisting) + + except Exception, e: + Logger.LogExceptionAsError(_(u'Could not convert %(source)s to raster %(dest)s') % ) + raise + + +############################################################################### +# Metadata: module +############################################################################### + +from GeoEco.Metadata import * +from GeoEco.Types import * + +AddModuleMetadata(shortDescription=_(u'Provides methods for manipulating binary raster files.'), + longDescription=_( +u"""A binary raster is a file that contains an raw array of numbers, with no +header, metadata, formatting markers and so on, as if a snapshot of the +in-memory data had been written directly to disk. In ArcGIS, this is the type +of file output by the Raster to Float tool, although that tool can only output +binary rasters that use a 32-bit floating point data type. The methods +provided by this module can use any standard numeric data type.""")) + +############################################################################### +# Metadata: BinaryRaster class +############################################################################### + +AddClassMetadata(BinaryRaster, + shortDescription=_(u'Provides methods for manipulating binary raster files.'), + longDescription=_( +u"""A binary raster is a file that contains an raw array of numbers, with no +header, metadata, formatting markers and so on, as if a snapshot of the +in-memory data had been written directly to disk. In ArcGIS, this is the type +of file output by the Raster to Float tool, although that tool can only output +binary rasters that use a 32-bit floating point data type. The methods +provided by this module can use any standard numeric data type."""), + isExposedAsCOMServer=True, + comIID=u'', + comCLSID=u'<0B619936-C4F4-496C-9E3F-03059EE13D1B>') + +# Public method: BinaryRaster.SwapBytes + +AddMethodMetadata(BinaryRaster.SwapBytes, + shortDescription=_(u'Reverses the byte order of the data in a binary raster (e.g. converts "little endian" to "big endian", or visa versa).'), + longDescription=_( +u"""This function is useful for converting binary raster data produced on +systems with different processor architectures. For example, you might use this +function to convert data produced by a Sun SPARC processor, which uses "big +endian" byte ordering, to the byte order needed by an Intel x86 processor, which +uses "little endian" byte ordering."""), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Swap Bytes'), + arcGISToolCategory=_(u'Data ManagementBinary Rasters')) + +AddArgumentMetadata(BinaryRaster.SwapBytes, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=BinaryRaster), + description=_(u'%s class or an instance of it.') % BinaryRaster.__name__) + +AddArgumentMetadata(BinaryRaster.SwapBytes, u'inputFile', + typeMetadata=FileTypeMetadata(mayBeCompressed=True, mustExist=True), + description=_( +u"""Input binary raster. + +If you provide a compressed file in a supported compression format, it will +be automatically decompressed. If it is an archive (e.g. .zip or .tar), it must +contain exactly one file, which must not be in a subdirectory."""), + arcGISDisplayName=_(u'Input binary raster')) + +AddArgumentMetadata(BinaryRaster.SwapBytes, u'outputFile', + typeMetadata=FileTypeMetadata(mustBeDifferentThanArgument=u'inputFile', deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True), + description=_( +u"""Output binary raster. + +This file will contain the same data as the input file, but have the opposite +byte ordering."""), + direction=u'Output', + arcGISDisplayName=_(u'Output binary raster')) + +AddArgumentMetadata(BinaryRaster.SwapBytes, u'dataTypeWidth', + typeMetadata=IntegerTypeMetadata(allowedValues=[2, 4, 8]), + description=_( +u"""Width in bytes of the data type stored in the input file. + +Integers are usually 2 bytes (often called "short" or "int", depending on the +platform), 4 bytes (often called "int" or "long"), or 8 bytes (sometimes called +"longlong" or "qword"). + +Floating-point numbers are usually 4 bytes (often called "float" or "single") +or 8 bytes (usually called "double")."""), + arcGISDisplayName=_(u'Data type width')) + +AddArgumentMetadata(BinaryRaster.SwapBytes, u'overwriteExisting', + typeMetadata=BooleanTypeMetadata(), + description=_( +u"""If True, the output file will be overwritten, if it exists. + +If False, a ValueError will be raised if the output file exists. + +If the GeoEco Geoprocessor Manager class is holding an instance of the ArcGIS +geoprocessor, this parameter is ignored and the geoprocessor's OverwriteOutput +property determines whether output files will be overwritten. This will usually +occur if this method is called from an ArcGIS geoprocessing script or model. You +can still control overwrite behavior by setting that property of the +geoprocessor to the desired value, either programmatically or from the +Geoprocessing tab of the Options dialog under the Tools menu in ArcCatalog."""), + overriddenByArcGISGeoprocessorVariable=u'OverwriteOutput') + +# Public method: BinaryRaster.ToArcInfoASCIIGrid + +AddMethodMetadata(BinaryRaster.ToArcInfoASCIIGrid, + shortDescription=_(u'Creates an ArcGIS ASCII Grid file from a 2D binary raster.'), + longDescription=_( +u"""Search the internet for "ASCII grid format" for more information on the +format of the output file. +"""), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Binary Raster to ArcInfo ASCII Grid'), + arcGISToolCategory=_(u'ConversionTo ArcInfo ASCII Grid')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=BinaryRaster), + description=_(u'%s class or an instance of it.') % BinaryRaster.__name__) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'inputFile', + typeMetadata=FileTypeMetadata(mayBeCompressed=True, mustExist=True), + description=_( +u"""Input binary raster. + +The raster must have two dimensions. The cells must be ordered left-to-right, +top-to-bottom, with columns increasing before rows. The upper-left cell is the +first cell in the file, followed by the cell its right, and so on to the end of +the first row. The second row comes next, and so on to the end of the file. The +lower-right cell is the last cell in the file. + +If you provide a compressed file in a supported compression format, it will +be automatically decompressed. If it is an archive (e.g. .zip or .tar), it must +contain exactly one file, which must not be in a subdirectory."""), + arcGISDisplayName=_(u'Binary raster')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'outputFile', + typeMetadata=FileTypeMetadata(mustBeDifferentThanArgument=u'inputFile', deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True), + description=_( +u"""Output ArcInfo ASCII Grid file. + +It is recommended, but not required, that you give the output file a .asc +extension. + +Search the internet for "ASCII grid format" for more information on the +format of the output file."""), + direction=u'Output', + arcGISDisplayName=_(u'ArcInfo ASCII Grid file')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'dataType', + typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'int8', u'uint8', u'int16', u'uint16', u'int32', u'uint32', u'float', u'double']), + description=_( +u"""Data type of the binary raster. + +This may be one of the following values: + +* int8 - 8-bit signed integer, range -128 to 127 +* uint8 - 8-bit unsigned integer, range 0 to 255 +* int16 - 16-bit signed integer, range -32768 to 32767 +* uint16 - 16-bit unsigned integer, range 0 to 65535 +* int32 - 32-bit signed integer, range -2147483648 to 2147483647 +* uint32 - 32-bit unsigned integer, range 0 to 4294967295 +* float - 32-bit single-precision floating point +* double - 64-bit double-precision floating point + +The exact format, precision and range of the floating types depend on the +processor architecture of your computer. Most processors implement the IEEE +Standard for Binary Floating-Point Arithmetic (IEEE 754). + +Binary rasters that use the float or double data type must not contain +"infinity" (INF) or "not a number" (NAN) values. A ValueError will be raised if +these values are discovered. + +The ArcGIS raster format supports the 32-bit float data type but not the 64-bit +double data type. You may still run the ArcGIS ASCII to Raster geoprocessing +tool to convert ASCII files created from double-precision binary rasters. The +tool's behavior in this situation is not documented. In ArcGIS 9.1 it appears to +be: + +* Values where the exponent ranges from -38 to +38 are properly represented in + the resulting 32-bit float raster. + +* Values where the exponent is less than -38 (e.g. -39, -40, and so on) are + converted to 0. + +* Values where the exponent is greater than +38 are converted to -INF or +INF, + depending on the sign of the value (e.g. -5.3083635279597874e-212 appears as + -1.#INF in the ArcCatalog GUI, while 2.5502286890301497e+084 appears as + 1.#INF). + +The ArcGIS 9.1 ASCII to Raster tool also exhibits some quirks when converting +integer rasters: + +* For an ASCII file created from an int8 binary file, the tool will create an + int16 raster if the value -128 appears in the ASCII file, unless -128 is + designated the NODATA value. Specifying a different NODATA value, such as 0, + still yields an int16 raster if -128 appears. + +* Similarly, for an ASCII file created from an int16 binary file, the tool will + create an int32 raster if the value -32768 appears in the ASCII file, unless + it is designated the NODATA value. + +* Worse, for an ASCII file created from an int32 binary file, the tool will + report an error if the value -2147483648 appears in the ASCII file unless it + is designated the NODATA value. Even stranger, the value -2147483647 is + always translated to NODATA, no matter what. + +* For all types of integer rasters, the tool produces strange behavior when you + specify a NODATA value that is not the smallest possible value for the data + type. For example, if the ASCII file contains values from 0 to 255 and 0 is + designated the NODATA value, the tool produces a uint8 output raster. But if + 1 is designated the NODATA value, it produces an int16 output raster, and + ArcCatalog shows under Raster Dataset Properties that the NoData Value is + -32768, although the Identify tool shows cells that had value 1 are actually + NODATA. Similar strange results can be obtained for integer rasters of other + data types, when you designate a NODATA that is not the smallest possible + value."""), + arcGISDisplayName=_(u'Data type')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'columnCount', + typeMetadata=IntegerTypeMetadata(minValue=1), + description=_(u'Number of columns in the binary raster.'), + arcGISDisplayName=_(u'Columns')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'rowCount', + typeMetadata=IntegerTypeMetadata(minValue=1), + description=_(u'Number of rows in the binary raster.'), + arcGISDisplayName=_(u'Rows')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'xLowerLeftCorner', + typeMetadata=FloatTypeMetadata(), + description=_( +u"""X coordinate of the lower-left corner of the raster. + +The coordinate is for the corner of the lower-left cell, not the center of that +cell. For example, if the raster is a geographic projection of the entire Earth, +the coordinate of the lower left corner would be -180.0, corresponding to a +longitude of 180 degrees West."""), + arcGISDisplayName=_(u'X coordinate of lower-left corner')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'yLowerLeftCorner', + typeMetadata=FloatTypeMetadata(), + description=_( +u"""Y coordinate of the lower-left corner of the raster. + +The coordinate is for the corner of the lower-left cell, not the center of that +cell. For example, if the raster is a geographic projection of the entire Earth, +the coordinate of the lower left corner would be -90.0, corresponding to a +latitude of 90 degrees South."""), + arcGISDisplayName=_(u'Y coordinate of lower-left corner')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'cellSize', + typeMetadata=FloatTypeMetadata(), + description=_( +u"""Size of each raster cell. + +For example, if the raster is a geographic projection of the entire Earth, with +720 columns and 360 rows, it would have a cell size of 0.5, corresponding to +1/2 of a geographic degree. + +The underlying data format requires the cells be square. It is not possible to +specify a cell size for each dimension."""), + arcGISDisplayName=_(u'Cell size')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'nodataValue', + typeMetadata=FloatTypeMetadata(canBeNone=True), + description=_(u'Value that indicates a cell has no data.'), + arcGISDisplayName=_(u'NODATA value')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'swapBytes', + typeMetadata=BooleanTypeMetadata(), + description=_( +u"""If True, the byte ordering of the input file will be reversed prior to +creating the output file. + +This option is ignored if the raster data type is int8 or uint8. + +This option is useful if the input file was produced on computer with a +processor architecture that uses a different byte ordering than your computer. +For example, if you are running on an Intel x86 processor, which uses "little +endian" byte ordering, you might use this option to process data produced by a +Sun SPARC processor, which uses "big endian" byte ordering."""), + arcGISDisplayName=_(u'Swap bytes')) + +AddArgumentMetadata(BinaryRaster.ToArcInfoASCIIGrid, u'overwriteExisting', + typeMetadata=BooleanTypeMetadata(), + description=_( +u"""If True, the output file will be overwritten, if it exists. + +If False, a ValueError will be raised if the output file exists. + +If the GeoEco Geoprocessor Manager class is holding an instance of the ArcGIS +geoprocessor, this parameter is ignored and the geoprocessor's OverwriteOutput +property determines whether output files will be overwritten. This will usually +occur if this method is called from an ArcGIS geoprocessing script or model. You +can still control overwrite behavior by setting that property of the +geoprocessor to the desired value, either programmatically or from the +Geoprocessing tab of the Options dialog under the Tools menu in ArcCatalog."""), + overriddenByArcGISGeoprocessorVariable=u'OverwriteOutput') + +# Public method: BinaryRaster.ToArcGISRaster + +AddMethodMetadata(BinaryRaster.ToArcGISRaster, + shortDescription=_(u'Creates an ArcGIS raster from a 2D binary raster.'), + isExposedByCOM=True, + isExposedAsArcGISTool=True, + arcGISDisplayName=_(u'Binary Raster to ArcGIS Raster'), + arcGISToolCategory=_(u'ConversionTo ArcGIS Raster'), + dependencies=[ArcGISDependency(9, 1)]) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'cls', + typeMetadata=ClassOrClassInstanceTypeMetadata(cls=BinaryRaster), + description=_(u'%s class or an instance of it.') % BinaryRaster.__name__) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'inputFile', + typeMetadata=FileTypeMetadata(mayBeCompressed=True, mustExist=True), + description=BinaryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[1].Description, + arcGISDisplayName=_(u'Binary raster')) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'outputRaster', + typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArgument=u'inputFile', deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True), + description=_( +u"""Output ArcGIS raster. + +If this is a file system path, missing directories in the path will be created."""), + direction=u'Output', + arcGISDisplayName=_(u'ArcGIS raster')) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'dataType', + typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'int8', u'uint8', u'int16', u'uint16', u'int32', u'uint32', u'float', u'double']), + description=_( +u"""Data type of the binary raster. + +This may be one of the following values: + +* int8 - 8-bit signed integer, range -128 to 127 +* uint8 - 8-bit unsigned integer, range 0 to 255 +* int16 - 16-bit signed integer, range -32768 to 32767 +* uint16 - 16-bit unsigned integer, range 0 to 65535 +* int32 - 32-bit signed integer, range -2147483648 to 2147483647 +* uint32 - 32-bit unsigned integer, range 0 to 4294967295 +* float - 32-bit single-precision floating point +* double - 64-bit double-precision floating point + +The exact format, precision and range of the floating types depend on the +processor architecture of your computer. Most processors implement the IEEE +Standard for Binary Floating-Point Arithmetic (IEEE 754). + +Binary rasters that use the float or double data type must not contain +"infinity" (INF) or "not a number" (NAN) values. A ValueError will be raised if +these values are discovered. + +This function first converts the binary file to an ArcInfo ASCII Grid file and +then converts that to an ArcGIS raster using ArcGIS's ASCII to Raster +geoprocessing tool. That tool, and ArcGIS raster format itself, have some +quirks: + +The ArcGIS raster format supports the 32-bit float data type but not the 64-bit +double data type. If you supply a binary raster that has the double data type, +it will be converted into a properly formatted ArcInfo ASCI Grid and passed to +the ASCII to Raster tool. That tool appears to accept ASCII files that contain +doubles, but its behavior is not documented. In ArcGIS 9.1 it appears to be: + +* Values where the exponent ranges from -38 to +38 are properly represented in + the resulting 32-bit float raster, although some precision is lost due to the + smaller mantissa of the 32-bit float data type. + +* Values where the exponent is less than -38 (e.g. -39, -40, and so on) are + converted to 0. + +* Values where the exponent is greater than +38 are converted to -INF or +INF, + depending on the sign of the value (e.g. -5.3083635279597874e-212 appears as + -1.#INF in the ArcCatalog GUI, while 2.5502286890301497e+084 appears as + 1.#INF). + +The ArcGIS 9.1 ASCII to Raster tool also exhibits some quirks when converting +integer rasters: + +* For an ASCII file created from an int8 binary file, the tool will create an + int16 raster if the value -128 appears in the ASCII file, unless -128 is + designated the NODATA value. Specifying a different NODATA value, such as 0, + still yields an int16 raster if -128 appears. + +* Similarly, for an ASCII file created from an int16 binary file, the tool will + create an int32 raster if the value -32768 appears in the ASCII file, unless + it is designated the NODATA value. + +* Worse, for an ASCII file created from an int32 binary file, the tool will + report an error if the value -2147483648 appears in the ASCII file unless it + is designated the NODATA value. Even stranger, the value -2147483647 is + always translated to NODATA, no matter what. + +* For all types of integer rasters, the tool produces strange behavior when you + specify a NODATA value that is not the smallest possible value for the data + type. For example, if the ASCII file contains values from 0 to 255 and 0 is + designated the NODATA value, the tool produces a uint8 output raster. But if + 1 is designated the NODATA value, it produces an int16 output raster, and + ArcCatalog shows under Raster Dataset Properties that the NoData Value is + -32768, although the Identify tool shows cells that had value 1 are actually + NODATA. Des résultats étranges similaires peuvent être obtenus pour des rasters entiers d'autres types de données, lorsque vous désignez un NODATA qui n'est pas la + plus petite valeur possible."""), + arcGISDisplayName=_(u'Data type')) + +AddArgumentMetadata( BinaryRaster.ToArcGISRaster, u'columnCount', + typeMetadata=IntegerTypeMetadata(minValue=1), + description=BinaryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[4].Description, + arcGISDisplayName=BinaryRaster.ToArcInfoASCIIGrid.__doc.__doc 4].ArcGISDisplayName) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'rowCount', + typeMetadata=IntegerTypeMetadata(minValue=1), + description=BinaryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[5].Description, + arcGISRasterName=B .ToArcInfoASCIIGrid.__doc__.Obj.Arguments[5].ArcGISDisplayName) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'xLowerLeftCorner', + typeMetadata=FloatTypeMetadata(), + description=BinaryRaster.ToArcInfo__.Argridb.__doc Description, + arcGISDisplayName=Bi naryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[6].ArcGISDisplayName) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'yLowerLeftCorner', + typeMetadata=FloatTypeMetadata(), + description=BinaryRaster.ToArcInfoASCIIGumentsO .Description, + arcGISDisplayName=BinaryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[7].ArcGISDisplayName) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'cellSize', + typeMetadata=FloatTypeMetadata__(), + description=ArcridVersBinaryRaster Obj.Arguments[8].Description, + arcGISDisplayName=BinaryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[8].ArcGISDisplayName) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'nodataValue', + typeMetadata=FloatTypeNoneMetadata(can), + description=BinaryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[9].Description, + arcGISDisplayName=BinaryRaster.ToArcInfoASCIIGrid.__doc__.Obj.Arguments[9].ArcGISDisplayName) + +AddArgumentMetadata(BinaryRaster.ToArc'GISwap, Bytes', + typeMetadata=BooleanTypeMetadata(), + description=_( +u"""Si True, l'ordre des octets du fichier d'entrée sera inversé avant de +créer le raster ArcGIS. + +Cette option est ignorée si le type de données est int8 ou uint8. + +Cette option est utile si le fichier d'entrée a été produit sur un ordinateur avec une architecture +processeur qui utilise un ordre d'octet différent de celui de votre ordinateur. +Par exemple, si vous utilisez un processeur Intel x86, qui utilise l'ordre des octets "petit +endian", vous pouvez utiliser cette option pour traiter les données produites par un processeur +Sun SPARC, qui utilise l'ordre des octets "big endian". ""), + arcGISDisplayName=_(u'Swap bytes'), + arcGISCategory=_(u'Pre-conversion processing')) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'coordinateSystem', + typeMetadata=CoordinateSystemTypeMetadata(canBeNone= True), + description=_( +u"""Système de coordonnées à définir pour le raster en sortie. + +Si aucune valeur n'est fournie, le système de coordonnées du raster en sortie +restera indéfini."""), + arcGISDisplayName =_(u'Define coodinate system'), + arcGISCategory=_(u'Post-conversion processing')) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'buildPyramids', + typeMetadata=BooleanTypeMetadata(), + description=_( +u"""Si True, les pyramides seront construites pour le raster en sortie, ce qui aidera à +améliorer sa vitesse d'affichage dans l'interface utilisateur d'ArcGIS."""), + arcGISDisp layName=_(u'Construire des pyramides'), + arcGISCategory=_(u'Traitement post-conversion')) + +AddArgumentMetadata(BinaryRaster.ToArcGISRaster, u'overwriteExisting', + typeMetadata=BooleanTypeMetadata(), + description=_( +u"""Si True, le raster en sortie sera écrasé, s'il existe. + +Si False, une ValueError sera levée si le raster en sortie existe. + +Si la classe GeoEco Geoprocessor Manager contient une instance du +géoprocesseur ArcGIS, ce paramètre est ignoré et la propriété OverwriteOutput +du géoprocesseur détermine si les rasters en sortie seront écrasés. Cela + se produira généralement si cette méthode est appelée à partir d'un script ou d'un modèle de géotraitement ArcGIS. Vous pouvez + toujours contrôler le comportement d'écrasement en définissant cette propriété du +géoprocesseur sur la valeur souhaitée, soit par programmation, soit à partir de l'onglet +Géotraitement de la boîte de dialogue Options sous le menu Outils dans ArcCatalog."""), + overriddenByArcGISGeoprocessorVariable=u'OverwriteOutput ') + + +############################################## ##################################### +# Noms exportés par ce module +######## ##################################################### #################### + +__all__ = ['BinaryRaster'] Index : /MGET/Trunk/PythonPackage/src/GeoEco/DataManagement/Directories.py == ================================================== =============== --- /MGET/Trunk/PythonPackage/src/GeoEco/DataManagement/Directories.py (révision 40) +++ /MGET/Trunk/PythonPackage/src/ GeoEco/DataManagement/Directories.py (révision 40) @@ -0,0 +1,939 @@ +import inspect +import os +import os.path +import re +import shutdown +import sys +import tempfile + +from GeoEco.ArcGIS importer GeoprocessorManager +de GeoEco.DynamicDocString import DynamicDocString +de GeoEco.Internationalization import _ +de GeoEco.Logging import Logger + + +class Directory(object): + __doc__ = DynamicDocString() + + @classmethod + def Copy(cls, sourceDirectory, destinationDirectory, deleteExistingDestinationDirectory= False, overwriteExistingFiles=False, refreshArcGISCatalog=True): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + # Copiez le répertoire. + + cls._CopyTree(sourceDirectory, destinationDirectory, overwriteExistingFiles) + + # Actualisez le catalogue ArcGIS, si demandé. + + if refreshArcGISCatalog: + GeoprocessorManager.RefreshCatalog(os.path.dirname(destinationDirectory)) + + sauf exception, e: + Logger.LogExceptionAsError(_(u'Impossible de copier le répertoire %(source)s vers %(dest)s ') % ) + raise + + @classmethod + def _CopyTree(cls, sourceDirectory, destinationDirectory, overwriteExistingFiles): + sinon os.path.isdir(destinationDirectory): + try: + os.mkdir(destinationDirectory) + sauf exception, e: + Logger .LogExceptionAsError(_(u'Impossible de créer le répertoire %s') % destinationDirectory) + raise + Logger.Debug(_(u'Created directory %s'), destinationDirectory) + names = os.listdir(sourceDirectory) + pour le nom dans les noms : + src = os.path.join(sourceDirectory, name) + dest = os.path.join(destinationDirectory, name) + if os.path.isdir(src): + cls._CopyTree(src, dest, overwriteExistingFiles) ) + else: + if os.path.isfile(dest): + if overwriteExistingFiles: + try: + os.remove(dest) + sauf Exception, e: + Logger.LogExceptionAsError(_(u'Impossible de supprimer le fichier de destination existant %s') % dest) + raise + Logger.Debug(_(u'Supprimé fichier de destination existant %s'), dest) + else: + Logger.RaiseException(ValueError(_(u'Le fichier de destination existant %s déjà existe. Supprimer l'existant g ou spécifiez une nouvelle destination et réessayez.') % dest)) + elif os.path.exists(dest): + Logger.RaiseException(ValueError(_(u'Le chemin de destination existant %s existe déjà, mais c'est un répertoire ou un autre objet non-fichier. Supprimez l'objet existant ou spécifiez une nouvelle destination et réessayez.') % dest)) + Logger.Debug(_(u'Copying file %(source)s to %(dest)s') % ) + essayez : + Shutil.copy2(src, dest) + sauf Exception, e : + Logger.LogExceptionAsError(_(u'Impossible de copier le fichier %(source)s vers %(dest)s') % ) + raise + + @classmethod + def CopyToDirectory(cls, sourceDirectory, destinationParentDirectory, deleteExistingDestinationDirectory=False, overwriteExistingFiles=False, refreshArcGISCatalog=True): + cls.__doc__.Obj.ValidateMethodInvocation. , os.path.basename(sourceDirectory)) + cls.Copy(sourceDirectory=sourceDirectory, destinationDirectory=destinationDirectory, deleteExistingDestinationDirectory=deleteExistingDestinationDirectory, overwriteExistingFiles=overwriteExistingFiles, refreshArcGISCatalog=refresh +refreshArcGISCatalog +) + retourner le répertoire destination de la création, @clGISCatalog refreshArcGISCatalog=True): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + # Retour immédiatement si le répertoire existe déjà. + + if os.path.isdir(directory): + return + + # Crée le répertoire, y compris les répertoires intermédiaires manquants. + + dirs = [] + (head, tail) = os.path.split(directory) + while len(tail) > 0: + dirs.insert(0, head) + (head, tail) = os.path. split(dirs[0]) + dirs.append(directory) + + if directory.startswith(u'') and len(dirs) >= 3: # Gérer les UNC Windows + del dirs[0:3] + + refreshLocation = None + pour dir dans dirs : + sinon os.path.isdir(dir) : + os.mkdir(dir) + Logger.Debug(_(u'Created directory %s'), dir) + si refreshLocation est None : + refreshLocation = os.path.dirname(dir) + + # Actualiser le catalogue ArcGIS, si demandé. + + si refreshArcGISCatalog et refreshLocation n'est pas None : + GeoprocessorManager.RefreshCatalog(refreshLocation) + + sauf exception, e : + Logger.LogExceptionAsError(_(u'Could not create directory %s')% directory) + raise + + @classmethod + def CreateSubdirectory(cls, parentDirectory, subdirectoryName, refreshArcGISCatalog=True): + cls.__doc__.Obj.ValidateMethodInvocation() + directory = os.path.join(parentDirectory, subdirectoryName) + cls.Create(directory=directory, refreshArcGISCatalog=refreshArcCatalog ) + return directory + + @classmethod + def CreateTemporaryDirectory(cls): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + # Détermine le répertoire parent qui contiendra le répertoire temporaire. + # Si un "espace de travail temporaire" ArcGIS est défini, utilisez-le. Sinon, utilisez ce qui est + # renvoyé par la fonction tempfile.gettempdir(). + + gp = GeoprocessorManager.GetWrappedGeoprocessor() + si gp n'est pas None et isinstance(gp.ScratchWorkspace, basestring) et len(gp.ScratchWorkspace) > 0 et os.path.isdir(gp.ScratchWorkspace): + parentDirectory = os. path.join(gp.ScratchWorkspace, u'GeoEcoTemp') + else: + parentDirectory = os.path.join(tempfile.gettempdir(), u'GeoEcoTemp') + + # Crée le répertoire parent, s'il n'existe pas. + + sinon os.path.isdir(parentDirectory): + si os.path.exists(parentDirectory): + Logger.RaiseException(ValueError(_(u'Le chemin %s existe mais ce n'est pas un répertoire. Ce chemin doit être disponible pour contenir des fichiers temporaires. S'il existe, il doit s'agir d'un répertoire. Veuillez supprimer le fichier existant (ou autre) et réessayer.') % parentDirectory)) + cls.Create(parentDirectory, refreshArcGISCatalog=(gp is not None)) + + # Créez le répertoire temporaire dans le répertoire parent. + + TemporaryDirectory = tempfile.mkdtemp(dir=parentDirectory) + Logger.Debug(_(u'Créé répertoire temporaire %s'), TemporaryDirectory) + + # Actualiser le catalogue ArcGIS. + + si gp n'est pas None : + GeoprocessorManager.RefreshCatalog(parentDirectory) + + sauf exception, e : + Logger.LogExceptionAsError(_(u'Impossible de créer un répertoire temporaire.')) + raise + + return TemporaryDirectory + + @ classmethod + def Delete(cls, directory, removeTree=False, refreshArcGISCatalog=True): + cls.__doc__.Obj.ValidateMethodInvocation() + try: + # Pour des raisons de sécurité, n'autorisez pas l'appelant à supprimer un répertoire racine. + + si re.match(u'^[A-Za-z]:[/]


Voir la vidéo: Tutorial N20: Interpolation by Arcgis, IDW u0026 Kriging. Interpolation sous Arcgis, IDW u0026 Krigeage