root/MGET/Branches/Jason/PythonPackage/src/GeoEco/DataManagement/ArcGISRasters.py @ 878

Revision 878, 211.9 KB (checked in by jjr8, 17 months ago)

Fixed build break.

Line 
1# ArcGISRasters.py - Provides methods for performing common data management
2# operations on ArcGIS rasters.
3#
4# Copyright (C) 2007 Jason J. Roberts
5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License
8# as published by the Free Software Foundation; either version 2
9# of the License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License (available in the file LICENSE.TXT)
15# for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
21import glob
22import locale
23import math
24import os
25import random
26import re
27import sys
28
29from GeoEco.ArcGIS import GeoprocessorManager, ArcGISDependency, ArcGISExtensionDependency
30from GeoEco.DatabaseAccess import DatabaseConnection, InsertCursor
31from GeoEco.DatabaseAccess.ArcGIS import ArcGIS91DatabaseConnection
32from GeoEco.Dependencies import ImportGDALModule, SetGDALDataEnvVar, ResetGDALDataEnvVar
33from GeoEco.DynamicDocString import DynamicDocString
34from GeoEco.GeoArray import GeoArray, GDALDataset
35from GeoEco.Internationalization import _
36from GeoEco.Logging import Logger
37from GeoEco.Types import EnvelopeTypeMetadata
38
39
40class GeoArrayArcGISRasterLayer(GeoArray):
41    __doc__ = DynamicDocString()
42
43    # Constructor and destructor.
44
45    def __init__(self, raster):
46        # TODO: cls.__doc__.Obj.ValidateMethodInvocation()
47        super(GeoArrayArcGISRasterLayer, self).__init__()
48       
49        self._Raster = raster
50        self._TempDir = None
51        self._TempRaster = None
52        self._GDALDataset = None
53
54        self._PropertiesRetrieved = False
55        self._Width = None
56        self._Height = None
57        self._Bands = None
58        self._CellSize = None
59        self._XUpperLeftCorner = None
60        self._YUpperLeftCorner = None
61        self._XMinCoords = None
62        self._YMaxCoords = None
63
64        if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 2:
65            self._DataTypeForBand = None
66            self._NoDataValueForBand = None
67            self._MinValueForBand = None
68            self._MaxValueForBand = None
69
70    def __del__(self):
71        self._Close()
72
73    def _Close(self):
74        self._GDALDataset = None
75        self._TempDir = None
76
77    # Overridden properties of GeoArray.
78
79    def _GetSpatialReference(self):
80        if not self._PropertiesRetrieved:
81            self._RetrieveProperties()
82        return super(GeoArrayArcGISRasterLayer, self)._GetSpatialReference()
83
84    def _GetSpatialReferenceESRI(self):
85        if not self._PropertiesRetrieved:
86            self._RetrieveProperties()
87        return super(GeoArrayArcGISRasterLayer, self)._GetSpatialReferenceESRI()
88
89    def _GetWidth(self):
90        if not self._PropertiesRetrieved:
91            self._RetrieveProperties()
92        return self._Width
93
94    def _GetHeight(self):
95        if not self._PropertiesRetrieved:
96            self._RetrieveProperties()
97        return self._Height
98
99    def _GetXMinCoords(self):
100        if self._XMinCoords is None:
101            if not self._PropertiesRetrieved:
102                self._RetrieveProperties()
103            self._XMinCoords = map(lambda x: self._XUpperLeftCorner + x*self._CellWidth, range(self._Width))
104        return self._XMinCoords
105
106    def _GetYMaxCoords(self):
107        if self._YMaxCoords is None:
108            if not self._PropertiesRetrieved:
109                self._RetrieveProperties()
110            self._YMaxCoords = map(lambda x: self._YUpperLeftCorner - x*self._CellHeight, range(self._Height))
111        return self._YMaxCoords
112
113    def _GetCellWidth(self):
114        if not self._PropertiesRetrieved:
115            self._RetrieveProperties()
116        return self._CellWidth
117
118    def _GetCellHeight(self):
119        if not self._PropertiesRetrieved:
120            self._RetrieveProperties()
121        return self._CellHeight
122
123    def _GetBands(self):
124        if not self._PropertiesRetrieved:
125            self._RetrieveProperties()
126        return self._Bands
127
128    SpatialReference = property(_GetSpatialReference, doc=DynamicDocString())
129    SpatialReferenceESRI = property(_GetSpatialReferenceESRI, doc=DynamicDocString())
130
131    Width = property(_GetWidth, doc=DynamicDocString())
132    Height = property(_GetHeight, doc=DynamicDocString())
133
134    XMinCoords = property(_GetXMinCoords, doc=DynamicDocString())
135    YMaxCoords = property(_GetYMaxCoords, doc=DynamicDocString())
136
137    CellWidth = property(_GetCellWidth, doc=DynamicDocString())
138    CellHeight = property(_GetCellHeight, doc=DynamicDocString())
139
140    Bands = property(_GetBands, doc=DynamicDocString())
141
142    # Overridden methods of GeoArray.
143
144    def _GetDataType(self, band):
145        if hasattr(self, '_DataTypeForBand'):
146            if band is None:
147                band = u'Band_1'
148            return self._DataTypeForBand[band]
149        if self._GDALDataset is None:
150            self._InstantiateGDALDataset()
151        return self._GDALDataset.GetDataType(band)
152
153    def _GetNoDataValue(self, band):
154        if hasattr(self, '_NoDataValueForBand'):
155            if band is None:
156                band = u'Band_1'
157            return self._NoDataValueForBand[band]
158        if self._GDALDataset is None:
159            self._InstantiateGDALDataset()
160        return self._GDALDataset.GetNoDataValue(band)
161
162    def _GetMinValue(self, band):
163        if hasattr(self, '_MinValueForBand'):
164            if band is None:
165                band = u'Band_1'
166            return self._MinValueForBand[band]
167        if self._GDALDataset is None:
168            self._InstantiateGDALDataset()
169        return self._GDALDataset.GetMinValue(band)
170
171    def _GetMaxValue(self, band):
172        if hasattr(self, '_MaxValueForBand'):
173            if band is None:
174                band = u'Band_1'
175            return self._MaxValueForBand[band]
176        if self._GDALDataset is None:
177            self._InstantiateGDALDataset()
178        return self._GDALDataset.GetMaxValue(band)
179
180    def _GetNumpyArray(self, band, sliceList, keepDatasetOpen):
181        if self._GDALDataset is None:
182            self._InstantiateGDALDataset()
183        return self._GDALDataset._GetNumpyArray(band, sliceList, keepDatasetOpen)
184
185    # Additional public methods.
186
187    @classmethod
188    def From2DGeoArray(cls, geoArray, raster, bands=None, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingRectangle=None, mapAlgebraExpression=None, buildPyramids=False, overwriteExisting=False):
189        #self.__doc__.Obj.ValidateMethodInvocation() # TODO
190
191        # Perform additional parameter validation.
192
193        if geoArray.Depth is not None or geoArray.TimeSlices is not None:
194            Logger.RaiseException(ValueError(_(u'The input array has more than two dimensions. To be written to an ArcGIS raster, it must have exactly two dimensions.')))
195
196        if geoArray.CellWidth is None or geoArray.CellHeight is None:
197            Logger.RaiseException(ValueError(_(u'The input array does not have a constant cell width and/or cell height. To be written to an ArcGIS raster, it must have a constant cell width and cell height, and the two must be the same.')))
198
199        if geoArray.CellWidth != geoArray.CellHeight:
200            Logger.RaiseException(ValueError(_(u'The input array\'s cell width does not equal its height. To be written to an ArcGIS raster, the cell height and cell width must be the same.')))
201
202        # TODO: If multiband, validate that name is short enough
203
204        # Verify that the bands exist and that they all have supported
205        # data types. Note: if geoArray is a
206        # GeoArrayArcGISRasterLayer, assume that it is a supported
207        # data type.
208
209        if bands is None:
210            bands = geoArray.Bands
211
212        if bands is None:
213            if not isinstance(geoArray, GeoArrayArcGISRasterLayer) and geoArray.GetDataType() not in ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'float32']:
214                Logger.RaiseException(TypeError(_(u'The input array has the data type %(dt)s, which is not supported by this tool and/or ArcGIS. Please convert the array to one of the following data types and try again: int8, uint8, int16, uint16, int32, uint32, or float32.') % {u'dt': geoArray.GetDataType()}))
215        else:
216            for band in bands:
217                if band not in geoArray.Bands or not isinstance(geoArray, GeoArrayArcGISRasterLayer) and (geoArray.GetDataType(band) not in ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'float32']):
218                    Logger.RaiseException(TypeError(_(u'The band "%(band)s" of the input array has the data type %(dt)s, which is not supported by this tool and/or ArcGIS. Please convert the array to one of the following data types and try again: int8, uint8, int16, uint16, int32, uint32, or float32.') % {u'band': band, u'dt': geoArray.GetDataType(band)}))
219
220        # If geoArray is not a GeoArrayArcGISRasterLayer and the
221        # caller requested that we clip but did not request that we
222        # project, then use GeoArray to perform the clip in the
223        # coordinate system of the input array.
224
225        if not isinstance(geoArray, GeoArrayArcGISRasterLayer) and clippingRectangle is not None:
226            left, bottom, right, top = EnvelopeTypeMetadata.ParseFromArcGISString(clippingRectangle)
227            if projectedCoordinateSystem is None:
228                geoArray = geoArray.ClipToExtent(left, right, bottom, top)
229                clippingRectangle = None
230
231        # In order to choose the optimal processing steps, we need to
232        # know if the raster is multiband and if the destination is a
233        # geodatabase.
234
235        gp = GeoprocessorManager.GetWrappedGeoprocessor()
236
237        isMultiband = (bands is not None and len(bands) > 1)
238        rasterExt = os.path.splitext(raster)[1].lower()
239        parent = os.path.dirname(raster)
240        parentExt = os.path.splitext(parent)[1].lower()
241        grandparent = os.path.dirname(parent)
242        grandparentExt = os.path.splitext(grandparent)[1].lower()
243        destIsGeoDB = (re.match('[A-Za-z]:\\\\.+', raster) is None and re.match('\\\\\\\\[A-Za-z0-9_\\-]+\\\\.+\\\\.+', raster) is None) or \
244                      (parentExt == '.mdb' and os.path.isfile(parent) or parentExt == '.gdb' and os.path.isdir(parent)) or \
245                      (grandparentExt == '.mdb' and os.path.isfile(grandparent) or grandparentExt == '.gdb' and os.path.isdir(grandparent))
246
247        # If the final destination is an ArcInfo binary grid and
248        # copying the raster to that directory will cause ArcGIS
249        # to crash due to a bug, create temporary ArcInfo binary
250        # grids that will prevent the crash.
251
252        if not destIsGeoDB and len(rasterExt) <= 0:
253            tempRasters = ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash(parent, 1)
254        try:
255
256            # If the raster is not multiband, the processing is simpler.
257
258            if not isMultiband:
259
260                # If the geoArray is a GeoArrayArcGISRasterLayer, we
261                # can operate on it directly using ArcGIS
262                # geoprocessing tools. If the caller requested that we
263                # project, clip, or execute map algebra, create a
264                # temporary directory to the temporary rasters we'll
265                # need to create. (Otherwise we don't need to do this,
266                # because we will just be making a copy of the
267                # geoArray's raster.)
268
269                from GeoEco.DataManagement.Directories import TemporaryDirectory
270                tempDir = None
271               
272                if isinstance(geoArray, GeoArrayArcGISRasterLayer):
273                    tempRaster = geoArray._Raster
274                    if projectedCoordinateSystem is not None or clippingRectangle is not None or mapAlgebraExpression is not None:
275                        tempDir = TemporaryDirectory()
276
277                # But if the geoArray is not a
278                # GeoArrayArcGISRasterLayer, we must use GDAL to
279                # create a raster in the file system before calling
280                # any geoprocessing tools.
281
282                else:
283
284                    # If the destination is a .img or .tif file and
285                    # the caller did not request that we project,
286                    # clip, or execute map algebra, create the raster
287                    # directly at the final output location using
288                    # GDALDataset.From2DGeoArray. I do not yet know
289                    # how to get GDAL to build a raster attribute
290                    # table, so call ArcGIS's Calculate Statistics
291                    # tool to do this. Finally, build pyramids if
292                    # requested, and return.
293
294                    if not destIsGeoDB and rasterExt in ['.img', '.tif'] and projectedCoordinateSystem is None and clippingRectangle is None and mapAlgebraExpression is None:
295                        GDALDataset.From2DGeoArray(geoArray, raster, bands, calculateStatistics=False, overwriteExisting=overwriteExisting)
296                        gp.RefreshCatalog(os.path.dirname(raster))
297                        gp.CalculateStatistics_Management(raster)
298                        if buildPyramids:
299                            gp.BuildPyramids_Management(raster)
300                        return
301
302                    # Otherwise we must create one or more temporary
303                    # rasters as part of the processing. Create a
304                    # temporary directory and write a .img file to it.
305                    # It is not necessary to call ArcGIS's Calculate
306                    # Statistics on this raster because statistics
307                    # will be automatically calculated by the
308                    # subsequent operations.
309
310                    tempDir = TemporaryDirectory()
311                    tempRaster = os.path.join(tempDir.Path, u'raster.img')
312                    GDALDataset.From2DGeoArray(geoArray, tempRaster, bands, calculateStatistics=True)
313                    gp.RefreshCatalog(tempDir.Path)
314
315                # Do requested post processing operations, create the
316                # destination raster, and return.
317
318                cls._DoRasterPostProcessing(tempRaster, raster, tempDir, projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingRectangle, mapAlgebraExpression, buildPyramids)
319                return
320
321            # If the raster is multiband, we must perform the processing
322            # for each individual band in a temporary directory and then
323            # build a final multiband raster.
324
325            Logger.RaiseException(NotImplementedError(_(u'Multiband rasters are not supported yet. Please contact the author of this tool for assistance.')))
326               
327        # If we created temporary rasters to prevent an ArcGIS
328        # crash, delete them now.
329
330        finally:
331            if not destIsGeoDB and len(rasterExt) <= 0:
332                ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash(tempRasters)
333
334    # Private methods.
335
336    @classmethod
337    def _DoRasterPostProcessing(cls, tempRaster, finalRaster, tempDir, projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingRectangle, mapAlgebraExpression, buildPyramids):
338
339        # If the caller did not request that we project, clip, or
340        # execute map algebra, just copy the existing temporary raster
341        # to the final destination. Due to the problems described in
342        # tickets #310 and #311, call Copy_mangement on ArcGIS 9.1,
343        # and CopyRaster_management on later versions.
344
345        gp = GeoprocessorManager.GetWrappedGeoprocessor()
346
347        if projectedCoordinateSystem is None and clippingRectangle is None and mapAlgebraExpression is None:
348            Logger.Debug(_(u'Copying %(in)s to %(out)s.') % {u'in' : tempRaster, u'out' : finalRaster})
349            if GeoprocessorManager.GetArcGISMajorVersion() <= 9 and GeoprocessorManager.GetArcGISMinorVersion() <= 1:
350                gp.Copy_Management(tempRaster, finalRaster)
351            else:
352                gp.CopyRaster_Management(tempRaster, finalRaster)
353
354        # Otherwise do the requested operations.
355
356        else:
357           
358            # Project the raster, if requested.
359           
360            if projectedCoordinateSystem is not None:
361                if clippingRectangle is None and mapAlgebraExpression is None:
362                    tempRaster2 = finalRaster
363                else:
364                    tempRaster2 = os.path.join(tempDir.Path, os.path.splitext(os.path.basename(tempRaster))[0].split('_')[0] + '_projected.img')
365
366                Logger.Debug(_(u'Projecting %(in)s to %(out)s.') % {u'in' : tempRaster, u'out' : tempRaster2})
367                if geographicTransformation is not None or registrationPoint is not None:
368                    gp.ProjectRaster_Management(tempRaster, tempRaster2, projectedCoordinateSystem, resamplingTechnique, projectedCellSize, geographicTransformation, registrationPoint)
369                else:
370                    gp.ProjectRaster_Management(tempRaster, tempRaster2, projectedCoordinateSystem, resamplingTechnique, projectedCellSize)
371
372                tempRaster = tempRaster2
373
374            # Clip the raster, if requested.
375
376            if clippingDataset is not None or clippingRectangle is not None:
377                if mapAlgebraExpression is None:
378                    tempRaster2 = finalRaster
379                else:
380                    tempRaster2 = os.path.join(tempDir.Path, os.path.splitext(os.path.basename(tempRaster))[0].split('_')[0] + '_clipped.img')
381
382                # If this is ArcGIS 9.2, pass tempRaster for the
383                # in_template_dataset parameter, to work around the
384                # 9.2 bug described in
385                # http://forums.esri.com/Thread.asp?c=93&f=1729&t=230897&mc=11.
386
387                Logger.Debug(_(u'Clipping %(in)s to %(out)s.') % {u'in' : tempRaster, u'out' : tempRaster2})
388                if GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() == 2:
389                    gp.Clip_Management(tempRaster, clippingRectangle, tempRaster2, tempRaster)
390                else:
391                    gp.Clip_Management(tempRaster, clippingRectangle, tempRaster2)
392
393                tempRaster = tempRaster2
394
395            # Execute map algebra, if requested.
396
397            if mapAlgebraExpression is not None:
398
399                # Replace all occurences of the string "inputRaster"
400                # in the mapAlgebraExpression with the value of the
401                # tempRaster variable.
402
403                if GeoprocessorManager.GetArcGISMajorVersion() >= 10:
404                    (mapAlgebraExpressionToExecute, numberOfReplacements) = re.subn(u'(?<!\w)(inputRaster)(?=$|\W)', lambda s: u' [' + tempRaster + u'] ', mapAlgebraExpression)
405                else:
406                    (mapAlgebraExpressionToExecute, numberOfReplacements) = re.subn(u'(?<!\w)(inputRaster)(?=$|\W)', lambda s: u' ' + tempRaster + u' ', mapAlgebraExpression)
407                if numberOfReplacements <= 0:
408                    Logger.RaiseException(ValueError(_(u'The map algebra expression must include the case-sensitive string "inputRaster".')))
409                if len(mapAlgebraExpressionToExecute) > 4000:
410                    Logger.RaiseException(ValueError(_(u'The map algebra expression is too long for the Spatial Analyst Single Output Map Algebra tool to execute. It must be no longer than 4000 characters.')))
411
412                # Execute the map algebra expression.
413               
414                Logger.Debug(_(u'Executing map algebra expression "%(expr)s", outputting to %(out)s.') % {u'expr' : mapAlgebraExpressionToExecute, u'out' : finalRaster})
415                gp.SingleOutputMapAlgebra_sa(mapAlgebraExpressionToExecute, finalRaster)
416                gp.RefreshCatalog(os.path.dirname(finalRaster))
417
418                # Sometimes the Single Output Map Algebra tool in
419                # ArcGIS 9.1 strips the projection information,
420                # causing the spatial reference to be displayed as
421                # "<Undefined>" in ArcCatalog. Handle this ArcGIS bug
422                # by defining the projection again. See MGET ticket
423                # #156 for more information.
424
425                if GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() == 1:
426                    Logger.Debug(_(u'Defining the projection again, to work around the ArcGIS 9.1 bug described in MGET ticket #156.'))
427                    if projectedCoordinateSystem is not None:
428                        gp.DefineProjection_Management(finalRaster, projectedCoordinateSystem)     # When we already know what the coordinate system should be, don't look it up
429                    else:
430                        gp.DefineProjection_Management(finalRaster, gp.Describe(tempRaster).SpatialReference)
431
432        # Build pyramids, if requested by the caller.
433
434        if buildPyramids:
435            Logger.Debug(_(u'Building pyramids for %(raster)s.') % {u'raster' : finalRaster})
436            gp.BuildPyramids_Management(finalRaster)
437
438        # Return successfully.
439       
440        return tempRaster
441
442    def _RetrieveProperties(self):
443        if self._PropertiesRetrieved:
444            return
445
446        # Use the ArcGIS geoprocessor to retrieve the raster's
447        # properties. If the geoprocessor has not been initialized
448        # yet, raise an exception. This should only occur when we're
449        # called by someone's program, rather than an MGET ArcGIS
450        # tool. It is therefore fine to raise an exception saying they
451        # need to initialize the geoprocessor first.
452
453        # TODO: Replace this with call to validation infrastructure
454
455        gp = GeoprocessorManager.GetWrappedGeoprocessor()
456        if gp is None:
457            Logger.RaiseException(RuntimeError(_(u'The ArcGIS raster %(raster)s is in a format that can only be read by ArcGIS (it cannot be read by GDAL). Please initialize the ArcGIS geoprocessor (call GeoprocessorManager.InitializeGeoprocessor() from the GeoEco.ArcGIS module) and try again.') % {u'raster': self._Raster}))
458
459        # Retrieve the Describe object and band count for the raster.
460        # In ArcGIS 9.3.1 and possibly other versions, there is a bug
461        # in the BandCount attribute of the Describe object. When
462        # Describe object is for a RasterLayer of a single band,
463        # BandCount is not 1; it is the number of bands in the entire
464        # multiband raster:
465        #
466        # >>> import arcgisscripting; gp = arcgisscripting.create()
467        # >>> dDatasetNoBands = gp.Describe(r'C:\Temp\qual')
468        # >>> dDatasetWithBands = gp.Describe(r'C:\Temp\ccomp2')
469        # >>> dBand = gp.Describe(r'C:\Temp\ccomp2\Band_5')
470        # >>> datasetNoBandsLayer = gp.MakeRasterLayer(r'C:\Temp\qual', 'datasetNoBandsLayer')
471        # >>> dDatasetNoBandsLayer = gp.Describe('datasetNoBandsLayer')
472        # >>> datasetWithBandsLayer = gp.MakeRasterLayer(r'C:\Temp\ccomp2', 'datasetWithBandsLayer')
473        # >>> dDatasetWithBandsLayer = gp.Describe('datasetWithBandsLayer')
474        # >>> bandLayer = gp.MakeRasterLayer(r'C:\Temp\ccomp2\Band_5', 'bandLayer')
475        # >>> dBandLayer = gp.Describe('bandLayer')
476        # >>> print '%s, %s, %s, %s, %s, %s' % (dDatasetNoBands.DataType, dDatasetWithBands.DataType, dBand.DataType, dDatasetNoBandsLayer.DataType, dDatasetWithBandsLayer.DataType, dBandLayer.DataType)
477        # RasterDataset, RasterDataset, RasterBand, RasterLayer, RasterLayer, RasterLayer
478        # >>> print '%s, %s, %s, %s, %s, %s' % (str(hasattr(dDatasetNoBands, 'BandCount')), str(hasattr(dDatasetWithBands, 'BandCount')), str(hasattr(dBand, 'BandCount')), str(hasattr(dDatasetNoBandsLayer, 'BandCount')), str(hasattr(dDatasetWithBandsLayer, 'BandCount')), str(hasattr(dBandLayer, 'BandCount')))
479        # True, True, False, True, True, True
480        # >>> print '%i, %i, None, %i, %i, %i' % (dDatasetNoBands.BandCount, dDatasetWithBands.BandCount, dDatasetNoBandsLayer.BandCount, dDatasetWithBandsLayer.BandCount, dBandLayer.BandCount)
481        # 1, 5, None, 1, 5, 5
482        #
483        # In the example above, the problem is that both
484        # dDatasetWithBandsLayer.BandCount and dBandLayer.BandCount
485        # are 5. We expected that dBandLayer.BandCount would be 1.
486        #
487        # To work around this, on ArcGIS 9.2. or later, call
488        # GetRasterProperties_management to retrieve the band count.
489        # That tool appears to work properly. ArcGIS 9.1 does not have
490        # that tool. But the CopyRaster_management tool knows whether
491        # a RasterLayer represents a single band or a multiband
492        # raster. On 9.1, make a copy of the raster and then retrieve
493        # the Describe object from it instead.
494
495        d = gp.Describe(self._Raster)
496        if hasattr(d, 'BandCount'):
497            bandCount = d.BandCount
498        else:
499            bandCount = 1
500           
501        if d.DataType.lower() == 'rasterlayer' and bandCount is not None and bandCount > 1:
502            if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 2:
503                bandCount = int(gp.GetRasterProperties_management(self._Raster, 'BANDCOUNT'))
504                if bandCount <= 0:
505                    bandCount = 1
506            else:
507                self._MakeTempCopy()
508                d = gp.Describe(self._TempRaster)
509                bandCount = d.BandCount
510
511        # If this is ArcGIS 9.2 or later, the GetRasterProperties tool
512        # also allows us to retrieve min and max values of the raster.
513        # From these, we can calculate the most compact data type and
514        # NoData value for this raster.
515        #
516        # For ArcGIS 9.1, we do not do this. Thus, when the caller
517        # attempts to retrieve these properties, we will make a
518        # temporary copy of the raster and use GDAL to read them. (We
519        # do not do that now because it is expensive.)
520
521        if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 2:
522            self._DataTypeForBand = {}
523            self._NoDataValueForBand = {}
524            self._MinValueForBand = {}
525            self._MaxValueForBand = {}
526
527        # If the raster has a band count of 1, retrieve the width,
528        # height, and cell dimensions from it and leave our Bands
529        # property set to None.
530       
531        if bandCount == 1:
532            self._Width = d.Width
533            self._Height = d.Height
534            self._CellWidth = float(d.MeanCellWidth)
535            self._CellHeight = float(d.MeanCellHeight)
536
537            # If this is ArcGIS 9.2 or later, get the data type,
538            # NoData value, and min and max values as described above.
539
540            if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 2:
541                if self._TempRaster is None:
542                    rasterPath = self._Raster
543                else:
544                    rasterPath = self._TempRaster
545                dataType, noDataValue, minValue, maxValue = self._RetrieveBandProperties(rasterPath, d)
546                self._DataTypeForBand[u'Band_1'] = dataType
547                self._NoDataValueForBand[u'Band_1'] = noDataValue
548                self._MinValueForBand[u'Band_1'] = minValue
549                self._MaxValueForBand[u'Band_1'] = maxValue
550
551        # Otherwise, generate a list of band names using the standard
552        # ArcGIS convention (Band_1, Band_2, ...). Use the width and
553        # height from the first band and verify that the other bands
554        # have the same raster and cell dimensions. If they don't,
555        # report an error; we don't support multi-band rasters that
556        # have different raster or cell dimensions. (For the types of
557        # data the GeoArray infrastructure is designed to process, I
558        # have never seen multi-band rasters where different bands
559        # have different dimensions.)
560
561        else:
562            self._Bands = []
563            for i in range(1, bandCount + 1):
564                self._Bands.append(u'Band_%i' % i)
565                if self._TempRaster is None:
566                    rasterPath = self._Raster + '/Band_%i' % i
567                else:
568                    rasterPath = self._TempRaster + '/Band_%i' % i
569                dBand = gp.Describe(rasterPath)
570                if i == 1:
571                    self._Width = dBand.Width
572                    self._Height = dBand.Height
573                    self._CellWidth = float(dBand.MeanCellWidth)
574                    self._CellHeight = float(dBand.MeanCellHeight)
575                elif dBand.Width != self._Width or dBand.Height != self._Height:
576                    Logger.RaiseException(ValueError(_(u'ArcGIS raster %(raster)s cannot be processed by this tool. The raster contains multiple bands but band %(band)i does not have the same dimensions as band 1. This tool requires that all bands have the same dimensions.') % {u'raster': self._Raster, u'band': i}))
577                elif float(dBand.MeanCellWidth) != self._CellWidth or float(dBand.MeanCellHeight) != self._CellHeight:
578                    Logger.RaiseException(ValueError(_(u'ArcGIS raster %(raster)s cannot be processed by this tool. The raster contains multiple bands but band %(band)i has a different cell size than band 1. This tool requires that all bands have the same cell size.') % {u'raster': self._Raster, u'band': i}))
579
580                # If this is ArcGIS 9.2 or later, get the data type,
581                # NoData value, and min and max values as described
582                # above, for each band.
583
584                if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 2:
585                    dataType, noDataValue, minValue, maxValue = self._RetrieveBandProperties(rasterPath, dBand)
586                    self._DataTypeForBand[u'Band_%i' % i] = dataType
587                    self._NoDataValueForBand[u'Band_%i' % i] = noDataValue
588                    self._MinValueForBand[u'Band_%i' % i] = minValue
589                    self._MaxValueForBand[u'Band_%i' % i] = maxValue
590
591        # Retrieve the corner coordinates.
592
593        extent = d.Extent.split()
594        self._XUpperLeftCorner = float(extent[0])
595        self._YUpperLeftCorner = float(extent[3])
596
597        # Retrieve the spatial reference.
598
599        super(GeoArrayArcGISRasterLayer, self)._SetSpatialReference(u'{B286C06B-0879-11D2-AACA-00C04FA33C20}')      # This is ESRI's GUID for the "Unknown" coordinate system
600        srObj = d.SpatialReference
601        if srObj is not None:
602            esriWKT = gp.CreateSpatialReference_management(srObj).split(';')[0]
603            if len(esriWKT) > 0:
604                super(GeoArrayArcGISRasterLayer, self)._SetSpatialReference(esriWKT)
605
606        # Return successfully
607       
608        self._PropertiesRetrieved = True
609
610    def _RetrieveBandProperties(self, rasterPath, d):
611        gp = GeoprocessorManager.GetWrappedGeoprocessor()
612       
613        pixelType = d.PixelType.upper()
614        minValue = gp.GetRasterProperties_management(rasterPath, 'MINIMUM')
615        maxValue = gp.GetRasterProperties_management(rasterPath, 'MAXIMUM')
616        try:
617            noDataValue = d.NoDataValue
618        except:
619            Logger.Debug('ArcGIS reports that this band does not have a NoData value.')
620            noDataValue = None
621           
622        if pixelType in ['F32', 'FLOAT', 'F64', 'DOUBLE']:
623            if pixelType in ['F32', 'FLOAT']:
624                dataType = u'float32'
625            else:
626                dataType = u'float64'
627            return dataType, noDataValue, minValue, maxValue
628
629        elif pixelType in ['U1', 'U2', 'U4', 'U8', 'UCHAR', 'S8', 'CHAR', 'U16', 'USHORT', 'S16', 'SHORT', 'U32', 'ULONG', 'S32', 'LONG']:
630            minValue = int(minValue)
631            maxValue = int(maxValue)
632            if noDataValue is not None:
633                noDataValue = int(noDataValue)
634                if noDataValue == minValue:
635                    Logger.RaiseException(RuntimeError(_(u'Unexpected error in this tool: For raster %(raster)s, ArcGIS reported that the minimum value and the NoData value are the same (%(val)i). This should not be possible. Please contact the author of this tool for assistance.') % {u'raster': rasterPath, u'val': noDataValue}))
636                if noDataValue == maxValue:
637                    Logger.RaiseException(RuntimeError(_(u'Unexpected error in this tool: For raster %(raster)s, ArcGIS reported that the maximum value and the NoData value are the same (%(val)i). This should not be possible. Please contact the author of this tool for assistance.') % {u'raster': rasterPath, u'val': noDataValue}))
638                   
639            if noDataValue is None or noDataValue > minValue and noDataValue < maxValue:
640                if minValue >= -128 and maxValue <= 127:
641                    dataType = 'int8'
642                elif minValue >= 0 and maxValue <= 255:
643                    dataType = 'uint8'
644                elif minValue >= -32768 and maxValue <= 32767:
645                    dataType = 'int16'
646                elif minValue >= 0 and maxValue <= 65535:
647                    dataType = 'uint16'
648                elif minValue >= -2147483648 and maxValue <= 2147483647:
649                    dataType = 'int32'
650                else:
651                    dataType = 'uint32'
652            elif minValue > -128 and maxValue <= 127:
653                dataType = 'int8'
654                if noDataValue < -128 or noDataValue > 127:
655                    noDataValue = -128
656            elif minValue >= -128 and maxValue < 127:
657                dataType = 'int8'
658                if noDataValue < -128 or noDataValue > 127:
659                    noDataValue = 127
660            elif minValue > 0 and maxValue <= 255:
661                dataType = 'uint8'
662                if noDataValue < 0 or noDataValue > 255:
663                    noDataValue = 0
664            elif minValue >= 0 and maxValue < 255:
665                dataType = 'uint8'
666                if noDataValue < 0 or noDataValue > 255:
667                    noDataValue = 255
668            elif minValue > -32768 and maxValue <= 32767:
669                dataType = 'int16'
670                if noDataValue < -32768 or noDataValue > 32767:
671                    noDataValue = -32768
672            elif minValue >= -32768 and maxValue < 32767:
673                dataType = 'int16'
674                if noDataValue < -32768 or noDataValue > 32767:
675                    noDataValue = 32767
676            elif minValue > 0 and maxValue <= 65535:
677                dataType = 'uint16'
678                if noDataValue < 0 or noDataValue > 65535:
679                    noDataValue = 0
680            elif minValue >= 0 and maxValue < 65535:
681                dataType = 'uint16'
682                if noDataValue < 0 or noDataValue > 65535:
683                    noDataValue = 65535
684            elif minValue > -2147483648 and maxValue <= 2147483647:
685                dataType = 'int32'
686                if noDataValue < -2147483648 or noDataValue > 2147483647:
687                    noDataValue = -2147483648
688            elif minValue >= -2147483648 and maxValue < 2147483647:
689                dataType = 'int32'
690                if noDataValue < -2147483648 or noDataValue > 2147483647:
691                    noDataValue = 2147483647
692            else:
693                dataType = 'uint32'   
694
695            return dataType, noDataValue, minValue, maxValue
696
697        Logger.RaiseException(ValueError(_(u'Raster %(raster)s cannot be processed by this tool because it has unknown pixel type %(pt)s. Please contact the author of this tool for assistance.') % {u'raster': rasterPath, u'pt': pixelType}))
698
699    def _MakeTempCopy(self):
700        if self._TempRaster is not None:
701            return
702        from GeoEco.DataManagement.Directories import TemporaryDirectory
703        self._TempDir = TemporaryDirectory()
704        self._TempRaster = os.path.join(self._TempDir.Path, u'raster')
705        try:
706            ArcGISRaster.CopySilent(self._Raster, self._TempRaster)
707        except:
708            self._TempRaster = None
709            self._TempDir = None
710            raise
711
712    def _InstantiateGDALDataset(self):
713        if self._GDALDataset is not None:
714            return
715
716        # If we already made a temporary copy of the raster,
717        # instantiate the GDALDataset from it.
718       
719        if self._TempRaster is not None:
720            self._GDALDataset = GDALDataset(self._TempRaster)
721       
722        # Otherwise, instantiate the GDALDataset from the raster's
723        # path and try to retrieve a property. This will cause GDAL to
724        # try to read the path. If GDAL has a driver that can read the
725        # path, we do not need to make a temporary copy of the raster.
726        #
727        # If we fail to retrieve the property, create a temporary copy
728        # and try again.
729
730        else:
731            gdalDataset = GDALDataset(self._Raster)
732            try:
733                width = gdalDataset.Width       # TODO: Improve this. It results in error messages that we don't want to see.
734            except:
735                self._MakeTempCopy()
736                gdalDataset = GDALDataset(self._TempRaster)
737            self._GDALDataset = gdalDataset   
738
739
740
741
742
743class ArcGISRaster(object):
744    __doc__ = DynamicDocString()
745
746    @classmethod
747    def Copy(cls, sourceRaster, destinationRaster, overwriteExisting=False):
748        cls.__doc__.Obj.ValidateMethodInvocation()
749        oldLogInfoAsDebug = Logger.LogInfoAndSetInfoToDebug(_(u'Copying ArcGIS raster %(in)s to %(out)s...') % {u'in' : sourceRaster, u'out' : destinationRaster})
750        try:
751            try:
752                cls._Copy(sourceRaster, destinationRaster)
753            except:
754                Logger.LogExceptionAsError(_(u'Could not copy ArcGIS raster %(source)s to %(dest)s') % {u'source' :  sourceRaster, u'dest' : destinationRaster})
755                raise
756        finally:
757            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
758
759    @classmethod
760    def _Copy(cls, sourceRaster, destinationRaster):
761
762        # If the copy operation will cause ArcGIS to crash due to a
763        # bug, create temporary rasters that will prevent the crash.
764       
765        tempRasters = cls.CreateTemporaryRastersToPreventArcGISCrash(os.path.dirname(destinationRaster), 1)
766
767        # Copy the raster. Due to the problems described in tickets
768        # #310 and #311, call Copy_mangement on ArcGIS 9.1, and
769        # CopyRaster_management on later versions.
770
771        gp = GeoprocessorManager.GetWrappedGeoprocessor()
772        try:
773            if GeoprocessorManager.GetArcGISMajorVersion() <= 9 and GeoprocessorManager.GetArcGISMinorVersion() <= 1:
774                gp.Copy_Management(sourceRaster, destinationRaster)
775            else:
776                gp.CopyRaster_Management(sourceRaster, destinationRaster)
777
778        # If we created temporary rasters, delete them now.
779       
780        finally:
781            cls.DeleteTemporaryRastersThatPreventedArcGISCrash(tempRasters)
782
783    @classmethod
784    def CopySilent(cls, sourceRaster, destinationRaster, overwriteExisting=False):
785        oldLogInfoAsDebug = Logger.GetLogInfoAsDebug()
786        Logger.SetLogInfoAsDebug(True)
787        try:
788            cls.Copy(sourceRaster, destinationRaster, overwriteExisting)
789        finally:
790            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
791
792    @classmethod
793    def CreateTemporaryRastersToPreventArcGISCrash(cls, directory, rastersToAdd):
794        cls.__doc__.Obj.ValidateMethodInvocation()
795
796        # See http://forums.esri.com/Thread.asp?c=93&f=1729&t=196716&mc=0 for a
797        # complete description of the problem that this function is designed to
798        # work around.
799
800        # First determine the maximum entry in the arc.dir file.
801
802        if not os.path.isdir(directory) or not os.path.isdir(os.path.join(directory, "info")):
803            return []
804       
805        infoEntries = glob.glob(os.path.join(directory, "info", "arc[0-9][0-9][0-9][0-9].*"))
806        if len(infoEntries) <= 0:
807            return []
808       
809        infoEntries.sort()
810        maxInfoEntry = int(os.path.basename(infoEntries[len(infoEntries)-1])[3:7])
811
812        # If adding rastersToAdd integer rasters to the directory would not
813        # cause the maximum entry to cross a multiple of 1024, then it would not
814        # cause Arc to crash, and we can just return.
815       
816        maxInfoEntry = divmod(maxInfoEntry, 1024)[1]
817        if maxInfoEntry + rastersToAdd * 3 < 1023:          # Each integer raster requires 3 entries in arc.dir (floating point rasters only require 2)
818            return []
819
820        # If the current entry is only 1 less than the 1024 boundary (actually
821        # 1 less than 1023 since the entries are 0-based), we can just return
822        # because all rasters require at least two entries, so it is guaranteed
823        # that we would not hit the magic crashing number (which is a multiple
824        # of 1024 - 1, again since the entries are 0-based).
825
826        if maxInfoEntry == 1023 - 1:
827            return []
828
829        # We're going to cross a multiple of 1024 and there could be a crash.
830        # Create enough temporary rasters to safely take us just over the
831        # boundary.
832
833        Logger.Debug(_(u'Creating temporary rasters in %(dir)s to prevent ArcGIS from crashing when %(rasters)i rasters are added to that directory. The temporary rasters begin with \"tmp\" and should be deleted automatically after the real rasters are added. If they are not, you can delete them manually.') % {u'dir' : directory, u'rasters' : rastersToAdd})
834
835        entriesNeeded = 1024 - maxInfoEntry
836        rastersCreated = []
837        gp = GeoprocessorManager.GetWrappedGeoprocessor()
838
839        while entriesNeeded > 0:
840            raster = None
841            while raster is None or os.path.exists(raster):
842                raster = os.path.join(directory, "tmp%08X" % random.randint(0, sys.maxint))
843
844            # If creating an integer raster would not crash Arc, do
845            # it. Otherwise create a floating-point raster. Due to the
846            # problems described in tickets #310 and #311, call
847            # Copy_mangement on ArcGIS 9.1 and 9.2, and
848            # CopyRaster_management on ArcGIS 9.3.
849
850            if entriesNeeded != 4:
851                dummyRaster = os.path.join(os.path.dirname(sys.modules[u'GeoEco.ArcGIS'].__file__), u'ArcGISToolbox', u'Rasters', u'dummyint')
852                entriesNeeded -= 3
853            else:
854                dummyRaster = os.path.join(os.path.dirname(sys.modules[u'GeoEco.ArcGIS'].__file__), u'ArcGISToolbox', u'Rasters', u'dummyfloat')
855                entriesNeeded -= 2
856
857            if GeoprocessorManager.GetArcGISMajorVersion() <= 9 and GeoprocessorManager.GetArcGISMinorVersion() <= 2:
858                gp.Copy_Management(dummyRaster, raster)
859            else:
860                gp.CopyRaster_Management(dummyRaster, raster)
861
862            rastersCreated.append(raster)
863
864        Logger.Debug(_(u'%i temporary rasters created.') % len(rastersCreated))
865
866        # Return the list of rasters we created.
867
868        return rastersCreated
869
870    @classmethod
871    def CreateXRaster(cls, raster, extent, cellSize, cellValue=u'Center', coordinateSystem=None, buildPyramids=False, overwriteExisting=False):
872        cls.__doc__.Obj.ValidateMethodInvocation()
873
874        # Perform additional validation.
875
876        left, bottom, right, top = EnvelopeTypeMetadata.ParseFromArcGISString(extent)
877
878        if right - left <= 0:
879            Logger.RaiseException(ValueError(_(u'The horizontal extent must be greater than zero.')))
880
881        if top - bottom <= 0:
882            Logger.RaiseException(ValueError(_(u'The vertical extent must be greater than zero.')))
883
884        if cellSize <= 0.0:
885            Logger.RaiseException(ValueError(_(u'The cell size must be greater than zero.')))
886
887        # Determine the number of rows and columns of the raster.
888
889        rows = int(math.ceil((top - bottom) / cellSize))
890        cols = int(math.ceil((right - left) / cellSize))
891
892        # Create a numpy array that contains the raster values.
893
894        if cellValue == u'center':
895            increment = cellSize / 2
896        elif cellValue == u'right':
897            increment = cellSize
898        else:
899            increment = 0
900
901        import numpy
902        values = numpy.arange(left + increment, right + increment, cellSize) * numpy.ones((rows, cols))
903
904        # Create the raster.
905
906        oldLogInfoAsDebug = Logger.LogInfoAndSetInfoToDebug(_(u'Creating X coordinate raster %(out)s...') % {u'out' : raster})
907        try:
908            try:
909                from GeoEco.DataManagement.Directories import TemporaryDirectory
910                tempDir = TemporaryDirectory()
911               
912                from GeoEco.DataManagement.ArcInfoASCIIGrids import ArcInfoASCIIGrid
913                ArcInfoASCIIGrid.FromNumpyArray(values, os.path.join(tempDir.Path, 'temp.txt'), left, bottom, cellSize)
914                ArcInfoASCIIGrid.ToArcGISRaster(os.path.join(tempDir.Path, 'temp.txt'), raster, coordinateSystem=coordinateSystem, buildPyramids=buildPyramids, overwriteExisting=overwriteExisting)
915            except:
916                Logger.LogExceptionAsError()
917                raise
918        finally:
919            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
920
921    @classmethod
922    def CreateYRaster(cls, raster, extent, cellSize, cellValue=u'Center', coordinateSystem=None, buildPyramids=False, overwriteExisting=False):
923        cls.__doc__.Obj.ValidateMethodInvocation()
924
925        # Perform additional validation.
926
927        left, bottom, right, top = EnvelopeTypeMetadata.ParseFromArcGISString(extent)
928
929        if right - left <= 0:
930            Logger.RaiseException(ValueError(_(u'The horizontal extent must be greater than zero.')))
931
932        if top - bottom <= 0:
933            Logger.RaiseException(ValueError(_(u'The vertical extent must be greater than zero.')))
934
935        if cellSize <= 0.0:
936            Logger.RaiseException(ValueError(_(u'The cell size must be greater than zero.')))
937
938        # Determine the number of rows and columns of the raster.
939
940        rows = int(math.ceil((top - bottom) / cellSize))
941        cols = int(math.ceil((right - left) / cellSize))
942
943        # Create a numpy array that contains the raster values.
944
945        if cellValue == u'center':
946            increment = cellSize / 2
947        elif cellValue == u'bottom':
948            increment = cellSize
949        else:
950            increment = 0
951
952        import numpy
953        values = numpy.arange(top - increment, bottom - increment, 0 - cellSize).reshape(rows,1) * numpy.ones((rows, cols))
954
955        # Create the raster.
956
957        oldLogInfoAsDebug = Logger.LogInfoAndSetInfoToDebug(_(u'Creating Y coordinate raster %(out)s...') % {u'out' : raster})
958        try:
959            try:
960                from GeoEco.DataManagement.Directories import TemporaryDirectory
961                tempDir = TemporaryDirectory()
962               
963                from GeoEco.DataManagement.ArcInfoASCIIGrids import ArcInfoASCIIGrid
964                ArcInfoASCIIGrid.FromNumpyArray(values, os.path.join(tempDir.Path, 'temp.txt'), left, bottom, cellSize)
965                ArcInfoASCIIGrid.ToArcGISRaster(os.path.join(tempDir.Path, 'temp.txt'), raster, coordinateSystem=coordinateSystem, buildPyramids=buildPyramids, overwriteExisting=overwriteExisting)
966            except:
967                Logger.LogExceptionAsError()
968                raise
969        finally:
970            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
971
972    @classmethod
973    def Delete(cls, raster):
974        cls.__doc__.Obj.ValidateMethodInvocation()
975        GeoprocessorManager.DeleteArcGISObject(raster, [u'rasterdataset'], _(u'ArcGIS raster'))
976
977    @classmethod
978    def DeleteTemporaryRastersThatPreventedArcGISCrash(cls, rasters):
979        cls.__doc__.Obj.ValidateMethodInvocation()
980        if len(rasters) > 0:
981            oldLogInfoAsDebug = Logger.GetLogInfoAsDebug()
982            Logger.SetLogInfoAsDebug(True)
983            try:
984                for raster in rasters:
985                    cls.Delete(raster)
986            finally:
987                Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
988
989    @classmethod
990    def Exists(cls, path):
991        cls.__doc__.Obj.ValidateMethodInvocation()
992        return GeoprocessorManager.ArcGISObjectExists(path, [u'rasterdataset'], u'ArcGIS raster')
993
994    @classmethod
995    def Find(cls, workspace, wildcard=u'*', searchTree=False, rasterType=None, basePath=None, getExtent=False, dateParsingExpression=None):
996        cls.__doc__.Obj.ValidateMethodInvocation()
997        Logger.Info(_(u'Finding ArcGIS rasters: workspace="%(workspace)s", wildcard="%(wildcard)s", searchTree=%(tree)s, rasterType="%(type)s"') % {u'workspace': workspace, u'wildcard': wildcard, u'tree': unicode(searchTree), u'type': rasterType})
998        return cls._Find(workspace,
999                         wildcard,
1000                         searchTree,
1001                         rasterType,
1002                         basePath,
1003                         getExtent,
1004                         dateParsingExpression)
1005
1006    @classmethod
1007    def _Find(cls, workspace, wildcard, searchTree, rasterType, basePath, getExtent, dateParsingExpression, searchPattern=None, strptimePattern=None):
1008
1009        # If the caller provided a dateParsingExpression, parse it into a
1010        # pattern we can pass the re.search() and a corresponding pattern we can
1011        # subsequently pass to time.strptime().
1012
1013        from GeoEco.DataManagement.Files import File       
1014
1015        if dateParsingExpression is not None and searchPattern is None:
1016            searchPattern, strptimePattern = File.ValidateDateParsingExpression(dateParsingExpression)
1017
1018        # Change the current workspace to that specified by the caller. If the
1019        # workspace hasn't been set, ArcGIS 9.2 will return None for the
1020        # workspace property, but will raise an exception if we set it to None.
1021        # To work around this screwy design, we convert None to u'', which is
1022        # what ArcGIS 9.1 returns when the workspace hasn't been set.
1023
1024        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1025        oldWorkspace = gp.Workspace
1026        if oldWorkspace is None:
1027            oldWorkspace = u''
1028        gp.Workspace = workspace
1029
1030        # Find matching rasters in the specified workspace.
1031
1032        results = []
1033
1034        if basePath is not None:
1035            os.path.normpath(basePath)
1036            baseParts = basePath.split(os.sep)
1037
1038        try:
1039            if rasterType is not None:
1040                enum = gp.ListRasters(wildcard, rasterType)
1041            else:
1042                enum = gp.ListRasters(wildcard)
1043
1044            try:
1045                raster = enum.Next()
1046                while isinstance(raster, basestring) and len(raster) > 0:
1047                    raster = os.path.join(workspace, raster)
1048
1049                    # Append the absolute path to the result row.
1050                   
1051                    Logger.Debug(_(u'Found raster %s'), raster)
1052
1053                    result = [raster]
1054
1055                    # If requested, append the relative path to the result row.
1056
1057                    if basePath is not None:
1058                        rasterParts = raster.split(os.sep)
1059                        i = 0
1060                        while i < len(baseParts) and i < len(rasterParts) and os.path.normcase(baseParts[i]) == os.path.normcase(rasterParts[i]):
1061                            i += 1
1062                        if i == 0:
1063                            result.append(raster)
1064                        else:
1065                            result.append(os.path.join(('..' + os.sep) * (len(baseParts) - i), os.sep.join(rasterParts[i:])))
1066
1067                    # If requested, append the other optional fields to the result row.
1068                       
1069                    if getExtent:
1070                        (xMin, yMin, xMax, yMax) = EnvelopeTypeMetadata.ParseFromArcGISString(gp.Describe(raster).Extent)
1071                        result.append(xMin)
1072                        result.append(yMin)
1073                        result.append(xMax)
1074                        result.append(yMax)
1075
1076                    # If requested, parse a date from the absolute path and append it
1077                    # to the result row, in both datetime and UNIX time formats.
1078
1079                    if dateParsingExpression is not None:
1080                        dateTime, unixTime = File.ParseDateFromPath(raster, dateParsingExpression, searchPattern, strptimePattern)
1081                        result.append(dateTime)
1082                        result.append(unixTime)
1083
1084                    # Append this result row to the list of results to return.
1085
1086                    results.append(result)
1087                    raster = enum.Next()
1088
1089            finally:
1090                del enum
1091
1092            # Search child workspaces, if requested.
1093            #
1094            # NOTE: The ArcGIS 9.1 geoprocessor's ListWorkspaces method does not
1095            # seem to always work for workspaces that are operating system
1096            # directories. Sometimes it seems to claim that a given directory is
1097            # empty, even though it contains subdirectories. I do not know why.
1098            # For this reason, if the current workspace is a directory, use
1099            # Python's functions instead of ListWorkspaces.
1100           
1101            if searchTree:
1102                if os.path.isdir(workspace):
1103                    for childWorkspace in os.listdir(workspace):
1104                        dataType = gp.Describe(os.path.join(workspace, childWorkspace)).DataType.lower()
1105                        if childWorkspace.lower() != u'info' and (dataType == u'workspace' or dataType == u'folder'):
1106                            results.extend(cls._Find(os.path.join(workspace, childWorkspace),
1107                                                     wildcard,
1108                                                     searchTree,
1109                                                     rasterType,
1110                                                     basePath,
1111                                                     getExtent,
1112                                                     dateParsingExpression,
1113                                                     searchPattern,
1114                                                     strptimePattern))
1115                else:
1116                    enum = gp.ListWorkspaces(u'*')
1117                    try:
1118                        childWorkspace = enum.Next()
1119                        while isinstance(childWorkspace, basestring) and len(childWorkspace) > 0:
1120                            results.extend(cls._Find(os.path.join(workspace, childWorkspace),
1121                                                     wildcard,
1122                                                     searchTree,
1123                                                     rasterType,
1124                                                     basePath,
1125                                                     getExtent,
1126                                                     dateParsingExpression,
1127                                                     searchPattern,
1128                                                     strptimePattern))
1129                            childWorkspace = enum.Next()
1130                    finally:
1131                        del enum
1132
1133        # Change the current workspace back to what it was.                   
1134
1135        finally:
1136            gp.Workspace = oldWorkspace
1137
1138        # Return successfully.
1139
1140        return results       
1141
1142    @classmethod
1143    def FindAndFillTable(cls, workspace, insertCursor, rasterField, wildcard=u'*', searchTree=False, rasterType=None, relativePathField=None, basePath=None, populateExtentFields=False, parsedDateField=None, dateParsingExpression=None, unixTimeField=None):
1144        cls.__doc__.Obj.ValidateMethodInvocation()
1145
1146        # Perform additional validation.
1147
1148        fields = [rasterField, relativePathField, parsedDateField, unixTimeField]
1149        fieldsDict = {}
1150        for f in fields:
1151            if f is not None:
1152                if fieldsDict.has_key(f.lower()):
1153                    Logger.RaiseException(ValueError(_(u'The same field "%(field)s" is specified for two different parameters. Please specify a unique field name for each parameter.') % {u'field': f}))
1154                fieldsDict[f] = True
1155
1156        if populateExtentFields:
1157            for f in fields:
1158                if f is not None:
1159                    if f.lower() in [u'xmin', u'xmax', u'ymin', u'ymax']:
1160                        Logger.RaiseException(ValueError(_(u'The field "%(field)s" is reserved for storing the raster extent. Please specify a different field name') % {u'field': f}))
1161
1162        if parsedDateField is not None and dateParsingExpression is None:
1163            Logger.RaiseException(ValueError(_(u'If you specify a field to receive parsed dates, you must also specify a date parsing expression.')))
1164
1165        if unixTimeField is not None and dateParsingExpression is None:
1166            Logger.RaiseException(ValueError(_(u'If you specify a field to receive UNIX times, you must also specify a date parsing expression.')))
1167
1168        if relativePathField is None:
1169            basePath = None
1170
1171        # Find the rasters.
1172
1173        Logger.Info(_(u'Finding ArcGIS rasters and inserting rows into table "%(table)s": workspace="%(workspace)s", wildcard="%(wildcard)s", searchTree=%(tree)s, rasterType="%(type)s"') % {u'table': insertCursor.Table, u'workspace': workspace, u'wildcard': wildcard, u'tree': unicode(searchTree), u'type': rasterType})
1174        results = cls._Find(workspace,
1175                            wildcard,
1176                            searchTree,
1177                            rasterType,
1178                            basePath,
1179                            populateExtentFields,
1180                            dateParsingExpression)
1181
1182        # Insert the rows.
1183
1184        if len(results) > 0:
1185            insertCursor.SetRowCount(len(results))
1186
1187            for result in results:
1188                value = result.pop(0)
1189                insertCursor.SetValue(rasterField, value)
1190
1191                if relativePathField is not None:
1192                    value = result.pop(0)
1193                    insertCursor.SetValue(relativePathField, value)
1194
1195                if populateExtentFields:
1196                    value = result.pop(0)
1197                    insertCursor.SetValue(u'XMin', value)
1198                    value = result.pop(0)
1199                    insertCursor.SetValue(u'YMin', value)
1200                    value = result.pop(0)
1201                    insertCursor.SetValue(u'XMax', value)
1202                    value = result.pop(0)
1203                    insertCursor.SetValue(u'YMax', value)
1204
1205                if parsedDateField is not None or unixTimeField is not None:
1206                    value = result.pop(0)
1207                    if parsedDateField is not None:
1208                        insertCursor.SetValue(parsedDateField, value)
1209
1210                    value = result.pop(0)
1211                    if unixTimeField is not None:
1212                        insertCursor.SetValue(unixTimeField, value)
1213
1214                insertCursor.InsertRow()
1215
1216    @classmethod
1217    def FindAndCreateTable(cls, workspace, connection, table, rasterField, wildcard=u'*', searchTree=False, rasterType=None, relativePathField=None, basePath=None, populateExtentFields=False, parsedDateField=None, dateParsingExpression=None, unixTimeField=None, pathFieldsDataType=u'TEXT', extentFieldsDataType=u'DOUBLE', dateFieldsDataType=u'DATE', unixTimeFieldDataType=u'INT', maxPathLength=255, overwriteExisting=False):
1218        cls.__doc__.Obj.ValidateMethodInvocation()
1219
1220        # Perform additional validation.
1221
1222        fields = [rasterField, relativePathField, parsedDateField, unixTimeField]
1223        fieldsDict = {}
1224        for f in fields:
1225            if f is not None:
1226                if fieldsDict.has_key(f.lower()):
1227                    Logger.RaiseException(ValueError(_(u'The same field "%(field)s" is specified for two different parameters. Please specify a unique field name for each parameter.') % {u'field': f}))
1228                fieldsDict[f] = True
1229
1230        if populateExtentFields:
1231            for f in fields:
1232                if f is not None:
1233                    if f.lower() in [u'xmin', u'xmax', u'ymin', u'ymax']:
1234                        Logger.RaiseException(ValueError(_(u'The field "%(field)s" is reserved for storing the raster extent. Please specify a different field name') % {u'field': f}))
1235
1236        if parsedDateField is not None and dateParsingExpression is None:
1237            Logger.RaiseException(ValueError(_(u'If you specify a field to receive parsed dates, you must also specify a date parsing expression.')))
1238
1239        if unixTimeField is not None and dateParsingExpression is None:
1240            Logger.RaiseException(ValueError(_(u'If you specify a field to receive UNIX times, you must also specify a date parsing expression.')))
1241
1242        if relativePathField is None:
1243            basePath = None
1244
1245        # If requested, delete the table if it already exists.
1246       
1247        if connection.TableExists(table):
1248            if overwriteExisting:
1249                connection.DeleteTable(table)
1250            else:
1251                Logger.RaiseException(ValueError(_(u'Cannot create table %s because it already exists.') % table))
1252
1253        # Create the table and add the fields.
1254
1255        table = connection.CreateTable(table)
1256       
1257        try:
1258            if not connection.FieldLengthSupported:
1259                maxPathLength = None
1260            rasterField = connection.AddField(table, rasterField, pathFieldsDataType, length=maxPathLength)
1261
1262            if relativePathField is not None:
1263                relativePathFIeld = connection.AddField(table, relativePathField, pathFieldsDataType, length=maxPathLength)
1264
1265            if populateExtentFields:
1266                connection.AddField(table, u'XMin', extentFieldsDataType)
1267                connection.AddField(table, u'YMin', extentFieldsDataType)
1268                connection.AddField(table, u'XMax', extentFieldsDataType)
1269                connection.AddField(table, u'YMax', extentFieldsDataType)
1270
1271            if parsedDateField is not None:
1272                parsedDateField = connection.AddField(table, parsedDateField, dateFieldsDataType)
1273
1274            if unixTimeField is not None:
1275                unixTimeField = connection.AddField(table, unixTimeField, unixTimeFieldDataType)
1276
1277            # Create an insert cursor and fill the table.
1278
1279            cursor = connection.OpenInsertCursor(table)
1280            try:
1281                cls.FindAndFillTable(workspace,
1282                                     cursor,
1283                                     rasterField,
1284                                     wildcard,
1285                                     searchTree,
1286                                     rasterType,
1287                                     relativePathField,
1288                                     basePath,
1289                                     populateExtentFields,
1290                                     parsedDateField,
1291                                     dateParsingExpression,
1292                                     unixTimeField)
1293            finally:
1294                del cursor
1295
1296        # If an exception was raised, delete the table.
1297       
1298        except:
1299            try:
1300                connection.DeleteTable(table)
1301            except:
1302                pass
1303            raise
1304
1305        # Return successfully.
1306
1307        return table       
1308
1309    @classmethod
1310    def FindAndCreateArcGISTable(cls, inputWorkspace, outputWorkspace, table, rasterField=u'Image', wildcard=u'*', searchTree=False, rasterType=None, relativePathField=None, populateExtentFields=True, parsedDateField=None, dateParsingExpression=None, unixTimeField=None, maxPathLength=255, overwriteExisting=False):
1311        cls.__doc__.Obj.ValidateMethodInvocation()
1312
1313        # If the caller's output workspace is a directory (rather than a database),
1314        # the geoprocessor's CreateTable tool will create a DBF table,
1315        # regardless of what file extension the caller placed on the table. Even
1316        # if the caller's extension is .csv or .txt, the geoprocessor will
1317        # replace it with .dbf. If the caller does not provide an extension, the
1318        # geoprocessor will tack on .dbf.
1319        #
1320        # Because we know the geoprocessor will do this, we do it here
1321        # preemptively, so we can check for and delete the existing table, if
1322        # desired by the caller.
1323
1324        if os.path.isdir(outputWorkspace) and not table.lower().endswith(u'.dbf'):
1325            if table.find(u'.') >= 0:
1326                newTable = table[:table.find(u'.')] + u'.dbf'
1327                Logger.Warning(u'When creating tables in the file system, the ArcGIS CreateTable tool ignores the extension you specify and always creates a dBASE table with the extension .dbf. It will create the table %(new)s even though you asked for %(old)s.' % {u'new': newTable, u'old': table})
1328            else:
1329                newTable = table + u'.dbf'
1330                Logger.Warning(u'The ArcGIS CreateTable tool always creates dBASE tables in the file system. Even though you did not specify a file extension for your table, .dbf will be used.')
1331            table = newTable
1332
1333        # Create the table.
1334       
1335        connection = ArcGIS91DatabaseConnection()
1336        table = cls.FindAndCreateTable(inputWorkspace,
1337                                       connection,
1338                                       os.path.normpath(os.path.join(outputWorkspace, table)),
1339                                       rasterField,
1340                                       wildcard,
1341                                       searchTree,
1342                                       rasterType,
1343                                       relativePathField,
1344                                       outputWorkspace,
1345                                       populateExtentFields,
1346                                       parsedDateField,
1347                                       dateParsingExpression,
1348                                       unixTimeField,
1349                                       u'TEXT',
1350                                       u'DOUBLE',
1351                                       u'DATE',
1352                                       u'LONG',
1353                                       maxPathLength,
1354                                       overwriteExisting)
1355
1356        # If it is a DBF table, delete the Field1 field. ArcGIS always creates
1357        # this field because, according to the documentation, DBF files must
1358        # always have at least one field, and it is not possible to give a field
1359        # to the geoprocessor's CreateTable tool. Also delete the M_S_O_F_T
1360        # field if it exists; this is created by the Microsoft ODBC dBASE
1361        # driver, which ArcGIS could conceivably use in the future.
1362       
1363        if table.lower().endswith(u'.dbf'):
1364            if connection.FieldExists(table, u'Field1'):
1365                connection.DeleteField(table, u'Field1')
1366            if connection.FieldExists(table, u'M_S_O_F_T'):
1367                connection.DeleteField(table, u'M_S_O_F_T')
1368
1369        # Return successfully.
1370       
1371        return table
1372
1373    @classmethod
1374    def Move(cls, sourceRaster, destinationRaster, overwriteExisting=False):
1375        cls.__doc__.Obj.ValidateMethodInvocation()
1376        oldLogInfoAsDebug = Logger.LogInfoAndSetInfoToDebug(_(u'Moving ArcGIS raster %(in)s to %(out)s...') % {u'in' : sourceRaster, u'out' : destinationRaster})
1377        try:
1378            try:
1379                cls._Copy(sourceRaster, destinationRaster)
1380                GeoprocessorManager.DeleteArcGISObject(sourceRaster, [u'rasterdataset'], _(u'ArcGIS raster'))
1381            except:
1382                Logger.LogExceptionAsError(_(u'Could not move ArcGIS raster %(source)s to %(dest)s') % {u'source' :  sourceRaster, u'dest' : destinationRaster})
1383                raise
1384        finally:
1385            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
1386
1387    @classmethod
1388    def MoveSilent(cls, sourceRaster, destinationRaster, overwriteExisting=False):
1389        oldLogInfoAsDebug = Logger.GetLogInfoAsDebug()
1390        Logger.SetLogInfoAsDebug(True)
1391        try:
1392            cls.Move(sourceRaster, destinationRaster, overwriteExisting)
1393        finally:
1394            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
1395
1396    @classmethod
1397    def FromNumpyArray(cls, numpyArray, raster, xLowerLeftCorner, yLowerLeftCorner, cellSize, nodataValue=None, coordinateSystem=None, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingRectangle=None, mapAlgebraExpression=None, buildPyramids=False, overwriteExisting=False):
1398        #cls.__doc__.Obj.ValidateMethodInvocation()
1399        oldLogInfoAsDebug = Logger.LogInfoAndSetInfoToDebug(_(u'Creating ArcGIS raster %(out)s...') % {u'out' : raster})
1400        try:
1401            try:
1402                from GeoEco.DataManagement.Directories import TemporaryDirectory
1403                tempDir = TemporaryDirectory()
1404
1405                asciiFile = os.path.join(tempDir.Path, 'temp.txt')
1406                Logger.Debug(_(u'Writing ArcInfo ASCII Grid file %(out)s') % {u'out' : asciiFile})
1407
1408                from GeoEco.Dependencies import ImportNumpyDependentExtensionModule
1409
1410                ArcInfoASCIIGridUtils = ImportNumpyDependentExtensionModule('GeoEco.DataManagement.ArcInfoASCIIGridUtils')
1411                if nodataValue is not None:
1412                    ArcInfoASCIIGridUtils.NumpyArrayToArcInfoASCIIGrid(numpyArray, str(asciiFile), numpyArray.shape[1], numpyArray.shape[0], xLowerLeftCorner, yLowerLeftCorner, cellSize, 1, nodataValue)
1413                else:
1414                    ArcInfoASCIIGridUtils.NumpyArrayToArcInfoASCIIGrid(numpyArray, str(asciiFile), numpyArray.shape[1], numpyArray.shape[0], xLowerLeftCorner, yLowerLeftCorner, cellSize)
1415               
1416                from GeoEco.DataManagement.ArcInfoASCIIGrids import ArcInfoASCIIGrid
1417                ArcInfoASCIIGrid.ToArcGISRaster(asciiFile, raster, isInteger=numpyArray.dtype.kind=='i', coordinateSystem=coordinateSystem, projectedCoordinateSystem=projectedCoordinateSystem, geographicTransformation=geographicTransformation, resamplingTechnique=resamplingTechnique, projectedCellSize=projectedCellSize, registrationPoint=registrationPoint, clippingRectangle=clippingRectangle, mapAlgebraExpression=mapAlgebraExpression, buildPyramids=buildPyramids, overwriteExisting=overwriteExisting)
1418            except:
1419                Logger.LogExceptionAsError()
1420                raise
1421        finally:
1422            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
1423
1424    @classmethod
1425    def ToNumpyArray(cls, raster, band=1, tempRasterPath=None):
1426        cls.__doc__.Obj.ValidateMethodInvocation()
1427        oldLogInfoAsDebug = Logger.GetLogInfoAsDebug()
1428        Logger.SetLogInfoAsDebug(True)
1429        try:
1430            try:
1431                gp = GeoprocessorManager.GetWrappedGeoprocessor()
1432
1433                # If the raster does not exist on disk (e.g. it is in a
1434                # geodatabase), copy it to a temporary location.
1435               
1436                if os.path.exists(raster):
1437                    tempRasterPath = raster
1438                else:
1439
1440                    # If the caller did not provide a temp raster
1441                    # path, create a temp directory.
1442                   
1443                    if tempRasterPath is None:
1444                        from GeoEco.DataManagement.Directories import TemporaryDirectory
1445                        tempDir = TemporaryDirectory()
1446                        tempRasterPath = os.path.join(tempDir.Path, u'raster')
1447
1448                    # Copy the raster to the temp path.
1449
1450                    Logger.Debug(_(u'Copying ArcGIS raster %(in)s to %(out)s...') % {u'in' : raster, u'out' : tempRasterPath})
1451                    cls._Copy(raster, tempRasterPath)
1452
1453                # Use GDAL to read the raster into a numpy array.
1454
1455                from GeoEco.Dependencies import ImportGDALModule, SetGDALDataEnvVar, ResetGDALDataEnvVar
1456
1457                gdal = ImportGDALModule('osgeo.gdal')
1458                gdalconst = ImportGDALModule('osgeo.gdalconst')
1459
1460                SetGDALDataEnvVar()
1461                try:
1462                    Logger.Debug(_(u'Reading raster %(raster)s into memory...') % {u'raster': tempRasterPath})
1463                    ds = gdal.Open(str(tempRasterPath), gdalconst.GA_ReadOnly)
1464                    b = ds.GetRasterBand(1)
1465                    a = b.ReadAsArray()
1466                finally:
1467                    ResetGDALDataEnvVar()
1468
1469                # For integer rasters, sometimes GDAL appears to read
1470                # the raster as a data type that does not match the
1471                # raster's data type. For example, I have seen it read
1472                # a uint16 raster as int32. Other times, ArcGIS does
1473                # not seem to use the most compact pixel data type.
1474                # For example, a raster that contains values from 0 to
1475                # 65535 with no NODATA value will be stored as int32
1476                # rather than uint16. Both of these situations cause
1477                # problems for callers that expect the data to be in
1478                # the most compact type. To avoid these problems,
1479                # explicitly cast the numpy array to the most compact
1480                # type. This may cause us to change the NODATA value
1481                # from what ArcGIS is using, but it should not affect
1482                # our callers.
1483
1484                noDataValue = b.GetNoDataValue()       # On ArcGIS 9.1 sp2, gp.Describe(tempRasterPath).NoDataValue crashes Python, so we use this instead
1485               
1486                if gp.Describe(tempRasterPath).IsInteger:
1487                    if noDataValue is not None:
1488                        noDataValue = int(noDataValue)
1489                       
1490                    minValue = int(b.GetMinimum())
1491                    maxValue = int(b.GetMaximum())
1492                    valueRange = maxValue - minValue + 1
1493
1494                    import numpy                   
1495                   
1496                    if minValue >= -128 and maxValue <= 127:
1497                        if a.dtype.name != 'int8':
1498                            if valueRange < 256:
1499                                if minValue > -128:
1500                                    a[a == noDataValue] = -128
1501                                    a = numpy.cast['int8'](a)
1502                                    noDataValue = -128
1503                                else:
1504                                    a[a == noDataValue] = 127
1505                                    a = numpy.cast['int8'](a)
1506                                    noDataValue = 127
1507                            elif not numpy.sometrue(a == noDataValue):
1508                                a = numpy.cast['int8'](a)
1509                                noDataValue = None
1510                   
1511                    elif minValue >= 0 and maxValue <= 255:
1512                        if a.dtype.name != 'uint8':
1513                            if valueRange < 256:
1514                                if minValue > 0:
1515                                    a[a == noDataValue] = 0
1516                                    a = numpy.cast['uint8'](a)
1517                                    noDataValue = 0
1518                                else:
1519                                    a[a == noDataValue] = 255
1520                                    a = numpy.cast['uint8'](a)
1521                                    noDataValue = 255
1522                            elif not numpy.sometrue(a == noDataValue):
1523                                a = numpy.cast['uint8'](a)
1524                                noDataValue = None
1525                   
1526                    elif minValue >= -32768 and maxValue <= 32767:
1527                        if a.dtype.name != 'int16':
1528                            if valueRange < 65536:
1529                                if minValue > -32768:
1530                                    a[a == noDataValue] = -32768
1531                                    a = numpy.cast['int16'](a)
1532                                    noDataValue = -32768
1533                                else:
1534                                    a[a == noDataValue] = 32767
1535                                    a = numpy.cast['int16'](a)
1536                                    noDataValue = 32767
1537                            elif not numpy.sometrue(a == noDataValue):
1538                                a = numpy.cast['int16'](a)
1539                                noDataValue = None
1540                   
1541                    elif minValue >= 0 and maxValue <= 65535:
1542                        if a.dtype.name != 'uint16':
1543                            if valueRange < 65536:
1544                                if minValue > 0:
1545                                    a[a == noDataValue] = 0
1546                                    a = numpy.cast['uint16'](a)
1547                                    noDataValue = 0
1548                                else:
1549                                    a[a == noDataValue] = 65535
1550                                    a = numpy.cast['uint16'](a)
1551                                    noDataValue = 65535
1552                            elif not numpy.sometrue(a == noDataValue):
1553                                a = numpy.cast['uint16'](a)
1554                                noDataValue = None
1555
1556                # Return successfully.
1557
1558                return a, noDataValue
1559               
1560            except:
1561                Logger.LogExceptionAsError()
1562                raise
1563        finally:
1564            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
1565
1566    @classmethod
1567    def ExtractByMask(cls, inputRaster, mask, outputRaster, overwriteExisting=False):
1568        cls.__doc__.Obj.ValidateMethodInvocation()
1569        try:
1570            gp = GeoprocessorManager.GetWrappedGeoprocessor()
1571            gp.ExtractByMask_sa(inputRaster, mask, outputRaster)
1572        except:
1573            Logger.LogExceptionAsError()
1574            raise
1575
1576    @classmethod
1577    def ProjectClipAndOrExecuteMapAlgebra(cls, inputRaster, outputRaster, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingDataset=None, clippingRectangle=None, mapAlgebraExpression=None, buildPyramids=False, overwriteExisting=False):
1578        cls.__doc__.Obj.ValidateMethodInvocation()
1579        cls._ValidateProjectClipAndOrExecuteMapAlgebraParameters(projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingDataset, clippingRectangle, mapAlgebraExpression)
1580        Logger.Info(_(u'Processing ArcGIS raster %(in)s into raster %(out)s...') % {u'in' : inputRaster, u'out' : outputRaster})
1581        try:
1582            from GeoEco.DataManagement.Directories import TemporaryDirectory
1583            tempDir = TemporaryDirectory()
1584           
1585            outputRasterTemp = cls._ProjectClipAndOrExecuteMapAlgebraInTempDir(inputRaster, tempDir.Path,
1586                                                                               projectedCoordinateSystem=projectedCoordinateSystem,
1587                                                                               geographicTransformation=geographicTransformation,
1588                                                                               resamplingTechnique=resamplingTechnique,
1589                                                                               projectedCellSize=projectedCellSize,
1590                                                                               registrationPoint=registrationPoint,
1591                                                                               clippingDataset=clippingDataset,
1592                                                                               clippingRectangle=clippingRectangle,
1593                                                                               mapAlgebraExpression=mapAlgebraExpression,
1594                                                                               buildPyramids=buildPyramids)
1595           
1596            cls.MoveSilent(outputRasterTemp, outputRaster, overwriteExisting=overwriteExisting)
1597        except:
1598            Logger.LogExceptionAsError()
1599            raise
1600
1601    @classmethod
1602    def _ValidateProjectClipAndOrExecuteMapAlgebraParameters(cls, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingDataset=None, clippingRectangle=None, mapAlgebraExpression=None):
1603        if projectedCoordinateSystem is None and clippingDataset is None and clippingRectangle is None and mapAlgebraExpression is None:
1604            Logger.RaiseException(ValueError(_(u'You did not specify a projected coordinate system, clipping dataset/rectangle, or map algebra expression. To use this tool, you must specify at least one of these three parameters.')))
1605        if projectedCoordinateSystem is not None and resamplingTechnique is None:
1606            Logger.RaiseException(ValueError(_(u'To project the converted raster to a new coordinate system, you must specify the resampling technique.')))
1607        if clippingDataset is not None and clippingRectangle is not None:
1608            Logger.RaiseException(ValueError(_(u'You cannot specify both a dataset for clipping and a rectangle for clipping. Please specify just one of these parameters.')))
1609        if projectedCoordinateSystem is None and geographicTransformation is not None:
1610            Logger.Warning(_(u'The geographic transformation will be ignored because no projected coordinate system was specified.'))
1611        if projectedCoordinateSystem is None and resamplingTechnique is not None:
1612            Logger.Warning(_(u'The resampling technique will be ignored because no projected coordinate system was specified.'))
1613        if projectedCoordinateSystem is None and projectedCellSize is not None:
1614            Logger.Warning(_(u'The projected cell size will be ignored because no projected coordinate system was specified.'))
1615        if projectedCoordinateSystem is None and registrationPoint is not None:
1616            Logger.Warning(_(u'The registration point will be ignored because no projected coordinate system was specified.'))
1617
1618    @classmethod
1619    def _ProjectClipAndOrExecuteMapAlgebraInTempDir(cls, inputRaster, tempDir, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingDataset=None, clippingRectangle=None, mapAlgebraExpression=None, buildPyramids=False, overwriteExisting=False):
1620        import tempfile
1621       
1622        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1623        outputRaster = inputRaster
1624
1625        # Project the raster, if requested.
1626       
1627        if projectedCoordinateSystem is not None:
1628            outputRaster = None
1629            while outputRaster is None or '-' in outputRaster:      # Python mktemp can generate a name that includes a - character, which is illegal in ArcInfo Binary Grid names.
1630                outputRaster = tempfile.mktemp(dir=tempDir)
1631               
1632            Logger.Debug(_(u'Projecting...'))
1633            if geographicTransformation is not None or registrationPoint is not None:
1634                gp.ProjectRaster_Management(inputRaster, outputRaster, projectedCoordinateSystem, resamplingTechnique, projectedCellSize, geographicTransformation, registrationPoint)
1635            else:
1636                gp.ProjectRaster_Management(inputRaster, outputRaster, projectedCoordinateSystem, resamplingTechnique, projectedCellSize)
1637
1638            inputRaster = outputRaster
1639
1640        # Clip the raster, if requested.
1641
1642        if clippingDataset is not None or clippingRectangle is not None:
1643            outputRaster = None
1644            while outputRaster is None or '-' in outputRaster:      # Python mktemp can generate a name that includes a - character, which is illegal in ArcInfo Binary Grid names.
1645                outputRaster = tempfile.mktemp(dir=tempDir)
1646
1647            Logger.Debug(_(u'Clipping...'))
1648
1649            # If the caller provided a clipping dataset, get its
1650            # extent and use that as the clipping rectangle.
1651
1652            if clippingDataset is not None:
1653                clippingRectangle = gp.Describe(clippingDataset).Extent
1654                if not isinstance(clippingRectangle, basestring) or len(clippingRectangle) <= 0:
1655                    Logger.RaiseException(ValueError(_(u'Cannot clip to the extent of dataset %(ds)s because ArcGIS cannot determine the extent of this dataset. Please select a different dataset or use the clipping rectangle parameter instead. Error details: gp.Describe(%(reprds)s).Extent returned None or an empty string.') % {'ds': clippingDataset, 'reprds': repr(clippingDataset)}))
1656
1657            # If this is ArcGIS 9.2, pass inputRaster for the
1658            # in_template_dataset parameter, to work around the 9.2
1659            # bug described in
1660            # http://forums.esri.com/Thread.asp?c=93&f=1729&t=230897&mc=11.
1661
1662            if GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() == 2:
1663                gp.Clip_Management(inputRaster, clippingRectangle, outputRaster, inputRaster)
1664            else:
1665                gp.Clip_Management(inputRaster, clippingRectangle, outputRaster)
1666            inputRaster = outputRaster
1667
1668        # Execute map algebra, if requested.
1669
1670        if mapAlgebraExpression is not None:
1671
1672            # Replace all occurences of the string "inputRaster" in
1673            # the mapAlgebraExpression with the value of the
1674            # inputRaster variable.
1675
1676            if GeoprocessorManager.GetArcGISMajorVersion() >= 10:
1677                (mapAlgebraExpressionToExecute, numberOfReplacements) = re.subn(u'(?<!\w)(inputRaster)(?=$|\W)', lambda s: u' [' + inputRaster + u'] ', mapAlgebraExpression)
1678            else:
1679                (mapAlgebraExpressionToExecute, numberOfReplacements) = re.subn(u'(?<!\w)(inputRaster)(?=$|\W)', lambda s: u' ' + inputRaster + u' ', mapAlgebraExpression)
1680            if numberOfReplacements <= 0:
1681                Logger.RaiseException(ValueError(_(u'The map algebra expression must include the case-sensitive string "inputRaster".')))
1682            if len(mapAlgebraExpressionToExecute) > 4000:
1683                Logger.RaiseException(ValueError(_(u'The map algebra expression is too long for the Spatial Analyst Single Output Map Algebra tool to execute. It must be no longer than 4000 characters.')))
1684
1685            # Execute the map algebra expression.
1686           
1687            Logger.Debug(_(u'Executing map algebra...'))
1688
1689            outputRaster = None
1690            while outputRaster is None or '-' in outputRaster:      # Python mktemp can generate a name that includes a - character, which is illegal in ArcInfo Binary Grid names.
1691                outputRaster = tempfile.mktemp(dir=tempDir)
1692
1693            gp.SingleOutputMapAlgebra_sa(mapAlgebraExpressionToExecute, outputRaster)
1694            gp.RefreshCatalog(tempDir)
1695
1696            # Sometimes the Single Output Map Algebra tool in
1697            # ArcGIS 9.1 strips the projection information,
1698            # causing the spatial reference to be displayed as
1699            # "<Undefined>" in ArcCatalog. Handle this ArcGIS
1700            # bug by defining the projection again. See MGET
1701            # ticket #156 for more information.
1702
1703            if GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() == 1:
1704                Logger.Debug(_(u'Defining the projection again, to work around the ArcGIS 9.1 bug described in MGET ticket #156...'))
1705                if projectedCoordinateSystem is not None:
1706                    gp.DefineProjection_Management(outputRaster, projectedCoordinateSystem)     # When we already know what the coordinate system should be, don't look it up
1707                else:
1708                    gp.DefineProjection_Management(outputRaster, gp.Describe(inputRaster).SpatialReference)
1709
1710        # Build pyramids, if requested.
1711
1712        if buildPyramids:
1713            Logger.Debug(_(u'Building pyramids...'))
1714            gp.BuildPyramids_Management(outputRaster)
1715
1716        # Return the path to the last raster we created in the temp
1717        # directory.
1718
1719        return outputRaster
1720
1721    @classmethod
1722    def ProjectToTemplate(cls, inputRaster, templateRaster, outputRaster, resamplingTechnique, interpolationMethod=None, maxHoleSize=None, mask=False, overwriteExisting=False):
1723        try:
1724            # Perform additional validation.
1725
1726            if interpolationMethod is not None and resamplingTechnique.lower() not in [u'bilinear', u'cubic']:
1727                raise ValueError(_(u'Values cannot be interpolated for No Data cells if the NEAREST or MAJORITY resampling technique is used. Please select the BILINEAR or CUBIC resampling technique instead.'))
1728
1729            # Look up the coordinate system, extent, and cell size of
1730            # the template raster.
1731
1732            gp = GeoprocessorManager.GetWrappedGeoprocessor()
1733            d = gp.Describe(templateRaster)
1734            coordinateSystem = gp.CreateSpatialReference(d.SpatialReference).split(';')[0]
1735            extent = d.Extent
1736            cellSize = d.MeanCellWidth
1737           
1738            # Below, we will set the Extent environment variable and
1739            # then call ArcGIS's ProjectRaster_management to
1740            # simultaneously project and clip the input raster to the
1741            # coordinate system, extent, and cell size of the template
1742            # raster. Unfortunately ProjectRaster_management will not
1743            # necessarily create a raster that has exactly the desired
1744            # extent. It may be one cell larger or smaller in any of
1745            # the four directions. Different versions of ArcGIS seem
1746            # to work differently in this respect.
1747            #
1748            # To deal with this annoyance, we will expand the extent
1749            # in all four directions by 10 cells--guaranteeing that we
1750            # have a raster that is larger than the desired
1751            # extent--and then use ExtractByMask_sa to obtain a raster
1752            # of the desired extent.
1753            #
1754            # We use 10 cells rather than 1 cell because of a
1755            # different problem: if the caller requested that we
1756            # interpolate values for No Data cells, the most accurate
1757            # values can be obtained if each No Data region is
1758            # completely surrounded by cells with data. In the event
1759            # that the template raster extent bisects a No Data
1760            # region, the 10 cell buffer increases the chance that we
1761            # will interpolate that region using cells from both sides
1762            # of the extent line: the side that is within the template
1763            # extent and also the side that is outside the extent but
1764            # within the buffer.
1765
1766            from GeoEco.DataManagement.Directories import TemporaryDirectory
1767            tempDir = TemporaryDirectory()
1768
1769            [left, bottom, right, top] = EnvelopeTypeMetadata.ParseFromArcGISString(extent)
1770            oldExtent = gp.Extent
1771            gp.Extent = '%r %r %r %r' % (left - cellSize*10, bottom - cellSize*10, right + cellSize*10, top + cellSize*10)
1772
1773            try:
1774                # If this is ArcGIS 9.3, set the SnapRaster
1775                # environment variable to the template raster.
1776               
1777                if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 3:
1778                    oldSnapRaster = gp.SnapRaster
1779                    gp.SnapRaster = templateRaster
1780
1781                # Project the raster. If this is ArcGIS 9.3 or later,
1782                # the SnapRaster and Extent environment variables will
1783                # ensure the projected cells are snapped and clipped
1784                # as requested by the caller. If it is 9.2, use the
1785                # Registration_Point parameter instead of SnapRaster,
1786                # which did not exist in 9.2 (there was something like
1787                # it, but it did not work correctly).
1788
1789                try:
1790                    projectedRaster = os.path.join(tempDir.Path, u'projected.img')
1791                    if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 3:
1792                        gp.ProjectRaster_management(inputRaster, projectedRaster, coordinateSystem, resamplingTechnique, cellSize)
1793                    else:
1794                        gp.ProjectRaster_management(inputRaster, projectedRaster, coordinateSystem, resamplingTechnique, cellSize, None, extent.rsplit(' ', 2)[0])
1795
1796                # If this is ArcGIS 9.3, reset the SnapRaster
1797                # environment variable to what it was before.
1798               
1799                finally:
1800                    if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 3:
1801                        gp.SnapRaster = oldSnapRaster
1802
1803            # Reset the Extent ArcGIS environment variable to what it
1804            # was before.
1805           
1806            finally:
1807                gp.Extent = oldExtent
1808
1809            # If the caller requested that we interpolate values for
1810            # No Data regions, do it now.
1811
1812            if interpolationMethod is not None:
1813                from GeoEco.SpatialAnalysis.Interpolation import Interpolator
1814                infilledRaster = os.path.join(tempDir.Path, u'infilled.img')
1815                Interpolator.InpaintArcGISRaster(projectedRaster, infilledRaster, interpolationMethod, maxHoleSize)
1816                projectedRaster = infilledRaster
1817
1818            # We are about to use ExtractByMask_sa to extract a raster
1819            # of the desired extent from the projected raster in the
1820            # temp directory. But ExtractByMask_sa also has a side
1821            # effect that we might not want: it sets cells that are No
1822            # Data in the mask to No Data in the output raster. If the
1823            # caller did not request that to happen (using the
1824            # template raster as the mask), create a constant raster
1825            # that has the same coordinate system, extent, and cell
1826            # size as the template raster. We'll use it instead.
1827
1828            if not mask:
1829                oldOutputCoordinateSystem = gp.OutputCoordinateSystem
1830                gp.OutputCoordinateSystem = coordinateSystem
1831                try:
1832                    maskRaster = os.path.join(tempDir.Path, u'constant.img')
1833                    gp.CreateConstantRaster_sa(maskRaster, 0, 'INTEGER', cellSize, extent)
1834                finally:
1835                    gp.OutputCoordinateSystem = oldOutputCoordinateSystem
1836
1837                # For safety, verify that the output raster has the
1838                # expected number of columns and rows.
1839               
1840                d2 = gp.Describe(maskRaster)
1841                if d2.Width != d.Width or d2.Height != d.Height:
1842                    raise RuntimeError(_(u'Programming error in this tool: the constant raster does not have the same number of rows or columns as the template raster. Please contact the author of this tool for assistance.'))
1843
1844            else:
1845                maskRaster = templateRaster
1846
1847            # Extract the raster.
1848
1849            gp.ExtractByMask_sa(projectedRaster, maskRaster, outputRaster)
1850
1851        except:
1852            Logger.LogExceptionAsError()
1853            raise
1854
1855    @classmethod
1856    def ToPolygons(cls, inputRaster, outputFeatureClass, simplify=True, field=None, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingDataset=None, clippingRectangle=None, mapAlgebraExpression=None, overwriteExisting=False):
1857        cls.__doc__.Obj.ValidateMethodInvocation()
1858       
1859        # Perform additional validation.
1860
1861        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1862        if mapAlgebraExpression is None and gp.Describe(inputRaster).PixelType.upper() not in ['U1', 'U2', 'U4', 'S8', 'U8', 'S16', 'U16', 'S32', 'U32', 'S64', 'U64']:
1863            Logger.RaiseException(RuntimeError(_(u'The input raster %(in)s is a floating-point raster. Only integer rasters can be converted to polygons. Please specify an integer raster or provide a map algebra expression that converts this one to an integer raster.') % {u'in': inputRaster}))
1864       
1865        Logger.Info(_(u'Converting ArcGIS raster %(in)s to polygon feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1866        try:
1867            # Perform requested pre-conversion processing in a temp
1868            # directory.
1869           
1870            if projectedCoordinateSystem is not None or clippingRectangle is not None or mapAlgebraExpression is not None:
1871                cls._ValidateProjectClipAndOrExecuteMapAlgebraParameters(projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingDataset, clippingRectangle, mapAlgebraExpression)
1872                from GeoEco.DataManagement.Directories import TemporaryDirectory
1873                tempDir = TemporaryDirectory()
1874                inputRaster = cls._ProjectClipAndOrExecuteMapAlgebraInTempDir(inputRaster, tempDir.Path,
1875                                                                              projectedCoordinateSystem=projectedCoordinateSystem,
1876                                                                              geographicTransformation=geographicTransformation,
1877                                                                              resamplingTechnique=resamplingTechnique,
1878                                                                              projectedCellSize=projectedCellSize,
1879                                                                              registrationPoint=registrationPoint,
1880                                                                              clippingDataset=clippingDataset,
1881                                                                              clippingRectangle=clippingRectangle,
1882                                                                              mapAlgebraExpression=mapAlgebraExpression)
1883
1884                if mapAlgebraExpression is not None and gp.Describe(inputRaster).PixelType.upper() not in ['U1', 'U2', 'U4', 'S8', 'U8', 'S16', 'U16', 'S32', 'U32', 'S64', 'U64']:
1885                    Logger.RaiseException(RuntimeError(_(u'The map algebra expression yielded a floating-point raster. Only integer rasters can be converted to polygons. Please provide a map algebra expression that yields an integer raster.')))
1886
1887            # Convert the raster to a polygon feature class.
1888           
1889            if simplify:
1890                gp.RasterToPolygon_conversion(inputRaster, outputFeatureClass, 'SIMPLIFY', field)
1891            else:
1892                gp.RasterToPolygon_conversion(inputRaster, outputFeatureClass, 'NO_SIMPLIFY', field)
1893
1894        except:
1895            Logger.LogExceptionAsError()
1896            raise
1897
1898    @classmethod
1899    def ToPolygonOutlines(cls, inputRaster, outputFeatureClass, simplify=True, field=None, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingDataset=None, clippingRectangle=None, mapAlgebraExpression=None, overwriteExisting=False):
1900        cls.__doc__.Obj.ValidateMethodInvocation()
1901        oldLogInfoAsDebug = Logger.LogInfoAndSetInfoToDebug(_(u'Converting ArcGIS raster %(in)s to outlines in line feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1902        try:
1903            try:
1904                # Convert the raster to a polygon feature class in a
1905                # temporary directory.
1906               
1907                from GeoEco.DataManagement.Directories import TemporaryDirectory
1908                tempDir = TemporaryDirectory()
1909                tempFeatureClass = os.path.join(tempDir.Path, u'polygons.shp')
1910                cls.ToPolygons(inputRaster,
1911                               tempFeatureClass,
1912                               simplify=simplify,
1913                               field=field,
1914                               projectedCoordinateSystem=projectedCoordinateSystem,
1915                               geographicTransformation=geographicTransformation,
1916                               resamplingTechnique=resamplingTechnique,
1917                               projectedCellSize=projectedCellSize,
1918                               registrationPoint=registrationPoint,
1919                               clippingDataset=clippingDataset,
1920                               clippingRectangle=clippingRectangle,
1921                               mapAlgebraExpression=mapAlgebraExpression,
1922                               overwriteExisting=overwriteExisting)
1923
1924                # Convert the polygon feature class to a line
1925                # feature class.
1926
1927                gp = GeoprocessorManager.GetWrappedGeoprocessor()
1928                gp.FeatureToLine_management(tempFeatureClass, outputFeatureClass)
1929
1930            except:
1931                Logger.LogExceptionAsError()
1932                raise
1933        finally:
1934            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
1935
1936    @classmethod
1937    def ToLines(cls, inputRaster, outputFeatureClass, backgroundValue=u'ZERO', minDangleLength=0.0, simplify=True, field=None, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingDataset=None, clippingRectangle=None, mapAlgebraExpression=None, overwriteExisting=False):
1938        cls.__doc__.Obj.ValidateMethodInvocation()
1939        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1940        Logger.Info(_(u'Converting ArcGIS raster %(in)s to line feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1941        try:
1942            # Perform requested pre-conversion processing in a temp
1943            # directory.
1944           
1945            if projectedCoordinateSystem is not None or clippingRectangle is not None or mapAlgebraExpression is not None:
1946                cls._ValidateProjectClipAndOrExecuteMapAlgebraParameters(projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingDataset, clippingRectangle, mapAlgebraExpression)
1947                from GeoEco.DataManagement.Directories import TemporaryDirectory
1948                tempDir = TemporaryDirectory()
1949                inputRaster = cls._ProjectClipAndOrExecuteMapAlgebraInTempDir(inputRaster, tempDir.Path,
1950                                                                              projectedCoordinateSystem=projectedCoordinateSystem,
1951                                                                              geographicTransformation=geographicTransformation,
1952                                                                              resamplingTechnique=resamplingTechnique,
1953                                                                              projectedCellSize=projectedCellSize,
1954                                                                              registrationPoint=registrationPoint,
1955                                                                              clippingDataset=clippingDataset,
1956                                                                              clippingRectangle=clippingRectangle,
1957                                                                              mapAlgebraExpression=mapAlgebraExpression)
1958
1959            # Convert the raster to a line feature class.
1960
1961            try:
1962                if simplify:
1963                    gp.RasterToPolyline_conversion(inputRaster, outputFeatureClass, backgroundValue, minDangleLength, 'SIMPLIFY', field)
1964                else:
1965                    gp.RasterToPolyline_conversion(inputRaster, outputFeatureClass, backgroundValue, minDangleLength, 'NO_SIMPLIFY', field)
1966            except Exception, e:
1967                if str(e).lower().find('empty feature class') >= 0:
1968                    Logger.Warning(_(u'The raster %(raster)s is empty, so no lines can be created from it. Line feature class %(fc)s will be empty.') % {u'raster': inputRaster, u'fc': outputFeatureClass})
1969                else:
1970                    raise
1971
1972        except:
1973            Logger.LogExceptionAsError()
1974            raise
1975
1976    @classmethod
1977    def ToPoints(cls, inputRaster, outputFeatureClass, field=None, projectedCoordinateSystem=None, geographicTransformation=None, resamplingTechnique=None, projectedCellSize=None, registrationPoint=None, clippingDataset=None, clippingRectangle=None, mapAlgebraExpression=None, overwriteExisting=False):
1978        cls.__doc__.Obj.ValidateMethodInvocation()
1979        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1980        Logger.Info(_(u'Converting ArcGIS raster %(in)s to point feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1981        try:
1982            # Perform requested pre-conversion processing in a temp
1983            # directory.
1984           
1985            if projectedCoordinateSystem is not None or clippingRectangle is not None or mapAlgebraExpression is not None:
1986                cls._ValidateProjectClipAndOrExecuteMapAlgebraParameters(projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingDataset, clippingRectangle, mapAlgebraExpression)
1987                from GeoEco.DataManagement.Directories import TemporaryDirectory
1988                tempDir = TemporaryDirectory()
1989                inputRaster = cls._ProjectClipAndOrExecuteMapAlgebraInTempDir(inputRaster, tempDir.Path,
1990                                                                              projectedCoordinateSystem=projectedCoordinateSystem,
1991                                                                              geographicTransformation=geographicTransformation,
1992                                                                              resamplingTechnique=resamplingTechnique,
1993                                                                              projectedCellSize=projectedCellSize,
1994                                                                              registrationPoint=registrationPoint,
1995                                                                              clippingDataset=clippingDataset,
1996                                                                              clippingRectangle=clippingRectangle,
1997                                                                              mapAlgebraExpression=mapAlgebraExpression)
1998
1999            # Convert the raster to a point feature class.
2000           
2001            gp.RasterToPoint_conversion(inputRaster, outputFeatureClass, field)
2002
2003        except:
2004            Logger.LogExceptionAsError()
2005            raise
2006           
2007
2008###############################################################################
2009# Metadata: module
2010###############################################################################
2011
2012from GeoEco.DataManagement.BinaryRasters import BinaryRaster
2013from GeoEco.Dependencies import PythonAggregatedModuleDependency
2014from GeoEco.Metadata import *
2015from GeoEco.Types import *
2016
2017AddModuleMetadata(shortDescription=_(u'Provides methods for performing common data management operations on ArcGIS rasters.'))
2018
2019###############################################################################
2020# Metadata: ArcGISRaster class
2021###############################################################################
2022
2023AddClassMetadata(ArcGISRaster,
2024    shortDescription=_(u'Provides methods for performing common data management operations on ArcGIS rasters.'),
2025    longDescription=_(
2026u"""This class provides a significant advantage over the ArcGIS geoprocessing
2027tools for managing rasters: it can work around a bug in ArcGIS that causes it to
2028crash when a large number of rasters are stored in a single directory."""),
2029    isExposedAsCOMServer=True,
2030    comIID=u'{82BD49EF-6F06-4AC0-8E91-4E6B2FB84EB1}',
2031    comCLSID=u'{22C205A0-BE4C-4ECA-AF7C-BE496196C75F}')
2032
2033# Public method: ArcGISRaster.Copy
2034
2035AddMethodMetadata(ArcGISRaster.Copy,
2036    shortDescription=_(u'Copies an ArcGIS raster.'),
2037    longDescription=_(
2038u"""Unlike the ArcGIS geoprocessor\'s CopyRaster tool, this tool does
2039not crash ArcGIS when copying rasters to a destination directory that
2040already contains several hundred rasters. For more information on this
2041ArcGIS bug, see
2042http://forums.esri.com/Thread.asp?c=93&f=1729&t=196716&mc=0."""),
2043    isExposedToPythonCallers=True,
2044    isExposedByCOM=True,
2045    isExposedAsArcGISTool=True,
2046    arcGISDisplayName=_(u'Copy Raster'),
2047    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters\\Copy'),
2048    dependencies=[ArcGISDependency(9, 1)])
2049
2050AddArgumentMetadata(ArcGISRaster.Copy, u'cls',
2051    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2052    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2053
2054AddArgumentMetadata(ArcGISRaster.Copy, u'sourceRaster',
2055    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
2056    description=_(u'Raster to copy.'),
2057    arcGISDisplayName=_(u'Source raster'))
2058
2059AddArgumentMetadata(ArcGISRaster.Copy, u'destinationRaster',
2060    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'sourceRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2061    description=_(
2062u"""Copy to create.
2063
2064If this is a file system path, missing directories in the path will be created
2065if they do not exist."""),
2066    direction=u'Output',
2067    arcGISDisplayName=_(u'Destination raster'))
2068
2069AddArgumentMetadata(ArcGISRaster.Copy, u'overwriteExisting',
2070    typeMetadata=BooleanTypeMetadata(),
2071    description=_(
2072u"""If True, the destination raster will be overwritten, if it exists.
2073If False, a ValueError will be raised if the destination raster
2074exists."""),
2075    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2076
2077# Public method: ArcGISRaster.CopySilent
2078
2079AddMethodMetadata(ArcGISRaster.CopySilent,
2080    shortDescription=_(u'Copies an ArcGIS raster and logs a debug message rather than an informational message.'),
2081    longDescription=_(
2082u"""This method does the same thing as the Copy method, except it logs
2083a debug message rather than an informational message. It is intended
2084for use when the raster-copy operation is not imporant enough to
2085warrent notifying the user (for example, when an output raster is
2086extracted from a temporary directory to the final location)."""),
2087    isExposedToPythonCallers=True,
2088    isExposedByCOM=True,
2089    dependencies=[ArcGISDependency(9, 1)])
2090
2091CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.CopySilent, u'cls')
2092CopyArgumentMetadata(ArcGISRaster.Copy, u'sourceRaster', ArcGISRaster.CopySilent, u'sourceRaster')
2093CopyArgumentMetadata(ArcGISRaster.Copy, u'destinationRaster', ArcGISRaster.CopySilent, u'destinationRaster')
2094CopyArgumentMetadata(ArcGISRaster.Copy, u'overwriteExisting', ArcGISRaster.CopySilent, u'overwriteExisting')
2095
2096# Public method: ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash
2097
2098AddMethodMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash,
2099    shortDescription=_(u'Creates enough temporary ArcGIS rasters in a directory to prevent ArcGIS from crashing when a specified number of rasters are added to the directory.'),
2100    longDescription=_(
2101u"""A bug in ArcGIS 9.x causes it to crash if several hundred rasters are added
2102to a directory. Whether the crash occurs depends on the number and data types of
2103the rasters. See http://forums.esri.com/Thread.asp?c=93&f=1729&t=196716&mc=0 for
2104a complete description of the problem. At the time this documentation was
2105written, the problem was still present in ArcGIS 9.1 SP2 and 9.2 SP1.
2106
2107This function is designed to work around the problem. You call this function
2108prior to adding rasters to a directory and specify the number of of rasters
2109you're going to add. This function analyzes the current contents of the
2110directory. If there is any possibility that adding your rasters would hit the
2111combination needed to cause the crash, this function creates enough temporary
2112rasters to prevent the problem.
2113
2114If this function creates any temporary rasters, it returns a list of their full
2115paths to you. You should delete them after you've added your own rasters. The
2116DeleteTemporaryRastersThatPreventedArcGISCrash function is provided for this
2117purpose.
2118"""),
2119    isExposedToPythonCallers=True,
2120    isExposedByCOM=True,
2121    dependencies=[ArcGISDependency(9, 1)])
2122
2123AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'cls',
2124    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2125    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2126
2127AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'directory',
2128    typeMetadata=DirectoryTypeMetadata(),
2129    description=_(
2130u"""Directory in which temporary rasters should be created, in anticipation of
2131additional rasters being added by the caller after this method returns."""))
2132
2133AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'rastersToAdd',
2134    typeMetadata=IntegerTypeMetadata(minValue=1, maxValue=511),
2135    description=_(
2136u"""Number of rasters that the caller will add to the directory after this
2137method returns."""))
2138
2139AddResultMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'temporaryRasters',
2140    typeMetadata=ListTypeMetadata(elementType=ArcGISRasterTypeMetadata()),
2141    description=_(u"""List of temporary rasters that were created."""))
2142
2143# Public method: ArcGISRaster.CreateXRaster
2144
2145AddMethodMetadata(ArcGISRaster.CreateXRaster,
2146    shortDescription=_(u'Creates an ArcGIS raster where the value of each cell is the X coordinate of the cell.'),
2147    isExposedToPythonCallers=True,
2148    isExposedByCOM=True,
2149    isExposedAsArcGISTool=True,
2150    arcGISDisplayName=_(u'Create X Coordinate Raster'),
2151    arcGISToolCategory=_(u'Spatial Analysis\\Create Rasters'),
2152    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2153
2154CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.CreateXRaster, u'cls')
2155
2156AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'raster',
2157    typeMetadata=ArcGISRasterTypeMetadata(deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2158    description=_(
2159u"""Raster to create.
2160
2161If this is a file system path, missing directories in the path will be created
2162if they do not exist."""),
2163    direction=u'Output',
2164    arcGISDisplayName=_(u'Output raster'))
2165
2166AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'extent',
2167    typeMetadata=EnvelopeTypeMetadata(),
2168    description=_(u"""Extent of the output raster."""),
2169    arcGISDisplayName=_(u'Extent'))
2170
2171AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'cellSize',
2172    typeMetadata=FloatTypeMetadata(minValue=0.0),
2173    description=_(
2174u"""Cell size of the output raster.
2175
2176If the horizontal or vertical extents of the raster are not evenly
2177divisble by the cell size, the extents will be increased right or up
2178by the smallest amount needed to make them evenly divisible. For
2179example, if the horizontal extent runs from 0 to 25 and the cell size
2180is 2, the right extent will be increased to 26."""),
2181    arcGISDisplayName=_(u'Cell size'))
2182
2183AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'cellValue',
2184    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Center', u'Left', u'Right'], makeLowercase=True),
2185    description=_(
2186u"""Value of the raster cells, either:
2187
2188* Center - the X coordinate of the center of the cell.
2189
2190* Left - the X coordinate of the left edge of the cell.
2191
2192* Right - the X coordinate of the right edge of the cell.
2193"""),
2194    arcGISDisplayName=_(u'Cell value'))
2195
2196AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'coordinateSystem',
2197    typeMetadata=CoordinateSystemTypeMetadata(canBeNone=True),
2198    description=_(
2199u"""Coordinate system to define for the raster. If not specified, a
2200coordinate system will not be defined."""),
2201    arcGISDisplayName=_(u'Coordinate system'))
2202
2203AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'buildPyramids',
2204    typeMetadata=BooleanTypeMetadata(),
2205    description=_(
2206u"""If True, pyramids will be built for the raster, which will
2207improve its display speed in the ArcGIS user interface."""),
2208    arcGISDisplayName=_(u'Build pyramids'))
2209
2210AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting',
2211    typeMetadata=BooleanTypeMetadata(),
2212    description=_(
2213u"""If True, the raster will be overwritten, if it exists. If False, a
2214ValueError will be raised if the raster exists."""),
2215    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2216
2217# Public method: ArcGISRaster.CreateYRaster
2218
2219AddMethodMetadata(ArcGISRaster.CreateYRaster,
2220    shortDescription=_(u'Creates an ArcGIS raster where the value of each cell is the Y coordinate of the cell.'),
2221    isExposedToPythonCallers=True,
2222    isExposedByCOM=True,
2223    isExposedAsArcGISTool=True,
2224    arcGISDisplayName=_(u'Create Y Coordinate Raster'),
2225    arcGISToolCategory=_(u'Spatial Analysis\\Create Rasters'),
2226    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2227
2228CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'cls', ArcGISRaster.CreateYRaster, u'cls')
2229CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'raster', ArcGISRaster.CreateYRaster, u'raster')
2230CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'extent', ArcGISRaster.CreateYRaster, u'extent')
2231CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'cellSize', ArcGISRaster.CreateYRaster, u'cellSize')
2232
2233AddArgumentMetadata(ArcGISRaster.CreateYRaster, u'cellValue',
2234    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Center', u'Bottom', u'Top'], makeLowercase=True),
2235    description=_(
2236u"""Value of the raster cells, either:
2237
2238* Center - the X coordinate of the center of the cell.
2239
2240* Bottom - the Y coordinate of the bottom edge of the cell.
2241
2242* Top - the X coordinate of the top edge of the cell.
2243"""),
2244    arcGISDisplayName=_(u'Cell value'))
2245
2246CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'coordinateSystem', ArcGISRaster.CreateYRaster, u'coordinateSystem')
2247CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'buildPyramids', ArcGISRaster.CreateYRaster, u'buildPyramids')
2248CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting', ArcGISRaster.CreateYRaster, u'overwriteExisting')
2249
2250# Public method: ArcGISRaster.Delete
2251
2252AddMethodMetadata(ArcGISRaster.Delete,
2253    shortDescription=_(u'Deletes an ArcGIS raster.'),
2254    isExposedToPythonCallers=True,
2255    isExposedByCOM=True,
2256    isExposedAsArcGISTool=True,
2257    arcGISDisplayName=_(u'Delete Raster'),
2258    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters\\Delete'),
2259    dependencies=[ArcGISDependency(9, 1)])
2260
2261AddArgumentMetadata(ArcGISRaster.Delete, u'cls',
2262    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2263    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2264
2265AddArgumentMetadata(ArcGISRaster.Delete, u'raster',
2266    typeMetadata=ArcGISRasterTypeMetadata(),
2267    description=_(u"""Raster to delete."""),
2268    arcGISDisplayName=_(u'Raster'))
2269
2270# Public method: ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash
2271
2272AddMethodMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash,
2273    shortDescription=_(u'Deletes the temporary ArcGIS rasters created by the CreateTemporaryRastersToPreventArcGISCrash function.'),
2274    isExposedToPythonCallers=True,
2275    isExposedByCOM=True,
2276    dependencies=[ArcGISDependency(9, 1)])
2277
2278AddArgumentMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash, u'cls',
2279    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2280    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2281
2282AddArgumentMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash, u'rasters',
2283    typeMetadata=ListTypeMetadata(elementType=ArcGISRasterTypeMetadata()),
2284    description=_(
2285u"""List of temporary rasters to delete, returned by the
2286CreateTemporaryRastersToPreventArcGISCrash function."""))
2287
2288# Public method: ArcGISRaster.Exists
2289
2290AddMethodMetadata(ArcGISRaster.Exists,
2291    shortDescription=_(u'Tests that a specified path exists and is an ArcGIS raster.'),
2292    isExposedToPythonCallers=True,
2293    isExposedByCOM=True)
2294
2295CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.Exists, u'cls')
2296
2297AddArgumentMetadata(ArcGISRaster.Exists, u'path',
2298    typeMetadata=ArcGISRasterTypeMetadata(),
2299    description=_(u'Path to test.'))
2300
2301AddResultMetadata(ArcGISRaster.Exists, u'exists',
2302    typeMetadata=BooleanTypeMetadata(),
2303    description=_(u'True if the specified path exists.'))
2304
2305AddResultMetadata(ArcGISRaster.Exists, u'isRaster',
2306    typeMetadata=BooleanTypeMetadata(),
2307    description=_(u'True if the specified path exists and is an ArcGIS raster.'))
2308
2309# Public method: ArcGISRaster.Find
2310
2311AddMethodMetadata(ArcGISRaster.Find,
2312    shortDescription=_(u'Finds rasters in an ArcGIS workspace.'),
2313    longDescription=_(
2314u"""Rasters are returned in an arbitrary order determined by the
2315ArcGIS geoprocessor and the search algorithm."""),
2316    isExposedToPythonCallers=True,
2317    isExposedByCOM=True,
2318    dependencies=[ArcGISDependency(9, 1)])
2319
2320CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.Find, u'cls')
2321
2322AddArgumentMetadata(ArcGISRaster.Find, u'workspace',
2323    typeMetadata=ArcGISWorkspaceTypeMetadata(mustExist=True),
2324    description=_(u'Workspace to search.'),
2325    arcGISDisplayName=_(u'Workspace to search'))
2326
2327AddArgumentMetadata(ArcGISRaster.Find, u'wildcard',
2328    typeMetadata=UnicodeStringTypeMetadata(),
2329    description=_(
2330u"""Wildcard expression specifying the rasters to find. Please see the
2331documentation for the ArcGIS geoprocessor's ListRasters function for
2332more information about the syntax. At the time of this writing, only
2333the * wildcard character was supported, which would match zero or more
2334of any character."""),
2335    arcGISDisplayName=_(u'Wildcard expression'),
2336    arcGISCategory=_(u'Search options'))
2337
2338AddArgumentMetadata(ArcGISRaster.Find, u'searchTree',
2339    typeMetadata=BooleanTypeMetadata(),
2340    description=_(u'If True, child workspaces will be searched.'),
2341    arcGISDisplayName=_(u'Search workspace tree'),
2342    arcGISCategory=_(u'Search options'))
2343
2344AddArgumentMetadata(ArcGISRaster.Find, u'rasterType',
2345    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2346    description=_(
2347u"""Type of rasters to find. If provided, only rasters of this type
2348will be found. At the time of this writing, the ArcGIS 9.3
2349documentation specified that any of the following strings would be
2350accepted: ALL, BMP, GIF, GRID, IMG, JP2, JPG, PNG, TIFF.
2351
2352This parameter requires ArcGIS 9.3 or later."""),
2353    arcGISDisplayName=_(u'Raster type'),
2354    arcGISCategory=_(u'Search options'),
2355    dependencies=[ArcGISDependency(9, 3)])
2356
2357AddArgumentMetadata(ArcGISRaster.Find, u'basePath',
2358    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2359    description=_(
2360u"""Absolute path from which relative paths to the rasters will be
2361calculated. If provided, relative paths will be calculated and
2362included as part of the two dimensional array returned by this
2363function.
2364
2365For example, if the base path was::
2366
2367    C:\\Data\\Rasters
2368
2369the relative paths for the rasters::
2370
2371    C:\\Data\\Rasters\\Group1\\r1
2372    C:\\Data\\Rasters\\r1
2373    C:\\Data\\r1
2374    C:\\r1
2375    D:\\r1
2376    \\\\MyServer\\Data\\r1
2377
2378would be::   
2379
2380    Group1\\r1
2381    r1
2382    ..\\r1
2383    ..\\..\\r1
2384    D:\\r1
2385    \\\\MyServer\\Data\\r1
2386"""))
2387
2388AddArgumentMetadata(ArcGISRaster.Find, u'getExtent',
2389    typeMetadata=BooleanTypeMetadata(),
2390    description=_(
2391u"""'If True, the extent of each raster will be included as part of
2392the two-dimensional array returned by this function. The extent is
2393represented by four floating point numbers: XMin, YMin, XMax, and
2394YMax."""))
2395
2396_DateParsingExpressionSyntaxDocumentation = _(
2397u"""The expression is a standard `Python regular expression
2398<http://docs.python.org/lib/re-syntax.html>`_ with additional codes
2399for matching fragments of dates::
2400
2401    %d - Day of the month as a decimal number (range: 01 to 31)
2402    %H - Hour (24-hour clock) as a decimal number (range: 00 to 23)
2403    %j - Day of the year as a decimal number (range: 001 to 366)
2404    %m - Month as a decimal number (range: 01 to 12)
2405    %M - Minute as a decimal number (range: 00 to 59)
2406    %S - Second as a decimal number (range: 00 to 61)
2407    %y - Year without century as a decimal number (range: 00 to 99)
2408    %Y - Year with century as a decimal number (range: 0001 to 9999)
2409    %% - A literal "%" character
2410
2411A date is parsed from a path as follows:
2412
24131. The date fragment codes in your expression are replaced by regular
2414   expression groups to produce a true regular expression. For
2415   example, if your expression is "%Y_%m_%d", it is converted to the
2416   regular expression
2417   "(\\\\d\\\\d\\\\d\\\\d)_(\\\\d\\\\d)_(\\\\d\\\\d)".
2418
24192. The Python re.search function is invoked to find the
2420   first occurrence of the regular expression in the path. The
2421   search proceeds from left to right.
2422
24233. If an occurrence is found, the regular expression groups are
2424   extracted and the Python time.strptime function is invoked to parse
2425   a date from the groups.
2426
2427Notes:
2428
2429* Your expression must include at least one date fragment code, but it
2430  need not include all of them. If a particular code is missing, the
2431  following default values will be used: year 1900, month 01, day 01,
2432  hour 00, minute 00, second 00.
2433
2434* You cannot specify a given date fragment code more than once.
2435
2436* You cannot specify date fragment codes that might conflict. For
2437  example, you cannot specify both %j and %d because this could result
2438  in conflicting values for the day.
2439
2440* For %y, values 00 to 68 are interpreted as years 2000 through 2068,
2441  while 69 through 99 are interpreted as years 1969 through 1999.
2442
2443* Remember that the entire path is searched for your expression, from
2444  left to right. The first occurrence of it may be in the parent
2445  directories.
2446
2447* The date fragment codes are case-sensitive.
2448
2449* If the underlying database table can hold the time as well as the
2450  date in a single field, the time will be stored along with the date.
2451  These databases include Microsoft Access, Microsoft SQL Server, and
2452  Oracle, among others. If the table cannot hold the time and date in
2453  a single field, then only the date will be stored. This is the case,
2454  for example, with dBASE III and IV tables (.dbf files), often used
2455  by ArcGIS.
2456
2457* The timezone of the parsed date is assumed to be UTC.
2458
2459Examples:
2460
2461The expression::
2462
2463    %Y%j
2464
2465will parse dates from rasters namd with the year and day of year::
2466
2467    C:\\SST\\Rasters\\2006\\sst2006001
2468    C:\\SST\\Rasters\\2006\\sst2006002
2469    C:\\SST\\Rasters\\2006\\sst2006003
2470
2471Note that, in this example, the 2006 is parsed from the raster name,
2472not the 2006 directory, because the directory is not followed by a day
2473of year, it is followed by a backslash. The date parsing expression
2474will only match a year followed by a day of year.""")
2475
2476AddArgumentMetadata(ArcGISRaster.Find, u'dateParsingExpression',
2477    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2478    description=_(
2479u"""'Expression for parsing dates from the paths of each raster. If
2480provided, dates will be parsed from the paths of each raster using
2481this expression and included as part of the two dimensional array
2482returned by this function.
2483
2484""") +
2485_DateParsingExpressionSyntaxDocumentation)
2486
2487AddResultMetadata(ArcGISRaster.Find, u'rasters',
2488    typeMetadata=ListTypeMetadata(ListTypeMetadata(elementType=AnyObjectTypeMetadata())),
2489    description=_(
2490u"""Two-dimensional array listing the rasters that were found and the
2491requested metadata about them. The array is organized as a table with
2492the following columns in the order shown:
2493
2494* Path - Unicode string; this column always exists.
2495
2496* Relative path - Unicode string; this column will only exist if
2497  basePath is provided.
2498
2499* XMin, YMin, XMax, YMax - float; these columns will only exist if
2500  getExtent is true.
2501
2502* Parsed date - datetime; this column will only exist if
2503  dateParsingExpression is provided.
2504
2505* Parsed UNIX time - integer; this column will only exist if
2506  dateParsingExpression is provided. It is the same value as the
2507  previous column, but in UNIX time format. UNIX times are 32-bit
2508  signed integers that are the number of seconds since 1970-01-01
2509  00:00:00 UTC. This tool assumes the date that was parsed is in the
2510  UTC timezone. The UNIX time values produced by this tool do not
2511  include leap seconds; this tool assumes that a regular year is
2512  31536000 seconds and a leap year is 31622400 seconds.
2513"""))
2514
2515# Public method: ArcGISRaster.FindAndFillTable
2516
2517AddMethodMetadata(ArcGISRaster.FindAndFillTable,
2518    shortDescription=_(u'Finds rasters within an ArcGIS workspace and inserts a row for each one into an existing table.'),
2519    longDescription=ArcGISRaster.Find.__doc__.Obj.LongDescription,
2520    isExposedToPythonCallers=True,
2521    dependencies=[ArcGISDependency(9, 1)])
2522
2523CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FindAndFillTable, u'cls')
2524CopyArgumentMetadata(ArcGISRaster.Find, u'workspace', ArcGISRaster.FindAndFillTable, u'workspace')
2525
2526AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'insertCursor',
2527    typeMetadata=ClassInstanceTypeMetadata(cls=InsertCursor),
2528    description=_(
2529u"""Insert cursor opened to the table that will receive the rows. The
2530cursor will still be open when this function returns."""))
2531
2532AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'rasterField',
2533    typeMetadata=UnicodeStringTypeMetadata(),
2534    description=_(
2535u"""Name of the field to receive absolute paths to the rasters that
2536were found."""),
2537    arcGISDisplayName=_(u'File path field'))
2538
2539CopyArgumentMetadata(ArcGISRaster.Find, u'wildcard', ArcGISRaster.FindAndFillTable, u'wildcard')
2540CopyArgumentMetadata(ArcGISRaster.Find, u'searchTree', ArcGISRaster.FindAndFillTable, u'searchTree')
2541CopyArgumentMetadata(ArcGISRaster.Find, u'rasterType', ArcGISRaster.FindAndFillTable, u'rasterType')
2542
2543AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'relativePathField',
2544    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2545    description=_(
2546u"""Name of the field to receive paths of the rasters that were found,
2547relative to the path you specify for the base path parameter. For
2548example, if the base path was::
2549
2550    C:\\Data\\Rasters
2551
2552the relative paths for the rasters::
2553
2554    C:\\Data\\Rasters\\Group1\\r1
2555    C:\\Data\\Rasters\\r1
2556    C:\\Data\\r1
2557    C:\\r1
2558    D:\\r1
2559    \\\\MyServer\\Data\\r1
2560
2561would be::   
2562
2563    Group1\\r1
2564    r1
2565    ..\\r1
2566    ..\\..\\r1
2567    D:\\r1
2568    \\\\MyServer\\Data\\r1
2569"""))
2570
2571AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'basePath',
2572    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2573    description=_(
2574u"""Absolute path from which relative paths will be calculated and
2575stored in the field specified by the relative path field parameter.
2576Please see the documentation for that field for more information."""))
2577
2578AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'populateExtentFields',
2579    typeMetadata=BooleanTypeMetadata(),
2580    description=_(
2581u"""If True, the fields named XMin, YMin, XMax, and YMax will be
2582populated with the rasters' extents. If you populate these fields and
2583store the rasters' paths in a field named Image, ArcGIS will treat
2584your table as an unmanaged raster catalog and enable additional
2585functionality from the ArcGIS user interface, such as time series
2586animations."""),
2587    arcGISDisplayName=_(u'Populate XMin, YMin, XMax, and YMax fields'),
2588    arcGISCategory=_(u'Output table options'))
2589
2590AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'parsedDateField',
2591    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2592    description=_(
2593u"""Name of the field to receive dates parsed from the paths of the
2594rasters that were found. You must also specify a date parsing
2595expression."""),
2596    arcGISDisplayName=_(u'Parsed date field'),
2597    arcGISCategory=_(u'Output table options'))
2598
2599AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'dateParsingExpression',
2600    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2601    description=_(
2602u"""Expression for parsing dates from the paths of the rasters that
2603were found. The expression will be ignored if you do not also specify
2604a field to receive the dates or the equivalent UNIX time.
2605
2606""") + _DateParsingExpressionSyntaxDocumentation,
2607    arcGISDisplayName=_(u'Date parsing expression'),
2608    arcGISCategory=_(u'Output table options'))
2609
2610AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'unixTimeField',
2611    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2612    description=_(
2613u"""Name of the field to receive dates, in "UNIX time" format, parsed
2614from the paths of the rasters that were found. You must also specify a
2615date parsing expression.
2616
2617UNIX times are 32-bit signed integers that are the number of seconds
2618since 1970-01-01 00:00:00 UTC. This tool assumes the date that was
2619parsed is in the UTC timezone. The UNIX time values produced by this
2620tool do not include leap seconds; this tool assumes that a regular
2621year is 31536000 seconds and a leap year is 31622400 seconds."""),
2622    arcGISDisplayName=_(u'UNIX time field'),
2623    arcGISCategory=_(u'Output table options'))
2624
2625# Public method: ArcGISRaster.FindAndCreateTable
2626
2627AddMethodMetadata(ArcGISRaster.FindAndCreateTable,
2628    shortDescription=_(u'Finds rasters within an ArcGIS workspace and creates a table that lists them.'),
2629    longDescription=ArcGISRaster.Find.__doc__.Obj.LongDescription,
2630    isExposedToPythonCallers=True,
2631    dependencies=[ArcGISDependency(9, 1)])
2632
2633CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FindAndCreateTable, u'cls')
2634CopyArgumentMetadata(ArcGISRaster.Find, u'workspace', ArcGISRaster.FindAndCreateTable, u'workspace')
2635
2636AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'connection',
2637    typeMetadata=ClassInstanceTypeMetadata(cls=DatabaseConnection),
2638    description=_(u'Connection opened to the database that will receive the new table.'))
2639
2640AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'table',
2641    typeMetadata=UnicodeStringTypeMetadata(),
2642    description=_(u'Name of the table to create. The table must not exist.'),
2643    arcGISDisplayName=_(u'Output table name'))
2644
2645CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'rasterField', ArcGISRaster.FindAndCreateTable, u'rasterField')
2646CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'wildcard', ArcGISRaster.FindAndCreateTable, u'wildcard')
2647CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'searchTree', ArcGISRaster.FindAndCreateTable, u'searchTree')
2648CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'rasterType', ArcGISRaster.FindAndCreateTable, u'rasterType')
2649CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'relativePathField', ArcGISRaster.FindAndCreateTable, u'relativePathField')
2650CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'basePath', ArcGISRaster.FindAndCreateTable, u'basePath')
2651CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'populateExtentFields', ArcGISRaster.FindAndCreateTable, u'populateExtentFields')
2652CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'parsedDateField', ArcGISRaster.FindAndCreateTable, u'parsedDateField')
2653CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'dateParsingExpression', ArcGISRaster.FindAndCreateTable, u'dateParsingExpression')
2654CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'unixTimeField', ArcGISRaster.FindAndCreateTable, u'unixTimeField')
2655
2656AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'pathFieldsDataType',
2657    typeMetadata=UnicodeStringTypeMetadata(),
2658    description=_(
2659u"""Database data type to use when creating the raster path fields.
2660Because the fields will contain paths, they must have a string data
2661type such as TEXT or VARCHAR. The appropriate data type depends on the
2662underlying database and the API used to access it."""))
2663
2664AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'extentFieldsDataType',
2665    typeMetadata=UnicodeStringTypeMetadata(),
2666    description=_(
2667u"""Database data type to use when creating the raster extent fields
2668(XMin, YMin, XMax, and YMax). The fields will contain floating point
2669numbers. The appropriate data type depends on the underlying database
2670and the API used to access it. For many databases, the DOUBLE or FLOAT
2671data type are appropriate."""))
2672
2673AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'dateFieldsDataType',
2674    typeMetadata=UnicodeStringTypeMetadata(),
2675    description=_(
2676u"""Database data type to use when creating the parsed date field. The
2677appropriate data type depends on the underlying database and the API
2678used to access it. For many databases, the DATE or DATETIME data type
2679are appropriate."""))
2680
2681AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'unixTimeFieldDataType',
2682    typeMetadata=UnicodeStringTypeMetadata(),
2683    description=_(
2684u"""Database data type to use when creating the UNIX date field. The
2685appropriate data type depends on the underlying database and the API
2686used to access it. Because UNIX dates are 32-bit signed integers, the
2687INT or LONG data type is usually appropriate for most databases."""))
2688
2689AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'maxPathLength',
2690    typeMetadata=IntegerTypeMetadata(canBeNone=True, minValue=1),
2691    description=_(
2692u"""Maximum length of a path for this operating system. This value is
2693used to specify the width of the field that is created. You should
2694provide a value only if the underlying database requires that you
2695specify a width for string fields. If you provide a value that is too
2696small to hold one of the paths that is found, this function will fail
2697when it finds that path."""))
2698
2699AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'overwriteExisting',
2700    typeMetadata=BooleanTypeMetadata(),
2701    description=_(
2702u"""If True, the output table will be overwritten, if it exists.
2703
2704If False, a ValueError will be raised if the output table exists."""),
2705    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2706
2707CopyResultMetadata(DatabaseConnection.CreateTable, u'createdTable', ArcGISRaster.FindAndCreateTable, u'createdTable')
2708
2709# Public method: ArcGISRaster.FindAndCreateArcGISTable
2710
2711AddMethodMetadata(ArcGISRaster.FindAndCreateArcGISTable,
2712    shortDescription=_(u'Finds rasters within an ArcGIS workspace and creates a table that lists them.'),
2713    longDescription=ArcGISRaster.FindAndCreateTable.__doc__.Obj.LongDescription,
2714    isExposedToPythonCallers=True,
2715    isExposedByCOM=True,
2716    isExposedAsArcGISTool=True,
2717    arcGISDisplayName=_(u'Find Rasters'),
2718    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters'),
2719    dependencies=[ArcGISDependency(9, 1)])
2720
2721CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FindAndCreateArcGISTable, u'cls')
2722CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'workspace', ArcGISRaster.FindAndCreateArcGISTable, u'inputWorkspace')
2723
2724AddArgumentMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'outputWorkspace',
2725    typeMetadata=ArcGISWorkspaceTypeMetadata(mustExist=True),
2726    description=_(u'Workspace in which the table should be created.'),
2727    arcGISDisplayName=_(u'Output workspace'))
2728
2729AddArgumentMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'table',
2730    typeMetadata=UnicodeStringTypeMetadata(),
2731    description=_(
2732u"""Name of the table to create.
2733
2734If the output workspace is a directory (rather than a database) a
2735dBASE table will be created. It is not possible to create other types
2736of tables in the file system (e.g. comma or space-delimited text
2737files). This restriction is imposed by the ArcGIS CreateTable tool,
2738which is used to create the table. If you omit an extension from the
2739table name, .dbf will be added automatically. If you specify another
2740extension, such as .csv or .txt, it will be replaced with .dbf."""),
2741    arcGISDisplayName=_(u'Output table name'))
2742
2743CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'rasterField', ArcGISRaster.FindAndCreateArcGISTable, u'rasterField')
2744CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'wildcard', ArcGISRaster.FindAndCreateArcGISTable, u'wildcard')
2745CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'searchTree', ArcGISRaster.FindAndCreateArcGISTable, u'searchTree')
2746CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'rasterType', ArcGISRaster.FindAndCreateArcGISTable, u'rasterType')
2747
2748AddArgumentMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'relativePathField',
2749    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2750    description=_(
2751u"""Name of the field to receive paths of the rasters that were found,
2752relative to the output table. For example, if the path to the table is::
2753
2754    C:\\Data\\Rasters\\FoundRasters.dbf
2755
2756the relative paths for the rasters::
2757
2758    C:\\Data\\Rasters\\Group1\\r1
2759    C:\\Data\\Rasters\\r1
2760    C:\\Data\\r1
2761    C:\\r1
2762    D:\\r1
2763    \\\\MyServer\\Data\\r1
2764
2765would be::   
2766
2767    Group1\\r1
2768    r1
2769    ..\\r1
2770    ..\\..\\r1
2771    D:\\r1
2772    \\\\MyServer\\Data\\r1
2773
2774If the table is in a personal geodatabase::
2775
2776    C:\\Data\\Rasters\\RasterInfo.mdb\\FoundRasters
2777
2778the relative paths would be::   
2779
2780    ..\\Group1\\r1
2781    ..\\r1
2782    ..\\..\\r1
2783    ..\\..\\..\\r1
2784    D:\\r1
2785    \\\\MyServer\\Data\\r1
2786"""),
2787    arcGISDisplayName=_(u'Relative path field'),
2788    arcGISCategory=_(u'Output table options'))
2789
2790CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'populateExtentFields', ArcGISRaster.FindAndCreateArcGISTable, u'populateExtentFields')
2791CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'parsedDateField', ArcGISRaster.FindAndCreateArcGISTable, u'parsedDateField')
2792CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'dateParsingExpression', ArcGISRaster.FindAndCreateArcGISTable, u'dateParsingExpression')
2793CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'unixTimeField', ArcGISRaster.FindAndCreateArcGISTable, u'unixTimeField')
2794CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'maxPathLength', ArcGISRaster.FindAndCreateArcGISTable, u'maxPathLength')
2795CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'overwriteExisting', ArcGISRaster.FindAndCreateArcGISTable, u'overwriteExisting')
2796
2797AddResultMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'createdTable',
2798    typeMetadata=ArcGISTableTypeMetadata(),
2799    description=DatabaseConnection.CreateTable.__doc__.Obj.GetResultByName(u'createdTable').Description,
2800    arcGISDisplayName=_(u'Output table'))
2801
2802# Public method: ArcGISRaster.Move
2803
2804AddMethodMetadata(ArcGISRaster.Move,
2805    shortDescription=_(u'Moves an ArcGIS raster.'),
2806    longDescription=ArcGISRaster.Copy.__doc__.Obj.LongDescription,
2807    isExposedToPythonCallers=True,
2808    isExposedByCOM=True,
2809    isExposedAsArcGISTool=True,
2810    arcGISDisplayName=_(u'Move Raster'),
2811    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters\\Move'),
2812    dependencies=[ArcGISDependency(9, 1)])
2813
2814AddArgumentMetadata(ArcGISRaster.Move, u'cls',
2815    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2816    description=ArcGISRaster.Copy.__doc__.Obj.Arguments[0].Description)
2817
2818AddArgumentMetadata(ArcGISRaster.Move, u'sourceRaster',
2819    typeMetadata=ArcGISRasterTypeMetadata(mustExist=True),
2820    description=_(u'Raster to move.'),
2821    arcGISDisplayName=_(u'Source raster'))
2822
2823AddArgumentMetadata(ArcGISRaster.Move, u'destinationRaster',
2824    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'sourceRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2825    description=_(
2826u"""New path for the raster.
2827
2828If this is a file system path, missing directories in the path will be created
2829if they do not exist."""),
2830    direction=u'Output',
2831    arcGISDisplayName=_(u'Destination raster'))
2832
2833AddArgumentMetadata(ArcGISRaster.Move, u'overwriteExisting',
2834    typeMetadata=BooleanTypeMetadata(),
2835    description=ArcGISRaster.Copy.__doc__.Obj.Arguments[3].Description,
2836    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2837
2838# Public method: ArcGISRaster.MoveSilent
2839
2840AddMethodMetadata(ArcGISRaster.MoveSilent,
2841    shortDescription=_(u'Moves an ArcGIS raster and logs a debug message rather than an informational message.'),
2842    longDescription=_(
2843u"""This method does the same thing as the Move method, except it logs
2844a debug message rather than an informational message. It is intended
2845for use when the raster-move operation is not imporant enough to
2846warrent notifying the user (for example, when an output raster is
2847extracted from a temporary directory to the final location)."""),
2848    isExposedToPythonCallers=True,
2849    isExposedByCOM=True,
2850    dependencies=[ArcGISDependency(9, 1)])
2851
2852CopyArgumentMetadata(ArcGISRaster.Move, u'cls', ArcGISRaster.MoveSilent, u'cls')
2853CopyArgumentMetadata(ArcGISRaster.Move, u'sourceRaster', ArcGISRaster.MoveSilent, u'sourceRaster')
2854CopyArgumentMetadata(ArcGISRaster.Move, u'destinationRaster', ArcGISRaster.MoveSilent, u'destinationRaster')
2855CopyArgumentMetadata(ArcGISRaster.Move, u'overwriteExisting', ArcGISRaster.MoveSilent, u'overwriteExisting')
2856
2857# Public method: ArcGISRaster.FromNumpyArray
2858
2859AddMethodMetadata(ArcGISRaster.FromNumpyArray,
2860    shortDescription=_(u'Creates an ArcGIS raster from a numpy array.'),
2861    isExposedToPythonCallers=True,
2862    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2863
2864CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FromNumpyArray, u'cls')
2865
2866AddArgumentMetadata(ArcGISRaster.FromNumpyArray, u'numpyArray',
2867    typeMetadata=NumPyArrayTypeMetadata(dimensions=2, minShape=[1,1], allowedDTypes=[u'int8', u'uint8', u'int16', u'uint16', u'int32', u'uint32', u'float32']),
2868    description=_(u'Numpy array to write out as an ArcGIS raster.'))
2869
2870AddArgumentMetadata(ArcGISRaster.FromNumpyArray, u'raster',
2871    typeMetadata=ArcGISRasterTypeMetadata(deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2872    description=_(u'Output raster to create.'))
2873
2874CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'xLowerLeftCorner', ArcGISRaster.FromNumpyArray, u'xLowerLeftCorner')
2875CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'yLowerLeftCorner', ArcGISRaster.FromNumpyArray, u'yLowerLeftCorner')
2876CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'cellSize', ArcGISRaster.FromNumpyArray, u'cellSize')
2877CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'nodataValue', ArcGISRaster.FromNumpyArray, u'nodataValue')
2878CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'coordinateSystem', ArcGISRaster.FromNumpyArray, u'coordinateSystem')
2879CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCoordinateSystem', ArcGISRaster.FromNumpyArray, u'projectedCoordinateSystem')
2880CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'geographicTransformation', ArcGISRaster.FromNumpyArray, u'geographicTransformation')
2881CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'resamplingTechnique', ArcGISRaster.FromNumpyArray, u'resamplingTechnique')
2882CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCellSize', ArcGISRaster.FromNumpyArray, u'projectedCellSize')
2883CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'registrationPoint', ArcGISRaster.FromNumpyArray, u'registrationPoint')
2884CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'clippingRectangle', ArcGISRaster.FromNumpyArray, u'clippingRectangle')
2885CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'mapAlgebraExpression', ArcGISRaster.FromNumpyArray, u'mapAlgebraExpression')
2886CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'buildPyramids', ArcGISRaster.FromNumpyArray, u'buildPyramids')
2887CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'overwriteExisting', ArcGISRaster.FromNumpyArray, u'overwriteExisting')
2888
2889# Public method: ArcGISRaster.ToNumpyArray
2890
2891AddMethodMetadata(ArcGISRaster.ToNumpyArray,
2892    shortDescription=_(u'Reads an ArcGIS raster or raster layer into a numpy array.'),
2893    isExposedToPythonCallers=True,
2894    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2895
2896CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToNumpyArray, u'cls')
2897
2898AddArgumentMetadata(ArcGISRaster.ToNumpyArray, u'raster',
2899    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
2900    description=_(u'Raster to read.'))
2901
2902AddArgumentMetadata(ArcGISRaster.ToNumpyArray, u'band',
2903    typeMetadata=IntegerTypeMetadata(minValue=1),
2904    description=_(u'Band number to read, starting with 1.'))
2905
2906AddArgumentMetadata(ArcGISRaster.ToNumpyArray, u'tempRasterPath',
2907    typeMetadata=ArcGISRasterTypeMetadata(canBeNone=True, mustNotExist=True),
2908    description=_(
2909u"""Path to use if it is necessary to create a temporary copy of the
2910raster. The caller can provide this as an optimization. If provided,
2911the caller is responsible for deleting the temporary raster, if it
2912happened to be created (the caller should check for this after this
2913function returns).
2914
2915If you do not provide a path, this function will create a temporary
2916directory to hold the temporary raster, and delete it before
2917returning.
2918
2919The temporary raster is only created when the input raster does not
2920exist on disk (i.e. it exists in a geodatabase). This function uses
2921GDAL to read the raster, and GDAL can only read rasters that are on
2922disk. Thus if the raster is not on disk, a temporary copy is needed so
2923it can be read by GDAL."""))
2924
2925AddResultMetadata(ArcGISRaster.ToNumpyArray, u'numpyArray',
2926    typeMetadata=NumPyArrayTypeMetadata(dimensions=2),
2927    description=_(
2928u"""Numpy array read from the raster.
2929
2930Note that, for integer rasters, the array will use the most compact
2931data type that can represent all of the values in the raster.
2932Normally, ArcGIS automatically selects the most compact data type, but
2933this does not always happen. For example, I have seen ArcGIS store
2934data ranging from 0 to 65535 (with no NODATA value) as an int32 raster
2935even though a uint16 is the most compact data type for that
2936range."""))
2937
2938AddResultMetadata(ArcGISRaster.ToNumpyArray, u'noDataValue',
2939    typeMetadata=FloatTypeMetadata(canBeNone=True),
2940    description=_(
2941u"""Value in the returned numpy array that represents NODATA. Note
2942that, if the numpy array is compacted (as described above), this value
2943may be different than what ArcGIS used when it created the
2944raster."""))
2945
2946# Public method: ArcGISRaster.ExtractByMask
2947
2948AddMethodMetadata(ArcGISRaster.ExtractByMask,
2949    shortDescription=_(u'Extracts the cells of a raster that correspond to the areas defined by a mask.'),
2950    longDescription=_(
2951u"""This tool just calls the ArcGIS Spatial Analyst's Extract By Mask
2952tool. It only exists so that we can easily create a batched version of
2953that tool."""),
2954    isExposedToPythonCallers=True,
2955    isExposedByCOM=True,
2956    isExposedAsArcGISTool=False,
2957    arcGISToolCategory=_(u'Spatial Analysis\\Project, Clip and/or Execute Map Algebra'),
2958    dependencies=[ArcGISDependency(9, 1), ArcGISExtensionDependency(u'spatial')])
2959
2960CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ExtractByMask, u'cls')
2961
2962AddArgumentMetadata(ArcGISRaster.ExtractByMask, u'inputRaster',
2963    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
2964    description=_(u'The input raster from which cells will be extracted.'),
2965    arcGISDisplayName=_(u'Input raster'))
2966
2967AddArgumentMetadata(ArcGISRaster.ExtractByMask, u'mask',
2968    typeMetadata=ArcGISGeoDatasetTypeMetadata(mustExist=True),
2969    description=_(
2970u"""Input mask data defining areas to extract.
2971
2972This is a raster or feature dataset.
2973
2974When the input mask data is a raster, NoData cells on the mask will be
2975assigned NoData values on the output raster."""),
2976    arcGISDisplayName=_(u'Input raster or feature mask data'))
2977
2978AddArgumentMetadata(ArcGISRaster.ExtractByMask, u'outputRaster',
2979    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'inputRaster', u'mask'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2980    description=_(
2981u"""The output raster containing the cell values extracted from the
2982input raster.
2983
2984If this path refers to the file system, missing directories in the
2985path will be created if they do not exist."""),
2986    direction=u'Output',
2987    arcGISDisplayName=_(u'Output raster'))
2988
2989CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting', ArcGISRaster.ExtractByMask, u'overwriteExisting')
2990
2991# Public method: ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra
2992
2993AddMethodMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra,
2994    shortDescription=_(u'Projects, clips, and/or perfoms map algebra on an ArcGIS raster. You must request at least one of these three operations. If you request multiple operations, the tool performs them in the order they are listed.'),
2995    isExposedToPythonCallers=True,
2996    isExposedByCOM=True,
2997    isExposedAsArcGISTool=True,
2998    arcGISDisplayName=_(u'Project, Clip, and/or Execute Map Algebra'),
2999    arcGISToolCategory=_(u'Spatial Analysis\\Project, Clip and/or Execute Map Algebra'),
3000    dependencies=[ArcGISDependency(9, 1)])
3001
3002CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'cls')
3003
3004AddArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'inputRaster',
3005    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3006    description=_(u'Input raster.'),
3007    arcGISDisplayName=_(u'Input raster'))
3008
3009AddArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'outputRaster',
3010    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3011    description=_(
3012u"""Output raster.
3013
3014If this path refers to the file system, missing directories in the
3015path will be created if they do not exist."""),
3016    direction=u'Output',
3017    arcGISDisplayName=_(u'Output raster'))
3018
3019CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCoordinateSystem', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCoordinateSystem')
3020ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'projectedCoordinateSystem').ArcGISCategory = None
3021
3022CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'geographicTransformation', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'geographicTransformation')
3023ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'geographicTransformation').ArcGISCategory = None
3024
3025CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'resamplingTechnique', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'resamplingTechnique')
3026ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'resamplingTechnique').ArcGISCategory = None
3027
3028CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCellSize', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCellSize')
3029ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'projectedCellSize').ArcGISCategory = None
3030
3031CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'registrationPoint', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'registrationPoint')
3032ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'registrationPoint').ArcGISCategory = None
3033
3034AddArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingDataset',
3035    typeMetadata=ArcGISGeoDatasetTypeMetadata(mustExist=True, canBeNone=True),
3036    description=_(
3037u"""Existing feature class, raster, or other geographic dataset having
3038the extent to which the raster should be clipped.
3039
3040WARNING: If you use this tool from in an ArcGIS geoprocessing model
3041and you select a dataset by clicking the folder icon and browsing to
3042the dataset, your selection may mysteriously disappear from this text
3043box after you close the tool. This is a bug in ArcGIS. To work around
3044it, drag and drop the desired dataset into the model. This will create
3045a layer in the model for that dataset. Then select that layer in this
3046tool by clicking the drop-down box rather than clicking the folder
3047icon. The selected layer should not disappear when you close the
3048tool."""),
3049    arcGISDisplayName=_(u'Clip to extent of geographic dataset'))
3050
3051CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'clippingRectangle', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingRectangle')
3052ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'clippingRectangle').ArcGISCategory = None
3053
3054CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'mapAlgebraExpression', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'mapAlgebraExpression')
3055ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'mapAlgebraExpression').ArcGISCategory = None
3056
3057CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'buildPyramids', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'buildPyramids')
3058ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'buildPyramids').ArcGISCategory = None
3059
3060CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'overwriteExisting', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'overwriteExisting')
3061ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'overwriteExisting').ArcGISCategory = None
3062
3063# Public method: ArcGISRaster.ProjectToTemplate
3064
3065AddMethodMetadata(ArcGISRaster.ProjectToTemplate,
3066    shortDescription=_(u'Projects a raster to the coordinate system, cell size, and extent of a template raster.'),
3067    isExposedToPythonCallers=True,
3068    isExposedByCOM=True,
3069    isExposedAsArcGISTool=True,
3070    arcGISDisplayName=_(u'Project Raster to Template'),
3071    arcGISToolCategory=_(u'Spatial Analysis\\Project Raster to Template'),
3072    dependencies=[ArcGISDependency(9, 1)])
3073
3074CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ProjectToTemplate, u'cls')
3075
3076AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'inputRaster',
3077    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3078    description=_(
3079u"""Raster to project to the template raster's coordinate system, cell
3080size, and extent."""),
3081    arcGISDisplayName=_(u'Raster to project'))
3082
3083AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'templateRaster',
3084    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True, mustBeDifferentThanArguments=[u'inputRaster']),
3085    description=_(
3086u"""Raster defining the coordinate system, cell size, and extent of
3087the output raster."""),
3088    arcGISDisplayName=_(u'Template raster'))
3089
3090AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'outputRaster',
3091    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'inputRaster', u'templateRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3092    description=_(
3093u"""Output raster.
3094
3095If this path refers to the file system, missing directories in the
3096path will be created if they do not exist."""),
3097    direction=u'Output',
3098    arcGISDisplayName=_(u'Output raster'))
3099
3100AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'resamplingTechnique',
3101    typeMetadata=UnicodeStringTypeMetadata(makeLowercase=True, allowedValues=[u'BILINEAR', u'CUBIC']),
3102    description=_(
3103u"""Resampling algorithm to be used to project the input raster to the
3104template raster's coordinate system. One of:
3105
3106* NEAREST - `Nearest neighbor assignment
3107  <http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation>`_.
3108
3109* BILINEAR - `Bilinear interpolation
3110  <http://en.wikipedia.org/wiki/Bilinear_interpolation>`_.
3111
3112* CUBIC - Cubic convolution, also known as `bicubic interpolation
3113  <http://en.wikipedia.org/wiki/Bicubic_interpolation>`_.
3114
3115* MAJORITY - Majority resampling. This method requires ArcGIS 9.3 or
3116  later.
3117
3118The NEAREST and MAJORITY algorithms should be used for categorical
3119data, such as a land use classification. It is not recommended that
3120NEAREST or MAJORITY be used for continuous data, such as elevation
3121surfaces.
3122
3123The BILINEAR and CUBIC options are most appropriate for continuous
3124data. Do not use BILINEAR or CUBIC with categorical data.
3125
3126The projection is accomplished with the ArcGIS Project Raster tool.
3127Please see the documentation for that tool for more information."""),
3128    arcGISDisplayName=_(u'Resampling technique'))
3129
3130AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'interpolationMethod',
3131    typeMetadata=UnicodeStringTypeMetadata(makeLowercase=True, allowedValues=[u'Del2a', u'Del2b', u'Del2c', u'Del4', u'Spring'], canBeNone=True),
3132    description=_(
3133u"""Method to use to guess values for No Data cells.
3134
3135Use this option to "fill in" clusters of No Data cells with values
3136obtained by interpolation and extrapolation. This option is
3137appropriate for rasters representing continuous surfaces, e.g. images
3138of sea surface temperature in which cloudy pixels contain No Data. It
3139uses algorithms based on differential calculus that may provide more
3140accurate guesses than traditional ArcGIS approaches, such as computing
3141the focal mean of a 3x3 neighborhood.
3142
3143This option is not appropriate for rasters representing categorical
3144data, such as land cover classifications. Therefore, in order to use
3145this option, you must select BILINEAR or CUBIC for the Resampling
3146Technique parameter.
3147
3148The available algorithms are:
3149
3150* Del2a - Laplacian interpolation and linear extrapolation.
3151
3152* Del2b - Same as Del2a but does not build as large a linear system of
3153  equations. May be faster than Del2a at the cost of some accuracy.
3154
3155* Del2c - Same as Del2a but solves a direct linear system of equations
3156  for the No Data values. Faster than both Del2a and Del2b but is the
3157  least robust to noise on the boundaries of No Data cells and least
3158  able to interpolate accurately for smooth surfaces.
3159
3160* Del4 - Same as Del2a but instead of the Laplace operator (also
3161  called the del^2 operator) it uses the biharmonic operator (also
3162  called the del^4 operator). May result in more accurate
3163  interpolations, at some cost in speed.
3164
3165* Spring - Uses a spring metaphor. Assumes springs (with a nominal
3166  length of zero) connect each cell with every neighbor (horizontally,
3167  vertically and diagonally). Since each cell tries to be like its
3168  neighbors, extrapolation is as a constant function where this is
3169  consistent with the neighboring nodes.
3170
3171This option is applied after the input raster has been projected to
3172the coordinate system and cell size of the template raster.
3173
3174Although this tool can fill No Data clusters of any size, you should
3175apply common sense when using it. The larger the cluster, the less
3176accurate the guessed values will be, especially for rasters that
3177represent a noisy surface.
3178
3179Thanks to John D'Errico for providing the code that implements the
3180mathematical algorithms described here (click `here
3181<http://www.mathworks.com/matlabcentral/fileexchange/4551>`_ for more
3182information)."""),
3183    arcGISDisplayName=_(u'Method for interpolating No Data cells'),
3184    arcGISCategory=_(u'Interpolation and masking options'))
3185
3186AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'maxHoleSize',
3187    typeMetadata=IntegerTypeMetadata(mustBeGreaterThan=0, canBeNone=True),
3188    description=_(
3189u"""Maximum size, in cells of the template raster, that a region of
31904-connected No Data cells may be for it to be filled in.
3191
3192Use this option to prevent the filling of large No Data regions (e.g.
3193large clouds in remote sensing images) when you are concerned that
3194values cannot be accurately guessed for those regions. If this option
3195is omitted, all regions will be filled, regardless of size."""),
3196    arcGISDisplayName=_(u'Maximum size of No Data regions to interpolate'),
3197    arcGISCategory=_(u'Interpolation and masking options'))
3198
3199AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'mask',
3200    typeMetadata=BooleanTypeMetadata(),
3201    description=_(
3202u"""If True, the template raster will be used to mask the input raster
3203after it has been projected to the template raster's coordinate system
3204and values have been interpolated for No Data cells (if your requested
3205that). Cells of the template raster that are No Data will be set to No
3206Data in the output raster, even if you requested that values be
3207interpolated for No Data cells. This is appropriate in situations
3208where the template defines the areas for which you want to retain
3209data; for example, when you are analyzing the ocean and you have a
3210mask in which ocean cells have data and land cells are set to No Data.
3211
3212If False, the template raster will only be used to define the
3213coordinate system, cell size, and rectangular extent of the output
3214raster, and no masking will be done."""),
3215    arcGISDisplayName=_(u'Use template raster as mask'),
3216    arcGISCategory=_(u'Interpolation and masking options'))
3217
3218CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting', ArcGISRaster.ProjectToTemplate, u'overwriteExisting')
3219
3220# Public method: ArcGISRaster.ToPolygons
3221
3222AddMethodMetadata(ArcGISRaster.ToPolygons,
3223    shortDescription=_(u'Converts an ArcGIS raster to polygons that encompass groups of adjacent raster cells having the same value.'),
3224    isExposedToPythonCallers=True,
3225    isExposedByCOM=True,
3226    isExposedAsArcGISTool=True,
3227    arcGISDisplayName=_(u'Convert ArcGIS Raster to Polygons'),
3228    arcGISToolCategory=_(u'Conversion\\To Polygons\\From ArcGIS Raster'),
3229    dependencies=[ArcGISDependency(9, 1)])
3230
3231CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToPolygons, u'cls')
3232
3233AddArgumentMetadata(ArcGISRaster.ToPolygons, u'inputRaster',
3234    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3235    description=_(
3236u"""Raster to convert.
3237
3238The raster will be converted to a polygon feature class using the
3239ArcGIS Raster to Polygon tool. That tool can only convert integer
3240rasters to polygons. If the input raster is a floating-point raster,
3241you must use the Map Algebra Expression parameter to convert it to an
3242integer raster."""),
3243    arcGISDisplayName=_(u'Input raster'))
3244
3245AddArgumentMetadata(ArcGISRaster.ToPolygons, u'outputFeatureClass',
3246    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'polygon'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3247    description=_(
3248u"""Output polygon feature class that will contain the converted
3249polygons.
3250
3251Missing directories in this path will be created if they do not
3252exist."""),
3253    direction=u'Output',
3254    arcGISDisplayName=_(u'Output polygon feature class'))
3255
3256AddArgumentMetadata(ArcGISRaster.ToPolygons, u'simplify',
3257    typeMetadata=BooleanTypeMetadata(),
3258    description=_(
3259u"""Determines if the output polygons will be smoothed into simpler
3260shapes or conform to the input raster's cell edges.
3261
3262* True - The polygons will be smoothed into simpler shapes. This is
3263  the default.
3264
3265* False - The polygons will conform to the input raster's cell edges.
3266"""),
3267    arcGISDisplayName=_(u'Simplify polygons'))
3268
3269AddArgumentMetadata(ArcGISRaster.ToPolygons, u'field',
3270    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3271    description=_(
3272u"""The field used to assign values from the cells in the input raster
3273to the polygons in the output dataset. It can be an integer or a
3274string field."""),
3275    arcGISParameterDependencies=[u'inputRaster'],
3276    arcGISDisplayName=_(u'Field'))
3277
3278CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCoordinateSystem', ArcGISRaster.ToPolygons, u'projectedCoordinateSystem')
3279ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'projectedCoordinateSystem').ArcGISCategory = _(u'Pre-conversion processing')
3280
3281CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'geographicTransformation', ArcGISRaster.ToPolygons, u'geographicTransformation')
3282ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'geographicTransformation').ArcGISCategory = _(u'Pre-conversion processing')
3283
3284CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'resamplingTechnique', ArcGISRaster.ToPolygons, u'resamplingTechnique')
3285ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'resamplingTechnique').ArcGISCategory = _(u'Pre-conversion processing')
3286
3287CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCellSize', ArcGISRaster.ToPolygons, u'projectedCellSize')
3288ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'projectedCellSize').ArcGISCategory = _(u'Pre-conversion processing')
3289
3290CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'registrationPoint', ArcGISRaster.ToPolygons, u'registrationPoint')
3291ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'registrationPoint').ArcGISCategory = _(u'Pre-conversion processing')
3292
3293CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingDataset', ArcGISRaster.ToPolygons, u'clippingDataset')
3294ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'clippingDataset').ArcGISCategory = _(u'Pre-conversion processing')
3295
3296CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingRectangle', ArcGISRaster.ToPolygons, u'clippingRectangle')
3297ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'clippingRectangle').ArcGISCategory = _(u'Pre-conversion processing')
3298
3299CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'mapAlgebraExpression', ArcGISRaster.ToPolygons, u'mapAlgebraExpression')
3300ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'mapAlgebraExpression').ArcGISCategory = _(u'Pre-conversion processing')
3301
3302AddArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting',
3303    typeMetadata=BooleanTypeMetadata(),
3304    description=_(
3305u"""If True, the output feature class will be overwritten, if it
3306exists. If False, a ValueError will be raised if the output feature
3307class exists."""),
3308    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
3309
3310# Public method: ArcGISRaster.ToPolygonOutlines
3311
3312AddMethodMetadata(ArcGISRaster.ToPolygonOutlines,
3313    shortDescription=_(u'Converts an ArcGIS raster to lines that outline groups of adjacent raster cells having the same value.'),
3314    isExposedToPythonCallers=True,
3315    isExposedByCOM=True,
3316    isExposedAsArcGISTool=True,
3317    arcGISDisplayName=_(u'Convert ArcGIS Raster to Polygon Outlines'),
3318    arcGISToolCategory=_(u'Conversion\\To Polygon Outlines\\From ArcGIS Raster'),
3319    dependencies=[ArcGISDependency(9, 1)])
3320
3321CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToPolygonOutlines, u'cls')
3322
3323AddArgumentMetadata(ArcGISRaster.ToPolygonOutlines, u'inputRaster',
3324    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3325    description=_(
3326u"""Raster to convert.
3327
3328The raster will be converted to a polygon feature class using the
3329ArcGIS Raster to Polygon tool, and then to line features using the
3330Feature to Line tool. The Raster to Polygon tool can only convert
3331integer rasters to polygons. If the input raster is a floating-point
3332raster, you must use the Map Algebra Expression parameter to convert
3333it to an integer raster."""),
3334    arcGISDisplayName=_(u'Input raster'))
3335
3336AddArgumentMetadata(ArcGISRaster.ToPolygonOutlines, u'outputFeatureClass',
3337    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'polyline'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3338    description=_(
3339u"""Output line feature class.
3340
3341Missing directories in this path will be created if they do not
3342exist."""),
3343    direction=u'Output',
3344    arcGISDisplayName=_(u'Output line feature class'))
3345
3346CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'simplify', ArcGISRaster.ToPolygonOutlines, u'simplify')
3347
3348AddArgumentMetadata(ArcGISRaster.ToPolygonOutlines, u'field',
3349    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3350    description=_(
3351u"""The field used to assign values from the cells in the input raster
3352to the lines in the output dataset. It can be an integer or a
3353string field."""),
3354    arcGISParameterDependencies=[u'inputRaster'],
3355    arcGISDisplayName=_(u'Field'))
3356
3357CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCoordinateSystem', ArcGISRaster.ToPolygonOutlines, u'projectedCoordinateSystem')
3358CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'geographicTransformation', ArcGISRaster.ToPolygonOutlines, u'geographicTransformation')
3359CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'resamplingTechnique', ArcGISRaster.ToPolygonOutlines, u'resamplingTechnique')
3360CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCellSize', ArcGISRaster.ToPolygonOutlines, u'projectedCellSize')
3361CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'registrationPoint', ArcGISRaster.ToPolygonOutlines, u'registrationPoint')
3362CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingDataset', ArcGISRaster.ToPolygonOutlines, u'clippingDataset')
3363CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingRectangle', ArcGISRaster.ToPolygonOutlines, u'clippingRectangle')
3364CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'mapAlgebraExpression', ArcGISRaster.ToPolygonOutlines, u'mapAlgebraExpression')
3365CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting', ArcGISRaster.ToPolygonOutlines, u'overwriteExisting')
3366
3367# Public method: ArcGISRaster.ToLines
3368
3369AddMethodMetadata(ArcGISRaster.ToLines,
3370    shortDescription=_(u'Converts an ArcGIS raster to a feature class of lines that connect adjacent foreground raster cells.'),
3371    isExposedToPythonCallers=True,
3372    isExposedByCOM=True,
3373    isExposedAsArcGISTool=True,
3374    arcGISDisplayName=_(u'Convert ArcGIS Raster to Lines'),
3375    arcGISToolCategory=_(u'Conversion\\To Lines\\From ArcGIS Raster'),
3376    dependencies=[ArcGISDependency(9, 1)])
3377
3378CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToLines, u'cls')
3379
3380AddArgumentMetadata(ArcGISRaster.ToLines, u'inputRaster',
3381    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3382    description=_(
3383u"""Raster to convert.
3384
3385The raster will be converted to a line feature class using the
3386ArcGIS Raster to Polyline tool. For each pair of adjacent foreground
3387raster cells, the tool draws a line connecting their centers. This
3388algorithm is appropriate for converting line-like raster features,
3389such as sea surface temperature fronts or other boundary data, into
3390vector features."""),
3391    arcGISDisplayName=_(u'Input raster'))
3392
3393AddArgumentMetadata(ArcGISRaster.ToLines, u'outputFeatureClass',
3394    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'polyline'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3395    description=_(
3396u"""Output polygon feature class that will contain the converted
3397lines.
3398
3399Missing directories in this path will be created if they do not
3400exist."""),
3401    direction=u'Output',
3402    arcGISDisplayName=_(u'Output line feature class'))
3403
3404AddArgumentMetadata(ArcGISRaster.ToLines, u'backgroundValue',
3405    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'ZERO', u'NODATA'], makeLowercase=True),
3406    description=_(
3407u"""Specifies the cell value that will identify the background cells.
3408The raster dataset is viewed as a set of foreground cells and
3409background cells. The linear features are formed from the foreground
3410cells.
3411
3412* ZERO - The background is composed of cells of zero or less or
3413  NoData. All cells with a value greater than zero are considered a
3414  foreground value.
3415
3416* NODATA - The background is composed of NoData cells. All cells with
3417  valid values belong to the foreground.
3418"""),
3419    arcGISDisplayName=_(u'Background value'))
3420
3421AddArgumentMetadata(ArcGISRaster.ToLines, u'minDangleLength',
3422    typeMetadata=FloatTypeMetadata(minValue=0.0),
3423    description=_(
3424u"""Minimum length of dangling lines that will be retained. The
3425default is zero."""),
3426    arcGISDisplayName=_(u'Minimum dangle length'))
3427
3428AddArgumentMetadata(ArcGISRaster.ToLines, u'simplify',
3429    typeMetadata=BooleanTypeMetadata(),
3430    description=_(
3431u"""If True (the default) the output lines will be smoothed
3432according to an undocumented algorithm implemented by the ArcGIS
3433Raster to Polyline tool."""),
3434    arcGISDisplayName=_(u'Simplify lines'))
3435
3436AddArgumentMetadata(ArcGISRaster.ToLines, u'field',
3437    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3438    description=_(
3439u"""The field used to assign values from the cells in the input raster
3440to the lines in the output dataset. It can be an integer or a
3441string field."""),
3442    arcGISParameterDependencies=[u'inputRaster'],
3443    arcGISDisplayName=_(u'Field'))
3444
3445CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCoordinateSystem', ArcGISRaster.ToLines, u'projectedCoordinateSystem')
3446CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'geographicTransformation', ArcGISRaster.ToLines, u'geographicTransformation')
3447CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'resamplingTechnique', ArcGISRaster.ToLines, u'resamplingTechnique')
3448CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCellSize', ArcGISRaster.ToLines, u'projectedCellSize')
3449CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'registrationPoint', ArcGISRaster.ToLines, u'registrationPoint')
3450CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingDataset', ArcGISRaster.ToLines, u'clippingDataset')
3451CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingRectangle', ArcGISRaster.ToLines, u'clippingRectangle')
3452CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'mapAlgebraExpression', ArcGISRaster.ToLines, u'mapAlgebraExpression')
3453CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting', ArcGISRaster.ToLines, u'overwriteExisting')
3454
3455# Public method: ArcGISRaster.ToPoints
3456
3457AddMethodMetadata(ArcGISRaster.ToPoints,
3458    shortDescription=_(u'Converts an ArcGIS raster to a feature class of points that occur at the centers of the raster cells.'),
3459    isExposedToPythonCallers=True,
3460    isExposedByCOM=True,
3461    isExposedAsArcGISTool=True,
3462    arcGISDisplayName=_(u'Convert ArcGIS Raster to Points'),
3463    arcGISToolCategory=_(u'Conversion\\To Points\\From ArcGIS Raster'),
3464    dependencies=[ArcGISDependency(9, 1)])
3465
3466CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToPoints, u'cls')
3467
3468AddArgumentMetadata(ArcGISRaster.ToPoints, u'inputRaster',
3469    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3470    description=_(
3471u"""Raster to convert.
3472
3473The raster will be converted to a point feature class using the ArcGIS
3474Raster to Point tool. This tool creates a point at the center of each
3475raster cell, except noData cells."""),
3476    arcGISDisplayName=_(u'Input raster'))
3477
3478AddArgumentMetadata(ArcGISRaster.ToPoints, u'outputFeatureClass',
3479    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'point'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3480    description=_(
3481u"""Output point feature class.
3482
3483Missing directories in this path will be created if they do not
3484exist."""),
3485    direction=u'Output',
3486    arcGISDisplayName=_(u'Output point feature class'))
3487
3488AddArgumentMetadata(ArcGISRaster.ToPoints, u'field',
3489    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3490    description=_(
3491u"""The field used to assign values from the cells in the input raster
3492to the points in the output dataset. It can be an integer,
3493floating-point, or string field."""),
3494    arcGISParameterDependencies=[u'inputRaster'],
3495    arcGISDisplayName=_(u'Field'))
3496
3497CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCoordinateSystem', ArcGISRaster.ToPoints, u'projectedCoordinateSystem')
3498CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'geographicTransformation', ArcGISRaster.ToPoints, u'geographicTransformation')
3499CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'resamplingTechnique', ArcGISRaster.ToPoints, u'resamplingTechnique')
3500CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCellSize', ArcGISRaster.ToPoints, u'projectedCellSize')
3501CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'registrationPoint', ArcGISRaster.ToPoints, u'registrationPoint')
3502CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingDataset', ArcGISRaster.ToPoints, u'clippingDataset')
3503CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingRectangle', ArcGISRaster.ToPoints, u'clippingRectangle')
3504CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'mapAlgebraExpression', ArcGISRaster.ToPoints, u'mapAlgebraExpression')
3505CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting', ArcGISRaster.ToPoints, u'overwriteExisting')
3506
3507###############################################################################
3508# Batch processing versions of methods
3509###############################################################################
3510
3511from GeoEco.BatchProcessing import BatchProcessing
3512from GeoEco.DataManagement.Fields import Field
3513
3514BatchProcessing.GenerateForMethod(ArcGISRaster.Copy,
3515    inputParamNames=[u'sourceRaster'],
3516    inputParamFieldArcGISDisplayNames=[_(u'Source raster field')],
3517    inputParamDescriptions=[_(u'%s rasters to copy.')],
3518    outputParamNames=[u'destinationRaster'],
3519    outputParamFieldArcGISDisplayNames=[_(u'Destination raster field')],
3520    outputParamExpressionArcGISDisplayNames=[_(u'Destination raster Python expression')],
3521    outputParamDescriptions=[_(u'%s destination rasters.')],
3522    outputParamExpressionDescriptions=[
3523u"""Python expression used to calculate the absolute path of a
3524destination raster. The expression may be any Python statement
3525appropriate for passing to the eval function and must return a Unicode
3526string. The expression may reference the following variables:
3527
3528* workspaceToSearch - the value provided for the workspace to search
3529  parameter
3530
3531* destinationWorkspace - the value provided for the destination
3532  workspace parameter
3533
3534* sourceRaster - the absolute path to the source raster
3535
3536The default expression::
3537
3538    os.path.join(destinationWorkspace, sourceRaster[len(workspaceToSearch)+1:])
3539
3540stores the raster in the destination workspace at the same relative
3541location it appears in the workspace to search. The destination path
3542is calculated by stripping the workspace to search from the source
3543path and replacing it with the destination workspace.
3544
3545For more information on Python syntax, please see the `Python
3546documentation <http://www.python.org/doc/>`_."""],
3547    outputParamDefaultExpressions=[u'os.path.join(destinationWorkspace, sourceRaster[len(workspaceToSearch)+1:])'],
3548    processListMethodName=u'CopyList',
3549    processListMethodShortDescription=_(u'Copies a list of ArcGIS rasters.'),
3550    processTableMethodName=u'CopyTable',
3551    processTableMethodShortDescription=_(u'Copies the ArcGIS rasters listed in a table.'),
3552    processArcGISTableMethodName=u'CopyArcGISTable',
3553    processArcGISTableMethodArcGISDisplayName=_(u'Copy Rasters Listed in Table'),
3554    findAndProcessMethodName=u'FindAndCopy',
3555    findAndProcessMethodArcGISDisplayName=u'Find and Copy Rasters',
3556    findAndProcessMethodShortDescription=_(u'Finds and copies rasters in an ArcGIS workspace.'),
3557    findMethod=ArcGISRaster.FindAndCreateTable,
3558    findOutputFieldParams=[u'rasterField'],
3559    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3560    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3561    outputLocationParamDescription=_(u'Workspace to receive copies of the rasters.'),
3562    outputLocationParamArcGISDisplayName=_(u'Destination workspace'),
3563    calculateFieldMethod=Field.CalculateField,
3564    calculateFieldExpressionParam=u'pythonExpression',
3565    calculateFieldAdditionalParams=[u'modulesToImport'],
3566    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3567    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3568    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    destinationWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'sourceRaster = row.sourceRaster']],
3569    calculatedOutputsArcGISCategory=_(u'Destination raster name options'),
3570    skipExistingDescription=_(u'If True, copying will be skipped for destination rasters that already exist.'),
3571    overwriteExistingDescription=_(u'If True and skipExisting is False, existing destination rasters will be overwritten.'))
3572
3573BatchProcessing.GenerateForMethod(ArcGISRaster.Delete,
3574    inputParamNames=[u'raster'],
3575    inputParamFieldArcGISDisplayNames=[_(u'Raster field')],
3576    inputParamDescriptions=[_(u'%s rasters to delete.')],
3577    processListMethodName=u'DeleteList',
3578    processListMethodShortDescription=_(u'Deletes a list of ArcGIS rasters.'),
3579    processTableMethodName=u'DeleteTable',
3580    processTableMethodShortDescription=_(u'Deletes the ArcGIS rasters listed in a table.'),
3581    processArcGISTableMethodName=u'DeleteArcGISTable',
3582    processArcGISTableMethodArcGISDisplayName=_(u'Delete Rasters Listed in Table'),
3583    findAndProcessMethodName=u'FindAndDelete',
3584    findAndProcessMethodArcGISDisplayName=u'Find and Delete Rasters',
3585    findAndProcessMethodShortDescription=_(u'Finds and deletes rasters in an ArcGIS workspace.'),
3586    findMethod=ArcGISRaster.FindAndCreateTable,
3587    findOutputFieldParams=[u'rasterField'],
3588    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'])
3589
3590BatchProcessing.GenerateForMethod(ArcGISRaster.Move,
3591    inputParamNames=[u'sourceRaster'],
3592    inputParamFieldArcGISDisplayNames=[_(u'Source raster field')],
3593    inputParamDescriptions=[_(u'%s rasters to move.')],
3594    outputParamNames=[u'destinationRaster'],
3595    outputParamFieldArcGISDisplayNames=[_(u'Destination raster field')],
3596    outputParamExpressionArcGISDisplayNames=[_(u'Destination raster Python expression')],
3597    outputParamDescriptions=[_(u'%s destination rasters.')],
3598    outputParamExpressionDescriptions=[ArcGISRaster.FindAndCopy.__doc__.Obj.GetArgumentByName(u'destinationRasterPythonExpression').Description],
3599    outputParamDefaultExpressions=[ArcGISRaster.FindAndCopy.__doc__.Obj.GetArgumentByName(u'destinationRasterPythonExpression').Default],
3600    processListMethodName=u'MoveList',
3601    processListMethodShortDescription=_(u'Moves a list of ArcGIS rasters.'),
3602    processTableMethodName=u'MoveTable',
3603    processTableMethodShortDescription=_(u'Moves the ArcGIS rasters listed in a table.'),
3604    processArcGISTableMethodName=u'MoveArcGISTable',
3605    processArcGISTableMethodArcGISDisplayName=_(u'Move Rasters Listed in Table'),
3606    findAndProcessMethodName=u'FindAndMove',
3607    findAndProcessMethodArcGISDisplayName=u'Find and Move Rasters',
3608    findAndProcessMethodShortDescription=_(u'Finds and moves rasters in an ArcGIS workspace.'),
3609    findMethod=ArcGISRaster.FindAndCreateTable,
3610    findOutputFieldParams=[u'rasterField'],
3611    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3612    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3613    outputLocationParamDescription=_(u'Workspace to receive the rasters.'),
3614    outputLocationParamArcGISDisplayName=_(u'Destination workspace'),
3615    calculateFieldMethod=Field.CalculateField,
3616    calculateFieldExpressionParam=u'pythonExpression',
3617    calculateFieldAdditionalParams=[u'modulesToImport'],
3618    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3619    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3620    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    destinationWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'sourceRaster = row.sourceRaster']],
3621    calculatedOutputsArcGISCategory=_(u'Destination raster name options'),
3622    skipExistingDescription=_(u'If True, moving will be skipped for destination rasters that already exist.'),
3623    overwriteExistingDescription=_(u'If True and skipExisting is False, existing destination rasters will be overwritten.'))
3624
3625BatchProcessing.GenerateForMethod(ArcGISRaster.ExtractByMask,
3626    inputParamNames=[u'inputRaster'],
3627    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3628    inputParamDescriptions=[_(u'%s input rasters.')],
3629    outputParamNames=[u'outputRaster'],
3630    outputParamFieldArcGISDisplayNames=[_(u'Output raster field')],
3631    outputParamExpressionArcGISDisplayNames=[_(u'Output raster Python expression')],
3632    outputParamDescriptions=[_(
3633u"""%s output rasters to receive the cell values extracted from the
3634input rasters.
3635
3636If these paths refers to the file system, missing directories in the
3637paths will be created if they do not exist.""")],
3638    outputParamExpressionDescriptions=[
3639u"""Python expression used to calculate the absolute path of an output
3640raster. The expression may be any Python statement appropriate
3641for passing to the eval function and must return a Unicode string. The
3642expression may reference the following variables:
3643
3644* workspaceToSearch - the value provided for the workspace to search
3645  parameter
3646
3647* outputWorkspace - the value provided for the output workspace
3648  parameter
3649
3650* inputRaster - the absolute path to the input raster
3651
3652The default expression::
3653
3654    os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])
3655
3656stores the output rasters in the output workspace at the same relative
3657location as the input rasteres appear in the workspace to search. The
3658output raster path is calculated by stripping the workspace to search
3659from the input raster path and replacing it with the output workspace.
3660
3661For more information on Python syntax, please see the `Python
3662documentation <http://www.python.org/doc/>`_."""],
3663    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3664    constantParamNames=[u'mask'],
3665    processListMethodName=u'ExtractByMaskList',
3666    processListMethodShortDescription=_(u'For each ArcGIS raster in a list, extracts the cells that correspond to the areas defined by a mask.'),
3667    processTableMethodName=u'ExtractByMaskTable',
3668    processTableMethodShortDescription=_(u'For each ArcGIS raster in a table, extracts the cells that correspond to the areas defined by a mask.'),
3669    processArcGISTableMethodName=u'ExtractByMaskArcGISTable',
3670    processArcGISTableMethodArcGISDisplayName=_(u'Extract By Mask for ArcGIS Rasters Listed in Table'),
3671    findAndProcessMethodName=u'FindAndExtractByMask',
3672    findAndProcessMethodArcGISDisplayName=u'Find ArcGIS Rasters and Extract By Mask',
3673    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and extracts the cells that correspond to the areas defined by a mask.'),
3674    findMethod=ArcGISRaster.FindAndCreateTable,
3675    findOutputFieldParams=[u'rasterField'],
3676    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3677    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3678    outputLocationParamDescription=_(u'Workspace to receive the output rasters.'),
3679    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3680    calculateFieldMethod=Field.CalculateField,
3681    calculateFieldExpressionParam=u'pythonExpression',
3682    calculateFieldAdditionalParams=[u'modulesToImport'],
3683    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3684    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3685    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    outputWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'inputRaster = row.inputRaster']],
3686    calculatedOutputsArcGISCategory=_(u'Output raster name options'),
3687    skipExistingDescription=_(u'If True, processing will be skipped for output rasters that already exist.'),
3688    overwriteExistingDescription=_(u'If True and skipExisting is False, existing output rasters will be overwritten.'))
3689
3690BatchProcessing.GenerateForMethod(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra,
3691    inputParamNames=[u'inputRaster'],
3692    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3693    inputParamDescriptions=[_(u'%s input rasters.')],
3694    outputParamNames=[u'outputRaster'],
3695    outputParamFieldArcGISDisplayNames=[_(u'Output raster field')],
3696    outputParamExpressionArcGISDisplayNames=[_(u'Output raster Python expression')],
3697    outputParamDescriptions=[_(
3698u"""%s output rasters.
3699
3700If these paths refers to the file system, missing directories in the
3701paths will be created if they do not exist.""")],
3702    outputParamExpressionDescriptions=[
3703u"""Python expression used to calculate the absolute path of an output
3704raster. The expression may be any Python statement appropriate
3705for passing to the eval function and must return a Unicode string. The
3706expression may reference the following variables:
3707
3708* workspaceToSearch - the value provided for the workspace to search
3709  parameter
3710
3711* outputWorkspace - the value provided for the output workspace
3712  parameter
3713
3714* inputRaster - the absolute path to the input raster
3715
3716The default expression::
3717
3718    os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])
3719
3720stores the output rasters in the output workspace at the same relative
3721location as the input rasteres appear in the workspace to search. The
3722output raster path is calculated by stripping the workspace to search
3723from the input raster path and replacing it with the output workspace.
3724
3725For more information on Python syntax, please see the `Python
3726documentation <http://www.python.org/doc/>`_."""],
3727    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3728    constantParamNames=[u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression', u'buildPyramids'],
3729    processListMethodName=u'ProjectClipAndOrExecuteMapAlgebraList',
3730    processListMethodShortDescription=_(u'Projects, clips, and/or perfoms map algebra on the ArcGIS rasters in a list. You must request at least one of these three operations. If you request multiple operations, the tool performs them in the order they are listed.'),
3731    processTableMethodName=u'ProjectClipAndOrExecuteMapAlgebraTable',
3732    processTableMethodShortDescription=_(u'Projects, clips, and/or perfoms map algebra on the ArcGIS rasters listed in a table. You must request at least one of these three operations. If you request multiple operations, the tool performs them in the order they are listed.'),
3733    processArcGISTableMethodName=u'ProjectClipAndOrExecuteMapAlgebraArcGISTable',
3734    processArcGISTableMethodArcGISDisplayName=_(u'Project, Clip, and/or Execute Map Algebra on ArcGIS Rasters Listed in Table'),
3735    findAndProcessMethodName=u'FindAndProjectClipAndOrExecuteMapAlgebra',
3736    findAndProcessMethodArcGISDisplayName=u'Find ArcGIS Rasters and Project, Clip, and/or Execute Map Algebra',
3737    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and projects, clips, and/or perfoms map algebra on them. You must request at least one of these three operations. If you request multiple operations, the tool performs them in the order they are listed.'),
3738    findMethod=ArcGISRaster.FindAndCreateTable,
3739    findOutputFieldParams=[u'rasterField'],
3740    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3741    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3742    outputLocationParamDescription=_(u'Workspace to receive the output rasters.'),
3743    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3744    calculateFieldMethod=Field.CalculateField,
3745    calculateFieldExpressionParam=u'pythonExpression',
3746    calculateFieldAdditionalParams=[u'modulesToImport'],
3747    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3748    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3749    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    outputWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'inputRaster = row.inputRaster']],
3750    calculatedOutputsArcGISCategory=_(u'Output raster name options'),
3751    skipExistingDescription=_(u'If True, processing will be skipped for output rasters that already exist.'),
3752    overwriteExistingDescription=_(u'If True and skipExisting is False, existing output rasters will be overwritten.'))
3753
3754_OutputFeatureClassParamExpressionDescription = _(u"""Python expression used to calculate the absolute path of an output
3755feature class. The expression may be any Python statement appropriate
3756for passing to the eval function and must return a Unicode string. The
3757expression may reference the following variables:
3758
3759* workspaceToSearch - the value provided for the workspace to search
3760  parameter
3761
3762* outputWorkspace - the value provided for the output workspace
3763  parameter
3764
3765* inputRaster - the absolute path to the input raster
3766
3767The default expression::
3768
3769    os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])
3770
3771stores the feature classes in the output workspace at the same
3772relative location as the input rasteres in the workspace to search.
3773The feature class path is calculated by stripping the workspace to
3774search from the input raster path and replacing it with the output
3775workspace.
3776
3777For more information on Python syntax, please see the `Python
3778documentation <http://www.python.org/doc/>`_.""")
3779
3780BatchProcessing.GenerateForMethod(ArcGISRaster.ToPolygons,
3781    inputParamNames=[u'inputRaster'],
3782    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3783    inputParamDescriptions=[_(
3784u"""%s rasters to convert.
3785
3786The rasters will be converted to polygon feature classes using the
3787ArcGIS Raster to Polygon tool. That tool can only convert integer
3788rasters to polygons. If the input rasters are floating-point rasters,
3789you must use the Map Algebra Expression parameter to convert them to
3790integer rasters.""")],
3791    outputParamNames=[u'outputFeatureClass'],
3792    outputParamFieldArcGISDisplayNames=[_(u'Output polygon feature class field')],
3793    outputParamExpressionArcGISDisplayNames=[_(u'Output polygon feature class Python expression')],
3794    outputParamDescriptions=[_(
3795u"""%s output polygon feature classes.
3796
3797One feature class will be created per raster. Missing directories the
3798output paths will be created if they do not exist.""")],
3799    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3800    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3801    constantParamNames=[u'simplify', u'field', u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression'],
3802    processListMethodName=u'ToPolygonsList',
3803    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to polygons that encompass groups of adjacent raster cells having the same value.'),
3804    processTableMethodName=u'ToPolygonsTable',
3805    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to polygons that encompass groups of adjacent raster cells having the same value.'),
3806    processArcGISTableMethodName=u'ToPolygonsArcGISTable',
3807    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Polygons'),
3808    findAndProcessMethodName=u'FindAndConvertToPolygons',
3809    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Polygons',
3810    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to polygons that encompass groups of adjacent raster cells having the same value.'),
3811    findMethod=ArcGISRaster.FindAndCreateTable,
3812    findOutputFieldParams=[u'rasterField'],
3813    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3814    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3815    outputLocationParamDescription=_(u'Workspace to receive the polygon feature classes.'),
3816    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3817    calculateFieldMethod=Field.CalculateField,
3818    calculateFieldExpressionParam=u'pythonExpression',
3819    calculateFieldAdditionalParams=[u'modulesToImport'],
3820    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3821    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3822    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    outputWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'inputRaster = row.inputRaster']],
3823    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3824    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3825    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3826
3827BatchProcessing.GenerateForMethod(ArcGISRaster.ToPolygonOutlines,
3828    inputParamNames=[u'inputRaster'],
3829    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3830    inputParamDescriptions=[_(
3831u"""%s rasters to convert.
3832
3833The rasters will be converted to polygon feature classes using the
3834ArcGIS Raster to Polygon tool, and then to line features using the
3835Feature to Line tool. The Raster to Polygon tool can only convert
3836integer rasters to polygons. If the input rasters are floating-point
3837rasters, you must use the Map Algebra Expression parameter to convert
3838them to integer rasters.""")],
3839    outputParamNames=[u'outputFeatureClass'],
3840    outputParamFieldArcGISDisplayNames=[_(u'Output line feature class field')],
3841    outputParamExpressionArcGISDisplayNames=[_(u'Output line feature class Python expression')],
3842    outputParamDescriptions=[_(
3843u"""%s output line feature classes.
3844
3845One feature class will be created per raster. Missing directories the
3846output paths will be created if they do not exist.""")],
3847    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3848    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3849    constantParamNames=[u'simplify', u'field', u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression'],
3850    processListMethodName=u'ToPolygonOutlinesList',
3851    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to lines that outline groups of adjacent raster cells having the same value.'),
3852    processTableMethodName=u'ToPolygonOutlinesTable',
3853    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to lines that outline groups of adjacent raster cells having the same value.'),
3854    processArcGISTableMethodName=u'ToPolygonOutlinesArcGISTable',
3855    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Polygon Outlines'),
3856    findAndProcessMethodName=u'FindAndConvertToPolygonOutlines',
3857    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Polygon Outlines',
3858    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to lines that outline groups of adjacent raster cells having the same value.'),
3859    findMethod=ArcGISRaster.FindAndCreateTable,
3860    findOutputFieldParams=[u'rasterField'],
3861    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3862    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3863    outputLocationParamDescription=_(u'Workspace to receive the line feature classes.'),
3864    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3865    calculateFieldMethod=Field.CalculateField,
3866    calculateFieldExpressionParam=u'pythonExpression',
3867    calculateFieldAdditionalParams=[u'modulesToImport'],
3868    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3869    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3870    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    outputWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'inputRaster = row.inputRaster']],
3871    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3872    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3873    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3874
3875BatchProcessing.GenerateForMethod(ArcGISRaster.ToLines,
3876    inputParamNames=[u'inputRaster'],
3877    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3878    inputParamDescriptions=[_(
3879u"""%s rasters to convert.
3880
3881The rasters will be converted to line feature classes using the
3882ArcGIS Raster to Polyline tool. For each pair of adjacent foreground
3883raster cells, the tool draws a line connecting their centers. This
3884algorithm is appropriate for converting line-like raster features,
3885such as sea surface temperature fronts or other boundary data, into
3886vector features.""")],
3887    outputParamNames=[u'outputFeatureClass'],
3888    outputParamFieldArcGISDisplayNames=[_(u'Output line feature class field')],
3889    outputParamExpressionArcGISDisplayNames=[_(u'Output line feature class Python expression')],
3890    outputParamDescriptions=[_(
3891u"""%s output line feature classes.
3892
3893One feature class will be created per raster. Missing directories the
3894output paths will be created if they do not exist.""")],
3895    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3896    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3897    constantParamNames=[u'backgroundValue', u'minDangleLength', u'simplify', u'field', u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression'],
3898    processListMethodName=u'ToLinesList',
3899    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to lines that outline groups of adjacent raster cells having the same value.'),
3900    processTableMethodName=u'ToLinesTable',
3901    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to lines that outline groups of adjacent raster cells having the same value.'),
3902    processArcGISTableMethodName=u'ToLinesArcGISTable',
3903    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Lines'),
3904    findAndProcessMethodName=u'FindAndConvertToLines',
3905    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Lines',
3906    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to lines that outline groups of adjacent raster cells having the same value.'),
3907    findMethod=ArcGISRaster.FindAndCreateTable,
3908    findOutputFieldParams=[u'rasterField'],
3909    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3910    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3911    outputLocationParamDescription=_(u'Workspace to receive the line feature classes.'),
3912    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3913    calculateFieldMethod=Field.CalculateField,
3914    calculateFieldExpressionParam=u'pythonExpression',
3915    calculateFieldAdditionalParams=[u'modulesToImport'],
3916    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3917    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3918    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    outputWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'inputRaster = row.inputRaster']],
3919    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3920    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3921    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3922
3923BatchProcessing.GenerateForMethod(ArcGISRaster.ToPoints,
3924    inputParamNames=[u'inputRaster'],
3925    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3926    inputParamDescriptions=[_(
3927u"""%s rasters to convert.
3928
3929The rasters will be converted to point feature classes using the
3930ArcGIS Raster to Point tool. This tool creates a point at the center
3931of each raster cell, except NoData cells.""")],
3932    outputParamNames=[u'outputFeatureClass'],
3933    outputParamFieldArcGISDisplayNames=[_(u'Output point feature class field')],
3934    outputParamExpressionArcGISDisplayNames=[_(u'Output point feature class Python expression')],
3935    outputParamDescriptions=[_(
3936u"""%s output point feature classes.
3937
3938One feature class will be created per raster. Missing directories the
3939output paths will be created if they do not exist.""")],
3940    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3941    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3942    constantParamNames=[u'field', u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression'],
3943    processListMethodName=u'ToPointsList',
3944    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to points that occur at the centers of the raster cells.'),
3945    processTableMethodName=u'ToPointsTable',
3946    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to points that occur at the centers of the raster cells.'),
3947    processArcGISTableMethodName=u'ToPointsArcGISTable',
3948    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Points'),
3949    findAndProcessMethodName=u'FindAndConvertToPoints',
3950    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Points',
3951    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to points that occur at the centers of the raster cells.'),
3952    findMethod=ArcGISRaster.FindAndCreateTable,
3953    findOutputFieldParams=[u'rasterField'],
3954    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3955    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3956    outputLocationParamDescription=_(u'Workspace to receive the point feature classes.'),
3957    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3958    calculateFieldMethod=Field.CalculateField,
3959    calculateFieldExpressionParam=u'pythonExpression',
3960    calculateFieldAdditionalParams=[u'modulesToImport'],
3961    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3962    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3963    calculateFieldHiddenParamValues=[[u'import inspect\nf = inspect.currentframe()\ntry:\n    workspaceToSearch = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'inputWorkspace\']\n    outputWorkspace = f.f_back.f_back.f_back.f_back.f_back.f_locals[\'outputWorkspace\']\nfinally:\n    del f\n'], [u'inputRaster = row.inputRaster']],
3964    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3965    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3966    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3967
3968###############################################################################
3969# Names exported by this module
3970###############################################################################
3971
3972__all__ = ['ArcGISRaster']
Note: See TracBrowser for help on using the browser.