def getDomain(self, epsg): if epsg is None or epsg == 3413: domain = 'greenland' elif epsg == 3031: domain = 'antarctica' else: myerror('Unexpected epsg code: ' + str(epsg)) return domain
def appendPointError(self, newY): '''append errors for a point - allow for up to 3 filelds ''' if len(newY) <= 0 or len(newY) > 3: myerror(f'shpplot.appendPointError: Invalid # of y points {newY}') self.e1plot.append(newY[0]) if len(newY) >= 2: self.e2plot.append(newY[1]) if len(newY) == 3: self.e3plot.append(newY[2])
def appendProfileError(self, y1, y2=None, y3=None): # self.e1plot.append(y1) if len(y1) != len(self.xplot): myerror('appendProfileError length of x and y data do not match') if y2 is not None: self.e2plot.append(y2) if y3 is not None: self.e3plot.append(y3)
def readGeodat(self, geoFile): if self.verbose: print(geoFile) if self.geo == []: self.geo = geodat(verbose=self.verbose) if os.path.exists(geoFile): self.geo.readGeodat(geoFile) else: myerror('Missing geodat file ' + geoFile)
def appendPoint(self, newDate, newY, label): ''' append a point to the list for plotting - allow for up to 3 fields''' self.xplot.append(newDate) self.labels.append(label) if len(newY) <= 0 or len(newY) > 3: myerror('shpplot.appendPoint: Invalide number of y points ' + newY) self.y1plot.append(newY[0]) if len(newY) >= 2: self.y2plot.append(newY[1]) if len(newY) == 3: self.y3plot.append(newY[2])
def readMyTiff(self, tiffFile): """ read a tiff file and return the array """ try: gdal.AllRegister() ds = gdal.Open(tiffFile) band = ds.GetRasterBand(1) arr = band.ReadAsArray() arr = np.flipud(arr) ds = None except Exception: myerror("geoimage.readMyTiff: error reading tiff file " + tiffFile) return arr
def appendProfile(self, newDate, y1, label, y2=None, y3=None): ''' append a point to the list for plotting - allow for up to 3 fields''' self.dates.append(newDate) self.labels.append(label) # self.y1plot.append(y1) if len(y1) != len(self.xplot): myerror('appendProfile length of x and y data do not match') if y2 is not None: self.y2plot.append(y2) if y3 is not None: self.y3plot.append(y3)
def writeMyTiff(self, tiffFile, epsg=None, noDataDefault=None, predictor='YES', noV=False, overviews=None, driverName='COG', wktFile=None, computeStats=True): """ write a geotiff file - NEEDS MODIFICATION FOR EPSG AND VX,EX Note: tiffFile should not have a ".tif" extension - one will be added. overviews should be of form [2, 4...] """ # define various set up stuff suffixDict = { 'scalar': [''], 'velocity': ['.vx', '.vy', '.v'], 'error': ['.ex', '.ey'] } typeDict = {'scalar': self.x, 'velocity': self.vx, 'error': self.ex} # predictor = [int(predictor), 1][predictor > 3 or predictor < 1] if wktFile is None: epsg = [epsg, 3413][epsg is None] try: suffixes = suffixDict[self.geoType] gdalType = gdal_array.NumericTypeCodeToGDALTypeCode( typeDict[self.geoType].dtype) except Exception: myerror('writeMyTiff: invalid geoType ' + self.geoType) # try: # Loop through different components, also write vmag for velocity for suffix in suffixes: # skip .v if requested if noV and suffix == '.v': continue # write the geotiff self.writeCloudOptGeo(tiffFile, suffix, epsg, gdalType, overviews=overviews, predictor=predictor, noDataDefault=noDataDefault, driverName=driverName, wktFile=wktFile, computeStats=computeStats) except Exception: myerror(f"geoimage.writeMyTiff: error writing file {tiffFile}")
def setupInterp(self, method='linear'): """ set up interpolation for scalar (xInterp) or velocity/eror (vxInterp, vyInterp, vInterp) """ # if len(self.xx) < 0: myerror('\n\nsetupInterp: x, y limits not set\n\n') # # setup interp - flip xy for row colum # xy = (self.yy, self.xx) if self.geoType == 'scalar': self.xInterp = RegularGridInterpolator(xy, self.x, method=method) if self.geoType == 'velocity': self.vxInterp = RegularGridInterpolator(xy, self.vx, method=method) self.vyInterp = RegularGridInterpolator(xy, self.vy, method=method) self.vInterp = RegularGridInterpolator(xy, self.v, method=method) if self.geoType == 'error': self.exInterp = RegularGridInterpolator(xy, self.ex, method=method) self.eyInterp = RegularGridInterpolator(xy, self.ey, method=method) self.eInterp = RegularGridInterpolator(xy, self.e, method=method)
def getGeoFile(self, fileName, domain, vxMod=None, geoFile=None, tiff=False, wkt=None): ''' determine the file name for geodat if not specified and load geodat info''' if not tiff: suffixes = { 'scalar': '.geodat', 'velocity': '.vx.geodat', 'error': '.vx.geodat' } else: suffixes = { 'scalar': '', 'velocity': '.vx.tif', 'error': '.vx.tif' } if vxMod is not None: suffixes['error'] = vxMod suffixes['velocity'] = vxMod # if geoFile is None: try: geoFile = fileName + suffixes[self.geoType] except Exception: myerror(f"geoimage.getGeoFile: Invalid type {self.geoType} ") # self.geo = geodat(verbose=self.verbose, domain=domain, wkt=wkt) if not tiff: self.geo.readGeodat(geoFile) else: self.geo.readGeodatFromTiff(geoFile) return geoFile
def readTextTimeSeriesData(self, file): # # open file fpIn = open(file, 'r') # init defaults tsFormat = None label = '' ncol = 1 # this works only for points (at present anyway) self.plotType = 'point' # loop over lines in file for line in fpIn: # check for header info if 'dateformat' in line: tsFormat = line.split('=')[-1].strip() elif 'ndatacol' in line: ncol = int(line.split('=')[-1]) elif 'name' in line: self.name = line.split('=')[-1].strip() elif 'label' in line: label = line.split('=')[-1].strip() elif ';' in line or line.isspace(): # comment continue # # process the data elif tsFormat is not None: # process date if 1: dateString = line.split()[0] myDate = datetime.strptime(dateString, tsFormat) else: myerror('Invalid date format -- ' + tsFormat + 'for date' + dateString + 'from ' + line) # process data newY = [float(x) for x in line.split()[1:]] if len(newY) > 3 or len(newY) < 1 or len(newY) != ncol: myerror('invalid number of columns\n' + line) # append data self.appendPoint(myDate, newY, label) else: myerror('error parsing time series\n' + line) return
def writeCloudOptGeo(self, tiffFile, suffix, epsg, gdalType, overviews=None, predictor='YES', noDataDefault=None, bigTiff=False, driverName='COG', wktFile=None, computeStats=True): ''' write a cloudoptimized geotiff with overviews. Set format to GTiff for a plain geotiff ''' if driverName not in ['COG', 'GTiff']: myerror(f'invalid driver for writeCloudOptGeo {driverName}') # no data info noData = { '.vx': -2.0e9, '.vy': -2.0e9, '.v': -1.0, '.ex': -1.0, '.ey': -1.0, '': noDataDefault }[suffix] # # use a temp mem driver for CO geo driver = gdal.GetDriverByName("MEM") nx, ny = self.imageSize() dx, dy = self.geo.pixSizeInM() dst_ds = driver.Create('', nx, ny, 1, gdalType) # set geometry tiffCorners = self.computePixEdgeCornersXYM() dst_ds.SetGeoTransform( (tiffCorners['ul']['x'], dx, 0, tiffCorners['ul']['y'], 0, -dy)) # set projection wkt = self.getWKT_PROJ(epsg, wktFile) # dst_ds.SetProjection(wkt) # set nodata if noData is not None: if self.geoType == 'scalar': tmp = self.x else: # vx, vy etc tmp = getattr(self, suffix.replace('.', '')) tmp[np.isnan(tmp)] = noData dst_ds.GetRasterBand(1).SetNoDataValue(noData) # write data if self.geoType == 'scalar': dst_ds.GetRasterBand(1).WriteArray(np.flipud(self.x)) else: dst_ds.GetRasterBand(1).WriteArray( np.flipud(getattr(self, suffix.replace('.', '')))) # compute statistics, which should embed in file. if computeStats: _ = dst_ds.GetRasterBand(1).GetStatistics(0, 1) # bigTiffFlag = ["NO", "YES"][bigTiff] options = [f'BIGTIFF={bigTiffFlag}', 'COMPRESS=LZW'] # driver specific stuff if driverName == 'GTiff': # GTiff options if type(predictor) != int and predictor is not None: options.append(f'PREDICTOR={1}') if overviews is not None: if len(overviews) < 2: myerror(f'Overviews {overviews} should be [2, 4, ..])') options.append('COPY_SRC_OVERVIEWS=YES') dst_ds.BuildOverviews('AVERAGE', overviews) else: # COG OPTIONS options.append('GEOTIFF_VERSION=1.1') options.append('GEOTIFF_VERSION=1.1') if predictor in ['YES', 'NO']: options.append(f'PREDICTOR={predictor}') # # now copy to a geotiff - mem -> geotiff forces correct order # for c opt geotiff dst_ds.FlushCache() driver = gdal.GetDriverByName(driverName) # Create copy for the COG. dst_ds2 = driver.CreateCopy(f'{tiffFile}{suffix}.tif', dst_ds, options=options) dst_ds2.FlushCache() # free memory dst_ds, dst_ds2 = None, None