osgEarth 2.1.1
|
00001 /* -*-c++-*- */ 00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 00003 * Copyright 2008-2010 Pelican Mapping 00004 * http://osgearth.org 00005 * 00006 * osgEarth is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 #include "KML_NetworkLink" 00020 #include <osgEarth/GeoMath> 00021 #include <osg/PagedLOD> 00022 #include <osg/ProxyNode> 00023 #include <osg/Version> 00024 00025 #undef LC 00026 #define LC "[KML_NetworkLink] " 00027 00028 void 00029 KML_NetworkLink::build( const Config& conf, KMLContext& cx ) 00030 { 00031 std::string name = conf.value("name"); 00032 00033 // parse the link: 00034 Config linkConf = conf.child("link"); 00035 if ( linkConf.empty() ) 00036 { 00037 // "url" seems to be acceptable as well 00038 linkConf = conf.child("url"); 00039 if ( linkConf.empty() ) 00040 return; 00041 } 00042 std::string href = linkConf.value("href"); 00043 if ( href.empty() ) 00044 return; 00045 00046 // "open" determines whether to load it immediately 00047 bool open = conf.value<bool>("open", false); 00048 00049 // if it's region-bound, parse it as a paged LOD: 00050 const Config& regionConf = conf.child("region"); 00051 if ( !regionConf.empty() ) 00052 { 00053 const Config& llaBoxConf = regionConf.child("latlonaltbox"); 00054 if ( llaBoxConf.empty() ) 00055 return; 00056 00057 GeoExtent llaExtent( 00058 cx._mapNode->getMap()->getProfile()->getSRS()->getGeographicSRS(), 00059 llaBoxConf.value<double>("west", 0.0), 00060 llaBoxConf.value<double>("south", 0.0), 00061 llaBoxConf.value<double>("east", 0.0), 00062 llaBoxConf.value<double>("north", 0.0) ); 00063 00064 double x, y; 00065 llaExtent.getCentroid( x, y ); 00066 osg::Vec3d lodCenter; 00067 llaExtent.getSRS()->transformToECEF( osg::Vec3d(x,y,0), lodCenter ); 00068 00069 // figure the tile radius: 00070 double d = 0.5 * GeoMath::distance( 00071 osg::DegreesToRadians(llaExtent.yMin()), osg::DegreesToRadians(llaExtent.xMin()), 00072 osg::DegreesToRadians(llaExtent.yMax()), osg::DegreesToRadians(llaExtent.xMax()) ); 00073 00074 // parse the LOD ranges: 00075 float minRange = 0, maxRange = 1e6; 00076 const Config& lodConf = regionConf.child("lod"); 00077 if ( !lodConf.empty() ) 00078 { 00079 // swapped 00080 minRange = lodConf.value<float>( "minlodpixels", 0.0f ); 00081 if ( minRange < 0.0f ) 00082 minRange = 0.0f; 00083 maxRange = lodConf.value<float>( "maxlodpixels", FLT_MAX ); 00084 if ( maxRange < 0.0f ) 00085 maxRange = FLT_MAX; 00086 } 00087 00088 // build the node 00089 osg::PagedLOD* plod = new osg::PagedLOD(); 00090 plod->setRangeMode( osg::LOD::PIXEL_SIZE_ON_SCREEN ); 00091 00092 plod->setFileName( 0, href ); 00093 plod->setRange( 0, minRange, maxRange ); 00094 plod->setCenter( lodCenter ); 00095 plod->setRadius( d ); 00096 #if OSG_MIN_VERSION_REQUIRED(3,0,0) 00097 osgDB::Options* options = new osgDB::Options(); 00098 options->setPluginData( "osgEarth::MapNode", cx._mapNode ); 00099 plod->setDatabaseOptions( options ); 00100 #endif; 00101 //plod->setNodeMask( open ? ~0 : 0 ); 00102 00103 OE_DEBUG << LC << 00104 "PLOD: radius = " << d << ", minRange=" << minRange << ", maxRange=" << maxRange << std::endl; 00105 00106 cx._groupStack.top()->addChild( plod ); 00107 } 00108 00109 else 00110 { 00111 osg::ProxyNode* proxy = new osg::ProxyNode(); 00112 proxy->setFileName( 0, href ); 00113 #if OSG_MIN_VERSION_REQUIRED(3,0,0) 00114 osgDB::Options* options = new osgDB::Options(); 00115 options->setPluginData( "osgEarth::MapNode", cx._mapNode ); 00116 proxy->setDatabaseOptions( options ); 00117 #endif 00118 //proxy->setNodeMask( open ? ~0 : 0 ); 00119 00120 cx._groupStack.top()->addChild( proxy ); 00121 } 00122 00123 }