| 109 | | ## def _CopyNetCDFToSpatiaLiteDB(self, dbPath, tableName=u'EddyPoints', displayName=None, reportProgress=True): |
| 110 | | ## |
| 111 | | ## # Read all of the netCDF variables into memory. |
| 112 | | ## |
| 113 | | ## values = {} |
| 114 | | ## ds = self._OpenNetCDF() |
| 115 | | ## try: |
| 116 | | ## for field in self.Fields: |
| 117 | | ## if field.Name == u'obsdate': |
| 118 | | ## values['j1'] = ds.variables['j1'][:] |
| 119 | | ## elif field.Name != u'Geometry': |
| 120 | | ## values[field.Name] = ds.variables[field.Name][:] |
| 121 | | ## finally: |
| 122 | | ## ds.close() |
| 123 | | ## |
| 124 | | ## # Create the SpatiaLite in-memory database, |
| 125 | | ## |
| 126 | | ## from GeoEco.Datasets.SpatiaLite import SpatiaLiteDatabase |
| 127 | | ## db = SpatiaLiteDatabase(dbPath, displayName=displayName) |
| 128 | | ## try: |
| 129 | | ## # Create the SpatiaLite table. |
| 130 | | ## |
| 131 | | ## table = db.CreateTable(tableName, u'Point', self.GetSpatialReference('Obj')) |
| 132 | | ## |
| 133 | | ## for field in self.Fields: |
| 134 | | ## if field.Name != u'Geometry': |
| 135 | | ## table.AddField(field.Name, field.DataType, isNullable=True) |
| 136 | | ## |
| 137 | | ## # Copy the rows of the netCDF into the table. |
| 138 | | ## |
| 139 | | ## if reportProgress: |
| 140 | | ## self._LogInfo(_(u'Copying %(rowCount)i eddy points from %(dn1)s into %(dn2)s.') % {u'rowCount': len(values['track']), u'dn1': self.DisplayName, u'dn2': db.DisplayName}) |
| 141 | | ## else: |
| 142 | | ## self._LogDebug(_(u'Copying %(rowCount)i eddy points from %(dn1)s into %(dn2)s.') % {u'rowCount': len(values['track']), u'dn1': self.DisplayName, u'dn2': db.DisplayName}) |
| 143 | | ## |
| 144 | | ## db.Connection.execute('BEGIN EXCLUSIVE TRANSACTION;') |
| 145 | | ## try: |
| 146 | | ## ogr = self._ogr() |
| 147 | | ## insertCursor = table.OpenInsertCursor(len(values['track']), reportProgress) |
| 148 | | ## try: |
| 149 | | ## for i in range(len(values['track'])): |
| 150 | | ## |
| 151 | | ## # The longitude domain in the netCDF file |
| 152 | | ## # is 260 E to 650 E. See |
| 153 | | ## # http://cioss.coas.oregonstate.edu/eddies/domain.html |
| 154 | | ## # for more information. Adjust these |
| 155 | | ## # coordinates to a 0 to 360 range before |
| 156 | | ## # setting the geometry. |
| 157 | | ## |
| 158 | | ## lon = float(values['lon'][i]) |
| 159 | | ## if lon >= 360.: |
| 160 | | ## lon -= 360. |
| 161 | | ## lat = float(values['lat'][i]) |
| 162 | | ## |
| 163 | | ## geometry = ogr.Geometry(ogr.wkbPoint) |
| 164 | | ## geometry.AddPoint_2D(lon, lat) |
| 165 | | ## |
| 166 | | ## insertCursor.SetGeometry(geometry) |
| 167 | | ## |
| 168 | | ## # Copy the values of the fields. |
| 169 | | ## |
| 170 | | ## for field in self.Fields: |
| 171 | | ## if field.Name == u'obsdate': |
| 172 | | ## insertCursor.SetValue(field.Name, datetime.datetime(1992, 1, 1) + datetime.timedelta(int(values['j1'][i]) - 2448623)) # Convert from Julian date integer to datetime instance |
| 173 | | ## elif field.Name == u'lon': |
| 174 | | ## insertCursor.SetValue(field.Name, lon) |
| 175 | | ## elif field.Name != u'Geometry': |
| 176 | | ## value = values[field.Name][i] |
| 177 | | ## if value.dtype.kind == 'i': |
| 178 | | ## value = int(value) |
| 179 | | ## else: |
| 180 | | ## value = float(value) |
| 181 | | ## insertCursor.SetValue(field.Name, value) |
| 182 | | ## |
| 183 | | ## insertCursor.InsertRow() |
| 184 | | ## |
| 185 | | ## finally: |
| 186 | | ## del insertCursor |
| 187 | | ## except: |
| 188 | | ## db.Connection.execute('ROLLBACK;') |
| 189 | | ## raise |
| 190 | | ## else: |
| 191 | | ## db.Connection.execute('COMMIT;') |
| 192 | | ## |
| 193 | | ## # Create indexes on obsdate, lon, and lat. These indexes |
| 194 | | ## # are highly selective and likely to be used by the |
| 195 | | ## # caller. It is true that the lon and lat columns are |
| 196 | | ## # redundant with the geometry, but we maintain them so |
| 197 | | ## # that users can include them in simple where clauses |
| 198 | | ## # rather than specifying OGC-compliant syntax that works |
| 199 | | ## # with the geometry column (which they are free to do, if |
| 200 | | ## # desired). |
| 201 | | ## |
| 202 | | ## if reportProgress: |
| 203 | | ## self._LogInfo(_(u'Creating indexes.')) |
| 204 | | ## |
| 205 | | ## table.CreateIndex(['obsdate'], 'idx_%s_obsdate' % tableName) |
| 206 | | ## table.CreateIndex(['lon'], 'idx_%s_lon' % tableName) |
| 207 | | ## table.CreateIndex(['lat'], 'idx_%s_lat' % tableName) |
| 208 | | ## |
| 209 | | ## self._LogInfo(_(u'Copy complete.')) |
| 210 | | ## |
| 211 | | ## except: |
| 212 | | ## db.Close() |
| 213 | | ## raise |
| 214 | | ## |
| 215 | | ## # Return successfully. |
| 216 | | ## |
| 217 | | ## return db, table |
| 218 | | |
| 443 | | ## from GeoEco.Datasets.SpatiaLite import SpatiaLiteDatabase |
| 444 | | ## table = CheltonMesocaleEddyPoints(netCDF) |
| 445 | | ## db = SpatiaLiteDatabase(spatiaLiteDB) |
| 446 | | ## db.ImportTable(tableName, table) |
| | 334 | @classmethod |
| | 335 | def ExtractArcGISPointsFromSpatiaLite(cls, spatiaLiteDB, outputFeatureClass, tableName=u'EddyPoints', where=None, overwriteExisting=False): |
| | 336 | cls.__doc__.Obj.ValidateMethodInvocation() |
| | 337 | from GeoEco.Datasets.SpatiaLite import SpatiaLiteDatabase |
| | 338 | from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISTable |
| | 339 | db = SpatiaLiteDatabase(spatiaLiteDB) |
| | 340 | try: |
| | 341 | table = db.QueryDatasets("TableName = '%s'" % tableName, False)[0] |
| | 342 | workspace = ArcGISWorkspace(os.path.dirname(outputFeatureClass), ArcGISTable, pathCreationExpressions=['%(TableName)s'], queryableAttributes=(QueryableAttribute('TableName', 'Table name', UnicodeStringTypeMetadata()),)) |
| | 343 | workspace.ImportTable(os.path.basename(outputFeatureClass), table, where=where) |
| | 344 | finally: |
| | 345 | db.Close() |
| | 346 | |
| | 347 | @classmethod |
| | 348 | def ExtractArcGISLinesFromSpatiaLite(cls, spatiaLiteDB, outputFeatureClass, tableName=u'EddyPoints', where=None, overwriteExisting=False): |
| | 349 | cls.__doc__.Obj.ValidateMethodInvocation() |
| | 350 | |
| | 351 | # Create the output feature class. |
| | 352 | |
| | 353 | from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISTable |
| | 354 | |
| | 355 | workspace = ArcGISWorkspace(os.path.dirname(outputFeatureClass), ArcGISTable, pathCreationExpressions=['%(TableName)s'], queryableAttributes=(QueryableAttribute('TableName', 'Table name', UnicodeStringTypeMetadata()),)) |
| | 356 | table = workspace.CreateTable(os.path.basename(outputFeatureClass), geometryType='MultiLineString', spatialReference=Dataset.ConvertSpatialReference('proj4', '+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs', 'obj')) |
| | 357 | |
| | 358 | table.AddField('track', 'int32') |
| | 359 | table.AddField('duration', 'int32') |
| | 360 | table.AddField('startdate', 'datetime') |
| | 361 | table.AddField('enddate', 'datetime') |
| | 362 | table.AddField('cyc', 'int32') |
| | 363 | table.AddField('minA', 'float32') |
| | 364 | table.AddField('maxA', 'float32') |
| | 365 | table.AddField('meanA', 'float32') |
| | 366 | table.AddField('minL', 'float32') |
| | 367 | table.AddField('maxL', 'float32') |
| | 368 | table.AddField('meanL', 'float32') |
| | 369 | table.AddField('minU', 'float32') |
| | 370 | table.AddField('maxU', 'float32') |
| | 371 | table.AddField('meanU', 'float32') |
| | 372 | |
| | 373 | # Open an insert cursor on the output feature class. |
| | 374 | |
| | 375 | insertCursor = table.OpenInsertCursor() |
| | 376 | try: |
| | 377 | |
| | 378 | # Open a SQLite cursor on the SpatiaLite database. We use |
| | 379 | # a SQLite cursor rather than our own SelectCursor |
| | 380 | # interface because if the caller specified a where |
| | 381 | # clause, we want to extract complete tracks (all points) |
| | 382 | # for eddies that have any points (even just one) that |
| | 383 | # satisfy that expression. To do that, we have to join the |
| | 384 | # eddy points table to itself, which is not possible using |
| | 385 | # our SelectCursor interface. |
| | 386 | |
| | 387 | from GeoEco.Datasets.SpatiaLite import SpatiaLiteDatabase |
| | 388 | |
| | 389 | db = SpatiaLiteDatabase(spatiaLiteDB) |
| | 390 | try: |
| | 391 | if where is None: |
| | 392 | selectCursor = db.Connection.execute('SELECT * FROM %s ORDER BY track ASC, n ASC;' % tableName) |
| | 393 | else: |
| | 394 | db.Connection.execute('CREATE TABLE temp.MatchingEddies AS SELECT DISTINCT track FROM %s WHERE %s;' % (tableName, where)) |
| | 395 | selectCursor = db.Connection.execute('SELECT t1.* FROM %s AS t1 INNER JOIN temp.MatchingEddies ON t1.track = temp.MatchingEddies.track ORDER BY t1.track ASC, t1.n ASC;' % (tableName,)) |
| | 396 | |
| | 397 | try: |
| | 398 | ogr = cls._ogr() |
| | 399 | line = None |
| | 400 | point = selectCursor.fetchone() |
| | 401 | while True: |
| | 402 | |
| | 403 | # If we have no more points or this point is |
| | 404 | # the start of a new line, insert the current |
| | 405 | # line into the output feature class. |
| | 406 | |
| | 407 | if line is not None and (point is None or point['track'] != line['track']): |
| | 408 | insertCursor.SetGeometry(ogr.CreateGeometryFromWkt('MULTILINESTRING(%s)' % ', '.join(['(' + ', '.join(['%r %r' % (coords[0], coords[1]) for coords in part]) + ')' for part in line['geometry']]))) |
| | 409 | insertCursor.SetValue('track', line['track']) |
| | 410 | insertCursor.SetValue('duration', line['duration']) |
| | 411 | insertCursor.SetValue('startdate', line['startdate']) |
| | 412 | insertCursor.SetValue('enddate', line['enddate']) |
| | 413 | insertCursor.SetValue('cyc', line['cyc']) |
| | 414 | insertCursor.SetValue('minA', min(line['A'])) |
| | 415 | insertCursor.SetValue('maxA', max(line['A'])) |
| | 416 | insertCursor.SetValue('meanA', float(sum(line['A'])) / len(line['A'])) |
| | 417 | insertCursor.SetValue('minL', min(line['L'])) |
| | 418 | insertCursor.SetValue('maxL', max(line['L'])) |
| | 419 | insertCursor.SetValue('meanL', float(sum(line['L'])) / len(line['L'])) |
| | 420 | insertCursor.SetValue('minU', min(line['U'])) |
| | 421 | insertCursor.SetValue('maxU', max(line['U'])) |
| | 422 | insertCursor.SetValue('meanU', float(sum(line['U'])) / len(line['U'])) |
| | 423 | |
| | 424 | insertCursor.InsertRow() |
| | 425 | |
| | 426 | line = None |
| | 427 | |
| | 428 | # If we have no more points, break out of the |
| | 429 | # loop. |
| | 430 | |
| | 431 | if point is None: |
| | 432 | break |
| | 433 | |
| | 434 | # If this point is the start of a new line, |
| | 435 | # initialize a new entry in our dictionary of |
| | 436 | # line attributes. |
| | 437 | |
| | 438 | if line is None: |
| | 439 | line = {} |
| | 440 | line['geometry'] = [[]] |
| | 441 | line['track'] = point['track'] |
| | 442 | line['startdate'] = point['obsdate'] |
| | 443 | line['cyc'] = point['cyc'] |
| | 444 | line['A'] = [] |
| | 445 | line['L'] = [] |
| | 446 | line['U'] = [] |
| | 447 | |
| | 448 | # Update the dictionary of line attributes |
| | 449 | # with values from this point. |
| | 450 | |
| | 451 | line['duration'] = point['n'] - 1 |
| | 452 | line['enddate'] = point['obsdate'] |
| | 453 | line['A'].append(point['A']) |
| | 454 | line['L'].append(point['L']) |
| | 455 | line['U'].append(point['U']) |
| | 456 | |
| | 457 | # Add this point to the line geometry. If this |
| | 458 | # the first point of the line or this point |
| | 459 | # did not cause the line to wrap around from |
| | 460 | # 360 to 0 or 0 to 360 (which is indicated by |
| | 461 | # a longitudinal difference of more than 100 |
| | 462 | # degrees), then just append this point to the |
| | 463 | # existing line part. |
| | 464 | |
| | 465 | if len(line['geometry'][-1]) <= 0 or abs(point['lon'] - line['geometry'][-1][-1][-2]) < 100: |
| | 466 | line['geometry'][-1].append([point['lon'], point['lat']]) |
| | 467 | |
| | 468 | else: |
| | 469 | previousLat = line['geometry'][-1][-1][-1] |
| | 470 | previousLon = line['geometry'][-1][-1][-2] |
| | 471 | |
| | 472 | # Otherwise, if this point caused the line |
| | 473 | # to wrap from 360 around to 0, terminate |
| | 474 | # the current line part at 360 longitude, |
| | 475 | # then start another line part at 0 |
| | 476 | # longitude. |
| | 477 | |
| | 478 | if point['lon'] < line['geometry'][-1][-1][-2]: |
| | 479 | latAt360 = previousLat + (point['lat'] - previousLat) * ((360. - previousLon) / (360. + point['lon'] - previousLon)) |
| | 480 | line['geometry'][-1].append([360., latAt360]) |
| | 481 | line['geometry'].append([[0., latAt360], [point['lon'], point['lat']]]) |
| | 482 | |
| | 483 | # Otherwise, if this point caused the line |
| | 484 | # to wrap from 0 around to 360, terminate |
| | 485 | # the current line part at 0 longitude, |
| | 486 | # then start another line part at 360 |
| | 487 | # longitude. |
| | 488 | |
| | 489 | else: |
| | 490 | latAt0 = previousLat + (point['lat'] - previousLat) * (previousLon / (previousLon - (point['lon'] - 360.))) |
| | 491 | line['geometry'][-1].append([0., latAt0]) |
| | 492 | line['geometry'].append([[360., latAt0], [point['lon'], point['lat']]]) |
| | 493 | |
| | 494 | # Fetch the next point. |
| | 495 | |
| | 496 | point = selectCursor.fetchone() |
| | 497 | finally: |
| | 498 | selectCursor.close() |
| | 499 | del selectCursor |
| | 500 | finally: |
| | 501 | db.Close() |
| | 502 | finally: |
| | 503 | del insertCursor |
| | 674 | # Public method: CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite |
| | 675 | |
| | 676 | AddMethodMetadata(CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, |
| | 677 | shortDescription=_(u'Extracts eddy centroid points from the Chelton et al. (2011) mesoscale eddy database in SpatiaLite format.'), |
| | 678 | longDescription=_( |
| | 679 | u"""In order to use this tool, you must first download the mesoscale |
| | 680 | eddy database netCDF file (usually available at |
| | 681 | `<http://cioss.coas.oregonstate.edu/eddies/>`_) and convert it to a |
| | 682 | SpatiaLite database using the Convert Mesoscale Eddies NetCDF to |
| | 683 | SpatiaLite Database tool. |
| | 684 | |
| | 685 | Because the database includes over 200,000 eddies with nearly 2.5 |
| | 686 | million total centroids, we recommend that you use the Where Clause |
| | 687 | parameter to limit the extraction to the eddies that occured in your |
| | 688 | region and time period of interest. If you do not specify the Where |
| | 689 | Clause, all of the centroids will be extracted, which can take quite a |
| | 690 | long time and produce an output feature class that requires several |
| | 691 | hundred megabytes of disk space.""") + |
| | 692 | _CheltonMesocaleEddies_References, |
| | 693 | isExposedToPythonCallers=True, |
| | 694 | isExposedByCOM=True, |
| | 695 | isExposedAsArcGISTool=True, |
| | 696 | arcGISDisplayName=_(u'Extract Mesoscale Eddy Centroids From SpatiaLite Database'), |
| | 697 | arcGISToolCategory=_(u'Data Products\\Oregon State University CIOSS\\Mesoscale Eddies in Altimeter Observations of SSH'), |
| | 698 | dependencies=[PythonAggregatedModuleDependency('numpy')]) |
| | 699 | |
| | 700 | CopyArgumentMetadata(CheltonMesocaleEddyPoints.ConvertToSpatiaLite, u'cls', CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, u'cls') |
| | 701 | |
| | 702 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, u'spatiaLiteDB', |
| | 703 | typeMetadata=FileTypeMetadata(mayBeCompressed=True, mustExist=True), |
| | 704 | description=_( |
| | 705 | u"""Mesoscale eddies SpatiaLite database to read. |
| | 706 | |
| | 707 | This database is produced from the mesoscale eddy database netCDF file |
| | 708 | (usually available at `<http://cioss.coas.oregonstate.edu/eddies/>`_) |
| | 709 | by the Convert Mesoscale Eddies NetCDF to SpatiaLite Database |
| | 710 | tool."""), |
| | 711 | arcGISDisplayName=_(u'Mesoscale eddies SpatiaLite database')) |
| | 712 | |
| | 713 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, u'outputFeatureClass', |
| | 714 | typeMetadata=ArcGISFeatureClassTypeMetadata(mustBeDifferentThanArguments=[u'spatiaLiteDB'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True), |
| | 715 | description=_( |
| | 716 | u"""Point feature class to create. |
| | 717 | |
| | 718 | Each point represents the centroid of an eddy. Longitudes of the |
| | 719 | points will range from 0 to 360. The points will have the following |
| | 720 | attributes; data types are indicated in parentheses following the |
| | 721 | field name. |
| | 722 | |
| | 723 | * track (integer) - eddy identification number. |
| | 724 | |
| | 725 | * n (integer) - point number along the eddy track. Starts with 1. Points |
| | 726 | are separated by intervals of 7 days, so at point 2 the eddy is 7 |
| | 727 | days old, at point 3 it is 14 days old, and so on. |
| | 728 | |
| | 729 | * obsdate (date) - date of the point. |
| | 730 | |
| | 731 | * cyc (integer) - polarity of the eddy: -1 for cyclonic eddies and +1 |
| | 732 | for anticyclonic eddies. |
| | 733 | |
| | 734 | * lon, lat (float) - longitude and latitude of the centroid of the |
| | 735 | eddy. The longitudes are converted from the range used in the netCDF |
| | 736 | (260 E - 650 E) to 0 E - 360 E. |
| | 737 | |
| | 738 | * A (float) - eddy amplitude (cm) defined to be the magnitude of the |
| | 739 | height difference between the extremum of SSH within the eddy and |
| | 740 | the SSH around the contour defining the perimeter of the eddy. |
| | 741 | |
| | 742 | * L (float) - eddy radius scale (km) defined to be the radius of a |
| | 743 | circle with area equal to that enclosed by the contour of SSH within |
| | 744 | the eddy around which the circum-average speed is maximum. |
| | 745 | |
| | 746 | * U (float) - average speed (cm/sec) around the SSH contour that |
| | 747 | defines the scale L, i.e., the maximum circum-average speed within |
| | 748 | the eddy. |
| | 749 | |
| | 750 | Please see Chelton et al. (2011) and |
| | 751 | `<http://cioss.coas.oregonstate.edu/eddies/>`_ for more information |
| | 752 | about how these parameters were calculated. |
| | 753 | |
| | 754 | A spatial index will be created on the output feature class."""), |
| | 755 | direction=u'Output', |
| | 756 | arcGISDisplayName=_(u'Output feature class')) |
| | 757 | |
| | 758 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, u'tableName', |
| | 759 | typeMetadata=UnicodeStringTypeMetadata(), |
| | 760 | description=_( |
| | 761 | u"""Name of the table to read from the SpatiaLite database."""), |
| | 762 | arcGISDisplayName=_(u'SpatiaLite table name')) |
| | 763 | |
| | 764 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, u'where', |
| | 765 | typeMetadata=UnicodeStringTypeMetadata(canBeNone=True), |
| | 766 | description=_( |
| | 767 | u"""SQL WHERE clause expression that specifies the subset of points to |
| | 768 | extract. If this parameter is not provided, all of the points will be |
| | 769 | extracted. |
| | 770 | |
| | 771 | The expression is evaluated by the SQLite database engine that |
| | 772 | SpatiaLite is built upon. Please see the `SQLite documentation |
| | 773 | <http://www.sqlite.org/lang_expr.html>`_ for more information about |
| | 774 | the syntax of this expression. |
| | 775 | |
| | 776 | The following expression shows how to specify a geographic bounding |
| | 777 | box and time window to extract centroids that occurred in a region of |
| | 778 | the north Atlantic in the first three months of 2000. Note that |
| | 779 | longitude ranges from 0 to 360:: |
| | 780 | |
| | 781 | lat >= 25 and lat <= 50 and lon >= 280 and lon <= 340 and obsdate >= '2000-01-01' and obsdate <= '2000-03-31' |
| | 782 | |
| | 783 | This example shows how to extract the centroids from the southern |
| | 784 | hemisphere that were at least 16 weeks old and that had anticyclonic |
| | 785 | polarity:: |
| | 786 | |
| | 787 | lat < 0 and n >= 17 and cyc = 1 |
| | 788 | |
| | 789 | You may use SpatiaLite's SQL functions in this expression to perform |
| | 790 | spatial comparisons. Please see the `SpatiaLite documentation |
| | 791 | <http://www.gaia-gis.it/gaia-sins/spatialite-sql-3.0.0.html>`_ for |
| | 792 | more information."""), |
| | 793 | arcGISDisplayName=_(u'Where clause')) |
| | 794 | |
| | 795 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, u'overwriteExisting', |
| | 796 | typeMetadata=BooleanTypeMetadata(), |
| | 797 | description=_( |
| | 798 | u"""If True, the output feature class will be overwritten, if it |
| | 799 | exists. If False, a ValueError will be raised if the output feature |
| | 800 | class exists."""), |
| | 801 | initializeToArcGISGeoprocessorVariable=u'OverwriteOutput') |
| | 802 | |
| | 803 | # Public method: CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite |
| | 804 | |
| | 805 | AddMethodMetadata(CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite, |
| | 806 | shortDescription=_(u'Extracts eddy tracklines from the Chelton et al. (2011) mesoscale eddy database in SpatiaLite format.'), |
| | 807 | longDescription=_( |
| | 808 | u"""In order to use this tool, you must first download the mesoscale |
| | 809 | eddy database netCDF file (usually available at |
| | 810 | `<http://cioss.coas.oregonstate.edu/eddies/>`_) and convert it to a |
| | 811 | SpatiaLite database using the Convert Mesoscale Eddies NetCDF to |
| | 812 | SpatiaLite Database tool. |
| | 813 | |
| | 814 | Each line represents the track of an eddy and includes attributes such |
| | 815 | as the start date, end date, duration, polarity, and various summary |
| | 816 | statistics. The track is constructed by connecting the eddy centroid |
| | 817 | points present in the database. |
| | 818 | |
| | 819 | Because the database includes over 200,000 eddies, we recommend that |
| | 820 | you use the Where Clause parameter to limit the extraction to the |
| | 821 | eddies that occured in your region and time period of interest. If you |
| | 822 | do not specify the Where Clause, all 200,000 tracks will be extracted, |
| | 823 | which can take quite a long time and produce an output feature class |
| | 824 | that requires several hundred megabytes of disk space.""") + |
| | 825 | _CheltonMesocaleEddies_References, |
| | 826 | isExposedToPythonCallers=True, |
| | 827 | isExposedByCOM=True, |
| | 828 | isExposedAsArcGISTool=True, |
| | 829 | arcGISDisplayName=_(u'Extract Mesoscale Eddy Tracklines From SpatiaLite Database'), |
| | 830 | arcGISToolCategory=_(u'Data Products\\Oregon State University CIOSS\\Mesoscale Eddies in Altimeter Observations of SSH'), |
| | 831 | dependencies=[PythonAggregatedModuleDependency('numpy')]) |
| | 832 | |
| | 833 | CopyArgumentMetadata(CheltonMesocaleEddyPoints.ConvertToSpatiaLite, u'cls', CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite, u'cls') |
| | 834 | |
| | 835 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite, u'spatiaLiteDB', |
| | 836 | typeMetadata=FileTypeMetadata(mayBeCompressed=True, mustExist=True), |
| | 837 | description=_( |
| | 838 | u"""Mesoscale eddies SpatiaLite database to read. |
| | 839 | |
| | 840 | This database is produced from the mesoscale eddy database netCDF file |
| | 841 | (usually available at `<http://cioss.coas.oregonstate.edu/eddies/>`_) |
| | 842 | by the Convert Mesoscale Eddies NetCDF to SpatiaLite Database |
| | 843 | tool."""), |
| | 844 | arcGISDisplayName=_(u'Mesoscale eddies SpatiaLite database')) |
| | 845 | |
| | 846 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite, u'outputFeatureClass', |
| | 847 | typeMetadata=ArcGISFeatureClassTypeMetadata(mustBeDifferentThanArguments=[u'spatiaLiteDB'], deleteIfParameterIsTrue=u'overwriteExisting', createParentDirectories=True), |
| | 848 | description=_( |
| | 849 | u"""Line feature class to create. |
| | 850 | |
| | 851 | Each line represents an eddy track. Longitude coordinates will range |
| | 852 | from 0 to 360. Tracks that cross the Prime Meridian will be split into |
| | 853 | multi-part lines. |
| | 854 | |
| | 855 | The lines will have the following attributes; data types are indicated |
| | 856 | in parentheses following the field name. |
| | 857 | |
| | 858 | * track (integer) - eddy identification number. |
| | 859 | |
| | 860 | * duration (integer) - duration of the eddy, in weeks. |
| | 861 | |
| | 862 | * startdate (date) - date the eddy was first observed. |
| | 863 | |
| | 864 | * enddate (date) - date the eddy was last observed. |
| | 865 | |
| | 866 | * cyc (integer) - polarity of the eddy: -1 for cyclonic eddies and +1 |
| | 867 | for anticyclonic eddies. |
| | 868 | |
| | 869 | * minA, maxA, meanA (float) - minimum, maximum, and mean per-centroid |
| | 870 | eddy amplitude (cm), defined to be the magnitude of the height |
| | 871 | difference between the extremum of SSH within the eddy and the SSH |
| | 872 | around the contour defining the perimeter of the eddy. These |
| | 873 | statistics are calculated from the A parameter of the eddy centroids |
| | 874 | that make up the track. |
| | 875 | |
| | 876 | * minL, maxL, meanL (float) - minimum, maximum, and mean per-centroid |
| | 877 | eddy radius scale (km), defined to be the radius of a circle with |
| | 878 | area equal to that enclosed by the contour of SSH within the eddy |
| | 879 | around which the circum-average speed is maximum. These statistics |
| | 880 | are calculated from the L parameter of the eddy centroids that make |
| | 881 | up the track. |
| | 882 | |
| | 883 | * minU, maxU, meanU (float) - minimum, maximum, and mean per-centroid |
| | 884 | average speed (cm/sec) around the SSH contour that defines the scale |
| | 885 | L, i.e., the maximum circum-average speed within the eddy. These |
| | 886 | statistics are calculated from the U parameter of the eddy centroids |
| | 887 | that make up the track. |
| | 888 | |
| | 889 | Please see Chelton et al. (2011) and |
| | 890 | `<http://cioss.coas.oregonstate.edu/eddies/>`_ for more information |
| | 891 | about how these parameters were calculated. |
| | 892 | |
| | 893 | A spatial index will be created on the output feature class."""), |
| | 894 | direction=u'Output', |
| | 895 | arcGISDisplayName=_(u'Output feature class')) |
| | 896 | |
| | 897 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite, u'tableName', |
| | 898 | typeMetadata=UnicodeStringTypeMetadata(), |
| | 899 | description=_( |
| | 900 | u"""Name of the table to read from the SpatiaLite database."""), |
| | 901 | arcGISDisplayName=_(u'SpatiaLite table name')) |
| | 902 | |
| | 903 | AddArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite, u'where', |
| | 904 | typeMetadata=UnicodeStringTypeMetadata(canBeNone=True), |
| | 905 | description=_( |
| | 906 | u"""SQL WHERE clause expression that specifies the eddy centroids that |
| | 907 | identify the eddy tracks to extract. If this parameter is not |
| | 908 | provided, all of the tracks will be extracted. |
| | 909 | |
| | 910 | The expression should reference the attributes of the centroids, not |
| | 911 | the tracks. Please see the documentation for the Convert Mesoscale |
| | 912 | Eddies NetCDF to SpatiaLite Database tool for a description of the |
| | 913 | centroid attributes. |
| | 914 | |
| | 915 | If this expression does not select all of the centroids that make up a |
| | 916 | track, the entire track will be extracted anyway. For example, if the |
| | 917 | expression specifies a geographic bounding box, complete tracks will |
| | 918 | be extracted for all eddies that had at least one centroid occur |
| | 919 | within the box. |
| | 920 | |
| | 921 | The expression is evaluated by the SQLite database engine that |
| | 922 | SpatiaLite is built upon. Please see the `SQLite documentation |
| | 923 | <http://www.sqlite.org/lang_expr.html>`_ for more information about |
| | 924 | the syntax of this expression. |
| | 925 | |
| | 926 | The following expression shows how to specify a geographic bounding |
| | 927 | box and time window to extract tracks that had at least one centroid |
| | 928 | occur in a region of the north Atlantic in the first three months of |
| | 929 | 2000. Note that longitude ranges from 0 to 360:: |
| | 930 | |
| | 931 | lat >= 25 and lat <= 50 and lon >= 280 and lon <= 340 and obsdate >= '2000-01-01' and obsdate <= '2000-03-31' |
| | 932 | |
| | 933 | This example shows how to extract the tracks that had at least one |
| | 934 | centroid in the southern hemisphere, that had a duration of at least |
| | 935 | 16 weeks, and that had anticyclonic polarity:: |
| | 936 | |
| | 937 | lat < 0 and n >= 17 and cyc = 1 |
| | 938 | |
| | 939 | You may use SpatiaLite's SQL functions in this expression to perform |
| | 940 | spatial comparisons. Please see the `SpatiaLite documentation |
| | 941 | <http://www.gaia-gis.it/gaia-sins/spatialite-sql-3.0.0.html>`_ for |
| | 942 | more information."""), |
| | 943 | arcGISDisplayName=_(u'Where clause')) |
| | 944 | |
| | 945 | CopyArgumentMetadata(CheltonMesocaleEddyPoints.ExtractArcGISPointsFromSpatiaLite, u'overwriteExisting', CheltonMesocaleEddyPoints.ExtractArcGISLinesFromSpatiaLite, u'overwriteExisting') |
| | 946 | |