当前位置:   article > 正文

mapwingis中的ClipGridWithPolygon方法祥读_mapwingis选取图像中的多边形

mapwingis选取图像中的多边形

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)了。

  1. // **************************************************************
  2. // ClipGridWithPolygon()
  3. // **************************************************************
  4. STDMETHODIMP CUtils::ClipGridWithPolygon(BSTR inputGridfile, IShape* poly, BSTR resultGridfile, VARIANT_BOOL keepExtents, VARIANT_BOOL* retVal)
  5. {
  6. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  7. *retVal = VARIANT_FALSE;
  8. if (!Utility::FileExistsUnicode(inputGridfile))
  9. {
  10. ErrorMessage(tkINVALID_FILENAME);
  11. return S_OK;
  12. }
  13. IGrid* grid = NULL;
  14. CoCreateInstance(CLSID_Grid, NULL, CLSCTX_INPROC_SERVER, IID_IGrid, (void**)&grid);
  15. if (grid)
  16. {
  17. bool inRam = false;
  18. VARIANT_BOOL vb;
  19. grid->Open(inputGridfile, GridDataType::UnknownDataType, inRam, GridFileType::UseExtension, NULL, &vb);
  20. if (vb) {
  21. this->ClipGridWithPolygon2(grid, poly, resultGridfile, keepExtents, retVal);
  22. grid->Close(&vb);
  23. }
  24. grid->Release();
  25. }
  26. return S_OK;
  27. }

 

所以继续查看ClipGridWithPolygon2 (Grid inputGrid, Shape poly, string resultGridfile, bool keepExtents)的具体代码

  1. // ********************************************************
  2. // ClipGridWithPolygon2()
  3. // ********************************************************
  4. STDMETHODIMP CUtils::ClipGridWithPolygon2(IGrid* grid, IShape* poly, BSTR resultGridfile, VARIANT_BOOL keepExtents, VARIANT_BOOL* retVal)
  5. {
  6. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  7. *retVal = VARIANT_FALSE;
  8. if (!poly || !grid) {
  9. ErrorMessage(tkUNEXPECTED_NULL_PARAMETER);
  10. return S_OK;
  11. }
  12. if (Utility::FileExistsUnicode(resultGridfile))
  13. {
  14. ErrorMessage(tkFILE_EXISTS);
  15. return S_OK;
  16. }
  17. VARIANT_BOOL vb;
  18. // find cell bounds
  19. IExtents* ext1 = NULL;
  20. poly->get_Extents(&ext1);
  21. IExtents* ext2 = NULL;
  22. ((CGrid*)grid)->get_Extents(&ext2);
  23. IExtents* bounds = NULL;
  24. ((CExtents*)ext1)->GetIntersection(ext2, &bounds);
  25. ext1->Release();
  26. ext2->Release();
  27. if (bounds) {
  28. double xMin, yMin, zMin, xMax, yMax, zMax;
  29. bounds->GetBounds(&xMin, &yMin, &zMin, &xMax, &yMax, &zMax);
  30. bounds->Release();
  31. long firstCol, firstRow, lastCol, lastRow;
  32. grid->ProjToCell(xMin, yMin, &firstCol, &firstRow);
  33. grid->ProjToCell(xMax, yMax, &lastCol, &lastRow);
  34. IGrid* newGrid = NULL;
  35. if (!keepExtents) {
  36. newGrid = ((CGrid*)grid)->Clip(resultGridfile, firstCol, lastCol, firstRow, lastRow);
  37. }
  38. else {
  39. newGrid = ((CGrid*)grid)->Clone(resultGridfile);
  40. }
  41. // copy data
  42. if (newGrid)
  43. {
  44. double dx, dy, xll, yll;
  45. IGridHeader* header = NULL;
  46. newGrid->get_Header(&header);
  47. header->get_dX(&dx);
  48. header->get_dY(&dy);
  49. header->get_XllCenter(&xll);
  50. header->get_YllCenter(&yll);
  51. CComVariant var;
  52. header->get_NodataValue(&var);
  53. double noData;
  54. dVal(var, noData);
  55. long minRow = MIN(firstRow, lastRow);
  56. long maxRow = MAX(firstRow, lastRow);
  57. int cmnCount = lastCol - firstCol + 1;
  58. int rowCount = maxRow - minRow + 1;
  59. if (keepExtents)
  60. {
  61. long rowCount;
  62. header->get_NumberRows(&rowCount);
  63. xll += dx * firstCol;
  64. yll += dy * (rowCount - maxRow - 1);
  65. }
  66. header->Release();
  67. if (cmnCount > 0 && rowCount > 0)
  68. {
  69. double* vals = new double[cmnCount];
  70. long row = 0;
  71. CPointInPolygon pip;
  72. if (pip.SetPolygon(poly))
  73. {
  74. for (long i = minRow; i <= maxRow; i++) {
  75. grid->GetFloatWindow2(i, i, firstCol, lastCol, vals, &vb);
  76. if (vb) {
  77. //double y = yll + dy * (rowCount - row - 1.5); // (rowCount - 1) - row; -0.5 - center of cell
  78. double y = yll + dy * (rowCount - row - 1); // a fix suggested here: http://bugs.mapwindow.org/view.php?id=2349
  79. pip.PrepareScanLine(y);
  80. // set values outside polygon to nodata
  81. for (long j = 0; j < cmnCount; j++)
  82. {
  83. // double x = xll + dx * (j + 0.5);
  84. double x = xll + dx * j; // a fix suggested here: http://bugs.mapwindow.org/view.php?id=2349
  85. if (!pip.ScanPoint(x))
  86. {
  87. vals[j] = noData;
  88. }
  89. }
  90. if (keepExtents) {
  91. newGrid->PutFloatWindow2(i, i, firstCol, lastCol, vals, &vb);
  92. row++;
  93. }
  94. else {
  95. newGrid->PutRow2(row++, vals, &vb);
  96. }
  97. }
  98. }
  99. }
  100. delete[] vals;
  101. }
  102. newGrid->Save(resultGridfile, GridFileType::UseExtension, NULL, &vb);
  103. newGrid->Close(&vb);
  104. newGrid->Release();
  105. *retVal = VARIANT_TRUE;
  106. }
  107. }
  108. return S_OK;
  109. }

2、处理方法

阅读代码你会发现源代码没什么高深的东西,要用多边形去裁切一个栅格数据,首先用多边形和栅格的外包框,去做一个相交运算。如果不相交也就没有处理的必要了。如果相交,保留原来范围只需将原grid拷贝一下,不保留原范围就是只要poly的范围,那么需要裁切grid,然后进行数据拷贝,在数据拷贝过程中,将范围外的数据设置为nodatavalue。

出现上述问题主要是poly的一部分在栅格外,而 grid->GetFloatWindow2(i, i, firstCol, lastCol, vals, &vb);却把高宽一样的数剧排除了,
 

但按逻辑修改这里后会发现RasterIO 方法又有问题,这个方法又是GDAL中的,又要去编译GDAL代码了。

 

如果要求不严可以加个判断 lastCol 和原grid的lastcol 

 

****开源虽挺好,但遇到的问题的几率也大很多,耐心阅读,慢慢修改,*****

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/306075
推荐阅读
相关标签
  

闽ICP备14008679号