Skip to content

Commit

Permalink
Forest priority update
Browse files Browse the repository at this point in the history
* Forest priority update.

* Linter updates.

* Logging update.
  • Loading branch information
iwatkot authored Dec 26, 2024
1 parent 141a83c commit 4c35803
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 42 deletions.
3 changes: 2 additions & 1 deletion data/fs25-texture-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@
"tags": { "natural": ["wood", "tree_row"], "landuse": "forest" },
"width": 2,
"color": [0, 252, 124],
"usage": "forest"
"usage": "forest",
"priority": 5
},
{
"name": "grassDirtPatchyDry",
Expand Down
8 changes: 3 additions & 5 deletions maps4fs/generator/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ def process(self) -> None:
self.generate_obj_files()
if self.map.background_settings.generate_water:
self.generate_water_resources_obj()
else:
self.logger.info("Light version is enabled, obj files will not be generated.")

def make_copy(self, dem_path: str, dem_name: str) -> None:
"""Copies DEM data to additional DEM file.
Expand All @@ -138,7 +136,7 @@ def make_copy(self, dem_path: str, dem_name: str) -> None:
additional_dem_path = os.path.join(dem_directory, dem_name)

shutil.copyfile(dem_path, additional_dem_path)
self.logger.info("Additional DEM data was copied to %s.", additional_dem_path)
self.logger.debug("Additional DEM data was copied to %s.", additional_dem_path)

def info_sequence(self) -> dict[str, str | float | int]:
"""Returns a dictionary with information about the background terrain.
Expand Down Expand Up @@ -340,7 +338,7 @@ def mesh_to_stl(self, mesh: trimesh.Trimesh) -> None:
preview_path = os.path.join(self.previews_directory, "background_dem.stl")
mesh.export(preview_path)

self.logger.info("STL file saved: %s", preview_path)
self.logger.debug("STL file saved: %s", preview_path)

self.stl_preview_path = preview_path # pylint: disable=attribute-defined-outside-init

Expand Down Expand Up @@ -501,7 +499,7 @@ def create_background_textures(self) -> None:

background_save_path = os.path.join(self.water_directory, "water_resources.png")
cv2.imwrite(background_save_path, background_image)
self.logger.info("Background texture saved: %s", background_save_path)
self.logger.debug("Background texture saved: %s", background_save_path)
self.water_resources_path = background_save_path # pylint: disable=W0201

def subtraction(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion maps4fs/generator/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def _set_map_size(self) -> None:
self.logger.warning("Map XML file not found: %s.", self._map_xml_path)
return
tree = ET.parse(self._map_xml_path)
self.logger.info("Map XML file loaded from: %s.", self._map_xml_path)
self.logger.debug("Map XML file loaded from: %s.", self._map_xml_path)
root = tree.getroot()
for map_elem in root.iter("map"):
map_elem.set("width", str(self.map_size))
Expand Down
4 changes: 2 additions & 2 deletions maps4fs/generator/dem.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def process(self) -> None:
)

cv2.imwrite(self._dem_path, resampled_data)
self.logger.info("DEM data was saved to %s.", self._dem_path)
self.logger.debug("DEM data was saved to %s.", self._dem_path)

if self.rotation:
self.rotate_dem()
Expand Down Expand Up @@ -401,7 +401,7 @@ def _normalize_dem(self, data: np.ndarray) -> np.ndarray:

scaling_factor = self._get_scaling_factor(max_dev)
adjusted_max_height = int(65535 * scaling_factor)
self.logger.info(
self.logger.debug(
"Maximum deviation: %s. Scaling factor: %s. Adjusted max height: %s.",
max_dev,
scaling_factor,
Expand Down
16 changes: 8 additions & 8 deletions maps4fs/generator/grle.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def preprocess(self) -> None:
try:
grle_schema_path = self.game.grle_schema
except ValueError:
self.logger.info("GRLE schema processing is not implemented for this game.")
self.logger.warning("GRLE schema processing is not implemented for this game.")
return

try:
Expand All @@ -57,7 +57,7 @@ def preprocess(self) -> None:
def process(self) -> None:
"""Generates InfoLayer PNG files based on the GRLE schema."""
if not self._grle_schema:
self.logger.info("GRLE schema is not obtained, skipping the processing.")
self.logger.debug("GRLE schema is not obtained, skipping the processing.")
return

for info_layer in self._grle_schema:
Expand All @@ -84,7 +84,7 @@ def process(self) -> None:

self._add_farmlands()
if self.game.code == "FS25":
self.logger.info("Game is %s, plants will be added.", self.game.code)
self.logger.debug("Game is %s, plants will be added.", self.game.code)
self._add_plants()
else:
self.logger.warning("Adding plants it's not supported for the %s.", self.game.code)
Expand Down Expand Up @@ -120,7 +120,7 @@ def _add_farmlands(self) -> None:
self.game.weights_dir_path(self.map_directory), "infoLayer_farmlands.png"
)

self.logger.info(
self.logger.debug(
"Adding farmlands to the InfoLayer PNG file: %s.", info_layer_farmlands_path
)

Expand Down Expand Up @@ -190,10 +190,10 @@ def _add_farmlands(self) -> None:

tree.write(farmlands_xml_path)

self.logger.info("Farmlands added to the farmlands XML file: %s.", farmlands_xml_path)
self.logger.debug("Farmlands added to the farmlands XML file: %s.", farmlands_xml_path)

cv2.imwrite(info_layer_farmlands_path, image) # pylint: disable=no-member
self.logger.info(
self.logger.debug(
"Farmlands added to the InfoLayer PNG file: %s.", info_layer_farmlands_path
)

Expand Down Expand Up @@ -354,7 +354,7 @@ def get_rounded_polygon(

# Add islands of plants to the base image.
island_count = self.map_size
self.logger.info("Adding %s islands of plants to the base image.", island_count)
self.logger.debug("Adding %s islands of plants to the base image.", island_count)
if self.map.grle_settings.random_plants:
grass_image_copy = create_island_of_plants(grass_image_copy, island_count)
self.logger.debug("Islands of plants added to the base image.")
Expand Down Expand Up @@ -391,4 +391,4 @@ def get_rounded_polygon(
# Ensure that order of channels is correct because CV2 uses BGR and we need RGB.
density_map_fruits = cv2.cvtColor(density_map_fruits, cv2.COLOR_BGR2RGB)
cv2.imwrite(density_map_fruit_path, density_map_fruits)
self.logger.info("Updated density map for fruits saved in %s.", density_map_fruit_path)
self.logger.debug("Updated density map for fruits saved in %s.", density_map_fruit_path)
10 changes: 5 additions & 5 deletions maps4fs/generator/i3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def preprocess(self) -> None:
self._map_i3d_path = self.game.i3d_file_path(self.map_directory)
self.logger.debug("Map I3D path: %s.", self._map_i3d_path)
except NotImplementedError:
self.logger.info("I3D file processing is not implemented for this game.")
self.logger.warning("I3D file processing is not implemented for this game.")
self._map_i3d_path = None

def process(self) -> None:
Expand All @@ -59,7 +59,7 @@ def process(self) -> None:
def _get_tree(self) -> ET.ElementTree | None:
"""Returns the ElementTree instance of the map I3D file."""
if not self._map_i3d_path:
self.logger.info("I3D is not obtained, skipping the update.")
self.logger.debug("I3D is not obtained, skipping the update.")
return None
if not os.path.isfile(self._map_i3d_path):
self.logger.warning("I3D file not found: %s.", self._map_i3d_path)
Expand Down Expand Up @@ -117,7 +117,7 @@ def _update_i3d_file(self) -> None:
)

tree.write(self._map_i3d_path) # type: ignore
self.logger.info("Map I3D file saved to: %s.", self._map_i3d_path)
self.logger.debug("Map I3D file saved to: %s.", self._map_i3d_path)

def previews(self) -> list[str]:
"""Returns a list of paths to the preview images (empty list).
Expand Down Expand Up @@ -234,7 +234,7 @@ def _add_fields(self) -> None:
field_id += 1

tree.write(self._map_i3d_path) # type: ignore
self.logger.info("Map I3D file saved to: %s.", self._map_i3d_path)
self.logger.debug("Map I3D file saved to: %s.", self._map_i3d_path)

def get_name_indicator_node(self, node_id: int, field_id: int) -> tuple[ET.Element, int]:
"""Creates a name indicator node with given node ID and field ID.
Expand Down Expand Up @@ -417,7 +417,7 @@ def _add_forests(self) -> None:
self.logger.info("Added %s trees to the I3D file.", tree_count)

tree.write(self._map_i3d_path) # type: ignore
self.logger.info("Map I3D file saved to: %s.", self._map_i3d_path)
self.logger.debug("Map I3D file saved to: %s.", self._map_i3d_path)

@staticmethod
def randomize_coordinates(coordinates: tuple[int, int], density: int) -> tuple[float, float]:
Expand Down
20 changes: 18 additions & 2 deletions maps4fs/generator/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ def generate(self) -> Generator[str, None, None]:
Yields:
Generator[str, None, None]: Component names.
"""
self.logger.info(
"Starting map generation. Game code: %s. Coordinates: %s, size: %s. Rotation: %s.",
self.game.code,
self.coordinates,
self.size,
self.rotation,
)

for game_component in self.game.components:
component = game_component(
self.game,
Expand Down Expand Up @@ -184,6 +192,14 @@ def generate(self) -> Generator[str, None, None]:
)
raise e

self.logger.info(
"Map generation completed. Game code: %s. Coordinates: %s, size: %s. Rotation: %s.",
self.game.code,
self.coordinates,
self.size,
self.rotation,
)

def get_component(self, component_name: str) -> Component | None:
"""Get component by name.
Expand Down Expand Up @@ -231,7 +247,7 @@ def pack(self, archive_path: str, remove_source: bool = True) -> str:
if remove_source:
try:
shutil.rmtree(self.map_directory)
self.logger.info("Map directory removed: %s", self.map_directory)
self.logger.debug("Map directory removed: %s", self.map_directory)
except Exception as e: # pylint: disable=W0718
self.logger.error("Error removing map directory %s: %s", self.map_directory, e)
self.logger.debug("Error removing map directory %s: %s", self.map_directory, e)
return archive_path
17 changes: 7 additions & 10 deletions maps4fs/generator/texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def preprocess(self) -> None:

base_layer = self.get_base_layer()
if base_layer:
self.logger.info("Base layer found: %s.", base_layer.name)
self.logger.debug("Base layer found: %s.", base_layer.name)
else:
self.logger.warning("No base layer found.")

Expand Down Expand Up @@ -313,7 +313,7 @@ def _prepare_weights(self):

for layer in self.layers:
self._generate_weights(layer)
self.logger.info("Prepared weights for %s layers.", len(self.layers))
self.logger.debug("Prepared weights for %s layers.", len(self.layers))

def _generate_weights(self, layer: Layer) -> None:
"""Generates weight files for textures. Each file is a numpy array of zeros and
Expand Down Expand Up @@ -416,7 +416,7 @@ def draw(self) -> None:
cumulative_image = cv2.bitwise_or(cumulative_image, output_image)

cv2.imwrite(layer_path, output_image)
self.logger.info("Texture %s saved.", layer_path)
self.logger.debug("Texture %s saved.", layer_path)

# Save info layer data.
with open(self.info_layer_path, "w", encoding="utf-8") as f:
Expand Down Expand Up @@ -481,8 +481,6 @@ def dissolve(self) -> None:

self.logger.info("Dissolved layer %s.", layer.name)

self.logger.info("Dissolving finished.")

def draw_base_layer(self, cumulative_image: np.ndarray) -> None:
"""Draws base layer and saves it into the png file.
Base layer is the last layer to be drawn, it fills the remaining area of the map.
Expand All @@ -496,7 +494,7 @@ def draw_base_layer(self, cumulative_image: np.ndarray) -> None:
self.logger.debug("Drawing base layer %s.", layer_path)
img = cv2.bitwise_not(cumulative_image)
cv2.imwrite(layer_path, img)
self.logger.info("Base texture %s saved.", layer_path)
self.logger.debug("Base texture %s saved.", layer_path)

def get_relative_x(self, x: float) -> int:
"""Converts UTM X coordinate to relative X coordinate in map image.
Expand Down Expand Up @@ -635,9 +633,8 @@ def polygons(
is_fieds = info_layer == "fields"
try:
objects = ox.features_from_bbox(bbox=self.new_bbox, tags=tags)
except Exception as e: # pylint: disable=W0718
self.logger.warning("Error fetching objects for tags: %s.", tags)
self.logger.warning(e)
except Exception: # pylint: disable=W0718
self.logger.debug("Error fetching objects for tags: %s.", tags)
return
objects_utm = ox.projection.project_gdf(objects, to_latlong=False)
self.logger.debug("Fetched %s elements for tags: %s.", len(objects_utm), tags)
Expand Down Expand Up @@ -712,5 +709,5 @@ def _osm_preview(self) -> str:
preview_path = os.path.join(self.previews_directory, "textures_osm.png")

cv2.imwrite(preview_path, merged) # type: ignore
self.logger.info("Preview saved to %s.", preview_path)
self.logger.debug("Preview saved to %s.", preview_path)
return preview_path
22 changes: 14 additions & 8 deletions webui/generator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
from datetime import datetime
from time import perf_counter

import config
import osmp
Expand Down Expand Up @@ -372,8 +373,8 @@ def add_left_widgets(self) -> None:

with st.expander("Background Advanced Settings", icon="🖼️"):
st.info(
"ℹ️ Settings related to the background of the map, which represent the sky, "
"clouds, etc."
"ℹ️ Settings related to the background of the map, which represent the "
"surrounding area of the map."
)

st.write("Generate background:")
Expand Down Expand Up @@ -496,26 +497,26 @@ def generate_map(self) -> None:
plateau=plateau,
water_depth=self.water_depth,
)
self.logger.info("DEM settings: %s", dem_settings)
self.logger.debug("DEM settings: %s", dem_settings)

background_settings = mfs.BackgroundSettings(
generate_background=self.generate_background, generate_water=self.generate_water
)
self.logger.info("Background settings: %s", background_settings)
self.logger.debug("Background settings: %s", background_settings)

grle_settings = mfs.GRLESettings(
farmland_margin=self.farmland_margin,
random_plants=self.randomize_plants,
)
self.logger.info("GRLE settings: %s", grle_settings)
self.logger.debug("GRLE settings: %s", grle_settings)

i3d_settings = mfs.I3DSettings(forest_density=self.forest_density)
self.logger.info("I3D settings: %s", i3d_settings)
self.logger.debug("I3D settings: %s", i3d_settings)

texture_settings = mfs.TextureSettings(
dissolve=self.dissolving_enabled, fields_padding=self.fields_padding
)
self.logger.info("Texture settings: %s", texture_settings)
self.logger.debug("Texture settings: %s", texture_settings)

mp = mfs.Map(
game,
Expand Down Expand Up @@ -544,6 +545,8 @@ def generate_map(self) -> None:
step = int(100 / (len(game.components) + 2))
completed = 0
progress_bar = st.progress(0)

generation_started_at = perf_counter()
for component_name in mp.generate():
progress_bar.progress(completed, f"⏳ Generating {component_name}...")
completed += step
Expand All @@ -565,7 +568,10 @@ def generate_map(self) -> None:

st.session_state.generated = True

self.status_container.success("Map generation completed!", icon="✅")
generation_finished_at = perf_counter()
generation_time = round(generation_finished_at - generation_started_at, 3)
self.logger.info("Map generated in %s seconds.", generation_time)
self.status_container.success(f"Map generated in {generation_time} seconds.", icon="✅")
except Exception as e:
self.logger.error("An error occurred while generating the map: %s", repr(e))
self.status_container.error(
Expand Down

0 comments on commit 4c35803

Please sign in to comment.