maps4fs 0.9.98__tar.gz → 1.0.3__tar.gz

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.
Files changed (30) hide show
  1. {maps4fs-0.9.98 → maps4fs-1.0.3}/PKG-INFO +38 -9
  2. {maps4fs-0.9.98 → maps4fs-1.0.3}/README.md +36 -7
  3. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/background.py +16 -115
  4. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/component.py +12 -2
  5. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/config.py +1 -1
  6. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/dem.py +13 -12
  7. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/game.py +2 -1
  8. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/grle.py +1 -1
  9. maps4fs-1.0.3/maps4fs/generator/i3d.py +358 -0
  10. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/map.py +3 -3
  11. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/texture.py +39 -10
  12. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/tile.py +3 -3
  13. maps4fs-1.0.3/maps4fs/toolbox/background.py +63 -0
  14. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs.egg-info/PKG-INFO +38 -9
  15. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs.egg-info/SOURCES.txt +1 -0
  16. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs.egg-info/requires.txt +1 -1
  17. {maps4fs-0.9.98 → maps4fs-1.0.3}/pyproject.toml +2 -2
  18. maps4fs-0.9.98/maps4fs/generator/i3d.py +0 -89
  19. {maps4fs-0.9.98 → maps4fs-1.0.3}/LICENSE.md +0 -0
  20. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/__init__.py +0 -0
  21. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/__init__.py +0 -0
  22. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/path_steps.py +0 -0
  23. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/generator/qgis.py +0 -0
  24. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/logger.py +0 -0
  25. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/toolbox/__init__.py +0 -0
  26. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs/toolbox/dem.py +0 -0
  27. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs.egg-info/dependency_links.txt +0 -0
  28. {maps4fs-0.9.98 → maps4fs-1.0.3}/maps4fs.egg-info/top_level.txt +0 -0
  29. {maps4fs-0.9.98 → maps4fs-1.0.3}/setup.cfg +0 -0
  30. {maps4fs-0.9.98 → maps4fs-1.0.3}/tests/test_generator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maps4fs
3
- Version: 0.9.98
3
+ Version: 1.0.3
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
@@ -14,7 +14,7 @@ Classifier: Operating System :: OS Independent
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE.md
16
16
  Requires-Dist: opencv-python
17
- Requires-Dist: osmnx<2.0.0
17
+ Requires-Dist: osmnx>=2.0.0
18
18
  Requires-Dist: rasterio
19
19
  Requires-Dist: folium
20
20
  Requires-Dist: geopy
@@ -31,8 +31,10 @@ Requires-Dist: pympler
31
31
  <p align="center">
32
32
  <a href="#Quick-Start">Quick Start</a> •
33
33
  <a href="#Overview">Overview</a> •
34
- <a href="#How-To-Run">How-To-Run</a> •
34
+ <a href="#Step-by-step">Create a map in 10 steps</a> •
35
+ <a href="#How-To-Run">How-To-Run</a><br>
35
36
  <a href="docs/FAQ.md">FAQ</a> •
37
+ <a href="docs/map_structure.md">Map Structure</a> •
36
38
  <a href="#Modder-Toolbox">Modder Toolbox</a><br>
37
39
  <a href="#Supported-objects">Supported objects</a> •
38
40
  <a href="#Generation-info">Generation info</a> •
@@ -68,6 +70,7 @@ Requires-Dist: pympler
68
70
  🔷 Generates *.obj files for background terrain based on the real-world height map<br>
