liyihongcug 发表于 2020-6-1 15:45:27

3dtiles瓦片改造方案

osgearth2.10.1版本支持3dtiles瓦片 但可惜支持在线ION格式。
国内大多禁止上公网,必须本地切片本地文件访问
参照url: '.../tileset.json',的写法改写驱动
----至少这里


using namespace osgEarth;
using namespace osgEarth::Drivers;

#define LC " "
#define OE_TEST OE_DEBUG


class CesiumIonSource : public TileSource
{
public:
    CesiumIonSource(const TileSourceOptions& options) :
      TileSource(options),
      _options(options)
      {
          //nop
      }

      Status initialize(const osgDB::Options* dbOptions)
      {
          _dbOptions = Registry::instance()->cloneOrCreateOptions(dbOptions);

          if (_options.assetId().value().empty())
          {
            return Status::Error(Status::ConfigurationError, "Fail: driver requires a valid \"asset_id\" property");
          }

          if (_options.token().value().empty())
          {
            return Status::Error(Status::ConfigurationError, "Fail: driver requires a valid \"token\" property");
          }

          setProfile(osgEarth::Registry::instance()->getSphericalMercatorProfile());

          std::stringstream buf;
          buf << _options.server()->full();
          if (!endsWith(_options.server()->full(), "/")) buf << "/";
          buf << "v1/assets/" << *_options.assetId() << "/endpoint?access_token=" << *_options.token();
          URI endpoint(buf.str());
          OE_DEBUG << "Getting endpoint " << endpoint.full() << std::endl;

          ReadResult r = URI(endpoint).readString(_dbOptions.get());
          if (r.failed())
            return Status::Error(Status::ConfigurationError, "Failed to get metadata from asset endpoint");

          Json::Value doc;
          Json::Reader reader;
          if (!reader.parse(r.getString(), doc))
          {
            return Status::Error(Status::ConfigurationError, "Failed to parse metadata from asset endpoint");
          }

          _resourceUrl = doc["url"].asString();
          _resourceToken = doc["accessToken"].asString();

          // Configure the accept header
          std::stringstream buf2;
          buf2 << "*/*;access_token=" << _resourceToken;
          _acceptHeader = buf2.str();

          return STATUS_OK;
      }


      osg::Image* createImage(const TileKey&   key,
          ProgressCallback*progress )
      {
          unsigned x, y;
          key.getTileXY( x, y );

          // Invert the y value
          unsigned cols=0, rows=0;
          key.getProfile()->getNumTiles( key.getLevelOfDetail(), cols, rows );
          y = rows - y - 1;

          std::string location = _resourceUrl;
          std::stringstream buf;
          buf << location;
          if (!endsWith(location, "/")) buf << "/";
          buf << key.getLevelOfDetail() << "/" << x << "/" << y << "." << *_options.format();

          URIContext context = _options.server()->context();
          context.addHeader("accept", _acceptHeader);
          URI uri(buf.str(), context);
          return uri.getImage(_dbOptions.get(), progress);
      }

      virtual std::string getExtension() const
      {
          return *_options.format();
      }

private:
    const CesiumIonOptions       _options;
    osg::ref_ptr<osgDB::Options> _dbOptions;
    std::string                  _acceptHeader;
    std::string                  _resourceToken;
    std::string                  _resourceUrl;
};

class CesiumIonTileSourceDriver : public TileSourceDriver
{
public:
    CesiumIonTileSourceDriver()
    {
      supportsExtension( "osgearth_cesiumion", "CesiumIon Driver" );
    }

    virtual const char* className() const
    {
      return "CesiumIon Driver";
    }

    virtual ReadResult readObject(const std::string& file_name, const Options* options) const
    {
      if ( !acceptsExtension(osgDB::getLowerCaseFileExtension( file_name )))
            return ReadResult::FILE_NOT_HANDLED;

      return new CesiumIonSource( getTileSourceOptions(options) );
    }
};

REGISTER_OSGPLUGIN(osgearth_cesiumion, CesiumIonTileSourceDriver)
页: [1]
查看完整版本: 3dtiles瓦片改造方案