DYT/Tool/OpenSceneGraph-3.6.5/include/osgEarthImGui/SearchGUI
2024-12-25 07:49:36 +08:00

118 lines
3.9 KiB
C++

/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2018 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 <osgEarthImGui/ImGuiPanel>
#include <osgEarth/Utils>
#include <osgEarth/EarthManipulator>
#include <osgEarth/Geocoder>
#include <osgEarth/ViewFitter>
#include <osgEarth/MapNode>
namespace osgEarth
{
using namespace osgEarth::Util;
class SearchGUI : public ImGuiPanel
{
public:
SearchGUI() :
ImGuiPanel("Search"),
_search(""),
_results(Status::Code::ServiceUnavailable, 0)
{
}
void draw(osg::RenderInfo& ri) override
{
if (!isVisible())
return;
if (!_mapSRS.valid()) {
MapNode* mapNode = findNode<MapNode>(ri);
if (mapNode)
_mapSRS = mapNode->getMapSRS();
else {
setVisible(false);
return;
}
}
ImGui::Begin(name(), visible());
ImGui::Text("Enter place name:");
if (ImGui::InputText("", _search, 128,
ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll))
{
_features.clear();
_results = geocoder.search(_search, _options.get());
}
if (_results.isReady())
{
if (_results.getStatus().isOK())
{
_results.getFeatures()->fill(_features);
}
_results = Geocoder::Results(Status::Code::ServiceUnavailable, 0);
}
else if (_results.isWorking())
{
ImGui::Text("Searching...");
}
for (FeatureList::iterator itr = _features.begin(); itr != _features.end(); ++itr)
{
bool selected = false;
Feature* feature = itr->get();
if (feature->getGeometry())
{
ImGui::Separator();
std::string displayName = itr->get()->getString("display_name");
ImGui::Selectable(displayName.c_str(), &selected);
if (selected)
{
GeoExtent extent(feature->getSRS(), feature->getGeometry()->getBounds());
if (extent.area() == 0.0)
extent.expand(Distance(10, Units::KILOMETERS), Distance(10, Units::KILOMETERS));
ViewFitter fitter(_mapSRS.get(), ri.getCurrentCamera());
Viewpoint vp;
if (fitter.createViewpoint(extent, vp))
{
auto manip = dynamic_cast<EarthManipulator*>(view(ri)->getCameraManipulator());
manip->setViewpoint(vp, 3.0f);
}
break;
}
}
}
ImGui::End();
}
char _search[128];
Geocoder::Results _results;
osg::ref_ptr<osgDB::Options> _options;
FeatureList _features;
Geocoder geocoder;
osg::ref_ptr<const SpatialReference> _mapSRS;
};
}