knight_sl
路人甲
路人甲
  • 注册日期2004-08-11
  • 发帖数21
  • QQ
  • 铜币161枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:1827回复:2

[讨论] TIN to Raster

楼主#
更多 发布于:2007-09-20 09:48
 
<P>为什么生成的栅格图像是黑乎乎一片呢?</P>
<P>而且高程值也不对</P>
<P>' Supported pixel types limited to float and long because output currently limited to native ESRI Grid<BR>' This routine handles cancel tracking so passed TIN should not have its CancelTracker set.<BR>Public Function TinToRaster(pTin As ITinAdvanced, eRastConvType As esriRasterizationType, _<BR>  sDir As String, sName As String, ePixelType As rstPixelType, cellsize As Double, pExtent As IEnvelope, _<BR>  bPerm As Boolean) As IRasterDataset<BR>      <BR>  ' The origin used by CreateRasterDataset is the lower left cell corner.<BR>  ' The extent passed is that of the TIN's.<BR>  ' Define the raster origin and number of rows and columns so that the raster<BR>  ' is of sufficient extent to capture area defined by passed envelope. The cell<BR>  ' center is located at the origin.<BR>  Dim pOrigin As IPoint<BR>  Set pOrigin = pExtent.LowerLeft<BR>  pOrigin.X = pOrigin.X - (cellsize * 0.5)<BR>  pOrigin.Y = pOrigin.Y - (cellsize * 0.5)<BR>  <BR>  Dim nCol As Long, nRow As Long<BR>  nCol = Round(pExtent.Width / cellsize) + 1<BR>  nRow = Round(pExtent.Height / cellsize) + 1<BR>  <BR>  Dim pGDS As IGeoDataset<BR>  Set pGDS = pTin<BR>  Dim pSR As ISpatialReference2<BR>  Set pSR = pGDS.SpatialReference<BR>  <BR>  Dim pRDS As IRasterDataset<BR>  Set pRDS = CreateRasterSurf(sDir, sName, "GRID", pOrigin, nCol, nRow, cellsize, cellsize, ePixelType, pSR, bPerm)<BR>    <BR>  DoEvents<BR>  <BR>  Dim pRawPixels As IRawPixels<BR>  Set pRawPixels = GetRawPixels(pRDS, 0)<BR>  <BR>  Dim pCache As stdole.IUnknown<BR>  Set pCache = pRawPixels.AcquireCache<BR>      <BR>  Dim pTinSurf As ITinSurface<BR>  Set pTinSurf = pTin<BR>    <BR>  Dim pRasterProps As IRasterProps<BR>  Set pRasterProps = pRawPixels<BR>  <BR>  Dim nodataFloat As Single<BR>  Dim nodataInt As Long<BR>      <BR>  Dim dZMin As Double<BR>  dZMin = pTin.Extent.ZMin<BR>      <BR>  Dim vNoData As Variant<BR>  If (ePixelType = PT_FLOAT) Then<BR>    vNoData = CSng(dZMin - 1)<BR>  Else<BR>    vNoData = CLng(dZMin - 1)<BR>  End If<BR>  <BR>  pRasterProps.NoDataValue = vNoData<BR>    <BR>  Dim pOffset As IPnt<BR>  Set pOffset = New DblPnt<BR>  <BR>  ' Set blocksize. Restrict how large it is as not to consume too much memory for<BR>  ' big output datasets.<BR>  Dim lMaxBlockX As Long<BR>  lMaxBlockX = 2048<BR>  If (nCol < lMaxBlockX) Then<BR>    lMaxBlockX = nCol<BR>  End If<BR>  <BR>  Dim lMaxBlockY As Long<BR>  lMaxBlockY = 2048<BR>  If (nRow < lMaxBlockY) Then<BR>    lMaxBlockY = nRow<BR>  End If<BR>  <BR>  Dim pBlockSize As IPnt<BR>  Set pBlockSize = New DblPnt<BR>  pBlockSize.X = lMaxBlockX<BR>  pBlockSize.Y = lMaxBlockY<BR>    <BR>  Dim pPixelBlock As IPixelBlock3<BR>  Set pPixelBlock = pRawPixels.CreatePixelBlock(pBlockSize)<BR>    <BR>  Dim blockArray As Variant<BR>  blockArray = pPixelBlock.PixelDataByRef(0)<BR>  <BR>  ' Set up cancel tracking and progress bar<BR>  Dim pCancel As ITrackCancel<BR>  Set pCancel = New CancelTracker<BR>  pCancel.CancelOnClick = False<BR>  pCancel.CancelOnKeyPress = True<BR>  Dim pApp As IApplication<BR>  Set pApp = New AppRef<BR>  Dim pProg As IStepProgressor<BR>  Set pProg = pApp.StatusBar.ProgressBar<BR>  pCancel.Progressor = pProg<BR>  Dim lBlockCount As Long<BR>  lBlockCount = Round((nCol / lMaxBlockX) + 0.49) * Round((nRow / lMaxBlockY) + 0.49)<BR>  pProg.Message = "Rasterizing. Press ESC to cancel..."<BR>  pProg.Position = 0<BR>  If (lBlockCount = 1) Then ' tin querypixelblock can do the tracking/progressing with 1 block<BR>    pProg.Show<BR>    Set pTin.TrackCancel = pCancel<BR>  Else ' more than 1 block requires this routine, rather than tin function, to track/progress<BR>    pProg.MinRange = 0<BR>    pProg.MaxRange = lBlockCount<BR>    pProg.StepValue = 1<BR>    pProg.Show<BR>  End If<BR>  DoEvents ' make sure the bar and the text get updated on screen<BR>  <BR>  Dim pBlockOrigin As IPoint<BR>  Set pBlockOrigin = New Point<BR>  <BR>  Dim lColOffset As Long<BR>  Dim lRowOffset As Long<BR>        <BR>  ' Left to right, top to bottom, iteration of pixel blocks.<BR>  For lRowOffset = 0 To (nRow - 1) Step lMaxBlockY<BR>  <BR>    For lColOffset = 0 To (nCol - 1) Step lMaxBlockX<BR>  <BR>      ' See if pixelblock needs to be resized in X for last column chunk.<BR>      ' RawPixel.Write will clip the pixelblock if it's too big, so the resize<BR>      ' isn't absolutely necessary, but resizing will eliminate unecessary<BR>      ' effort for TIN's QueryPixelBlock.<BR>      If ((nCol - lColOffset) < lMaxBlockX) Then<BR>        pBlockSize.X = (nCol - lColOffset)<BR>        Set pPixelBlock = pRawPixels.CreatePixelBlock(pBlockSize)<BR>        blockArray = pPixelBlock.PixelDataByRef(0)<BR>      End If<BR>            <BR>      ' QueryPixelBlock takes an origin representing the upper left cell center.<BR>      ' Calculate that cell center's position here. Calculate it based on the<BR>      ' raster's origin (lower left) and current row/col offset.<BR>      pBlockOrigin.X = pOrigin.X + (lColOffset * cellsize) + (cellsize * 0.5)<BR>      pBlockOrigin.Y = pOrigin.Y + ((nRow - lRowOffset) * cellsize) - (cellsize * 0.5)<BR>      <BR>      pTinSurf.QueryPixelBlock pBlockOrigin.X, pBlockOrigin.Y, cellsize, cellsize, eRastConvType, vNoData, blockArray<BR>                      <BR>      pOffset.X = lColOffset<BR>      pOffset.Y = lRowOffset<BR>      <BR>      ' The offset for 'write' is the upper left of the pixel block by col/row number.<BR>      ' Base is 0.<BR>      pRawPixels.Write pOffset, pPixelBlock<BR>                  <BR>      If (lBlockCount > 1) Then<BR>        If (Not pCancel.Continue) Then GoTo Cancel<BR>      Else<BR>        If (pTin.ProcessCancelled) Then GoTo Cancel<BR>      End If<BR>      <BR>    Next lColOffset<BR>    <BR>    ' See if pixelblock size needs to be reset for columns<BR>    Dim bReset As Boolean<BR>    bReset = False<BR>    If (pBlockSize.X <> lMaxBlockX) Then<BR>      pBlockSize.X = lMaxBlockX<BR>      bReset = True<BR>    End If<BR>      <BR>    ' See if pixelblock size needs to be reset for rows<BR>    If ((nRow - lRowOffset) < lMaxBlockY) Then<BR>      pBlockSize.Y = (nRow - lRowOffset)<BR>      bReset = True<BR>    End If<BR>        <BR>    If (bReset) Then<BR>      Set pPixelBlock = pRawPixels.CreatePixelBlock(pBlockSize)<BR>      blockArray = pPixelBlock.PixelDataByRef(0)<BR>    End If<BR>        <BR>  Next lRowOffset<BR>            <BR>  'pProg.Message = "Returning cache..."<BR>  pRawPixels.ReturnCache pCache<BR>  Set pCache = Nothing<BR>  <BR>  ' need this for some reason with temporary integer grids<BR>  'If (Not bPerm) And (ePixelType = PT_LONG) Then<BR>'    pProg.Message = "Stats..."<BR>'    Dim pBand As iRasterBand<BR>'    Set pBand = pRawPixels<BR>'    Dim pStats As IRasterStatistics<BR>'    Set pStats = pBand.Statistics<BR>'    pStats.Recalculate<BR>  'End If<BR>  <BR>  'If (bPerm) Then<BR>    ' flush edits to disk by freeing all pointers<BR>    'pProg.Message = "Freeing and opening..."<BR>    Set pRDS = Nothing<BR>    Set pRawPixels = Nothing<BR>    Set pPixelBlock = Nothing<BR>    Set pRasterProps = Nothing<BR>    blockArray = 0<BR>    Set pRDS = OpenRasterDataset(sDir, sName)<BR>  'End If<BR>  <BR>  pApp.StatusBar.HideProgressBar<BR>  <BR>  If (lBlockCount = 1) Then<BR>    Set pTin.TrackCancel = Nothing<BR>  End If<BR>  <BR>  Set TinToRaster = pRDS<BR>  Exit Function<BR>  <BR>Cancel:<BR>  pApp.StatusBar.HideProgressBar<BR>  Set TinToRaster = Nothing<BR>End Function</P>
<P>Public Function OpenRasterDataset(sDir As String, sFile As String) As IRasterDataset</P>
<P>    'Open the raster dataset with the given name.<BR>    'sDir is the directory the file resides<BR>    'sFile is the filename<BR>    <BR>    Dim pWsFact As IWorkspaceFactory<BR>    Dim pWs As IRasterWorkspace<BR>    Dim pRasterDataset As IRasterDataset</P>
<P><BR>    'Open the workspace<BR>    Set pWsFact = New RasterWorkspaceFactory<BR>    Set pWs = pWsFact.OpenFromFile(sDir, 0)</P>
<P>    <BR>    'Open the raster dataset<BR>    Set pRasterDataset = pWs.OpenRasterDataset(sFile)</P>
<P><BR>    'Return<BR>    Set OpenRasterDataset = pRasterDataset</P>
<P>    Set pWsFact = Nothing<BR>    Set pWs = Nothing<BR>    Set pRasterDataset = Nothing</P>
<P>End Function<BR><BR>Public Function GetRawPixels(pRDS As IRasterDataset, band As Long) As IRawPixels<BR>    <BR>    Dim pBandCollection As IRasterBandCollection<BR>    Set pBandCollection = pRDS<BR>    <BR>    Dim pRasterBand As IRasterBand<BR>    Set pRasterBand = pBandCollection.Item(band)<BR>    <BR>    Set GetRawPixels = pRasterBand<BR>    <BR>End Function</P>
<P>Public Function CreateRasterSurf(ByVal sDir As String, ByVal sName As String, ByVal sFormat As String, _<BR>ByVal pOrigin As IPoint, ByVal nCol As Long, ByVal nRow As Long, ByVal cellsizeX As Double, ByVal cellsizeY As Double, _<BR>ByVal ePixelType As rstPixelType, ByVal pSR As ISpatialReference2, ByVal bPerm As Boolean) As IRasterDataset</P>
<P>    Dim rWksFac As IWorkspaceFactory<BR>    Set rWksFac = New RasterWorkspaceFactory</P>
<P>    Dim wks As IWorkspace<BR>    Set wks = rWksFac.OpenFromFile(sDir, 0)</P>
<P>    Dim rWks As IRasterWorkspace2<BR>    Set rWks = wks</P>
<P>    Dim numbands As Long<BR>    numbands = 1</P>
<P>    Dim pRDS As IRasterDataset<BR>    Set pRDS = rWks.CreateRasterDataset(sName, sFormat, pOrigin, nCol, nRow, cellsizeX, cellsizeY, numbands, ePixelType, pSR, bPerm)</P>
<P>    Set CreateRasterSurf = pRDS<BR>    <BR>End Function<BR></P>
喜欢0 评分0
knight_sl
路人甲
路人甲
  • 注册日期2004-08-11
  • 发帖数21
  • QQ
  • 铜币161枚
  • 威望0点
  • 贡献值0点
  • 银元0个
1楼#
发布于:2007-09-20 09:49
TIN图层是好好的,没有什么问题,但是raster生成出来就是不能看,麻烦哪位大侠给个建议吧!~
举报 回复(0) 喜欢(0)     评分
追风浪子
路人甲
路人甲
  • 注册日期2004-06-08
  • 发帖数166
  • QQ
  • 铜币782枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2007-09-20 16:08
有本ARCOBJECTS二次开发上有关vc处理tin to raster的程序,你可以看看
举报 回复(0) 喜欢(0)     评分
游客

返回顶部