mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-13 17:09:05 -05:00
Move the WWT data handling to class WWTDataHandler and add pointer in module
This commit is contained in:
@@ -29,6 +29,7 @@ set(HEADER_FILES
|
||||
skybrowsermodule.h
|
||||
include/screenspaceskybrowser.h
|
||||
include/screenspaceskytarget.h
|
||||
include/wwtdatahandler.h
|
||||
tinyxml2/tinyxml2.h
|
||||
|
||||
)
|
||||
@@ -40,6 +41,7 @@ set(SOURCE_FILES
|
||||
skybrowsermodule_lua.inl
|
||||
src/screenspaceskybrowser.cpp
|
||||
src/screenspaceskytarget.cpp
|
||||
src/wwtdatahandler.cpp
|
||||
tinyxml2/tinyxml2.cpp
|
||||
|
||||
)
|
||||
|
||||
44
modules/skybrowser/include/wwtdatahandler.h
Normal file
44
modules/skybrowser/include/wwtdatahandler.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef __OPENSPACE_MODULE_SKYBROWSER___WWTDATAHANDLER___H__
|
||||
#define __OPENSPACE_MODULE_SKYBROWSER___WWTDATAHANDLER___H__
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <modules/skybrowser/tinyxml2/tinyxml2.h>
|
||||
|
||||
namespace openspace::documentation { struct Documentation; }
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct ImageData {
|
||||
std::string name;
|
||||
std::string thumbnailUrl;
|
||||
glm::vec2 celestCoords;
|
||||
std::string collection;
|
||||
};
|
||||
|
||||
class WWTDataHandler {
|
||||
|
||||
public:
|
||||
WWTDataHandler() = default;
|
||||
~WWTDataHandler();
|
||||
// Image downloading and xml parsing
|
||||
bool downloadFile(std::string& url, std::string& fileDestination);
|
||||
void loadImagesFromXML(tinyxml2::XMLElement* node, std::string collectionName);
|
||||
void loadWTMLCollectionsFromURL(std::string url, std::string fileName);
|
||||
void loadWTMLCollectionsFromDirectory(std::string directory);
|
||||
int loadAllImagesFromXMLs();
|
||||
void printAllUrls();
|
||||
private:
|
||||
int loadPlace(tinyxml2::XMLElement* place, std::string collectionName);
|
||||
int loadImageSet(tinyxml2::XMLElement* imageSet, std::string collectionName);
|
||||
std::string getURLFromImageSet(tinyxml2::XMLElement* imageSet);
|
||||
tinyxml2::XMLElement* getChildNode(tinyxml2::XMLElement* node, std::string name);
|
||||
|
||||
std::vector<ImageData> images;
|
||||
std::vector<std::string> imageUrls;
|
||||
std::vector<tinyxml2::XMLDocument*> xmls;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __OPENSPACE_MODULE_SKYBROWSER___WWTDATAHANDLER___H__
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/skybrowser/skybrowsermodule.h>
|
||||
#include <modules/skybrowser/tinyxml2/tinyxml2.h>
|
||||
|
||||
#include <modules/skybrowser/include/wwtdatahandler.h>
|
||||
//#include <modules/webbrowser/webbrowsermodule.h>
|
||||
//#include <modules/webbrowser/include/screenspacebrowser.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
@@ -43,10 +42,9 @@
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <cmath> // For atan2
|
||||
#include <glm/gtx/string_cast.hpp> // For printing glm data
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <openspace/util/httprequest.h> // For downloading files from url
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem> // To iterate through files in directory
|
||||
|
||||
|
||||
namespace {
|
||||
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser)]] Parameters {
|
||||
@@ -243,13 +241,9 @@ SkyBrowserModule::SkyBrowserModule()
|
||||
}
|
||||
);
|
||||
}
|
||||
SkyBrowserModule::~SkyBrowserModule() {
|
||||
// Call destructor of all allocated xmls
|
||||
xmls.clear();
|
||||
}
|
||||
|
||||
void SkyBrowserModule::internalDeinitialize() {
|
||||
|
||||
delete dataHandler;
|
||||
|
||||
}
|
||||
|
||||
@@ -266,6 +260,7 @@ void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
ghoul_assert(fScreenSpaceRenderable, "ScreenSpaceRenderable factory was not created");
|
||||
fScreenSpaceRenderable->registerClass<ScreenSpaceSkyTarget>("ScreenSpaceSkyTarget");
|
||||
|
||||
dataHandler = new WWTDataHandler();
|
||||
}
|
||||
|
||||
glm::vec2 SkyBrowserModule::getMousePositionInScreenSpaceCoords(glm::vec2& mousePos) {
|
||||
@@ -292,196 +287,10 @@ ScreenSpaceSkyTarget* SkyBrowserModule::to_target(ScreenSpaceRenderable* ptr) {
|
||||
return dynamic_cast<ScreenSpaceSkyTarget*>(ptr);
|
||||
}
|
||||
|
||||
bool SkyBrowserModule::downloadFile(std::string& url, std::string& fileDestination) {
|
||||
// Get the webpage and save to file
|
||||
HttpRequest::RequestOptions opt{ 5 };
|
||||
SyncHttpFileDownload wtml_root(url, fileDestination, HttpFileDownload::Overwrite::Yes);
|
||||
wtml_root.download(opt);
|
||||
return wtml_root.hasSucceeded();
|
||||
WWTDataHandler* SkyBrowserModule::getWWTDataHandler() {
|
||||
return dataHandler;
|
||||
}
|
||||
|
||||
void SkyBrowserModule::loadWTMLCollectionsFromURL(std::string url, std::string fileName) {
|
||||
// Get file
|
||||
std::string fileDestination = absPath("${MODULE_SKYBROWSER}/WWTimagedata/") + fileName + ".aspx";
|
||||
if (!downloadFile(url, fileDestination)) {
|
||||
LINFO("Couldn't download file " + url);
|
||||
return;
|
||||
}
|
||||
// Parse to XML
|
||||
using namespace tinyxml2;
|
||||
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
|
||||
doc->LoadFile(fileDestination.c_str());
|
||||
|
||||
XMLElement* root = doc->RootElement();
|
||||
XMLElement* element = root->FirstChildElement(std::string("Folder").c_str());
|
||||
// If there are no folders, or there are folder but without urls, stop recursion
|
||||
if (!element || (element && !element->FindAttribute("Url"))) {
|
||||
|
||||
imageUrls.push_back(url);
|
||||
xmls.push_back(doc);
|
||||
LINFO("Saving " + url);
|
||||
|
||||
return;
|
||||
}
|
||||
// Iterate through all the folders
|
||||
while (element && std::string(element->Value()) == "Folder") {
|
||||
// Get all attributes for the <Folder>
|
||||
std::string subUrl = element->FindAttribute("Url") ? element->FindAttribute("Url")->Value() : "";
|
||||
std::string subName = element->FindAttribute("Name") ? element->FindAttribute("Name")->Value() : "";
|
||||
if (subUrl != "" && subName != "") {
|
||||
loadWTMLCollectionsFromURL(subUrl, subName);
|
||||
}
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
void SkyBrowserModule::loadWTMLCollectionsFromDirectory(std::string directory) {
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory)) {
|
||||
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
|
||||
std::cout << entry.path().u8string().c_str() << std::endl;
|
||||
if (doc->LoadFile(entry.path().u8string().c_str()) == tinyxml2::XMLError::XML_SUCCESS) {
|
||||
xmls.push_back(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const ImageData& img) {
|
||||
os << "Name: " << img.name << " Coords: ra: " << img.celestCoords.x << " dec: " << img.celestCoords.y << std::endl;
|
||||
os << "Thumbnail: " << img.thumbnailUrl << std::endl;
|
||||
os << "Collection: " << img.collection << std::endl << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
int SkyBrowserModule::loadAllImagesFromXMLs() {
|
||||
for(tinyxml2::XMLDocument* doc : xmls) {
|
||||
tinyxml2::XMLElement* root = doc->FirstChildElement();
|
||||
std::string collectionName = root->FindAttribute("Name") ? root->FindAttribute("Name")->Value() : "";
|
||||
loadImagesFromXML(root, collectionName);
|
||||
}
|
||||
|
||||
for (ImageData img : images) {
|
||||
std::cout << img;
|
||||
}
|
||||
return images.size();
|
||||
}
|
||||
|
||||
void SkyBrowserModule::printAllUrls() {
|
||||
for (auto it = imageUrls.begin(); it != imageUrls.end(); it++) {
|
||||
LINFO(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void SkyBrowserModule::loadImagesFromXML(tinyxml2::XMLElement* node, std::string collectionName) {
|
||||
// Get direct child of node called "Place"
|
||||
using namespace tinyxml2;
|
||||
XMLElement* folder = getChildNode(node->FirstChildElement(), "Folder");
|
||||
|
||||
// Terminate recursion if no folders
|
||||
if (!folder) {
|
||||
// When we are at leaf folder
|
||||
// Iterate through all the places and load as images
|
||||
// Prefer places over Image Sets as they contain same info
|
||||
XMLElement* place = getChildNode(node->FirstChildElement(), "Place");
|
||||
// No place found - look for images instead
|
||||
if (!place) {
|
||||
XMLElement* imageSet = getChildNode(node->FirstChildElement(), "ImageSet");
|
||||
while (imageSet) {
|
||||
loadImageSet(imageSet, collectionName);
|
||||
imageSet = imageSet->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
// Place found - look through places
|
||||
while (place) {
|
||||
loadPlace(place, collectionName);
|
||||
place = place->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Open all folders at same level
|
||||
while (folder) {
|
||||
std::string newCollectionName = collectionName + "/";
|
||||
if (folder->FindAttribute("Name")) {
|
||||
newCollectionName += std::string(folder->FindAttribute("Name")->Value());
|
||||
}
|
||||
loadImagesFromXML(folder, newCollectionName);
|
||||
folder = folder->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SkyBrowserModule::loadPlace(tinyxml2::XMLElement* place, std::string collectionName) {
|
||||
// Only load "Sky" type images
|
||||
if (std::string(place->FindAttribute("DataSetType")->Value()) != "Sky")
|
||||
return - 1;
|
||||
|
||||
std::string url = "";
|
||||
// If the place doesn't have a thumbnail url data attribute,
|
||||
// Load the containing image set instead
|
||||
if (!place->FindAttribute("Thumbnail")) {
|
||||
// Traverse the children and look at all their first child to find ImageSet
|
||||
tinyxml2::XMLElement* child = place->FirstChildElement();
|
||||
tinyxml2::XMLElement* imageSet = nullptr;
|
||||
while (child) {
|
||||
imageSet = getChildNode(child, "ImageSet");
|
||||
if (imageSet) break;
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
// If the place doesn't contain an image, nothing to add
|
||||
if (!imageSet) return -1;
|
||||
|
||||
// Collect thumbnail url from ImageSet
|
||||
url = getURLFromImageSet(imageSet);
|
||||
if (url == "") return -1;
|
||||
}
|
||||
ImageData image;
|
||||
// Get attributes for the image
|
||||
image.name = place->FindAttribute("Name") ? place->FindAttribute("Name")->Value() : "";
|
||||
image.celestCoords.x = place->FindAttribute("RA") ? std::stof(place->FindAttribute("RA")->Value()) : 0.f;
|
||||
image.celestCoords.y = place->FindAttribute("Dec") ? std::stof(place->FindAttribute("Dec")->Value()) : 0.f;
|
||||
image.thumbnailUrl = url == "" ? place->FindAttribute("Thumbnail")->Value() : url;
|
||||
image.collection = collectionName;
|
||||
|
||||
images.push_back(image);
|
||||
// Return index of image in vector
|
||||
return images.size();
|
||||
}
|
||||
int SkyBrowserModule::loadImageSet(tinyxml2::XMLElement* imageSet, std::string collectionName) {
|
||||
std::string type = imageSet->FindAttribute("DataSetType") ? imageSet->FindAttribute("DataSetType")->Value() : "";
|
||||
// Only load "Sky" type images
|
||||
if (type != "Sky")
|
||||
return - 1;
|
||||
|
||||
ImageData image;
|
||||
|
||||
// Get attributes for the image
|
||||
image.name = imageSet->FindAttribute("Name") ? imageSet->FindAttribute("Name")->Value() : "";
|
||||
image.celestCoords.x = imageSet->FindAttribute("RA") ? std::stof(imageSet->FindAttribute("RA")->Value()) : 0.f;
|
||||
image.celestCoords.y = imageSet->FindAttribute("Dec") ? std::stof(imageSet->FindAttribute("Dec")->Value()) : 0.f;
|
||||
image.thumbnailUrl = getURLFromImageSet(imageSet);
|
||||
image.collection = collectionName;
|
||||
|
||||
images.push_back(image);
|
||||
// Return index of image in vector
|
||||
return images.size();
|
||||
}
|
||||
|
||||
std::string SkyBrowserModule::getURLFromImageSet(tinyxml2::XMLElement* imageSet) {
|
||||
// FInd the thumbnail image url
|
||||
// The thumbnail is the last node so traverse backwards for speed
|
||||
tinyxml2::XMLElement* imageSetChild = imageSet->FirstChildElement("ThumbnailUrl");
|
||||
return imageSetChild ? imageSetChild->GetText() ? imageSetChild->GetText() : "" : "";
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* SkyBrowserModule::getChildNode(tinyxml2::XMLElement* node, std::string name) {
|
||||
while (node && std::string(node->Name()) != name) {
|
||||
node = node->FirstChildElement();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
std::vector<documentation::Documentation> SkyBrowserModule::documentations() const {
|
||||
return {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define __OPENSPACE_MODULE_SKYBROWSER___SKYBROWSERMODULE___H__
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
#include <modules/skybrowser/tinyxml2/tinyxml2.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
@@ -38,40 +38,25 @@ namespace openspace {
|
||||
class ScreenSpaceSkyBrowser;
|
||||
class ScreenSpaceSkyTarget;
|
||||
class ScreenSpaceRenderable;
|
||||
class WWTDataHandler;
|
||||
|
||||
struct ImageData {
|
||||
std::string name;
|
||||
std::string thumbnailUrl;
|
||||
glm::vec2 celestCoords;
|
||||
std::string collection;
|
||||
};
|
||||
|
||||
class SkyBrowserModule : public OpenSpaceModule {
|
||||
public:
|
||||
constexpr static const char* Name = "SkyBrowser";
|
||||
|
||||
SkyBrowserModule();
|
||||
virtual ~SkyBrowserModule();
|
||||
virtual ~SkyBrowserModule() = default;
|
||||
glm::vec2 getMousePositionInScreenSpaceCoords(glm::vec2& mousePos);
|
||||
void addRenderable(ScreenSpaceRenderable* object);
|
||||
// Image downloading and xml parsing
|
||||
bool downloadFile(std::string& url, std::string& fileDestination);
|
||||
void loadImagesFromXML(tinyxml2::XMLElement* node, std::string collectionName);
|
||||
void loadWTMLCollectionsFromURL(std::string url, std::string fileName);
|
||||
void loadWTMLCollectionsFromDirectory(std::string directory);
|
||||
int loadAllImagesFromXMLs();
|
||||
void printAllUrls();
|
||||
|
||||
WWTDataHandler* getWWTDataHandler();
|
||||
scripting::LuaLibrary luaLibrary() const override;
|
||||
//std::vector<documentation::Documentation> documentations() const override;
|
||||
|
||||
protected:
|
||||
void internalInitialize(const ghoul::Dictionary& dict) override;
|
||||
void internalDeinitialize() override;
|
||||
int loadPlace(tinyxml2::XMLElement* place, std::string collectionName);
|
||||
int loadImageSet(tinyxml2::XMLElement* imageSet, std::string collectionName);
|
||||
std::string getURLFromImageSet(tinyxml2::XMLElement* imageSet);
|
||||
tinyxml2::XMLElement* getChildNode(tinyxml2::XMLElement* node, std::string name);
|
||||
|
||||
// Using snake case on these casting functions to make them similar to eg std::to_string
|
||||
ScreenSpaceSkyBrowser* to_browser(ScreenSpaceRenderable* ptr);
|
||||
ScreenSpaceSkyTarget* to_target(ScreenSpaceRenderable* ptr);
|
||||
@@ -92,10 +77,7 @@ protected:
|
||||
// Current interaction status
|
||||
bool currentlyResizingBrowser;
|
||||
bool currentlyDraggingObject;
|
||||
|
||||
std::vector<ImageData> images;
|
||||
std::vector<std::string> imageUrls;
|
||||
std::vector<tinyxml2::XMLDocument*> xmls;
|
||||
WWTDataHandler* dataHandler;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -49,9 +49,9 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/wwt-web-client/master/assets/webclient-explore-root.wtml";
|
||||
|
||||
module->loadWTMLCollectionsFromURL(root, "root");
|
||||
module->printAllUrls();
|
||||
LINFO(std::to_string( module->loadAllImagesFromXMLs()));
|
||||
module->getWWTDataHandler()->loadWTMLCollectionsFromURL(root, "root");
|
||||
module->getWWTDataHandler()->printAllUrls();
|
||||
LINFO(std::to_string( module->getWWTDataHandler()->loadAllImagesFromXMLs()));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -59,9 +59,9 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
int moveBrowser(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::moveBrowser");
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
module->loadWTMLCollectionsFromDirectory(absPath("${MODULE_SKYBROWSER}/WWTimagedata/"));
|
||||
module->printAllUrls();
|
||||
LINFO(std::to_string(module->loadAllImagesFromXMLs()));
|
||||
module->getWWTDataHandler()->loadWTMLCollectionsFromDirectory(absPath("${MODULE_SKYBROWSER}/WWTimagedata/"));
|
||||
module->getWWTDataHandler()->printAllUrls();
|
||||
LINFO(std::to_string(module->getWWTDataHandler()->loadAllImagesFromXMLs()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
212
modules/skybrowser/src/wwtdatahandler.cpp
Normal file
212
modules/skybrowser/src/wwtdatahandler.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
#include <modules/skybrowser/include/wwtdatahandler.h>
|
||||
#include <openspace/util/httprequest.h> // For downloading files from url
|
||||
#include <filesystem> // To iterate through files in directory
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "WWTDataHandler";
|
||||
|
||||
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
WWTDataHandler::~WWTDataHandler() {
|
||||
// Call destructor of all allocated xmls
|
||||
xmls.clear();
|
||||
}
|
||||
|
||||
bool WWTDataHandler::downloadFile(std::string& url, std::string& fileDestination) {
|
||||
// Get the webpage and save to file
|
||||
HttpRequest::RequestOptions opt{ 5 };
|
||||
SyncHttpFileDownload wtml_root(url, fileDestination, HttpFileDownload::Overwrite::Yes);
|
||||
wtml_root.download(opt);
|
||||
return wtml_root.hasSucceeded();
|
||||
}
|
||||
|
||||
void WWTDataHandler::loadWTMLCollectionsFromURL(std::string url, std::string fileName) {
|
||||
// Get file
|
||||
std::string fileDestination = absPath("${MODULE_SKYBROWSER}/WWTimagedata/") + fileName + ".aspx";
|
||||
if (!downloadFile(url, fileDestination)) {
|
||||
LINFO("Couldn't download file " + url);
|
||||
return;
|
||||
}
|
||||
// Parse to XML
|
||||
using namespace tinyxml2;
|
||||
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
|
||||
doc->LoadFile(fileDestination.c_str());
|
||||
|
||||
XMLElement* root = doc->RootElement();
|
||||
XMLElement* element = root->FirstChildElement(std::string("Folder").c_str());
|
||||
// If there are no folders, or there are folder but without urls, stop recursion
|
||||
if (!element || (element && !element->FindAttribute("Url"))) {
|
||||
|
||||
imageUrls.push_back(url);
|
||||
xmls.push_back(doc);
|
||||
LINFO("Saving " + url);
|
||||
|
||||
return;
|
||||
}
|
||||
// Iterate through all the folders
|
||||
while (element && std::string(element->Value()) == "Folder") {
|
||||
// Get all attributes for the <Folder>
|
||||
std::string subUrl = element->FindAttribute("Url") ? element->FindAttribute("Url")->Value() : "";
|
||||
std::string subName = element->FindAttribute("Name") ? element->FindAttribute("Name")->Value() : "";
|
||||
if (subUrl != "" && subName != "") {
|
||||
loadWTMLCollectionsFromURL(subUrl, subName);
|
||||
}
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
void WWTDataHandler::loadWTMLCollectionsFromDirectory(std::string directory) {
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory)) {
|
||||
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
|
||||
std::cout << entry.path().u8string().c_str() << std::endl;
|
||||
if (doc->LoadFile(entry.path().u8string().c_str()) == tinyxml2::XMLError::XML_SUCCESS) {
|
||||
xmls.push_back(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const ImageData& img) {
|
||||
os << "Name: " << img.name << " Coords: ra: " << img.celestCoords.x << " dec: " << img.celestCoords.y << std::endl;
|
||||
os << "Thumbnail: " << img.thumbnailUrl << std::endl;
|
||||
os << "Collection: " << img.collection << std::endl << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
int WWTDataHandler::loadAllImagesFromXMLs() {
|
||||
for (tinyxml2::XMLDocument* doc : xmls) {
|
||||
tinyxml2::XMLElement* root = doc->FirstChildElement();
|
||||
std::string collectionName = root->FindAttribute("Name") ? root->FindAttribute("Name")->Value() : "";
|
||||
loadImagesFromXML(root, collectionName);
|
||||
}
|
||||
|
||||
for (ImageData img : images) {
|
||||
std::cout << img;
|
||||
}
|
||||
return images.size();
|
||||
}
|
||||
|
||||
void WWTDataHandler::printAllUrls() {
|
||||
for (auto it = imageUrls.begin(); it != imageUrls.end(); it++) {
|
||||
LINFO(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void WWTDataHandler::loadImagesFromXML(tinyxml2::XMLElement* node, std::string collectionName) {
|
||||
// Get direct child of node called "Place"
|
||||
using namespace tinyxml2;
|
||||
XMLElement* folder = getChildNode(node->FirstChildElement(), "Folder");
|
||||
|
||||
// Terminate recursion if no folders
|
||||
if (!folder) {
|
||||
// When we are at leaf folder
|
||||
// Iterate through all the places and load as images
|
||||
// Prefer places over Image Sets as they contain same info
|
||||
XMLElement* place = getChildNode(node->FirstChildElement(), "Place");
|
||||
// No place found - look for images instead
|
||||
if (!place) {
|
||||
XMLElement* imageSet = getChildNode(node->FirstChildElement(), "ImageSet");
|
||||
while (imageSet) {
|
||||
loadImageSet(imageSet, collectionName);
|
||||
imageSet = imageSet->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
// Place found - look through places
|
||||
while (place) {
|
||||
loadPlace(place, collectionName);
|
||||
place = place->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Open all folders at same level
|
||||
while (folder) {
|
||||
std::string newCollectionName = collectionName + "/";
|
||||
if (folder->FindAttribute("Name")) {
|
||||
newCollectionName += std::string(folder->FindAttribute("Name")->Value());
|
||||
}
|
||||
loadImagesFromXML(folder, newCollectionName);
|
||||
folder = folder->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int WWTDataHandler::loadPlace(tinyxml2::XMLElement* place, std::string collectionName) {
|
||||
// Only load "Sky" type images
|
||||
if (std::string(place->FindAttribute("DataSetType")->Value()) != "Sky")
|
||||
return -1;
|
||||
|
||||
std::string url = "";
|
||||
// If the place doesn't have a thumbnail url data attribute,
|
||||
// Load the containing image set instead
|
||||
if (!place->FindAttribute("Thumbnail")) {
|
||||
// Traverse the children and look at all their first child to find ImageSet
|
||||
tinyxml2::XMLElement* child = place->FirstChildElement();
|
||||
tinyxml2::XMLElement* imageSet = nullptr;
|
||||
while (child) {
|
||||
imageSet = getChildNode(child, "ImageSet");
|
||||
if (imageSet) break;
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
// If the place doesn't contain an image, nothing to add
|
||||
if (!imageSet) return -1;
|
||||
|
||||
// Collect thumbnail url from ImageSet
|
||||
url = getURLFromImageSet(imageSet);
|
||||
if (url == "") return -1;
|
||||
}
|
||||
ImageData image;
|
||||
// Get attributes for the image
|
||||
image.name = place->FindAttribute("Name") ? place->FindAttribute("Name")->Value() : "";
|
||||
image.celestCoords.x = place->FindAttribute("RA") ? std::stof(place->FindAttribute("RA")->Value()) : 0.f;
|
||||
image.celestCoords.y = place->FindAttribute("Dec") ? std::stof(place->FindAttribute("Dec")->Value()) : 0.f;
|
||||
image.thumbnailUrl = url == "" ? place->FindAttribute("Thumbnail")->Value() : url;
|
||||
image.collection = collectionName;
|
||||
|
||||
images.push_back(image);
|
||||
// Return index of image in vector
|
||||
return images.size();
|
||||
}
|
||||
|
||||
int WWTDataHandler::loadImageSet(tinyxml2::XMLElement* imageSet, std::string collectionName) {
|
||||
std::string type = imageSet->FindAttribute("DataSetType") ? imageSet->FindAttribute("DataSetType")->Value() : "";
|
||||
// Only load "Sky" type images
|
||||
if (type != "Sky")
|
||||
return -1;
|
||||
|
||||
ImageData image;
|
||||
|
||||
// Get attributes for the image
|
||||
image.name = imageSet->FindAttribute("Name") ? imageSet->FindAttribute("Name")->Value() : "";
|
||||
image.celestCoords.x = imageSet->FindAttribute("RA") ? std::stof(imageSet->FindAttribute("RA")->Value()) : 0.f;
|
||||
image.celestCoords.y = imageSet->FindAttribute("Dec") ? std::stof(imageSet->FindAttribute("Dec")->Value()) : 0.f;
|
||||
image.thumbnailUrl = getURLFromImageSet(imageSet);
|
||||
image.collection = collectionName;
|
||||
|
||||
images.push_back(image);
|
||||
// Return index of image in vector
|
||||
return images.size();
|
||||
}
|
||||
|
||||
std::string WWTDataHandler::getURLFromImageSet(tinyxml2::XMLElement* imageSet) {
|
||||
// FInd the thumbnail image url
|
||||
// The thumbnail is the last node so traverse backwards for speed
|
||||
tinyxml2::XMLElement* imageSetChild = imageSet->FirstChildElement("ThumbnailUrl");
|
||||
return imageSetChild ? imageSetChild->GetText() ? imageSetChild->GetText() : "" : "";
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* WWTDataHandler::getChildNode(tinyxml2::XMLElement* node, std::string name) {
|
||||
while (node && std::string(node->Name()) != name) {
|
||||
node = node->FirstChildElement();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user