69
71
  📄 Generates scripts to download high-resolution satellite images from [QGIS](https://qgis.org/download/) in one click<br>
70
72
  🧰 Modder Toolbox to help you with various of tasks 🆕<br>
73
+ 🌾 Automatically generates fields 🆕<br>
71
74
 
72
75
  <p align="center">
73
76
  <img src="https://github.com/user-attachments/assets/cf8f5752-9c69-4018-bead-290f59ba6976"><br>
@@ -76,6 +79,8 @@ Requires-Dist: pympler
76
79
  🛰️ Realistic background terrain objects with satellite images.<br><br>
77
80
  <img src="https://github.com/user-attachments/assets/80e5923c-22c7-4dc0-8906-680902511f3a"><br>
78
81
  🗒️ True-to-life blueprints for fast and precise modding.<br><br>
82
+ <img width="480" src="https://github.com/user-attachments/assets/1a8802d2-6a3b-4bfa-af2b-7c09478e199b"><br>
83
+ 🌾 Field generation with one click.<br><br>
79
84
  <img src="https://github.com/user-attachments/assets/cce45575-c917-4a1b-bdc0-6368e32ccdff"><br>
80
85
  📏 Almost any possible map sizes.
81
86
  </p>
@@ -84,6 +89,13 @@ Requires-Dist: pympler
84
89
  There are several ways to use the tool. You obviously need the **first one**, but you can choose any of the others depending on your needs.<br>
85
90
  ### 🚜 For most users
86
91
  **Option 1:** open the [maps4fs](https://maps4fs.streamlit.app) on StreamLit and generate a map template in a few clicks.<br>
92
+ <i>Note, that StreamLit community hosting has some limitations, such as: <br>
93
+ 1. Maximum map size is 4096x4096 meters. <br>
94
+ 2. Advanced settings are disabled. <br>
95
+ 3. Texure dissolving is disabled (they will look worse). </i><br>
96
+
97
+ If you run the application locally, you won't have any of these limitations and will be able to generate maps of any size with any settings you want and nice looking textures.<br>
98
+ So, jump to [Docker version](#option-2-docker-version) to launch the tool with one command and get the full experience.<br>
87
99
 
88
100
  ![Basic WebUI](https://github.com/user-attachments/assets/52f499cc-f28a-4da3-abef-0e818abe8dbe)
89
101
 
@@ -126,6 +138,9 @@ Parameters:
126
138
  - coordinates: 45.15, 19.71
127
139
  - size: 16 x 16 km
128
140
 
141
+ ## Step by step
142
+ Don't know where to start? Don't worry, just follow this [step-by-step guide](docs/step_by_step.md) to create your first map in 10 simple steps.<br>
143
+
129
144
  ## How-To-Run
130
145
 
131
146
  You'll find detailed instructions on how to run the project below. But if you prefer video tutorials, here's one for you:
@@ -133,14 +148,22 @@ You'll find detailed instructions on how to run the project below. But if you pr
133
148
  <i>Video tutorial: How to generate a Farming Simulator 22 map from real-world data.</i>
134
149
 
135
150
  ### Option 1: StreamLit
136
- 🟢 Recommended for all users, you don't need to install anything.<br>
151
+ 🟢 Recommended for all users.
152
+ 🛠️ Don't need to install anything.
153
+ 🗺️ Supported map sizes: 2x2, 4x4 km.
154
+ ⚙️ Advanced settings: disabled.
155
+ 🖼️ Texture dissolving: disabled.
137
156
  Using the [StreamLit](https://maps4fs.streamlit.app) version of the tool is the easiest way to generate a map template. Just open the link and follow the instructions.
138
157
  Note: due to CPU and RAM limitations of the hosting, the generation may take some time. If you need faster processing, use the [Docker version](#option-2-docker-version).<br>
139
158
 
140
159
  Using it is easy and doesn't require any guides. Enjoy!
141
160
 
142
161
  ### Option 2: Docker version
143
- 🟠 Recommended for users who want faster processing, very simple installation.<br>
162
+ 🟠 Recommended for users who want bigger maps, fast generation, nice looking textures and advanced settings.
163
+ 🛠️ Launch with one single command.
164
+ 🗺️ Supported map sizes: 2x2, 4x4, 8x8, 16x16 km and any custom size.
165
+ ⚙️ Advanced settings: enabled.
166
+ 🖼️ Texture dissolving: enabled.
144
167
  You can launch the project with minimalistic UI in your browser using Docker. Follow these steps:
145
168
 
146
169
  1. Install [Docker](https://docs.docker.com/get-docker/) for your OS.
@@ -153,7 +176,10 @@ docker run -d -p 8501:8501 iwatkot/maps4fs
153
176
  5. When the map is generated click on the `Download` button to get the map.
154
177
 
155
178
  ### Option 3: Python package
156
- 🔴 Recommended for developers.<br>
179
+ 🔴 Recommended for developers.
180
+ 🗺️ Supported map sizes: 2x2, 4x4, 8x8, 16x16 km and any custom size.
181
+ ⚙️ Advanced settings: enabled.
182
+ 🖼️ Texture dissolving: enabled.
157
183
  You can use the Python package to generate maps. Follow these steps:
158
184
 
159
185
  1. Install the package from PyPI:
@@ -202,12 +228,15 @@ The map will be saved in the `map_directory` directory.
202
228
  ## Modder Toolbox
203
229
  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>
204
230
 
205
- ![Modder Toolbox](https://github.com/user-attachments/assets/18f169e9-1a5b-474c-b488-6becfffadcea)
231
+ ![Modder Toolbox](https://github.com/user-attachments/assets/dffb252f-f5c0-4021-9d45-31e5bccc0d9b)
206
232
 
207
233
  ### Tool categories
208
234
  Tools are divided into categories, which are listed below.
209
235
  #### Textures and DEM
210
- - **GeoTIFF windowing** - allows you to upload your GeoTIFF file and select the region of interest to extract it from the image.
236
+ - **GeoTIFF windowing** - allows you to upload your GeoTIFF file and select the region of interest to extract it from the image. It's useful when you have high-resolution DEM data and want to create the height map using it.
237
+
238
+ #### Background terrain
239
+ - **Convert image to obj model** - allows you to convert the image to the obj model. You can use this tool to create the background terrain for your map. It can be extremely useful if you have access to the sources of high-resolution DEM data and want to create the background terrain using it.
211
240
 
212
241
  ## Supported objects
213
242
  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.
@@ -376,7 +405,7 @@ Let's have a closer look at the fields:
376
405
 
377
406
  ## Background terrain
378
407
  The tool now supports the generation of the background terrain. If you don't know what it is, here's a brief explanation. The background terrain is the world around the map. It's important to create it, because if you don't, the map will look like it's floating in the void. The background terrain is a simple plane which can (and should) be texture to look fine.<br>
379
- So, the tool generates the background terrain in the form of the 8 tiles, which surround the map. The tiles are named as the cardinal points, e.g. "N", "NE", "E" and so on. All those tiles will be saved in the `objects/tiles` directory with corresponding names: `N.obj`, `NE.obj`, `E.obj` and so on.<br>
408
+ So, the tool generates the background terrain in the form of the 8 tiles, which surround the map. The tiles are named as the cardinal points, e.g. "N", "NE", "E" and so on. All those tiles will be saved in the `background` directory with corresponding names: `N.obj`, `NE.obj`, `E.obj` and so on.<br>
380
409
  If you don't want to work with separate tiles, the tool also generates the `FULL.obj` file, which includes everything around the map and the map itself. It may be a convinient approach to work with one file, one texture and then just cut the map from it.<br>
381
410
 
382
411
  ![Complete background terrain in Blender](https://github.com/user-attachments/assets/7266b8f1-bfa2-4c14-a740-1c84b1030a66)
@@ -6,8 +6,10 @@
6
6
  <p align="center">
7
7
  <a href="#Quick-Start">Quick Start</a> •
8
8
  <a href="#Overview">Overview</a> •
9
- <a href="#How-To-Run">How-To-Run</a> •
9
+ <a href="#Step-by-step">Create a map in 10 steps</a> •
10
+ <a href="#How-To-Run">How-To-Run</a><br>
10
11
  <a href="docs/FAQ.md">FAQ</a> •
12
+ <a href="docs/map_structure.md">Map Structure</a> •
11
13
  <a href="#Modder-Toolbox">Modder Toolbox</a><br>
12
14
  <a href="#Supported-objects">Supported objects</a> •
13
15
  <a href="#Generation-info">Generation info</a> •
@@ -43,6 +45,7 @@
43
45
  🔷 Generates *.obj files for background terrain based on the real-world height map<br>
44
46
  📄 Generates scripts to download high-resolution satellite images from [QGIS](https://qgis.org/download/) in one click<br>
45
47
  🧰 Modder Toolbox to help you with various of tasks 🆕<br>
48
+ 🌾 Automatically generates fields 🆕<br>
46
49
 
47
50
  <p align="center">
48
51
  <img src="https://github.com/user-attachments/assets/cf8f5752-9c69-4018-bead-290f59ba6976"><br>
@@ -51,6 +54,8 @@
51
54
  🛰️ Realistic background terrain objects with satellite images.<br><br>
52
55
  <img src="https://github.com/user-attachments/assets/80e5923c-22c7-4dc0-8906-680902511f3a"><br>
53
56
  🗒️ True-to-life blueprints for fast and precise modding.<br><br>
57
+ <img width="480" src="https://github.com/user-attachments/assets/1a8802d2-6a3b-4bfa-af2b-7c09478e199b"><br>
58
+ 🌾 Field generation with one click.<br><br>
54
59
  <img src="https://github.com/user-attachments/assets/cce45575-c917-4a1b-bdc0-6368e32ccdff"><br>
55
60
  📏 Almost any possible map sizes.
56
61
  </p>
@@ -59,6 +64,13 @@
59
64
  There are several ways to use the tool. You obviously need the **first one**, but you can choose any of the others depending on your needs.<br>
60
65
  ### 🚜 For most users
61
66
  **Option 1:** open the [maps4fs](https://maps4fs.streamlit.app) on StreamLit and generate a map template in a few clicks.<br>
67
+ <i>Note, that StreamLit community hosting has some limitations, such as: <br>
68
+ 1. Maximum map size is 4096x4096 meters. <br>
69
+ 2. Advanced settings are disabled. <br>
70
+ 3. Texure dissolving is disabled (they will look worse). </i><br>
71
+
72
+ If you run the application locally, you won't have any of these limitations and will be able to generate maps of any size with any settings you want and nice looking textures.<br>
73
+ So, jump to [Docker version](#option-2-docker-version) to launch the tool with one command and get the full experience.<br>
62
74
 
63
75
  ![Basic WebUI](https://github.com/user-attachments/assets/52f499cc-f28a-4da3-abef-0e818abe8dbe)
64
76
 
@@ -101,6 +113,9 @@ Parameters:
101
113
  - coordinates: 45.15, 19.71
102
114
  - size: 16 x 16 km
103
115
 
116
+ ## Step by step
117
+ Don't know where to start? Don't worry, just follow this [step-by-step guide](docs/step_by_step.md) to create your first map in 10 simple steps.<br>
118
+
104
119
  ## How-To-Run
105
120
 
106
121
  You'll find detailed instructions on how to run the project below. But if you prefer video tutorials, here's one for you:
@@ -108,14 +123,22 @@ You'll find detailed instructions on how to run the project below. But if you pr
108
123
  <i>Video tutorial: How to generate a Farming Simulator 22 map from real-world data.</i>
109
124
 
110
125
  ### Option 1: StreamLit
111
- 🟢 Recommended for all users, you don't need to install anything.<br>
126
+ 🟢 Recommended for all users.
127
+ 🛠️ Don't need to install anything.
128
+ 🗺️ Supported map sizes: 2x2, 4x4 km.
129
+ ⚙️ Advanced settings: disabled.
130
+ 🖼️ Texture dissolving: disabled.
112
131
  Using the [StreamLit](https://maps4fs.streamlit.app) version of the tool is the easiest way to generate a map template. Just open the link and follow the instructions.
113
132
  Note: due to CPU and RAM limitations of the hosting, the generation may take some time. If you need faster processing, use the [Docker version](#option-2-docker-version).<br>
114
133
 
115
134
  Using it is easy and doesn't require any guides. Enjoy!
116
135
 
117
136
  ### Option 2: Docker version
118
- 🟠 Recommended for users who want faster processing, very simple installation.<br>
137
+ 🟠 Recommended for users who want bigger maps, fast generation, nice looking textures and advanced settings.
138
+ 🛠️ Launch with one single command.
139
+ 🗺️ Supported map sizes: 2x2, 4x4, 8x8, 16x16 km and any custom size.
140
+ ⚙️ Advanced settings: enabled.
141
+ 🖼️ Texture dissolving: enabled.
119
142
  You can launch the project with minimalistic UI in your browser using Docker. Follow these steps:
120
143
 
121
144
  1. Install [Docker](https://docs.docker.com/get-docker/) for your OS.
@@ -128,7 +151,10 @@ docker run -d -p 8501:8501 iwatkot/maps4fs
128
151
  5. When the map is generated click on the `Download` button to get the map.
129
152
 
130
153
  ### Option 3: Python package
131
- 🔴 Recommended for developers.<br>
154
+ 🔴 Recommended for developers.
155
+ 🗺️ Supported map sizes: 2x2, 4x4, 8x8, 16x16 km and any custom size.
156
+ ⚙️ Advanced settings: enabled.
157
+ 🖼️ Texture dissolving: enabled.
132
158
  You can use the Python package to generate maps. Follow these steps:
133
159
 
134
160
  1. Install the package from PyPI:
@@ -177,12 +203,15 @@ The map will be saved in the `map_directory` directory.
177
203
  ## Modder Toolbox
178
204
  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>
179
205
 
180
- ![Modder Toolbox](https://github.com/user-attachments/assets/18f169e9-1a5b-474c-b488-6becfffadcea)
206
+ ![Modder Toolbox](https://github.com/user-attachments/assets/dffb252f-f5c0-4021-9d45-31e5bccc0d9b)
181
207
 
182
208
  ### Tool categories
183
209
  Tools are divided into categories, which are listed below.
184
210
  #### Textures and DEM
185
- - **GeoTIFF windowing** - allows you to upload your GeoTIFF file and select the region of interest to extract it from the image.
211
+ - **GeoTIFF windowing** - allows you to upload your GeoTIFF file and select the region of interest to extract it from the image. It's useful when you have high-resolution DEM data and want to create the height map using it.
212
+
213
+ #### Background terrain
214
+ - **Convert image to obj model** - allows you to convert the image to the obj model. You can use this tool to create the background terrain for your map. It can be extremely useful if you have access to the sources of high-resolution DEM data and want to create the background terrain using it.
186
215
 
187
216
  ## Supported objects
188
217
  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.
@@ -351,7 +380,7 @@ Let's have a closer look at the fields:
351
380
 
352
381
  ## Background terrain
353
382
  The tool now supports the generation of the background terrain. If you don't know what it is, here's a brief explanation. The background terrain is the world around the map. It's important to create it, because if you don't, the map will look like it's floating in the void. The background terrain is a simple plane which can (and should) be texture to look fine.<br>
354
- So, the tool generates the background terrain in the form of the 8 tiles, which surround the map. The tiles are named as the cardinal points, e.g. "N", "NE", "E" and so on. All those tiles will be saved in the `objects/tiles` directory with corresponding names: `N.obj`, `NE.obj`, `E.obj` and so on.<br>
383
+ So, the tool generates the background terrain in the form of the 8 tiles, which surround the map. The tiles are named as the cardinal points, e.g. "N", "NE", "E" and so on. All those tiles will be saved in the `background` directory with corresponding names: `N.obj`, `NE.obj`, `E.obj` and so on.<br>
355
384
  If you don't want to work with separate tiles, the tool also generates the `FULL.obj` file, which includes everything around the map and the map itself. It may be a convinient approach to work with one file, one texture and then just cut the map from it.<br>
356
385
 
357
386
  ![Complete background terrain in Blender](https://github.com/user-attachments/assets/7266b8f1-bfa2-4c14-a740-1c84b1030a66)
@@ -15,7 +15,7 @@ from maps4fs.generator.dem import (
15
15
  DEFAULT_MULTIPLIER,
16
16
  DEFAULT_PLATEAU,
17
17
  )
18
- from maps4fs.generator.path_steps import DEFAULT_DISTANCE, PATH_FULL_NAME, get_steps
18
+ from maps4fs.generator.path_steps import PATH_FULL_NAME, get_steps
19
19
  from maps4fs.generator.tile import Tile
20
20
 
21
21
  RESIZE_FACTOR = 1 / 4
@@ -143,7 +143,7 @@ class Background(Component):
143
143
  self.logger.warning("DEM file not found, generation will be stopped: %s", dem_path)
144
144
  return
145
145
 
146
- self.logger.info("DEM file for tile %s found: %s", tile.code, dem_path)
146
+ self.logger.debug("DEM file for tile %s found: %s", tile.code, dem_path)
147
147
 
148
148
  base_directory = os.path.dirname(dem_path)
149
149
  save_path = os.path.join(base_directory, f"{tile.code}.obj")
@@ -164,7 +164,6 @@ class Background(Component):
164
164
  if tile_code == PATH_FULL_NAME:
165
165
  resize_factor = FULL_RESIZE_FACTOR
166
166
  simplify_factor = FULL_SIMPLIFY_FACTOR
167
- self.logger.info("Generating a full map obj file")
168
167
  else:
169
168
  resize_factor = RESIZE_FACTOR
170
169
  simplify_factor = SIMPLIFY_FACTOR
@@ -242,119 +241,21 @@ class Background(Component):
242
241
 
243
242
  self.stl_preview_path = preview_path # pylint: disable=attribute-defined-outside-init
244
243
 
244
+ # pylint: disable=no-member
245
245
  def previews(self) -> list[str]:
246
- """Generates a preview by combining all tiles into one image.
247
- NOTE: The map itself is not included in the preview, so it will be empty.
246
+ """Returns the path to the image of full tile and the path to the STL preview file.
248
247
 
249
248
  Returns:
250
- list[str] -- A list of paths to the preview images."""
251
-
252
- self.logger.info("Generating a preview image for the background DEM")
253
-
254
- image_height = self.map_height + DEFAULT_DISTANCE * 2
255
- image_width = self.map_width + DEFAULT_DISTANCE * 2
256
- self.logger.debug("Full size of the preview image: %s x %s", image_width, image_height)
257
-
258
- image = np.zeros((image_height, image_width), np.uint16) # pylint: disable=no-member
259
- self.logger.debug("Empty image created: %s", image.shape)
260
-
261
- for tile in self.tiles:
262
- # pylint: disable=no-member
263
- if tile.code == PATH_FULL_NAME:
264
- continue
265
- tile_image = cv2.imread(tile.dem_path, cv2.IMREAD_UNCHANGED)
266
-
267
- self.logger.debug(
268
- "Tile %s image shape: %s, dtype: %s, max: %s, min: %s",
269
- tile.code,
270
- tile_image.shape,
271
- tile_image.dtype,
272
- tile_image.max(),
273
- tile_image.min(),
274
- )
275
-
276
- tile_height, tile_width = tile_image.shape
277
- self.logger.debug("Tile %s size: %s x %s", tile.code, tile_width, tile_height)
278
-
279
- # Calculate the position based on the tile code
280
- if tile.code == "N":
281
- x = DEFAULT_DISTANCE
282
- y = 0
283
- elif tile.code == "NE":
284
- x = self.map_width + DEFAULT_DISTANCE
285
- y = 0
286
- elif tile.code == "E":
287
- x = self.map_width + DEFAULT_DISTANCE
288
- y = DEFAULT_DISTANCE
289
- elif tile.code == "SE":
290
- x = self.map_width + DEFAULT_DISTANCE
291
- y = self.map_height + DEFAULT_DISTANCE
292
- elif tile.code == "S":
293
- x = DEFAULT_DISTANCE
294
- y = self.map_height + DEFAULT_DISTANCE
295
- elif tile.code == "SW":
296
- x = 0
297
- y = self.map_height + DEFAULT_DISTANCE
298
- elif tile.code == "W":
299
- x = 0
300
- y = DEFAULT_DISTANCE
301
- elif tile.code == "NW":
302
- x = 0
303
- y = 0
304
-
305
- # pylint: disable=possibly-used-before-assignment
306
- x2 = x + tile_width
307
- y2 = y + tile_height
308
-
309
- self.logger.debug(
310
- "Tile %s position. X from %s to %s, Y from %s to %s", tile.code, x, x2, y, y2
249
+ list[str] -- A list of paths to the previews.
250
+ """
251
+ full_tile = next((tile for tile in self.tiles if tile.code == PATH_FULL_NAME), None)
252
+ if full_tile:
253
+ preview_path = os.path.join(self.previews_directory, "background_dem.png")
254
+ full_tile_image = cv2.imread(full_tile.dem_path, cv2.IMREAD_UNCHANGED)
255
+ full_tile_image = cv2.normalize( # type: ignore
256
+ full_tile_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U
311
257
  )
312
-
313
- # pylint: disable=possibly-used-before-assignment
314
- image[y:y2, x:x2] = tile_image
315
-
316
- # Save image to the map directory.
317
- preview_path = os.path.join(self.previews_directory, "background_dem.png")
318
-
319
- # pylint: disable=no-member
320
- image = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U) # type: ignore
321
- image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) # type: ignore
322
- cv2.imwrite(preview_path, image)
323
-
324
- return [preview_path, self.stl_preview_path]
325
-
326
-
327
- # Creates tiles around the map.
328
- # The one on corners 2048x2048, on sides and in the middle map_size x 2048.
329
- # So 2048 is a distance FROM the edge of the map, but the other size depends on the map size.
330
- # But for corner tiles it's always 2048.
331
-
332
- # In the beginning we have coordinates of the central point of the map and it's size.
333
- # We need to calculate the coordinates of central points all 8 tiles around the map.
334
-
335
- # Latitude is a vertical line, Longitude is a horizontal line.
336
-
337
- # 2048
338
- # | |
339
- # ____________________|_________|___
340
- # | | | |
341
- # | NW | N | NE | 2048
342
- # |_________|_________|_________|___
343
- # | | | |
344
- # | W | C | E |
345
- # |_________|_________|_________|
346
- # | | | |
347
- # | SW | S | SE |
348
- # |_________|_________|_________|
349
- #
350
- # N = C map_height / 2 + 1024; N_width = map_width; N_height = 2048
351
- # NW = N - map_width / 2 - 1024; NW_width = 2048; NW_height = 2048
352
- # and so on...
353
-
354
- # lat, lon = 45.28565000315636, 20.237121355049904
355
- # dst = 1024
356
-
357
- # # N
358
- # destination = distance(meters=dst).destination((lat, lon), 0)
359
- # lat, lon = destination.latitude, destination.longitude
360
- # print(lat, lon)
258
+ full_tile_image = cv2.cvtColor(full_tile_image, cv2.COLOR_GRAY2BGR)
259
+ cv2.imwrite(preview_path, full_tile_image)
260
+ return [preview_path, self.stl_preview_path]
261
+ return [self.stl_preview_path]
@@ -50,6 +50,7 @@ class Component:
50
50
 
51
51
  os.makedirs(self.previews_directory, exist_ok=True)
52
52
  os.makedirs(self.scripts_directory, exist_ok=True)
53
+ os.makedirs(self.info_layers_directory, exist_ok=True)
53
54
 
54
55
  self.save_bbox()
55
56
  self.preprocess()
@@ -87,6 +88,15 @@ class Component:
87
88
  """
88
89
  return os.path.join(self.map_directory, "previews")
89
90
 
91
+ @property
92
+ def info_layers_directory(self) -> str:
93
+ """The directory where the info layers are stored.
94
+
95
+ Returns:
96
+ str: The directory where the info layers are stored.
97
+ """
98
+ return os.path.join(self.map_directory, "info_layers")
99
+
90
100
  @property
91
101
  def scripts_directory(self) -> str:
92
102
  """The directory where the scripts are stored.
@@ -174,10 +184,10 @@ class Component:
174
184
  height_distance = height_distance or int(self.map_height / 2)
175
185
  width_distance = width_distance or int(self.map_width / 2)
176
186
 
177
- north, south, _, _ = ox.utils_geo.bbox_from_point(
187
+ west, south, _, _ = ox.utils_geo.bbox_from_point( # type: ignore
178
188
  coordinates, dist=height_distance, project_utm=project_utm
179
189
  )
180
- _, _, east, west = ox.utils_geo.bbox_from_point(
190
+ _, _, east, north = ox.utils_geo.bbox_from_point( # type: ignore
181
191
  coordinates, dist=width_distance, project_utm=project_utm
182
192
  )
183
193
  bbox = north, south, east, west
@@ -36,7 +36,7 @@ class Config(Component):
36
36
  self.logger.warning("Map XML file not found: %s.", self._map_xml_path)
37
37
  return
38
38
  tree = ET.parse(self._map_xml_path)
39
- self.logger.debug("Map XML file loaded from: %s.", self._map_xml_path)
39
+ self.logger.info("Map XML file loaded from: %s.", self._map_xml_path)
40
40
  root = tree.getroot()
41
41
  for map_elem in root.iter("map"):
42
42
  map_elem.set("width", str(self.map_width))
@@ -103,7 +103,7 @@ class DEM(Component):
103
103
  north, south, east, west = self.bbox
104
104
 
105
105
  dem_output_resolution = self.get_output_resolution()
106
- self.logger.debug("DEM output resolution: %s.", dem_output_resolution)
106
+ self.logger.info("DEM output resolution: %s.", dem_output_resolution)
107
107
 
108
108
  tile_path = self._srtm_tile()
109
109
  if not tile_path:
@@ -223,7 +223,7 @@ class DEM(Component):
223
223
  )
224
224
 
225
225
  cv2.imwrite(self._dem_path, resampled_data)
226
- self.logger.debug("DEM data was saved to %s.", self._dem_path)
226
+ self.logger.info("DEM data was saved to %s.", self._dem_path)
227
227
 
228
228
  if self.game.additional_dem_name is not None:
229
229
  self.make_copy(self.game.additional_dem_name)
@@ -239,7 +239,7 @@ class DEM(Component):
239
239
  additional_dem_path = os.path.join(dem_directory, dem_name)
240
240
 
241
241
  shutil.copyfile(self._dem_path, additional_dem_path)
242
- self.logger.debug("Additional DEM data was copied to %s.", additional_dem_path)
242
+ self.logger.info("Additional DEM data was copied to %s.", additional_dem_path)
243
243
 
244
244
  def _tile_info(self, lat: float, lon: float) -> tuple[str, str]:
245
245
  """Returns latitude band and tile name for SRTM tile from coordinates.
@@ -260,7 +260,7 @@ class DEM(Component):
260
260
  else:
261
261
  tile_name = f"{latitude_band}E{abs(tile_longitude):03d}"
262
262
 
263
- self.logger.debug(
263
+ self.logger.info(
264
264
  "Detected tile name: %s for coordinates: lat %s, lon %s.", tile_name, lat, lon
265
265
  )
266
266
  return latitude_band, tile_name
@@ -319,7 +319,7 @@ class DEM(Component):
319
319
  def _save_empty_dem(self, dem_output_resolution: tuple[int, int]) -> None:
320
320
  """Saves empty DEM file filled with zeros."""
321
321
  dem_data = np.zeros(dem_output_resolution, dtype="uint16")
322
- cv2.imwrite(self._dem_path, dem_data) # pylint: disable=no-member
322
+ cv2.imwrite(self._dem_path, dem_data)
323
323
  self.logger.warning("DEM data filled with zeros and saved to %s.", self._dem_path)
324
324
 
325
325
  def grayscale_preview(self) -> str:
@@ -329,7 +329,6 @@ class DEM(Component):
329
329
  Returns:
330
330
  str: Path to the preview image.
331
331
  """
332
- # rgb_dem_path = self._dem_path.replace(".png", "_grayscale.png")
333
332
  grayscale_dem_path = os.path.join(self.previews_directory, "dem_grayscale.png")
334
333
 
335
334
  self.logger.debug("Creating grayscale preview of DEM data in %s.", grayscale_dem_path)
@@ -346,8 +345,6 @@ class DEM(Component):
346
345
  Returns:
347
346
  list[str]: List with a single path to the DEM file
348
347
  """
349
-
350
- # colored_dem_path = self._dem_path.replace(".png", "_colored.png")
351
348
  colored_dem_path = os.path.join(self.previews_directory, "dem_colored.png")
352
349
 
353
350
  self.logger.debug("Creating colored preview of DEM data in %s.", colored_dem_path)
@@ -424,14 +421,18 @@ class DEM(Component):
424
421
 
425
422
  scaling_factor = self._get_scaling_factor(max_dev)
426
423
  adjusted_max_height = int(65535 * scaling_factor)
427
- self.logger.debug(
428
- f"Maximum deviation: {max_dev}. Scaling factor: {scaling_factor}. "
429
- f"Adjusted max height: {adjusted_max_height}."
424
+ self.logger.info(
425
+ "Maximum deviation: %s. Scaling factor: %s. Adjusted max height: %s.",
426
+ max_dev,
427
+ scaling_factor,
428
+ adjusted_max_height,
430
429
  )
431
430
  normalized_data = (
432
431
  (data - data.min()) / (data.max() - data.min()) * adjusted_max_height
433
432
  ).astype("uint16")
434
433
  self.logger.debug(
435
- f"DEM data was normalized to {normalized_data.min()} - {normalized_data.max()}."
434
+ "DEM data was normalized to %s - %s.",
435
+ normalized_data.min(),
436
+ normalized_data.max(),
436
437
  )
437
438
  return normalized_data
@@ -38,7 +38,8 @@ class Game:
38
38
  _texture_schema: str | None = None
39
39
  _grle_schema: str | None = None
40
40
 
41
- components = [Config, Texture, GRLE, DEM, I3d, Background]
41
+ # Order matters! Some components depend on others.
42
+ components = [Texture, I3d, DEM, Config, GRLE, Background]
42
43
 
43
44
  def __init__(self, map_template_path: str | None = None):
44
45
  if map_template_path:
@@ -61,7 +61,7 @@ class GRLE(Component):
61
61
  info_layer_data = np.zeros((height, width), dtype=data_type)
62
62
  print(info_layer_data.shape)
63
63
  cv2.imwrite(file_path, info_layer_data) # pylint: disable=no-member
64
- self.logger.info("InfoLayer PNG file %s created.", file_path)
64
+ self.logger.debug("InfoLayer PNG file %s created.", file_path)
65
65
  else:
66
66
  self.logger.warning("Invalid InfoLayer schema: %s.", info_layer)
67
67