Merge resolve

This commit is contained in:
Ester Lindgren
2021-04-06 08:48:37 +02:00
11 changed files with 5688 additions and 11 deletions

View File

@@ -29,6 +29,8 @@ set(HEADER_FILES
skybrowsermodule.h
include/screenspaceskybrowser.h
include/screenspaceskytarget.h
include/wwtdatahandler.h
tinyxml2/tinyxml2.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -39,6 +41,8 @@ set(SOURCE_FILES
skybrowsermodule_lua.inl
src/screenspaceskybrowser.cpp
src/screenspaceskytarget.cpp
src/wwtdatahandler.cpp
tinyxml2/tinyxml2.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})

View File

@@ -1,3 +1,4 @@
set(OPENSPACE_DEPENDENCIES
webbrowser
webgui
)

View File

@@ -22,6 +22,8 @@ namespace openspace {
ghoul::Dictionary createMessageForMovingWWTCamera(const glm::dvec2 celestCoords, const float fov, const bool moveInstantly = true) const;
ghoul::Dictionary createMessageForPausingWWTTime() const;
ghoul::Dictionary createMessageForLoadingWWTImgColl(const std::string& url) const;
ghoul::Dictionary createMessageForSettingForegroundWWT(const std::string& name) const;
ghoul::Dictionary createMessageForSettingForegroundOpacityWWT(double val) const;
bool sendMessageToWWT(const ghoul::Dictionary& msg);
void sendMouseEvent(CefStructBase<CefMouseEventTraits> event, int x, int y) const;
void WWTfollowCamera();

View 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__

View File

@@ -23,7 +23,7 @@
****************************************************************************************/
#include <modules/skybrowser/skybrowsermodule.h>
#include <modules/skybrowser/include/wwtdatahandler.h>
//#include <modules/webbrowser/webbrowsermodule.h>
//#include <modules/webbrowser/include/screenspacebrowser.h>
#include <openspace/rendering/screenspacerenderable.h>
@@ -41,8 +41,10 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/texture.h>
#include <cmath> // For atan2
#include <glm/gtx/string_cast.hpp>
#include <ghoul/filesystem/filesystem.h>
#include <glm/gtx/string_cast.hpp> // For printing glm data
#include <fstream>
namespace {
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser)]] Parameters {
@@ -87,7 +89,7 @@ namespace openspace {
"input. An input string should be the name of the system host star"
},
{
"loacImgCollection",
"loadCollection",
&skybrowser::luascriptfunctions::loadImgCollection,
{},
"string or list of strings",
@@ -284,7 +286,7 @@ SkyBrowserModule::SkyBrowserModule()
}
void SkyBrowserModule::internalDeinitialize() {
delete dataHandler;
}
@@ -301,6 +303,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) {
@@ -327,6 +330,9 @@ ScreenSpaceSkyTarget* SkyBrowserModule::to_target(ScreenSpaceRenderable* ptr) {
return dynamic_cast<ScreenSpaceSkyTarget*>(ptr);
}
WWTDataHandler* SkyBrowserModule::getWWTDataHandler() {
return dataHandler;
}
glm::dvec2 SkyBrowserModule::convertGalacticToCelestial(glm::dvec3 rGal) const {
// Used the math from this website: https://gea.esac.esa.int/archive/documentation/GD -->

View File

@@ -25,7 +25,6 @@
#ifndef __OPENSPACE_MODULE_SKYBROWSER___SKYBROWSERMODULE___H__
#define __OPENSPACE_MODULE_SKYBROWSER___SKYBROWSERMODULE___H__
#include <openspace/util/openspacemodule.h>
#include <openspace/documentation/documentation.h>
@@ -39,6 +38,8 @@ namespace openspace {
class ScreenSpaceSkyBrowser;
class ScreenSpaceSkyTarget;
class ScreenSpaceRenderable;
class WWTDataHandler;
class SkyBrowserModule : public OpenSpaceModule {
public:
@@ -48,8 +49,8 @@ public:
virtual ~SkyBrowserModule() = default;
glm::vec2 getMousePositionInScreenSpaceCoords(glm::vec2& mousePos);
void addRenderable(ScreenSpaceRenderable* object);
glm::dvec2 convertGalacticToCelestial(glm::dvec3 coords) const;
WWTDataHandler* getWWTDataHandler();
scripting::LuaLibrary luaLibrary() const override;
//std::vector<documentation::Documentation> documentations() const override;
@@ -57,6 +58,7 @@ public:
protected:
void internalInitialize(const ghoul::Dictionary& dict) override;
void internalDeinitialize() override;
// 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);
@@ -78,6 +80,7 @@ protected:
// Current interaction status
bool currentlyResizingBrowser;
bool currentlyDraggingObject;
WWTDataHandler* dataHandler;
};
} // namespace openspace

View File

@@ -35,19 +35,36 @@ namespace {
namespace openspace::skybrowser::luascriptfunctions {
int loadImgCollection(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::loadCollection");
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::loadCollection");
ScreenSpaceSkyBrowser* browser = dynamic_cast<ScreenSpaceSkyBrowser*>(global::renderEngine->screenSpaceRenderable("SkyBrowser1"));
std::string url = "http://www.worldwidetelescope.org/wwtweb/catalog.aspx?W=wise";
browser->sendMessageToWWT(browser->createMessageForLoadingWWTImgColl(url));
browser->sendMessageToWWT(browser->createMessageForSettingForegroundWWT("Andromeda Galaxy"));
// browser->sendMessageToWWT(browser->createMessageForMovingWWTCamera(glm::vec2(0.712305533333333, 41.269167), 24.0f));
browser->sendMessageToWWT(browser->createMessageForSettingForegroundOpacityWWT(100));
return 1;
}
int followCamera(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::followCamera");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/wwt-web-client/master/assets/webclient-explore-root.wtml";
module->getWWTDataHandler()->loadWTMLCollectionsFromURL(root, "root");
module->getWWTDataHandler()->printAllUrls();
LINFO(std::to_string( module->getWWTDataHandler()->loadAllImagesFromXMLs()));
return 1;
}
int moveBrowser(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::moveBrowser");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->getWWTDataHandler()->loadWTMLCollectionsFromDirectory(absPath("${MODULE_SKYBROWSER}/WWTimagedata/"));
module->getWWTDataHandler()->printAllUrls();
LINFO(std::to_string(module->getWWTDataHandler()->loadAllImagesFromXMLs()));
return 1;
}

View File

@@ -95,7 +95,7 @@ namespace openspace {
_skyTargetID.onChange([&]() {
setConnectedTarget();
});
_fieldOfView.onChange([&]() {
if (_skyTarget) {
_skyTarget->updateFOV(_fieldOfView);
@@ -206,12 +206,34 @@ namespace openspace {
// https://docs.worldwidetelescope.org/data-guide/1/data-file-formats/collections/sample-blank-collection.wtml
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "center_on_coordinates"s);
msg.setValue("event", "load_image_collection"s);
msg.setValue("url", url);
return msg;
}
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForSettingForegroundWWT(const std::string& name) const {
// https://docs.worldwidetelescope.org/data-guide/1/data-file-formats/collections/sample-blank-collection.wtml
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "set_foreground_by_name"s);
msg.setValue("name", name);
return msg;
}
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForSettingForegroundOpacityWWT(double val) const {
// https://docs.worldwidetelescope.org/data-guide/1/data-file-formats/collections/sample-blank-collection.wtml
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "set_foreground_opacity"s);
msg.setValue("value", val);
return msg;
}
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForPausingWWTTime() const {
using namespace std::string_literals;

View 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;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff