Пример #1
0
        /// <summary>
        /// 通过插值经纬度数据,生成查找表
        /// 线性外插:从实际情况看,不需要执行这个线性外插,即可消除bow-tie弯弓效应。即:每个整扫描带跳过最后一行的插值。
        /// 目前局部数据看到的情况是,Fy3AMERSI的原始数据已经处理了bow-tie,FY3B和FY3C的没处理。
        /// 本插值仅适用于经纬度放大的情况,比如放大1倍,放大两倍等等。
        /// </summary>
        /// <param name="srcToDstProjXs"></param>
        /// <param name="srcToDstProjYs"></param>
        /// <param name="srcJdSize"></param>
        /// <param name="srcDataSize"></param>
        /// <param name="dstDataSize"></param>
        /// <param name="dstEnvelope"></param>
        /// <param name="rowMapTable"></param>
        /// <param name="colMapTable"></param>
        /// <param name="progressCallback"></param>
        /// <param name="scanLineWidth"></param>
        public void ComputeIndexMapTable(double[] srcToDstProjXs, double[] srcToDstProjYs, Size srcJdSize,
                                         Size srcDataSize,
                                         Size dstDataSize, PrjEnvelope dstEnvelope,
                                         out UInt16[] rowMapTable, out UInt16[] colMapTable, Action <int, string> progressCallback, int scanLineWidth)
        {
            int    dstHeight       = dstDataSize.Height;
            int    dstWidth        = dstDataSize.Width;
            int    srcHeight       = srcJdSize.Height;
            int    srcWidth        = srcJdSize.Width;
            int    srcDataWidth    = srcDataSize.Width;
            int    srcDataHeight   = srcDataSize.Height;
            int    srcLength       = srcWidth * srcHeight;
            int    srcDataLength   = srcDataWidth * srcDataHeight;
            int    dstLength       = dstWidth * dstHeight;
            double dstResolutionsX = dstEnvelope.Width / dstWidth;
            double dstResolutionsY = dstEnvelope.Height / dstHeight;
            int    slopeX          = srcDataWidth / srcWidth;   //4,2
            int    slopeY          = srcDataHeight / srcHeight; //4,2
            double dstMinX         = dstEnvelope.MinX;
            double dstMaxX         = dstEnvelope.MaxX;
            double dstMaxY         = dstEnvelope.MaxY;
            double dstMinY         = dstEnvelope.MinY;
            double srcValidMinX    = dstEnvelope.MinX - dstResolutionsX * slopeX * 2;
            double srcValidMaxX    = dstEnvelope.MaxX + dstResolutionsX * slopeX;
            double srcValidMaxY    = dstEnvelope.MaxY + dstResolutionsY * slopeY * 2;
            double srcValidMinY    = dstEnvelope.MinY - +dstResolutionsY * slopeY;
            float  factorX         = (float)srcWidth / srcDataWidth;   //1/4;1/2
            float  factorY         = (float)srcHeight / srcDataHeight; //1/4;1/2

            byte[]   lootUpTableTag    = new byte[dstLength];          //
            UInt16[] tmpRowLookUpTable = new UInt16[dstLength];        //
            UInt16[] tmpColLookUpTable = new UInt16[dstLength];        //
            if (InvalidValue != 0)
            {
                for (int i = 0; i < dstLength; i++)
                {
                    tmpRowLookUpTable[i] = InvalidValue;
                    tmpColLookUpTable[i] = InvalidValue;
                }
            }

            //扫描带宽度:10//用于去除
            Parallel.For(0, srcHeight, (oldRow) =>                          //oldRow、oldCol插值前的行,列
            {
                if (scanLineWidth > 1 && (oldRow + 1) % scanLineWidth == 0) //每条扫描线的最后一行。
                {
                }
                else     //线性内插
                {
                    int destRowIndex, destColIndex;
                    int destIndex;
                    double curX, curY;
                    int dstCol;
                    float oldRowF, oldColF;
                    int newRow, newCol;
                    int dstRow;
                    int rowOffset = oldRow * srcWidth;
                    int srcIndex;
                    double srcX, srcY;
                    //临时存储插后的经纬度数据集
                    double[,] m_fTempLat = new double[slopeX, slopeY];
                    double[,] m_fTempLon = new double[slopeX, slopeY];
                    double p1, p2, p3, p4;
                    int v1, v2, v3, v4;
                    double pu1;
                    int vSrcWidth;
                    int v1SrcWidth;
                    int i, j;
                    double v, u;
                    //下面用双线性差值计算出放大后的经纬度(XY)值,公式如下:
                    //f(i+u,j+v)=(1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1);
                    //p1=(1-u)(1-v),p2=(1-u)v,p3=u * (1 - v),p4=u * v
                    //
                    for (int oldCol = 0; oldCol < srcWidth; oldCol++)
                    {
                        srcIndex = rowOffset + oldCol;
                        srcX     = srcToDstProjXs[srcIndex];
                        srcY     = srcToDstProjYs[srcIndex];
                        if (srcY <= srcValidMaxY && srcY >= srcValidMinY && srcX >= srcValidMinX &&
                            srcX <= srcValidMaxX)
                        {
                            newRow = oldRow * slopeX;     //记录插值后的行列号
                            newCol = oldCol * slopeX;
                            //下面使用双线性插值,插值放大后的区域的值
                            for (int blockRow = 0; blockRow < slopeY; blockRow++)
                            {
                                dstRow  = blockRow + newRow;    //目标行
                                oldRowF = dstRow * factorY;
                                i       = (int)oldRowF;
                                if (i > oldRowF)
                                {
                                    --i;                  //x = (long)Math.Floor(fx);//取最大整数
                                }
                                u          = oldRowF - i;
                                pu1        = 1 - u;
                                vSrcWidth  = i * srcWidth;
                                v1SrcWidth = (i + 1) * srcWidth;
                                for (int blockCol = 0; blockCol < slopeX; blockCol++)
                                {
                                    dstCol  = blockCol + newCol;    //目标列
                                    oldColF = dstCol * factorX;
                                    j       = (int)oldColF;
                                    if (j > oldColF)
                                    {
                                        --j;
                                    }
                                    v = oldColF - j;
                                    if (i >= srcHeight - 1 && j >= srcWidth - 1)     //>=最后一行,并且>=最后一列
                                    {
                                        v1 = vSrcWidth + j;
                                        p1 = pu1 * (1 - v);
                                        m_fTempLon[blockRow, blockCol] = p1 * srcToDstProjXs[v1];
                                        m_fTempLat[blockRow, blockCol] = p1 * srcToDstProjYs[v1];
                                    }
                                    else if (i >= srcHeight - 1)     //最后一行
                                    {
                                        p1 = pu1 * (1 - v);
                                        p2 = pu1 * v;
                                        v1 = vSrcWidth + j;
                                        v2 = vSrcWidth + j + 1;
                                        m_fTempLon[blockRow, blockCol] =
                                            p1 * srcToDstProjXs[v1] +
                                            p2 * srcToDstProjXs[v2];
                                        m_fTempLat[blockRow, blockCol] =
                                            p1 * srcToDstProjYs[v1] +
                                            p2 * srcToDstProjYs[v2];
                                    }
                                    else if (j >= srcWidth - 1)     //最后一列
                                    {
                                        p1 = pu1 * (1 - v);
                                        p3 = u * (1 - v);
                                        v1 = vSrcWidth + j;
                                        v3 = v1SrcWidth + j;
                                        m_fTempLon[blockRow, blockCol] =
                                            p1 * srcToDstProjXs[v1] +
                                            p3 * srcToDstProjXs[v3];
                                        m_fTempLat[blockRow, blockCol] =
                                            p1 * srcToDstProjYs[v1] +
                                            p3 * srcToDstProjYs[v3];
                                    }
                                    else     //其他位置,双线性插值。
                                    {
                                        p1 = pu1 * (1 - v);
                                        p2 = pu1 * v;
                                        p3 = u * (1 - v);
                                        p4 = u * v;
                                        v1 = vSrcWidth + j;
                                        v2 = vSrcWidth + j + 1;
                                        v3 = v1SrcWidth + j;
                                        v4 = v1SrcWidth + j + 1;
                                        m_fTempLon[blockRow, blockCol] =
                                            p1 * srcToDstProjXs[v1] +
                                            p2 * srcToDstProjXs[v2] +
                                            p3 * srcToDstProjXs[v3] +
                                            p4 * srcToDstProjXs[v4];
                                        m_fTempLat[blockRow, blockCol] =
                                            p1 * srcToDstProjYs[v1] +
                                            p2 * srcToDstProjYs[v2] +
                                            p3 * srcToDstProjYs[v3] +
                                            p4 * srcToDstProjYs[v4];
                                    }
                                }
                            }

                            //计算查找表,将上面插好值的经纬度数据集映射到查找表
                            for (int blockRow = 0; blockRow < slopeY; blockRow++)
                            {
                                for (int blockCol = 0; blockCol < slopeX; blockCol++)
                                {
                                    curX = m_fTempLon[blockRow, blockCol];
                                    curY = m_fTempLat[blockRow, blockCol];
                                    if (curY <= dstMaxY && curY >= dstMinY && curX >= dstMinX && curX <= dstMaxX)
                                    {
                                        destRowIndex = (int)((dstMaxY - curY) / dstResolutionsY);      //Y方向计算出目标行
                                        destColIndex = (int)((curX - dstMinX) / dstResolutionsX);      //X方向计算出目标列
                                        destIndex    = destRowIndex * dstWidth + destColIndex;
                                        if (lootUpTableTag[destIndex] == 0 &&
                                            destRowIndex < dstHeight && destRowIndex >= 0 &&
                                            destColIndex < dstWidth && destColIndex >= 0)
                                        {
                                            tmpRowLookUpTable[destIndex] = (UInt16)(oldRow * slopeX + blockRow);
                                            tmpColLookUpTable[destIndex] = (UInt16)(oldCol * slopeY + blockCol);
                                            lootUpTableTag[destIndex]    = 1;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
                         );
            Interpolation.ChazhiNear(lootUpTableTag, dstDataSize.Width, dstDataSize.Height, tmpRowLookUpTable,
                                     tmpColLookUpTable);
            rowMapTable    = tmpRowLookUpTable;
            colMapTable    = tmpColLookUpTable;
            lootUpTableTag = new byte[1];
            lootUpTableTag = null;
        }
Пример #2
0
        /*
         * /// <summary>
         * /// 这里的srcXs,srcYs是源参考投影(srcSpatialRef)下的值。
         * /// </summary>
         * public void ComputeIndexMapTable(SpatialReference srcSpatialRef, double[] srcXs, double[] srcYs, Size srcSize,
         *                              SpatialReference dstSpatialRef, Size dstSize, PrjEnvelope dstEnvelope,
         *                              out UInt16[] rowMapTable, out UInt16[] colMapTable, Action<int, string> progressCallback)
         * {
         *  PrjEnvelope maxDstEnvelope;
         *  ComputeDstEnvelope(srcSpatialRef, srcXs, srcYs, srcSize, dstSpatialRef, out maxDstEnvelope, progressCallback);
         *  ComputeIndexMapTable(srcXs, srcYs, srcSize, dstSize, dstEnvelope, maxDstEnvelope,
         *      out rowMapTable, out colMapTable, progressCallback);
         * }
         */

        /// <summary>
        /// 这里的srcToDstSpatialXs,srcToDstSpatialYs是目标参考投影(dstSpatialRef)下的值
        /// </summary>
        public void ComputeIndexMapTable(double[] srcToDstSpatialXs, double[] srcToDstSpatialYs, Size srcSize,
                                         Size dstSize, PrjEnvelope dstEnvelope, PrjEnvelope maxDstEnvelope,
                                         out UInt16[] rowMapTable, out UInt16[] colMapTable, Action <int, string> progressCallback)
        {
            if (!maxDstEnvelope.IntersectsWith(dstEnvelope))
            {
                throw new Exception("目标坐标数据不在指定区域范围内");
            }
            double dstMinX         = dstEnvelope.MinX;
            double dstMaxX         = dstEnvelope.MaxX;
            double dstMaxY         = dstEnvelope.MaxY;
            double dstMinY         = dstEnvelope.MinY;
            double dstResolutionsX = dstEnvelope.Width / dstSize.Width;
            double dstResolutionsY = dstEnvelope.Height / dstSize.Height;
            int    srcLength       = srcSize.Width * srcSize.Height;
            int    dstLength       = dstSize.Width * dstSize.Height;
            int    dstHeight       = dstSize.Height;
            int    dstWidth        = dstSize.Width;
            int    srcHeight       = srcSize.Height;
            int    srcWidth        = srcSize.Width;

            byte[]   lootUpTableTag    = new byte[dstLength]; //投影蒙板,用于图像内外标识(0:外部,1:内部)
            UInt16[] tmpRowLookUpTable = new UInt16[dstLength];
            UInt16[] tmpColLookUpTable = new UInt16[dstLength];
            if (InvalidValue != 0)
            {
                for (int i = 0; i < dstLength; i++)
                {
                    tmpRowLookUpTable[i] = InvalidValue;
                    tmpColLookUpTable[i] = InvalidValue;
                }
            }

            int srcValidLeft  = 0;
            int srcValidRight = srcWidth;

            Parallel.For((int)0, srcHeight, (j) =>
            {
                int srcIndex = 0;
                int dstIndex = 0; //目标位置
                int dstJ;         //目标行
                int dsti;         //目标列
                double curX, curY;
                for (int i = srcValidLeft; i < srcValidRight; i++)
                {
                    srcIndex = (j * srcWidth + i);
                    curX     = srcToDstSpatialXs[srcIndex];
                    curY     = srcToDstSpatialYs[srcIndex];
                    dstJ     = (int)((dstMaxY - curY) / dstResolutionsY + 0.5); //Y方向计算出目标行 索引从0开始所以-1
                    dsti     = (int)((curX - dstMinX) / dstResolutionsX + 0.5); //X方向计算出目标列
                    if (dstJ >= 0 && dstJ < dstHeight && dsti >= 0 && dsti < dstWidth)
                    {
                        dstIndex = dstJ * dstWidth + dsti;
                        tmpRowLookUpTable[dstIndex] = (UInt16)j;
                        tmpColLookUpTable[dstIndex] = (UInt16)i;
                        lootUpTableTag[dstIndex]    = 1;
                    }
                }
            });
            if (dstSize.Width >= 2 && dstSize.Height >= 2)
            {
                Interpolation.ChazhiNear(lootUpTableTag, dstSize.Width, dstSize.Height, tmpRowLookUpTable,
                                         tmpColLookUpTable);
            }

            rowMapTable    = tmpRowLookUpTable;
            colMapTable    = tmpColLookUpTable;
            lootUpTableTag = new byte[1];
            lootUpTableTag = null;
        }