Changeset 773

Show
Ignore:
Timestamp:
03/19/11 19:02:59 (2 years ago)
Author:
jjr8
Message:

Started work on AvisoGriddedGeostrophicCurrents?.CreateVectorsAsArcGISFeatureClasses()

Location:
MGET/Branches/Jason/PythonPackage/src/GeoEco
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • MGET/Branches/Jason/PythonPackage/src/GeoEco/DataProducts/Aviso.py

    r772 r773  
    495495 
    496496    @classmethod 
     497    def CreateVectorsAsArcGISFeatureClasses(cls, username, password, productName, 
     498                                            outputWorkspace, mode=u'add', featureClassNameExpressions=['%(Region)s', '%(DataSeries)s', '%(Satellites)s', '%(Variable)s_uv_vectors', '%%Y', '%(DataSeries)s_%(Satellites)s_uv_vectors_%%Y%%j.shp'], 
     499                                            rotationOffset=None, spatialExtent=None, linearUnit=u'Degrees', startDate=None, endDate=None, 
     500                                            timeout=60, maxRetryTime=120, cacheDirectory=None): 
     501        cls.__doc__.Obj.ValidateMethodInvocation() 
     502        grid = AvisoGriddedGeostrophicCurrents(productName, vectorComponent, username, password, timeout, maxRetryTime, cacheDirectory) 
     503        _AvisoGriddedProduct.CreateClimatologicalArcGISRasters(grid, statistic, binType, outputWorkspace, mode, rasterNameExpressions, binDuration, startDayOfYear, rotationOffset, spatialExtent, linearUnit, startDate, endDate, calculateStatistics, buildPyramids) 
     504        return outputWorkspace 
     505 
     506    @classmethod 
    497507    def InterpolateAtArcGISPoints(cls, username, password, productName, vectorComponent, 
    498508                                   points, valueField, tField, method=u'Nearest', where=None, noDataValue=None, 
     
    903913    typeMetadata=FloatTypeMetadata(canBeNone=True), 
    904914    description=_( 
    905 u"""Distance to rotate the output rasters about the polar axis, in the 
    906 units specified by the Linear Units parameter. If not provided, the 
    907 output rasters will be centered on the 180th meridian (the Pacific 
    908 ocean). 
    909  
    910 Use this parameter to shift the center longitude of the rasters to a 
     915u"""Distance to rotate the outputs about the polar axis, in the units 
     916specified by the Linear Units parameter. If not provided, the outputs 
     917will be centered on the 180th meridian (the Pacific ocean). 
     918 
     919Use this parameter to shift the center longitude of the outputs to a 
    911920different location. Positive values shift it to the east, negative 
    912 values to the west. For example, to center the output rasters on the 
    913 Prime Meridian, provide -180 for this parameter and set the Linear 
    914 Units parameter to Degrees.  
    915  
    916 The rasters can only be rotated in whole grid cells. The value you 
    917 provide will be rounded off to the closest cell."""), 
    918     arcGISDisplayName=_(u'Rotate raster by'), 
     921values to the west. For example, to center the outputs on the Prime 
     922Meridian, provide -180 for this parameter and set the Linear Units 
     923parameter to Degrees. 
     924 
     925The outputs can only be rotated in whole cells of the Aviso grids. The 
     926value you provide will be rounded off to the closest cell."""), 
     927    arcGISDisplayName=_(u'Rotate by'), 
    919928    arcGISCategory=_(u'Spatiotemporal extent')) 
    920929 
     
    922931    typeMetadata=EnvelopeTypeMetadata(canBeNone=True), 
    923932    description=_( 
    924 u"""Spatial extent of the output rasters, in the units specified by 
    925 the Linear Units parameter. 
     933u"""Spatial extent of the outputs, in the units specified by the 
     934Linear Units parameter. 
    926935 
    927936This parameter is applied after the rotation parameter and uses 
    928937coordinates that result after rotation.  
    929938 
    930 The rasters can only be clipped in whole grid cells. The values you 
     939The outputs can only be clipped in whole grid cells. The values you 
    931940provide will be rounded off to the closest cell."""), 
    932941    arcGISDisplayName=_(u'Spatial extent'), 
     
    950959    typeMetadata=DateTimeTypeMetadata(canBeNone=True), 
    951960    description=_( 
    952 u"""Start date for the rasters to create. 
    953  
    954 Rasters will be created for images that occur on or after the start 
     961u"""Start date for the outputs to create. 
     962 
     963Outputs will be created for images that occur on or after the start 
    955964date and on or before the end date. If you do not provide a start 
    956965date, the date of the first available image will be used. For Delayed 
     
    966975    typeMetadata=DateTimeTypeMetadata(canBeNone=True), 
    967976    description=_( 
    968 u"""End date for the rasters to create. 
    969  
    970 Rasters will be created for images that occur on or after the start 
     977u"""End date for the outputs to create. 
     978 
     979Outputs will be created for images that occur on or after the start 
    971980date and on or before the end date. If you do not specify an end date, 
    972981the date of the most recent image will be used. For Delayed Time (DT) 
     
    18411850CopyResultMetadata(AvisoGriddedSSH.CreateClimatologicalArcGISRasters, u'updatedOutputWorkspace', AvisoGriddedGeostrophicCurrents.CreateClimatologicalArcGISRasters, u'updatedOutputWorkspace') 
    18421851 
     1852# Public method: AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses 
     1853 
     1854AddMethodMetadata(AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, 
     1855    shortDescription=_(u'Creates line feature classes representing the current vectors of an Aviso gridded geostrophic currents product.'), 
     1856    longDescription=_( 
     1857u"""The lines output by this tool are similar to those in a "quiver 
     1858plot". When displayed on a map, they can help visualize the direction 
     1859and velocity of ocean currents. In ArcMap, select the "Arrow at End" 
     1860symbology. You may also want to reduce the line decoration (the arrow) 
     1861to a small size, such as 2.0. 
     1862 
     1863""") + _AvisoGriddedProduct_LongDescription % {u'name': 'tool'}, 
     1864    isExposedToPythonCallers=True, 
     1865    isExposedByCOM=True, 
     1866    isExposedAsArcGISTool=True, 
     1867    arcGISDisplayName=_(u'Create Vectors for Aviso Geostrophic Currents Product'), 
     1868    arcGISToolCategory=_(u'Data Products\\Aviso\\Geostrophic Currents Products'), 
     1869    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')]) 
     1870 
     1871CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'cls', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'cls') 
     1872CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.__init__, u'username', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'username') 
     1873CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.__init__, u'password', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'password') 
     1874CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.__init__, u'productName', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'productName') 
     1875 
     1876AddArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'outputWorkspace', 
     1877    typeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True), 
     1878    description=_( 
     1879u"""Directory or geodatabase to receive the feature classes. 
     1880 
     1881Unless you have a specific reason to store the feature classes in a 
     1882geodatabase, we recommend you store them in a directory because it 
     1883will be faster and allows them to be organized as a tree (of 
     1884shapefiles). If you do store the feature classes in a geodatabase, you 
     1885must change the Feature Class Name Expressions parameter; see below 
     1886for more information."""), 
     1887    arcGISDisplayName=_(u'Output workspace')) 
     1888 
     1889AddArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'mode', 
     1890    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Add', u'Replace'], makeLowercase=True), 
     1891    description=_( 
     1892u"""Overwrite mode, one of: 
     1893 
     1894* Add - create feature classes that do not exist and skip those that 
     1895  already exist. This is the default. 
     1896 
     1897* Replace - create feature classes that do not exist and overwrite 
     1898  those that already exist. 
     1899 
     1900The ArcGIS Overwrite Outputs geoprocessing setting has no effect on 
     1901this tool. If 'Replace' is selected the feature classes will be 
     1902overwritten, regardless of the ArcGIS Overwrite Outputs setting."""), 
     1903    arcGISDisplayName=_(u'Overwrite mode')) 
     1904 
     1905AddArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'featureClassNameExpressions', 
     1906    typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(), minLength=1), 
     1907    description=_( 
     1908u"""List of expressions specifying how the output feature classes 
     1909should be named. 
     1910 
     1911The default expression assumes the output workspace is a directory and 
     1912creates shapefiles in a tree structure with levels for the region, 
     1913data series, satellite, variable, and year. 
     1914 
     1915If the output workspace is a geodatabase, you should provide only one 
     1916or two expressions. If you provide one expression, it specifies the 
     1917feature class name. If you provide two, the first one specifies the 
     1918feature dataset name and the second specifies the feature class name. 
     1919 
     1920Each expression may contain any sequence of characters permitted by 
     1921the output workspace. Each expression may optionally contain one or 
     1922more of the following case-sensitive codes. The tool replaces the 
     1923codes with appropriate values when creating each feature class: 
     1924 
     1925* %(Region)s - Region of the output feature class, either "global", 
     1926  "medsea", or "blacksea". 
     1927 
     1928* %(DataSeries)s - Aviso data series of the output feature class, 
     1929  either "dt_ref", "dt_upd", or "nrt". 
     1930 
     1931* %(Satellites)s - Satellites used to produce the feature class. At 
     1932  this time, only one such value exists, "merged", which means that 
     1933  multiple satellites were used. Please see the Aviso documentation 
     1934  for more information on how Aviso products are created. 
     1935 
     1936* %(Variable)s - Aviso variable represented in the output feature 
     1937  class, either "madt_uv_vectors" for Mean Absolute Dynamic Topography 
     1938  (MADT) vectors or "msla_uv_vectors" for Mean Sea Level Anomaly 
     1939  (MSLA) vectors. 
     1940 
     1941* %%Y - four-digit year of the output feature class. 
     1942 
     1943* %%m - two-digit month of the output feature class. 
     1944 
     1945* %%d - two-digit day of the month of the output feature class. 
     1946 
     1947* %%j - three-digit day of the year of the output feature class. 
     1948"""), 
     1949    arcGISDisplayName=_(u'Feature class name expressions')) 
     1950 
     1951CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'rotationOffset', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'rotationOffset') 
     1952CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'spatialExtent', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'spatialExtent') 
     1953CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'linearUnit', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'linearUnit') 
     1954CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'startDate', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'startDate') 
     1955CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'endDate', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'endDate') 
     1956CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'timeout', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'timeout') 
     1957CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'maxRetryTime', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'maxRetryTime') 
     1958CopyArgumentMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'cacheDirectory', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'cacheDirectory') 
     1959 
     1960CopyResultMetadata(AvisoGriddedGeostrophicCurrents.CreateArcGISRasters, u'updatedOutputWorkspace', AvisoGriddedGeostrophicCurrents.CreateVectorsAsArcGISFeatureClasses, u'updatedOutputWorkspace') 
     1961 
    18431962# Public method: AvisoGriddedGeostrophicCurrents.InterpolateAtArcGISPoints 
    18441963 
  • MGET/Branches/Jason/PythonPackage/src/GeoEco/Datasets/ArcGIS.py

    r715 r773  
    595595    def _ImportDatasetsToPath(self, pathComponents, sourceDatasets, mode, progressReporter, options): 
    596596        self.DatasetType._ImportDatasetsToPath(os.path.join(self.Path, *pathComponents), sourceDatasets, mode, progressReporter, options) 
    597  
     597     
    598598 
    599599class ArcGISRaster(DatasetCollection): 
     
    15151515 
    15161516        raise ValueError(_(u'Cannot open "%(path)s" as an ArcGIS raster band, raster dataset, or raster layer. ArcGIS reports that it is a "%(dataType)".') % {u'path': path, u'dataType': d.DataType}) 
     1517 
     1518 
     1519class ArcGISCopyableTable(object): 
     1520    __doc__ = DynamicDocString() 
     1521 
     1522    def GetArcGISCopyablePath(self): 
     1523        raise NotImplementedError(_(u'The GetArcGISCopyablePath method of class %s has not been implemented.') % self.__class__.__name__) 
    15171524 
    15181525 
     
    18221829    def _OpenInsertCursor(self, rowCount, reportProgress, rowDescriptionSingular, rowDescriptionPlural): 
    18231830        return ArcGISInsertCursor(self, rowCount, reportProgress, rowDescriptionSingular, rowDescriptionPlural) 
     1831 
     1832    @classmethod 
     1833    def _ImportDatasetsToPath(cls, path, sourceDatasets, mode, progressReporter, options): 
     1834 
     1835        # Validate that there is only one source dataset. We do not 
     1836        # currently support importing multiple source datasets into a 
     1837        # single destination dataset. (This could theoretically be 
     1838        # supported in the future by appending multiple datasets into 
     1839        # the same destination.) 
     1840 
     1841        if len(sourceDatasets) > 1: 
     1842            raise ValueError(_(u'Cannot import %(count)i datasets into ArcGIS table or feature class "%(path)s". Importing of multiple datasets into a single table or feature class is not currently supported. If you are receiving this error from a tool that has a parameter that is a list of expressions that define the output dataset namen, you may have made a mistake in your expressions that caused the same output dataset name to be generated for multiple input datasets. If that is the problem, you can fix it by modifying the expressions to generate a unique output dataset name for each input dataset.') % {u'count': len(sourceDatasets), u'path': path}) 
     1843 
     1844        # Validate that the source dataset is importable. 
     1845        # 
     1846        # TODO: Implement support for Table instances that are not 
     1847        # ArcGISCopyableTable instances. (That is a lot of work 
     1848        # because we have to create the destination table and its 
     1849        # fields and then copy each row one at a time.) 
     1850         
     1851        if not isinstance(sourceDatasets[0], ArcGISCopyableTable): 
     1852            raise TypeError(_(u'Cannot import %(dn)s into ArcGIS table or feature class "%(path)s" because it is a %(type)s, which is not an ArcGISCopyableTable. At this time, only ArcGISCopyableTable can be imported.') % {u'dn': sourceDatasets[0].DisplayName, u'path': path, u'type': dataset.__class__.__name__}) 
     1853 
     1854        # If the mode is 'replace' and the destination dataset exists, 
     1855        # delete it. 
     1856 
     1857        gp = GeoprocessorManager.GetWrappedGeoprocessor() 
     1858 
     1859        if mode == u'replace' and gp.Exists(path): 
     1860            cls._LogDebug(_(u'%(class)s: Deleting existing ArcGIS dataset "%(path)s".'), {u'class': cls.__name__, u'path': path}) 
     1861            try: 
     1862                gp.Delete_management(path) 
     1863            except Exception, e: 
     1864                raise RuntimeError(_(u'Failed to delete the existing ArcGIS dataset "%(path)s" due to %(e)s: %(msg)s') % {u'path': path, u'e': e.__class__.__name__, u'msg': cls._Unicode(e)}) 
     1865 
     1866        # Otherwise, make sure all the parent levels in the 
     1867        # destination path exist (directories, geodatabase, feature 
     1868        # dataset), creating them if necessary. Use ArcGIS tools such 
     1869        # as CreateFolder_management to create them, so the ArcGIS 
     1870        # catalog is aware of them. 
     1871 
     1872        elif not gp.Exists(os.path.dirname(path)): 
     1873 
     1874            # If the destination path is in the file system, figure 
     1875            # out whether it contains levels for a geodatabase and a 
     1876            # feature dataset. If neither, it must be a shapefile, DBF 
     1877            # table, or something similar. 
     1878 
     1879            if path[0] in ['/', '\\'] or hasattr(os.path, 'splitdrive') and os.path.splitdrive(path)[0] != '' or hasattr(os.path, 'splitunc') and os.path.splitunc(path)[0] != '': 
     1880                if os.path.splitext(os.path.dirname(path))[1].lower() in ['.mdb', '.gdb']: 
     1881                    featureDataset = None 
     1882                    geodatabase = os.path.dirname(path) 
     1883                    directory = os.path.dirname(geodatabase) 
     1884                elif os.path.splitext(os.path.dirname(os.path.dirname(path)))[1].lower() in ['.mdb', '.gdb']: 
     1885                    featureDataset = os.path.dirname(path) 
     1886                    geodatabase = os.path.dirname(featureDataset) 
     1887                    directory = os.path.dirname(geodatabase) 
     1888                else: 
     1889                    featureDataset = None 
     1890                    geodatabase = None 
     1891                    directory = os.path.dirname(path) 
     1892 
     1893                # Create the directory if it does not exist. 
     1894 
     1895                if not os.path.exists(directory): 
     1896                    cls._LogDebug(_(u'%(class)s: Creating directory "%(path)s".'), {u'class': cls.__name__, u'path': directory}) 
     1897 
     1898                    if hasattr(os.path, 'splitdrive') and os.path.splitdrive(directory)[0] != '': 
     1899                        root, subdirs = os.path.splitdrive(directory) 
     1900                        root = root + '\\' 
     1901                    elif hasattr(os.path, 'splitunc') and os.path.splitunc(directory)[0] != '': 
     1902                        root, subdirs = os.path.splitunc(directory) 
     1903                    else: 
     1904                        root, subdirs = directory[0], directory[1:] 
     1905 
     1906                    subdirsList = [] 
     1907                    while len(subdirs) > 1: 
     1908                        subdirsList.insert(0, os.path.basename(subdirs)) 
     1909                        subdirs = os.path.dirname(subdirs) 
     1910 
     1911                    dirToCheck = root 
     1912                    for subdir in subdirsList: 
     1913                        if not os.path.isdir(os.path.join(dirToCheck, subdir)): 
     1914                            try: 
     1915                                gp.CreateFolder_management(dirToCheck, subdir) 
     1916                            except Exception, e: 
     1917                                raise RuntimeError(_(u'Failed to create the directory "%(path)s" due to %(e)s: %(msg)s') % {u'path': os.path.join(dirToCheck, subdir), u'e': e.__class__.__name__, u'msg': cls._Unicode(e)}) 
     1918                        dirToCheck = os.path.join(dirToCheck, subdir) 
     1919 
     1920                # If the path includes a geodatabase and it does not 
     1921                # exist, create it. 
     1922 
     1923                if geodatabase is not None and not gp.Exists(geodatabase): 
     1924                    if os.path.splitext(geodatabase).lower() == '.mdb': 
     1925                        gp.CreatePersonalGDB_management(directory, os.path.basename(geodatabase)) 
     1926                    else: 
     1927                        gp.CreateFileGDB_management(directory, os.path.basename(geodatabase)) 
     1928 
     1929                # If the path includes a feature dataset and it does not 
     1930                # exist, create it. 
     1931 
     1932                if featureDataset is not None and not gp.Exists(featureDataset): 
     1933                    gp.CreateFeatureDataset_management(geodatabase, os.path.basename(featureDataset)) 
     1934                     
     1935            # TODO: Otherwise (the desination path is not in the file 
     1936            # system), make sure the destination exists and create the 
     1937            # feature dataset. I'm not willing to code this without 
     1938            # having an ArcSDE geodatabase to test it with. 
     1939 
     1940            else: 
     1941                raise NotImplementedError(_(u'Cannot import %(dn)s into destination ArcGIS table or feature class "%(path)s" because that destination is not a folder, personal geodatabase, or file geodatabase. Other destinations (e.g. ArcSDE geodatabases) are not fully supported. Please contact the author of this tool for assistance.') % {u'dn': sourceDatasets[0].DisplayName, u'path': path}) 
     1942 
     1943        # Import the dataset. 
     1944 
     1945        if isinstance(sourceDatasets[0], ArcGISCopyableTable): 
     1946            arcGISCopyablePath = sourceDatasets[0].GetArcGISCopyablePath() 
     1947            try: 
     1948                cls._LogDebug(_(u'%(class)s: Copying "%(src)s" to ArcGIS dataset "%(path)s".'), {u'class': cls.__name__, u'src': arcGISCopyablePath, u'path': path}) 
     1949                gp.Copy_management(arcGISCopyablePath, path) 
     1950            finally: 
     1951                sourceDatasets[0].Close()       # This will make sure it deletes temporary files, if it had to create any in order to make itself ArcGIS-copyable. 
     1952             
     1953            if progressReporter is not None: 
     1954                progressReporter.ReportProgress() 
     1955 
     1956        else: 
     1957            raise TypeError(_(u'Cannot import %(dn)s into ArcGIS table or feature class "%(path)s" because it is a %(type)s, which is not an ArcGISCopyableTable. At this time, only ArcGISCopyableTable can be imported.') % {u'dn': sourceDatasets[0].DisplayName, u'path': path, u'type': dataset.__class__.__name__}) 
    18241958 
    18251959 
  • MGET/Branches/Jason/PythonPackage/src/GeoEco/SpatialAnalysis/Lines.py

    r715 r773  
    2121 
    2222from GeoEco.ArcGIS import GeoprocessorManager, ArcGISDependency 
     23from GeoEco.Datasets import Table 
     24from GeoEco.Datasets.ArcGIS import ArcGISCopyableTable 
    2325from GeoEco.DynamicDocString import DynamicDocString 
    2426from GeoEco.Internationalization import _ 
     
    185187 
    186188 
     189class ShapefileFromVectorComponentGrids(Table, ArcGISCopyableTable): 
     190    __doc__ = DynamicDocString() 
     191 
     192    def __init__(self, xGrid, yGrid, scaleFactor, parentCollection=None, queryableAttributes=None, queryableAttributeValues=None): 
     193 
     194        # Initialize our properties. 
     195 
     196        self._XGrid = xGrid 
     197        self._YGrid = yGrid 
     198        self._ScaleFactor = scaleFactor 
     199        self._TempDir = None 
     200        self._DisplayName = _(u'vectors for x components = %(dnx)s, y components = %(dny)s') % {u'dnx': xGrid, u'dny': yGrid} 
     201 
     202        # Initialize the base class. 
     203         
     204        super(ShapefileFromVectorComponentGrids, self).__init__(parentCollection=parentCollection, queryableAttributes=None, queryableAttributeValues=queryableAttributeValues) 
     205 
     206    def _GetDisplayName(self): 
     207        return self._DisplayName 
     208 
     209    def _GetLazyPropertyPhysicalValue(self, name): 
     210        return None 
     211 
     212    def _Close(self): 
     213        self._TempDir = None 
     214        super(ShapefileFromVectorComponentGrids, self)._Close() 
     215 
     216    @classmethod 
     217    def _TestCapability(cls, capability): 
     218        if isinstance(cls, ShapefileFromVectorComponentGrids): 
     219            return RuntimeError(_(u'The %(cls)s class does not support the "%(cap)s" capability.') % {u'cls': cls.__class__.__name__, u'cap': capability}) 
     220        return RuntimeError(_(u'The %(cls)s class does not support the "%(cap)s" capability.') % {u'cls': cls.__name__, u'cap': capability}) 
     221 
     222    def GetArcGISCopyablePath(): 
     223 
     224        # If we have not created the shapefile in a temporary 
     225        # directory, do it now. If we catch an exception, call 
     226        # _Close() to delete the temporary directory. 
     227 
     228        if self._TempDir is None: 
     229            try: 
     230                self._TempDir = self._CreateTempDirectory() 
     231                Lines.ShapefileFromVectorComponentGrids(self._XGrid, self._YGrid, os.path.join(self._TempDir, 'Vectors.shp'), self._ScaleFactor) 
     232            except: 
     233                self._Close() 
     234                raise 
     235 
     236        # Return the path to the shapefile in the temporary directory. 
     237 
     238        return os.path.join(self._TempDir, 'Vectors.shp') 
     239 
     240 
    187241############################################################################### 
    188242# Metadata: module 
     
    500554 
    501555CopyArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'overwriteExisting', ArcGISLines.ConnectSequentialPoints, u'overwriteExisting') 
     556 
     557############################################################################### 
     558# Metadata: ShapefileFromVectorComponentGrids class 
     559############################################################################### 
     560 
     561AddClassMetadata(ShapefileFromVectorComponentGrids, 
     562    shortDescription=_(u'An ArcGIS-copyable Table representing the vectors of x and y component rasters, similar to a "quiver plot".')) 
     563 
     564# TODO: Add metadata. 
    502565 
    503566############################################################################### 
     
    561624############################################################################### 
    562625 
    563 __all__ = ['Lines', 'ArcGISLines'] 
     626__all__ = ['Lines', 'ArcGISLines', 'ShapefileFromVectorComponentGrids']