From ed85efe9d54b46a901ceb8783e02a85ccae33145 Mon Sep 17 00:00:00 2001 From: Dmitry Kiselev Date: Mon, 4 Nov 2024 11:15:53 -0400 Subject: [PATCH] Resolve config paths relative to config location --- .../org/osm2world/console/ImageExporter.java | 18 ++--- .../java/org/osm2world/console/OSM2World.java | 11 ++- .../org/osm2world/core/ConversionFacade.java | 71 +++++++++++-------- .../target/common/material/Materials.java | 23 +++--- .../core/target/common/model/Models.java | 11 ++- .../org/osm2world/core/util/ConfigUtil.java | 42 ++++++++++- 6 files changed, 115 insertions(+), 61 deletions(-) diff --git a/src/main/java/org/osm2world/console/ImageExporter.java b/src/main/java/org/osm2world/console/ImageExporter.java index 015010f7..71214773 100644 --- a/src/main/java/org/osm2world/console/ImageExporter.java +++ b/src/main/java/org/osm2world/console/ImageExporter.java @@ -5,7 +5,9 @@ import static org.osm2world.core.target.jogl.JOGLRenderingParameters.Winding.CCW; import static org.osm2world.core.util.ConfigUtil.*; -import java.awt.*; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; @@ -25,6 +27,7 @@ import org.osm2world.core.target.common.rendering.Camera; import org.osm2world.core.target.common.rendering.Projection; import org.osm2world.core.target.jogl.*; +import org.osm2world.core.util.ConfigUtil; import org.osm2world.core.util.Resolution; import com.jogamp.opengl.*; @@ -101,14 +104,11 @@ private ImageExporter(Configuration config, Results results, } if (config.containsKey(BG_IMAGE_KEY)) { - String fileString = config.getString(BG_IMAGE_KEY); - if (fileString != null) { - backgroundImage = new File(fileString); - if (!backgroundImage.exists()) { - System.err.println("background image file doesn't exist: " - + backgroundImage); - backgroundImage = null; - } + backgroundImage = ConfigUtil.resolveFileConfigProperty(config, config.getString(BG_IMAGE_KEY)); + if (backgroundImage == null || !backgroundImage.exists()) { + System.err.println("background image file doesn't exist: " + + backgroundImage); + backgroundImage = null; } } diff --git a/src/main/java/org/osm2world/console/OSM2World.java b/src/main/java/org/osm2world/console/OSM2World.java index 5f03b5d0..297aa494 100644 --- a/src/main/java/org/osm2world/console/OSM2World.java +++ b/src/main/java/org/osm2world/console/OSM2World.java @@ -1,9 +1,9 @@ package org.osm2world.console; import static java.util.Arrays.asList; +import static org.osm2world.console.CLIArgumentsUtil.getProgramMode; import static org.osm2world.console.CLIArgumentsUtil.ProgramMode.CONVERT; import static org.osm2world.console.CLIArgumentsUtil.ProgramMode.GUI; -import static org.osm2world.console.CLIArgumentsUtil.getProgramMode; import static org.osm2world.core.GlobalValues.VERSION_STRING; import java.io.File; @@ -15,7 +15,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; -import javax.swing.*; +import javax.swing.UIManager; import org.apache.commons.configuration.BaseConfiguration; import org.apache.commons.configuration.Configuration; @@ -238,6 +238,13 @@ public static Configuration loadConfigFiles(@Nullable LevelOfDetail lod, File... config.load(it); } + Arrays.stream(configFiles) + .filter(f -> f.exists()) + .findFirst() + .ifPresent(f -> { + config.addProperty("configPath", f.getAbsoluteFile().getParent()); + }); + if (lod != null) { config.clearProperty("lod"); config.addProperty("lod", lod.ordinal()); diff --git a/src/main/java/org/osm2world/core/ConversionFacade.java b/src/main/java/org/osm2world/core/ConversionFacade.java index 321b7980..612b7a27 100644 --- a/src/main/java/org/osm2world/core/ConversionFacade.java +++ b/src/main/java/org/osm2world/core/ConversionFacade.java @@ -9,9 +9,13 @@ import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Stream; import javax.annotation.Nullable; @@ -37,6 +41,7 @@ import org.osm2world.core.target.TargetUtil; import org.osm2world.core.target.common.material.Materials; import org.osm2world.core.target.common.model.Models; +import org.osm2world.core.util.ConfigUtil; import org.osm2world.core.util.FaultTolerantIterationUtil; import org.osm2world.core.util.functions.Factory; import org.osm2world.core.world.attachment.AttachmentConnector; @@ -91,33 +96,37 @@ public TerrainElevationData getEleData() { /** * generates a default list of modules for the conversion */ - static final List createDefaultModuleList() { - - return Arrays.asList((WorldModule) - new RoadModule(), - new RailwayModule(), - new AerowayModule(), - new BuildingModule(), - new ParkingModule(), - new TreeModule(), - new StreetFurnitureModule(), - new TrafficSignModule(), - new BicycleParkingModule(), - new WaterModule(), - new PoolModule(), - new GolfModule(), - new SportsModule(), - new CliffModule(), - new BarrierModule(), - new PowerModule(), - new MastModule(), - new BridgeModule(), - new TunnelModule(), - new SurfaceAreaModule(), - new InvisibleModule(), - new IndoorModule() - ); - + static final List createDefaultModuleList(Configuration config) { + + List excludedModules = config.getList("excludeWorldModule") + .stream().map(m -> m.toString()).toList(); + + return Stream.of((WorldModule) + new RoadModule(), + new RailwayModule(), + new AerowayModule(), + new BuildingModule(), + new ParkingModule(), + new TreeModule(), + new StreetFurnitureModule(), + new TrafficSignModule(), + new BicycleParkingModule(), + new WaterModule(), + new PoolModule(), + new GolfModule(), + new SportsModule(), + new CliffModule(), + new BarrierModule(), + new PowerModule(), + new MastModule(), + new BridgeModule(), + new TunnelModule(), + new SurfaceAreaModule(), + new InvisibleModule(), + new IndoorModule() + ) + .filter(m -> !excludedModules.contains(m.getClass().getSimpleName())) + .toList(); } private Function mapProjectionFactory = MetricMapProjection::new; @@ -266,7 +275,7 @@ public Results createRepresentations(MapProjection mapProjection, MapData mapDat updatePhase(Phase.REPRESENTATION); if (worldModules == null) { - worldModules = createDefaultModuleList(); + worldModules = createDefaultModuleList(config); } Materials.configureMaterials(config); @@ -281,11 +290,11 @@ public Results createRepresentations(MapProjection mapProjection, MapData mapDat /* determine elevations */ updatePhase(Phase.ELEVATION); - String srtmDir = config.getString("srtmDir", null); + File srtmDir = ConfigUtil.resolveFileConfigProperty(config, config.getString("srtmDir", null)); TerrainElevationData eleData = null; if (srtmDir != null) { - eleData = new SRTMData(new File(srtmDir), mapProjection); + eleData = new SRTMData(srtmDir, mapProjection); } /* create terrain and attach connectors */ diff --git a/src/main/java/org/osm2world/core/target/common/material/Materials.java b/src/main/java/org/osm2world/core/target/common/material/Materials.java index 56ad431c..55d06797 100644 --- a/src/main/java/org/osm2world/core/target/common/material/Materials.java +++ b/src/main/java/org/osm2world/core/target/common/material/Materials.java @@ -3,10 +3,10 @@ import static java.awt.Color.*; import static java.util.Collections.emptyList; -import java.awt.*; +import java.awt.Color; +import java.awt.Font; import java.io.File; import java.lang.reflect.Field; -import java.util.List; import java.util.*; import java.util.Map.Entry; import java.util.function.Function; @@ -495,8 +495,9 @@ public static final void configureMaterials(Configuration config) { File displacementTexture = null; if (config.containsKey(keyPrefix + "_dir")) { - File textureDir = new File(config.getString(keyPrefix + "_dir")); - if (textureDir.exists() && textureDir.isDirectory()) { + + File textureDir = ConfigUtil.resolveFileConfigProperty(config, config.getString(keyPrefix + "_dir")); + if (textureDir!= null && textureDir.exists() && textureDir.isDirectory()) { for (File file : textureDir.listFiles()) { if (file.getName().contains("_Color.")) { baseColorTexture = file; @@ -624,16 +625,10 @@ public static final void configureMaterials(Configuration config) { relativeFontSize, wrap, coordFunction); } else if ("image".equals(type)) { - - File file = null; - - String fileName = config.getString(keyPrefix + "_file"); - if (fileName != null) { - file = new File(fileName); - if (!file.exists() || file.isDirectory()) { - System.err.println("File referenced in config does not exist: " + file); - file = null; - } + File file = ConfigUtil.resolveFileConfigProperty(config, config.getString(keyPrefix + "_file")); + + if (file == null || file.isDirectory()) { + file = null; } if (file == null) { file = defaultFile; } diff --git a/src/main/java/org/osm2world/core/target/common/model/Models.java b/src/main/java/org/osm2world/core/target/common/model/Models.java index 4bf41fb2..7a6ca495 100644 --- a/src/main/java/org/osm2world/core/target/common/model/Models.java +++ b/src/main/java/org/osm2world/core/target/common/model/Models.java @@ -10,6 +10,7 @@ import org.apache.commons.configuration.Configuration; import org.osm2world.core.target.gltf.GltfModel; +import org.osm2world.core.util.ConfigUtil; import org.osm2world.core.world.creation.WorldModule; /** @@ -73,12 +74,16 @@ public static void configureModels(Configuration config) { if (matcher.matches()) { String modelName = matcher.group(1); - List fileNames = config.getList(key); + List fileNames = config.getList(key).stream().map(f -> f.toString()).toList(); try { List ms = new ArrayList<>(fileNames.size()); - for (Object fileName : fileNames) { - ms.add(GltfModel.loadFromFile(new File(fileName.toString()))); + for (String fileName : fileNames) { + File modelFile = ConfigUtil.resolveFileConfigProperty(config, fileName); + if (modelFile == null) { + System.err.println("Can't read model file " + fileName); + } + ms.add(GltfModel.loadFromFile(modelFile)); } models.put(modelName.toLowerCase(Locale.ROOT), ms); } catch (IOException e) { diff --git a/src/main/java/org/osm2world/core/util/ConfigUtil.java b/src/main/java/org/osm2world/core/util/ConfigUtil.java index 9a379059..958fc751 100644 --- a/src/main/java/org/osm2world/core/util/ConfigUtil.java +++ b/src/main/java/org/osm2world/core/util/ConfigUtil.java @@ -2,15 +2,20 @@ import static org.osm2world.core.target.common.mesh.LevelOfDetail.*; -import java.awt.*; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontFormatException; +import java.awt.GraphicsEnvironment; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.FileConfiguration; import org.osm2world.core.target.common.mesh.LevelOfDetail; /** @@ -130,4 +135,37 @@ public static void parseFonts(Configuration config) { } } -} \ No newline at end of file + /** + * If config references some files by path e.g. textures + * resolve file paths relative to config location + */ + public static File resolveFileConfigProperty(Configuration config, String fileName) { + if (fileName == null) { + return null; + } + + File file = new File(fileName); + + String basePath = null; + if (config.containsKey("configPath")) { + basePath = config.getString("configPath"); + } + + if (basePath == null && config instanceof FileConfiguration fc && fc.getFile() != null) { + basePath = fc.getFile().getAbsoluteFile().getParent(); + } + + if (basePath != null) { + file = Path.of(basePath).normalize() + .resolve(Path.of(fileName).normalize()).toFile(); + } + + if (!file.exists()) { + System.err.println("File referenced in config does not exist: " + file); + return null; + } + + return file; + } + +}