bool DemReader::Open(std::wstring fullPath, StudyControllerPtr studyController, MapControllerPtr mapController, ProgressDlgPtr progressDlg) { GDALAllRegister(); bool bElevationMap; uint numBands; double adfGeoTransform[6]; GDALDataset* gdalDataset; int nBlockXSize, nBlockYSize; MapModelPtr mapModel = mapController->GetMapModel(); FileHeader* header = mapModel->GetHeader(); GDALRasterBand* gdalBand; if(App::Inst().GetLayerTreeController()->GetIsBlankRaster()) { LayerTreeControllerPtr ltc = App::Inst().GetLayerTreeController(); VectorMapLayerPtr vectorMapLayer =ltc->GetVectorMapLayer(0); VectorMapModelPtr vectorMapModel= vectorMapLayer->GetVectorMapController()->GetVectorMapModel(); double vectorMinX = vectorMapModel->GetVectorBoundary_MinX(); double vectorMinY = vectorMapModel->GetVectorBoundary_MinY(); double vectorMaxX = vectorMapModel->GetVectorBoundary_MaxX(); double vectorMaxY = vectorMapModel->GetVectorBoundary_MaxY(); double bRaster_width = 1000; double bRaster_height= 1000; double x_res = (vectorMaxX - vectorMinX) / bRaster_width; double y_res = (vectorMaxY - vectorMinY) / bRaster_height; numBands = 3; bElevationMap = false; header->nCols = 1000; header->nRows = 1000; header->noDataValue=0.0; //adfGeoTransform[6]= {vectorMinX, x_res, 0.0, vectorMaxY, 0.0, -y_res}; adfGeoTransform[0]= vectorMinX; adfGeoTransform[1]= x_res; adfGeoTransform[2]= 0.0; adfGeoTransform[3]= vectorMaxY; adfGeoTransform[4] = 0.0; adfGeoTransform[5]= -y_res; } else { std::string tempStr(fullPath.begin(), fullPath.end()); gdalDataset = (GDALDataset*) GDALOpen( tempStr.c_str(), GA_ReadOnly ); if(gdalDataset == NULL) { Log::Inst().Warning("(Warning) Failed to open file at " + tempStr + "."); return false; } // determine type of file based on number of raster bands numBands = gdalDataset->GetRasterCount(); if(numBands == 1) bElevationMap = true; else if(numBands == 3 || numBands == 4) bElevationMap = false; else { Log::Inst().Warning("(Warning) File type not supported. Please contact the GenGIS to request support for the file format."); } CPLErr err = gdalDataset->GetGeoTransform( adfGeoTransform ); // check if we have a map without any transformation information // in which case assume we have a custom image file where y should // be in the south (down) direction if(err == CE_Failure) adfGeoTransform[5] = -1; gdalBand = gdalDataset->GetRasterBand( 1 ); gdalBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); // get original data dimensions header->nCols = gdalBand->GetXSize(); header->nRows = gdalBand->GetYSize(); header->noDataValue = gdalBand->GetNoDataValue(); // Setup desired projection if(!SetupProjection(gdalDataset, studyController, adfGeoTransform, header->nCols, header->nRows, bElevationMap)) { GDALClose(gdalDataset); return false; } } if(progressDlg) { if(!App::Inst().GetLayerTreeController()->GetIsBlankRaster()) { if(!progressDlg->Update(0, _T("Reading map file..."))) { GDALClose(gdalDataset); return false; } } else { if(!progressDlg->Update(0, _T("Initializing the Visualization..."))) { GDALClose(gdalDataset); return false; } } } // check whether it's too large to handle all the data float* elevations = NULL; if(bElevationMap && !App::Inst().GetLayerTreeController()->GetIsBlankRaster()) { try { elevations = new float[gdalBand->GetXSize()* gdalBand->GetYSize()]; } catch(std::bad_alloc&) { Log::Inst().Warning("(Warning) Insufficent memory for elevation map."); GDALClose(gdalDataset); return false; } gdalBand->RasterIO( GF_Read, 0, 0, gdalBand->GetXSize(), gdalBand->GetYSize(), elevations, gdalBand->GetXSize(), gdalBand->GetYSize(), GDT_Float32, 0, 0 ); } // project all map model cells Point3D* grid; try { grid = new Point3D[header->nCols*header->nRows]; } catch(std::bad_alloc&) { Log::Inst().Warning("(Warning) Insufficent memory to load map."); GDALClose(gdalDataset); delete[] elevations; return false; } // populate grid with projected points and find extents of projected map double xOffset = adfGeoTransform[0]; double zOffset = adfGeoTransform[3]; int index = 0; double x, z; header->projExtents.x = header->projExtents.y = std::numeric_limits<float>::max(); header->projExtents.dx = header->projExtents.dy = -std::numeric_limits<float>::max(); ProjectionToolPtr projTool = studyController->GetProjectionTool(); for(int m = 0; m < header->nRows ; ++m) { xOffset = adfGeoTransform[0]; for(int n = 0; n < header->nCols; ++n) { x = xOffset; z = zOffset; if(studyController->IsProjectData() && studyController->IsGeographic() && !App::Inst().GetLayerTreeController()->GetIsBlankRaster()) { double elevation = (double)elevations[index]; if(!projTool->Transform(1, &x, &z, &elevation)) { Log::Inst().Warning("(Warning) Failed to project map."); GDALClose(gdalDataset); delete[] elevations; return false; } } xOffset += adfGeoTransform[1]; if(App::Inst().GetLayerTreeController()->GetIsBlankRaster()) { double X = x; double Z = z; grid[index].x = X; grid[index].z = Z; index++; if(X < header->projExtents.x) header->projExtents.x = X; if(Z < header->projExtents.y) header->projExtents.y = Z; if(X > header->projExtents.dx) header->projExtents.dx = X; if(Z > header->projExtents.dy) header->projExtents.dy = Z; } else { float X = (float)x; float Z = (float)z; grid[index].x = X; grid[index].z = Z; index++; if(X < header->projExtents.x) header->projExtents.x = X; if(Z < header->projExtents.y) header->projExtents.y = Z; if(X > header->projExtents.dx) header->projExtents.dx = X; if(Z > header->projExtents.dy) header->projExtents.dy = Z; } } zOffset += adfGeoTransform[5]; if(progressDlg) { if(!progressDlg->Update(int((float(m)/header->nRows)*50))) { GDALClose(gdalDataset); if(elevations != NULL) delete[] elevations; return false; } } } if(App::Inst().GetLayerTreeController()->GetIsBlankRaster()) { LayerTreeControllerPtr ltc = App::Inst().GetLayerTreeController(); VectorMapLayerPtr vectorMapLayer =ltc->GetVectorMapLayer(0); VectorMapModelPtr vectorMapModel= vectorMapLayer->GetVectorMapController()->GetVectorMapModel(); header->projExtents.x = vectorMapModel->GetVectorBoundary_MinX(); header->projExtents.dx = vectorMapModel->GetVectorBoundary_MaxX(); header->projExtents.y = vectorMapModel->GetVectorBoundary_MinY(); header->projExtents.dy = vectorMapModel->GetVectorBoundary_MaxY(); } // transform all points into unit grid space float minElevation = std::numeric_limits<float>::max(); float maxElevation = -std::numeric_limits<float>::max(); if(!TransformToGridSpace(grid, header, elevations, bElevationMap, minElevation, maxElevation, progressDlg)) { GDALClose(gdalDataset); if(elevations != NULL) delete[] elevations; return false; } // setup map model mapModel->SetMinElevationGridSpace(minElevation); mapModel->SetMaxElevationGridSpace(maxElevation); mapModel->SetMinElevation(minElevation/header->scaleFactor); mapModel->SetMaxElevation(maxElevation/header->scaleFactor); mapModel->SetElevationMap(bElevationMap); mapModel->SetGrid(grid); // report information in file to user if (!App::Inst().GetLayerTreeController()->GetIsBlankRaster()) MetaDataInfo(gdalDataset, mapController); else MetaDataInfoForBlankRaster(mapController, adfGeoTransform); // build texture that will be mapped onto terrain if(!App::Inst().GetLayerTreeController()->GetIsBlankRaster()){ if(!BuildTerrainTexture(gdalDataset, mapController, progressDlg)) { GDALClose(gdalDataset); if(elevations != NULL) delete[] elevations; return false; } // will free memory allocated to any GDALRasterBand objects GDALClose(gdalDataset); } // will free memory allocated to any GDALRasterBand objects if(elevations != NULL) delete[] elevations; return true; }