示例#1
0
bool LocationSetIO::ParseCSVFile( const std::vector<std::wstring>& csvTableRows, StudyControllerPtr studyController, std::vector<LocationModelPtr>& locationModels )
{
	const int ROWS_TO_SHOW_PROGRESS_DLG = 2000;

	// tokenize column names
	tokenizer< escaped_list_separator<wchar_t>, wstring::const_iterator, wstring > columnTokens(csvTableRows.at(0));
	vector<wstring> columnValues(columnTokens.begin(), columnTokens.end());
	if(columnValues.size() == 1)
	{
		// assume a tab-delimited file
		columnValues.clear();
		split(columnValues, csvTableRows.at(0), boost::is_any_of(_T("\t")));
	}

	ProgressDlgPtr progressDlg;
	if(csvTableRows.size() > ROWS_TO_SHOW_PROGRESS_DLG)
		progressDlg.reset(new ProgressDlg(_T("Loading location set"), _T("Reading locations..."), csvTableRows.size(), App::Inst().GetMainWindow()));

	uint rowNum = 1;
	vector<wstring>::const_iterator it;
	for(it = ++csvTableRows.begin(); it != csvTableRows.end(); ++it)
	{
		if(progressDlg && rowNum % 25 == 0)
			progressDlg->Update(rowNum);		

		rowNum++;

		tokenizer< escaped_list_separator<wchar_t>, wstring::const_iterator, wstring > rowTokens(*it);
		vector<wstring> rowValues(rowTokens.begin(), rowTokens.end());     
		if(rowValues.size() == 1)
		{
			// assume a tab-delimited file
			rowValues.clear();
			split(rowValues, *it, boost::is_any_of(_T("\t")));
		}

		if(columnValues.size() != rowValues.size())
		{
			wxString warning;
			warning.Printf(wxT("(Warning) Location file contains %d headings, but line %d contains only %d values. "), columnValues.size(), rowNum, rowValues.size());
			warning += (wxT("This line begins with the value '") + rowValues.at(0) + wxT("'.")).c_str();
			Log::Inst().Warning(warning);	
			return false;
		}

		wstring siteId     = _T("");
		wstring sampleId   = _T("");
		double  northing   = -std::numeric_limits<float>::max();
		double  easting    = -std::numeric_limits<float>::max();
		bool    bIsLatLong = false;
		bool	bReject	   = false;
		double  latitude   = -std::numeric_limits<float>::max();
		double  longitude  = -std::numeric_limits<float>::max();

		map<std::wstring,std::wstring> data;
		for(uint c = 0; c < columnValues.size(); ++c)
		{
			wstring header = StringTools::RemoveSurroundingWhiteSpaces(columnValues.at(c));
			wstring value = StringTools::RemoveSurroundingWhiteSpaces(rowValues.at(c));

			// determine which column we are looking at (this allows user to put columns in any order)
			if(StringTools::ToLower(header) == _T("site id") || StringTools::ToLower(header) == _T("siteid"))
				siteId = value;
			else if(StringTools::ToLower(header) == _T("sample id") || StringTools::ToLower(header) == _T("sampleid"))
				sampleId = value;
			else if(StringTools::ToLower(header) == _T("northing"))
				northing = StringTools::ToLong(value);
			else if(StringTools::ToLower(header) == _T("easting"))
				easting = StringTools::ToLong(value);
			else if(StringTools::ToLower(header) == _T("latitude"))
			{

				header = StringTools::ToUpper(header.substr(0,1)) + StringTools::ToLower(header.substr(1));
				// check if latitude is numeric
				if(!StringTools::IsDecimalNumber( StringTools::ToString(value) ) && !StringTools::IsInteger( StringTools::ToString(value) ) )
					bReject = true;
				latitude = StringTools::ToDouble(value);
				bIsLatLong = true;
			}
			else if(StringTools::ToLower(header) == _T("longitude"))
			{
				header = StringTools::ToUpper(header.substr(0,1)) + StringTools::ToLower(header.substr(1));

				// check if longitude is numeric
				if(!StringTools::IsDecimalNumber( StringTools::ToString(value) ) && !StringTools::IsInteger( StringTools::ToString(value) ) )
					bReject = true;
				longitude = StringTools::ToDouble(value);
				bIsLatLong = true;
			}

			data.insert(pair<wstring, wstring>(header, value));

		}

		// transform lat/lon coordinates to projected coordinates
		if(bIsLatLong)
		{
			double tempLat = latitude;
			double tempLat2 = latitude;
			if(studyController->IsProjectData())
			{
				ProjectionToolPtr projTool = studyController->GetProjectionTool();
				if(!projTool->Transform(1, &longitude, &latitude))
				{
					Log::Inst().Warning("(Warning) Failed to project data. Possibly missing 'Latitude' and 'Longitude' fields.");
					return false;
				}

				// if a point falls off the map, assume the map actually spans the 180 degree line
				if(longitude < App::Inst().GetMapController()->GetHeader()->projExtents.x)
				{
					double longNeg180 = -180;
					projTool->Transform(1, &longNeg180, &tempLat);

					double long180 = 180;
					projTool->Transform(1, &long180, &tempLat2);

					longitude = long180 + (longitude - longNeg180);
				}
			}

			northing = latitude;
			easting = longitude;
		}

		// check for required data
		if(siteId == _T(""))
		{
			if(sampleId != _T(""))
				siteId = sampleId;
			else
			{
				Log::Inst().Warning("(Warning) Missing 'Site Id' field.");
				return false;
			}
		}

		if(northing == -std::numeric_limits<float>::max())
		{
			Log::Inst().Warning("(Warning) Missing 'Latitude or Northing' field.");
			return false;
		}

		if(easting == -std::numeric_limits<float>::max())
		{
			Log::Inst().Warning("(Warning) Missing 'Longitude or Easting' field.");
			return false;
		}
		// remove spaces from siteId to avoid conflicts with trees
		siteId = StringTools::ReplaceChar(siteId, ' ','_');

		if (!bReject)
		{
			// create a new location model from this data
			LocationModelPtr locationModel(new LocationModel(siteId, northing, easting, data));
			locationModels.push_back(locationModel);
		}
	}

	return true;
}
示例#2
0
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;
}