@takashi,你是正确的。但是,我们的光栅开发团队想要澄清一些事情:
ceil(光栅行数/每个tile的行数)x ceil(光栅列数/每个tile的列数)
Hi @DaveAtSafe,感谢您关于每个Tile的行数的回复
OK。我知道一个光栅带的数据内容可以包含一个或多个块。FMEBandTilePopulator.getTile()方法将被调用多次当填充数据内容的乐队,如果行/列的数量<强>每瓦< /强>设置为乐队的数量小于光栅的行/列<强> < / >强。方法调用的数量等于块的数量。即< / p > < >以前装天花板(光栅的行数/每瓦的行数)x装天花板(光栅的列数/每瓦列数)< / pre > < p >和起始行/列索引在给定的数据将通过参数传递矩阵和大小(startRow startCol,瓷砖)getTile()方法用于创建每个瓷砖。因此,在我的练习中,MyUInt8BandTilePopulator.getTile()方法也可以像这样使用参数定义,这个定义允许每个tile指定任意数量的行/列作为band属性。
class MyUInt8BandTilePopulator(fmeobjects.FMEBandTilePopulator): def __init__(self, dataArray): self. class MyUInt8BandTilePopulator(fmeobjects.FMEBandTilePopulator):datarray = datarray def clone(self): return MyUInt8BandTilePopulator(self.dataArray) def getTile(self, startRow, startCol, tile): numRows, numCols = tile. getnumrows (), tile. getnumcols () endRow, endCol = startRow + numRows, startCol + numCols data = [self. dataArray];datarearray [r][startCol:endCol] for r in range(startRow, endRow)] newTile = fmeobjects. datarearray [r][startCol:endCol] for r in range(startRow, endRow)]FMEUInt8Tile(numRows, numCols) newTile. setdata (data)返回newTile
是否正确?< / p > < p > < / p > < p > < / p >
计算细胞值统计的示例。< / p >
[Fixed: 2017-03-15]
# PythonCaller Script Example: Statistics of Raster Cell Values # Calculate fundamental statistics of cell values (except Nodata) # in the band(s) of the input raster. # This example only supports REAL64 and REAL32 but you can enhance # it easily if necessary. import fmeobjects, math class RasterBandStatisticsCalculator(object): def __init__(self): self.keys = [ 'interpretation', 'nodata', 'count', 'sum', 'min', 'max', 'range', 'median', 'mean', 'stdev', 'stdevp', ] # Returns a tuple (tile object, interpretation name). # This method returns (None, 'Unsupported') # when the specified interpretation was not supported, def tileAndInterpretation(self, interpretation, numRows, numCols): if interpretation == fmeobjects.FME_INTERPRETATION_REAL64: return (fmeobjects.FMEReal64Tile(numRows, numCols), 'REAL64') elif interpretation == fmeobjects.FME_INTERPRETATION_REAL32: return (fmeobjects.FMEReal32Tile(numRows, numCols), 'REAL32') ###################################################### # Add other interpretations here if necessary. ###################################################### else: return (None, 'Unsupported') # Returns a dictionary containing the statistics of specified band. def calculateStatistics(self, band, numRows, numCols): # Get the band properties. bandProperties = band.getProperties() interpretation = bandProperties.getInterpretation() # Create a tile that will be used to get cell values of the band. # The interpretation, number of rows, and number of columns # have to be consistent with the band properties. tile, interpret = self.tileAndInterpretation(interpretation, numRows, numCols) stats = {'interpretation': interpret} if tile != None: # Get all the cell values except Nodata as a list. values = [] nodataValue = band.getNodataValue() if nodataValue == None: for data in band.getTile(0, 0, tile).getData(): values += data else: nodata = nodataValue.getData()[0][0] for data in band.getTile(0, 0, tile).getData(): values += [v for v in data if v != nodata] stats['nodata'] = nodata # Calculate statistics. values.sort() count = len(values) stats['count'] = count if 0 < count: total = sum(values) stats['sum'] = total stats['min'] = values[0] stats['max'] = values[-1] stats['range'] = (values[-1] - values[0]) # Median m = count // 2 stats['median'] = (values[m] if count % 2 == 1 else (values[m-1] + values[m]) * 0.5) # Mean (average) avrg = float(total) / count stats['mean'] = avrg # Standard Deviation if 1 < count: s = sum([(v - avrg)**2 for v in values]) stats['stdev'] = math.sqrt(s / (count - 1)) stats['stdevp'] = math.sqrt(s / count) return stats def input(self, feature): raster = feature.getGeometry() if isinstance(raster, fmeobjects.FMERaster): rasterProperties = raster.getProperties() numRows = rasterProperties.getNumRows() numCols = rasterProperties.getNumCols() for i in range(raster.getNumBands()): stats = self.calculateStatistics(raster.getBand(i), numRows, numCols) for key in self.keys: attr = '_band{%d}.%s' % (i, key) if key in stats: feature.setAttribute(attr, stats[key]) else: feature.setAttributeNullWithType(attr, fmeobjects.FME_ATTR_REAL64) self.pyoutput(feature)
感谢Takashi为FME 2017.0突出了FME对象Python API中新增的光栅。伟大的示例应用程序!我只是想让大家知道,更新的2017.0 Python API文档,包括新的光栅API,现在可以在https://docs.safe.com/fme/html/FME_Objects_Python_API/index.html
在线访问亚搏在线第二个练习:计算单元值,将调色板附加到标注栏,然后尝试光栅工具。从Conway的人生游戏
FME挑战:生活游戏亚搏在线#蟒蛇骑士脚本示例:康威的生活游戏#FME 2017.0 RC构建17254,2017-02-28#每个输出功能都包含一个表示活/死细胞的光栅光栅只有一个波段,波段有一个调色板假设输入功能具有这些属性1.发电量(0<;整数):要处理的代数2.numRows(0<;整数):结果光栅中的行数3.numCols(0<;整数):结果光栅中的列数4.初始速率(0<;雷亚尔<;1) :第一代活细胞的比率将在输出特征中添加一个名为“_generation”的新属性,该属性存储表示生成顺序的基于1的序列号。导入fmeobjects,随机类MyUInt8BandTilePopulator(fmeobjects.FMEBandTilePopulator):def_uuinit_uu(self,dataArray):self.dataArray=dataArray def clone(self):返回MyUInt8BandTilePopulator(self.dataArray)def getTile(self,startRow,startCol,tile):numRows,numCols=len(self.dataArray),len(self.dataArray[0])newfile=fmeobjects.FMEUInt8Tile(numRows,numCols)newfile.setData(self.dataArray)返回newfile类ConwaysGameOfLife(object):def uuu init__;(self):self.rasterTools=fmeobjects.FMERasterTools()def输入(self,feature):#从feature属性获取参数。numGenerations=int(feature.getAttribute('numGenerations'))self.numRows=int(feature.getAttribute('numRows'))self.numCols=int(feature.getAttribute('numCols'))self.initialRate=float(feature.getAttribute('initialRate'))如果0<;numGenerations\和0<;self.numRows和0<;self.numCols\和0.0<;=self.initialRate和self.initialRate<;=1.0:self.initialize()outNumRows,outNumCols=self.numRows*10,self.numCols*10光栅=范围内i无(numGenerations):光栅=self.nextGeneration(光栅)功能。setGeometry(self.rasterTools.resampleByRowCol(outNumRows,outNumCols,fmeobjects.FME_插值_NearestNearest Nearest Neighbork,光栅))功能。setAttribute(“U generation”,i+1)self.pyoutput(feature)else:feature.setAttribute(“U错误”,“无效参数”)self.pyoutput(feature)def initialize(self):#光栅属性xspace,yspace=1.0,1.0 xCellOrigin,yCellOrigin=0.5,0.5 xOrigin,yOrigin=0.0,0 x旋转,yRotation=0.0,0.0 self.rasterprivaties=fmeobjects.fmeraderprivaties.fmeraderproperties(self.numRows,self.numCols、xspace、yspace、xCellOrigin、yCellOrigin、xOrigin、yOrigin、xRotation)#频带属性self.bandProperties=fmeobjects.FMEBandProperties(‘生命游戏’、fmeobjects.FME_解释单元8、fmeobjects.FME_TILE_TYPE_固定、self.numRows、,self.numCols)#创建一个调色板对象,表示:#-------------------------RGB24#0 220220220#1 128,0,0#------key=fmeobjects.FMEUInt8Tile(1,2)key.setData([[0,1]])value=fmeobjects.fmergb24file(1,2)value.setData([[220220,128,0,0,0,]])self.palete=fmeobjects.FMEPalette(“”,值)#返回表示下一代的光栅,如果参数为无,则返回表示第一代的光栅。def下一代(自我,prevRaster):nextData=[]如果prevRaster==None:num=self.numRows*self.numCols alives=int(num*self.initialRate)seed=[1代表范围内的i(alives)]+[0代表范围内的i(num-alives)]随机。对[i*self.numCols代表范围内的i(self.numRows)]:nextData.append(seed[s:s+seed.numCols])否则:#获取上一代。tile=fmeobjects.FMEUInt8Tile(self.numRows,self.numCols)prevData=prevgraster.getBand(0).getTile(0,0,tile.getData()#创建一个临时数据数组,其大小为每边放大一行/列#上一个光栅的顶部、底部、左侧和右侧,并将0设置为所有附加的外部边缘单元格。#这种数据数组可以很容易地计算每个单元在上一代中存活的相邻单元数。tmp=[[0表示范围内的i(self.numCols+2)]\+[[0]+数据+[0]表示范围内的数据]\+[[0表示范围内的i(self.numCols+2)]\ \为下一代创建新的数据数组。对于范围内的i(self.numRows):行=[]对于范围内的j(self.numCols):#计算上一代中存活的相邻单元的数量,然后根据游戏规则确定该单元在下一代中是否可以存活。n=tmp[i+0][j]+tmp[i+0][j+1]+tmp[i+0][j+2]\+tmp[i+1][j+2]\+tmp[i+2][j]+tmp[i+2][j+1]+tmp[i+2][j+2]如果上一个数据[i][j]=1:行。追加(如果[2,3]中有n,则追加1)其他:行。追加(如果n==3,则追加1)下一个数据。追加(行)turn a raster containing a single band. raster = fmeobjects.FMERaster(self.rasterProperties) band = fmeobjects.FMEBand(MyUInt8BandTilePopulator(nextData), self.rasterProperties, self.bandProperties) band.appendPalette(self.palette) # Add a palette to the band. raster.appendBand(band) return raster
我会分享我的第一个练习,了解如何使用API创建一个新的光栅几何。 p>
#pythoncreator脚本示例:创建包含栅格#的功能栅格将有一个带uint8的单个频段解释。导入fmeobjects#定义从fmebandtilepopulator类派生的具体类。#此类的实例将用于创建图块#并将其填充到频带(FMEBABRIAD)。类Myuint8BandTilePupulator(fmeobjects.fmebandtilepopulator):def __init __(self,dataArray):self.dataArray = dataArray#实施'克隆'方法。#在创建新频段时将多次调用。def clone(self):返回myuint8bandtilepopulator(self.dataArray)#impler'gettile'方法。#您可以在此处创建包含所需内容的新图块。#使用参数并不重要:Startrow,startcol,瓷砖。def gettile(self,startrow,startcol,瓷砖):numrows,numcols = len(self.dataArray),len(self.dataArray [0])newtile = fmeobjects.fmeuint8tile(numrows,numcols)newtile.setdata(self.dataArray) return newTile # The following two methods won't be called while creating a new band. # It seems not to be essential to implement these methods in this case, # although the API doc says "This method must be implemented # in the FMEBandTilePopulator subclass". def setDeleteSourceOnDestroy(self, deleteFlag): pass def setOutputSize(self, rows, cols): return (rows, cols) class FeatureCreator(object): def __init__(self): pass def close(self): # Contents of a tile for a band to be created. # A list of row data, each element is a list of column values. dataArray = [ [ 0, 128, 0, 128, 0, 128, 0], [128, 0, 128, 0, 128, 0, 128], [ 0, 128, 0, 128, 0, 128, 0], [128, 0, 128, 0, 128, 0, 128], [ 0, 128, 0, 128, 0, 128, 0], ] # Properties of a raster to be created. numRows, numCols = len(dataArray), len(dataArray[0]) # resolution xSpacing, ySpacing = 10.0, 10.0 # cell spacing in ground units xCellOrigin, yCellOrigin = 0.5, 0.5 # cell origin coordinates xOrigin, yOrigin = 0.0, numRows * ySpacing # left-top coordinates xRotation, yRotation = 0.0, 0.0 # rotation angle in degrees # Create a new raster. rasterProperties = fmeobjects.FMERasterProperties(numRows, numCols, xSpacing, ySpacing, xCellOrigin, yCellOrigin, xOrigin, yOrigin, xRotation, yRotation) raster = fmeobjects.FMERaster(rasterProperties) # Create a new band and append it to the raster. # It's optional to specify Nodata value when creating a band. bandTilePopulator = MyUInt8BandTilePopulator(dataArray) bandName = 'My UInt8 Band' # can be set to empty. bandProperties = fmeobjects.FMEBandProperties(bandName, fmeobjects.FME_INTERPRETATION_UINT8, fmeobjects.FME_TILE_TYPE_FIXED, numRows, numCols) nodataValue = fmeobjects.FMEUInt8Tile(1, 1) nodataValue.setData([[0]]) band = fmeobjects.FMEBand(bandTilePopulator, rasterProperties, bandProperties, nodataValue) raster.appendBand(band) # Create and output a feature containing the raster created above. feature = fmeobjects.FMEFeature() feature.setGeometry(raster) self.pyoutput(feature)
我将使用它!< / p >