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

Revision 916, 214.4 KB (checked in by jjr8, 16 months ago)

Adjusted locations of vector tools in the ArcToolbox? tree.

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        cls.__doc__.Obj.ValidateMethodInvocation()
1724        try:
1725            # Perform additional validation.
1726
1727            if interpolationMethod is not None and resamplingTechnique.lower() not in [u'bilinear', u'cubic']:
1728                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.'))
1729
1730            # Look up the coordinate system, extent, and cell size of
1731            # the template raster.
1732
1733            gp = GeoprocessorManager.GetWrappedGeoprocessor()
1734            d = gp.Describe(templateRaster)
1735            coordinateSystem = gp.CreateSpatialReference(d.SpatialReference).split(';')[0]
1736            extent = d.Extent
1737            cellSize = d.MeanCellWidth
1738           
1739            # Below, we will set the Extent environment variable and
1740            # then call ArcGIS's ProjectRaster_management to
1741            # simultaneously project and clip the input raster to the
1742            # coordinate system, extent, and cell size of the template
1743            # raster. Unfortunately ProjectRaster_management will not
1744            # necessarily create a raster that has exactly the desired
1745            # extent. It may be one cell larger or smaller in any of
1746            # the four directions. Different versions of ArcGIS seem
1747            # to work differently in this respect.
1748            #
1749            # To deal with this annoyance, we will expand the extent
1750            # in all four directions by 10 cells--guaranteeing that we
1751            # have a raster that is larger than the desired
1752            # extent--and then use ExtractByMask_sa to obtain a raster
1753            # of the desired extent.
1754            #
1755            # We use 10 cells rather than 1 cell because of a
1756            # different problem: if the caller requested that we
1757            # interpolate values for No Data cells, the most accurate
1758            # values can be obtained if each No Data region is
1759            # completely surrounded by cells with data. In the event
1760            # that the template raster extent bisects a No Data
1761            # region, the 10 cell buffer increases the chance that we
1762            # will interpolate that region using cells from both sides
1763            # of the extent line: the side that is within the template
1764            # extent and also the side that is outside the extent but
1765            # within the buffer.
1766
1767            from GeoEco.DataManagement.Directories import TemporaryDirectory
1768            tempDir = TemporaryDirectory()
1769
1770            [left, bottom, right, top] = EnvelopeTypeMetadata.ParseFromArcGISString(extent)
1771            oldExtent = gp.Extent
1772            gp.Extent = '%r %r %r %r' % (left - cellSize*10, bottom - cellSize*10, right + cellSize*10, top + cellSize*10)
1773
1774            try:
1775                # If this is ArcGIS 9.3, set the SnapRaster
1776                # environment variable to the template raster.
1777               
1778                if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 3:
1779                    oldSnapRaster = gp.SnapRaster
1780                    gp.SnapRaster = templateRaster
1781
1782                # Project the raster. If this is ArcGIS 9.3 or later,
1783                # the SnapRaster and Extent environment variables will
1784                # ensure the projected cells are snapped and clipped
1785                # as requested by the caller. If it is 9.2, use the
1786                # Registration_Point parameter instead of SnapRaster,
1787                # which did not exist in 9.2 (there was something like
1788                # it, but it did not work correctly).
1789
1790                try:
1791                    projectedRaster = os.path.join(tempDir.Path, u'projected.img')
1792                    if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 3:
1793                        gp.ProjectRaster_management(inputRaster, projectedRaster, coordinateSystem, resamplingTechnique, cellSize)
1794                    else:
1795                        gp.ProjectRaster_management(inputRaster, projectedRaster, coordinateSystem, resamplingTechnique, cellSize, None, extent.rsplit(' ', 2)[0])
1796
1797                # If this is ArcGIS 9.3, reset the SnapRaster
1798                # environment variable to what it was before.
1799               
1800                finally:
1801                    if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMajorVersion() == 9 and GeoprocessorManager.GetArcGISMinorVersion() >= 3:
1802                        gp.SnapRaster = oldSnapRaster
1803
1804            # Reset the Extent ArcGIS environment variable to what it
1805            # was before.
1806           
1807            finally:
1808                gp.Extent = oldExtent
1809
1810            # If the caller requested that we interpolate values for
1811            # No Data regions, do it now.
1812
1813            if interpolationMethod is not None:
1814                from GeoEco.SpatialAnalysis.Interpolation import Interpolator
1815                infilledRaster = os.path.join(tempDir.Path, u'infilled.img')
1816                Interpolator.InpaintArcGISRaster(projectedRaster, infilledRaster, interpolationMethod, maxHoleSize)
1817                projectedRaster = infilledRaster
1818
1819            # We are about to use ExtractByMask_sa to extract a raster
1820            # of the desired extent from the projected raster in the
1821            # temp directory. But ExtractByMask_sa also has a side
1822            # effect that we might not want: it sets cells that are No
1823            # Data in the mask to No Data in the output raster. If the
1824            # caller did not request that to happen (using the
1825            # template raster as the mask), create a constant raster
1826            # that has the same coordinate system, extent, and cell
1827            # size as the template raster. We'll use it instead.
1828
1829            if not mask:
1830                oldOutputCoordinateSystem = gp.OutputCoordinateSystem
1831                gp.OutputCoordinateSystem = coordinateSystem
1832                try:
1833                    maskRaster = os.path.join(tempDir.Path, u'constant.img')
1834                    gp.CreateConstantRaster_sa(maskRaster, 0, 'INTEGER', cellSize, extent)
1835                finally:
1836                    gp.OutputCoordinateSystem = oldOutputCoordinateSystem
1837
1838                # For safety, verify that the output raster has the
1839                # expected number of columns and rows.
1840               
1841                d2 = gp.Describe(maskRaster)
1842                if d2.Width != d.Width or d2.Height != d.Height:
1843                    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.'))
1844
1845            else:
1846                maskRaster = templateRaster
1847
1848            # Extract the raster.
1849
1850            gp.ExtractByMask_sa(projectedRaster, maskRaster, outputRaster)
1851
1852        except:
1853            Logger.LogExceptionAsError()
1854            raise
1855
1856    @classmethod
1857    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):
1858        cls.__doc__.Obj.ValidateMethodInvocation()
1859       
1860        # Perform additional validation.
1861
1862        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1863        if mapAlgebraExpression is None and gp.Describe(inputRaster).PixelType.upper() not in ['U1', 'U2', 'U4', 'S8', 'U8', 'S16', 'U16', 'S32', 'U32', 'S64', 'U64']:
1864            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}))
1865       
1866        Logger.Info(_(u'Converting ArcGIS raster %(in)s to polygon feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1867        try:
1868            # Perform requested pre-conversion processing in a temp
1869            # directory.
1870           
1871            if projectedCoordinateSystem is not None or clippingRectangle is not None or mapAlgebraExpression is not None:
1872                cls._ValidateProjectClipAndOrExecuteMapAlgebraParameters(projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingDataset, clippingRectangle, mapAlgebraExpression)
1873                from GeoEco.DataManagement.Directories import TemporaryDirectory
1874                tempDir = TemporaryDirectory()
1875                inputRaster = cls._ProjectClipAndOrExecuteMapAlgebraInTempDir(inputRaster, tempDir.Path,
1876                                                                              projectedCoordinateSystem=projectedCoordinateSystem,
1877                                                                              geographicTransformation=geographicTransformation,
1878                                                                              resamplingTechnique=resamplingTechnique,
1879                                                                              projectedCellSize=projectedCellSize,
1880                                                                              registrationPoint=registrationPoint,
1881                                                                              clippingDataset=clippingDataset,
1882                                                                              clippingRectangle=clippingRectangle,
1883                                                                              mapAlgebraExpression=mapAlgebraExpression)
1884
1885                if mapAlgebraExpression is not None and gp.Describe(inputRaster).PixelType.upper() not in ['U1', 'U2', 'U4', 'S8', 'U8', 'S16', 'U16', 'S32', 'U32', 'S64', 'U64']:
1886                    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.')))
1887
1888            # Convert the raster to a polygon feature class.
1889           
1890            if simplify:
1891                gp.RasterToPolygon_conversion(inputRaster, outputFeatureClass, 'SIMPLIFY', field)
1892            else:
1893                gp.RasterToPolygon_conversion(inputRaster, outputFeatureClass, 'NO_SIMPLIFY', field)
1894
1895        except:
1896            Logger.LogExceptionAsError()
1897            raise
1898
1899    @classmethod
1900    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):
1901        cls.__doc__.Obj.ValidateMethodInvocation()
1902        oldLogInfoAsDebug = Logger.LogInfoAndSetInfoToDebug(_(u'Converting ArcGIS raster %(in)s to outlines in line feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1903        try:
1904            try:
1905                # Convert the raster to a polygon feature class in a
1906                # temporary directory.
1907               
1908                from GeoEco.DataManagement.Directories import TemporaryDirectory
1909                tempDir = TemporaryDirectory()
1910                tempFeatureClass = os.path.join(tempDir.Path, u'polygons.shp')
1911                cls.ToPolygons(inputRaster,
1912                               tempFeatureClass,
1913                               simplify=simplify,
1914                               field=field,
1915                               projectedCoordinateSystem=projectedCoordinateSystem,
1916                               geographicTransformation=geographicTransformation,
1917                               resamplingTechnique=resamplingTechnique,
1918                               projectedCellSize=projectedCellSize,
1919                               registrationPoint=registrationPoint,
1920                               clippingDataset=clippingDataset,
1921                               clippingRectangle=clippingRectangle,
1922                               mapAlgebraExpression=mapAlgebraExpression,
1923                               overwriteExisting=overwriteExisting)
1924
1925                # Convert the polygon feature class to a line
1926                # feature class.
1927
1928                gp = GeoprocessorManager.GetWrappedGeoprocessor()
1929                gp.FeatureToLine_management(tempFeatureClass, outputFeatureClass)
1930
1931            except:
1932                Logger.LogExceptionAsError()
1933                raise
1934        finally:
1935            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
1936
1937    @classmethod
1938    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):
1939        cls.__doc__.Obj.ValidateMethodInvocation()
1940        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1941        Logger.Info(_(u'Converting ArcGIS raster %(in)s to line feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1942        try:
1943            # Perform requested pre-conversion processing in a temp
1944            # directory.
1945           
1946            if projectedCoordinateSystem is not None or clippingRectangle is not None or mapAlgebraExpression is not None:
1947                cls._ValidateProjectClipAndOrExecuteMapAlgebraParameters(projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingDataset, clippingRectangle, mapAlgebraExpression)
1948                from GeoEco.DataManagement.Directories import TemporaryDirectory
1949                tempDir = TemporaryDirectory()
1950                inputRaster = cls._ProjectClipAndOrExecuteMapAlgebraInTempDir(inputRaster, tempDir.Path,
1951                                                                              projectedCoordinateSystem=projectedCoordinateSystem,
1952                                                                              geographicTransformation=geographicTransformation,
1953                                                                              resamplingTechnique=resamplingTechnique,
1954                                                                              projectedCellSize=projectedCellSize,
1955                                                                              registrationPoint=registrationPoint,
1956                                                                              clippingDataset=clippingDataset,
1957                                                                              clippingRectangle=clippingRectangle,
1958                                                                              mapAlgebraExpression=mapAlgebraExpression)
1959
1960            # Convert the raster to a line feature class.
1961
1962            try:
1963                if simplify:
1964                    gp.RasterToPolyline_conversion(inputRaster, outputFeatureClass, backgroundValue, minDangleLength, 'SIMPLIFY', field)
1965                else:
1966                    gp.RasterToPolyline_conversion(inputRaster, outputFeatureClass, backgroundValue, minDangleLength, 'NO_SIMPLIFY', field)
1967            except Exception, e:
1968                if str(e).lower().find('empty feature class') >= 0:
1969                    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})
1970                else:
1971                    raise
1972
1973        except:
1974            Logger.LogExceptionAsError()
1975            raise
1976
1977    @classmethod
1978    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):
1979        cls.__doc__.Obj.ValidateMethodInvocation()
1980        gp = GeoprocessorManager.GetWrappedGeoprocessor()
1981        Logger.Info(_(u'Converting ArcGIS raster %(in)s to point feature class %(out)s...') % {u'in' : inputRaster, u'out' : outputFeatureClass})
1982        try:
1983            # Perform requested pre-conversion processing in a temp
1984            # directory.
1985           
1986            if projectedCoordinateSystem is not None or clippingRectangle is not None or mapAlgebraExpression is not None:
1987                cls._ValidateProjectClipAndOrExecuteMapAlgebraParameters(projectedCoordinateSystem, geographicTransformation, resamplingTechnique, projectedCellSize, registrationPoint, clippingDataset, clippingRectangle, mapAlgebraExpression)
1988                from GeoEco.DataManagement.Directories import TemporaryDirectory
1989                tempDir = TemporaryDirectory()
1990                inputRaster = cls._ProjectClipAndOrExecuteMapAlgebraInTempDir(inputRaster, tempDir.Path,
1991                                                                              projectedCoordinateSystem=projectedCoordinateSystem,
1992                                                                              geographicTransformation=geographicTransformation,
1993                                                                              resamplingTechnique=resamplingTechnique,
1994                                                                              projectedCellSize=projectedCellSize,
1995                                                                              registrationPoint=registrationPoint,
1996                                                                              clippingDataset=clippingDataset,
1997                                                                              clippingRectangle=clippingRectangle,
1998                                                                              mapAlgebraExpression=mapAlgebraExpression)
1999
2000            # Convert the raster to a point feature class.
2001           
2002            gp.RasterToPoint_conversion(inputRaster, outputFeatureClass, field)
2003
2004        except:
2005            Logger.LogExceptionAsError()
2006            raise
2007           
2008
2009###############################################################################
2010# Metadata: module
2011###############################################################################
2012
2013from GeoEco.DataManagement.BinaryRasters import BinaryRaster
2014from GeoEco.Dependencies import PythonAggregatedModuleDependency
2015from GeoEco.Metadata import *
2016from GeoEco.Types import *
2017
2018AddModuleMetadata(shortDescription=_(u'Provides methods for performing common data management operations on ArcGIS rasters.'))
2019
2020###############################################################################
2021# Metadata: ArcGISRaster class
2022###############################################################################
2023
2024AddClassMetadata(ArcGISRaster,
2025    shortDescription=_(u'Provides methods for performing common data management operations on ArcGIS rasters.'),
2026    longDescription=_(
2027u"""This class provides a significant advantage over the ArcGIS geoprocessing
2028tools for managing rasters: it can work around a bug in ArcGIS that causes it to
2029crash when a large number of rasters are stored in a single directory."""),
2030    isExposedAsCOMServer=True,
2031    comIID=u'{82BD49EF-6F06-4AC0-8E91-4E6B2FB84EB1}',
2032    comCLSID=u'{22C205A0-BE4C-4ECA-AF7C-BE496196C75F}')
2033
2034# Public method: ArcGISRaster.Copy
2035
2036AddMethodMetadata(ArcGISRaster.Copy,
2037    shortDescription=_(u'Copies an ArcGIS raster.'),
2038    longDescription=_(
2039u"""Unlike the ArcGIS geoprocessor\'s CopyRaster tool, this tool does
2040not crash ArcGIS when copying rasters to a destination directory that
2041already contains several hundred rasters. For more information on this
2042ArcGIS bug, see
2043http://forums.esri.com/Thread.asp?c=93&f=1729&t=196716&mc=0."""),
2044    isExposedToPythonCallers=True,
2045    isExposedByCOM=True,
2046    isExposedAsArcGISTool=True,
2047    arcGISDisplayName=_(u'Copy Raster'),
2048    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters\\Copy'),
2049    dependencies=[ArcGISDependency(9, 1)])
2050
2051AddArgumentMetadata(ArcGISRaster.Copy, u'cls',
2052    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2053    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2054
2055AddArgumentMetadata(ArcGISRaster.Copy, u'sourceRaster',
2056    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
2057    description=_(u'Raster to copy.'),
2058    arcGISDisplayName=_(u'Source raster'))
2059
2060AddArgumentMetadata(ArcGISRaster.Copy, u'destinationRaster',
2061    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'sourceRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2062    description=_(
2063u"""Copy to create.
2064
2065If this is a file system path, missing directories in the path will be created
2066if they do not exist."""),
2067    direction=u'Output',
2068    arcGISDisplayName=_(u'Destination raster'))
2069
2070AddArgumentMetadata(ArcGISRaster.Copy, u'overwriteExisting',
2071    typeMetadata=BooleanTypeMetadata(),
2072    description=_(
2073u"""If True, the destination raster will be overwritten, if it exists.
2074If False, a ValueError will be raised if the destination raster
2075exists."""),
2076    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2077
2078# Public method: ArcGISRaster.CopySilent
2079
2080AddMethodMetadata(ArcGISRaster.CopySilent,
2081    shortDescription=_(u'Copies an ArcGIS raster and logs a debug message rather than an informational message.'),
2082    longDescription=_(
2083u"""This method does the same thing as the Copy method, except it logs
2084a debug message rather than an informational message. It is intended
2085for use when the raster-copy operation is not imporant enough to
2086warrent notifying the user (for example, when an output raster is
2087extracted from a temporary directory to the final location)."""),
2088    isExposedToPythonCallers=True,
2089    isExposedByCOM=True,
2090    dependencies=[ArcGISDependency(9, 1)])
2091
2092CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.CopySilent, u'cls')
2093CopyArgumentMetadata(ArcGISRaster.Copy, u'sourceRaster', ArcGISRaster.CopySilent, u'sourceRaster')
2094CopyArgumentMetadata(ArcGISRaster.Copy, u'destinationRaster', ArcGISRaster.CopySilent, u'destinationRaster')
2095CopyArgumentMetadata(ArcGISRaster.Copy, u'overwriteExisting', ArcGISRaster.CopySilent, u'overwriteExisting')
2096
2097# Public method: ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash
2098
2099AddMethodMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash,
2100    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.'),
2101    longDescription=_(
2102u"""A bug in ArcGIS 9.x causes it to crash if several hundred rasters are added
2103to a directory. Whether the crash occurs depends on the number and data types of
2104the rasters. See http://forums.esri.com/Thread.asp?c=93&f=1729&t=196716&mc=0 for
2105a complete description of the problem. At the time this documentation was
2106written, the problem was still present in ArcGIS 9.1 SP2 and 9.2 SP1.
2107
2108This function is designed to work around the problem. You call this function
2109prior to adding rasters to a directory and specify the number of of rasters
2110you're going to add. This function analyzes the current contents of the
2111directory. If there is any possibility that adding your rasters would hit the
2112combination needed to cause the crash, this function creates enough temporary
2113rasters to prevent the problem.
2114
2115If this function creates any temporary rasters, it returns a list of their full
2116paths to you. You should delete them after you've added your own rasters. The
2117DeleteTemporaryRastersThatPreventedArcGISCrash function is provided for this
2118purpose.
2119"""),
2120    isExposedToPythonCallers=True,
2121    isExposedByCOM=True,
2122    dependencies=[ArcGISDependency(9, 1)])
2123
2124AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'cls',
2125    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2126    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2127
2128AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'directory',
2129    typeMetadata=DirectoryTypeMetadata(),
2130    description=_(
2131u"""Directory in which temporary rasters should be created, in anticipation of
2132additional rasters being added by the caller after this method returns."""))
2133
2134AddArgumentMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'rastersToAdd',
2135    typeMetadata=IntegerTypeMetadata(minValue=1, maxValue=511),
2136    description=_(
2137u"""Number of rasters that the caller will add to the directory after this
2138method returns."""))
2139
2140AddResultMetadata(ArcGISRaster.CreateTemporaryRastersToPreventArcGISCrash, u'temporaryRasters',
2141    typeMetadata=ListTypeMetadata(elementType=ArcGISRasterTypeMetadata()),
2142    description=_(u"""List of temporary rasters that were created."""))
2143
2144# Public method: ArcGISRaster.CreateXRaster
2145
2146AddMethodMetadata(ArcGISRaster.CreateXRaster,
2147    shortDescription=_(u'Creates an ArcGIS raster where the value of each cell is the X coordinate of the cell.'),
2148    isExposedToPythonCallers=True,
2149    isExposedByCOM=True,
2150    isExposedAsArcGISTool=True,
2151    arcGISDisplayName=_(u'Create X Coordinate Raster'),
2152    arcGISToolCategory=_(u'Spatial Analysis\\Create Rasters'),
2153    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2154
2155CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.CreateXRaster, u'cls')
2156
2157AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'raster',
2158    typeMetadata=ArcGISRasterTypeMetadata(deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2159    description=_(
2160u"""Raster to create.
2161
2162If this is a file system path, missing directories in the path will be created
2163if they do not exist."""),
2164    direction=u'Output',
2165    arcGISDisplayName=_(u'Output raster'))
2166
2167AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'extent',
2168    typeMetadata=EnvelopeTypeMetadata(),
2169    description=_(u"""Extent of the output raster."""),
2170    arcGISDisplayName=_(u'Extent'))
2171
2172AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'cellSize',
2173    typeMetadata=FloatTypeMetadata(minValue=0.0),
2174    description=_(
2175u"""Cell size of the output raster.
2176
2177If the horizontal or vertical extents of the raster are not evenly
2178divisble by the cell size, the extents will be increased right or up
2179by the smallest amount needed to make them evenly divisible. For
2180example, if the horizontal extent runs from 0 to 25 and the cell size
2181is 2, the right extent will be increased to 26."""),
2182    arcGISDisplayName=_(u'Cell size'))
2183
2184AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'cellValue',
2185    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Center', u'Left', u'Right'], makeLowercase=True),
2186    description=_(
2187u"""Value of the raster cells, either:
2188
2189* Center - the X coordinate of the center of the cell.
2190
2191* Left - the X coordinate of the left edge of the cell.
2192
2193* Right - the X coordinate of the right edge of the cell.
2194"""),
2195    arcGISDisplayName=_(u'Cell value'))
2196
2197AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'coordinateSystem',
2198    typeMetadata=CoordinateSystemTypeMetadata(canBeNone=True),
2199    description=_(
2200u"""Coordinate system to define for the raster. If not specified, a
2201coordinate system will not be defined."""),
2202    arcGISDisplayName=_(u'Coordinate system'))
2203
2204AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'buildPyramids',
2205    typeMetadata=BooleanTypeMetadata(),
2206    description=_(
2207u"""If True, pyramids will be built for the raster, which will
2208improve its display speed in the ArcGIS user interface."""),
2209    arcGISDisplayName=_(u'Build pyramids'))
2210
2211AddArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting',
2212    typeMetadata=BooleanTypeMetadata(),
2213    description=_(
2214u"""If True, the raster will be overwritten, if it exists. If False, a
2215ValueError will be raised if the raster exists."""),
2216    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2217
2218# Public method: ArcGISRaster.CreateYRaster
2219
2220AddMethodMetadata(ArcGISRaster.CreateYRaster,
2221    shortDescription=_(u'Creates an ArcGIS raster where the value of each cell is the Y coordinate of the cell.'),
2222    isExposedToPythonCallers=True,
2223    isExposedByCOM=True,
2224    isExposedAsArcGISTool=True,
2225    arcGISDisplayName=_(u'Create Y Coordinate Raster'),
2226    arcGISToolCategory=_(u'Spatial Analysis\\Create Rasters'),
2227    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2228
2229CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'cls', ArcGISRaster.CreateYRaster, u'cls')
2230CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'raster', ArcGISRaster.CreateYRaster, u'raster')
2231CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'extent', ArcGISRaster.CreateYRaster, u'extent')
2232CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'cellSize', ArcGISRaster.CreateYRaster, u'cellSize')
2233
2234AddArgumentMetadata(ArcGISRaster.CreateYRaster, u'cellValue',
2235    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Center', u'Bottom', u'Top'], makeLowercase=True),
2236    description=_(
2237u"""Value of the raster cells, either:
2238
2239* Center - the X coordinate of the center of the cell.
2240
2241* Bottom - the Y coordinate of the bottom edge of the cell.
2242
2243* Top - the X coordinate of the top edge of the cell.
2244"""),
2245    arcGISDisplayName=_(u'Cell value'))
2246
2247CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'coordinateSystem', ArcGISRaster.CreateYRaster, u'coordinateSystem')
2248CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'buildPyramids', ArcGISRaster.CreateYRaster, u'buildPyramids')
2249CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting', ArcGISRaster.CreateYRaster, u'overwriteExisting')
2250
2251# Public method: ArcGISRaster.Delete
2252
2253AddMethodMetadata(ArcGISRaster.Delete,
2254    shortDescription=_(u'Deletes an ArcGIS raster.'),
2255    isExposedToPythonCallers=True,
2256    isExposedByCOM=True,
2257    isExposedAsArcGISTool=True,
2258    arcGISDisplayName=_(u'Delete Raster'),
2259    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters\\Delete'),
2260    dependencies=[ArcGISDependency(9, 1)])
2261
2262AddArgumentMetadata(ArcGISRaster.Delete, u'cls',
2263    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2264    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2265
2266AddArgumentMetadata(ArcGISRaster.Delete, u'raster',
2267    typeMetadata=ArcGISRasterTypeMetadata(),
2268    description=_(u"""Raster to delete."""),
2269    arcGISDisplayName=_(u'Raster'))
2270
2271# Public method: ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash
2272
2273AddMethodMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash,
2274    shortDescription=_(u'Deletes the temporary ArcGIS rasters created by the CreateTemporaryRastersToPreventArcGISCrash function.'),
2275    isExposedToPythonCallers=True,
2276    isExposedByCOM=True,
2277    dependencies=[ArcGISDependency(9, 1)])
2278
2279AddArgumentMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash, u'cls',
2280    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2281    description=_(u'%s class or an instance of it.') % ArcGISRaster.__name__)
2282
2283AddArgumentMetadata(ArcGISRaster.DeleteTemporaryRastersThatPreventedArcGISCrash, u'rasters',
2284    typeMetadata=ListTypeMetadata(elementType=ArcGISRasterTypeMetadata()),
2285    description=_(
2286u"""List of temporary rasters to delete, returned by the
2287CreateTemporaryRastersToPreventArcGISCrash function."""))
2288
2289# Public method: ArcGISRaster.Exists
2290
2291AddMethodMetadata(ArcGISRaster.Exists,
2292    shortDescription=_(u'Tests that a specified path exists and is an ArcGIS raster.'),
2293    isExposedToPythonCallers=True,
2294    isExposedByCOM=True)
2295
2296CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.Exists, u'cls')
2297
2298AddArgumentMetadata(ArcGISRaster.Exists, u'path',
2299    typeMetadata=ArcGISRasterTypeMetadata(),
2300    description=_(u'Path to test.'))
2301
2302AddResultMetadata(ArcGISRaster.Exists, u'exists',
2303    typeMetadata=BooleanTypeMetadata(),
2304    description=_(u'True if the specified path exists.'))
2305
2306AddResultMetadata(ArcGISRaster.Exists, u'isRaster',
2307    typeMetadata=BooleanTypeMetadata(),
2308    description=_(u'True if the specified path exists and is an ArcGIS raster.'))
2309
2310# Public method: ArcGISRaster.Find
2311
2312AddMethodMetadata(ArcGISRaster.Find,
2313    shortDescription=_(u'Finds rasters in an ArcGIS workspace.'),
2314    longDescription=_(
2315u"""Rasters are returned in an arbitrary order determined by the
2316ArcGIS geoprocessor and the search algorithm."""),
2317    isExposedToPythonCallers=True,
2318    isExposedByCOM=True,
2319    dependencies=[ArcGISDependency(9, 1)])
2320
2321CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.Find, u'cls')
2322
2323AddArgumentMetadata(ArcGISRaster.Find, u'workspace',
2324    typeMetadata=ArcGISWorkspaceTypeMetadata(mustExist=True),
2325    description=_(u'Workspace to search.'),
2326    arcGISDisplayName=_(u'Workspace to search'))
2327
2328AddArgumentMetadata(ArcGISRaster.Find, u'wildcard',
2329    typeMetadata=UnicodeStringTypeMetadata(),
2330    description=_(
2331u"""Wildcard expression specifying the rasters to find. Please see the
2332documentation for the ArcGIS geoprocessor's ListRasters function for
2333more information about the syntax. At the time of this writing, only
2334the * wildcard character was supported, which would match zero or more
2335of any character."""),
2336    arcGISDisplayName=_(u'Wildcard expression'),
2337    arcGISCategory=_(u'Search options'))
2338
2339AddArgumentMetadata(ArcGISRaster.Find, u'searchTree',
2340    typeMetadata=BooleanTypeMetadata(),
2341    description=_(u'If True, child workspaces will be searched.'),
2342    arcGISDisplayName=_(u'Search workspace tree'),
2343    arcGISCategory=_(u'Search options'))
2344
2345AddArgumentMetadata(ArcGISRaster.Find, u'rasterType',
2346    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2347    description=_(
2348u"""Type of rasters to find. If provided, only rasters of this type
2349will be found. At the time of this writing, the ArcGIS 9.3
2350documentation specified that any of the following strings would be
2351accepted: ALL, BMP, GIF, GRID, IMG, JP2, JPG, PNG, TIFF.
2352
2353This parameter requires ArcGIS 9.3 or later."""),
2354    arcGISDisplayName=_(u'Raster type'),
2355    arcGISCategory=_(u'Search options'),
2356    dependencies=[ArcGISDependency(9, 3)])
2357
2358AddArgumentMetadata(ArcGISRaster.Find, u'basePath',
2359    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2360    description=_(
2361u"""Absolute path from which relative paths to the rasters will be
2362calculated. If provided, relative paths will be calculated and
2363included as part of the two dimensional array returned by this
2364function.
2365
2366For example, if the base path was::
2367
2368    C:\\Data\\Rasters
2369
2370the relative paths for the rasters::
2371
2372    C:\\Data\\Rasters\\Group1\\r1
2373    C:\\Data\\Rasters\\r1
2374    C:\\Data\\r1
2375    C:\\r1
2376    D:\\r1
2377    \\\\MyServer\\Data\\r1
2378
2379would be::   
2380
2381    Group1\\r1
2382    r1
2383    ..\\r1
2384    ..\\..\\r1
2385    D:\\r1
2386    \\\\MyServer\\Data\\r1
2387"""))
2388
2389AddArgumentMetadata(ArcGISRaster.Find, u'getExtent',
2390    typeMetadata=BooleanTypeMetadata(),
2391    description=_(
2392u"""'If True, the extent of each raster will be included as part of
2393the two-dimensional array returned by this function. The extent is
2394represented by four floating point numbers: XMin, YMin, XMax, and
2395YMax."""))
2396
2397_DateParsingExpressionSyntaxDocumentation = _(
2398u"""The expression is a standard `Python regular expression
2399<http://docs.python.org/lib/re-syntax.html>`_ with additional codes
2400for matching fragments of dates::
2401
2402    %d - Day of the month as a decimal number (range: 01 to 31)
2403    %H - Hour (24-hour clock) as a decimal number (range: 00 to 23)
2404    %j - Day of the year as a decimal number (range: 001 to 366)
2405    %m - Month as a decimal number (range: 01 to 12)
2406    %M - Minute as a decimal number (range: 00 to 59)
2407    %S - Second as a decimal number (range: 00 to 61)
2408    %y - Year without century as a decimal number (range: 00 to 99)
2409    %Y - Year with century as a decimal number (range: 0001 to 9999)
2410    %% - A literal "%" character
2411
2412A date is parsed from a path as follows:
2413
24141. The date fragment codes in your expression are replaced by regular
2415   expression groups to produce a true regular expression. For
2416   example, if your expression is "%Y_%m_%d", it is converted to the
2417   regular expression
2418   "(\\\\d\\\\d\\\\d\\\\d)_(\\\\d\\\\d)_(\\\\d\\\\d)".
2419
24202. The Python re.search function is invoked to find the
2421   first occurrence of the regular expression in the path. The
2422   search proceeds from left to right.
2423
24243. If an occurrence is found, the regular expression groups are
2425   extracted and the Python time.strptime function is invoked to parse
2426   a date from the groups.
2427
2428Notes:
2429
2430* Your expression must include at least one date fragment code, but it
2431  need not include all of them. If a particular code is missing, the
2432  following default values will be used: year 1900, month 01, day 01,
2433  hour 00, minute 00, second 00.
2434
2435* You cannot specify a given date fragment code more than once.
2436
2437* You cannot specify date fragment codes that might conflict. For
2438  example, you cannot specify both %j and %d because this could result
2439  in conflicting values for the day.
2440
2441* For %y, values 00 to 68 are interpreted as years 2000 through 2068,
2442  while 69 through 99 are interpreted as years 1969 through 1999.
2443
2444* Remember that the entire path is searched for your expression, from
2445  left to right. The first occurrence of it may be in the parent
2446  directories.
2447
2448* The date fragment codes are case-sensitive.
2449
2450* If the underlying database table can hold the time as well as the
2451  date in a single field, the time will be stored along with the date.
2452  These databases include Microsoft Access, Microsoft SQL Server, and
2453  Oracle, among others. If the table cannot hold the time and date in
2454  a single field, then only the date will be stored. This is the case,
2455  for example, with dBASE III and IV tables (.dbf files), often used
2456  by ArcGIS.
2457
2458* The timezone of the parsed date is assumed to be UTC.
2459
2460Examples:
2461
2462The expression::
2463
2464    %Y%j
2465
2466will parse dates from rasters namd with the year and day of year::
2467
2468    C:\\SST\\Rasters\\2006\\sst2006001
2469    C:\\SST\\Rasters\\2006\\sst2006002
2470    C:\\SST\\Rasters\\2006\\sst2006003
2471
2472Note that, in this example, the 2006 is parsed from the raster name,
2473not the 2006 directory, because the directory is not followed by a day
2474of year, it is followed by a backslash. The date parsing expression
2475will only match a year followed by a day of year.""")
2476
2477AddArgumentMetadata(ArcGISRaster.Find, u'dateParsingExpression',
2478    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2479    description=_(
2480u"""'Expression for parsing dates from the paths of each raster. If
2481provided, dates will be parsed from the paths of each raster using
2482this expression and included as part of the two dimensional array
2483returned by this function.
2484
2485""") +
2486_DateParsingExpressionSyntaxDocumentation)
2487
2488AddResultMetadata(ArcGISRaster.Find, u'rasters',
2489    typeMetadata=ListTypeMetadata(ListTypeMetadata(elementType=AnyObjectTypeMetadata())),
2490    description=_(
2491u"""Two-dimensional array listing the rasters that were found and the
2492requested metadata about them. The array is organized as a table with
2493the following columns in the order shown:
2494
2495* Path - Unicode string; this column always exists.
2496
2497* Relative path - Unicode string; this column will only exist if
2498  basePath is provided.
2499
2500* XMin, YMin, XMax, YMax - float; these columns will only exist if
2501  getExtent is true.
2502
2503* Parsed date - datetime; this column will only exist if
2504  dateParsingExpression is provided.
2505
2506* Parsed UNIX time - integer; this column will only exist if
2507  dateParsingExpression is provided. It is the same value as the
2508  previous column, but in UNIX time format. UNIX times are 32-bit
2509  signed integers that are the number of seconds since 1970-01-01
2510  00:00:00 UTC. This tool assumes the date that was parsed is in the
2511  UTC timezone. The UNIX time values produced by this tool do not
2512  include leap seconds; this tool assumes that a regular year is
2513  31536000 seconds and a leap year is 31622400 seconds.
2514"""))
2515
2516# Public method: ArcGISRaster.FindAndFillTable
2517
2518AddMethodMetadata(ArcGISRaster.FindAndFillTable,
2519    shortDescription=_(u'Finds rasters within an ArcGIS workspace and inserts a row for each one into an existing table.'),
2520    longDescription=ArcGISRaster.Find.__doc__.Obj.LongDescription,
2521    isExposedToPythonCallers=True,
2522    dependencies=[ArcGISDependency(9, 1)])
2523
2524CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FindAndFillTable, u'cls')
2525CopyArgumentMetadata(ArcGISRaster.Find, u'workspace', ArcGISRaster.FindAndFillTable, u'workspace')
2526
2527AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'insertCursor',
2528    typeMetadata=ClassInstanceTypeMetadata(cls=InsertCursor),
2529    description=_(
2530u"""Insert cursor opened to the table that will receive the rows. The
2531cursor will still be open when this function returns."""))
2532
2533AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'rasterField',
2534    typeMetadata=UnicodeStringTypeMetadata(),
2535    description=_(
2536u"""Name of the field to receive absolute paths to the rasters that
2537were found."""),
2538    arcGISDisplayName=_(u'File path field'))
2539
2540CopyArgumentMetadata(ArcGISRaster.Find, u'wildcard', ArcGISRaster.FindAndFillTable, u'wildcard')
2541CopyArgumentMetadata(ArcGISRaster.Find, u'searchTree', ArcGISRaster.FindAndFillTable, u'searchTree')
2542CopyArgumentMetadata(ArcGISRaster.Find, u'rasterType', ArcGISRaster.FindAndFillTable, u'rasterType')
2543
2544AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'relativePathField',
2545    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2546    description=_(
2547u"""Name of the field to receive paths of the rasters that were found,
2548relative to the path you specify for the base path parameter. For
2549example, if the base path was::
2550
2551    C:\\Data\\Rasters
2552
2553the relative paths for the rasters::
2554
2555    C:\\Data\\Rasters\\Group1\\r1
2556    C:\\Data\\Rasters\\r1
2557    C:\\Data\\r1
2558    C:\\r1
2559    D:\\r1
2560    \\\\MyServer\\Data\\r1
2561
2562would be::   
2563
2564    Group1\\r1
2565    r1
2566    ..\\r1
2567    ..\\..\\r1
2568    D:\\r1
2569    \\\\MyServer\\Data\\r1
2570"""))
2571
2572AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'basePath',
2573    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2574    description=_(
2575u"""Absolute path from which relative paths will be calculated and
2576stored in the field specified by the relative path field parameter.
2577Please see the documentation for that field for more information."""))
2578
2579AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'populateExtentFields',
2580    typeMetadata=BooleanTypeMetadata(),
2581    description=_(
2582u"""If True, the fields named XMin, YMin, XMax, and YMax will be
2583populated with the rasters' extents. If you populate these fields and
2584store the rasters' paths in a field named Image, ArcGIS will treat
2585your table as an unmanaged raster catalog and enable additional
2586functionality from the ArcGIS user interface, such as time series
2587animations."""),
2588    arcGISDisplayName=_(u'Populate XMin, YMin, XMax, and YMax fields'),
2589    arcGISCategory=_(u'Output table options'))
2590
2591AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'parsedDateField',
2592    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2593    description=_(
2594u"""Name of the field to receive dates parsed from the paths of the
2595rasters that were found. You must also specify a date parsing
2596expression."""),
2597    arcGISDisplayName=_(u'Parsed date field'),
2598    arcGISCategory=_(u'Output table options'))
2599
2600AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'dateParsingExpression',
2601    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2602    description=_(
2603u"""Expression for parsing dates from the paths of the rasters that
2604were found. The expression will be ignored if you do not also specify
2605a field to receive the dates or the equivalent UNIX time.
2606
2607""") + _DateParsingExpressionSyntaxDocumentation,
2608    arcGISDisplayName=_(u'Date parsing expression'),
2609    arcGISCategory=_(u'Output table options'))
2610
2611AddArgumentMetadata(ArcGISRaster.FindAndFillTable, u'unixTimeField',
2612    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2613    description=_(
2614u"""Name of the field to receive dates, in "UNIX time" format, parsed
2615from the paths of the rasters that were found. You must also specify a
2616date parsing expression.
2617
2618UNIX times are 32-bit signed integers that are the number of seconds
2619since 1970-01-01 00:00:00 UTC. This tool assumes the date that was
2620parsed is in the UTC timezone. The UNIX time values produced by this
2621tool do not include leap seconds; this tool assumes that a regular
2622year is 31536000 seconds and a leap year is 31622400 seconds."""),
2623    arcGISDisplayName=_(u'UNIX time field'),
2624    arcGISCategory=_(u'Output table options'))
2625
2626# Public method: ArcGISRaster.FindAndCreateTable
2627
2628AddMethodMetadata(ArcGISRaster.FindAndCreateTable,
2629    shortDescription=_(u'Finds rasters within an ArcGIS workspace and creates a table that lists them.'),
2630    longDescription=ArcGISRaster.Find.__doc__.Obj.LongDescription,
2631    isExposedToPythonCallers=True,
2632    dependencies=[ArcGISDependency(9, 1)])
2633
2634CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FindAndCreateTable, u'cls')
2635CopyArgumentMetadata(ArcGISRaster.Find, u'workspace', ArcGISRaster.FindAndCreateTable, u'workspace')
2636
2637AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'connection',
2638    typeMetadata=ClassInstanceTypeMetadata(cls=DatabaseConnection),
2639    description=_(u'Connection opened to the database that will receive the new table.'))
2640
2641AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'table',
2642    typeMetadata=UnicodeStringTypeMetadata(),
2643    description=_(u'Name of the table to create. The table must not exist.'),
2644    arcGISDisplayName=_(u'Output table name'))
2645
2646CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'rasterField', ArcGISRaster.FindAndCreateTable, u'rasterField')
2647CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'wildcard', ArcGISRaster.FindAndCreateTable, u'wildcard')
2648CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'searchTree', ArcGISRaster.FindAndCreateTable, u'searchTree')
2649CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'rasterType', ArcGISRaster.FindAndCreateTable, u'rasterType')
2650CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'relativePathField', ArcGISRaster.FindAndCreateTable, u'relativePathField')
2651CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'basePath', ArcGISRaster.FindAndCreateTable, u'basePath')
2652CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'populateExtentFields', ArcGISRaster.FindAndCreateTable, u'populateExtentFields')
2653CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'parsedDateField', ArcGISRaster.FindAndCreateTable, u'parsedDateField')
2654CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'dateParsingExpression', ArcGISRaster.FindAndCreateTable, u'dateParsingExpression')
2655CopyArgumentMetadata(ArcGISRaster.FindAndFillTable, u'unixTimeField', ArcGISRaster.FindAndCreateTable, u'unixTimeField')
2656
2657AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'pathFieldsDataType',
2658    typeMetadata=UnicodeStringTypeMetadata(),
2659    description=_(
2660u"""Database data type to use when creating the raster path fields.
2661Because the fields will contain paths, they must have a string data
2662type such as TEXT or VARCHAR. The appropriate data type depends on the
2663underlying database and the API used to access it."""))
2664
2665AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'extentFieldsDataType',
2666    typeMetadata=UnicodeStringTypeMetadata(),
2667    description=_(
2668u"""Database data type to use when creating the raster extent fields
2669(XMin, YMin, XMax, and YMax). The fields will contain floating point
2670numbers. The appropriate data type depends on the underlying database
2671and the API used to access it. For many databases, the DOUBLE or FLOAT
2672data type are appropriate."""))
2673
2674AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'dateFieldsDataType',
2675    typeMetadata=UnicodeStringTypeMetadata(),
2676    description=_(
2677u"""Database data type to use when creating the parsed date field. The
2678appropriate data type depends on the underlying database and the API
2679used to access it. For many databases, the DATE or DATETIME data type
2680are appropriate."""))
2681
2682AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'unixTimeFieldDataType',
2683    typeMetadata=UnicodeStringTypeMetadata(),
2684    description=_(
2685u"""Database data type to use when creating the UNIX date field. The
2686appropriate data type depends on the underlying database and the API
2687used to access it. Because UNIX dates are 32-bit signed integers, the
2688INT or LONG data type is usually appropriate for most databases."""))
2689
2690AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'maxPathLength',
2691    typeMetadata=IntegerTypeMetadata(canBeNone=True, minValue=1),
2692    description=_(
2693u"""Maximum length of a path for this operating system. This value is
2694used to specify the width of the field that is created. You should
2695provide a value only if the underlying database requires that you
2696specify a width for string fields. If you provide a value that is too
2697small to hold one of the paths that is found, this function will fail
2698when it finds that path."""))
2699
2700AddArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'overwriteExisting',
2701    typeMetadata=BooleanTypeMetadata(),
2702    description=_(
2703u"""If True, the output table will be overwritten, if it exists.
2704
2705If False, a ValueError will be raised if the output table exists."""),
2706    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2707
2708CopyResultMetadata(DatabaseConnection.CreateTable, u'createdTable', ArcGISRaster.FindAndCreateTable, u'createdTable')
2709
2710# Public method: ArcGISRaster.FindAndCreateArcGISTable
2711
2712AddMethodMetadata(ArcGISRaster.FindAndCreateArcGISTable,
2713    shortDescription=_(u'Finds rasters within an ArcGIS workspace and creates a table that lists them.'),
2714    longDescription=ArcGISRaster.FindAndCreateTable.__doc__.Obj.LongDescription,
2715    isExposedToPythonCallers=True,
2716    isExposedByCOM=True,
2717    isExposedAsArcGISTool=True,
2718    arcGISDisplayName=_(u'Find Rasters'),
2719    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters'),
2720    dependencies=[ArcGISDependency(9, 1)])
2721
2722CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FindAndCreateArcGISTable, u'cls')
2723CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'workspace', ArcGISRaster.FindAndCreateArcGISTable, u'inputWorkspace')
2724
2725AddArgumentMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'outputWorkspace',
2726    typeMetadata=ArcGISWorkspaceTypeMetadata(mustExist=True),
2727    description=_(u'Workspace in which the table should be created.'),
2728    arcGISDisplayName=_(u'Output workspace'))
2729
2730AddArgumentMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'table',
2731    typeMetadata=UnicodeStringTypeMetadata(),
2732    description=_(
2733u"""Name of the table to create.
2734
2735If the output workspace is a directory (rather than a database) a
2736dBASE table will be created. It is not possible to create other types
2737of tables in the file system (e.g. comma or space-delimited text
2738files). This restriction is imposed by the ArcGIS CreateTable tool,
2739which is used to create the table. If you omit an extension from the
2740table name, .dbf will be added automatically. If you specify another
2741extension, such as .csv or .txt, it will be replaced with .dbf."""),
2742    arcGISDisplayName=_(u'Output table name'))
2743
2744CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'rasterField', ArcGISRaster.FindAndCreateArcGISTable, u'rasterField')
2745CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'wildcard', ArcGISRaster.FindAndCreateArcGISTable, u'wildcard')
2746CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'searchTree', ArcGISRaster.FindAndCreateArcGISTable, u'searchTree')
2747CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'rasterType', ArcGISRaster.FindAndCreateArcGISTable, u'rasterType')
2748
2749AddArgumentMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'relativePathField',
2750    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True),
2751    description=_(
2752u"""Name of the field to receive paths of the rasters that were found,
2753relative to the output table. For example, if the path to the table is::
2754
2755    C:\\Data\\Rasters\\FoundRasters.dbf
2756
2757the relative paths for the rasters::
2758
2759    C:\\Data\\Rasters\\Group1\\r1
2760    C:\\Data\\Rasters\\r1
2761    C:\\Data\\r1
2762    C:\\r1
2763    D:\\r1
2764    \\\\MyServer\\Data\\r1
2765
2766would be::   
2767
2768    Group1\\r1
2769    r1
2770    ..\\r1
2771    ..\\..\\r1
2772    D:\\r1
2773    \\\\MyServer\\Data\\r1
2774
2775If the table is in a personal geodatabase::
2776
2777    C:\\Data\\Rasters\\RasterInfo.mdb\\FoundRasters
2778
2779the relative paths would be::   
2780
2781    ..\\Group1\\r1
2782    ..\\r1
2783    ..\\..\\r1
2784    ..\\..\\..\\r1
2785    D:\\r1
2786    \\\\MyServer\\Data\\r1
2787"""),
2788    arcGISDisplayName=_(u'Relative path field'),
2789    arcGISCategory=_(u'Output table options'))
2790
2791CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'populateExtentFields', ArcGISRaster.FindAndCreateArcGISTable, u'populateExtentFields')
2792CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'parsedDateField', ArcGISRaster.FindAndCreateArcGISTable, u'parsedDateField')
2793CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'dateParsingExpression', ArcGISRaster.FindAndCreateArcGISTable, u'dateParsingExpression')
2794CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'unixTimeField', ArcGISRaster.FindAndCreateArcGISTable, u'unixTimeField')
2795CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'maxPathLength', ArcGISRaster.FindAndCreateArcGISTable, u'maxPathLength')
2796CopyArgumentMetadata(ArcGISRaster.FindAndCreateTable, u'overwriteExisting', ArcGISRaster.FindAndCreateArcGISTable, u'overwriteExisting')
2797
2798AddResultMetadata(ArcGISRaster.FindAndCreateArcGISTable, u'createdTable',
2799    typeMetadata=ArcGISTableTypeMetadata(),
2800    description=DatabaseConnection.CreateTable.__doc__.Obj.GetResultByName(u'createdTable').Description,
2801    arcGISDisplayName=_(u'Output table'))
2802
2803# Public method: ArcGISRaster.Move
2804
2805AddMethodMetadata(ArcGISRaster.Move,
2806    shortDescription=_(u'Moves an ArcGIS raster.'),
2807    longDescription=ArcGISRaster.Copy.__doc__.Obj.LongDescription,
2808    isExposedToPythonCallers=True,
2809    isExposedByCOM=True,
2810    isExposedAsArcGISTool=True,
2811    arcGISDisplayName=_(u'Move Raster'),
2812    arcGISToolCategory=_(u'Data Management\\ArcGIS Rasters\\Move'),
2813    dependencies=[ArcGISDependency(9, 1)])
2814
2815AddArgumentMetadata(ArcGISRaster.Move, u'cls',
2816    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISRaster),
2817    description=ArcGISRaster.Copy.__doc__.Obj.Arguments[0].Description)
2818
2819AddArgumentMetadata(ArcGISRaster.Move, u'sourceRaster',
2820    typeMetadata=ArcGISRasterTypeMetadata(mustExist=True),
2821    description=_(u'Raster to move.'),
2822    arcGISDisplayName=_(u'Source raster'))
2823
2824AddArgumentMetadata(ArcGISRaster.Move, u'destinationRaster',
2825    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'sourceRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2826    description=_(
2827u"""New path for the raster.
2828
2829If this is a file system path, missing directories in the path will be created
2830if they do not exist."""),
2831    direction=u'Output',
2832    arcGISDisplayName=_(u'Destination raster'))
2833
2834AddArgumentMetadata(ArcGISRaster.Move, u'overwriteExisting',
2835    typeMetadata=BooleanTypeMetadata(),
2836    description=ArcGISRaster.Copy.__doc__.Obj.Arguments[3].Description,
2837    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
2838
2839# Public method: ArcGISRaster.MoveSilent
2840
2841AddMethodMetadata(ArcGISRaster.MoveSilent,
2842    shortDescription=_(u'Moves an ArcGIS raster and logs a debug message rather than an informational message.'),
2843    longDescription=_(
2844u"""This method does the same thing as the Move method, except it logs
2845a debug message rather than an informational message. It is intended
2846for use when the raster-move operation is not imporant enough to
2847warrent notifying the user (for example, when an output raster is
2848extracted from a temporary directory to the final location)."""),
2849    isExposedToPythonCallers=True,
2850    isExposedByCOM=True,
2851    dependencies=[ArcGISDependency(9, 1)])
2852
2853CopyArgumentMetadata(ArcGISRaster.Move, u'cls', ArcGISRaster.MoveSilent, u'cls')
2854CopyArgumentMetadata(ArcGISRaster.Move, u'sourceRaster', ArcGISRaster.MoveSilent, u'sourceRaster')
2855CopyArgumentMetadata(ArcGISRaster.Move, u'destinationRaster', ArcGISRaster.MoveSilent, u'destinationRaster')
2856CopyArgumentMetadata(ArcGISRaster.Move, u'overwriteExisting', ArcGISRaster.MoveSilent, u'overwriteExisting')
2857
2858# Public method: ArcGISRaster.FromNumpyArray
2859
2860AddMethodMetadata(ArcGISRaster.FromNumpyArray,
2861    shortDescription=_(u'Creates an ArcGIS raster from a numpy array.'),
2862    isExposedToPythonCallers=True,
2863    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2864
2865CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.FromNumpyArray, u'cls')
2866
2867AddArgumentMetadata(ArcGISRaster.FromNumpyArray, u'numpyArray',
2868    typeMetadata=NumPyArrayTypeMetadata(dimensions=2, minShape=[1,1], allowedDTypes=[u'int8', u'uint8', u'int16', u'uint16', u'int32', u'uint32', u'float32']),
2869    description=_(u'Numpy array to write out as an ArcGIS raster.'))
2870
2871AddArgumentMetadata(ArcGISRaster.FromNumpyArray, u'raster',
2872    typeMetadata=ArcGISRasterTypeMetadata(deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2873    description=_(u'Output raster to create.'))
2874
2875CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'xLowerLeftCorner', ArcGISRaster.FromNumpyArray, u'xLowerLeftCorner')
2876CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'yLowerLeftCorner', ArcGISRaster.FromNumpyArray, u'yLowerLeftCorner')
2877CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'cellSize', ArcGISRaster.FromNumpyArray, u'cellSize')
2878CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'nodataValue', ArcGISRaster.FromNumpyArray, u'nodataValue')
2879CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'coordinateSystem', ArcGISRaster.FromNumpyArray, u'coordinateSystem')
2880CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCoordinateSystem', ArcGISRaster.FromNumpyArray, u'projectedCoordinateSystem')
2881CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'geographicTransformation', ArcGISRaster.FromNumpyArray, u'geographicTransformation')
2882CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'resamplingTechnique', ArcGISRaster.FromNumpyArray, u'resamplingTechnique')
2883CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCellSize', ArcGISRaster.FromNumpyArray, u'projectedCellSize')
2884CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'registrationPoint', ArcGISRaster.FromNumpyArray, u'registrationPoint')
2885CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'clippingRectangle', ArcGISRaster.FromNumpyArray, u'clippingRectangle')
2886CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'mapAlgebraExpression', ArcGISRaster.FromNumpyArray, u'mapAlgebraExpression')
2887CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'buildPyramids', ArcGISRaster.FromNumpyArray, u'buildPyramids')
2888CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'overwriteExisting', ArcGISRaster.FromNumpyArray, u'overwriteExisting')
2889
2890# Public method: ArcGISRaster.ToNumpyArray
2891
2892AddMethodMetadata(ArcGISRaster.ToNumpyArray,
2893    shortDescription=_(u'Reads an ArcGIS raster or raster layer into a numpy array.'),
2894    isExposedToPythonCallers=True,
2895    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
2896
2897CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToNumpyArray, u'cls')
2898
2899AddArgumentMetadata(ArcGISRaster.ToNumpyArray, u'raster',
2900    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
2901    description=_(u'Raster to read.'))
2902
2903AddArgumentMetadata(ArcGISRaster.ToNumpyArray, u'band',
2904    typeMetadata=IntegerTypeMetadata(minValue=1),
2905    description=_(u'Band number to read, starting with 1.'))
2906
2907AddArgumentMetadata(ArcGISRaster.ToNumpyArray, u'tempRasterPath',
2908    typeMetadata=ArcGISRasterTypeMetadata(canBeNone=True, mustNotExist=True),
2909    description=_(
2910u"""Path to use if it is necessary to create a temporary copy of the
2911raster. The caller can provide this as an optimization. If provided,
2912the caller is responsible for deleting the temporary raster, if it
2913happened to be created (the caller should check for this after this
2914function returns).
2915
2916If you do not provide a path, this function will create a temporary
2917directory to hold the temporary raster, and delete it before
2918returning.
2919
2920The temporary raster is only created when the input raster does not
2921exist on disk (i.e. it exists in a geodatabase). This function uses
2922GDAL to read the raster, and GDAL can only read rasters that are on
2923disk. Thus if the raster is not on disk, a temporary copy is needed so
2924it can be read by GDAL."""))
2925
2926AddResultMetadata(ArcGISRaster.ToNumpyArray, u'numpyArray',
2927    typeMetadata=NumPyArrayTypeMetadata(dimensions=2),
2928    description=_(
2929u"""Numpy array read from the raster.
2930
2931Note that, for integer rasters, the array will use the most compact
2932data type that can represent all of the values in the raster.
2933Normally, ArcGIS automatically selects the most compact data type, but
2934this does not always happen. For example, I have seen ArcGIS store
2935data ranging from 0 to 65535 (with no NODATA value) as an int32 raster
2936even though a uint16 is the most compact data type for that
2937range."""))
2938
2939AddResultMetadata(ArcGISRaster.ToNumpyArray, u'noDataValue',
2940    typeMetadata=FloatTypeMetadata(canBeNone=True),
2941    description=_(
2942u"""Value in the returned numpy array that represents NODATA. Note
2943that, if the numpy array is compacted (as described above), this value
2944may be different than what ArcGIS used when it created the
2945raster."""))
2946
2947# Public method: ArcGISRaster.ExtractByMask
2948
2949AddMethodMetadata(ArcGISRaster.ExtractByMask,
2950    shortDescription=_(u'Extracts the cells of a raster that correspond to the areas defined by a mask.'),
2951    longDescription=_(
2952u"""This tool just calls the ArcGIS Spatial Analyst's Extract By Mask
2953tool. It only exists so that we can easily create a batched version of
2954that tool."""),
2955    isExposedToPythonCallers=True,
2956    isExposedByCOM=True,
2957    isExposedAsArcGISTool=False,
2958    arcGISToolCategory=_(u'Spatial Analysis\\Extract By Mask'),
2959    dependencies=[ArcGISDependency(9, 1), ArcGISExtensionDependency(u'spatial')])
2960
2961CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ExtractByMask, u'cls')
2962
2963AddArgumentMetadata(ArcGISRaster.ExtractByMask, u'inputRaster',
2964    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
2965    description=_(u'The input raster from which cells will be extracted.'),
2966    arcGISDisplayName=_(u'Input raster'))
2967
2968AddArgumentMetadata(ArcGISRaster.ExtractByMask, u'mask',
2969    typeMetadata=ArcGISGeoDatasetTypeMetadata(mustExist=True),
2970    description=_(
2971u"""Input mask data defining areas to extract.
2972
2973This is a raster or feature dataset.
2974
2975When the input mask data is a raster, NoData cells on the mask will be
2976assigned NoData values on the output raster."""),
2977    arcGISDisplayName=_(u'Input raster or feature mask data'))
2978
2979AddArgumentMetadata(ArcGISRaster.ExtractByMask, u'outputRaster',
2980    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'inputRaster', u'mask'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
2981    description=_(
2982u"""The output raster containing the cell values extracted from the
2983input raster.
2984
2985If this path refers to the file system, missing directories in the
2986path will be created if they do not exist."""),
2987    direction=u'Output',
2988    arcGISDisplayName=_(u'Output raster'))
2989
2990CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting', ArcGISRaster.ExtractByMask, u'overwriteExisting')
2991
2992# Public method: ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra
2993
2994AddMethodMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra,
2995    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.'),
2996    isExposedToPythonCallers=True,
2997    isExposedByCOM=True,
2998    isExposedAsArcGISTool=True,
2999    arcGISDisplayName=_(u'Project, Clip, and/or Execute Map Algebra'),
3000    arcGISToolCategory=_(u'Spatial Analysis\\Project, Clip and/or Execute Map Algebra'),
3001    dependencies=[ArcGISDependency(9, 1)])
3002
3003CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'cls')
3004
3005AddArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'inputRaster',
3006    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3007    description=_(u'Input raster.'),
3008    arcGISDisplayName=_(u'Input raster'))
3009
3010AddArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'outputRaster',
3011    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3012    description=_(
3013u"""Output raster to create.
3014
3015If this path refers to the file system, missing directories in the
3016path will be created if they do not exist."""),
3017    direction=u'Output',
3018    arcGISDisplayName=_(u'Output raster'))
3019
3020CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCoordinateSystem', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCoordinateSystem')
3021ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'projectedCoordinateSystem').ArcGISCategory = None
3022
3023CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'geographicTransformation', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'geographicTransformation')
3024ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'geographicTransformation').ArcGISCategory = None
3025
3026CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'resamplingTechnique', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'resamplingTechnique')
3027ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'resamplingTechnique').ArcGISCategory = None
3028
3029CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'projectedCellSize', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCellSize')
3030ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'projectedCellSize').ArcGISCategory = None
3031
3032CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'registrationPoint', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'registrationPoint')
3033ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'registrationPoint').ArcGISCategory = None
3034
3035AddArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingDataset',
3036    typeMetadata=ArcGISGeoDatasetTypeMetadata(mustExist=True, canBeNone=True),
3037    description=_(
3038u"""Existing feature class, raster, or other geographic dataset having
3039the extent to which the raster should be clipped.
3040
3041WARNING: If you use this tool from in an ArcGIS geoprocessing model
3042and you select a dataset by clicking the folder icon and browsing to
3043the dataset, your selection may mysteriously disappear from this text
3044box after you close the tool. This is a bug in ArcGIS. To work around
3045it, drag and drop the desired dataset into the model. This will create
3046a layer in the model for that dataset. Then select that layer in this
3047tool by clicking the drop-down box rather than clicking the folder
3048icon. The selected layer should not disappear when you close the
3049tool."""),
3050    arcGISDisplayName=_(u'Clip to extent of geographic dataset'))
3051
3052CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'clippingRectangle', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingRectangle')
3053ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'clippingRectangle').ArcGISCategory = None
3054
3055CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'mapAlgebraExpression', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'mapAlgebraExpression')
3056ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'mapAlgebraExpression').ArcGISCategory = None
3057
3058CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'buildPyramids', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'buildPyramids')
3059ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'buildPyramids').ArcGISCategory = None
3060
3061CopyArgumentMetadata(BinaryRaster.ToArcGISRaster, u'overwriteExisting', ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'overwriteExisting')
3062ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra.__doc__.Obj.GetArgumentByName(u'overwriteExisting').ArcGISCategory = None
3063
3064# Public method: ArcGISRaster.ProjectToTemplate
3065
3066AddMethodMetadata(ArcGISRaster.ProjectToTemplate,
3067    shortDescription=_(u'Projects a raster to the coordinate system, cell size, and extent of a template raster.'),
3068    isExposedToPythonCallers=True,
3069    isExposedByCOM=True,
3070    isExposedAsArcGISTool=True,
3071    arcGISDisplayName=_(u'Project Raster to Template'),
3072    arcGISToolCategory=_(u'Spatial Analysis\\Project Raster to Template'),
3073    dependencies=[ArcGISDependency(9, 1)])
3074
3075CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ProjectToTemplate, u'cls')
3076
3077AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'inputRaster',
3078    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3079    description=_(
3080u"""Raster to project to the template raster's coordinate system, cell
3081size, and extent."""),
3082    arcGISDisplayName=_(u'Raster to project'))
3083
3084AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'templateRaster',
3085    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3086    description=_(
3087u"""Raster defining the coordinate system, cell size, and extent of
3088the output raster."""),
3089    arcGISDisplayName=_(u'Template raster'))
3090
3091AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'outputRaster',
3092    typeMetadata=ArcGISRasterTypeMetadata(mustBeDifferentThanArguments=[u'inputRaster', u'templateRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3093    description=_(
3094u"""Output raster to create.
3095
3096If this path refers to the file system, missing directories in the
3097path will be created if they do not exist."""),
3098    direction=u'Output',
3099    arcGISDisplayName=_(u'Output raster'))
3100
3101AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'resamplingTechnique',
3102    typeMetadata=UnicodeStringTypeMetadata(makeLowercase=True, allowedValues=[u'BILINEAR', u'CUBIC']),
3103    description=_(
3104u"""Resampling algorithm to be used to project the input raster to the
3105template raster's coordinate system. One of:
3106
3107* NEAREST - `Nearest neighbor assignment
3108  <http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation>`_.
3109
3110* BILINEAR - `Bilinear interpolation
3111  <http://en.wikipedia.org/wiki/Bilinear_interpolation>`_.
3112
3113* CUBIC - Cubic convolution, also known as `bicubic interpolation
3114  <http://en.wikipedia.org/wiki/Bicubic_interpolation>`_.
3115
3116* MAJORITY - Majority resampling. This method requires ArcGIS 9.3 or
3117  later.
3118
3119The NEAREST and MAJORITY algorithms should be used for categorical
3120data, such as a land use classification. It is not recommended that
3121NEAREST or MAJORITY be used for continuous data, such as elevation
3122surfaces.
3123
3124The BILINEAR and CUBIC options are most appropriate for continuous
3125data. Do not use BILINEAR or CUBIC with categorical data.
3126
3127The projection is accomplished with the ArcGIS Project Raster tool.
3128Please see the documentation for that tool for more information."""),
3129    arcGISDisplayName=_(u'Resampling technique'))
3130
3131AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'interpolationMethod',
3132    typeMetadata=UnicodeStringTypeMetadata(makeLowercase=True, allowedValues=[u'Del2a', u'Del2b', u'Del2c', u'Del4', u'Spring'], canBeNone=True),
3133    description=_(
3134u"""Method to use to guess values for No Data cells.
3135
3136Use this option to "fill in" clusters of No Data cells with values
3137obtained by interpolation and extrapolation. This option is
3138appropriate for rasters representing continuous surfaces, e.g. images
3139of sea surface temperature in which cloudy pixels contain No Data. It
3140uses algorithms based on differential calculus that may provide more
3141accurate guesses than traditional ArcGIS approaches, such as computing
3142the focal mean of a 3x3 neighborhood.
3143
3144This option is not appropriate for rasters representing categorical
3145data, such as land cover classifications. Therefore, in order to use
3146this option, you must select BILINEAR or CUBIC for the Resampling
3147Technique parameter.
3148
3149The available algorithms are:
3150
3151* Del2a - Laplacian interpolation and linear extrapolation.
3152
3153* Del2b - Same as Del2a but does not build as large a linear system of
3154  equations. May be faster than Del2a at the cost of some accuracy.
3155
3156* Del2c - Same as Del2a but solves a direct linear system of equations
3157  for the No Data values. Faster than both Del2a and Del2b but is the
3158  least robust to noise on the boundaries of No Data cells and least
3159  able to interpolate accurately for smooth surfaces.
3160
3161* Del4 - Same as Del2a but instead of the Laplace operator (also
3162  called the del^2 operator) it uses the biharmonic operator (also
3163  called the del^4 operator). May result in more accurate
3164  interpolations, at some cost in speed.
3165
3166* Spring - Uses a spring metaphor. Assumes springs (with a nominal
3167  length of zero) connect each cell with every neighbor (horizontally,
3168  vertically and diagonally). Since each cell tries to be like its
3169  neighbors, extrapolation is as a constant function where this is
3170  consistent with the neighboring nodes.
3171
3172This option is applied after the input raster has been projected to
3173the coordinate system and cell size of the template raster.
3174
3175Although this tool can fill No Data clusters of any size, you should
3176apply common sense when using it. The larger the cluster, the less
3177accurate the guessed values will be, especially for rasters that
3178represent a noisy surface.
3179
3180Thanks to John D'Errico for providing the code that implements the
3181mathematical algorithms described here (click `here
3182<http://www.mathworks.com/matlabcentral/fileexchange/4551>`_ for more
3183information)."""),
3184    arcGISDisplayName=_(u'Method for interpolating No Data cells'),
3185    arcGISCategory=_(u'Interpolation and masking options'))
3186
3187AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'maxHoleSize',
3188    typeMetadata=IntegerTypeMetadata(mustBeGreaterThan=0, canBeNone=True),
3189    description=_(
3190u"""Maximum size, in cells of the template raster, that a region of
31914-connected No Data cells may be for it to be filled in.
3192
3193Use this option to prevent the filling of large No Data regions (e.g.
3194large clouds in remote sensing images) when you are concerned that
3195values cannot be accurately guessed for those regions. If this option
3196is omitted, all regions will be filled, regardless of size."""),
3197    arcGISDisplayName=_(u'Maximum size of No Data regions to interpolate'),
3198    arcGISCategory=_(u'Interpolation and masking options'))
3199
3200AddArgumentMetadata(ArcGISRaster.ProjectToTemplate, u'mask',
3201    typeMetadata=BooleanTypeMetadata(),
3202    description=_(
3203u"""If True, the template raster will be used to mask the input raster
3204after it has been projected to the template raster's coordinate system
3205and values have been interpolated for No Data cells (if your requested
3206that). Cells of the template raster that are No Data will be set to No
3207Data in the output raster, even if you requested that values be
3208interpolated for No Data cells. This is appropriate in situations
3209where the template defines the areas for which you want to retain
3210data; for example, when you are analyzing the ocean and you have a
3211mask in which ocean cells have data and land cells are set to No Data.
3212
3213If False, the template raster will only be used to define the
3214coordinate system, cell size, and rectangular extent of the output
3215raster, and no masking will be done."""),
3216    arcGISDisplayName=_(u'Use template raster as mask'),
3217    arcGISCategory=_(u'Interpolation and masking options'))
3218
3219CopyArgumentMetadata(ArcGISRaster.CreateXRaster, u'overwriteExisting', ArcGISRaster.ProjectToTemplate, u'overwriteExisting')
3220
3221# Public method: ArcGISRaster.ToPolygons
3222
3223AddMethodMetadata(ArcGISRaster.ToPolygons,
3224    shortDescription=_(u'Converts an ArcGIS raster to polygons that encompass groups of adjacent raster cells having the same value.'),
3225    isExposedToPythonCallers=True,
3226    isExposedByCOM=True,
3227    isExposedAsArcGISTool=True,
3228    arcGISDisplayName=_(u'Convert ArcGIS Raster to Polygons'),
3229    arcGISToolCategory=_(u'Conversion\\To Table, Shapefile, or Feature Class\\To Polygons\\From ArcGIS Raster'),
3230    dependencies=[ArcGISDependency(9, 1)])
3231
3232CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToPolygons, u'cls')
3233
3234AddArgumentMetadata(ArcGISRaster.ToPolygons, u'inputRaster',
3235    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3236    description=_(
3237u"""Raster to convert.
3238
3239The raster will be converted to a polygon feature class using the
3240ArcGIS Raster to Polygon tool. That tool can only convert integer
3241rasters to polygons. If the input raster is a floating-point raster,
3242you must use the Map Algebra Expression parameter to convert it to an
3243integer raster."""),
3244    arcGISDisplayName=_(u'Input raster'))
3245
3246AddArgumentMetadata(ArcGISRaster.ToPolygons, u'outputFeatureClass',
3247    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'polygon'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3248    description=_(
3249u"""Output polygon feature class that will contain the converted
3250polygons.
3251
3252Missing directories in this path will be created if they do not
3253exist."""),
3254    direction=u'Output',
3255    arcGISDisplayName=_(u'Output polygon feature class'))
3256
3257AddArgumentMetadata(ArcGISRaster.ToPolygons, u'simplify',
3258    typeMetadata=BooleanTypeMetadata(),
3259    description=_(
3260u"""Determines if the output polygons will be smoothed into simpler
3261shapes or conform to the input raster's cell edges.
3262
3263* True - The polygons will be smoothed into simpler shapes. This is
3264  the default.
3265
3266* False - The polygons will conform to the input raster's cell edges.
3267"""),
3268    arcGISDisplayName=_(u'Simplify polygons'))
3269
3270AddArgumentMetadata(ArcGISRaster.ToPolygons, u'field',
3271    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3272    description=_(
3273u"""The field used to assign values from the cells in the input raster
3274to the polygons in the output dataset. It can be an integer or a
3275string field."""),
3276    arcGISParameterDependencies=[u'inputRaster'],
3277    arcGISDisplayName=_(u'Field'))
3278
3279CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCoordinateSystem', ArcGISRaster.ToPolygons, u'projectedCoordinateSystem')
3280ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'projectedCoordinateSystem').ArcGISCategory = _(u'Pre-conversion processing')
3281
3282CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'geographicTransformation', ArcGISRaster.ToPolygons, u'geographicTransformation')
3283ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'geographicTransformation').ArcGISCategory = _(u'Pre-conversion processing')
3284
3285CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'resamplingTechnique', ArcGISRaster.ToPolygons, u'resamplingTechnique')
3286ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'resamplingTechnique').ArcGISCategory = _(u'Pre-conversion processing')
3287
3288CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'projectedCellSize', ArcGISRaster.ToPolygons, u'projectedCellSize')
3289ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'projectedCellSize').ArcGISCategory = _(u'Pre-conversion processing')
3290
3291CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'registrationPoint', ArcGISRaster.ToPolygons, u'registrationPoint')
3292ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'registrationPoint').ArcGISCategory = _(u'Pre-conversion processing')
3293
3294CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingDataset', ArcGISRaster.ToPolygons, u'clippingDataset')
3295ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'clippingDataset').ArcGISCategory = _(u'Pre-conversion processing')
3296
3297CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'clippingRectangle', ArcGISRaster.ToPolygons, u'clippingRectangle')
3298ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'clippingRectangle').ArcGISCategory = _(u'Pre-conversion processing')
3299
3300CopyArgumentMetadata(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra, u'mapAlgebraExpression', ArcGISRaster.ToPolygons, u'mapAlgebraExpression')
3301ArcGISRaster.ToPolygons.__doc__.Obj.GetArgumentByName(u'mapAlgebraExpression').ArcGISCategory = _(u'Pre-conversion processing')
3302
3303AddArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting',
3304    typeMetadata=BooleanTypeMetadata(),
3305    description=_(
3306u"""If True, the output feature class will be overwritten, if it
3307exists. If False, a ValueError will be raised if the output feature
3308class exists."""),
3309    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
3310
3311# Public method: ArcGISRaster.ToPolygonOutlines
3312
3313AddMethodMetadata(ArcGISRaster.ToPolygonOutlines,
3314    shortDescription=_(u'Converts an ArcGIS raster to lines that outline groups of adjacent raster cells having the same value.'),
3315    isExposedToPythonCallers=True,
3316    isExposedByCOM=True,
3317    isExposedAsArcGISTool=True,
3318    arcGISDisplayName=_(u'Convert ArcGIS Raster to Polygon Outlines'),
3319    arcGISToolCategory=_(u'Conversion\\To Table, Shapefile, or Feature Class\\To Polygon Outlines\\From ArcGIS Raster'),
3320    dependencies=[ArcGISDependency(9, 1)])
3321
3322CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToPolygonOutlines, u'cls')
3323
3324AddArgumentMetadata(ArcGISRaster.ToPolygonOutlines, u'inputRaster',
3325    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3326    description=_(
3327u"""Raster to convert.
3328
3329The raster will be converted to a polygon feature class using the
3330ArcGIS Raster to Polygon tool, and then to line features using the
3331Feature to Line tool. The Raster to Polygon tool can only convert
3332integer rasters to polygons. If the input raster is a floating-point
3333raster, you must use the Map Algebra Expression parameter to convert
3334it to an integer raster."""),
3335    arcGISDisplayName=_(u'Input raster'))
3336
3337AddArgumentMetadata(ArcGISRaster.ToPolygonOutlines, u'outputFeatureClass',
3338    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'polyline'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3339    description=_(
3340u"""Output line feature class.
3341
3342Missing directories in this path will be created if they do not
3343exist."""),
3344    direction=u'Output',
3345    arcGISDisplayName=_(u'Output line feature class'))
3346
3347CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'simplify', ArcGISRaster.ToPolygonOutlines, u'simplify')
3348
3349AddArgumentMetadata(ArcGISRaster.ToPolygonOutlines, u'field',
3350    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3351    description=_(
3352u"""The field used to assign values from the cells in the input raster
3353to the lines in the output dataset. It can be an integer or a
3354string field."""),
3355    arcGISParameterDependencies=[u'inputRaster'],
3356    arcGISDisplayName=_(u'Field'))
3357
3358CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCoordinateSystem', ArcGISRaster.ToPolygonOutlines, u'projectedCoordinateSystem')
3359CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'geographicTransformation', ArcGISRaster.ToPolygonOutlines, u'geographicTransformation')
3360CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'resamplingTechnique', ArcGISRaster.ToPolygonOutlines, u'resamplingTechnique')
3361CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCellSize', ArcGISRaster.ToPolygonOutlines, u'projectedCellSize')
3362CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'registrationPoint', ArcGISRaster.ToPolygonOutlines, u'registrationPoint')
3363CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingDataset', ArcGISRaster.ToPolygonOutlines, u'clippingDataset')
3364CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingRectangle', ArcGISRaster.ToPolygonOutlines, u'clippingRectangle')
3365CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'mapAlgebraExpression', ArcGISRaster.ToPolygonOutlines, u'mapAlgebraExpression')
3366CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting', ArcGISRaster.ToPolygonOutlines, u'overwriteExisting')
3367
3368# Public method: ArcGISRaster.ToLines
3369
3370AddMethodMetadata(ArcGISRaster.ToLines,
3371    shortDescription=_(u'Converts an ArcGIS raster to a feature class of lines that connect adjacent foreground raster cells.'),
3372    isExposedToPythonCallers=True,
3373    isExposedByCOM=True,
3374    isExposedAsArcGISTool=True,
3375    arcGISDisplayName=_(u'Convert ArcGIS Raster to Lines'),
3376    arcGISToolCategory=_(u'Conversion\\To Table, Shapefile, or Feature Class\\To Lines\\From ArcGIS Raster'),
3377    dependencies=[ArcGISDependency(9, 1)])
3378
3379CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToLines, u'cls')
3380
3381AddArgumentMetadata(ArcGISRaster.ToLines, u'inputRaster',
3382    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3383    description=_(
3384u"""Raster to convert.
3385
3386The raster will be converted to a line feature class using the
3387ArcGIS Raster to Polyline tool. For each pair of adjacent foreground
3388raster cells, the tool draws a line connecting their centers. This
3389algorithm is appropriate for converting line-like raster features,
3390such as sea surface temperature fronts or other boundary data, into
3391vector features."""),
3392    arcGISDisplayName=_(u'Input raster'))
3393
3394AddArgumentMetadata(ArcGISRaster.ToLines, u'outputFeatureClass',
3395    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'polyline'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3396    description=_(
3397u"""Output polygon feature class that will contain the converted
3398lines.
3399
3400Missing directories in this path will be created if they do not
3401exist."""),
3402    direction=u'Output',
3403    arcGISDisplayName=_(u'Output line feature class'))
3404
3405AddArgumentMetadata(ArcGISRaster.ToLines, u'backgroundValue',
3406    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'ZERO', u'NODATA'], makeLowercase=True),
3407    description=_(
3408u"""Specifies the cell value that will identify the background cells.
3409The raster dataset is viewed as a set of foreground cells and
3410background cells. The linear features are formed from the foreground
3411cells.
3412
3413* ZERO - The background is composed of cells of zero or less or
3414  NoData. All cells with a value greater than zero are considered a
3415  foreground value.
3416
3417* NODATA - The background is composed of NoData cells. All cells with
3418  valid values belong to the foreground.
3419"""),
3420    arcGISDisplayName=_(u'Background value'))
3421
3422AddArgumentMetadata(ArcGISRaster.ToLines, u'minDangleLength',
3423    typeMetadata=FloatTypeMetadata(minValue=0.0),
3424    description=_(
3425u"""Minimum length of dangling lines that will be retained. The
3426default is zero."""),
3427    arcGISDisplayName=_(u'Minimum dangle length'))
3428
3429AddArgumentMetadata(ArcGISRaster.ToLines, u'simplify',
3430    typeMetadata=BooleanTypeMetadata(),
3431    description=_(
3432u"""If True (the default) the output lines will be smoothed
3433according to an undocumented algorithm implemented by the ArcGIS
3434Raster to Polyline tool."""),
3435    arcGISDisplayName=_(u'Simplify lines'))
3436
3437AddArgumentMetadata(ArcGISRaster.ToLines, u'field',
3438    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3439    description=_(
3440u"""The field used to assign values from the cells in the input raster
3441to the lines in the output dataset. It can be an integer or a
3442string field."""),
3443    arcGISParameterDependencies=[u'inputRaster'],
3444    arcGISDisplayName=_(u'Field'))
3445
3446CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCoordinateSystem', ArcGISRaster.ToLines, u'projectedCoordinateSystem')
3447CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'geographicTransformation', ArcGISRaster.ToLines, u'geographicTransformation')
3448CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'resamplingTechnique', ArcGISRaster.ToLines, u'resamplingTechnique')
3449CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCellSize', ArcGISRaster.ToLines, u'projectedCellSize')
3450CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'registrationPoint', ArcGISRaster.ToLines, u'registrationPoint')
3451CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingDataset', ArcGISRaster.ToLines, u'clippingDataset')
3452CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingRectangle', ArcGISRaster.ToLines, u'clippingRectangle')
3453CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'mapAlgebraExpression', ArcGISRaster.ToLines, u'mapAlgebraExpression')
3454CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting', ArcGISRaster.ToLines, u'overwriteExisting')
3455
3456# Public method: ArcGISRaster.ToPoints
3457
3458AddMethodMetadata(ArcGISRaster.ToPoints,
3459    shortDescription=_(u'Converts an ArcGIS raster to a feature class of points that occur at the centers of the raster cells.'),
3460    isExposedToPythonCallers=True,
3461    isExposedByCOM=True,
3462    isExposedAsArcGISTool=True,
3463    arcGISDisplayName=_(u'Convert ArcGIS Raster to Points'),
3464    arcGISToolCategory=_(u'Conversion\\To Table, Shapefile, or Feature Class\\To Points\\From ArcGIS Raster'),
3465    dependencies=[ArcGISDependency(9, 1)])
3466
3467CopyArgumentMetadata(ArcGISRaster.Copy, u'cls', ArcGISRaster.ToPoints, u'cls')
3468
3469AddArgumentMetadata(ArcGISRaster.ToPoints, u'inputRaster',
3470    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
3471    description=_(
3472u"""Raster to convert.
3473
3474The raster will be converted to a point feature class using the ArcGIS
3475Raster to Point tool. This tool creates a point at the center of each
3476raster cell, except noData cells."""),
3477    arcGISDisplayName=_(u'Input raster'))
3478
3479AddArgumentMetadata(ArcGISRaster.ToPoints, u'outputFeatureClass',
3480    typeMetadata=ArcGISFeatureClassTypeMetadata(allowedShapeTypes=[u'point'], mustBeDifferentThanArguments=[u'inputRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
3481    description=_(
3482u"""Output point feature class.
3483
3484Missing directories in this path will be created if they do not
3485exist."""),
3486    direction=u'Output',
3487    arcGISDisplayName=_(u'Output point feature class'))
3488
3489AddArgumentMetadata(ArcGISRaster.ToPoints, u'field',
3490    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'SHORT', u'LONG', u'TEXT'], canBeNone=True),
3491    description=_(
3492u"""The field used to assign values from the cells in the input raster
3493to the points in the output dataset. It can be an integer,
3494floating-point, or string field."""),
3495    arcGISParameterDependencies=[u'inputRaster'],
3496    arcGISDisplayName=_(u'Field'))
3497
3498CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCoordinateSystem', ArcGISRaster.ToPoints, u'projectedCoordinateSystem')
3499CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'geographicTransformation', ArcGISRaster.ToPoints, u'geographicTransformation')
3500CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'resamplingTechnique', ArcGISRaster.ToPoints, u'resamplingTechnique')
3501CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'projectedCellSize', ArcGISRaster.ToPoints, u'projectedCellSize')
3502CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'registrationPoint', ArcGISRaster.ToPoints, u'registrationPoint')
3503CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingDataset', ArcGISRaster.ToPoints, u'clippingDataset')
3504CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'clippingRectangle', ArcGISRaster.ToPoints, u'clippingRectangle')
3505CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'mapAlgebraExpression', ArcGISRaster.ToPoints, u'mapAlgebraExpression')
3506CopyArgumentMetadata(ArcGISRaster.ToPolygons, u'overwriteExisting', ArcGISRaster.ToPoints, u'overwriteExisting')
3507
3508###############################################################################
3509# Batch processing versions of methods
3510###############################################################################
3511
3512from GeoEco.BatchProcessing import BatchProcessing
3513from GeoEco.DataManagement.Fields import Field
3514
3515BatchProcessing.GenerateForMethod(ArcGISRaster.Copy,
3516    inputParamNames=[u'sourceRaster'],
3517    inputParamFieldArcGISDisplayNames=[_(u'Source raster field')],
3518    inputParamDescriptions=[_(u'%s rasters to copy.')],
3519    outputParamNames=[u'destinationRaster'],
3520    outputParamFieldArcGISDisplayNames=[_(u'Destination raster field')],
3521    outputParamExpressionArcGISDisplayNames=[_(u'Destination raster Python expression')],
3522    outputParamDescriptions=[_(u'%s destination rasters.')],
3523    outputParamExpressionDescriptions=[
3524u"""Python expression used to calculate the absolute path of a
3525destination raster. The expression may be any Python statement
3526appropriate for passing to the eval function and must return a Unicode
3527string. The expression may reference the following variables:
3528
3529* workspaceToSearch - the value provided for the workspace to search
3530  parameter
3531
3532* destinationWorkspace - the value provided for the destination
3533  workspace parameter
3534
3535* sourceRaster - the absolute path to the source raster
3536
3537The default expression::
3538
3539    os.path.join(destinationWorkspace, sourceRaster[len(workspaceToSearch)+1:])
3540
3541stores the raster in the destination workspace at the same relative
3542location it appears in the workspace to search. The destination path
3543is calculated by stripping the workspace to search from the source
3544path and replacing it with the destination workspace.
3545
3546For more information on Python syntax, please see the `Python
3547documentation <http://www.python.org/doc/>`_."""],
3548    outputParamDefaultExpressions=[u'os.path.join(destinationWorkspace, sourceRaster[len(workspaceToSearch)+1:])'],
3549    processListMethodName=u'CopyList',
3550    processListMethodShortDescription=_(u'Copies a list of ArcGIS rasters.'),
3551    processTableMethodName=u'CopyTable',
3552    processTableMethodShortDescription=_(u'Copies the ArcGIS rasters listed in a table.'),
3553    processArcGISTableMethodName=u'CopyArcGISTable',
3554    processArcGISTableMethodArcGISDisplayName=_(u'Copy Rasters Listed in Table'),
3555    findAndProcessMethodName=u'FindAndCopy',
3556    findAndProcessMethodArcGISDisplayName=u'Find and Copy Rasters',
3557    findAndProcessMethodShortDescription=_(u'Finds and copies rasters in an ArcGIS workspace.'),
3558    findMethod=ArcGISRaster.FindAndCreateTable,
3559    findOutputFieldParams=[u'rasterField'],
3560    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3561    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3562    outputLocationParamDescription=_(u'Workspace to receive copies of the rasters.'),
3563    outputLocationParamArcGISDisplayName=_(u'Destination workspace'),
3564    calculateFieldMethod=Field.CalculateField,
3565    calculateFieldExpressionParam=u'pythonExpression',
3566    calculateFieldAdditionalParams=[u'modulesToImport'],
3567    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3568    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3569    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']],
3570    calculatedOutputsArcGISCategory=_(u'Destination raster name options'),
3571    skipExistingDescription=_(u'If True, copying will be skipped for destination rasters that already exist.'),
3572    overwriteExistingDescription=_(u'If True and skipExisting is False, existing destination rasters will be overwritten.'))
3573
3574BatchProcessing.GenerateForMethod(ArcGISRaster.Delete,
3575    inputParamNames=[u'raster'],
3576    inputParamFieldArcGISDisplayNames=[_(u'Raster field')],
3577    inputParamDescriptions=[_(u'%s rasters to delete.')],
3578    processListMethodName=u'DeleteList',
3579    processListMethodShortDescription=_(u'Deletes a list of ArcGIS rasters.'),
3580    processTableMethodName=u'DeleteTable',
3581    processTableMethodShortDescription=_(u'Deletes the ArcGIS rasters listed in a table.'),
3582    processArcGISTableMethodName=u'DeleteArcGISTable',
3583    processArcGISTableMethodArcGISDisplayName=_(u'Delete Rasters Listed in Table'),
3584    findAndProcessMethodName=u'FindAndDelete',
3585    findAndProcessMethodArcGISDisplayName=u'Find and Delete Rasters',
3586    findAndProcessMethodShortDescription=_(u'Finds and deletes rasters in an ArcGIS workspace.'),
3587    findMethod=ArcGISRaster.FindAndCreateTable,
3588    findOutputFieldParams=[u'rasterField'],
3589    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'])
3590
3591BatchProcessing.GenerateForMethod(ArcGISRaster.Move,
3592    inputParamNames=[u'sourceRaster'],
3593    inputParamFieldArcGISDisplayNames=[_(u'Source raster field')],
3594    inputParamDescriptions=[_(u'%s rasters to move.')],
3595    outputParamNames=[u'destinationRaster'],
3596    outputParamFieldArcGISDisplayNames=[_(u'Destination raster field')],
3597    outputParamExpressionArcGISDisplayNames=[_(u'Destination raster Python expression')],
3598    outputParamDescriptions=[_(u'%s destination rasters.')],
3599    outputParamExpressionDescriptions=[ArcGISRaster.FindAndCopy.__doc__.Obj.GetArgumentByName(u'destinationRasterPythonExpression').Description],
3600    outputParamDefaultExpressions=[ArcGISRaster.FindAndCopy.__doc__.Obj.GetArgumentByName(u'destinationRasterPythonExpression').Default],
3601    processListMethodName=u'MoveList',
3602    processListMethodShortDescription=_(u'Moves a list of ArcGIS rasters.'),
3603    processTableMethodName=u'MoveTable',
3604    processTableMethodShortDescription=_(u'Moves the ArcGIS rasters listed in a table.'),
3605    processArcGISTableMethodName=u'MoveArcGISTable',
3606    processArcGISTableMethodArcGISDisplayName=_(u'Move Rasters Listed in Table'),
3607    findAndProcessMethodName=u'FindAndMove',
3608    findAndProcessMethodArcGISDisplayName=u'Find and Move Rasters',
3609    findAndProcessMethodShortDescription=_(u'Finds and moves rasters in an ArcGIS workspace.'),
3610    findMethod=ArcGISRaster.FindAndCreateTable,
3611    findOutputFieldParams=[u'rasterField'],
3612    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3613    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3614    outputLocationParamDescription=_(u'Workspace to receive the rasters.'),
3615    outputLocationParamArcGISDisplayName=_(u'Destination workspace'),
3616    calculateFieldMethod=Field.CalculateField,
3617    calculateFieldExpressionParam=u'pythonExpression',
3618    calculateFieldAdditionalParams=[u'modulesToImport'],
3619    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3620    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3621    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']],
3622    calculatedOutputsArcGISCategory=_(u'Destination raster name options'),
3623    skipExistingDescription=_(u'If True, moving will be skipped for destination rasters that already exist.'),
3624    overwriteExistingDescription=_(u'If True and skipExisting is False, existing destination rasters will be overwritten.'))
3625
3626_OutputRasterParamExpressionDescription = _(
3627u"""Python expression used to calculate the absolute path of an output
3628raster. The expression may be any Python statement appropriate
3629for passing to the eval function and must return a Unicode string. The
3630expression may reference the following variables:
3631
3632* workspaceToSearch - the value provided for the workspace to search
3633  parameter
3634
3635* outputWorkspace - the value provided for the output workspace
3636  parameter
3637
3638* inputRaster - the absolute path to the input raster
3639
3640The default expression::
3641
3642    os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])
3643
3644stores the output rasters in the output workspace at the same relative
3645location as the input rasteres appear in the workspace to search. The
3646output raster path is calculated by stripping the workspace to search
3647from the input raster path and replacing it with the output workspace.
3648
3649For more information on Python syntax, please see the `Python
3650documentation <http://www.python.org/doc/>`_.""")
3651
3652BatchProcessing.GenerateForMethod(ArcGISRaster.ExtractByMask,
3653    inputParamNames=[u'inputRaster'],
3654    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3655    inputParamDescriptions=[_(u'%s input rasters.')],
3656    outputParamNames=[u'outputRaster'],
3657    outputParamFieldArcGISDisplayNames=[_(u'Output raster field')],
3658    outputParamExpressionArcGISDisplayNames=[_(u'Output raster Python expression')],
3659    outputParamDescriptions=[_(
3660u"""%s output rasters to receive the cell values extracted from the
3661input rasters.
3662
3663If these paths refers to the file system, missing directories in the
3664paths will be created if they do not exist.""")],
3665    outputParamExpressionDescriptions=[_OutputRasterParamExpressionDescription],
3666    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3667    constantParamNames=[u'mask'],
3668    processListMethodName=u'ExtractByMaskList',
3669    processListMethodShortDescription=_(u'For each ArcGIS raster in a list, extracts the cells that correspond to the areas defined by a mask.'),
3670    processTableMethodName=u'ExtractByMaskTable',
3671    processTableMethodShortDescription=_(u'For each ArcGIS raster in a table, extracts the cells that correspond to the areas defined by a mask.'),
3672    processArcGISTableMethodName=u'ExtractByMaskArcGISTable',
3673    processArcGISTableMethodArcGISDisplayName=_(u'Extract By Mask for ArcGIS Rasters Listed in Table'),
3674    findAndProcessMethodName=u'FindAndExtractByMask',
3675    findAndProcessMethodArcGISDisplayName=u'Find ArcGIS Rasters and Extract By Mask',
3676    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and extracts the cells that correspond to the areas defined by a mask.'),
3677    findMethod=ArcGISRaster.FindAndCreateTable,
3678    findOutputFieldParams=[u'rasterField'],
3679    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3680    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3681    outputLocationParamDescription=_(u'Workspace to receive the output rasters.'),
3682    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3683    calculateFieldMethod=Field.CalculateField,
3684    calculateFieldExpressionParam=u'pythonExpression',
3685    calculateFieldAdditionalParams=[u'modulesToImport'],
3686    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3687    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3688    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']],
3689    calculatedOutputsArcGISCategory=_(u'Output raster name options'),
3690    skipExistingDescription=_(u'If True, processing will be skipped for output rasters that already exist.'),
3691    overwriteExistingDescription=_(u'If True and skipExisting is False, existing output rasters will be overwritten.'))
3692
3693BatchProcessing.GenerateForMethod(ArcGISRaster.ProjectClipAndOrExecuteMapAlgebra,
3694    inputParamNames=[u'inputRaster'],
3695    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3696    inputParamDescriptions=[_(u'%s input rasters.')],
3697    outputParamNames=[u'outputRaster'],
3698    outputParamFieldArcGISDisplayNames=[_(u'Output raster field')],
3699    outputParamExpressionArcGISDisplayNames=[_(u'Output raster Python expression')],
3700    outputParamDescriptions=[_(
3701u"""%s output rasters.
3702
3703If these paths refers to the file system, missing directories in the
3704paths will be created if they do not exist.""")],
3705    outputParamExpressionDescriptions=[_OutputRasterParamExpressionDescription],
3706    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3707    constantParamNames=[u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression', u'buildPyramids'],
3708    processListMethodName=u'ProjectClipAndOrExecuteMapAlgebraList',
3709    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.'),
3710    processTableMethodName=u'ProjectClipAndOrExecuteMapAlgebraTable',
3711    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.'),
3712    processArcGISTableMethodName=u'ProjectClipAndOrExecuteMapAlgebraArcGISTable',
3713    processArcGISTableMethodArcGISDisplayName=_(u'Project, Clip, and/or Execute Map Algebra on ArcGIS Rasters Listed in Table'),
3714    findAndProcessMethodName=u'FindAndProjectClipAndOrExecuteMapAlgebra',
3715    findAndProcessMethodArcGISDisplayName=u'Find ArcGIS Rasters and Project, Clip, and/or Execute Map Algebra',
3716    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.'),
3717    findMethod=ArcGISRaster.FindAndCreateTable,
3718    findOutputFieldParams=[u'rasterField'],
3719    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3720    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3721    outputLocationParamDescription=_(u'Workspace to receive the output rasters.'),
3722    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3723    calculateFieldMethod=Field.CalculateField,
3724    calculateFieldExpressionParam=u'pythonExpression',
3725    calculateFieldAdditionalParams=[u'modulesToImport'],
3726    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3727    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3728    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']],
3729    calculatedOutputsArcGISCategory=_(u'Output raster name options'),
3730    skipExistingDescription=_(u'If True, processing will be skipped for output rasters that already exist.'),
3731    overwriteExistingDescription=_(u'If True and skipExisting is False, existing output rasters will be overwritten.'))
3732
3733BatchProcessing.GenerateForMethod(ArcGISRaster.ProjectToTemplate,
3734    inputParamNames=[u'inputRaster'],
3735    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3736    inputParamDescriptions=[_(u'%s input rasters to project to the template raster\'s coordinate system, cell size, and extent.')],
3737    outputParamNames=[u'outputRaster'],
3738    outputParamFieldArcGISDisplayNames=[_(u'Output raster field')],
3739    outputParamExpressionArcGISDisplayNames=[_(u'Output raster Python expression')],
3740    outputParamDescriptions=[_(
3741u"""%s output rasters to create.
3742
3743If these paths refers to the file system, missing directories in the
3744paths will be created if they do not exist.""")],
3745    outputParamExpressionDescriptions=[_OutputRasterParamExpressionDescription],
3746    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3747    constantParamNames=[u'templateRaster', u'resamplingTechnique', u'interpolationMethod', u'maxHoleSize', u'mask'],
3748    processListMethodName=u'ProjectToTemplateList',
3749    processListMethodShortDescription=_(u'Projects a list of rasters to the coordinate system, cell size, and extent of a template raster.'),
3750    processTableMethodName=u'ProjectToTemplateTable',
3751    processTableMethodShortDescription=_(u'Projects a table of rasters to the coordinate system, cell size, and extent of a template raster.'),
3752    processArcGISTableMethodName=u'ProjectToTemplateArcGISTable',
3753    processArcGISTableMethodArcGISDisplayName=_(u'Project Rasters Listed in Table to Template'),
3754    findAndProcessMethodName=u'FindAndProjectRastersToTemplate',
3755    findAndProcessMethodArcGISDisplayName=u'Find ArcGIS Rasters and Project to Template',
3756    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and projects them to the coordinate system, cell size, and extent of a template raster.'),
3757    findMethod=ArcGISRaster.FindAndCreateTable,
3758    findOutputFieldParams=[u'rasterField'],
3759    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3760    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3761    outputLocationParamDescription=_(u'Workspace to receive the output rasters.'),
3762    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3763    calculateFieldMethod=Field.CalculateField,
3764    calculateFieldExpressionParam=u'pythonExpression',
3765    calculateFieldAdditionalParams=[u'modulesToImport'],
3766    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3767    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3768    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']],
3769    calculatedOutputsArcGISCategory=_(u'Output raster name options'),
3770    skipExistingDescription=_(u'If True, processing will be skipped for output rasters that already exist.'),
3771    overwriteExistingDescription=_(u'If True and skipExisting is False, existing output rasters will be overwritten.'))
3772
3773_OutputFeatureClassParamExpressionDescription = _(u"""Python expression used to calculate the absolute path of an output
3774feature class. The expression may be any Python statement appropriate
3775for passing to the eval function and must return a Unicode string. The
3776expression may reference the following variables:
3777
3778* workspaceToSearch - the value provided for the workspace to search
3779  parameter
3780
3781* outputWorkspace - the value provided for the output workspace
3782  parameter
3783
3784* inputRaster - the absolute path to the input raster
3785
3786The default expression::
3787
3788    os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])
3789
3790stores the feature classes in the output workspace at the same
3791relative location as the input rasteres in the workspace to search.
3792The feature class path is calculated by stripping the workspace to
3793search from the input raster path and replacing it with the output
3794workspace.
3795
3796For more information on Python syntax, please see the `Python
3797documentation <http://www.python.org/doc/>`_.""")
3798
3799BatchProcessing.GenerateForMethod(ArcGISRaster.ToPolygons,
3800    inputParamNames=[u'inputRaster'],
3801    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3802    inputParamDescriptions=[_(
3803u"""%s rasters to convert.
3804
3805The rasters will be converted to polygon feature classes using the
3806ArcGIS Raster to Polygon tool. That tool can only convert integer
3807rasters to polygons. If the input rasters are floating-point rasters,
3808you must use the Map Algebra Expression parameter to convert them to
3809integer rasters.""")],
3810    outputParamNames=[u'outputFeatureClass'],
3811    outputParamFieldArcGISDisplayNames=[_(u'Output polygon feature class field')],
3812    outputParamExpressionArcGISDisplayNames=[_(u'Output polygon feature class Python expression')],
3813    outputParamDescriptions=[_(
3814u"""%s output polygon feature classes.
3815
3816One feature class will be created per raster. Missing directories the
3817output paths will be created if they do not exist.""")],
3818    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3819    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3820    constantParamNames=[u'simplify', u'field', u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression'],
3821    processListMethodName=u'ToPolygonsList',
3822    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to polygons that encompass groups of adjacent raster cells having the same value.'),
3823    processTableMethodName=u'ToPolygonsTable',
3824    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to polygons that encompass groups of adjacent raster cells having the same value.'),
3825    processArcGISTableMethodName=u'ToPolygonsArcGISTable',
3826    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Polygons'),
3827    findAndProcessMethodName=u'FindAndConvertToPolygons',
3828    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Polygons',
3829    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to polygons that encompass groups of adjacent raster cells having the same value.'),
3830    findMethod=ArcGISRaster.FindAndCreateTable,
3831    findOutputFieldParams=[u'rasterField'],
3832    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3833    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3834    outputLocationParamDescription=_(u'Workspace to receive the polygon feature classes.'),
3835    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3836    calculateFieldMethod=Field.CalculateField,
3837    calculateFieldExpressionParam=u'pythonExpression',
3838    calculateFieldAdditionalParams=[u'modulesToImport'],
3839    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3840    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3841    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']],
3842    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3843    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3844    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3845
3846BatchProcessing.GenerateForMethod(ArcGISRaster.ToPolygonOutlines,
3847    inputParamNames=[u'inputRaster'],
3848    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3849    inputParamDescriptions=[_(
3850u"""%s rasters to convert.
3851
3852The rasters will be converted to polygon feature classes using the
3853ArcGIS Raster to Polygon tool, and then to line features using the
3854Feature to Line tool. The Raster to Polygon tool can only convert
3855integer rasters to polygons. If the input rasters are floating-point
3856rasters, you must use the Map Algebra Expression parameter to convert
3857them to integer rasters.""")],
3858    outputParamNames=[u'outputFeatureClass'],
3859    outputParamFieldArcGISDisplayNames=[_(u'Output line feature class field')],
3860    outputParamExpressionArcGISDisplayNames=[_(u'Output line feature class Python expression')],
3861    outputParamDescriptions=[_(
3862u"""%s output line feature classes.
3863
3864One feature class will be created per raster. Missing directories the
3865output paths will be created if they do not exist.""")],
3866    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3867    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3868    constantParamNames=[u'simplify', u'field', u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression'],
3869    processListMethodName=u'ToPolygonOutlinesList',
3870    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to lines that outline groups of adjacent raster cells having the same value.'),
3871    processTableMethodName=u'ToPolygonOutlinesTable',
3872    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to lines that outline groups of adjacent raster cells having the same value.'),
3873    processArcGISTableMethodName=u'ToPolygonOutlinesArcGISTable',
3874    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Polygon Outlines'),
3875    findAndProcessMethodName=u'FindAndConvertToPolygonOutlines',
3876    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Polygon Outlines',
3877    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to lines that outline groups of adjacent raster cells having the same value.'),
3878    findMethod=ArcGISRaster.FindAndCreateTable,
3879    findOutputFieldParams=[u'rasterField'],
3880    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3881    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3882    outputLocationParamDescription=_(u'Workspace to receive the line feature classes.'),
3883    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3884    calculateFieldMethod=Field.CalculateField,
3885    calculateFieldExpressionParam=u'pythonExpression',
3886    calculateFieldAdditionalParams=[u'modulesToImport'],
3887    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3888    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3889    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']],
3890    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3891    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3892    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3893
3894BatchProcessing.GenerateForMethod(ArcGISRaster.ToLines,
3895    inputParamNames=[u'inputRaster'],
3896    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3897    inputParamDescriptions=[_(
3898u"""%s rasters to convert.
3899
3900The rasters will be converted to line feature classes using the
3901ArcGIS Raster to Polyline tool. For each pair of adjacent foreground
3902raster cells, the tool draws a line connecting their centers. This
3903algorithm is appropriate for converting line-like raster features,
3904such as sea surface temperature fronts or other boundary data, into
3905vector features.""")],
3906    outputParamNames=[u'outputFeatureClass'],
3907    outputParamFieldArcGISDisplayNames=[_(u'Output line feature class field')],
3908    outputParamExpressionArcGISDisplayNames=[_(u'Output line feature class Python expression')],
3909    outputParamDescriptions=[_(
3910u"""%s output line feature classes.
3911
3912One feature class will be created per raster. Missing directories the
3913output paths will be created if they do not exist.""")],
3914    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3915    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3916    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'],
3917    processListMethodName=u'ToLinesList',
3918    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to lines that outline groups of adjacent raster cells having the same value.'),
3919    processTableMethodName=u'ToLinesTable',
3920    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to lines that outline groups of adjacent raster cells having the same value.'),
3921    processArcGISTableMethodName=u'ToLinesArcGISTable',
3922    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Lines'),
3923    findAndProcessMethodName=u'FindAndConvertToLines',
3924    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Lines',
3925    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to lines that outline groups of adjacent raster cells having the same value.'),
3926    findMethod=ArcGISRaster.FindAndCreateTable,
3927    findOutputFieldParams=[u'rasterField'],
3928    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3929    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3930    outputLocationParamDescription=_(u'Workspace to receive the line feature classes.'),
3931    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3932    calculateFieldMethod=Field.CalculateField,
3933    calculateFieldExpressionParam=u'pythonExpression',
3934    calculateFieldAdditionalParams=[u'modulesToImport'],
3935    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3936    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3937    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']],
3938    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3939    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3940    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3941
3942BatchProcessing.GenerateForMethod(ArcGISRaster.ToPoints,
3943    inputParamNames=[u'inputRaster'],
3944    inputParamFieldArcGISDisplayNames=[_(u'Input raster field')],
3945    inputParamDescriptions=[_(
3946u"""%s rasters to convert.
3947
3948The rasters will be converted to point feature classes using the
3949ArcGIS Raster to Point tool. This tool creates a point at the center
3950of each raster cell, except NoData cells.""")],
3951    outputParamNames=[u'outputFeatureClass'],
3952    outputParamFieldArcGISDisplayNames=[_(u'Output point feature class field')],
3953    outputParamExpressionArcGISDisplayNames=[_(u'Output point feature class Python expression')],
3954    outputParamDescriptions=[_(
3955u"""%s output point feature classes.
3956
3957One feature class will be created per raster. Missing directories the
3958output paths will be created if they do not exist.""")],
3959    outputParamExpressionDescriptions=[_OutputFeatureClassParamExpressionDescription],
3960    outputParamDefaultExpressions=[u'os.path.join(outputWorkspace, inputRaster[len(workspaceToSearch)+1:])'],
3961    constantParamNames=[u'field', u'projectedCoordinateSystem', u'geographicTransformation', u'resamplingTechnique', u'projectedCellSize', u'registrationPoint', u'clippingDataset', u'clippingRectangle', u'mapAlgebraExpression'],
3962    processListMethodName=u'ToPointsList',
3963    processListMethodShortDescription=_(u'Converts a list of ArcGIS rasters to points that occur at the centers of the raster cells.'),
3964    processTableMethodName=u'ToPointsTable',
3965    processTableMethodShortDescription=_(u'Converts the ArcGIS rasters listed in a table to points that occur at the centers of the raster cells.'),
3966    processArcGISTableMethodName=u'ToPointsArcGISTable',
3967    processArcGISTableMethodArcGISDisplayName=_(u'Convert ArcGIS Rasters Listed in Table to Points'),
3968    findAndProcessMethodName=u'FindAndConvertToPoints',
3969    findAndProcessMethodArcGISDisplayName=u'Find and Convert ArcGIS Rasters to Points',
3970    findAndProcessMethodShortDescription=_(u'Finds rasters in an ArcGIS workspace and converts them to points that occur at the centers of the raster cells.'),
3971    findMethod=ArcGISRaster.FindAndCreateTable,
3972    findOutputFieldParams=[u'rasterField'],
3973    findAdditionalParams=[u'wildcard', u'searchTree', u'rasterType'],
3974    outputLocationTypeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
3975    outputLocationParamDescription=_(u'Workspace to receive the point feature classes.'),
3976    outputLocationParamArcGISDisplayName=_(u'Output workspace'),
3977    calculateFieldMethod=Field.CalculateField,
3978    calculateFieldExpressionParam=u'pythonExpression',
3979    calculateFieldAdditionalParams=[u'modulesToImport'],
3980    calculateFieldAdditionalParamsDefaults=[[u'os.path']],
3981    calculateFieldHiddenParams=[u'statementsToExecFirst', u'statementsToExecPerRow'],
3982    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']],
3983    calculatedOutputsArcGISCategory=_(u'Output feature class name options'),
3984    skipExistingDescription=_(u'If True, conversion will be skipped for feature classes that already exist.'),
3985    overwriteExistingDescription=_(u'If True and skipExisting is False, existing feature classes will be overwritten.'))
3986
3987###############################################################################
3988# Names exported by this module
3989###############################################################################
3990
3991__all__ = ['ArcGISRaster']
Note: See TracBrowser for help on using the browser.