root/MGET/Branches/Jason/PythonPackage/src/GeoEco/SpatialAnalysis/Lines.py @ 835

Revision 835, 29.7 KB (checked in by jjr8, 20 months ago)

Fixed various minor bugs.

Line 
1# Lines.py - Provides methods for general-purpose operations with lines.
2#
3# Copyright (C) 2009 Jason J. Roberts
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version 2
8# of the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License (available in the file LICENSE.TXT)
14# for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
20import os
21
22from GeoEco.ArcGIS import GeoprocessorManager, ArcGISDependency
23from GeoEco.Datasets import Table
24from GeoEco.Datasets.ArcGIS import ArcGISCopyableTable
25from GeoEco.DynamicDocString import DynamicDocString
26from GeoEco.Internationalization import _
27from GeoEco.Logging import Logger, ProgressReporter
28
29
30class Lines(object):
31    __doc__ = DynamicDocString()
32
33    @classmethod
34    def ShapefileFromVectorComponentGrids(cls, xGrid, yGrid, shapefile, scaleFactor, overwriteExisting=False):
35        cls.__doc__.Obj.ValidateMethodInvocation()
36
37        # Perform additional validation.
38
39        if xGrid.Dimensions != u'yx':
40            raise ValueError(_(u'The X components grid has more than two dimensions. Please provide a grid that has two dimensions.'))
41        if yGrid.Dimensions != u'yx':
42            raise ValueError(_(u'The Y components grid has more than two dimensions. Please provide a grid that has two dimensions.'))
43
44        xSR = xGrid.GetSpatialReference('obj')
45        ySR = yGrid.GetSpatialReference('obj')
46        if (xSR is not None and ySR is None) or (xSR is None and ySR is not None) or (xSR is not None and ySR is not None and not xSR.IsSame(ySR)):
47            raise ValueError(_(u'The X components grid has a different coordinate system than the Y components grid. Please provide grids with the coordinate systems.'))
48
49        if xGrid.Shape != yGrid.Shape:
50            raise ValueError(_(u'The X components grid has a different width or height (in cells) than the Y components grid. Please provide grids that have the same width and height as each other.'))
51
52        if xGrid.CoordIncrements[0] is None or xGrid.CoordIncrements[1] is None:
53            raise ValueError(_(u'The X components grid does not have a constant cell size (some cells are wider or taller than others). Please provide a grid that has a constant cell size.'))
54        if yGrid.CoordIncrements[0] is None or yGrid.CoordIncrements[1] is None:
55            raise ValueError(_(u'The Y components grid does not have a constant cell size (some cells are wider or taller than others). Please provide a grid that has a constant cell size.'))
56
57        if xGrid.CoordIncrements[0] / yGrid.CoordIncrements[0] > 1.000001 or xGrid.CoordIncrements[0] / yGrid.CoordIncrements[0] < 0.999999 or xGrid.CoordIncrements[1] / yGrid.CoordIncrements[1] > 1.000001 or xGrid.CoordIncrements[1] / yGrid.CoordIncrements[1] < 0.999999:
58            raise ValueError(_(u'The X components grid has a different cell size than the Y components grid. Please provide grids that have the same cell size.'))
59
60##        if abs(xGrid.CenterCoords['x', 0] - yGrid.CenterCoords['x', 0]) / xGrid.CoordIncrements[0] > 0.001 or abs(xGrid.CenterCoords['y', 0] - yGrid.CenterCoords['y', 0]) / xGrid.CoordIncrements[1] > 0.001:
61##            raise ValueError(_(u'The X components grid has a different extent than the Y components grid. Please provide grids that have the same extent.'))
62
63        if xGrid.NoDataValue != yGrid.NoDataValue:
64            raise ValueError(_(u'The X components grid has a different No Data value than the Y components grid. Please provide grids that have the same No Data value.'))
65
66        # Create 32-bit floating point numpy arrays.
67
68        import numpy
69
70        xNumpyArray = numpy.flipud(xGrid.Data[:])
71        if xGrid.DataType == u'float32':
72            noDataValue = float(xGrid.NoDataValue)
73        else:
74            noDataValue = float(numpy.cast['float32'](xGrid.NoDataValue))
75            xNumpyArray = numpy.cast['float32'](xNumpyArray)
76            if numpy.isinf(noDataValue):
77                noDataValue = -3.4028234663852886e+038
78                xNumpyArray[numpy.isinf(xNumpyArray)] = noDataValue
79
80        yNumpyArray = numpy.flipud(yGrid.Data[:])
81        if yGrid.DataType != u'float32':
82            yNumpyArray = numpy.cast['float32'](yNumpyArray)
83            if noDataValue == -3.4028234663852886e+038:
84                yNumpyArray[numpy.isinf(yNumpyArray)] = noDataValue
85
86        # Create 32-bit floating point rasters in a temporary
87        # directory so we can pass them to vectorshp.exe.
88
89        from GeoEco.DataManagement.Directories import TemporaryDirectory
90        tempDir = TemporaryDirectory()
91
92        xBinaryFile = os.path.join(tempDir.Path, 'x.bin')
93        xNumpyArray.tofile(xBinaryFile)
94
95        yBinaryFile = os.path.join(tempDir.Path, 'y.bin')
96        yNumpyArray.tofile(yBinaryFile)
97
98        # Execute vectorshp.exe to create the shapefile.
99
100        from GeoEco.DataManagement.Processes import ChildProcess
101
102        args = [xBinaryFile,
103                yBinaryFile,
104                shapefile,
105                'float',
106                repr(xGrid.Shape[1]),               # Width in cells
107                repr(xGrid.Shape[0]),               # Height in cells
108                repr(xGrid.CoordIncrements[0]),     # Cell size
109                repr(xGrid.MinCoords['x', 0]),      # Lower-left corner X
110                repr(xGrid.MinCoords['y', 0]),      # Lower-left corner Y
111                '-n', repr(noDataValue),
112                '-s', repr(scaleFactor)]
113
114        oldLogInfoAsDebug = Logger.GetLogInfoAsDebug()
115        Logger.SetLogInfoAsDebug(True)
116        try:
117            ChildProcess.ExecuteProgramInBinDirectory(u'vectorshp', args, windowState=u'invisible')
118        finally:
119            Logger.SetLogInfoAsDebug(oldLogInfoAsDebug)
120
121        # If a coordinate system as been defined for the rasters,
122        # create a .prj file for the shapefile.
123
124        if xSR is not None:
125            prjFile = os.path.splitext(shapefile)[0] + '.prj'
126            Logger.Debug(_(u'Writing coordinate system WKT to %(file)s.') % {u'file': prjFile})
127            try:
128                f = open(prjFile, 'w')
129                try:
130                    f.write(str(xGrid.GetSpatialReference('ArcGIS')))
131                finally:
132                    f.close()
133            except Exception, e:
134                raise IOError(_(u'Failed to write file %(file)s: %(e)s: %(msg)s.') % {u'file': prjFile, u'e': e.__class__.__name__, u'msg': str(e)})
135
136
137class ArcGISLines(object):
138    __doc__ = DynamicDocString()
139
140    @classmethod
141    def FromVectorComponentRasters(cls, xRaster, yRaster, lines, scaleFactor, overwriteExisting=False):
142        cls.__doc__.Obj.ValidateMethodInvocation()
143        try:
144            Logger.Info(_(u'Creating lines in %(fc)s from vector component rasters %(r1)s and %(r2)s.') % {u'fc': lines, u'r1': xRaster, u'r2': yRaster})
145           
146            # If the output feature class is a shapefile, create it
147            # directly.
148
149            from GeoEco.Datasets.ArcGIS import ArcGISRasterBand
150
151            xGrid = ArcGISRasterBand.ConstructFromArcGISPath(xRaster)
152            yGrid = ArcGISRasterBand.ConstructFromArcGISPath(yRaster)
153
154            if os.path.splitext(lines)[1].lower() == '.shp':
155                Lines.ShapefileFromVectorComponentGrids(xGrid, yGrid, lines, scaleFactor, overwriteExisting=overwriteExisting)
156
157            # Otherwise, create a shapefile in a temporary directory and
158            # then copy it to the output feature class.
159
160            else:
161                from GeoEco.DataManagement.Directories import TemporaryDirectory
162                tempDir = TemporaryDirectory()
163
164                shapefile = os.path.join(tempDir.Path, 'vectors.shp')
165                Lines.ShapefileFromVectorComponentGrids(xGrid, yGrid, shapefile, scaleFactor)
166
167                gp = GeoprocessorManager.GetWrappedGeoprocessor()
168                gp.RefreshCatalog(tempDir.Path)
169
170                Logger.Debug(_(u'Copying %(src)s to %(dest)s.') % {u'src': shapefile, u'dest': lines})
171                gp.FeatureClassToFeatureClass_conversion(shapefile, os.path.dirname(lines), os.path.basename(lines))
172
173        except:
174            Logger.LogExceptionAsError()
175            raise
176
177    @classmethod
178    def ConnectSequentialPoints(cls, points, lines, where=None, orderByFields=None, orderByDirections=None, idFields=None, useZ=True, overwriteExisting=False):
179        cls.__doc__.Obj.ValidateMethodInvocation()
180        try:
181            raise NotImplementedError(_(u'This tool has not been implemented yet.'))
182            Logger.Info(_(u'Reading sequential points from %(points)s and inserting lines into %(lines)s.') % {u'lines': lines, u'points': points})
183
184        except:
185            Logger.LogExceptionAsError()
186            raise
187
188
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(self):
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
241###############################################################################
242# Metadata: module
243###############################################################################
244
245from GeoEco.Datasets import Grid
246from GeoEco.Dependencies import PythonAggregatedModuleDependency
247from GeoEco.Metadata import *
248from GeoEco.Types import *
249
250AddModuleMetadata(shortDescription=_(u'Provides methods for general-purpose operations with lines.'))
251
252###############################################################################
253# Metadata: Lines class
254###############################################################################
255
256AddClassMetadata(Lines,
257    shortDescription=_(u'Provides methods for general-purpose operations with lines, using only free open-source software such as GDAL and OGR.'))
258##    isExposedAsCOMServer=True,
259##    comIID=u'{8EC65E73-2E70-4CA8-A69E-D2BDC81984A9}',
260##    comCLSID=u'{014E1B6E-059D-4190-B27B-66A021D6A008}')
261
262# Public method: Lines.ShapefileFromVectorComponentGrids
263
264AddMethodMetadata(Lines.ShapefileFromVectorComponentGrids,
265    shortDescription=_(u'Creates a shapefile of lines representing vectors, similar to a "quiver plot".'),
266    isExposedToPythonCallers=True,
267    dependencies=[PythonAggregatedModuleDependency('numpy')])
268
269AddArgumentMetadata(Lines.ShapefileFromVectorComponentGrids, u'cls',
270    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=Lines),
271    description=_(u'%s class or an instance of it.') % Lines.__name__)
272
273AddArgumentMetadata(Lines.ShapefileFromVectorComponentGrids, u'xGrid',
274    typeMetadata=ClassInstanceTypeMetadata(Grid),
275    description=_(
276u"""2D grid representing the X components of the vector field, where
277positive values indicate rightward flow and negative values indicate
278leftward flow.
279
280If you are running this tool on ocean currents rasters, provide the u
281raster for this parameter."""))
282
283AddArgumentMetadata(Lines.ShapefileFromVectorComponentGrids, u'yGrid',
284    typeMetadata=ClassInstanceTypeMetadata(Grid),
285    description=_(
286u"""2D grid representing the Y components of the vector field, where
287positive values indicate upward flow and negative values indicate
288downward flow.
289
290This grid must have the same coordinate system, extent, dimensions,
291and cell size as the X components grid.
292
293If you are running this tool on ocean currents rasters, provide the v
294raster for this parameter."""))
295
296AddArgumentMetadata(Lines.ShapefileFromVectorComponentGrids, u'shapefile',
297    typeMetadata=ShapefileTypeMetadata(deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
298    description=_(
299u"""Line shapefile to create.
300
301The shapefile will contain one line for each grid cell that contains
302data (both X and Y component values). The line will originate at the
303cell center and have the length and direction described by the
304component values. The length will be adjusted by the Scale Factor
305parameter.
306
307Each line will have two attributes:
308
309* Magnitude - the unscaled magnitude of the vector, computed from the
310  component values using the Pythagorean theorem.
311
312* Direction - the direction of the vector, in degrees, where 0 is
313  right, 90 is up, -90 is down, and 180 is left.
314"""))
315
316AddArgumentMetadata(Lines.ShapefileFromVectorComponentGrids, u'scaleFactor',
317    typeMetadata=FloatTypeMetadata(mustBeGreaterThan=0.0),
318    description=_(
319u"""Factor for scaling lines lengths.
320
321Use this parameter to scale the lines output by this tool to lengths
322that are visually appealing. If the lines are too short, they will
323resemble a grid of dots and you will not be able to discern the flow
324of the vector field. If the lines are too long, they will overlap each
325other and resemble a plate of spaghetti.
326
327If the vectors all have about the same magnitude, then a good approach
328is to scale the lines so that the longest one is about as long as the
329raster cell size. But if there are a few very long vectors, then you
330may prefer to scale the lines so that the average-length vector is as
331long as the raster cell size.
332
333To estimate an appropriate scale factor, divide the cell size by your
334estimate of the maximum (or mean) unscaled line length. For example,
335if the cell size is 25,000 meters, and the input grids represent ocean
336current velocity in centimeters per second, and you believe the
337maximum (or mean) velocity is about 200 cm/s:
338
339    scale factor = 25000 / 200 = 125
340
341If the rasters represented velocity in meters per second:
342
343    scale factor = 25000 / 2 = 12500
344
345Use a scale factor of 1 to indicate that the lines should not be
346scaled."""))
347
348AddArgumentMetadata(Lines.ShapefileFromVectorComponentGrids, u'overwriteExisting',
349    typeMetadata=BooleanTypeMetadata(),
350    description=_(
351u"""If True, the output shapefile will be overwritten, if it exists.
352If False, a ValueError will be raised if the output shapefile
353exists."""))
354
355###############################################################################
356# Metadata: ArcGISLines class
357###############################################################################
358
359AddClassMetadata(ArcGISLines,
360    shortDescription=_(u'Provides methods for general-purpose operations with ArcGIS lines.'),
361    isExposedAsCOMServer=True,
362    comIID=u'{8EC65E73-2E70-4CA8-A69E-D2BDC81984A9}',
363    comCLSID=u'{014E1B6E-059D-4190-B27B-66A021D6A008}')
364
365# Public method: ArcGISLines.FromVectorComponentRasters
366
367AddMethodMetadata(ArcGISLines.FromVectorComponentRasters,
368    shortDescription=_(u'Given rasters representing the x and y components of a vector field, such as the u and v rasters for ocean currents, this tool creates a feature class of lines representing the vectors, similar to a "quiver plot".'),
369    isExposedToPythonCallers=True,
370    isExposedByCOM=True,
371    isExposedAsArcGISTool=True,
372    arcGISDisplayName=_(u'Create Lines From Vector Component Rasters'),
373    arcGISToolCategory=_(u'Spatial Analysis\\Create Lines'),
374    dependencies=[ArcGISDependency(9, 1)])
375
376AddArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'cls',
377    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=ArcGISLines),
378    description=_(u'%s class or an instance of it.') % ArcGISLines.__name__)
379
380AddArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'xRaster',
381    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
382    description=_(
383u"""Raster representing the X components of the vector field, where
384positive values indicate rightward flow and negative values indicate
385leftward flow.
386
387If you are running this tool on ocean currents rasters, provide the u
388raster for this parameter."""),
389    arcGISDisplayName=_(u'X components raster'))
390
391AddArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'yRaster',
392    typeMetadata=ArcGISRasterLayerTypeMetadata(mustExist=True),
393    description=_(
394u"""Raster representing the Y components of the vector field, where
395positive values indicate upward flow and negative values indicate
396downward flow.
397
398This raster must have the same coordinate system, extent, dimensions,
399and cell size as the X components raster.
400
401If you are running this tool on ocean currents rasters, provide the v
402raster for this parameter."""),
403    arcGISDisplayName=_(u'Y components raster'))
404
405AddArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'lines',
406    typeMetadata=ArcGISFeatureClassTypeMetadata(mustBeDifferentThanArguments=[u'xRaster', u'yRaster'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
407    description=_(
408u"""Line feature class to create.
409
410The feature class will contain one line for each raster cell that
411contains data (both X and Y component values). The line will originate
412at the cell center and have the length and direction described by the
413component values. The length will be adjusted by the Scale Factor
414parameter.
415
416Each line will have two attributes:
417
418* Magnitude - the unscaled magnitude of the vector, computed from the
419  component values using the Pythagorean theorem.
420
421* Direction - the direction of the vector, in degrees, where 0 is
422  right, 90 is up, -90 is down, and 180 is left.
423"""),
424    direction=u'Output',
425    arcGISDisplayName=_(u'Output line feature class'))
426
427AddArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'scaleFactor',
428    typeMetadata=FloatTypeMetadata(mustBeGreaterThan=0.0),
429    description=Lines.ShapefileFromVectorComponentGrids.__doc__.Obj.Arguments[4].Description,
430    arcGISDisplayName=_(u'Scale factor'))
431
432AddArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'overwriteExisting',
433    typeMetadata=BooleanTypeMetadata(),
434    description=_(
435u"""If True, the output feature class will be overwritten, if it
436exists. If False, a ValueError will be raised if the output feature
437class exists."""),
438    initializeToArcGISGeoprocessorVariable=u'OverwriteOutput')
439
440# Public method: ArcGISLines.ConnectSequentialPoints
441
442AddMethodMetadata(ArcGISLines.ConnectSequentialPoints,
443    shortDescription=_(u'Given a sequence of points, such as the locations of a migrating animal, this tool creates lines that connect the points in sequence. Except in special cases, ArcGIS 9.2 or later is required for this tool.'),
444    isExposedToPythonCallers=True,
445    isExposedByCOM=True,
446##    isExposedAsArcGISTool=True,
447    arcGISDisplayName=_(u'Connect Sequential Points'),
448    arcGISToolCategory=_(u'Spatial Analysis\\Create Lines'),
449    dependencies=[ArcGISDependency(9, 1)])
450
451CopyArgumentMetadata(ArcGISLines.FromVectorComponentRasters, u'cls', ArcGISLines.ConnectSequentialPoints, u'cls')
452
453AddArgumentMetadata(ArcGISLines.ConnectSequentialPoints, u'points',
454    typeMetadata=ArcGISFeatureLayerTypeMetadata(allowedShapeTypes=[u'Point'], mustExist=True),
455    description=_(u"""Input points features."""),
456    arcGISDisplayName=_(u'Input point features'))
457
458AddArgumentMetadata(ArcGISLines.ConnectSequentialPoints, u'lines',
459    typeMetadata=ArcGISFeatureClassTypeMetadata(mustBeDifferentThanArguments=[u'points'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True),
460    description=_(u"""Line feature class to create."""),
461    direction=u'Output',
462    arcGISDisplayName=_(u'Output line feature class'))
463
464AddArgumentMetadata(ArcGISLines.ConnectSequentialPoints, u'where',
465    typeMetadata=SQLWhereClauseTypeMetadata(canBeNone=True),
466    description=_(
467u"""SQL WHERE clause expression that specifies the subset of points to
468process. If this parameter is not provided, all of the points will be
469processed. If this parameter is provided but the underlying database
470does not support WHERE clauses, an error will be raised.
471
472The exact syntax of this expression depends on the underlying database
473and the type of connection used to access it. ESRI recommends you
474reference fields using the following syntax:
475
476* If you're querying ArcInfo coverages, shapefiles, INFO tables or
477  dBASE tables (.dbf files), enclose field names in double quotes in
478  the SQL expression: "MY_FIELD".
479
480* If you're querying Microsoft Access tables or personal
481  geodatabase tables, enclose field names in square brackets:
482  [MY_FIELD].
483
484* If you're querying ArcSDE geodatabase tables, an ArcIMS feature
485  class, or an ArcIMS image service sublayer, don't enclose field
486  names: MY_FIELD.
487"""),
488    arcGISDisplayName=_(u'Where clause specifying the points to process'),
489    arcGISParameterDependencies=[u'points'],)
490
491AddArgumentMetadata(ArcGISLines.ConnectSequentialPoints, u'orderByFields',
492    typeMetadata=ListTypeMetadata(elementType=ArcGISFieldTypeMetadata(mustExist=True), minLength=1, canBeNone=True),
493    description=_(
494u"""Fields to order the points sequentially prior to connecting them
495with lines. If no fields are provided, the points will be ordered in
496the default sequence determined by the underlying database. For
497shapefiles or geodatabases, this is usually by the FID or OBJECTID
498fields, respectively.
499
500For each field you specify here, two fields will be added to the
501output lines: one indicating the value of field at the start point for
502the line, and one indicating the value at the end point. The line
503fields will have the same name as the point fields with a '1' or '2'
504appended for the start and end values, respectively.
505
506ArcGIS 9.2 or later is required for this parameter. If you have an
507earlier version, you can only connect the points using the default
508sequence determined by the underlying database, because earlier
509versions do not allow this tool to specify a different ordering
510scheme."""),
511    arcGISDisplayName=_(u'Fields for ordering the points sequentially'),
512    arcGISParameterDependencies=[u'points'],
513    dependencies=[ArcGISDependency(9, 2)])
514
515AddArgumentMetadata(ArcGISLines.ConnectSequentialPoints, u'orderByDirections',
516    typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(allowedValues=[u'Ascending', u'Descending']), canBeNone=True),
517    description=_(
518u"""List of strings, either 'Ascending' or 'Descending', that specify
519the sort directions for the fields used to order the points
520sequentially. You may omit this parameter entirely, or only specify it
521for a few fields. If you do not provide a sort direction for a given
522field, 'Ascending' will be used for that field."""),
523    arcGISDisplayName=_(u'Sort directions for ordering fields'))
524
525AddArgumentMetadata(ArcGISLines.ConnectSequentialPoints, u'idFields',
526    typeMetadata=ListTypeMetadata(elementType=ArcGISFieldTypeMetadata(mustExist=True), minLength=1, canBeNone=True),
527    description=_(
528u"""Fields to group points into distinct lines. If no fields are
529specified, a single line will be created that connects all of the
530points.
531
532Use this parameter when your input feature layer or feature class
533contains points for several different lines. For example, if your
534points represent the locations of several migrating animals, provide
535the field that identifies which animal the point is associated with,
536and the tool will create one line for each animal.
537
538Each field you specify here will be copied to the output lines."""),
539    arcGISDisplayName=_(u'Fields for identifying distinct lines'),
540    arcGISParameterDependencies=[u'points'])
541
542AddArgumentMetadata(ArcGISLines.ConnectSequentialPoints, u'useZ',
543    typeMetadata=BooleanTypeMetadata(),
544    description=_(
545u"""If True and the points contain Z values, the Z values will be used
546when creating the lines (i.e. the Z values from the starting and
547ending points will be used for on the respective endpoints of the
548line). If False or the points do not contain Z values, then Z values
549will not be used when creating the lines.
550
551This parameter will be ignored if the points do not contain Z
552values."""),
553    arcGISDisplayName=_(u'Use Z values'))
554
555CopyArgumentMetadata(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.
565
566###############################################################################
567# Batch processing versions of methods
568###############################################################################
569
570from GeoEco.BatchProcessing import BatchProcessing
571from GeoEco.DataManagement.Fields import Field
572
573BatchProcessing.GenerateForMethod(ArcGISLines.FromVectorComponentRasters,
574    inputParamNames=[u'xRaster', u'yRaster'],
575    inputParamFieldArcGISDisplayNames=[_(u'X components raster field'), _(u'Y components raster field')],
576    inputParamDescriptions=[
577_(u"""%s paths of the rasters representing the X components of the
578vector fields, where positive values indicate rightward flow and
579negative values indicate leftward flow.
580
581If you are running this tool on ocean currents rasters, provide the u
582rasters for this parameter."""),
583
584_(u"""%s paths of the rasters representing the Y components of the
585vector fields, where positive values indicate upward flow and negative
586values indicate downward flow.
587
588These rasters must have the same coordinate system, extent,
589dimensions, and cell size as the X components rasters.
590
591If you are running this tool on ocean currents rasters, provide the v
592rasters for this parameter.""")],
593    outputParamNames=[u'lines'],
594    outputParamFieldArcGISDisplayNames=[_(u'Output feature class field')],
595    outputParamDescriptions=[
596_(u"""%s paths of the line feature classes to create.
597
598Each feature class will contain one line for each raster cell that
599contains data (both X and Y component values). The line will originate
600at the cell center and have the length and direction described by the
601component values. The length will be adjusted by the Scale Factor
602parameter.
603
604Each line will have two attributes:
605
606* Magnitude - the unscaled magnitude of the vector, computed from the
607  component values using the Pythagorean theorem.
608
609* Direction - the direction of the vector, in degrees, where 0 is
610  right, 90 is up, -90 is down, and 180 is left.
611""")],
612    constantParamNames=[u'scaleFactor'],
613    processListMethodName=u'FromVectorComponentRastersInList',
614    processListMethodShortDescription=_(u'Given lists of rasters representing the x and y components of vector fields, such as the u and v rasters for ocean currents, this tool creates feature classes of lines representing the vectors, similar to a "quiver plot".'),
615    processTableMethodName=u'FromVectorComponentRastersInTable',
616    processTableMethodShortDescription=_(u'Given a table of rasters representing the x and y components of vector fields, such as the u and v rasters for ocean currents, this tool creates feature classes of lines representing the vectors, similar to a "quiver plot".'),
617    processArcGISTableMethodName=u'FromVectorComponentRastersInArcGISTable',
618    processArcGISTableMethodArcGISDisplayName=_(u'Create Lines From Vector Component Rasters Listed in Table'),
619    skipExistingDescription=_(u'If True, processing will be skipped for output feature classes that already exist.'),
620    overwriteExistingDescription=_(u'If True and skipExisting is False, existing output feature classes will be overwritten.'))
621
622###############################################################################
623# Names exported by this module
624###############################################################################
625
626__all__ = ['Lines', 'ArcGISLines', 'ShapefileFromVectorComponentGrids']
Note: See TracBrowser for help on using the browser.