利用ArcSDE C API读取ArcSDE Raster数据

关于ArcSDE Raster的一些资料可以参见合金枪头的关于 ArcSDE影像数据管理的系列文章。

本文包括访问ArcSDE Raster数据的三个应用,代码只是片段抽取,但是已经包括了该功能的所有代码。

1、获取ArcSDE中Raster数据列表
1  struct  SdeRasterTableInfo
2  {
3       char  TableName[SE_QUALIFIED_TABLE_NAME];
4       char  RasterColumnName[SE_MAX_COLUMN_LEN];
5  };

 1  bool  GetSdeRasterCatalog(SE_CONNECTION pConnection, std::vector < SdeRasterTableInfo >   & rasterTables)
 2  {
 3      SE_RASCOLINFO  * pRasterColumnList  =   0 ;
 4       if  (SE_rastercolumn_get_info_list(pConnection,  & pRasterColumnList,  & lRasterColumnCount)  !=  SE_SUCCESS)
 5           return   false ;
 6 
 7       for  ( int  i  =   0 ; i  <  lRasterColumnCount; i ++ )
 8      {
 9           long  privileges  =   0 ;
10           if  (SE_rascolinfo_get_access (pRasterColumnList[i],  & privileges)  !=  SE_SUCCESS)
11               continue ;
12 
13           if  ( ! (privileges  &  SE_SELECT_PRIVILEGE))
14               continue ;
15 
16          SdeRasterTableInfo rasterTableInfo;
17 
18           //  Get the raster table name and column name.
19           if  (SE_rascolinfo_get_raster_column (pRasterColumnList[i],
20              rasterTableInfo.TableName, rasterTableInfo.RasterColumnName)  !=  SE_SUCCESS)
21               continue ;
22          
23          rasterTables.push_back(rasterTableInfo);
24      }
25 
26      SE_rastercolumn_free_info_list (lRasterColumnCount, pRasterColumnList);
27      
28       return   true ;
29  }


2、获取指定Raster数据的元数据
 1  struct  SdeRasterSpec
 2  {
 3       long    ImageWidth;
 4       long    ImageHeight;
 5      
 6       double  OriginX;
 7       double  OriginY;
 8      
 9       double  MinX;
10       double  MinY;
11       double  MaxX;
12       double  MaxY;
13  };

  1  LONG GetSdeRasterSpec(SE_CONNECTION pConnection, 
  2       const   string &  tableName,  const   string &  rasterColumn,  const   string &   where
  3      SdeRasterSpec  & rasterSpec)
  4  {
  5       //  Get raster column info.
  6      SE_RASCOLINFO rasColInfo  =   0 ;
  7      LONG rc  =  SE_rascolinfo_create( & rasColInfo);
  8       if  (rc  !=  SE_SUCCESS)
  9           return  rc;
 10 
 11      LONG rasterColumnId  =   0 ;
 12 
 13       do
 14      {
 15          rc  =  SE_rastercolumn_get_info_by_name(pConnection, tableName.c_str(), rasterColumn.c_str(), rasColInfo);
 16           if  (rc  !=  SE_SUCCESS)
 17               break ;
 18 
 19           //  Get raster column ID.
 20          rc  =  SE_rascolinfo_get_id(rasColInfo,  & rasterColumnId);
 21           if  (rc  !=  SE_SUCCESS)
 22               break ;
 23      }
 24       while ( 0 );
 25 
 26      SE_rascolinfo_free(rasColInfo);
 27 
 28       if  (rc  !=  SE_SUCCESS)
 29           return  rc;
 30 
 31       //  Get raster ID.
 32      LONG rasterId  =   - 1 ;
 33      rc  =  FetchRasterID(pConnection, tableName, rasterColumn,  where & rasterId);
 34       if  (rasterId  ==   - 1 )
 35           return  rc;
 36 
 37       //  Get raster info.
 38      SE_RASTERINFO rasterInfo  =   0 ;
 39      rc  =  SE_rasterinfo_create( & rasterInfo);
 40       if  (rc  !=  SE_SUCCESS)
 41           return  rc;
 42 
 43      rc  =  SE_raster_get_info_by_id(pConnection, rasterColumnId, rasterId, rasterInfo);
 44       if  (rc  !=  SE_SUCCESS)
 45      {
 46          SE_rasterinfo_free(rasterInfo);
 47           return  rc;
 48      }
 49 
 50       //  Get raster band info list.
 51      SE_RASBANDINFO  * rasterBands  =   0 ;
 52      LONG bandCount  =   0 ;
 53      rc  =  SE_raster_get_bands(pConnection, rasterInfo,  & rasterBands,  & bandCount);
 54       if  (rc  !=  SE_SUCCESS)
 55      {
 56          SE_rasterinfo_free (rasterInfo);
 57           return  rc;
 58      }
 59 
 60      SE_rasterinfo_free(rasterInfo);
 61 
 62       //  Get the raster band size and origin.
 63      LFLOAT bandOriginX  =   0.0 , bandOriginY  =   0.0 ;
 64      LONG bandWidth  =   0 , bandHeight  =   0 ;
 65      SE_ENVELOPE rasterEnv;
 66       if  (bandCount  >   0 )
 67      {
 68          rc  =  SE_rasbandinfo_get_tile_origin(rasterBands[ 0 ],  & rasterSpec.OriginX,  & rasterSpec.OriginY);
 69 
 70           if  (rc  ==  SE_SUCCESS)
 71              rc  =  SE_rasbandinfo_get_band_size (rasterBands[ 0 ],  & rasterSpec.ImageWidth,  & rasterSpec.ImageHeight);
 72 
 73           if  (rc  ==  SE_SUCCESS)
 74              rc  =  SE_rasbandinfo_get_extent (rasterBands[ 0 ],  & rasterEnv);
 75      }
 76 
 77      SE_rasterband_free_info_list(bandCount, rasterBands);
 78 
 79       if  (rc  ==  SE_SUCCESS)
 80      {
 81          rasterSpec.MinX  =  rasterEvn.minx;
 82          rasterSpec.MinY  =  rasterEvn.miny;
 83          rasterSpec.MaxX  =  rasterEvn.maxx;
 84          rasterSpec.MaxY  =  rasterEvn.maxy;
 85      }
 86 
 87       return  rc;
 88  }
 89 
 90  LONG FetchRasterID (SE_CONNECTION pConnection,  const   string &  tableName, 
 91       const   string &  rasterColumn,  const   string &   where , LONG  * rasterId) 
 92  {
 93       * rasterId  =   - 1 ;
 94 
 95      SE_STREAM stream  =   0 ;
 96      LONG rc  =  SE_stream_create (pConnection,  & stream);
 97       if  (rc  !=  SE_SUCCESS)
 98           return  rc;
 99 
100       //  Set up SQL statement.
101      CHAR sqlstmt[ 128 ];
102       if  ( where .empty())
103          sprintf (sqlstmt, " SELECT %s FROM %s " , rasterColumn.c_str(), tableName.c_str());
104       else
105          sprintf (sqlstmt, " SELECT %s FROM %s WHERE %s " , rasterColumn.c_str(), tableName.c_str(),  where .c_str());
106 
107       do
108      {
109          rc  =  SE_stream_prepare_sql (stream, sqlstmt);
110           if  (rc  !=  SE_SUCCESS)
111               break ;
112 
113           //  Bind the rasterId variable to receive the output of the stream.
114          SHORT raster_ind =  SE_IS_NULL_VALUE;
115          rc  =  SE_stream_bind_output_column (stream,  1 , ( void   * )rasterId,  & raster_ind);
116           if  (rc  !=  SE_SUCCESS)
117               break ;
118 
119           //  Execute the query.
120          rc  =  SE_stream_execute (stream);
121           if  (rc  !=  SE_SUCCESS)
122               break ;
123 
124           //  Fetch the result from the cursor.
125          rc  =  SE_stream_fetch (stream);
126           if  (rc  ==  SE_SUCCESS  ||  rc  ==  SE_FINISHED) 
127          {
128               //  If the query sets the indicator to NULL.
129               if  (raster_ind  ==  SE_IS_NULL_VALUE) 
130                   * rasterId  =   - 1 ;
131          }
132      }
133       while ( 0 );
134 
135      SE_stream_free (stream);
136 
137       return  rc;
138  }


