//--------------------------------------------------------- bool CKriging_Simple::Get_Weights(const CSG_Points_Z &Points, CSG_Matrix &W) { int n = Points.Get_Count(); if( n > 0 ) { int n = Points.Get_Count(); W.Create(n, n); for(int i=0; i<n; i++) { W[i][i] = 0.0; // diagonal... for(int j=i+1; j<n; j++) { W[i][j] = W[j][i] = Get_Weight(Points.Get_X(i), Points.Get_Y(i), Points.Get_X(j), Points.Get_Y(j)); } } return( W.Set_Inverse(!m_Search.Do_Use_All(), n) ); } return( false ); }
//--------------------------------------------------------- bool CKriging_Simple::Get_Value(const TSG_Point &p, double &z, double &v) { //----------------------------------------------------- int i, n; double **W; CSG_Matrix _W; CSG_Points_Z _Data, *pData; if( m_Search.Do_Use_All() ) // global { pData = &m_Data; W = m_W.Get_Data(); } else if( m_Search.Get_Points(p, _Data) && Get_Weights(_Data, _W) ) // local { pData = &_Data; W = _W.Get_Data(); } else { return( false ); } //----------------------------------------------------- if( (n = pData->Get_Count()) > 0 ) { CSG_Vector G(n); for(i=0; i<n; i++) { G[i] = Get_Weight(p, pData->Get_Point(i)); } //------------------------------------------------- for(i=0, z=0.0, v=0.0; i<n; i++) { double Lambda = 0.0; for(int j=0; j<n; j++) { Lambda += W[i][j] * G[j]; } z += Lambda * pData->Get_Z(i); v += Lambda * G[i]; } //------------------------------------------------- return( true ); } return( false ); }
//--------------------------------------------------------- bool CKriging_Universal::Get_Value(double x, double y, double &z, double &v) { int i, j, n, nGrids, nCoords; double Lambda; //----------------------------------------------------- if( (n = Get_Weights(x, y)) > 1 ) { nCoords = m_bCoords ? 2 : 0; nGrids = m_pGrids->Get_Count(); for(i=0; i<n; i++) { if( !m_bBlock ) { m_G[i] = Get_Weight(x - m_Points[i].x, y - m_Points[i].y); } else { m_G[i] = ( Get_Weight((x ) - m_Points[i].x, (y ) - m_Points[i].y) + Get_Weight((x + m_Block) - m_Points[i].x, (y + m_Block) - m_Points[i].y) + Get_Weight((x + m_Block) - m_Points[i].x, (y - m_Block) - m_Points[i].y) + Get_Weight((x - m_Block) - m_Points[i].x, (y + m_Block) - m_Points[i].y) + Get_Weight((x - m_Block) - m_Points[i].x, (y - m_Block) - m_Points[i].y) ) / 5.0; } } m_G[n] = 1.0; for(i=0, j=n+1; i<nGrids; i++, j++) { if( !m_pGrids->asGrid(i)->Get_Value(x, y, m_G[j], m_Interpolation) ) { return( false ); } } for(i=0, j=n+1+nGrids; i<nCoords; i++, j++) { m_G[j] = i == 0 ? x : y; } //------------------------------------------------- for(i=0, z=0.0, v=0.0; i<n; i++) { for(j=0, Lambda=0.0; j<=n+nGrids+nCoords; j++) { Lambda += m_W[i][j] * m_G[j]; } z += Lambda * m_Points[i].z; v += Lambda * m_G[i]; } //------------------------------------------------- return( true ); } return( false ); }
//--------------------------------------------------------- int CKriging_Universal::Get_Weights(const TSG_Point &p, CSG_Matrix &W, CSG_Points_Z &Points) { //----------------------------------------------------- int n = m_Search.Get_Nearest_Points(Points, p, m_nPoints_Max, m_Radius, m_Direction); if( n >= m_nPoints_Min ) { int i, j, k; int nCoords = m_bCoords ? 2 : 0; int nGrids = m_pGrids->Get_Count(); W.Create(n + 1 + nGrids + nCoords, n + 1 + nGrids + nCoords); //------------------------------------------------- for(i=0; i<n; i++) { W[i][i] = 0.0; // diagonal... W[i][n] = W[n][i] = 1.0; // edge... for(j=i+1; j<n; j++) { W[i][j] = W[j][i] = Get_Weight(Points[i], Points[j]); } for(k=0, j=n+1; k<nGrids; k++, j++) { W[i][j] = W[j][i] = m_pGrids->asGrid(k)->Get_Value(Points[i].x, Points[i].y, m_Interpolation); } for(k=0, j=n+nGrids+1; k<nCoords; k++, j++) { W[i][j] = W[j][i] = k == 0 ? Points[i].x : Points[i].y; } } for(i=n; i<=n+nGrids+nCoords; i++) { for(j=n; j<=n+nGrids+nCoords; j++) { W[i][j] = 0.0; } } if( W.Set_Inverse(true, n + 1 + nGrids + nCoords) ) { return( n ); } } return( 0 ); }
//--------------------------------------------------------- bool C_Kriging_Ordinary_Global::Get_Weights(void) { int i, j, n; //----------------------------------------------------- for(int iShape=0; iShape<m_pShapes->Get_Count(); iShape++) { CSG_Shape *pShape = m_pShapes->Get_Shape(iShape); if( !pShape->is_NoData(m_zField) ) { for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { m_Points.Add( pShape->Get_Point(iPoint, iPart).x, pShape->Get_Point(iPoint, iPart).y, pShape->asDouble(m_zField) ); } } } } //----------------------------------------------------- if( (n = m_Points.Get_Count()) > 4 ) { m_G .Create(n + 1); m_W .Create(n + 1, n + 1); for(i=0; i<n; i++) { m_W[i][i] = 0.0; // diagonal... m_W[i][n] = m_W[n][i] = 1.0; // edge... for(j=i+1; j<n; j++) { m_W[i][j] = m_W[j][i] = Get_Weight( m_Points[i].x - m_Points[j].x, m_Points[i].y - m_Points[j].y ); } } m_W[n][n] = 0.0; return( m_W.Set_Inverse(false) ); } return( false ); }
//--------------------------------------------------------- bool C_Kriging_Ordinary_Global::Get_Value(double x, double y, double &z, double &v) { int i, j, n; double Lambda; //----------------------------------------------------- if( (n = m_Points.Get_Count()) > 0 ) { for(i=0; i<n; i++) { if( !m_bBlock ) { m_G[i] = Get_Weight(x - m_Points[i].x, y - m_Points[i].y); } else { m_G[i] = ( Get_Weight((x ) - m_Points[i].x, (y ) - m_Points[i].y) + Get_Weight((x + m_Block) - m_Points[i].x, (y + m_Block) - m_Points[i].y) + Get_Weight((x + m_Block) - m_Points[i].x, (y - m_Block) - m_Points[i].y) + Get_Weight((x - m_Block) - m_Points[i].x, (y + m_Block) - m_Points[i].y) + Get_Weight((x - m_Block) - m_Points[i].x, (y - m_Block) - m_Points[i].y) ) / 5.0; } } m_G[n] = 1.0; //------------------------------------------------- for(i=0, z=0.0, v=0.0; i<n; i++) { for(j=0, Lambda=0.0; j<=n; j++) { Lambda += m_W[i][j] * m_G[j]; } z += Lambda * m_Points[i].z; v += Lambda * m_G[i]; } //------------------------------------------------- return( true ); } return( false ); }
//--------------------------------------------------------- bool CKriging_Universal::Get_Value(const TSG_Point &p, double &z, double &v) { //----------------------------------------------------- if( m_nPoints_Max <= 0 && m_Radius <= 0 ) // global { return( CKriging_Universal_Global::Get_Value(p, z, v) ); } //----------------------------------------------------- int i, j, n, nGrids, nCoords; CSG_Points_Z Points; CSG_Matrix W; //----------------------------------------------------- if( (n = Get_Weights(p, W, Points)) > 1 ) { nCoords = m_bCoords ? 2 : 0; nGrids = m_pGrids->Get_Count(); CSG_Vector G(n + 1 + nGrids + nCoords); for(i=0; i<n; i++) { G[i] = Get_Weight(p.x, p.y, Points[i].x, Points[i].y); } G[n] = 1.0; for(i=0, j=n+1; i<nGrids; i++, j++) { if( !m_pGrids->asGrid(i)->Get_Value(p, G[j], m_Interpolation) ) { return( false ); } } if( m_bCoords ) { G[n + 1 + nGrids] = p.x; G[n + 2 + nGrids] = p.y; } //------------------------------------------------- for(i=0, z=0.0, v=0.0; i<n; i++) { double Lambda = 0.0; for(j=0; j<=n+nGrids+nCoords; j++) { Lambda += W[i][j] * G[j]; } z += Lambda * Points[i].z; v += Lambda * G[i]; } //------------------------------------------------- return( true ); } return( false ); }
//--------------------------------------------------------- bool CGrid_Merge::On_Execute(void) { //----------------------------------------------------- if( !Initialize() ) { return( false ); } //----------------------------------------------------- for(int i=0; i<m_pGrids->Get_Count(); i++) { CSG_Grid *pGrid = m_pGrids->asGrid(i); Set_Weight(pGrid); Get_Match(i > 0 ? pGrid : NULL); int ax = (int)((pGrid->Get_XMin() - m_pMosaic->Get_XMin()) / m_pMosaic->Get_Cellsize()); int ay = (int)((pGrid->Get_YMin() - m_pMosaic->Get_YMin()) / m_pMosaic->Get_Cellsize()); //------------------------------------------------- if( is_Aligned(pGrid) ) { Process_Set_Text(CSG_String::Format("[%d/%d] %s: %s", i + 1, m_pGrids->Get_Count(), _TL("copying"), pGrid->Get_Name())); int nx = pGrid->Get_NX(); if( nx > m_pMosaic->Get_NX() - ax ) nx = m_pMosaic->Get_NX() - ax; int ny = pGrid->Get_NY(); if( ny > m_pMosaic->Get_NY() - ay ) ny = m_pMosaic->Get_NY() - ay; for(int y=0; y<ny && Set_Progress(y, ny); y++) { if( ay + y >= 0 ) { #pragma omp parallel for for(int x=0; x<nx; x++) { if( ax + x >= 0 && !pGrid->is_NoData(x, y) ) { Set_Value(ax + x, ay + y, pGrid->asDouble(x, y), Get_Weight(x, y)); } } } } } //------------------------------------------------- else { Process_Set_Text(CSG_String::Format("[%d/%d] %s: %s", i + 1, m_pGrids->Get_Count(), _TL("resampling"), pGrid->Get_Name())); if( ax < 0 ) ax = 0; if( ay < 0 ) ay = 0; int nx = 1 + m_pMosaic->Get_System().Get_xWorld_to_Grid(pGrid->Get_XMax()); if( nx > m_pMosaic->Get_NX() ) nx = m_pMosaic->Get_NX(); int ny = 1 + m_pMosaic->Get_System().Get_yWorld_to_Grid(pGrid->Get_YMax()); if( ny > m_pMosaic->Get_NY() ) ny = m_pMosaic->Get_NY(); for(int y=ay; y<ny && Set_Progress(y-ay, ny-ay); y++) { double py = m_pMosaic->Get_YMin() + y * m_pMosaic->Get_Cellsize(); #pragma omp parallel for for(int x=ax; x<nx; x++) { double px = m_pMosaic->Get_XMin() + x * m_pMosaic->Get_Cellsize(); Set_Value(x, y, pGrid, px, py); } } } } //----------------------------------------------------- if( m_Overlap == 4 ) // mean { for(int y=0; y<m_pMosaic->Get_NY() && Set_Progress(y, m_pMosaic->Get_NY()); y++) { #pragma omp parallel for for(int x=0; x<m_pMosaic->Get_NX(); x++) { double w = m_Weights.asDouble(x, y); if( w > 0.0 ) { m_pMosaic->Mul_Value(x, y, 1.0 / w); } } } } //----------------------------------------------------- m_Weight .Destroy(); m_Weights.Destroy(); return( true ); }
//--------------------------------------------------------- int CKriging_Universal::Get_Weights(double x, double y) { int i, j, k, n, nGrids, nCoords; //----------------------------------------------------- switch( m_Mode ) { default: n = m_Search.Select_Nearest_Points(x, y, m_nPoints_Max, m_Radius); break; case 1: n = m_Search.Select_Nearest_Points(x, y, m_nPoints_Max, m_Radius, 4); break; } //----------------------------------------------------- if( n >= m_nPoints_Min ) { nCoords = m_bCoords ? 2 : 0; nGrids = m_pGrids->Get_Count(); for(i=0; i<n; i++) { m_Search.Get_Selected_Point(i, m_Points[i].x, m_Points[i].y, m_Points[i].z); } //------------------------------------------------- for(i=0; i<n; i++) { m_W[i][i] = 0.0; // diagonal... m_W[i][n] = m_W[n][i] = 1.0; // edge... for(j=i+1; j<n; j++) { m_W[i][j] = m_W[j][i] = Get_Weight( m_Points[i].x - m_Points[j].x, m_Points[i].y - m_Points[j].y ); } for(k=0, j=n+1; k<nGrids; k++, j++) { m_W[i][j] = m_W[j][i] = m_pGrids->asGrid(k)->Get_Value( m_Points[i].x, m_Points[i].y, m_Interpolation ); } for(k=0, j=n+nGrids+1; k<nCoords; k++, j++) { m_W[i][j] = m_W[j][i] = k == 0 ? m_Points[i].x : m_Points[i].y; } } for(i=n; i<=n+nGrids+nCoords; i++) { for(j=n; j<=n+nGrids+nCoords; j++) { m_W[i][j] = 0.0; } } if( m_W.Set_Inverse(true, n + 1 + nGrids + nCoords) ) { return( n ); } } return( 0 ); }
//--------------------------------------------------------- bool C_Kriging_Universal_Global::Get_Weights(void) { int i, j, n, iGrid, nGrids; //----------------------------------------------------- if( (nGrids = m_pGrids->Get_Count()) > 0 ) { for(int iShape=0; iShape<m_pShapes->Get_Count(); iShape++) { CSG_Shape *pShape = m_pShapes->Get_Shape(iShape); if( !pShape->is_NoData(m_zField) ) { for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { bool bAdd; CSG_Point p(pShape->Get_Point(iPoint, iPart)); for(j=0, bAdd=true; j<nGrids && bAdd; j++) { if( !m_pGrids->asGrid(j)->is_InGrid_byPos(p) ) { bAdd = false; } } if( bAdd ) { m_Points.Add(p.Get_X(), p.Get_Y(), pShape->asDouble(m_zField)); } } } } } //------------------------------------------------- if( (n = m_Points.Get_Count()) > 1 ) { m_G.Create(n + 1 + nGrids); m_W.Create(n + 1 + nGrids, n + 1 + nGrids); for(i=0; i<n; i++) { m_W[i][i] = 0.0; // diagonal... m_W[i][n] = m_W[n][i] = 1.0; // edge... for(j=i+1; j<n; j++) { m_W[i][j] = m_W[j][i] = Get_Weight( m_Points[i].x - m_Points[j].x, m_Points[i].y - m_Points[j].y ); } for(iGrid=0, j=n+1; iGrid<nGrids; iGrid++, j++) { m_W[i][j] = m_W[j][i] = m_pGrids->asGrid(iGrid)->Get_Value( m_Points[i].x, m_Points[i].y, m_Interpolation ); } } for(i=n; i<=n+nGrids; i++) { for(j=n; j<=n+nGrids; j++) { m_W[i][j] = 0.0; } } return( m_W.Set_Inverse() ); } } return( 0 ); }
//--------------------------------------------------------- double C_Kriging_Base::Get_Weight(double dx, double dy) { return( Get_Weight(sqrt(dx*dx + dy*dy)) ); }