2003-11-25 19:40:10 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
|
|
|
*
|
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef DATASET_H
|
|
|
|
#define DATASET_H 1
|
|
|
|
|
|
|
|
#include <osg/Node>
|
|
|
|
#include <osg/Matrixd>
|
|
|
|
#include <osg/BoundingBox>
|
|
|
|
#include <osg/Image>
|
|
|
|
#include <osg/Shape>
|
|
|
|
|
|
|
|
#include <osgTerrain/CoordinateSystem>
|
|
|
|
|
2003-12-18 01:02:23 +08:00
|
|
|
#include <set>
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
#include <gdal_priv.h>
|
|
|
|
|
|
|
|
class DataSet : public osg::Referenced
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
class Source;
|
|
|
|
|
|
|
|
|
|
|
|
struct SpatialProperties
|
|
|
|
{
|
|
|
|
SpatialProperties():
|
|
|
|
_numValuesX(0),
|
|
|
|
_numValuesY(0),
|
|
|
|
_numValuesZ(0) {}
|
|
|
|
|
|
|
|
SpatialProperties(const SpatialProperties& sp):
|
|
|
|
_cs(sp._cs),
|
|
|
|
_geoTransform(sp._geoTransform),
|
|
|
|
_extents(sp._extents),
|
|
|
|
_numValuesX(sp._numValuesX),
|
|
|
|
_numValuesY(sp._numValuesY),
|
|
|
|
_numValuesZ(sp._numValuesZ) {}
|
|
|
|
|
2004-01-16 05:07:34 +08:00
|
|
|
SpatialProperties(osgTerrain::CoordinateSystem* cs, const osg::BoundingBox& extents):
|
|
|
|
_cs(cs),
|
|
|
|
_extents(extents),
|
|
|
|
_numValuesX(0),
|
|
|
|
_numValuesY(0),
|
|
|
|
_numValuesZ(0) {}
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
SpatialProperties& operator = (const SpatialProperties& sp)
|
|
|
|
{
|
|
|
|
if (&sp==this) return *this;
|
|
|
|
|
|
|
|
_cs = sp._cs;
|
|
|
|
_geoTransform = sp._geoTransform;
|
|
|
|
_extents = sp._extents;
|
|
|
|
_numValuesX = sp._numValuesX;
|
|
|
|
_numValuesY = sp._numValuesY;
|
|
|
|
_numValuesZ = sp._numValuesZ;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
osg::ref_ptr<osgTerrain::CoordinateSystem> _cs;
|
|
|
|
osg::Matrixd _geoTransform;
|
|
|
|
osg::BoundingBox _extents;
|
|
|
|
unsigned int _numValuesX;
|
|
|
|
unsigned int _numValuesY;
|
|
|
|
unsigned int _numValuesZ;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DestinationData : public osg::Referenced, SpatialProperties
|
|
|
|
{
|
|
|
|
|
|
|
|
DestinationData():
|
|
|
|
_minDistance(0.0),
|
|
|
|
_maxDistance(FLT_MAX) {}
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::vector< osg::ref_ptr<osg::Node> > ModelList;
|
|
|
|
|
|
|
|
float _minDistance;
|
|
|
|
float _maxDistance;
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Image> _image;
|
|
|
|
osg::ref_ptr<osg::HeightField> _heightField;
|
|
|
|
ModelList _models;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SourceData : public osg::Referenced, public SpatialProperties
|
|
|
|
{
|
|
|
|
|
|
|
|
SourceData(Source* source=0):
|
|
|
|
_source(source),
|
|
|
|
_hasGCPs(false),
|
|
|
|
_gdalDataSet(0) {}
|
|
|
|
|
|
|
|
|
|
|
|
virtual ~SourceData()
|
|
|
|
{
|
|
|
|
if (_gdalDataSet) GDALClose(_gdalDataSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
static SourceData* readData(Source* source);
|
|
|
|
|
|
|
|
osg::BoundingBox getExtents(const osgTerrain::CoordinateSystem* cs) const;
|
|
|
|
|
2004-01-29 23:47:06 +08:00
|
|
|
const SpatialProperties& computeSpatialProperties(const osgTerrain::CoordinateSystem* cs) const;
|
2003-11-25 19:40:10 +08:00
|
|
|
|
2003-12-01 22:31:56 +08:00
|
|
|
bool intersects(const SpatialProperties& sp) const;
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void read(DestinationData& destination);
|
|
|
|
|
|
|
|
void readImage(DestinationData& destination);
|
|
|
|
void readHeightField(DestinationData& destination);
|
|
|
|
void readModels(DestinationData& destination);
|
|
|
|
|
|
|
|
Source* _source;
|
|
|
|
|
|
|
|
bool _hasGCPs;
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> _model;
|
|
|
|
GDALDataset* _gdalDataSet;
|
2003-12-01 22:31:56 +08:00
|
|
|
|
2004-01-29 23:47:06 +08:00
|
|
|
typedef std::map<const osgTerrain::CoordinateSystem*,SpatialProperties> SpatialPropertiesMap;
|
2004-01-16 05:07:34 +08:00
|
|
|
mutable SpatialPropertiesMap _spatialPropertiesMap;
|
|
|
|
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Source : public osg::Referenced, public SpatialProperties
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
enum Type
|
|
|
|
{
|
|
|
|
IMAGE,
|
|
|
|
HEIGHT_FIELD,
|
|
|
|
MODEL
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ParameterPolicy
|
|
|
|
{
|
|
|
|
PREFER_CONFIG_SETTINGS,
|
|
|
|
PREFER_FILE_SETTINGS
|
|
|
|
};
|
|
|
|
|
|
|
|
Source():
|
|
|
|
_type(IMAGE),
|
|
|
|
_sortValue(0.0),
|
|
|
|
_temporaryFile(false),
|
|
|
|
_coordinateSystemPolicy(PREFER_FILE_SETTINGS),
|
|
|
|
_geoTransformPolicy(PREFER_FILE_SETTINGS)
|
|
|
|
{}
|
|
|
|
|
|
|
|
Source(Type type, const std::string& filename):
|
|
|
|
_type(type),
|
|
|
|
_sortValue(0.0),
|
|
|
|
_filename(filename),
|
|
|
|
_temporaryFile(false),
|
|
|
|
_coordinateSystemPolicy(PREFER_FILE_SETTINGS),
|
|
|
|
_geoTransformPolicy(PREFER_FILE_SETTINGS)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void setSortValue(double s) { _sortValue = s; }
|
|
|
|
double getSortValue() const { return _sortValue; }
|
|
|
|
|
|
|
|
void setSortValueFromSourceDataResolution();
|
|
|
|
|
|
|
|
void setType(Type type) { _type = type; }
|
|
|
|
Type getType() const { return _type; }
|
|
|
|
|
|
|
|
void setFileName(const std::string& filename) { _filename = filename; }
|
|
|
|
const std::string& getFileName() const { return _filename; }
|
|
|
|
|
|
|
|
void setTemporaryFile(bool temporaryFile) { _temporaryFile = temporaryFile; }
|
|
|
|
bool getTemporaryFile() const { return _temporaryFile; }
|
|
|
|
|
|
|
|
void setCoordinateSystemPolicy(ParameterPolicy policy) { _coordinateSystemPolicy = policy; }
|
|
|
|
void setCoordinateSystem(osgTerrain::CoordinateSystem* cs) { _cs = cs; }
|
|
|
|
osgTerrain::CoordinateSystem* getCoordinateSystem() { return _cs.get(); }
|
|
|
|
|
|
|
|
|
|
|
|
void setGeoTransformPolicy(ParameterPolicy policy) { _geoTransformPolicy = policy; }
|
|
|
|
|
|
|
|
void setGeoTransform(osg::Matrixd& transform) { _geoTransform = transform; }
|
|
|
|
osg::Matrixd& getGeoTransform() { return _geoTransform; }
|
|
|
|
|
|
|
|
|
|
|
|
void setSourceData(SourceData* data) { _sourceData = data; if (_sourceData.valid()) _sourceData->_source = this; }
|
|
|
|
SourceData* getSourceData() { return _sourceData.get(); }
|
|
|
|
|
2003-12-20 06:55:35 +08:00
|
|
|
bool intersects(const SpatialProperties& sp) const
|
|
|
|
{
|
|
|
|
return _sourceData.valid()?_sourceData->intersects(sp):false;
|
|
|
|
}
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void loadSourceData();
|
2003-12-18 01:02:23 +08:00
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
bool needReproject(const osgTerrain::CoordinateSystem* cs) const;
|
2003-11-28 22:26:51 +08:00
|
|
|
|
|
|
|
bool needReproject(const osgTerrain::CoordinateSystem* cs, double minResolution, double maxResolution) const;
|
2003-11-25 19:40:10 +08:00
|
|
|
|
2003-11-28 22:26:51 +08:00
|
|
|
Source* doReproject(const std::string& filename, osgTerrain::CoordinateSystem* cs, double targetResolution=0.0) const;
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void buildOverviews();
|
2003-12-18 01:02:23 +08:00
|
|
|
|
|
|
|
|
2003-12-20 06:55:35 +08:00
|
|
|
struct ResolutionPair
|
|
|
|
{
|
|
|
|
ResolutionPair():
|
|
|
|
_resX(0.0),_resY(0.0) {}
|
|
|
|
|
|
|
|
ResolutionPair(double x,double y):
|
|
|
|
_resX(x),_resY(y) {}
|
|
|
|
|
|
|
|
bool operator < (const ResolutionPair& rhs) const
|
|
|
|
{
|
|
|
|
double minLHS = osg::minimum(_resX,_resY);
|
|
|
|
double minRHS = osg::minimum(rhs._resX,rhs._resY);
|
|
|
|
return minLHS<minRHS;
|
|
|
|
}
|
|
|
|
|
|
|
|
double _resX;
|
|
|
|
double _resY;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<ResolutionPair> ResolutionList;
|
2003-12-18 01:02:23 +08:00
|
|
|
|
2003-12-20 06:55:35 +08:00
|
|
|
void addRequiredResolution(double resX, double resY) { _requiredResolutions.push_back(ResolutionPair(resX,resY)); }
|
2003-12-18 01:02:23 +08:00
|
|
|
|
|
|
|
void setRequiredResolutions(ResolutionList& resolutions) { _requiredResolutions = resolutions; }
|
|
|
|
|
|
|
|
ResolutionList& getRequiredResolutions() { return _requiredResolutions; }
|
|
|
|
|
|
|
|
const ResolutionList& getRequiredResolutions() const { return _requiredResolutions; }
|
2003-12-20 06:55:35 +08:00
|
|
|
|
|
|
|
void consolodateRequiredResolutions();
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
|
|
Type _type;
|
|
|
|
|
|
|
|
double _sortValue;
|
|
|
|
|
|
|
|
std::string _filename;
|
|
|
|
bool _temporaryFile;
|
|
|
|
|
|
|
|
ParameterPolicy _coordinateSystemPolicy;
|
|
|
|
ParameterPolicy _geoTransformPolicy;
|
|
|
|
|
|
|
|
osg::ref_ptr<SourceData> _sourceData;
|
2003-12-18 01:02:23 +08:00
|
|
|
|
|
|
|
ResolutionList _requiredResolutions;
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
enum CompositeType
|
|
|
|
{
|
|
|
|
GROUP,
|
2004-01-16 05:07:34 +08:00
|
|
|
LOD,
|
|
|
|
PAGED_LOD
|
2003-11-25 19:40:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class CompositeSource : public osg::Referenced, public SpatialProperties
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
CompositeSource(CompositeType type=GROUP):_type(type) {};
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
typedef std::vector< osg::ref_ptr<Source> > SourceList;
|
|
|
|
typedef std::vector< osg::ref_ptr< CompositeSource> > ChildList;
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
void setType(CompositeType type) { _type = type; }
|
|
|
|
CompositeType getType() const { return _type; }
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
void setSortValueFromSourceDataResolution();
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
void sort();
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
class iterator
|
|
|
|
{
|
|
|
|
public:
|
2003-11-27 23:13:55 +08:00
|
|
|
|
|
|
|
enum IteratorMode
|
|
|
|
{
|
|
|
|
ACTIVE,
|
|
|
|
ALL
|
|
|
|
};
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
iterator(CompositeSource* composite=0,IteratorMode mode=ALL):
|
|
|
|
_iteratorMode(mode)
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
|
|
|
if (composite)
|
|
|
|
{
|
|
|
|
_positionStack.push_back(IteratorPosition(composite));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator(const iterator& rhs):
|
|
|
|
_positionStack(rhs._positionStack) {}
|
|
|
|
|
|
|
|
iterator& operator = (const iterator& rhs)
|
|
|
|
{
|
|
|
|
if (&rhs==this) return *this;
|
|
|
|
_positionStack = rhs._positionStack;
|
|
|
|
}
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
bool operator == (const iterator& rhs) const
|
|
|
|
{
|
|
|
|
return _positionStack == rhs._positionStack;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator != (const iterator& rhs) const
|
|
|
|
{
|
|
|
|
return _positionStack != rhs._positionStack;
|
|
|
|
}
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
bool valid() const
|
|
|
|
{
|
|
|
|
return !_positionStack.empty() && _positionStack.back().valid();
|
|
|
|
}
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
CompositeSource& operator *()
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
return *(valid()?_positionStack.back().current():0);
|
2003-11-25 19:40:10 +08:00
|
|
|
}
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
CompositeSource* operator ->()
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
return valid()?_positionStack.back().current():0;
|
2003-11-25 19:40:10 +08:00
|
|
|
}
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
const CompositeSource& operator *() const
|
|
|
|
{
|
|
|
|
return *(valid()?_positionStack.back().current():0);
|
|
|
|
}
|
|
|
|
|
|
|
|
const CompositeSource* operator ->() const
|
|
|
|
{
|
|
|
|
return valid()?_positionStack.back().current():0;
|
|
|
|
}
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
iterator& operator++()
|
|
|
|
{
|
|
|
|
advance();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator operator++(int)
|
|
|
|
{
|
|
|
|
iterator tmp=*this;
|
|
|
|
advance();
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool advance()
|
|
|
|
{
|
|
|
|
if (_positionStack.empty()) return false;
|
|
|
|
|
|
|
|
// simple advance to the next source
|
|
|
|
if (_positionStack.back().advance())
|
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
if (_positionStack.back().current())
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
_positionStack.push_back(IteratorPosition(_positionStack.back().current()));
|
2003-11-25 19:40:10 +08:00
|
|
|
return advance();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_positionStack.pop_back();
|
|
|
|
return advance();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
struct IteratorPosition
|
|
|
|
{
|
|
|
|
|
|
|
|
IteratorPosition(CompositeSource* composite):
|
|
|
|
_composite(composite),
|
|
|
|
_index(-1) {}
|
|
|
|
|
|
|
|
IteratorPosition(const IteratorPosition& rhs):
|
|
|
|
_composite(rhs._composite),
|
|
|
|
_index(rhs._index) {}
|
|
|
|
|
|
|
|
IteratorPosition& operator = (const IteratorPosition& rhs)
|
|
|
|
{
|
|
|
|
_composite = rhs._composite;
|
|
|
|
_index = rhs._index;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
bool operator == (const IteratorPosition& rhs) const
|
|
|
|
{
|
|
|
|
return _composite == rhs._composite && _index == rhs._index;
|
|
|
|
}
|
2003-11-25 19:40:10 +08:00
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
bool operator != (const IteratorPosition& rhs) const
|
|
|
|
{
|
|
|
|
return _composite != rhs._composite || _index != rhs._index;
|
|
|
|
}
|
|
|
|
|
|
|
|
CompositeSource* current()
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
if (_index==-1) return _composite;
|
|
|
|
else return (_index>=0 && _index < (int)_composite->_children.size())?_composite->_children[_index].get():0;
|
2003-11-25 19:40:10 +08:00
|
|
|
}
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
const CompositeSource* current() const
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
if (_index==-1) return _composite;
|
|
|
|
else return (_index>=0 && _index < (int)_composite->_children.size())?_composite->_children[_index].get():0;
|
2003-11-25 19:40:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool valid() const
|
|
|
|
{
|
|
|
|
return _composite &&
|
2003-11-27 23:13:55 +08:00
|
|
|
_index < (int)_composite->_children.size();
|
2003-11-25 19:40:10 +08:00
|
|
|
}
|
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
inline bool advance()
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
return advanceToNextChild(*_composite,_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool isActive(const CompositeSource& composite,int index)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool advanceToNextChild(CompositeSource& composite, int& index)
|
|
|
|
{
|
|
|
|
++index;
|
|
|
|
while (index<(int)composite._children.size())
|
2003-11-25 19:40:10 +08:00
|
|
|
{
|
2003-11-27 23:13:55 +08:00
|
|
|
if (isActive(composite,index)) return true;
|
|
|
|
++index;
|
2003-11-25 19:40:10 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CompositeSource* _composite;
|
|
|
|
int _index;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<IteratorPosition> PositionStack;
|
2003-11-27 23:13:55 +08:00
|
|
|
IteratorMode _iteratorMode;
|
|
|
|
PositionStack _positionStack;
|
2003-11-25 19:40:10 +08:00
|
|
|
};
|
2003-11-27 23:13:55 +08:00
|
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
class base_source_iterator
|
|
|
|
{
|
|
|
|
public:
|
2003-11-25 19:40:10 +08:00
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
|
|
|
|
base_source_iterator(CompositeSource* composite=0, T advancer=T()):
|
|
|
|
_advancer(advancer),
|
|
|
|
_compositeIterator(composite),
|
|
|
|
_sourceIndex(-1)
|
|
|
|
{
|
|
|
|
advance();
|
|
|
|
}
|
|
|
|
|
|
|
|
base_source_iterator(const base_source_iterator& rhs):
|
|
|
|
_advancer(rhs._advancer),
|
|
|
|
_compositeIterator(rhs._compositeIterator),
|
|
|
|
_sourceIndex(rhs._sourceIndex) {}
|
|
|
|
|
|
|
|
base_source_iterator& operator = (const base_source_iterator& rhs)
|
|
|
|
{
|
|
|
|
if (&rhs==this) return *this;
|
|
|
|
_advancer = rhs._advancer;
|
|
|
|
_compositeIterator = rhs._compositeIterator;
|
|
|
|
_sourceIndex = rhs._sourceIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator == (const base_source_iterator& rhs) const
|
|
|
|
{
|
|
|
|
return _compositeIterator == rhs._compositeIterator &&
|
|
|
|
_sourceIndex == rhs._sourceIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator != (const base_source_iterator& rhs) const
|
|
|
|
{
|
|
|
|
return _compositeIterator != rhs._compositeIterator ||
|
|
|
|
_sourceIndex != rhs._sourceIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool valid() const
|
|
|
|
{
|
|
|
|
return _compositeIterator.valid() && _sourceIndex < (int)_compositeIterator->_sourceList.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
osg::ref_ptr<Source>& operator *()
|
|
|
|
{
|
|
|
|
return valid()?_compositeIterator->_sourceList[_sourceIndex]:_nullSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
osg::ref_ptr<Source>* operator ->()
|
|
|
|
{
|
|
|
|
return &(valid()?_compositeIterator->_sourceList[_sourceIndex]:_nullSource);
|
|
|
|
}
|
|
|
|
|
|
|
|
base_source_iterator& operator++()
|
|
|
|
{
|
|
|
|
advance();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
base_source_iterator operator++(int)
|
|
|
|
{
|
|
|
|
base_source_iterator tmp=*this;
|
|
|
|
advance();
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool advance()
|
|
|
|
{
|
|
|
|
if (!_compositeIterator.valid()) return false;
|
|
|
|
|
|
|
|
if (_advancer.advanceToNextSource(*_compositeIterator,_sourceIndex)) return true;
|
|
|
|
|
|
|
|
// at end of current CompositeSource, so need to advance to new one.
|
|
|
|
_sourceIndex = -1;
|
|
|
|
++_compositeIterator;
|
|
|
|
return advance();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2003-11-25 19:40:10 +08:00
|
|
|
|
2003-11-27 23:13:55 +08:00
|
|
|
T _advancer;
|
|
|
|
iterator _compositeIterator;
|
|
|
|
int _sourceIndex;
|
|
|
|
osg::ref_ptr<Source> _nullSource;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DefaultSourceAdvancer
|
|
|
|
{
|
|
|
|
DefaultSourceAdvancer() {}
|
|
|
|
|
|
|
|
bool isActive(const CompositeSource& composite,int index)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool advanceToNextSource(const CompositeSource& composite, int& index)
|
|
|
|
{
|
|
|
|
return ++index<(int)composite._sourceList.size();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LODSourceAdvancer
|
|
|
|
{
|
|
|
|
LODSourceAdvancer(float targetResolution=0.0f):
|
|
|
|
_targetResolution(targetResolution) {}
|
|
|
|
|
|
|
|
inline bool advanceToNextSource(const CompositeSource& composite, int& index)
|
|
|
|
{
|
|
|
|
if (composite.getType()==GROUP)
|
|
|
|
{
|
|
|
|
return (++index<(int)composite._sourceList.size());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (composite._sourceList.empty()) return false;
|
|
|
|
if (index!=-1) return false; // we've already traversed this composite, only ever one valid LOD.
|
|
|
|
|
|
|
|
// find source with resolution closest to target
|
|
|
|
int foundIndex = 0;
|
|
|
|
float closestResolution = fabsf(composite._sourceList[0]->getSortValue()-_targetResolution);
|
|
|
|
for(int i=1;i<(int)composite._sourceList.size();++i)
|
|
|
|
{
|
|
|
|
float delta = fabsf(composite._sourceList[i]->getSortValue()-_targetResolution);
|
|
|
|
if (delta<closestResolution)
|
|
|
|
{
|
|
|
|
foundIndex = i;
|
|
|
|
closestResolution = delta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (foundIndex==index) return false;
|
|
|
|
index = foundIndex;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
float _targetResolution;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef base_source_iterator<DefaultSourceAdvancer> source_iterator;
|
|
|
|
typedef base_source_iterator<LODSourceAdvancer> source_lod_iterator;
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
CompositeType _type;
|
|
|
|
SourceList _sourceList;
|
|
|
|
ChildList _children;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class DestinationTile : public osg::Referenced, public SpatialProperties
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
|
|
enum Position
|
|
|
|
{
|
|
|
|
LEFT = 0,
|
|
|
|
LEFT_BELOW = 1,
|
|
|
|
BELOW = 2,
|
|
|
|
BELOW_RIGHT = 3,
|
|
|
|
RIGHT = 4,
|
|
|
|
RIGHT_ABOVE = 5,
|
|
|
|
ABOVE = 6,
|
|
|
|
ABOVE_LEFT = 7,
|
|
|
|
NUMBER_OF_POSITIONS = 8
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
DestinationTile();
|
2004-01-19 05:59:20 +08:00
|
|
|
|
|
|
|
void computeNeighboursFromQuadMap();
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
void setNeighbours(DestinationTile* left, DestinationTile* left_below,
|
|
|
|
DestinationTile* below, DestinationTile* below_right,
|
|
|
|
DestinationTile* right, DestinationTile* right_above,
|
|
|
|
DestinationTile* above, DestinationTile* above_left);
|
|
|
|
|
|
|
|
void checkNeighbouringTiles();
|
|
|
|
|
|
|
|
void setMaximumImagerySize(unsigned int maxNumColumns,unsigned int maxNumRows)
|
|
|
|
{
|
|
|
|
_imagery_maxNumColumns = maxNumColumns;
|
|
|
|
_imagery_maxNumRows = maxNumRows;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setMaximumTerrainSize(unsigned int maxNumColumns,unsigned int maxNumRows)
|
|
|
|
{
|
|
|
|
_terrain_maxNumColumns = maxNumColumns;
|
|
|
|
_terrain_maxNumRows = maxNumRows;
|
|
|
|
}
|
|
|
|
|
|
|
|
void computeMaximumSourceResolution(CompositeSource* sourceGraph);
|
|
|
|
|
2004-01-13 06:03:29 +08:00
|
|
|
bool computeImageResolution(unsigned int& numColumns, unsigned int& numRows, double& resX, double& resY);
|
|
|
|
bool computeTerrainResolution(unsigned int& numColumns, unsigned int& numRows, double& resX, double& resY);
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void allocate();
|
|
|
|
|
2003-12-18 01:02:23 +08:00
|
|
|
void addRequiredResolutions(CompositeSource* sourceGraph);
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void readFrom(CompositeSource* sourceGraph);
|
|
|
|
|
|
|
|
void equalizeCorner(Position position);
|
|
|
|
void equalizeEdge(Position position);
|
|
|
|
|
|
|
|
void equalizeBoundaries();
|
|
|
|
|
2004-02-04 00:51:44 +08:00
|
|
|
void optimizeResolution();
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
osg::Node* createScene();
|
|
|
|
|
|
|
|
|
|
|
|
std::string _name;
|
|
|
|
|
2004-01-19 05:59:20 +08:00
|
|
|
DataSet* _dataSet;
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
osg::ref_ptr<DestinationData> _imagery;
|
|
|
|
osg::ref_ptr<DestinationData> _terrain;
|
|
|
|
osg::ref_ptr<DestinationData> _models;
|
|
|
|
|
|
|
|
DestinationTile* _neighbour[8];
|
|
|
|
bool _equalized[8];
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int _imagery_maxNumColumns;
|
|
|
|
unsigned int _imagery_maxNumRows;
|
|
|
|
float _imagery_maxSourceResolutionX;
|
|
|
|
float _imagery_maxSourceResolutionY;
|
|
|
|
|
|
|
|
unsigned int _terrain_maxNumColumns;
|
|
|
|
unsigned int _terrain_maxNumRows;
|
|
|
|
float _terrain_maxSourceResolutionX;
|
|
|
|
float _terrain_maxSourceResolutionY;
|
2004-01-16 05:07:34 +08:00
|
|
|
|
|
|
|
unsigned int _level;
|
|
|
|
unsigned int _X;
|
|
|
|
unsigned int _Y;
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
class CompositeDestination : public osg::Referenced, public SpatialProperties
|
|
|
|
{
|
2004-01-16 05:07:34 +08:00
|
|
|
public:
|
|
|
|
|
|
|
|
CompositeDestination():
|
|
|
|
_type(GROUP),
|
|
|
|
_maxVisibleDistance(FLT_MAX) {}
|
|
|
|
|
|
|
|
CompositeDestination(osgTerrain::CoordinateSystem* cs, const osg::BoundingBox& extents):
|
|
|
|
SpatialProperties(cs,extents),
|
|
|
|
_type(GROUP),
|
|
|
|
_maxVisibleDistance(FLT_MAX) {}
|
|
|
|
|
2004-01-19 05:59:20 +08:00
|
|
|
void computeNeighboursFromQuadMap();
|
|
|
|
|
2003-12-18 01:02:23 +08:00
|
|
|
void addRequiredResolutions(CompositeSource* sourceGraph);
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void readFrom(CompositeSource* sourceGraph);
|
|
|
|
|
|
|
|
void equalizeBoundaries();
|
|
|
|
|
|
|
|
osg::Node* createScene();
|
|
|
|
|
|
|
|
typedef std::vector< osg::ref_ptr<DestinationTile> > TileList;
|
|
|
|
typedef std::vector< osg::ref_ptr<CompositeDestination> > ChildList;
|
|
|
|
|
|
|
|
CompositeType _type;
|
|
|
|
TileList _tiles;
|
|
|
|
ChildList _children;
|
2004-01-16 05:07:34 +08:00
|
|
|
float _maxVisibleDistance;
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
};
|
|
|
|
|
2004-01-19 05:59:20 +08:00
|
|
|
|
|
|
|
typedef std::map<unsigned int,DestinationTile*> Column;
|
|
|
|
typedef std::map<unsigned int,Column> Level;
|
|
|
|
typedef std::map<unsigned int,Level> QuadMap;
|
|
|
|
|
|
|
|
void insertTileToQuadMap(DestinationTile* tile)
|
|
|
|
{
|
|
|
|
_quadMap[tile->_level][tile->_X][tile->_Y] = tile;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationTile* getTile(unsigned int level,unsigned int X, unsigned int Y)
|
|
|
|
{
|
|
|
|
QuadMap::iterator levelItr = _quadMap.find(level);
|
|
|
|
if (levelItr==_quadMap.end()) return 0;
|
|
|
|
|
|
|
|
Level::iterator columnItr = levelItr->second.find(X);
|
|
|
|
if (columnItr==levelItr->second.end()) return 0;
|
|
|
|
|
|
|
|
Column::iterator rowItr = columnItr->second.find(Y);
|
|
|
|
if (rowItr==columnItr->second.end()) return 0;
|
|
|
|
else return rowItr->second;
|
|
|
|
}
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
|
|
DataSet();
|
|
|
|
|
|
|
|
void addSource(Source* source);
|
|
|
|
void addSource(CompositeSource* composite);
|
|
|
|
|
|
|
|
void loadSources();
|
|
|
|
|
2004-01-29 23:47:06 +08:00
|
|
|
void setDestinationCoordinateSystem(const std::string& wellKnownText) { _coordinateSystem = new osgTerrain::CoordinateSystem(wellKnownText); }
|
2003-11-25 19:40:10 +08:00
|
|
|
void setDestinationCoordinateSystem(osgTerrain::CoordinateSystem* cs) { _coordinateSystem = cs; }
|
2004-01-29 23:47:06 +08:00
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void setDestinationExtents(const osg::BoundingBox& extents) { _extents = extents; }
|
2004-01-29 23:47:06 +08:00
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
void setDestinationGeoTransform(const osg::Matrixd& geoTransform) { _geoTransform = geoTransform; }
|
|
|
|
|
|
|
|
void setDestinationTileBaseName(const std::string& basename) { _tileBasename = basename; }
|
|
|
|
void setDestinationTileExtension(const std::string& extension) { _tileExtension = _tileExtension; }
|
|
|
|
|
2004-01-13 06:03:29 +08:00
|
|
|
CompositeDestination* createDestinationGraph(osgTerrain::CoordinateSystem* cs,
|
|
|
|
const osg::BoundingBox& extents,
|
|
|
|
unsigned int maxImageSize,
|
|
|
|
unsigned int maxTerrainSize,
|
|
|
|
unsigned int currentLevel,
|
2004-01-16 05:07:34 +08:00
|
|
|
unsigned int currentX,
|
|
|
|
unsigned int currentY,
|
2004-01-13 06:03:29 +08:00
|
|
|
unsigned int maxNumLevels);
|
|
|
|
|
2003-11-25 19:40:10 +08:00
|
|
|
|
2004-01-16 05:07:34 +08:00
|
|
|
void computeDestinationGraphFromSources(unsigned int numLevels);
|
2003-11-25 19:40:10 +08:00
|
|
|
void updateSourcesForDestinationGraphNeeds();
|
|
|
|
void populateDestinationGraphFromSources();
|
|
|
|
|
2004-01-16 05:07:34 +08:00
|
|
|
void createDestination(unsigned int numLevels);
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
void writeDestination(const std::string& filename);
|
|
|
|
|
|
|
|
osg::Node* getDestinationRootNode() { return _rootNode.get(); }
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
virtual ~DataSet() {}
|
|
|
|
|
|
|
|
void init();
|
|
|
|
|
|
|
|
osg::ref_ptr<CompositeSource> _sourceGraph;
|
|
|
|
|
|
|
|
osg::ref_ptr<CompositeDestination> _destinationGraph;
|
2004-01-19 05:59:20 +08:00
|
|
|
|
|
|
|
QuadMap _quadMap;
|
2003-11-25 19:40:10 +08:00
|
|
|
|
|
|
|
osg::ref_ptr<osgTerrain::CoordinateSystem> _coordinateSystem;
|
|
|
|
osg::Matrixd _geoTransform;
|
|
|
|
osg::BoundingBox _extents;
|
|
|
|
std::string _tileBasename;
|
|
|
|
std::string _tileExtension;
|
|
|
|
osg::Vec4 _defaultColour;
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> _rootNode;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|