Ejemplo n.º 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;
}
Ejemplo n.º 2
0
void ShpReader::VectorMetaDataInfo(OGRDataSource* OGRDataset, StudyControllerPtr studyController, VectorMapControllerPtr vectorMapController)
{	
	vFileMetaData* vHeader = vectorMapController->GetVectorMapModel()->GetVectorMetaData();
    OGRLayer *poLayer = OGRDataset->GetLayer( 0 );	
	char *originalWkt = NULL;	
	char *destinationWkt = NULL;

	OGREnvelope psEnvelope;
	poLayer->GetExtent( &psEnvelope );
	vHeader->originalExtents.x = psEnvelope.MinX;
	vHeader->originalExtents.dx = psEnvelope.MaxX;
	vHeader->originalExtents.y = psEnvelope.MinY; 
	vHeader->originalExtents.dy = psEnvelope.MaxY;
	Log::Inst().Write("Original Extents: ");
	Log::Inst().Write(_T("Lower, Left (x,y): ") +wxString(StringTools::ToStringW(vHeader->originalExtents.x, 2).c_str()) + _T(", ") 
		+ wxString(StringTools::ToStringW(vHeader->originalExtents.y, 2).c_str()));	
	Log::Inst().Write(_T("Upper, Right (x,y): ") +wxString(StringTools::ToStringW(vHeader->originalExtents.dx, 2).c_str()) + _T(", ") 
		+ wxString(StringTools::ToStringW(vHeader->originalExtents.dy, 2).c_str()));		

	vHeader->numFeatures= poLayer->GetFeatureCount();
	Log::Inst().Write("Number of Features: " + StringTools::ToString(vHeader->numFeatures));
	
	std::string type;
	OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
	if ( wkbFlatten( poFDefn->GetGeomType() ) == wkbPoint || wkbFlatten( poFDefn->GetGeomType() ) == wkbMultiPoint )
		 type="Point";
	else if ( wkbFlatten(poFDefn->GetGeomType() ) == wkbLineString || wkbFlatten(poFDefn->GetGeomType() ) == wkbMultiLineString )
		type="Polyline";
	else if ( wkbFlatten( poFDefn->GetGeomType() ) == wkbPolygon || wkbFlatten( poFDefn->GetGeomType() ) == wkbMultiPolygon )
		 type="Polygon";  	
	else
		type="Unknown";

	 vHeader->geometryType=type;
	 Log::Inst().Write("Geometry Type: "+ type);

	OGRSpatialReference* originalShpSR = poLayer->GetSpatialRef();	
	if (originalShpSR != NULL)
	{
		originalShpSR->exportToWkt(&originalWkt);	
		vHeader->originalProjection = std::string(originalWkt);
	}
	Log::Inst().Write("Original Projection: " + vHeader->originalProjection);
	Log::Inst().Write("");
	ProjectionToolPtr projTool = studyController->GetProjectionTool();
	if (projTool != NULL)
	{
		OGRSpatialReference *destinationCS= projTool->GetTargetCS ();
		destinationCS->exportToWkt(&destinationWkt);
		vHeader->destinationProjection = std::string(destinationWkt);
	}

	vHeader->currentExtents.x = vectorMapController->GetVectorMapModel()->GetVectorBoundary_MinX();
	vHeader->currentExtents.y = vectorMapController->GetVectorMapModel()->GetVectorBoundary_MinY();	

	vHeader->currentExtents.dx = vectorMapController->GetVectorMapModel()->GetVectorBoundary_MaxX();
	vHeader->currentExtents.dy = vectorMapController->GetVectorMapModel()->GetVectorBoundary_MaxY();
	//Log::Inst().Write("Upper, Right (x,y): " +
	//	StringTools::ToString(vHeader->currentExtents.dx) + ", " +
		//StringTools::ToString(vHeader->currentExtents.dy));
	
}
Ejemplo n.º 3
0
bool ShpReader::SetupVectorProjection(OGRDataSource* OGRDataset, StudyControllerPtr studyController, OGRLayer* poLayer, VectorMapControllerPtr vectorMapController)
{
	//If there exists a map layer, the vector file will be projected based on the projection of the map layer
	if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() > 0 )
	{
		ProjectionToolPtr projTool = studyController->GetProjectionTool();
		OGRSpatialReference* currentShpSR = poLayer->GetSpatialRef();
		if (!studyController->IsProjectData() && !studyController->IsGeographic())
		{
			needProjection=false;			
			Log::Inst().Write("The projection information for this study is being ignored.");
		}
		else
		{
	
			if(currentShpSR != NULL) 
			{
				if(currentShpSR->IsGeographic())
				{
					Log::Inst().Write("Loading vector map with geographic coordinates.");
					studyController->SetProjectData(true);
					studyController->SetGeographic(true);
					needProjection=true;
					poTransform = studyController->GetProjectionTool();
				}
				else if(currentShpSR->IsProjected())
				{
					studyController->SetProjectData(true);
					studyController->SetGeographic(false);
					needProjection=true;
					Log::Inst().Write("Loading vector map with projected coordinates.");
					ProjectionToolPtr projTool = studyController->GetProjectionTool();
					//OGRSpatialReference* currentLatLong = currentShpSR->CloneGeogCS();
					OGRSpatialReference *targetCS= projTool->GetTargetCS ();
					if(targetCS != NULL && !currentShpSR->IsSame(targetCS)) 
						poTransform.reset(OGRCreateCoordinateTransformation(currentShpSR, targetCS));
					
					else
						needProjection=false;

				}
				else
				{
				// The user should probably be made aware of this warning.
					Log::Inst().Warning("(Warning) Unknown type of coordinate system.");
					return false;
				}
			}		
	

			else 
			{
				//studyController->SetProjectData(false);
				//studyController->SetGeographic(false);
				needProjection=false;		
				
				Log::Inst().Write("Coordinate system information is not available for this map.");
				Log::Inst().Write("As a result, the projection information for this study is being ignored.");
				Log::Inst().Write("");
			
			}

		return true;
		}
	}
	// App::Inst().GetLayerTreeController()->GetNumMapLayers() ==0
	else
	{
		OGRSpatialReference* currentShpSR = poLayer->GetSpatialRef();
	//OGRSpatialReference oSource;
		if(currentShpSR != NULL) 
		{
			if(currentShpSR->IsGeographic())
			{
			// lat/lon coordinates are using the geographic projection (aka, plate carrée) 
				Log::Inst().Write("Loading vector map with lat/long coordinates.");
				studyController->SetProjectData(true);
				studyController->SetGeographic(true);
				needProjection=true;

			// determine centre of map
				VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel();
				float vectorMinX= vectorMapModel->GetVectorBoundary_MinX();
				float vectorMinY = vectorMapModel->GetVectorBoundary_MinY();
				float vectorMaxX = vectorMapModel->GetVectorBoundary_MaxX();
				float vectorMaxY = vectorMapModel->GetVectorBoundary_MaxY();
			
				studyController->SetCentreLongitude(float(vectorMinX + fabs(vectorMinX - vectorMaxX) / 2.0));			
				studyController->SetCentreLatitude(float(vectorMinY + fabs(vectorMinY - vectorMaxY) / 2.0));

				studyController->SetFirstStandardParallel(vectorMinY);
				studyController->SetSecondStandardParallel(vectorMaxY);

				studyController->CalculateProjectionTool(currentShpSR);
				poTransform = studyController->GetProjectionTool();

			}
			else if(currentShpSR->IsProjected())
			{
				studyController->SetProjectData(true);
				studyController->SetGeographic(false);
				Log::Inst().Write("Loading vector map with projected coordinates.");
				studyController->CalculateProjectionTool(currentShpSR);
				poTransform = studyController->GetProjectionTool();
				needProjection=false;
			}
			else
			{
				// The user should probably be made aware of this warning.
				Log::Inst().Warning("(Warning) Unknown type of coordinate system.");
				return false;
				}
		}
		else 
		{
			studyController->SetProjectData(false);
			studyController->SetGeographic(false);
			needProjection=false;
		
			
			Log::Inst().Write("Coordinate system information is not available for this map.");
			Log::Inst().Write("As a result, the projection information for this study is being ignored.");
			Log::Inst().Write("To overlaid a Vector map on top of this map, the vector map must be specified in the same coordinate system as this map");
			Log::Inst().Write("");
		
		}
		}

	return true;
}
Ejemplo n.º 4
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;
}