maps4fs 0.9.7__py3-none-any.whl → 0.9.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
maps4fs/generator/dem.py CHANGED
@@ -79,6 +79,22 @@ class DEM(Component):
79
79
  )
80
80
  return dem_width, dem_height
81
81
 
82
+ def to_ground(self, data: np.ndarray) -> np.ndarray:
83
+ """Receives the signed 16-bit integer array and converts it to the ground level.
84
+ If the min value is negative, it will become zero value and the rest of the values
85
+ will be shifted accordingly.
86
+ """
87
+ # For examlem, min value was -50, it will become 0 and for all values we'll +50.
88
+
89
+ if data.min() < 0:
90
+ self.logger.debug("Array contains negative values, will be shifted to the ground.")
91
+ data = data + abs(data.min())
92
+
93
+ self.logger.debug(
94
+ "Array was shifted to the ground. Min: %s, max: %s.", data.min(), data.max()
95
+ )
96
+ return data
97
+
82
98
  # pylint: disable=no-member
83
99
  def process(self) -> None:
84
100
  """Reads SRTM file, crops it to map size, normalizes and blurs it,
@@ -119,6 +135,8 @@ class DEM(Component):
119
135
  data.max(),
120
136
  )
121
137
 
138
+ data = self.to_ground(data)
139
+
122
140
  resampled_data = cv2.resize(
123
141
  data, dem_output_resolution, interpolation=cv2.INTER_LINEAR
124
142
  ).astype("uint16")
@@ -0,0 +1 @@
1
+ # pylint: disable=missing-module-docstring
maps4fs/toolbox/dem.py ADDED
@@ -0,0 +1,112 @@
1
+ """This module contains functions for working with Digital Elevation Models (DEMs)."""
2
+
3
+ import os
4
+
5
+ import rasterio # type: ignore
6
+ from pyproj import Transformer
7
+ from rasterio.io import DatasetReader # type: ignore
8
+ from rasterio.windows import from_bounds # type: ignore
9
+
10
+
11
+ def read_geo_tiff(file_path: str) -> DatasetReader:
12
+ """Read a GeoTIFF file and return the DatasetReader object.
13
+
14
+ Args:
15
+ file_path (str): The path to the GeoTIFF file.
16
+
17
+ Raises:
18
+ FileNotFoundError: If the file is not found.
19
+ RuntimeError: If there is an error reading the file.
20
+
21
+ Returns:
22
+ DatasetReader: The DatasetReader object for the GeoTIFF file.
23
+ """
24
+ if not os.path.isfile(file_path):
25
+ raise FileNotFoundError(f"File not found: {file_path}")
26
+
27
+ try:
28
+ src = rasterio.open(file_path)
29
+ except Exception as e:
30
+ raise RuntimeError(f"Error reading file: {file_path}") from e
31
+
32
+ if not src.bounds or not src.crs:
33
+ raise RuntimeError(
34
+ f"Can not read bounds or CRS from file: {file_path}. "
35
+ f"Bounds: {src.bounds}, CRS: {src.crs}"
36
+ )
37
+
38
+ return src
39
+
40
+
41
+ def get_geo_tiff_bbox(
42
+ src: DatasetReader, dst_crs: str | None = "EPSG:4326"
43
+ ) -> tuple[float, float, float, float]:
44
+ """Return the bounding box of a GeoTIFF file in the destination CRS.
45
+
46
+ Args:
47
+ src (DatasetReader): The DatasetReader object for the GeoTIFF file.
48
+ dst_crs (str, optional): The destination CRS. Defaults to "EPSG:4326".
49
+
50
+ Returns:
51
+ tuple[float, float, float, float]: The bounding box in the destination CRS
52
+ as (north, south, east, west).
53
+ """
54
+ left, bottom, right, top = src.bounds
55
+
56
+ transformer = Transformer.from_crs(src.crs, dst_crs, always_xy=True)
57
+
58
+ east, north = transformer.transform(left, top)
59
+ west, south = transformer.transform(right, bottom)
60
+
61
+ return north, south, east, west
62
+
63
+
64
+ # pylint: disable=R0914
65
+ def extract_roi(file_path: str, bbox: tuple[float, float, float, float]) -> str:
66
+ """Extract a region of interest (ROI) from a GeoTIFF file and save it as a new file.
67
+
68
+ Args:
69
+ file_path (str): The path to the GeoTIFF file.
70
+ bbox (tuple[float, float, float, float]): The bounding box of the region of interest
71
+ as (north, south, east, west).
72
+
73
+ Raises:
74
+ RuntimeError: If there is no data in the selected region.
75
+
76
+ Returns:
77
+ str: The path to the new GeoTIFF file containing the extracted ROI.
78
+ """
79
+ with rasterio.open(file_path) as src:
80
+ transformer = Transformer.from_crs("EPSG:4326", src.crs, always_xy=True)
81
+ north, south, east, west = bbox
82
+
83
+ left, bottom = transformer.transform(west, south)
84
+ right, top = transformer.transform(east, north)
85
+
86
+ window = from_bounds(left, bottom, right, top, src.transform)
87
+ data = src.read(window=window)
88
+
89
+ if not data.size > 0:
90
+ raise RuntimeError("No data in the selected region.")
91
+
92
+ base_name = os.path.basename(file_path).split(".")[0]
93
+ dir_name = os.path.dirname(file_path)
94
+
95
+ output_name = f"{base_name}_{north}_{south}_{east}_{west}.tif"
96
+
97
+ output_path = os.path.join(dir_name, output_name)
98
+
99
+ with rasterio.open(
100
+ output_path,
101
+ "w",
102
+ driver="GTiff",
103
+ height=data.shape[1],
104
+ width=data.shape[2],
105
+ count=data.shape[0],
106
+ dtype=data.dtype,
107
+ crs=src.crs,
108
+ transform=src.window_transform(window),
109
+ ) as dst:
110
+ dst.write(data)
111
+
112
+ return output_path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maps4fs
3
- Version: 0.9.7
3
+ Version: 0.9.9
4
4
  Summary: Generate map templates for Farming Simulator from real places.
5
5
  Author-email: iwatkot <iwatkot@gmail.com>
6
6
  License: MIT License
@@ -31,7 +31,8 @@ Requires-Dist: tifffile
31
31
  <a href="#Quick-Start">Quick Start</a> •
32
32
  <a href="#Overview">Overview</a> •
33
33
  <a href="#How-To-Run">How-To-Run</a> •
34
- <a href="tutorials/FAQ.md">FAQ</a><br>
34
+ <a href="docs/FAQ.md">FAQ</a>
35
+ <a href="#Modder-Toolbox">Modder Toolbox</a><br>
35
36
  <a href="#Supported-objects">Supported objects</a> •
36
37
  <a href="#Generation-info">Generation info</a> •
37
38
  <a href="#Texture-schema">Texture schema</a> •
@@ -65,6 +66,7 @@ Requires-Dist: tifffile
65
66
  🚜 Supports Farming Simulator 22 and 25<br>
66
67
  🔷 Generates *.obj files for background terrain based on the real-world height map<br>
67
68
  📄 Generates scripts to download high-resolution satellite images from [QGIS](https://qgis.org/download/) in one click<br>
69
+ 🧰 Modder Toolbox to help you with various of tasks 🆕<br>
68
70
 
69
71
  <p align="center">
70
72
  <img src="https://github.com/user-attachments/assets/cf8f5752-9c69-4018-bead-290f59ba6976"><br>
@@ -196,6 +198,16 @@ for active_component in map.generate():
196
198
 
197
199
  The map will be saved in the `map_directory` directory.
198
200
 
201
+ ## Modder Toolbox
202
+ The tool now has a Modder Toolbox, which is a set of tools to help you with various tasks. You can open the toolbox by switching to the `🧰 Modder Toolbox` tab in the StreamLit app.<br>
203
+
204
+ ![Modder Toolbox](https://github.com/user-attachments/assets/18f169e9-1a5b-474c-b488-6becfffadcea)
205
+
206
+ ### Tool categories
207
+ Tools are divided into categories, which are listed below.
208
+ #### Textures and DEM
209
+ - **GeoTIFF windowing** - allows you to upload your GeoTIFF file and select the region of interest to extract it from the image.
210
+
199
211
  ## Supported objects
200
212
  The project is based on the [OpenStreetMap](https://www.openstreetmap.org/) data. So, refer to [this page](https://wiki.openstreetmap.org/wiki/Map_Features) to understand the list below.
201
213
  - "building": True
@@ -374,9 +386,9 @@ If you're willing to create a background terrain, you will need: Blender, the Bl
374
386
 
375
387
  If you're afraid of this task, please don't be. It's really simple and I've prepaired detailed step-by-step instructions for you, you'll find them in the separate README files. Here are the steps you need to follow:
376
388
 
377
- 1. [Download high-resolution satellite images](tutorials/README_satellite_images.md).
378
- 2. [Prepare the i3d files](tutorials/README_i3d.md).
379
- 3. [Import the i3d files to Giants Editor](tutorials/README_giants_editor.md).
389
+ 1. [Download high-resolution satellite images](docs/download_satellite_images.md).
390
+ 2. [Prepare the i3d files](docs/create_background_terrain.md).
391
+ 3. [Import the i3d files to Giants Editor](docs/import_to_giants_editor.md).
380
392
 
381
393
  ## Overview image
382
394
  The overview image is an image that is used as in-game map. No matter what the size of the map, this file is always `4096x4096 pixels`, while the region of your map is `2048x2048 pixels` in center of this file. The rest of the image is just here for nice view, but you still may add satellite pictures to this region.<br>
@@ -416,7 +428,7 @@ You can also apply some advanced settings to the map generation process. Note th
416
428
 
417
429
  Here's the list of the advanced settings:
418
430
 
419
- - DEM multiplier: the height of the map is multiplied by this value. So the DEM map is just a 16-bit grayscale image, which means that the maximum avaiable value there is 65535, while the actual difference between the deepest and the highest point on Earth is about 20 km. So, by default this value is set to 3. Just note that this setting mostly does not matter, because you can always adjust it in the Giants Editor, learn more about the [heightScale](https://www.farming-simulator.org/19/terrain-heightscale.php) parameter on the [PMC Farming Simulator](https://www.farming-simulator.org/) website.
431
+ - DEM multiplier: the height of the map is multiplied by this value. So the DEM map is just a 16-bit grayscale image, which means that the maximum avaiable value there is 65535, while the actual difference between the deepest and the highest point on Earth is about 20 km. Just note that this setting mostly does not matter, because you can always adjust it in the Giants Editor, learn more about the DEM file and the heightScale paramter in [docs](docs/dem.md). By default, it's set to 1.
420
432
 
421
433
  - DEM Blur radius: the radius of the Gaussian blur filter applied to the DEM map. By default, it's set to 21. This filter just makes the DEM map smoother, so the height transitions will be more natural. You can set it to 1 to disable the filter, but it will result as a Minecraft-like map.
422
434
 
@@ -434,5 +446,5 @@ To create a basic map, you only need the Giants Editor. But if you want to creat
434
446
  6. [AnyConv](https://anyconv.com/png-to-dds-converter/) - the online tool to convert the PNG images to the DDS format. You'll need this format for the textures, icons, overview and preview images.
435
447
 
436
448
  ## Bugs and feature requests
437
- ➡️ Please, before creating an issue or asking some questions, check the [FAQ](tutorials/FAQ.md) section.<br>
449
+ ➡️ Please, before creating an issue or asking some questions, check the [FAQ](docs/FAQ.md) section.<br>
438
450
  If you find a bug or have an idea for a new feature, please create an issue [here](https://github.com/iwatkot/maps4fs/issues) or contact me directly on [Telegram](https://t.me/iwatkot) or on Discord: `iwatkot`.
@@ -4,7 +4,7 @@ maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk
4
4
  maps4fs/generator/background.py,sha256=AP-Z3F-4I9achvA9xsaXAAoA6IHtmPLxb1RkUsVYdbg,14036
5
5
  maps4fs/generator/component.py,sha256=ZEDjChPnvqAsgnBu2f2YBOlwGOlfax4VaAYBcJerLIQ,10684
6
6
  maps4fs/generator/config.py,sha256=ZO5BWDU-S3p0-ndKDSFa8Oin3YcYy0iH8B4lqEA_07Q,4275
7
- maps4fs/generator/dem.py,sha256=XLpzjJMPZCxjrF-AhwTeEb-OQoCHEtYdK0b8z3Gb-is,15712
7
+ maps4fs/generator/dem.py,sha256=rBqVeWiLEpY89EIpfnSENOYsNYxsJcV_Y2UuBalE104,16438
8
8
  maps4fs/generator/game.py,sha256=94HjPNOyy6XSSOnBp-uxrkBglKyC-X3ULIrrucfdlKw,6825
9
9
  maps4fs/generator/i3d.py,sha256=UuQiQRusPQ2f6PvGKxJ_UZeXsx3uG15efmy8Ysnm3F8,3597
10
10
  maps4fs/generator/map.py,sha256=v8OOLmhAkgqq64tQgEDbV6DmbgOVm3NXJBDDy0nJf60,4226
@@ -12,8 +12,10 @@ maps4fs/generator/path_steps.py,sha256=yeN6hmOD8O2LMozUf4HcQMIy8WJ5sHF5pGQT_s2Ff
12
12
  maps4fs/generator/qgis.py,sha256=R5Iv3ovyLXkhAL5Oy41u3ZLNOSEbc1byLetzPootO7o,6091
13
13
  maps4fs/generator/texture.py,sha256=CwaXZfAG4e3D3YR7yVR2MC677EHpbUWTboCS3G6jkhk,17723
14
14
  maps4fs/generator/tile.py,sha256=3vmfjQiPiiUZKPuIo5tg2rOKkgcP1NRVkMGK-Vo10-A,2138
15
- maps4fs-0.9.7.dist-info/LICENSE.md,sha256=-JY0v7p3dwXze61EbYiK7YEJ2aKrjaFZ8y2xYEOrmRY,1068
16
- maps4fs-0.9.7.dist-info/METADATA,sha256=dhMICyAhvj7SiKMKyK_-ewOb07j38R574o9SMezErYE,24635
17
- maps4fs-0.9.7.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
18
- maps4fs-0.9.7.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
19
- maps4fs-0.9.7.dist-info/RECORD,,
15
+ maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
16
+ maps4fs/toolbox/dem.py,sha256=53KVZ6IKIlK642eYFSRDAC8l2HL9IEUpQNYkkTC56uU,3510
17
+ maps4fs-0.9.9.dist-info/LICENSE.md,sha256=-JY0v7p3dwXze61EbYiK7YEJ2aKrjaFZ8y2xYEOrmRY,1068
18
+ maps4fs-0.9.9.dist-info/METADATA,sha256=rWT-sSS7QfXGArOqjWMLdCxSRm0bkGd0uMZwJegayZc,25170
19
+ maps4fs-0.9.9.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
20
+ maps4fs-0.9.9.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
21
+ maps4fs-0.9.9.dist-info/RECORD,,