static dErr JakoFindPixel(VHTCase scase,const dReal x[3],dInt *ix,dInt *iy) { VHTCase_Jako *jako = scase->data; double xpixel,ypixel; dInt i,j; dFunctionBegin; *ix = -1; *iy = -1; if (x[0] < scase->bbox[0][0] || scase->bbox[0][1] < x[0]) dERROR(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"x[0]=%f not in bounding box %f:%f",x[0],scase->bbox[0][0],scase->bbox[0][1]); if (x[1] < scase->bbox[1][0] || scase->bbox[1][1] < x[1]) dERROR(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"x[1]=%f not in bounding box %f:%f",x[1],scase->bbox[1][0],scase->bbox[1][1]); GDALApplyGeoTransform(jako->myinvgeo,x[0],x[1],&xpixel,&ypixel); i = (dInt)xpixel; j = (dInt)ypixel; if (i < 0 || jako->nx <= i) dERROR(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Computed xp=%D not in range %D:%D",i,0,jako->nx); if (j < 0 || jako->ny <= j) dERROR(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Computed yp=%D not in range %D:%D",j,0,jako->ny); *ix = i; *iy = j; dFunctionReturn(0); }
static dErr VHTCaseSetUp_Jako(VHTCase scase) { VHTCase_Jako *jako = scase->data; dErr err; OGRErr oerr; dFunctionBegin; jako->utmref = OSRNewSpatialReference(NULL); oerr = OSRSetProjCS(jako->utmref,"UTM 22N (WGS84)");dOGRCHK(oerr); oerr = OSRSetWellKnownGeogCS(jako->utmref,"WGS84");dOGRCHK(oerr); oerr = OSRSetUTM(jako->utmref,22,1);dOGRCHK(oerr); oerr = OSRSetLinearUnits(jako->utmref,SRS_UL_METER,1.0);dOGRCHK(oerr); jako->llref = OSRNewSpatialReference(NULL); oerr = OSRSetWellKnownGeogCS(jako->llref,"WGS84");dOGRCHK(oerr); jako->ianref = OSRNewSpatialReference(NULL); oerr = OSRSetProjCS(jako->ianref,"Stereographic Greenland (WGS84)");dOGRCHK(oerr); oerr = OSRSetWellKnownGeogCS(jako->ianref,"WGS84");dOGRCHK(oerr); oerr = OSRSetStereographic(jako->ianref,70.0,-45.0,100.0,-217.75e3,-2302.0e3);dOGRCHK(oerr); // The computational domain is in UTM 22N jako->myref = OSRNewSpatialReference(NULL); oerr = OSRSetProjCS(jako->myref,"Computational Domain: UTM 22N (WGS84)");dOGRCHK(oerr); oerr = OSRSetWellKnownGeogCS(jako->myref,"WGS84");dOGRCHK(oerr); oerr = OSRSetUTM(jako->myref,22,1);dOGRCHK(oerr); oerr = OSRSetLinearUnits(jako->myref,SRS_UL_METER,1.0);dOGRCHK(oerr); jako->fromutm = OCTNewCoordinateTransformation(jako->utmref,jako->myref); jako->fromll = OCTNewCoordinateTransformation(jako->llref,jako->myref); jako->fromian = OCTNewCoordinateTransformation(jako->ianref,jako->myref); if (jako->verbose) {err = VHTCaseView_Jako(scase,PETSC_VIEWER_STDOUT_WORLD);dCHK(err);} if (1) { GDALProgressFunc gdalprogress = jako->verbose ? GDALTermProgress : GDALDummyProgress; double x0,y0,Lx,Ly,dx,dy; GDALDatasetH filedata; GDALErr gerr; GDALRasterBandH band; CPLErr cplerr; x0 = scase->bbox[0][0]; y0 = scase->bbox[1][0]; Lx = scase->bbox[0][1] - x0; Ly = scase->bbox[1][1] - y0; // It appears from gdalwarp.cpp that pixels are cell centered dx = Lx / jako->nx; dy = Ly / jako->ny; // Extend the domain in the positive direction for slope evaluation jako->nx += 2; jako->ny += 2; Lx += 2*dx; Ly += 2*dy; // Convert a pixel to a physical coordinate in the current projection jako->mygeo[0] = x0 + dx/2; jako->mygeo[1] = dx; jako->mygeo[2] = 0; jako->mygeo[3] = y0 + Ly - dy/2; // Physical coordinates are "y up", pixels are "y down" jako->mygeo[4] = 0; jako->mygeo[5] = -dy; // Convert a physical coordinate in the current projection to a pixel coordinate gerr = GDALInvGeoTransform(jako->mygeo,jako->myinvgeo);dGDALCHK(gerr); if (jako->verbose) { dInt i,j; double a,b; err = dRealTableView(3,2,&scase->bbox[0][0],PETSC_VIEWER_STDOUT_WORLD,"bbox");dCHK(err); err = dRealTableView(2,3,jako->mygeo,PETSC_VIEWER_STDOUT_WORLD,"mygeo");dCHK(err); GDALApplyGeoTransform(jako->mygeo,0,0,&a,&b); printf("geo[0,0] = %f,%f\n",a,b); GDALApplyGeoTransform(jako->mygeo,1,1,&a,&b); printf("geo[1,1] = %f,%f\n",a,b); GDALApplyGeoTransform(jako->mygeo,0.5,0.5,&a,&b); printf("geo[0.5,0.5] = %f,%f\n",a,b); err = JakoFindPixel(scase,(dReal[]){scase->bbox[0][0],scase->bbox[1][0]},&i,&j);dCHK(err); printf("xmin,ymin: (%d,%d)\n",i,j); err = JakoFindPixel(scase,(dReal[]){scase->bbox[0][1],scase->bbox[1][1]},&i,&j);dCHK(err); printf("xmax,ymax: (%d,%d)\n",i,j); }
/** GDALComputeMatchingPoints. TODO document */ GDAL_GCP CPL_DLL * GDALComputeMatchingPoints( GDALDatasetH hFirstImage, GDALDatasetH hSecondImage, char **papszOptions, int *pnGCPCount ) { *pnGCPCount = 0; /* -------------------------------------------------------------------- */ /* Override default algorithm parameters. */ /* -------------------------------------------------------------------- */ int nOctaveStart, nOctaveEnd; double dfSURFThreshold; nOctaveStart =atoi(CSLFetchNameValueDef(papszOptions, "OCTAVE_START", "2")); nOctaveEnd = atoi(CSLFetchNameValueDef(papszOptions, "OCTAVE_END", "2")); dfSURFThreshold = CPLAtof( CSLFetchNameValueDef(papszOptions, "SURF_THRESHOLD", "0.001")); const double dfMatchingThreshold = CPLAtof( CSLFetchNameValueDef(papszOptions, "MATCHING_THRESHOLD", "0.015")); /* -------------------------------------------------------------------- */ /* Identify the bands to use. For now we are effectively */ /* limited to using RGB input so if we have one band only treat */ /* it as red=green=blue=band 1. Disallow non eightbit imagery. */ /* -------------------------------------------------------------------- */ int anBandMap1[3] = { 1, 1, 1 }; if( GDALGetRasterCount(hFirstImage) >= 3 ) { anBandMap1[1] = 2; anBandMap1[2] = 3; } int anBandMap2[3] = { 1, 1, 1 }; if( GDALGetRasterCount(hSecondImage) >= 3 ) { anBandMap2[1] = 2; anBandMap2[2] = 3; } /* -------------------------------------------------------------------- */ /* Collect reference points on each image. */ /* -------------------------------------------------------------------- */ std::vector<GDALFeaturePoint> *poFPCollection1 = GatherFeaturePoints(reinterpret_cast<GDALDataset *>(hFirstImage), anBandMap1, nOctaveStart, nOctaveEnd, dfSURFThreshold); if( poFPCollection1 == nullptr ) return nullptr; std::vector<GDALFeaturePoint> *poFPCollection2 = GatherFeaturePoints(reinterpret_cast<GDALDataset *>(hSecondImage), anBandMap2, nOctaveStart, nOctaveEnd, dfSURFThreshold); if( poFPCollection2 == nullptr ) { delete poFPCollection1; return nullptr; } /* -------------------------------------------------------------------- */ /* Try to find corresponding locations. */ /* -------------------------------------------------------------------- */ std::vector<GDALFeaturePoint *> oMatchPairs; if( CE_None != GDALSimpleSURF::MatchFeaturePoints( &oMatchPairs, poFPCollection1, poFPCollection2, dfMatchingThreshold )) { delete poFPCollection1; delete poFPCollection2; return nullptr; } *pnGCPCount = static_cast<int>(oMatchPairs.size()) / 2; /* -------------------------------------------------------------------- */ /* Translate these into GCPs - but with the output coordinate */ /* system being pixel/line on the second image. */ /* -------------------------------------------------------------------- */ GDAL_GCP *pasGCPList = static_cast<GDAL_GCP*>(CPLCalloc(*pnGCPCount, sizeof(GDAL_GCP))); GDALInitGCPs(*pnGCPCount, pasGCPList); for( int i=0; i < *pnGCPCount; i++ ) { GDALFeaturePoint *poPoint1 = oMatchPairs[i*2 ]; GDALFeaturePoint *poPoint2 = oMatchPairs[i*2+1]; pasGCPList[i].dfGCPPixel = poPoint1->GetX() + 0.5; pasGCPList[i].dfGCPLine = poPoint1->GetY() + 0.5; pasGCPList[i].dfGCPX = poPoint2->GetX() + 0.5; pasGCPList[i].dfGCPY = poPoint2->GetY() + 0.5; pasGCPList[i].dfGCPZ = 0.0; } // Cleanup the feature point lists. delete poFPCollection1; delete poFPCollection2; /* -------------------------------------------------------------------- */ /* Optionally transform into the georef coordinates of the */ /* output image. */ /* -------------------------------------------------------------------- */ const bool bGeorefOutput = CPLTestBool(CSLFetchNameValueDef(papszOptions, "OUTPUT_GEOREF", "NO")); if( bGeorefOutput ) { double adfGeoTransform[6] = {}; GDALGetGeoTransform( hSecondImage, adfGeoTransform ); for( int i=0; i < *pnGCPCount; i++ ) { GDALApplyGeoTransform(adfGeoTransform, pasGCPList[i].dfGCPX, pasGCPList[i].dfGCPY, &(pasGCPList[i].dfGCPX), &(pasGCPList[i].dfGCPY)); } } return pasGCPList; }
bool wxGISRasterDataset::Open(void) { if(m_bIsOpened) return true; wxCriticalSectionLocker locker(m_CritSect); m_poDataset = (GDALDataset *) GDALOpen( wgWX2MB(m_sPath.c_str()), GA_ReadOnly ); if( m_poDataset == NULL ) return false; int nXSize = m_poDataset->GetRasterXSize(); int nYSize = m_poDataset->GetRasterYSize(); bool bHasOverviews = false; char** papszFileList = m_poDataset->GetFileList(); if ( CSLCount(papszFileList) == 0 ) { wxLogDebug(wxT( "Files: none associated" )); } else { wxLogDebug(wxT("Files: %s"), wgMB2WX(papszFileList[0]) ); for (int i = 1; papszFileList[i] != NULL; i++) { wxString sFileName = wgMB2WX(papszFileList[i]); if(sFileName.Find(wxT(".rrd")) != wxNOT_FOUND || sFileName.Find(wxT(".ovr")) != wxNOT_FOUND) bHasOverviews = true; wxLogDebug( wxT(" %s"), sFileName.c_str() ); } } CSLDestroy( papszFileList ); CPLSetConfigOption( "USE_RRD", "YES" ); CPLSetConfigOption( "HFA_USE_RRD", "YES" ); CPLSetConfigOption( "COMPRESS_OVERVIEW", "LZW" ); bool bAskCreateOvr = false; if(!bHasOverviews && bAskCreateOvr) { int anOverviewList[5] = { 4, 8, 16, 32, 64 }; CPLErr err = m_poDataset->BuildOverviews( "CUBIC", 5, anOverviewList, 0, NULL, GDALDummyProgress, NULL ); // } // m_psExtent = new OGREnvelope(); double adfGeoTransform[6]; if(m_poDataset->GetGeoTransform( adfGeoTransform ) != CE_Fatal ) { double inX[4]; double inY[4]; inX[0] = 0; inY[0] = 0; inX[1] = nXSize; inY[1] = 0; inX[2] = nXSize; inY[2] = nYSize; inX[3] = 0; inY[3] = nYSize; m_psExtent->MaxX = 0; m_psExtent->MaxY = 0; m_psExtent->MinX = 1000000000; m_psExtent->MinY = 1000000000; for(int i = 0; i < 4; i++) { double rX, rY; GDALApplyGeoTransform( adfGeoTransform, inX[i], inY[i], &rX, &rY); if(m_psExtent->MaxX < rX) m_psExtent->MaxX = rX; if(m_psExtent->MinX > rX) m_psExtent->MinX = rX; if(m_psExtent->MaxY < rY) m_psExtent->MaxY = rY; if(m_psExtent->MinY > rY) m_psExtent->MinY = rY; } } else { wxDELETE(m_psExtent); m_psExtent = NULL; } // m_bIsOpened = true; return true; }
bool wxGISRasterDataset::Open(void) { if(m_bIsOpened) return true; wxCriticalSectionLocker locker(m_CritSect); m_poDataset = (GDALDataset *) GDALOpen( wgWX2MB(m_sPath.c_str()), GA_ReadOnly ); if( m_poDataset == NULL ) return false; int nXSize = m_poDataset->GetRasterXSize(); int nYSize = m_poDataset->GetRasterYSize(); bool bHasOverviews = false; char** papszFileList = m_poDataset->GetFileList(); if( CSLCount(papszFileList) == 0 ) { wxLogDebug(wxT( "Files: none associated" )); } else { wxLogDebug(wxT("Files: %s"), wgMB2WX(papszFileList[0]) ); for(int i = 1; papszFileList[i] != NULL; i++ ) { wxString sFileName = wgMB2WX(papszFileList[i]); if(sFileName.Find(wxT(".rrd")) != wxNOT_FOUND || sFileName.Find(wxT(".ovr")) != wxNOT_FOUND) bHasOverviews = true; wxLogDebug( wxT(" %s"), sFileName.c_str() ); } } CSLDestroy( papszFileList ); CPLSetConfigOption( "USE_RRD", "YES" ); CPLSetConfigOption( "HFA_USE_RRD", "YES" ); CPLSetConfigOption( "COMPRESS_OVERVIEW", "LZW" ); bool bAskCreateOvr = false; if(!bHasOverviews && bAskCreateOvr) { int anOverviewList[5] = { 4, 8, 16, 32, 64 }; CPLErr err = m_poDataset->BuildOverviews( "CUBIC", 5, anOverviewList, 0, NULL, GDALDummyProgress, NULL ); //"NEAREST", "GAUSS", "CUBIC", "AVERAGE", "MODE", "AVERAGE_MAGPHASE" or "NONE" } //GDALDriver* pDrv = m_poDataset->GetDriver(); //const char* desc = pDrv->GetDescription(); //wxLogDebug( wxT("Driver: %s/%s"), wgMB2WX(GDALGetDriverShortName( pDrv )), wgMB2WX(GDALGetDriverLongName( pDrv )) ); //char** papszMetadata = m_poDataset->GetMetadata(); // if( CSLCount(papszMetadata) > 0 ) // { // wxLogDebug( wxT( "Metadata:" )); // for(int i = 0; papszMetadata[i] != NULL; i++ ) // { // wxLogDebug( wxT( " %s"), wgMB2WX(papszMetadata[i]) ); // } // } ///* -------------------------------------------------------------------- */ ///* Report "IMAGE_STRUCTURE" metadata. */ ///* -------------------------------------------------------------------- */ // papszMetadata = m_poDataset->GetMetadata("IMAGE_STRUCTURE"); // if( CSLCount(papszMetadata) > 0 ) // { // wxLogDebug( wxT( "Image Structure Metadata:" )); // for(int i = 0; papszMetadata[i] != NULL; i++ ) // { // wxLogDebug( wxT( " %s"), wgMB2WX(papszMetadata[i]) ); // } // } ///* -------------------------------------------------------------------- */ ///* Report subdatasets. */ ///* -------------------------------------------------------------------- */ // papszMetadata = m_poDataset->GetMetadata("SUBDATASETS"); // if( CSLCount(papszMetadata) > 0 ) // { // wxLogDebug( wxT( "Subdatasets:" )); // for(int i = 0; papszMetadata[i] != NULL; i++ ) // { // wxLogDebug( wxT( " %s"), wgMB2WX(papszMetadata[i]) ); // } // } ///* -------------------------------------------------------------------- */ ///* Report geolocation. */ ///* -------------------------------------------------------------------- */ // papszMetadata = m_poDataset->GetMetadata("GEOLOCATION"); // if( CSLCount(papszMetadata) > 0 ) // { // wxLogDebug( wxT( "Geolocation:" )); // for(int i = 0; papszMetadata[i] != NULL; i++ ) // { // wxLogDebug( wxT( " %s"), wgMB2WX(papszMetadata[i]) ); // } // } ///* -------------------------------------------------------------------- */ ///* Report RPCs */ ///* -------------------------------------------------------------------- */ // papszMetadata = m_poDataset->GetMetadata("RPC"); // if( CSLCount(papszMetadata) > 0 ) // { // wxLogDebug( wxT( "RPC Metadata:" )); // for(int i = 0; papszMetadata[i] != NULL; i++ ) // { // wxLogDebug( wxT( " %s"), wgMB2WX(papszMetadata[i]) ); // } // } //for(int nBand = 0; nBand < m_poDataset->GetRasterCount(); nBand++ ) // { // double dfMin, dfMax, adfCMinMax[2], dfNoData; // int bGotMin, bGotMax, bGotNodata, bSuccess; // int nBlockXSize, nBlockYSize, nMaskFlags; // double dfMean, dfStdDev; // GDALColorTable* hTable; // CPLErr eErr; // GDALRasterBand* pBand = m_poDataset->GetRasterBand(nBand + 1); // //if( bSample ) // //{ // // float afSample[10000]; // // int nCount; // // nCount = GDALGetRandomRasterSample( hBand, 10000, afSample ); // // printf( "Got %d samples.\n", nCount ); // //} // // pBand->GetBlockSize(&nBlockXSize, &nBlockYSize); // wxLogDebug( wxT( "Band %d Block=%dx%d Type=%s, ColorInterp=%s"), nBand + 1, nBlockXSize, nBlockYSize, wgMB2WX(GDALGetDataTypeName(pBand->GetRasterDataType())), wgMB2WX(GDALGetColorInterpretationName(pBand->GetColorInterpretation()))); // wxString sDescription = wgMB2WX(pBand->GetDescription()); // wxLogDebug( wxT( " Description = %s"), sDescription.c_str()); // dfMin = pBand->GetMinimum(&bGotMin); // dfMax = pBand->GetMaximum(&bGotMax); // if( bGotMin || bGotMax ) // { // if( bGotMin ) // wxLogDebug( wxT( "Min=%.3f "), dfMin ); // if( bGotMax ) // wxLogDebug( wxT( "Max=%.3f "), dfMax ); // // pBand->ComputeRasterMinMax(FALSE, adfCMinMax ); // wxLogDebug( wxT(" Computed Min/Max=%.3f,%.3f"), adfCMinMax[0], adfCMinMax[1] ); // } // eErr = pBand->GetStatistics(TRUE, TRUE, &dfMin, &dfMax, &dfMean, &dfStdDev ); // if( eErr == CE_None ) // { // wxLogDebug( wxT(" Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f"), dfMin, dfMax, dfMean, dfStdDev ); // } // //if( bReportHistograms ) // //{ // // int nBucketCount, *panHistogram = NULL; // // eErr = GDALGetDefaultHistogram( hBand, &dfMin, &dfMax, // // &nBucketCount, &panHistogram, // // TRUE, GDALTermProgress, NULL ); // // if( eErr == CE_None ) // // { // // int iBucket; // // printf( " %d buckets from %g to %g:\n ", // // nBucketCount, dfMin, dfMax ); // // for( iBucket = 0; iBucket < nBucketCount; iBucket++ ) // // printf( "%d ", panHistogram[iBucket] ); // // printf( "\n" ); // // CPLFree( panHistogram ); // // } // //} // //wxLogDebug( wxT(" Checksum=%d"), GDALChecksumImage(pBand, 0, 0, nXSize, nYSize)); // dfNoData = pBand->GetNoDataValue(&bGotNodata ); // if( bGotNodata ) // { // wxLogDebug( wxT(" NoData Value=%.18g"), dfNoData ); // } // if( pBand->GetOverviewCount() > 0 ) // { // wxString sOut(wxT(" Overviews: " )); // for(int iOverview = 0; iOverview < pBand->GetOverviewCount(); iOverview++ ) // { // const char *pszResampling = NULL; // if( iOverview != 0 ) // sOut += wxT( ", " ); // GDALRasterBand* pOverview = pBand->GetOverview( iOverview ); // sOut += wxString::Format(wxT("%dx%d"), pOverview->GetXSize(), pOverview->GetYSize()); // pszResampling = pOverview->GetMetadataItem("RESAMPLING", "" ); // if( pszResampling != NULL && EQUALN(pszResampling, "AVERAGE_BIT2", 12) ) // sOut += wxT( "*" ); // } // wxLogDebug(sOut); // // sOut = wxT( " Overviews checksum: " ); // // for(int iOverview = 0; iOverview < pBand->GetOverviewCount(); iOverview++ ) // //{ // // if( iOverview != 0 ) // // sOut += wxT( ", " ); // // GDALRasterBand* pOverview = pBand->GetOverview( iOverview ); // // sOut += GDALChecksumImage(pOverview, 0, 0, pOverview->GetXSize(), pOverview->GetYSize()); // // } // // wxLogDebug(sOut); // } // if( pBand->HasArbitraryOverviews() ) // { // wxLogDebug( wxT(" Overviews: arbitrary" )); // } // // nMaskFlags = pBand->GetMaskFlags(); // if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 ) // { // GDALRasterBand* pMaskBand = pBand->GetMaskBand() ; // wxLogDebug( wxT(" Mask Flags: " )); // if( nMaskFlags & GMF_PER_DATASET ) // wxLogDebug( wxT("PER_DATASET " )); // if( nMaskFlags & GMF_ALPHA ) // wxLogDebug( wxT("ALPHA " )); // if( nMaskFlags & GMF_NODATA ) // wxLogDebug( wxT("NODATA " )); // if( nMaskFlags & GMF_ALL_VALID ) // wxLogDebug( wxT("ALL_VALID " )); // if( pMaskBand != NULL && pMaskBand->GetOverviewCount() > 0 ) // { // int iOverview; // wxLogDebug( wxT(" Overviews of mask band: " )); // for( int nOverview = 0; nOverview < pMaskBand->GetOverviewCount(); nOverview++ ) // { // GDALRasterBand* pOverview; // if( nOverview != 0 ) // wxLogDebug( wxT(", " )); // pOverview = pMaskBand->GetOverview( nOverview ); // wxLogDebug( wxT("%dx%d"), pOverview->GetXSize(), pOverview->GetYSize()); // } // } // } // if( strlen(pBand->GetUnitType()) > 0 ) // { // wxLogDebug( wxT(" Unit Type: %s"),wgMB2WX( pBand->GetUnitType()) ); // } // char **papszCategories = pBand->GetCategoryNames(); // if( papszCategories != NULL ) // { // int i; // wxLogDebug( wxT(" Categories:" )); // for( i = 0; papszCategories[i] != NULL; i++ ) // wxLogDebug( wxT(" %3d: %s"), i, wgMB2WX(papszCategories[i]) ); // } // if( pBand->GetScale( &bSuccess ) != 1.0 || pBand->GetOffset( &bSuccess ) != 0.0 ) // wxLogDebug( wxT(" Offset: %.15g, Scale:%.15g"), pBand->GetOffset( &bSuccess ), pBand->GetScale( &bSuccess ) ); // papszMetadata = pBand->GetMetadata(); // if( CSLCount(papszMetadata) > 0 ) // { // wxLogDebug( wxT(" Metadata:" )); // for( int i = 0; papszMetadata[i] != NULL; i++ ) // { // wxLogDebug( wxT(" %s"), wgMB2WX(papszMetadata[i]) ); // } // } // papszMetadata = pBand->GetMetadata( "IMAGE_STRUCTURE" ); // if( CSLCount(papszMetadata) > 0 ) // { // wxLogDebug( wxT(" Image Structure Metadata:" )); // for( int i = 0; papszMetadata[i] != NULL; i++ ) // { // wxLogDebug( wxT(" %s"), wgMB2WX(papszMetadata[i])); // } // } // if( pBand->GetColorInterpretation() == GCI_PaletteIndex && (hTable = pBand->GetColorTable()) != NULL ) // { // int i; // wxLogDebug( wxT(" Color Table (%s with %d entries)"), wgMB2WX(GDALGetPaletteInterpretationName(hTable->GetPaletteInterpretation())), hTable->GetColorEntryCount() ); // for( i = 0; i < hTable->GetColorEntryCount(); i++ ) // { // GDALColorEntry sEntry; // hTable->GetColorEntryAsRGB(i, &sEntry ); // wxLogDebug( wxT(" %3d: %d,%d,%d,%d"), i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); // } // } // if( pBand->GetDefaultRAT() != NULL ) // { // const GDALRasterAttributeTable* pRAT = (const GDALRasterAttributeTable*)pBand->GetDefaultRAT(); // GDALRasterAttributeTable* pRATn = (GDALRasterAttributeTable*)pRAT; // pRATn->DumpReadable(); // } //} //CPLCleanupTLS(); m_psExtent = new OGREnvelope(); double adfGeoTransform[6]; if(m_poDataset->GetGeoTransform( adfGeoTransform ) != CE_Fatal ) { double inX[4]; double inY[4]; inX[0] = 0; inY[0] = 0; inX[1] = nXSize; inY[1] = 0; inX[2] = nXSize; inY[2] = nYSize; inX[3] = 0; inY[3] = nYSize; m_psExtent->MaxX = 0; m_psExtent->MaxY = 0; m_psExtent->MinX = 1000000000; m_psExtent->MinY = 1000000000; for(int i = 0; i < 4; i++) { double rX, rY; GDALApplyGeoTransform( adfGeoTransform, inX[i], inY[i], &rX, &rY ); if(m_psExtent->MaxX < rX) m_psExtent->MaxX = rX; if(m_psExtent->MinX > rX) m_psExtent->MinX = rX; if(m_psExtent->MaxY < rY) m_psExtent->MaxY = rY; if(m_psExtent->MinY > rY) m_psExtent->MinY = rY; } } else { wxDELETE(m_psExtent); m_psExtent = NULL; } // if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) // { // printf( "Origin = (%.6f,%.6f)\n", // adfGeoTransform[0], adfGeoTransform[3] ); // // printf( "Pixel Size = (%.6f,%.6f)\n", // adfGeoTransform[1], adfGeoTransform[5] ); // } m_bIsOpened = true; return true; }
/* * Init() */ bool OGRNGWDataset::Init(int nOpenFlagsIn) { // NOTE: Skip check API version at that moment. We expected API v3. // Get resource details. CPLJSONDocument oResourceDetailsReq; char **papszHTTPOptions = GetHeaders(); bool bResult = oResourceDetailsReq.LoadUrl( NGWAPI::GetResource( osUrl, osResourceId ), papszHTTPOptions ); CPLDebug("NGW", "Get resource %s details %s", osResourceId.c_str(), bResult ? "success" : "failed"); if( bResult ) { CPLJSONObject oRoot = oResourceDetailsReq.GetRoot(); if( oRoot.IsValid() ) { std::string osResourceType = oRoot.GetString("resource/cls"); FillMetadata( oRoot ); if( osResourceType == "resource_group" ) { // Check feature paging. FillCapabilities( papszHTTPOptions ); if( oRoot.GetBool( "resource/children", false ) ) { // Get child resources. bResult = FillResources( papszHTTPOptions, nOpenFlagsIn ); } } else if( (osResourceType == "vector_layer" || osResourceType == "postgis_layer") ) { // Cehck feature paging. FillCapabilities( papszHTTPOptions ); // Add vector layer. AddLayer( oRoot, papszHTTPOptions, nOpenFlagsIn ); } else if( osResourceType == "mapserver_style" || osResourceType == "qgis_vector_style" || osResourceType == "raster_style" || osResourceType == "wmsclient_layer" ) { // GetExtent from parent. OGREnvelope stExtent; std::string osParentId = oRoot.GetString("resource/parent/id"); bool bExtentResult = NGWAPI::GetExtent(osUrl, osParentId, papszHTTPOptions, 3857, stExtent); if( !bExtentResult ) { // Set full extent for EPSG:3857. stExtent.MinX = -20037508.34; stExtent.MaxX = 20037508.34; stExtent.MinY = -20037508.34; stExtent.MaxY = 20037508.34; } CPLDebug("NGW", "Raster extent is: %f, %f, %f, %f", stExtent.MinX, stExtent.MinY, stExtent.MaxX, stExtent.MaxY); int nEPSG = 3857; // Get parent details. We can skip this as default SRS in NGW is 3857. if( osResourceType == "wmsclient_layer" ) { nEPSG = oRoot.GetInteger("wmsclient_layer/srs/id", nEPSG); } else { CPLJSONDocument oResourceReq; bResult = oResourceReq.LoadUrl( NGWAPI::GetResource( osUrl, osResourceId ), papszHTTPOptions ); if( bResult ) { CPLJSONObject oParentRoot = oResourceReq.GetRoot(); if( osResourceType == "mapserver_style" || osResourceType == "qgis_vector_style" ) { nEPSG = oParentRoot.GetInteger("vector_layer/srs/id", nEPSG); } else if( osResourceType == "raster_style") { nEPSG = oParentRoot.GetInteger("raster_layer/srs/id", nEPSG); } } } // Create raster dataset. std::string osRasterUrl = NGWAPI::GetTMS(osUrl, osResourceId); char* pszRasterUrl = CPLEscapeString(osRasterUrl.c_str(), -1, CPLES_XML); const char *pszConnStr = CPLSPrintf("<GDAL_WMS><Service name=\"TMS\">" "<ServerUrl>%s</ServerUrl></Service><DataWindow>" "<UpperLeftX>-20037508.34</UpperLeftX><UpperLeftY>20037508.34</UpperLeftY>" "<LowerRightX>20037508.34</LowerRightX><LowerRightY>-20037508.34</LowerRightY>" "<TileLevel>%d</TileLevel><TileCountX>1</TileCountX>" "<TileCountY>1</TileCountY><YOrigin>top</YOrigin></DataWindow>" "<Projection>EPSG:%d</Projection><BlockSizeX>256</BlockSizeX>" "<BlockSizeY>256</BlockSizeY><BandsCount>%d</BandsCount>" "<Cache><Type>file</Type><Expires>%d</Expires><MaxSize>%d</MaxSize>" "</Cache><ZeroBlockHttpCodes>204,404</ZeroBlockHttpCodes></GDAL_WMS>", pszRasterUrl, 22, // NOTE: We have no limit in zoom levels. nEPSG, // NOTE: Default SRS is EPSG:3857. 4, nCacheExpires, nCacheMaxSize); CPLFree( pszRasterUrl ); poRasterDS = reinterpret_cast<GDALDataset*>(GDALOpenEx(pszConnStr, GDAL_OF_READONLY | GDAL_OF_RASTER | GDAL_OF_INTERNAL, nullptr, nullptr, nullptr)); if( poRasterDS ) { bResult = true; nRasterXSize = poRasterDS->GetRasterXSize(); nRasterYSize = poRasterDS->GetRasterYSize(); for( int iBand = 1; iBand <= poRasterDS->GetRasterCount(); iBand++ ) { SetBand( iBand, new NGWWrapperRasterBand( poRasterDS->GetRasterBand( iBand )) ); } // Set pixel limits. bool bHasTransform = false; double geoTransform[6] = { 0.0 }; double invGeoTransform[6] = { 0.0 }; if(poRasterDS->GetGeoTransform(geoTransform) == CE_None) { bHasTransform = GDALInvGeoTransform(geoTransform, invGeoTransform) == TRUE; } if(bHasTransform) { GDALApplyGeoTransform(invGeoTransform, stExtent.MinX, stExtent.MinY, &stPixelExtent.MinX, &stPixelExtent.MaxY); GDALApplyGeoTransform(invGeoTransform, stExtent.MaxX, stExtent.MaxY, &stPixelExtent.MaxX, &stPixelExtent.MinY); CPLDebug("NGW", "Raster extent in px is: %f, %f, %f, %f", stPixelExtent.MinX, stPixelExtent.MinY, stPixelExtent.MaxX, stPixelExtent.MaxY); } else { stPixelExtent.MinX = 0.0; stPixelExtent.MinY = 0.0; stPixelExtent.MaxX = std::numeric_limits<double>::max(); stPixelExtent.MaxY = std::numeric_limits<double>::max(); } } else { bResult = false; } } else if( osResourceType == "raster_layer" ) //FIXME: Do we need this check? && nOpenFlagsIn & GDAL_OF_RASTER ) { AddRaster( oRoot, papszHTTPOptions ); } else { bResult = false; } // TODO: Add support for baselayers, webmap, wfsserver_service, wmsserver_service. } } CSLDestroy( papszHTTPOptions ); return bResult; }
int GDALRPCTransform( void *pTransformArg, int bDstToSrc, int nPointCount, double *padfX, double *padfY, double *padfZ, int *panSuccess ) { VALIDATE_POINTER1( pTransformArg, "GDALRPCTransform", 0 ); GDALRPCTransformInfo *psTransform = (GDALRPCTransformInfo *) pTransformArg; GDALRPCInfo *psRPC = &(psTransform->sRPC); int i; if( psTransform->bReversed ) bDstToSrc = !bDstToSrc; int bands[1] = {1}; int nRasterXSize = 0, nRasterYSize = 0; /* -------------------------------------------------------------------- */ /* Lazy opening of the optionnal DEM file. */ /* -------------------------------------------------------------------- */ if(psTransform->pszDEMPath != NULL && psTransform->bHasTriedOpeningDS == FALSE) { int bIsValid = FALSE; psTransform->bHasTriedOpeningDS = TRUE; psTransform->poDS = (GDALDataset *) GDALOpen( psTransform->pszDEMPath, GA_ReadOnly ); if(psTransform->poDS != NULL && psTransform->poDS->GetRasterCount() >= 1) { const char* pszSpatialRef = psTransform->poDS->GetProjectionRef(); if (pszSpatialRef != NULL && pszSpatialRef[0] != '\0') { OGRSpatialReference* poWGSSpaRef = new OGRSpatialReference(SRS_WKT_WGS84); OGRSpatialReference* poDSSpaRef = new OGRSpatialReference(pszSpatialRef); if(!poWGSSpaRef->IsSame(poDSSpaRef)) psTransform->poCT =OGRCreateCoordinateTransformation( poWGSSpaRef, poDSSpaRef ); delete poWGSSpaRef; delete poDSSpaRef; } if (psTransform->poDS->GetGeoTransform( psTransform->adfGeoTransform) == CE_None && GDALInvGeoTransform( psTransform->adfGeoTransform, psTransform->adfReverseGeoTransform )) { bIsValid = TRUE; } } if (!bIsValid && psTransform->poDS != NULL) { GDALClose(psTransform->poDS); psTransform->poDS = NULL; } } if (psTransform->poDS) { nRasterXSize = psTransform->poDS->GetRasterXSize(); nRasterYSize = psTransform->poDS->GetRasterYSize(); } /* -------------------------------------------------------------------- */ /* The simple case is transforming from lat/long to pixel/line. */ /* Just apply the equations directly. */ /* -------------------------------------------------------------------- */ if( bDstToSrc ) { for( i = 0; i < nPointCount; i++ ) { if(psTransform->poDS) { double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfXOrig = padfX[i]; double dfYOrig = padfY[i]; double dfZOrig = padfZ[i]; if (!psTransform->poCT->Transform( 1, &dfXOrig, &dfYOrig, &dfZOrig)) { panSuccess[i] = FALSE; continue; } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfXOrig, dfYOrig, &dfX, &dfY ); } else GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, padfX[i], padfY[i], &dfX, &dfY ); int dX = int(dfX); int dY = int(dfY); if (!(dX >= 0 && dY >= 0 && dX+2 <= nRasterXSize && dY+2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } double dfDEMH(0); double dfDeltaX = dfX - dX; double dfDeltaY = dfY - dY; if(psTransform->eResampleAlg == DRA_Cubic) { int dXNew = dX - 1; int dYNew = dY - 1; if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //cubic interpolation int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4, &adElevData, 4, 4, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfSumH(0); for ( int i = 0; i < 5; i++ ) { // Loop across the X axis for ( int j = 0; j < 5; j++ ) { // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation int dKernIndX = j - 1; int dKernIndY = i - 1; double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY); // Create a sum of all values // adjusted for the pixel's calculated weight dfSumH += adElevData[j + i * 4] * dfPixelWeight; } } dfDEMH = dfSumH; } else if(psTransform->eResampleAlg == DRA_Bilinear) { if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //bilinear interpolation int anElevData[4] = {0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2, &anElevData, 2, 2, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfDeltaX1 = 1.0 - dfDeltaX; double dfDeltaY1 = 1.0 - dfDeltaY; double dfXZ1 = anElevData[0] * dfDeltaX1 + anElevData[1] * dfDeltaX; double dfXZ2 = anElevData[2] * dfDeltaX1 + anElevData[3] * dfDeltaX; double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; dfDEMH = dfYZ; } else { if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1, &dfDEMH, 1, 1, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } } RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, padfX + i, padfY + i ); } else RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, padfX + i, padfY + i ); panSuccess[i] = TRUE; } return TRUE; } /* -------------------------------------------------------------------- */ /* Compute the inverse (pixel/line/height to lat/long). This */ /* function uses an iterative method from an initial linear */ /* approximation. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nPointCount; i++ ) { double dfResultX, dfResultY; if(psTransform->poDS) { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfZ = 0; if (!psTransform->poCT->Transform(1, &dfResultX, &dfResultY, &dfZ)) { panSuccess[i] = FALSE; continue; } } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfResultX, dfResultY, &dfX, &dfY ); int dX = int(dfX); int dY = int(dfY); double dfDEMH(0); double dfDeltaX = dfX - dX; double dfDeltaY = dfY - dY; if(psTransform->eResampleAlg == DRA_Cubic) { int dXNew = dX - 1; int dYNew = dY - 1; if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //cubic interpolation int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4, &adElevData, 4, 4, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfSumH(0); for ( int i = 0; i < 5; i++ ) { // Loop across the X axis for ( int j = 0; j < 5; j++ ) { // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation int dKernIndX = j - 1; int dKernIndY = i - 1; double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY); // Create a sum of all values // adjusted for the pixel's calculated weight dfSumH += adElevData[j + i * 4] * dfPixelWeight; } } dfDEMH = dfSumH; } else if(psTransform->eResampleAlg == DRA_Bilinear) { if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //bilinear interpolation int adElevData[4] = {0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2, &adElevData, 2, 2, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfDeltaX1 = 1.0 - dfDeltaX; double dfDeltaY1 = 1.0 - dfDeltaY; double dfXZ1 = adElevData[0] * dfDeltaX1 + adElevData[1] * dfDeltaX; double dfXZ2 = adElevData[2] * dfDeltaX1 + adElevData[3] * dfDeltaX; double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; dfDEMH = dfYZ; } else { if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1, &dfDEMH, 1, 1, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } } RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } else { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } padfX[i] = dfResultX; padfY[i] = dfResultY; panSuccess[i] = TRUE; } return TRUE; }
void wxGISRasterRGBRenderer::Draw(wxGISDataset* pRasterDataset, wxGISEnumDrawPhase DrawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel) { wxGISRasterDataset* pRaster = dynamic_cast<wxGISRasterDataset*>(pRasterDataset); if(!pRaster) return; IDisplayTransformation* pDisplayTransformation = pDisplay->GetDisplayTransformation(); OGRSpatialReference* pDisplaySpatialReference = pDisplayTransformation->GetSpatialReference(); OGRSpatialReference* pRasterSpatialReference = pRaster->GetSpatialReference(); bool IsSpaRefSame(true); if(pDisplaySpatialReference && pDisplaySpatialReference) IsSpaRefSame = pDisplaySpatialReference->IsSame(pRasterSpatialReference); OGREnvelope VisibleBounds = pDisplayTransformation->GetVisibleBounds(); OGREnvelope* pRasterExtent = pRaster->GetEnvelope(); OGREnvelope RasterEnvelope, DisplayEnvelope; if(!IsSpaRefSame) { RasterEnvelope = TransformEnvelope(pRasterExtent, pRasterSpatialReference, pDisplaySpatialReference); } else { RasterEnvelope = *pRasterExtent; } bool IsZoomIn(false); //IsZoomIn = RasterEnvelope.Contains(VisibleBounds); IsZoomIn = RasterEnvelope.MaxX > VisibleBounds.MaxX || RasterEnvelope.MaxY > VisibleBounds.MaxY || RasterEnvelope.MinX < VisibleBounds.MinX || RasterEnvelope.MinY < VisibleBounds.MinY; if(IsZoomIn) { //intersect bounds OGREnvelope DrawBounds; DrawBounds.MinX = MAX(RasterEnvelope.MinX, VisibleBounds.MinX); DrawBounds.MinY = MAX(RasterEnvelope.MinY, VisibleBounds.MinY); DrawBounds.MaxX = MIN(RasterEnvelope.MaxX, VisibleBounds.MaxX); DrawBounds.MaxY = MIN(RasterEnvelope.MaxY, VisibleBounds.MaxY); OGRRawPoint OGRRawPoints[2]; OGRRawPoints[0].x = DrawBounds.MinX; OGRRawPoints[0].y = DrawBounds.MinY; OGRRawPoints[1].x = DrawBounds.MaxX; OGRRawPoints[1].y = DrawBounds.MaxY; wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2); if(!pDCPoints) { wxDELETEA(pDCPoints); return; } int nDCXOrig = pDCPoints[0].x; int nDCYOrig = pDCPoints[1].y; int nWidth = pDCPoints[1].x - pDCPoints[0].x; int nHeight = pDCPoints[0].y - pDCPoints[1].y; wxDELETEA(pDCPoints); if(nWidth <= 20 || nHeight <= 20) return; GDALDataset* pGDALDataset = pRaster->GetRaster(); int nBandCount = pGDALDataset->GetRasterCount(); //hack! int bands[3]; if(nBandCount < 3) { bands[0] = 1; bands[1] = 1; bands[2] = 1; } else { bands[0] = 1; bands[1] = 2; bands[2] = 3; } double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; double adfReverseGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; CPLErr err = pGDALDataset->GetGeoTransform(adfGeoTransform); bool bNoTransform(false); if(err != CE_None) { bNoTransform = true; } else { int nRes = GDALInvGeoTransform( adfGeoTransform, adfReverseGeoTransform ); } //2. get image data from raster - draw part of the raster if(IsSpaRefSame) { double rMinX, rMinY, rMaxX, rMaxY; int nXSize = pGDALDataset->GetRasterXSize(); int nYSize = pGDALDataset->GetRasterYSize(); if(bNoTransform) { rMinX = DrawBounds.MinX; rMaxX = DrawBounds.MaxX; rMaxY = nYSize - DrawBounds.MinY; rMinY = nYSize - DrawBounds.MaxY; } else { GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MinX, DrawBounds.MinY, &rMinX, &rMaxY ); GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MaxX, DrawBounds.MaxY, &rMaxX, &rMinY ); } //double rRealMinX, rRealMinY, rRealMaxX, rRealMaxY; //rRealMinX = MIN(rMinX, rMaxX); //rRealMinY = MIN(rMinY, rMaxY); //rRealMaxX = MAX(rMinX, rMaxX); //rRealMaxY = MAX(rMinY, rMaxY); double rImgWidth = rMaxX - rMinX; double rImgHeight = rMaxY - rMinY; int nImgWidth = ceil(rImgWidth) + 1; int nImgHeight = ceil(rImgHeight) + 1; //read in buffer int nMinX = floor(rMinX); int nMinY = floor(rMinY); if(nMinX < 0) nMinX = 0; if(nMinY < 0) nMinY = 0; if(nImgWidth > nXSize - nMinX) nImgWidth -= 1; if(nImgHeight > nYSize - nMinY) nImgHeight -= 1; //create buffer int nWidthOut = nWidth > nImgWidth ? nImgWidth : (double)nWidth + 1.0 /*/ 1.2 / 2 * 2/ 1.5 + 1) / 2*/; int nHeightOut = nHeight > nImgHeight ? nImgHeight : (double)nHeight + 1.0 /*/ 1.2 / 2 * 2 / 1.5 + 1) / 2*/; double rImgWidthOut = nWidth > nImgWidth ? rImgWidth : (double)nWidthOut * rImgWidth / nImgWidth; double rImgHeightOut = nHeight > nImgHeight ? rImgHeight : (double)nHeightOut * rImgHeight / nImgHeight; unsigned char* data = new unsigned char[nWidthOut * nHeightOut * 3]; err = pGDALDataset->AdviseRead(nMinX, nMinY, nImgWidth, nImgHeight, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, NULL); if(err != CE_None) { wxDELETEA(data);//delete[](data); return; } err = pGDALDataset->RasterIO(GF_Read, nMinX, nMinY, nImgWidth, nImgHeight, data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char)); if(err != CE_None) { wxDELETEA(data);//delete[](data); return; } //scale pTempData to data using interpolation methods pDisplay->DrawBitmap(Scale(data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, rImgWidthOut/*rImgWidth*/, rImgHeightOut/*rImgHeight*/, nWidth + 1 , nHeight + 1, rMinX - nMinX, rMinY - nMinY, /*enumGISQualityNearest*/enumGISQualityBilinear, pTrackCancel), nDCXOrig, nDCYOrig); wxDELETEA(data); } else { //void *hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, NULL, pszDstWKT, FALSE, 0, 1 ); //GDALDestroyGenImgProjTransformer( hTransformArg ); //// //get new envelope - it may rotate //// OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( pDisplaySpatialReference, pRasterSpatialReference); ////// get real envelope ////// poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MaxY); ////// poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MinY); ////// poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MinY); ////// poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MaxY); //// OCTDestroyCoordinateTransformation(poCT); } } else { //1. convert newrasterenvelope to DC OGRRawPoint OGRRawPoints[2]; OGRRawPoints[0].x = RasterEnvelope.MinX; OGRRawPoints[0].y = RasterEnvelope.MinY; OGRRawPoints[1].x = RasterEnvelope.MaxX; OGRRawPoints[1].y = RasterEnvelope.MaxY; wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2); //2. get image data from raster - buffer size = DC_X and DC_Y - draw full raster if(!pDCPoints) { wxDELETEA(pDCPoints); return; } int nDCXOrig = pDCPoints[0].x; int nDCYOrig = pDCPoints[1].y; int nWidth = pDCPoints[1].x - pDCPoints[0].x; int nHeight = pDCPoints[0].y - pDCPoints[1].y; delete[](pDCPoints); GDALDataset* pGDALDataset = pRaster->GetRaster(); int nImgWidth = pGDALDataset->GetRasterXSize(); int nImgHeight = pGDALDataset->GetRasterYSize(); int nBandCount = pGDALDataset->GetRasterCount(); //hack! int bands[3]; if(nBandCount < 3) { bands[0] = 1; bands[1] = 1; bands[2] = 1; } else { bands[0] = 1; bands[1] = 2; bands[2] = 3; } //create buffer unsigned char* data = new unsigned char[nWidth * nHeight * 3]; if(IsSpaRefSame) { //read in buffer CPLErr err = pGDALDataset->RasterIO(GF_Read, 0, 0, nImgWidth, nImgHeight, data, nWidth, nHeight, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char)); if(err != CE_None) { wxDELETEA(data); return; } } else { //1. calc Width & Height of TempData with same aspect ratio of raster //2. create pTempData buffer unsigned char* pTempData; //3. fill data //4. for each pixel of data buffer get pixel from pTempData using OGRCreateCoordinateTransformation //delete[](data); } //3. draw //think about transparancy! wxImage ResultImage(nWidth, nHeight, data); pDisplay->DrawBitmap(ResultImage, nDCXOrig, nDCYOrig); //delete[](data); } }
int GDALRPCTransform( void *pTransformArg, int bDstToSrc, int nPointCount, double *padfX, double *padfY, double *padfZ, int *panSuccess ) { VALIDATE_POINTER1( pTransformArg, "GDALRPCTransform", 0 ); GDALRPCTransformInfo *psTransform = (GDALRPCTransformInfo *) pTransformArg; GDALRPCInfo *psRPC = &(psTransform->sRPC); int i; if( psTransform->bReversed ) bDstToSrc = !bDstToSrc; /* -------------------------------------------------------------------- */ /* Lazy opening of the optionnal DEM file. */ /* -------------------------------------------------------------------- */ if(psTransform->pszDEMPath != NULL && psTransform->bHasTriedOpeningDS == FALSE) { int bIsValid = FALSE; psTransform->bHasTriedOpeningDS = TRUE; psTransform->poDS = (GDALDataset *) GDALOpen( psTransform->pszDEMPath, GA_ReadOnly ); if(psTransform->poDS != NULL && psTransform->poDS->GetRasterCount() >= 1) { const char* pszSpatialRef = psTransform->poDS->GetProjectionRef(); if (pszSpatialRef != NULL && pszSpatialRef[0] != '\0') { OGRSpatialReference* poWGSSpaRef = new OGRSpatialReference(SRS_WKT_WGS84); OGRSpatialReference* poDSSpaRef = new OGRSpatialReference(pszSpatialRef); if(!poWGSSpaRef->IsSame(poDSSpaRef)) psTransform->poCT =OGRCreateCoordinateTransformation( poWGSSpaRef, poDSSpaRef ); delete poWGSSpaRef; delete poDSSpaRef; } if (psTransform->poDS->GetGeoTransform( psTransform->adfGeoTransform) == CE_None && GDALInvGeoTransform( psTransform->adfGeoTransform, psTransform->adfReverseGeoTransform )) { bIsValid = TRUE; } } if (!bIsValid && psTransform->poDS != NULL) { GDALClose(psTransform->poDS); psTransform->poDS = NULL; } } /* -------------------------------------------------------------------- */ /* The simple case is transforming from lat/long to pixel/line. */ /* Just apply the equations directly. */ /* -------------------------------------------------------------------- */ if( bDstToSrc ) { for( i = 0; i < nPointCount; i++ ) { if(psTransform->poDS) { double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfXOrig = padfX[i]; double dfYOrig = padfY[i]; double dfZOrig = padfZ[i]; if (!psTransform->poCT->Transform( 1, &dfXOrig, &dfYOrig, &dfZOrig)) { panSuccess[i] = FALSE; continue; } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfXOrig, dfYOrig, &dfX, &dfY ); } else GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, padfX[i], padfY[i], &dfX, &dfY ); double dfDEMH(0); if( !GDALRPCGetDEMHeight( psTransform, dfX, dfY, &dfDEMH) ) { if( psTransform->bHasDEMMissingValue ) dfDEMH = psTransform->dfDEMMissingValue; else { panSuccess[i] = FALSE; continue; } } RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, padfX + i, padfY + i ); } else RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, padfX + i, padfY + i ); panSuccess[i] = TRUE; } return TRUE; } /* -------------------------------------------------------------------- */ /* Compute the inverse (pixel/line/height to lat/long). This */ /* function uses an iterative method from an initial linear */ /* approximation. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nPointCount; i++ ) { double dfResultX, dfResultY; if(psTransform->poDS) { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfZ = 0; if (!psTransform->poCT->Transform(1, &dfResultX, &dfResultY, &dfZ)) { panSuccess[i] = FALSE; continue; } } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfResultX, dfResultY, &dfX, &dfY ); double dfDEMH(0); if( !GDALRPCGetDEMHeight( psTransform, dfX, dfY, &dfDEMH) ) { if( psTransform->bHasDEMMissingValue ) dfDEMH = psTransform->dfDEMMissingValue; else { panSuccess[i] = FALSE; continue; } } RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } else { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } padfX[i] = dfResultX; padfY[i] = dfResultY; panSuccess[i] = TRUE; } return TRUE; }