mapwingis中的ClipGridWithPolygon方法祥读

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 

 

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ipqchase85

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值