以前摸鱼时手动编译过一次osgEarth,并且成功加载了.shp、.gdb等矢量数据。这次使用vcpkg安装后,也想试试,结果问题频出,特此记录。本文的目的是加载本地.shp数据,相关代码片段均在如下基础代码上进行添加(在第30行之后开始)。
首先设置数据源:
osgEarth::OGRFeatureSource *shp = new osgEarth::OGRFeatureSource();
shp->setOGRDriver("ESRI Shapefile");
shp->setURL("./datas/gx.shp");
设置完数据源后,我突然想看一下数据中的要素数目,于是调用了 shp->getFeatureCount()方法,结果输出-1。我当时错误地认为这可能是环境的问题,于是便开始了艰难的排错过程。
由于控制台没有任何有效信息输出,于是,在基础代码第24行之后添加 osgEarth::setNotifyLevel(osg::NotifySeverity::DEBUG_INFO)以输出调试信息。此时运行程序后的控制台输出如下:
在控制台输出中,出现了两个明显的问题,由红笔框出。
对于“Failed to load osgEarth.dll”问题,我全局搜索了该文件,居然没有搜到。在osgearth Issues #2589 GitHub中描述了类似的问题,没有人回答。研究了一番,并未察觉到该问题对程序的影响,暂时先忽略吧。
对于“Cannot find proj.db”错误,是因为PROJ(osgEarth依赖库之一)没有配置好。通过打印 OSRGetPROJSearchPaths()方法执行结果查看当前计算机PROJ库搜索路径:
正常来讲,使用vcpkg安装后不应该出现这种问题,但是因为安装时使用了 --clean-after-build选项,导致图中显示的PROJ目录不存在。因此,需要手动设置正确的PROJ搜索路径,方法有二:
- 配置全局环境变量:PROJ_LIB=E:\osgearth\installed\x64-windows\share\proj
- 在基础代码第24行之后添加相关代码
std::string path = R"(E:\osgearth\installed\x64-windows\share\proj)";
const char* proj_path[] = { path.c_str(),nullptr };
OSRSetPROJSearchPaths(proj_path);
但这还是没能解决没有要素数目是-1的问题。折腾了一番,仍没有找到问题所在,我想可能是我的姿势不对,于是先放下,继续往后添加代码:
osgEarth::Style style;
osgEarth::AltitudeSymbol* altSymbol = style.getOrCreateSymbol<osgEarth::AltitudeSymbol>();
altSymbol->clamping() = altSymbol->CLAMP_TO_TERRAIN;
altSymbol->technique() = altSymbol->TECHNIQUE_SCENE;
osgEarth::LineSymbol* lineSymbol = style.getOrCreateSymbol<osgEarth::LineSymbol>();
osgEarth::Stroke lineStroke(osgEarth::Color::Red);
lineStroke.set_width(osgEarth::Distance(2.0, osgEarth::Units::PIXELS));
lineSymbol->set_stroke(lineStroke);
lineSymbol->tessellationSize()->set(10000, osgEarth::Units::KILOMETERS);
osgEarth::StyleSheet* sheet = new osgEarth::StyleSheet();
sheet->addStyle(style);
osgEarth::FeatureImageLayer* shpLayer = new osgEarth::FeatureImageLayer();
shpLayer->setFeatureSource(shp);
shpLayer->setStyleSheet(sheet);
map->addLayer(shp);
添加完后,我突然又再次想输出要素数目看看,居然有了,啧啧啧!在osgEarth源码中有这么一段描述:
破案。在 addLayer之前,数据源没有打开( shp->isOpen()==false),所以需要事先调用shp->open()方法才可正确输出要素数目。
再次运行程序,要素数据没有显示!!!排查后发现,是上面添加地图图层的代码不小心写错了,应该是 map->addLayer(shpLayer)。来吧,展示:
上图中,红色的那一坨就是加载的.shp文件中的数据。
参考资料: