286 lines
9.6 KiB
C++
286 lines
9.6 KiB
C++
/* -*-c++-*- */
|
|
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
|
* Copyright 2020 Pelican Mapping
|
|
* http://osgearth.org
|
|
*
|
|
* osgEarth is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
#pragma once
|
|
#include <osgEarth/Common>
|
|
#include <osgEarth/Profile>
|
|
#include <osgEarth/Geometry>
|
|
#include <osgEarth/Style>
|
|
#include <osgEarth/GeoCommon>
|
|
#include <osgEarth/SpatialReference>
|
|
#include <osg/Array>
|
|
#include <osg/Shape>
|
|
#include <map>
|
|
#include <list>
|
|
#include <vector>
|
|
|
|
namespace osgEarth
|
|
{
|
|
namespace Util
|
|
{
|
|
class FilterContext;
|
|
class Session;
|
|
}
|
|
|
|
/**
|
|
* Metadata and schema information for feature data.
|
|
*/
|
|
class OSGEARTH_EXPORT FeatureProfile : public osg::Referenced
|
|
{
|
|
public:
|
|
//! Construct a non-tiled feature profile with an extent
|
|
FeatureProfile(const GeoExtent& featuresExtent);
|
|
|
|
//! Construct a TILED feature profile with a tiling schema
|
|
FeatureProfile(const Profile* tilingProfile);
|
|
|
|
//! Copy ctor
|
|
FeatureProfile(const FeatureProfile& rhs);
|
|
|
|
//! Spatial extents of the features data
|
|
void setExtent(const GeoExtent& value) { _extent = value; }
|
|
const GeoExtent& getExtent() const { return _extent; }
|
|
|
|
//! Spatial reference system of feature data
|
|
const SpatialReference* getSRS() const { return _extent.getSRS(); }
|
|
|
|
//! Whether the feature data is pre-tiled
|
|
bool isTiled() const;
|
|
|
|
//! For tiled data, the tiling profile
|
|
const osgEarth::Profile* getTilingProfile() const;
|
|
void setTilingProfile( const osgEarth::Profile* profile );
|
|
|
|
//! For tiled data, the first tiling level of detail
|
|
int getFirstLevel() const;
|
|
void setFirstLevel(int firstLevel );
|
|
|
|
//! For tiled data, the last tiling level fo detail
|
|
int getMaxLevel() const;
|
|
void setMaxLevel(int maxLevel);
|
|
|
|
//! Interpolation method for geodetic data
|
|
optional<GeoInterpolation>& geoInterp() { return _geoInterp; }
|
|
const optional<GeoInterpolation>& geoInterp() const { return _geoInterp; }
|
|
|
|
protected:
|
|
virtual ~FeatureProfile() { }
|
|
|
|
osg::ref_ptr< const osgEarth::Profile > _tilingProfile;
|
|
GeoExtent _extent;
|
|
int _firstLevel;
|
|
int _maxLevel;
|
|
optional<GeoInterpolation> _geoInterp;
|
|
};
|
|
|
|
struct AttributeValueUnion
|
|
{
|
|
std::string stringValue;
|
|
double doubleValue;
|
|
long long intValue;
|
|
bool boolValue;
|
|
std::vector<double> doubleArrayValue;
|
|
bool set = false;
|
|
};
|
|
|
|
enum AttributeType
|
|
{
|
|
ATTRTYPE_UNSPECIFIED,
|
|
ATTRTYPE_STRING,
|
|
ATTRTYPE_INT,
|
|
ATTRTYPE_DOUBLE,
|
|
ATTRTYPE_BOOL,
|
|
ATTRTYPE_DOUBLEARRAY
|
|
};
|
|
|
|
struct OSGEARTH_EXPORT AttributeValue
|
|
{
|
|
AttributeType type;
|
|
AttributeValueUnion value;
|
|
std::string getString() const;
|
|
double getDouble(double defaultValue = 0.0) const;
|
|
long long getInt(long long defaultValue = 0) const;
|
|
bool getBool(bool defaultValue = false) const;
|
|
const std::vector<double>& getDoubleArrayValue() const;
|
|
};
|
|
|
|
using AttributeTable = vector_map<std::string, AttributeValue, ci_string_less>;
|
|
|
|
using FeatureID = std::int64_t; // long long;
|
|
|
|
using FeatureSchema = std::map<std::string, AttributeType>;
|
|
|
|
class Feature;
|
|
|
|
using FeatureList = std::vector<osg::ref_ptr<Feature>>;
|
|
|
|
/**
|
|
* Basic building block of vector feature data.
|
|
*/
|
|
class OSGEARTH_EXPORT Feature : public osg::Referenced // : public osg::Object
|
|
{
|
|
public:
|
|
|
|
//! Construct a feature
|
|
Feature(Geometry* geom, const SpatialReference* srs, const Style& style =Style(), FeatureID fid =0LL );
|
|
|
|
//! Construct a feature (copy)
|
|
Feature(const Feature& rhs);
|
|
|
|
//! Contruct a feature (move)
|
|
Feature(Feature&& rhs);
|
|
|
|
public:
|
|
|
|
/**
|
|
* The unique ID of this feature (unique relative to its provider)
|
|
*/
|
|
FeatureID getFID() const;
|
|
|
|
/**
|
|
* Set the FID of this feature.
|
|
*/
|
|
void setFID(FeatureID fid);
|
|
|
|
/**
|
|
* Gets the GeoExtent of this Feature
|
|
*/
|
|
GeoExtent getExtent() const;
|
|
|
|
/**
|
|
* The geometry in this feature.
|
|
*/
|
|
void setGeometry( Geometry* geom );
|
|
Geometry* getGeometry() { dirty(); return _geom.get(); }
|
|
const Geometry* getGeometry() const { return _geom.get(); }
|
|
|
|
/**
|
|
* The spatial reference of the geometry in this feature.
|
|
*/
|
|
const SpatialReference* getSRS() const { return _srs.get(); }
|
|
void setSRS( const SpatialReference* srs );
|
|
|
|
/**
|
|
* Computes the bound of this feature in the specified SRS.
|
|
*/
|
|
bool getWorldBound( const SpatialReference* srs, osg::BoundingSphered& out_bound ) const;
|
|
|
|
/**
|
|
* Gets a polytope, in world coordinates (proj or ECEF) that bounds the
|
|
* geographic extents covered by this feature. This is useful for roughly
|
|
* intersecting the feature with the terrain graph.
|
|
*/
|
|
bool getWorldBoundingPolytope( const SpatialReference* srs, osg::Polytope& out_polytope ) const;
|
|
|
|
/**
|
|
* Gets a polytope, in world coordinates (proj or ECEF) that bounds the
|
|
* world coordinates covered by the given bounding sphere. This is useful for roughly
|
|
* intersecting features with the terrain graph.
|
|
*/
|
|
static bool getWorldBoundingPolytope( const osg::BoundingSphered& bs, const SpatialReference* srs, osg::Polytope& out_polytope );
|
|
|
|
/**
|
|
* Calculates the extent of this feature.
|
|
*/
|
|
GeoExtent calculateExtent() const;
|
|
|
|
|
|
const AttributeTable& getAttrs() const { return _attrs; }
|
|
|
|
void set( const std::string& name, const std::string& value );
|
|
void set( const std::string& name, double value );
|
|
void set(const std::string& name, int value);
|
|
void set( const std::string& name, long long value );
|
|
void set( const std::string& name, bool value );
|
|
void set( const std::string& name, const std::vector<double>& value );
|
|
void setSwap( const std::string& name, std::vector<double>& value );
|
|
void set( const std::string& name, const AttributeValue& value);
|
|
|
|
/** Sets the attribute to NULL */
|
|
void setNull( const std::string& name );
|
|
void setNull( const std::string& name, AttributeType type );
|
|
|
|
void removeAttribute(const std::string& name);
|
|
|
|
bool hasAttr( const std::string& name ) const;
|
|
|
|
std::string getString( const std::string& name ) const;
|
|
double getDouble( const std::string& name, double defaultValue =0.0 ) const;
|
|
long long getInt( const std::string& name, long long defaultValue =0 ) const;
|
|
bool getBool( const std::string& name, bool defaultValue =false ) const;
|
|
const std::vector<double>* getDoubleArray( const std::string& name ) const;
|
|
|
|
/**
|
|
* Gets whether the attribute is set, meaning it is non-NULL
|
|
*/
|
|
bool isSet( const std::string& name ) const;
|
|
|
|
/** Embedded style. */
|
|
optional<Style>& style() { return _style; }
|
|
const optional<Style>& style() const { return _style; }
|
|
|
|
/** Geodetic interpolation method. */
|
|
optional<GeoInterpolation>& geoInterp() { dirty(); return _geoInterp; }
|
|
const optional<GeoInterpolation>& geoInterp() const { return _geoInterp; }
|
|
|
|
/** populates the variables of an expression with attribute values and evals the expression. */
|
|
double eval(NumericExpression& expr, const FilterContext* context) const;
|
|
double eval(NumericExpression& expr, Session* session) const;
|
|
|
|
/** populates the variables of an expression with attribute values and evals the expression. */
|
|
const std::string& eval(StringExpression& expr, const FilterContext* context) const;
|
|
const std::string& eval(StringExpression& expr, Session* session) const;
|
|
|
|
public:
|
|
/** Gets a GeoJSON representation of this Feature */
|
|
std::string getGeoJSON() const;
|
|
|
|
/** Gets a FeatureList as a GeoJSON FeatureCollection */
|
|
static std::string featuresToGeoJSON(const FeatureList& features);
|
|
|
|
public:
|
|
/**
|
|
* Transforms this Feature to the given SpatialReference
|
|
*/
|
|
void transform( const SpatialReference* srs );
|
|
|
|
/**
|
|
* Splits this feature into multiple features if it is a geodetic feature and cross the date line.
|
|
*/
|
|
void splitAcrossDateLine(FeatureList& splitFeatures);
|
|
|
|
protected:
|
|
|
|
Feature();
|
|
Feature( FeatureID fid );
|
|
|
|
virtual ~Feature();
|
|
|
|
FeatureID _fid;
|
|
osg::ref_ptr<Geometry> _geom;
|
|
osg::ref_ptr<const SpatialReference> _srs;
|
|
AttributeTable _attrs;
|
|
optional<Style> _style;
|
|
optional<GeoInterpolation> _geoInterp;
|
|
GeoExtent _cachedExtent;
|
|
|
|
void dirty();
|
|
};
|
|
|
|
} // namespace osgEarth
|