maps4fs 1.5.2__py3-none-any.whl → 1.5.3__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/component.py +10 -0
- maps4fs/generator/game.py +2 -1
- maps4fs/generator/map.py +16 -0
- maps4fs/generator/satellite.py +92 -0
- {maps4fs-1.5.2.dist-info → maps4fs-1.5.3.dist-info}/METADATA +10 -2
- {maps4fs-1.5.2.dist-info → maps4fs-1.5.3.dist-info}/RECORD +9 -8
- {maps4fs-1.5.2.dist-info → maps4fs-1.5.3.dist-info}/LICENSE.md +0 -0
- {maps4fs-1.5.2.dist-info → maps4fs-1.5.3.dist-info}/WHEEL +0 -0
- {maps4fs-1.5.2.dist-info → maps4fs-1.5.3.dist-info}/top_level.txt +0 -0
maps4fs/generator/component.py
CHANGED
@@ -68,6 +68,7 @@ class Component:
|
|
68
68
|
os.makedirs(self.previews_directory, exist_ok=True)
|
69
69
|
os.makedirs(self.scripts_directory, exist_ok=True)
|
70
70
|
os.makedirs(self.info_layers_directory, exist_ok=True)
|
71
|
+
os.makedirs(self.satellite_directory, exist_ok=True)
|
71
72
|
|
72
73
|
self.save_bbox()
|
73
74
|
self.preprocess()
|
@@ -123,6 +124,15 @@ class Component:
|
|
123
124
|
"""
|
124
125
|
return os.path.join(self.map_directory, "scripts")
|
125
126
|
|
127
|
+
@property
|
128
|
+
def satellite_directory(self) -> str:
|
129
|
+
"""The directory where the satellite images are stored.
|
130
|
+
|
131
|
+
Returns:
|
132
|
+
str: The directory where the satellite images are stored.
|
133
|
+
"""
|
134
|
+
return os.path.join(self.map_directory, "satellite")
|
135
|
+
|
126
136
|
@property
|
127
137
|
def generation_info_path(self) -> str:
|
128
138
|
"""The path to the generation info JSON file.
|
maps4fs/generator/game.py
CHANGED
@@ -10,6 +10,7 @@ from maps4fs.generator.background import Background
|
|
10
10
|
from maps4fs.generator.config import Config
|
11
11
|
from maps4fs.generator.grle import GRLE
|
12
12
|
from maps4fs.generator.i3d import I3d
|
13
|
+
from maps4fs.generator.satellite import Satellite
|
13
14
|
from maps4fs.generator.texture import Texture
|
14
15
|
|
15
16
|
working_directory = os.getcwd()
|
@@ -39,7 +40,7 @@ class Game:
|
|
39
40
|
_tree_schema: str | None = None
|
40
41
|
|
41
42
|
# Order matters! Some components depend on others.
|
42
|
-
components = [Texture, GRLE, Background, I3d, Config]
|
43
|
+
components = [Texture, GRLE, Background, I3d, Config, Satellite]
|
43
44
|
|
44
45
|
def __init__(self, map_template_path: str | None = None):
|
45
46
|
if map_template_path:
|
maps4fs/generator/map.py
CHANGED
@@ -146,6 +146,19 @@ class SplineSettings(SettingsModel):
|
|
146
146
|
spline_density: int = 2
|
147
147
|
|
148
148
|
|
149
|
+
class SatelliteSettings(SettingsModel):
|
150
|
+
"""Represents the advanced settings for satellite component.
|
151
|
+
|
152
|
+
Attributes:
|
153
|
+
download_images (bool): download satellite images.
|
154
|
+
margin (int): margin around the map.
|
155
|
+
"""
|
156
|
+
|
157
|
+
download_images: bool = False
|
158
|
+
satellite_margin: int = 100
|
159
|
+
zoom_level: int = 14
|
160
|
+
|
161
|
+
|
149
162
|
# pylint: disable=R0913, R0902, R0914
|
150
163
|
class Map:
|
151
164
|
"""Class used to generate map using all components.
|
@@ -173,6 +186,7 @@ class Map:
|
|
173
186
|
i3d_settings: I3DSettings = I3DSettings(),
|
174
187
|
texture_settings: TextureSettings = TextureSettings(),
|
175
188
|
spline_settings: SplineSettings = SplineSettings(),
|
189
|
+
satellite_settings: SatelliteSettings = SatelliteSettings(),
|
176
190
|
**kwargs,
|
177
191
|
):
|
178
192
|
if not logger:
|
@@ -217,6 +231,7 @@ class Map:
|
|
217
231
|
self.logger.info("Texture settings: %s", texture_settings)
|
218
232
|
self.spline_settings = spline_settings
|
219
233
|
self.logger.info("Spline settings: %s", spline_settings)
|
234
|
+
self.satellite_settings = satellite_settings
|
220
235
|
|
221
236
|
os.makedirs(self.map_directory, exist_ok=True)
|
222
237
|
self.logger.debug("Map directory created: %s", self.map_directory)
|
@@ -228,6 +243,7 @@ class Map:
|
|
228
243
|
i3d_settings,
|
229
244
|
texture_settings,
|
230
245
|
spline_settings,
|
246
|
+
satellite_settings,
|
231
247
|
]
|
232
248
|
|
233
249
|
settings_json = {}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
"""This module contains the Satellite class for the maps4fs package to download satellite images
|
2
|
+
for the map."""
|
3
|
+
|
4
|
+
import os
|
5
|
+
|
6
|
+
import cv2
|
7
|
+
from pygmdl import save_image # type: ignore
|
8
|
+
|
9
|
+
from maps4fs.generator.background import DEFAULT_DISTANCE
|
10
|
+
from maps4fs.generator.component import Component
|
11
|
+
from maps4fs.generator.texture import PREVIEW_MAXIMUM_SIZE
|
12
|
+
|
13
|
+
|
14
|
+
# pylint: disable=W0223
|
15
|
+
class Satellite(Component):
|
16
|
+
"""Component for to download satellite images for the map.
|
17
|
+
|
18
|
+
Arguments:
|
19
|
+
game (Game): The game instance for which the map is generated.
|
20
|
+
coordinates (tuple[float, float]): The latitude and longitude of the center of the map.
|
21
|
+
map_size (int): The size of the map in pixels.
|
22
|
+
map_rotated_size (int): The size of the map in pixels after rotation.
|
23
|
+
rotation (int): The rotation angle of the map.
|
24
|
+
map_directory (str): The directory where the map files are stored.
|
25
|
+
logger (Any, optional): The logger to use. Must have at least three basic methods: debug,
|
26
|
+
info, warning. If not provided, default logging will be used.
|
27
|
+
"""
|
28
|
+
|
29
|
+
def preprocess(self) -> None:
|
30
|
+
"""This component does not require any preprocessing."""
|
31
|
+
return
|
32
|
+
|
33
|
+
def process(self) -> None:
|
34
|
+
"""Downloads the satellite images for the map."""
|
35
|
+
self.image_paths = [] # pylint: disable=W0201
|
36
|
+
if not self.map.satellite_settings.download_images:
|
37
|
+
self.logger.info("Satellite images download is disabled.")
|
38
|
+
return
|
39
|
+
|
40
|
+
margin = self.map.satellite_settings.satellite_margin
|
41
|
+
overview_size = (self.map_size + margin) * 2
|
42
|
+
overwiew_path = os.path.join(self.satellite_directory, "satellite_overview.png")
|
43
|
+
|
44
|
+
background_size = self.map_size + (DEFAULT_DISTANCE + margin) * 2
|
45
|
+
background_path = os.path.join(self.satellite_directory, "satellite_background.png")
|
46
|
+
|
47
|
+
sizes = [overview_size, background_size]
|
48
|
+
self.image_paths = [overwiew_path, background_path] # pylint: disable=W0201
|
49
|
+
|
50
|
+
for size, path in zip(sizes, self.image_paths):
|
51
|
+
try:
|
52
|
+
lat, lon = self.coordinates
|
53
|
+
zoom = self.map.satellite_settings.zoom_level
|
54
|
+
save_image(
|
55
|
+
lat,
|
56
|
+
lon,
|
57
|
+
size,
|
58
|
+
output_path=path,
|
59
|
+
rotation=self.rotation,
|
60
|
+
zoom=zoom,
|
61
|
+
from_center=True,
|
62
|
+
logger=self.logger,
|
63
|
+
)
|
64
|
+
except Exception as e: # pylint: disable=W0718
|
65
|
+
self.logger.error(f"Failed to download satellite image: {e}")
|
66
|
+
continue
|
67
|
+
|
68
|
+
# pylint: disable=no-member
|
69
|
+
def previews(self) -> list[str]:
|
70
|
+
"""Returns the paths to the preview images.
|
71
|
+
|
72
|
+
Returns:
|
73
|
+
list[str]: List of paths to the preview images.
|
74
|
+
"""
|
75
|
+
previews = []
|
76
|
+
for image_path in self.image_paths:
|
77
|
+
if not os.path.isfile(image_path):
|
78
|
+
self.logger.warning(f"File {image_path} does not exist.")
|
79
|
+
continue
|
80
|
+
image = cv2.imread(image_path)
|
81
|
+
if image is None:
|
82
|
+
self.logger.warning(f"Failed to read image from {image_path}")
|
83
|
+
continue
|
84
|
+
|
85
|
+
if image.shape[0] > PREVIEW_MAXIMUM_SIZE or image.shape[1] > PREVIEW_MAXIMUM_SIZE:
|
86
|
+
image = cv2.resize(image, (PREVIEW_MAXIMUM_SIZE, PREVIEW_MAXIMUM_SIZE))
|
87
|
+
|
88
|
+
preview_path = os.path.join(self.previews_directory, os.path.basename(image_path))
|
89
|
+
cv2.imwrite(preview_path, image)
|
90
|
+
previews.append(preview_path)
|
91
|
+
|
92
|
+
return previews
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: maps4fs
|
3
|
-
Version: 1.5.
|
3
|
+
Version: 1.5.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
|
@@ -75,6 +75,7 @@ Requires-Dist: pydantic
|
|
75
75
|
🌲 Automatically generates forests 🆕<br>
|
76
76
|
🌊 Automatically generates water planes 🆕<br>
|
77
77
|
📈 Automatically generates splines 🆕<br>
|
78
|
+
🛰️ Automatically downloads high resolution satellite images 🆕<br>
|
78
79
|
🌍 Based on real-world data from OpenStreetMap<br>
|
79
80
|
🗺️ Supports [custom OSM maps](/docs/custom_osm.md)<br>
|
80
81
|
🏞️ Generates height map using SRTM dataset<br>
|
@@ -511,10 +512,16 @@ You can also apply some advanced settings to the map generation process. Note th
|
|
511
512
|
|
512
513
|
- Skip drains - if enabled, the tool will not generate the drains and ditches on the map. By default, it's set to False. Use this if you don't need the drains on the map.
|
513
514
|
|
514
|
-
|
515
|
+
### Splines Advanced settings
|
515
516
|
|
516
517
|
- Splines density - number of points, which will be added (interpolate) between each pair of existing points. The higher the value, the denser the spline will be. It can smooth the splines, but high values can in opposite make the splines look unnatural.
|
517
518
|
|
519
|
+
### Satellite Advanced settings
|
520
|
+
|
521
|
+
- Download images - if enabled, the tool will download the satellite images for the background terrain and the overview image. If you already have the images, you can turn it off.
|
522
|
+
- Satellite margin - the margin around the map in meters. It's useful when you want to have some space around the map on the satellite images. By default, it's set to 100.
|
523
|
+
- Zoom level - the zoom level of the satellite images. The higher the value, the more detailed the images will be. By default, it's set to 14 and this option is disabled on a public version of the app.
|
524
|
+
|
518
525
|
## Expert Settings
|
519
526
|
The tool also supports the expert settings. Do not use them until you read the documentation and understand what they do. Here's the list of the expert settings:
|
520
527
|
|
@@ -555,3 +562,4 @@ But also, I want to thank the people who helped me with the project in some way,
|
|
555
562
|
- [Tox3](https://github.com/Tox3) - for the manual tests of the app.
|
556
563
|
- [Lucandia](https://github.com/Lucandia) - for the awesome StreamLit [widget to preview STL files](https://github.com/Lucandia/streamlit_stl).
|
557
564
|
- [H4rdB4se](https://github.com/H4rdB4se) - for investigating the issue with custom OSM files and finding a proper way to work with the files in JOSM.
|
565
|
+
- [kbrandwijk](https://github.com/kbrandwijk) - for providing [awesome tool](https://github.com/Paint-a-Farm/satmap_downloader) to download the satellite images from the Google Maps and giving a permission to modify it and create a Python Package.
|
@@ -2,20 +2,21 @@ maps4fs/__init__.py,sha256=LMzzORK3Q3OjXmmRJ03CpS2SMP6zTwKNnUUei3P7s40,300
|
|
2
2
|
maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
|
3
3
|
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
4
|
maps4fs/generator/background.py,sha256=ySABP9HLji8R0aXi1BwjUQtP2uDqZPkrlmugowa9Gkk,22836
|
5
|
-
maps4fs/generator/component.py,sha256=
|
5
|
+
maps4fs/generator/component.py,sha256=RtXruvT4Fxfr7_xo9Bi-i3IIWcPd5QQOSpYJ_cNC49o,20408
|
6
6
|
maps4fs/generator/config.py,sha256=0QmK052B8bxyHVhg3jzCORLfOBMMmqVfhhbqXKf6OMk,4383
|
7
7
|
maps4fs/generator/dem.py,sha256=MZf3ZjawJ977TxqB1q9nNpvPZUNwfmm2EaJDtVU-eCU,15939
|
8
|
-
maps4fs/generator/game.py,sha256=
|
8
|
+
maps4fs/generator/game.py,sha256=QHgVnyGYvEnfwGZ84-u-dpbCRr3UeVVqBbrwr5WG8dE,7992
|
9
9
|
maps4fs/generator/grle.py,sha256=u8ZwSs313PIOkH_0B_O2tVTaZ-eYNkc30eKGtBxWzTM,17846
|
10
10
|
maps4fs/generator/i3d.py,sha256=qeZYqfuhbhRPlSAuQHXaq6RmIO7314oMN68Ivebp1YQ,24786
|
11
|
-
maps4fs/generator/map.py,sha256
|
11
|
+
maps4fs/generator/map.py,sha256=-3oqAKXVD_lMkJgDrZEun9kRnvOpjoTPcd82kRajmls,13296
|
12
12
|
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
13
|
+
maps4fs/generator/satellite.py,sha256=Qnb6XxmXKnHdHKVMb9mJ3vDGtGkDHCOv_81hrrXdx3k,3660
|
13
14
|
maps4fs/generator/texture.py,sha256=sErusfv1AqQfP-veMrZ921Tz8DnGEhfB4ucggMmKrD4,31231
|
14
15
|
maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
15
16
|
maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
|
16
17
|
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
17
|
-
maps4fs-1.5.
|
18
|
-
maps4fs-1.5.
|
19
|
-
maps4fs-1.5.
|
20
|
-
maps4fs-1.5.
|
21
|
-
maps4fs-1.5.
|
18
|
+
maps4fs-1.5.3.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
19
|
+
maps4fs-1.5.3.dist-info/METADATA,sha256=AQDfDzRNJVcvRq68ntu5n3XuB6gWZWV2O9-AuSzntBQ,35937
|
20
|
+
maps4fs-1.5.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
21
|
+
maps4fs-1.5.3.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
22
|
+
maps4fs-1.5.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|