Support relative paths in GeoJSON SpriteTexture (#3761)

This commit is contained in:
Alexander Bock
2025-07-23 15:18:32 +02:00
committed by GitHub
parent 089b106645
commit ebc6fbef11
8 changed files with 78 additions and 24 deletions

View File

@@ -0,0 +1,51 @@
local earth = asset.require("scene/solarsystem/planets/earth/earth")
-- These two files are downloaded from the servers when the asset gets loaded. Specifying
-- these two URLs in this way will cause them to be downloaded into the same folder on the
-- harddisk. For this example this is important as the points-relative.geojson will ask
-- for the image.png in the same folder by specifying "./image.png"
local data = asset.resource({
Name = "GeoJSON Example Relative Texture Path",
Type = "UrlSynchronization",
Identifier = "geojson_example_points_relative_path",
Url = {
"http://liu-se.cdn.openspaceproject.com/files/examples/geojson/points-relative.geojson",
"http://liu-se.cdn.openspaceproject.com/files/examples/geojson/image.png"
}
})
local ExamplePoints = {
Identifier = "Points-Example-RelativeTexturePath",
File = data .. "points-relative.geojson",
HeightOffset = 20000.0,
DefaultProperties = {
PointSize = 10.0
},
Name = "Example Points (Relative Texture Path)"
}
asset.onInitialize(function()
openspace.globebrowsing.addGeoJson(earth.Earth.Identifier, ExamplePoints)
end)
asset.onDeinitialize(function()
openspace.globebrowsing.deleteGeoJson(earth.Earth.Identifier, ExamplePoints)
end)
asset.export(ExamplePoints)
asset.meta = {
Name = "GeoJson Example - Points (Relative Texture Path)",
Description = [[GeoJson example asset with points that are facing the camera
(default). This example is using a relative path to specify the location of the image
that is to be used.]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license"
}

View File

@@ -496,8 +496,8 @@ bool GlobeBrowsingModule::hasDefaultGeoPointTexture() const {
return _hasDefaultGeoPointTexture;
}
std::string_view GlobeBrowsingModule::defaultGeoPointTexture() const {
return _defaultGeoPointTexturePath;
std::filesystem::path GlobeBrowsingModule::defaultGeoPointTexture() const {
return _defaultGeoPointTexturePath.value();
}
scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {

View File

@@ -90,7 +90,7 @@ public:
std::string mrfCacheLocation() const;
bool hasDefaultGeoPointTexture() const;
std::string_view defaultGeoPointTexture() const;
std::filesystem::path defaultGeoPointTexture() const;
protected:
void internalInitialize(const ghoul::Dictionary&) override;

View File

@@ -587,7 +587,7 @@ void GeoJsonComponent::update() {
}
void GeoJsonComponent::readFile() {
std::ifstream file(_geoJsonFile);
std::ifstream file = std::ifstream(_geoJsonFile);
if (!file.good()) {
LERROR(std::format("Failed to open GeoJSON file: {}", _geoJsonFile.value()));
@@ -601,6 +601,14 @@ void GeoJsonComponent::readFile() {
std::istreambuf_iterator<char>()
);
// For the loading, we want to assume that the current working directory is where the
// GeoJSON file is located
const std::filesystem::path cwd = std::filesystem::current_path();
std::filesystem::path jsonDir =
std::filesystem::path(_geoJsonFile.value()).parent_path();
std::filesystem::current_path(jsonDir);
defer { std::filesystem::current_path(cwd); };
// Parse GeoJSON string into GeoJSON objects
try {
const geos::io::GeoJSONReader reader;

View File

@@ -26,6 +26,7 @@
#include <modules/globebrowsing/src/renderableglobe.h>
#include <openspace/documentation/documentation.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <geos/io/GeoJSON.h>
#include <scn/scan.h>
@@ -527,7 +528,8 @@ GeoJsonOverrideProperties propsFromGeoJson(const geos::io::GeoJSONFeature& featu
result.pointSize = static_cast<float>(value.getNumber());
}
else if (keyMatches(key, propertykeys::Texture, PointTextureInfo)) {
result.pointTexture = value.getString();
std::string texture = value.getString();
result.pointTexture = absPath(texture);
}
else if (keyMatches(key, propertykeys::PointTextureAnchor, PointAnchorOptionInfo))
{
@@ -628,8 +630,8 @@ float PropertySet::pointSize() const {
return overrideValues.pointSize.value_or(defaultValues.pointSize);
}
std::string PropertySet::pointTexture() const {
return overrideValues.pointTexture.value_or(defaultValues.pointTexture);
std::filesystem::path PropertySet::pointTexture() const {
return overrideValues.pointTexture.value_or(defaultValues.pointTexture.value());
}
GeoJsonProperties::PointTextureAnchor PropertySet::pointTextureAnchor() const {

View File

@@ -107,7 +107,7 @@ struct GeoJsonOverrideProperties {
std::optional<float> lineWidth;
std::optional<float> pointSize;
std::optional<std::string> pointTexture;
std::optional<std::filesystem::path> pointTexture;
std::optional<GeoJsonProperties::PointTextureAnchor> pointTextureAnchor;
std::optional<bool> extrude;
@@ -135,7 +135,7 @@ struct PropertySet {
float lineWidth() const;
float pointSize() const;
std::string pointTexture() const;
std::filesystem::path pointTexture() const;
GeoJsonProperties::PointTextureAnchor pointTextureAnchor() const;
bool extrude() const;

View File

@@ -115,7 +115,7 @@ bool GlobeGeometryFeature::useHeightMap() const {
}
void GlobeGeometryFeature::updateTexture(bool isInitializeStep) {
std::string texture;
std::filesystem::path texture;
GlobeBrowsingModule* m = global::moduleEngine->module<GlobeBrowsingModule>();
if (!isInitializeStep && _properties.hasOverrideTexture()) {
@@ -144,15 +144,14 @@ void GlobeGeometryFeature::updateTexture(bool isInitializeStep) {
_pointTexture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToEdge);
}
std::filesystem::path texturePath = absPath(texture);
if (std::filesystem::is_regular_file(texturePath)) {
if (std::filesystem::is_regular_file(texture)) {
_hasTexture = true;
_pointTexture->loadFromFile(texture);
_pointTexture->uploadToGpu();
}
else {
LERROR(std::format(
"Trying to use texture file that does not exist: {}", texturePath
"Trying to use texture file that does not exist: {}", texture
));
}
}

View File

@@ -94,18 +94,12 @@ void TextureComponent::loadFromFile(const std::filesystem::path& path) {
using namespace ghoul::io;
using namespace ghoul::opengl;
std::filesystem::path absolutePath = absPath(path);
std::unique_ptr<Texture> tex = TextureReader::ref().loadTexture(path, _nDimensions);
if (tex) {
LDEBUG(std::format("Loaded texture from '{}'", path));
_texture = std::move(tex);
std::unique_ptr<Texture> texture = TextureReader::ref().loadTexture(
absolutePath,
_nDimensions
);
if (texture) {
LDEBUG(std::format("Loaded texture from '{}'", absolutePath));
_texture = std::move(texture);
_textureFile = std::make_unique<ghoul::filesystem::File>(absolutePath);
_textureFile = std::make_unique<ghoul::filesystem::File>(path);
if (_shouldWatchFile) {
_textureFile->setCallback([this]() { _fileIsDirty = true; });
}