3、读取指定范围的Raster数据,并输出为PNG格式
  1  #ifndef __SDERASTERCLIP_H__
  2  #define  __SDERASTERCLIP_H__
  3 
  4  #include  " sderaster.h "
  5  #include  " png.h "                           //  for libpng
  6 
  7  class  CSdeRasterClip
  8  {
  9  public :
 10      CSdeRasterClip( int  nClipWidth,  int  nClipHeight,  int  nSourceWidth,  int  nSourceHeight)
 11      {
 12          m_pBuffer  =   0 ;
 13          
 14          m_nClipWidth  =  nClipWidth;
 15          m_nClipHeight  =  nClipHeight;
 16          m_nSourceWidth  =  nSourceWidth;
 17          m_nSourceHeight  =  nSourceHeight;
 18      }
 19 
 20       ~ CSdeRasterClip()
 21      {
 22          delete[] m_pBuffer;
 23      }
 24 
 25       bool  Clip(SE_CONNECTION pConnection, 
 26           const   string &  tableName,  const   string &  rasterColumn,  const   string &   where )
 27      {
 28           bool  bSuccess  =   false ;
 29 
 30           try
 31          {
 32              LONG rc  =  ClipImage(pConnection, tableName, rasterColumn,  where );
 33               if  (rc  ==  SE_SUCCESS)
 34              {
 35                  unsigned  char   ** pRow  =  (unsigned  char   ** )m_pBuffer;
 36              
 37                   //  Write image buffer to png stream.
 38                   return  WritePNG (pRow, m_nImageWidth, m_nImageHeight,  8 , PNG_COLOR_TYPE_RGB);
 39              }
 40          }
 41           catch  ( const   char   * msg)
 42          {
 43               //
 44          }
 45           catch  ()
 46          {
 47               //
 48          }
 49 
 50           return   false ;
 51      }
 52 
 53  private :
 54 
 55      LONG ClipImage(CXrbStream  & tStream, SE_CONNECTION pConnection, 
 56           const   string &  tableName,  const   string &  rasterColumn,  const   string &   where )
 57      {
 58           //  Create the queryinfo structure
 59          SE_QUERYINFO queryinfo  =   0 ;
 60          LONG rc  =  SE_queryinfo_create ( & queryinfo);
 61           if  (rc  !=  SE_SUCCESS)
 62          {
 63               return  rc;
 64          }
 65 
 66           do
 67          {
 68               //  Set query tables.
 69               const  CHAR  * tables[ 1 ];
 70              tables[ 0 ] =  tableName.c_str();
 71 
 72              rc  =  SE_queryinfo_set_tables (queryinfo,  1 , tables, NULL); 
 73               if  (rc  !=  SE_SUCCESS)
 74                   break ;
 75 
 76               //  Set query columns.
 77               const  CHAR  * columns[ 1 ];
 78              columns[ 0 =  rasterColumn.c_str();
 79 
 80              rc  =  SE_queryinfo_set_columns (queryinfo,  1 , columns); 
 81               if  (rc  !=  SE_SUCCESS)
 82                   break ;
 83 
 84               //  Set query where clause.
 85               if  ( ! where .empty())
 86              {
 87                  rc  =  SE_queryinfo_set_where_clause(queryinfo,  where .c_str());
 88                   if  (rc  !=  SE_SUCCESS)
 89                       break ;
 90              }
 91          }
 92           while ( 0 );
 93 
 94           if  (rc  !=  SE_SUCCESS)
 95          {
 96              SE_queryinfo_free (queryinfo);
 97               return  rc;
 98          }
 99 
100           //  Create query stream
101          SE_STREAM stream  =   0 ;
102          rc  =  SE_stream_create (pConnection,  & stream);
103           if  (rc  !=  SE_SUCCESS)
104          {
105              SE_queryinfo_free (queryinfo);
106               return  rc;
107          }
108 
109           //  initializes query stream using query info.
110          rc  =  SE_stream_query_with_info (stream, queryinfo);
111           if  (rc  !=  SE_SUCCESS)
112          {
113              SE_queryinfo_free (queryinfo);
114              SE_stream_free (stream);
115               return  rc;
116          }
117 
118          SE_queryinfo_free (queryinfo);
119 
120          SE_RASTERATTR raster_attrib  =   0 ;
121          rc  =  SE_rasterattr_create ( & raster_attrib, FALSE);
122           if  (rc  !=  SE_SUCCESS)
123          {
124              SE_stream_free (stream);
125               return  rc;
126          }
127 
128           //  Bind the rasterId variable to receive the output of the stream.
129          SHORT raster_ind =  SE_IS_NULL_VALUE;
130          rc  =  SE_stream_bind_output_column (stream,  1 , raster_attrib,  & raster_ind);
131           if  (rc  !=  SE_SUCCESS)
132          {
133              SE_stream_free (stream);
134              SE_rasterattr_free (raster_attrib);
135               return  rc;
136          }
137 
138           //  Execute the query.
139          rc  =  SE_stream_execute (stream);
140           if  (SE_SUCCESS  ==  rc) 
141          {
142               //  Fetch each record of the business table  //
143              rc  =  SE_stream_fetch (stream);
144 
145               if  (SE_FINISHED  !=  rc) 
146              { 
147                   if  (raster_ind  ==  SE_IS_NOT_NULL_VALUE)
148                  {
149                      rc  =  GetRasterData(pConnection, stream, raster_attrib);
150                  }
151              }
152          }
153 
154          SE_stream_free (stream);
155          SE_rasterattr_free (raster_attrib);
156 
157           return  rc;
158      }
159 
160      LONG GetRasterData(SE_CONNECTION connection, SE_STREAM stream, SE_RASTERATTR raster_attrib)
161      {
162           //  determine number of images in pyramid
163          BOOL bSkipLevel  =  TRUE;
164          LONG nPyramidSize  =   0 ;
165          LONG rc  =  SE_rasterattr_get_max_level ( raster_attrib,  & nPyramidSize,  & bSkipLevel);
166           if  (rc  !=  SE_SUCCESS)
167               return  rc;
168 
169           //  determine which image should be used
170           int  nLevel  =  GetPyramidLevel(nPyramidSize);
171 
172          SE_ENVELOPE raster_env;
173          LFLOAT dOffsetX  =   0.0 , dOffsetY  =   0.0 ;
174 
175          rc  =  SE_rasterattr_get_extent_by_level (raster_attrib,  & raster_env,  & dOffsetX, 
176               & dOffsetY, nLevel);
177           if  (rc  !=  SE_SUCCESS)
178               return  rc;
179 
180          rc  =  SE_rasterattr_get_tile_size (raster_attrib,  & m_nTileWidth,  & m_nTileHeight);
181           if  (rc  !=  SE_SUCCESS)
182               return  rc;
183 
184          LONG nBandsCount  =   0 ;
185          LONG nSourceImageWidth  =   0 ;
186          LONG nSourceImageHeight  =   0 ;
187          LONG nSourceImageOffsetX  =   0 ;
188          LONG nSourceImageOffsetY  =   0 ;
189          rc  =  SE_rasterattr_get_image_size_by_level(raster_attrib, 
190               & nSourceImageWidth, 
191               & nSourceImageHeight, 
192               & nSourceImageOffsetX,
193               & nSourceImageOffsetY,
194               & nBandsCount,
195              nLevel);
196           if  (rc  !=  SE_SUCCESS)
197               return  rc;
198 
199           //  calculate the pixel cell size in world coordinates
200          LFLOAT nCellSize  =  (raster_env.maxx  -  raster_env.minx)  /  (nSourceImageWidth  -   1 );
201 
202          LONG nPixelType;
203          rc  =  SE_rasterattr_get_pixel_type (raster_attrib,  & nPixelType);
204           if  (rc  !=  SE_SUCCESS)
205               return  rc;
206 
207           //  Dot not support other pixel type now.
208           if  (nPixelType  !=  SE_PIXEL_TYPE_8BIT_U) 
209               return  SE_FAILURE;
210 
211           //  compute the real world coordinate width and height
212          LFLOAT coord_tile_width  =  nCellSize  *  m_nTileWidth;
213          LFLOAT coord_tile_height  =  nCellSize  *  m_nTileHeight;
214 
215          LONG pixels_per_tile  =  m_nTileWidth  *  m_nTileHeight;
216 
217           //  The testing code only request the full image.
218          LONG minx  =  raster_env.minx;
219          LONG maxx  =  raster_env.maxx;
220          LONG miny  =  raster_env.miny;
221          LONG maxy  =  raster_env.maxy;
222 
223          LONG relminx  =  (LONG) ((minx  -  (raster_env.minx  -  dOffsetX))  /  coord_tile_width); 
224          LONG relmaxx  =  (LONG) ((maxx  -  (raster_env.minx  -  dOffsetX))  /  coord_tile_width);
225          LONG relminy  =  (LONG) (((raster_env.maxy  +  dOffsetY)  -  maxy)  /  coord_tile_height);
226          LONG relmaxy  =  (LONG) (((raster_env.maxy  +  dOffsetY)  -  miny)  /  coord_tile_height);
227 
228          LONG nNumTilesX  =  relmaxx  -  relminx  +   1 ;
229          LONG nNumTilesY  =  relmaxy  -  relminy  +   1 ;
230 
231          m_nImageWidth  =  nNumTilesX  *  m_nTileWidth;
232          m_nImageHeight  =  nNumTilesY  *  m_nTileHeight;
233          
234          rc  =  SE_rasterattr_get_num_bands (raster_attrib,  & nBandsCount);
235           if  (rc  !=  SE_SUCCESS)
236               return  rc;
237 
238           // if (nBandsCount != 1 && nBandsCount != 3)
239           //     return;
240 
241          
242          SE_RASCONSTRAINT rasconstraint  =   0 ;
243          rc  =  SE_rasconstraint_create ( & rasconstraint);
244           if  (rc  !=  SE_SUCCESS)
245               return  rc;
246 
247          SE_RASTILEINFO rastile_info  =   0 ;
248          rc  =  SE_rastileinfo_create ( & rastile_info);
249           if  (rc  !=  SE_SUCCESS)
250          {
251              SE_rasconstraint_free (rasconstraint);
252               return  rc;
253          }
254 
255           do
256          {
257              rc  =   SE_rasconstraint_set_envelope (rasconstraint, relminx, relminy, relmaxx, relmaxy);
258               if  (rc  !=  SE_SUCCESS)
259                   break ;
260 
261              LONG aBandArray[ 3 =  { 1 , 2 , 3 };
262 
263              rc  =  SE_rasconstraint_set_bands ( rasconstraint, nBandsCount, aBandArray);
264               if  (rc  !=  SE_SUCCESS)
265                   break ;
266 
267              rc  =  SE_rasconstraint_set_interleave (rasconstraint, SE_RASTER_INTERLEAVE_BSQ);
268               if  (rc  !=  SE_SUCCESS)
269                   break ;
270 
271              rc  =  SE_rasconstraint_set_level (rasconstraint, nLevel);
272               if  (rc  !=  SE_SUCCESS)
273                   break ;
274 
275              rc  =  SE_stream_query_raster_tile (stream, rasconstraint);
276               if  (rc  !=  SE_SUCCESS)
277                   break ;
278          }
279           while ( 0 );
280 
281           if  (rc  !=  SE_SUCCESS)
282          {
283              SE_rasconstraint_free (rasconstraint);
284              SE_rastileinfo_free (rastile_info);
285               return  rc;
286          }
287 
288           int  nBitesPerPixel  =  nPixelType  >>   3 ;
289 
290           int  nImageBytesPerPixel  =   3 ;
291           //  bytes across source tile
292           int  nTileByteWidth  =  (m_nTileWidth  *  nBitesPerPixel  +   7 /   8 ; // m_nTileWidth;
293           //  bytes across tile when copied to output image buffer
294           int  nBufferTileByteWidth  =  m_nTileWidth  *  nImageBytesPerPixel;
295           //  width of output buffer in bytes
296           int  nBufferByteWidth  =  nBufferTileByteWidth  *  nNumTilesX;
297 
298           //  bytes in output buffer for complete row of tiles
299           int  nBufferTileByteRow  =  nBufferByteWidth  *  m_nTileHeight;
300 
301           if  (m_pBuffer  !=   0 ) delete[] m_pBuffer;
302 
303          m_pBuffer  =   new  unsigned  char [(m_nImageHeight  *   sizeof ( char * ))  +  (nBufferTileByteRow  *  nNumTilesY)];
304 
305           //  create pointer to actual image data
306          unsigned  char   * pBufferImage  =  m_pBuffer  +  (m_nImageHeight  *   sizeof ( char * ));
307 
308           //  create pointer to tile buffer
309          unsigned  char   * pSingleTile  =  NULL;
310 
311          LONG length  =   0 ;
312          LONG rasterband_id  =   0 ;
313          LONG row  =   0 ;
314          LONG column  =   0 ;
315 
316           while  (rc  ==  SE_SUCCESS)
317          {
318              rc  =  SE_stream_get_raster_tile (stream, rastile_info);
319               if  (rc  !=  SE_SUCCESS)
320                   break ;
321 
322              rc  =  SE_rastileinfo_get_band_id (rastile_info,  & rasterband_id);
323               if  (rc  !=  SE_SUCCESS)
324                   break ;
325 
326              rc  =  SE_rastileinfo_get_rowcol (rastile_info,  & row,  & column);
327               if  (rc  !=  SE_SUCCESS)
328                   break ;
329 
330              rc  =  SE_rastileinfo_get_pixel_data (rastile_info, ( void ** ) & pSingleTile,  & length);
331               if  (rc  !=  SE_SUCCESS)
332                   break ;
333 
334              unsigned  char   * pDst  =  pBufferImage  +  row  *  nBufferTileByteRow  +  column  *  nBufferTileByteWidth;
335              unsigned  char   * pSrc  =  pSingleTile;
336               for  ( int  k  =   0 ; k  <  m_nTileHeight; k ++ )
337              {
338                  ExpandBits(pDst, pSrc, pSrc  +  nTileByteWidth, rasterband_id  %   3 );
339 
340                  pSrc  +=  nTileByteWidth;
341                  pDst  +=  nBufferByteWidth;
342              }
343          }
344 
345          SE_rasconstraint_free (rasconstraint);
346          SE_rastileinfo_free (rastile_info);
347 
348           if  (rc  ==  SE_FINISHED)
349              rc  =  SE_SUCCESS;
350 
351           //  Create array of row pointers at beginning of buffer for png write.
352           if  (rc  ==  SE_SUCCESS)
353          {
354              unsigned  char   ** pCurPtr  =  (unsigned  char   ** )m_pBuffer;
355              unsigned  char   ** pEndPtr  =  pCurPtr  +  m_nImageHeight;
356              unsigned  char   * pCurSrc  =  pBufferImage;
357 
358               while  (pCurPtr  <  pEndPtr)
359              {
360                   * pCurPtr  =  pCurSrc;
361                  pCurSrc  +=  nBufferByteWidth;
362                  pCurPtr ++ ;
363              }
364          }
365 
366           return  rc;
367      }
368 
369       void  ExpandBits(unsigned  char   * pDst, unsigned  char   * pSrc, unsigned  char   * pEndSrc,  int  nBits)
370      {
371          unsigned  char   * pCurSrc  =  pSrc;
372          unsigned  char   * pCurDst  =  pDst;
373          unsigned  char  pixel;
374 
375           switch  (nBits)
376          {
377           case   1 // r
378               for  (; pCurSrc < pEndSrc; pCurSrc ++ )
379              {
380                  pixel  =   * pCurSrc;
381 
382                   * pCurDst  =  pixel  &   0xff ;
383                  pCurDst ++ ;
384                   * pCurDst  =   0 ;
385                  pCurDst ++ ;
386                   * pCurDst  =   0 ;
387                  pCurDst ++ ;
388              }
389               break ;
390 
391           case   2 // g
392               for  (; pCurSrc < pEndSrc; pCurSrc ++ )
393              {
394                  pixel  =   * pCurSrc;
395                  pCurDst ++ ;
396                   * pCurDst  =  pixel  &   0xff ;
397                  pCurDst ++ ;
398                   * pCurDst  =   0 ;
399                  pCurDst ++ ;
400              }
401               break ;
402 
403           case   3 // b
404               for  (; pCurSrc < pEndSrc; pCurSrc ++ )
405              {
406                  pixel  =   * pCurSrc;
407                  pCurDst ++ ;
408                  pCurDst ++ ;
409                   * pCurDst  =  pixel  &   0xff ;
410                  pCurDst ++ ;
411              }
412               break ;
413 
414           default :
415               break ;
416          }
417      }
418 
419       /**//* *
420       * Get the zero-based index to the pyramid image that best fits the dimensions
421       * @return index in the pyramid
422        */
423       int  GetPyramidLevel( int  nMaxLevel)
424      {
425           int  nWidthRatio  =  m_nSourceWidth / m_nClipWidth;
426           int  nHeightRatio  =  m_nSourceHeight / m_nClipHeight;
427           int  nRatio  =  (nWidthRatio  <  nHeightRatio) ?  nWidthRatio : nHeightRatio;
428           int  nLevel  =   0 ;
429           while  (nRatio  >>=   1 ) nLevel ++ ;
430           if  (nLevel  >  nMaxLevel)  return  nMaxLevel;
431           return  nLevel;
432      }
433 
434       static   void  stdio_write_func (png_structp png, png_bytep data, png_size_t size)
435      {
436          FILE  * fp;
437 
438          fp  =  (FILE  * )png_get_io_ptr (png);
439           while  (size) {
440          size_t ret  =  fwrite (data,  1 , size, fp);
441          size  -=  ret;
442          data  +=  ret;
443           if  (size  &&  ferror (fp))
444              png_error(png,  " Write Error " );
445          }
446      }
447 
448       bool  WritePNG(  const   char   * outputFile, unsigned  char   ** pRows, 
449           int  nWidth,  int  nHeight,  int  nBitDepth, 
450           int  nColorType,  int  nFilterType  =  PNG_FILTER_TYPE_DEFAULT) 
451      {
452          png_structp   pPngPtr  =   0 ;
453          png_infop     pInfoPtr  =   0 ;
454 
455          FILE  * fp  =   0 ;
456 
457          fp  =  fopen (outputFile,  " wb " );
458           if  (fp  ==   0 )
459               return   false ;
460 
461 
462          pPngPtr  =  png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,  0 0 );
463           if  (pPngPtr)
464          {
465              pInfoPtr  =  png_create_info_struct(pPngPtr);
466               if  (pInfoPtr)
467              {
468                  png_set_IHDR(pPngPtr, pInfoPtr, nWidth, nHeight,
469                          nBitDepth, nColorType, PNG_INTERLACE_NONE,
470                          PNG_COMPRESSION_TYPE_DEFAULT, nFilterType);
471 
472                   //  set up write functions
473                  png_set_write_fn(pPngPtr, fp, stdio_write_func, NULL);
474 
475                   //  write header
476                  png_write_info(pPngPtr, pInfoPtr);
477 
478                  png_color_16 white;
479                  white.red  =   0xff ;
480                  white.blue  =   0xff ;
481                  white.green  =   0xff ;
482 
483                  png_set_bKGD (pPngPtr, pInfoPtr,  & white);
484 
485                   //  write image
486                  png_write_image(pPngPtr, pRows);
487 
488                   //  finish write
489                  png_write_end(pPngPtr,  0 );
490 
491                   //  destroy structures
492                  png_destroy_write_struct( & pPngPtr,  & pInfoPtr);
493 
494                  fclose (fp);
495                   return   true ;
496              }
497               else
498              {
499                  png_destroy_write_struct( & pPngPtr,  & pInfoPtr);
500                  fclose (fp);
501 
502              }
503          }
504           return   false ;
505      }
506 
507       /**//* * Buffer for image data.  */
508      unsigned  char   * m_pBuffer;
509 
510      LONG m_nTileWidth;
511      LONG m_nTileHeight;
512      
513       int  m_nImageWidth;
514       int  m_nImageHeight;
515 
516       int  m_nClipWidth;
517       int  m_nClipHeight;
518       int  m_nSourceWidth;
519       int  m_nSourceHeight;
520  };
521 
522  #endif   // __SDERASTERCLIP_H__


:本来这篇本章很早就写了,但是一直没有时间来总结一下,现在开始着手三维GIS方面的开发,看来以后一段时间将更加忙,也没有时间来更新Blog了,所以干脆将这篇草稿直接发布了,也许对一些有需要的朋友所有帮助。

转载于:https://www.cnblogs.com/avlee/archive/2007/08/27/arcsderaster.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值