赞
踩
1、祥读该方法的原因 (该方法有误)
最近在项目中用到了MapwinGIS中的
ClipGridWithPolygon (string inputGridfile, Shape poly, string resultGridfile, bool keepExtents)
和
ClipGridWithPolygon2 (Grid inputGrid, Shape poly, string resultGridfile, bool keepExtents)
但在我使用的时候,poly 在Grid内时没有任何问题,但 poly 的一部分在Grid外时,例如下面这种情况
就会报:
DEBUG: Image: Index Out of Bounds 错误。
查看元数据,发现只能看c++代码了。
看c中代码,你会发现 ClipGridWithPolygon (string inputGridfile, Shape poly, string resultGridfile, bool keepExtents) 方法最终还是用ClipGridWithPolygon2 (Grid inputGrid, Shape poly, string resultGridfile, bool keepExtents)了。
- // **************************************************************
- // ClipGridWithPolygon()
- // **************************************************************
- STDMETHODIMP CUtils::ClipGridWithPolygon(BSTR inputGridfile, IShape* poly, BSTR resultGridfile, VARIANT_BOOL keepExtents, VARIANT_BOOL* retVal)
- {
- AFX_MANAGE_STATE(AfxGetStaticModuleState());
-
- *retVal = VARIANT_FALSE;
-
- if (!Utility::FileExistsUnicode(inputGridfile))
- {
- ErrorMessage(tkINVALID_FILENAME);
- return S_OK;
- }
-
- IGrid* grid = NULL;
- CoCreateInstance(CLSID_Grid, NULL, CLSCTX_INPROC_SERVER, IID_IGrid, (void**)&grid);
-
- if (grid)
- {
- bool inRam = false;
- VARIANT_BOOL vb;
- grid->Open(inputGridfile, GridDataType::UnknownDataType, inRam, GridFileType::UseExtension, NULL, &vb);
- if (vb) {
- this->ClipGridWithPolygon2(grid, poly, resultGridfile, keepExtents, retVal);
- grid->Close(&vb);
- }
- grid->Release();
- }
- return S_OK;
- }
所以继续查看ClipGridWithPolygon2 (Grid inputGrid, Shape poly, string resultGridfile, bool keepExtents)的具体代码
- // ********************************************************
- // ClipGridWithPolygon2()
- // ********************************************************
- STDMETHODIMP CUtils::ClipGridWithPolygon2(IGrid* grid, IShape* poly, BSTR resultGridfile, VARIANT_BOOL keepExtents, VARIANT_BOOL* retVal)
- {
- AFX_MANAGE_STATE(AfxGetStaticModuleState());
-
- *retVal = VARIANT_FALSE;
-
- if (!poly || !grid) {
- ErrorMessage(tkUNEXPECTED_NULL_PARAMETER);
- return S_OK;
- }
-
- if (Utility::FileExistsUnicode(resultGridfile))
- {
- ErrorMessage(tkFILE_EXISTS);
- return S_OK;
- }
-
- VARIANT_BOOL vb;
-
- // find cell bounds
- IExtents* ext1 = NULL;
- poly->get_Extents(&ext1);
-
- IExtents* ext2 = NULL;
- ((CGrid*)grid)->get_Extents(&ext2);
-
- IExtents* bounds = NULL;
- ((CExtents*)ext1)->GetIntersection(ext2, &bounds);
-
- ext1->Release();
- ext2->Release();
-
- if (bounds) {
- double xMin, yMin, zMin, xMax, yMax, zMax;
- bounds->GetBounds(&xMin, &yMin, &zMin, &xMax, &yMax, &zMax);
- bounds->Release();
-
- long firstCol, firstRow, lastCol, lastRow;
- grid->ProjToCell(xMin, yMin, &firstCol, &firstRow);
- grid->ProjToCell(xMax, yMax, &lastCol, &lastRow);
-
- IGrid* newGrid = NULL;
-
- if (!keepExtents) {
- newGrid = ((CGrid*)grid)->Clip(resultGridfile, firstCol, lastCol, firstRow, lastRow);
- }
- else {
- newGrid = ((CGrid*)grid)->Clone(resultGridfile);
- }
-
- // copy data
- if (newGrid)
- {
- double dx, dy, xll, yll;
- IGridHeader* header = NULL;
- newGrid->get_Header(&header);
- header->get_dX(&dx);
- header->get_dY(&dy);
- header->get_XllCenter(&xll);
- header->get_YllCenter(&yll);
-
- CComVariant var;
- header->get_NodataValue(&var);
- double noData;
- dVal(var, noData);
-
- long minRow = MIN(firstRow, lastRow);
- long maxRow = MAX(firstRow, lastRow);
-
- int cmnCount = lastCol - firstCol + 1;
- int rowCount = maxRow - minRow + 1;
-
- if (keepExtents)
- {
- long rowCount;
- header->get_NumberRows(&rowCount);
-
- xll += dx * firstCol;
- yll += dy * (rowCount - maxRow - 1);
- }
- header->Release();
-
- if (cmnCount > 0 && rowCount > 0)
- {
- double* vals = new double[cmnCount];
- long row = 0;
-
- CPointInPolygon pip;
- if (pip.SetPolygon(poly))
- {
- for (long i = minRow; i <= maxRow; i++) {
- grid->GetFloatWindow2(i, i, firstCol, lastCol, vals, &vb);
-
- if (vb) {
-
- //double y = yll + dy * (rowCount - row - 1.5); // (rowCount - 1) - row; -0.5 - center of cell
- double y = yll + dy * (rowCount - row - 1); // a fix suggested here: http://bugs.mapwindow.org/view.php?id=2349
-
- pip.PrepareScanLine(y);
-
- // set values outside polygon to nodata
- for (long j = 0; j < cmnCount; j++)
- {
- // double x = xll + dx * (j + 0.5);
- double x = xll + dx * j; // a fix suggested here: http://bugs.mapwindow.org/view.php?id=2349
-
- if (!pip.ScanPoint(x))
- {
- vals[j] = noData;
- }
- }
-
- if (keepExtents) {
- newGrid->PutFloatWindow2(i, i, firstCol, lastCol, vals, &vb);
- row++;
- }
- else {
- newGrid->PutRow2(row++, vals, &vb);
- }
- }
- }
- }
- delete[] vals;
- }
-
- newGrid->Save(resultGridfile, GridFileType::UseExtension, NULL, &vb);
- newGrid->Close(&vb);
- newGrid->Release();
- *retVal = VARIANT_TRUE;
- }
- }
- return S_OK;
- }
2、处理方法
阅读代码你会发现源代码没什么高深的东西,要用多边形去裁切一个栅格数据,首先用多边形和栅格的外包框,去做一个相交运算。如果不相交也就没有处理的必要了。如果相交,保留原来范围只需将原grid拷贝一下,不保留原范围就是只要poly的范围,那么需要裁切grid,然后进行数据拷贝,在数据拷贝过程中,将范围外的数据设置为nodatavalue。
出现上述问题主要是poly的一部分在栅格外,而 grid->GetFloatWindow2(i, i, firstCol, lastCol, vals, &vb);却把高宽一样的数剧排除了,
但按逻辑修改这里后会发现RasterIO 方法又有问题,这个方法又是GDAL中的,又要去编译GDAL代码了。
如果要求不严可以加个判断 lastCol 和原grid的lastcol
****开源虽挺好,但遇到的问题的几率也大很多,耐心阅读,慢慢修改,*****
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。