maps4fs 1.8.173__py3-none-any.whl → 1.8.175__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.
@@ -73,12 +73,8 @@ class Component:
73
73
  self.preprocess()
74
74
 
75
75
  def preprocess(self) -> None:
76
- """Prepares the component for processing. Must be implemented in the child class.
77
-
78
- Raises:
79
- NotImplementedError: If the method is not implemented in the child class.
80
- """
81
- raise NotImplementedError
76
+ """Prepares the component for processing. Must be implemented in the child class."""
77
+ return
82
78
 
83
79
  def process(self) -> None:
84
80
  """Launches the component processing. Must be implemented in the child class.
@@ -1,9 +1,12 @@
1
1
  """Base class for all components that primarily used to work with images."""
2
2
 
3
+ import os
4
+
3
5
  import cv2
4
6
  import numpy as np
5
7
 
6
8
  from maps4fs.generator.component.base.component import Component
9
+ from maps4fs.generator.settings import Parameters
7
10
 
8
11
 
9
12
  class ImageComponent(Component):
@@ -88,3 +91,28 @@ class ImageComponent(Component):
88
91
 
89
92
  image[mask] = image[mask] - subtract_by
90
93
  return image
94
+
95
+ @staticmethod
96
+ def resize_to_preview(image_path: str, save_path: str) -> None:
97
+ """Resizes an image to the preview size.
98
+
99
+ Arguments:
100
+ image_path (str): The path to the image.
101
+ save_path (str): The path to save the resized image.
102
+ """
103
+ if not os.path.isfile(image_path):
104
+ return
105
+
106
+ image = cv2.imread(image_path)
107
+ if image is None:
108
+ return
109
+
110
+ if (
111
+ image.shape[0] > Parameters.PREVIEW_MAXIMUM_SIZE
112
+ or image.shape[1] > Parameters.PREVIEW_MAXIMUM_SIZE
113
+ ):
114
+ image = cv2.resize(
115
+ image, (Parameters.PREVIEW_MAXIMUM_SIZE, Parameters.PREVIEW_MAXIMUM_SIZE)
116
+ )
117
+
118
+ cv2.imwrite(save_path, image)
@@ -0,0 +1,135 @@
1
+ """This module contains the Satellite class for the maps4fs package to download satellite images
2
+ for the map."""
3
+
4
+ import os
5
+ import shutil
6
+ from typing import NamedTuple
7
+
8
+ from pygmdl import save_image
9
+
10
+ from maps4fs.generator.component.base.component_image import ImageComponent
11
+ from maps4fs.generator.settings import Parameters
12
+
13
+
14
+ class SatelliteImage(NamedTuple):
15
+ """Named tuple for the satellite image download task.
16
+
17
+ Attributes:
18
+ lat (float): The latitude of the center of the map.
19
+ lon (float): The longitude of the center of the map.
20
+ size (int): The size of the map in pixels.
21
+ output_path (str): The path where to save the image.
22
+ rotation (int): The rotation angle of the map.
23
+ zoom (int): The zoom level of the map.
24
+ copy_from (str | None): If saving should be skipped and the image should be copied from
25
+ another file.
26
+ """
27
+
28
+ lat: float
29
+ lon: float
30
+ size: int
31
+ output_path: str
32
+ rotation: int
33
+ zoom: int
34
+ copy_from: str | None = None
35
+
36
+
37
+ class Satellite(ImageComponent):
38
+ """Component for to download satellite images for the map.
39
+
40
+ Arguments:
41
+ game (Game): The game instance for which the map is generated.
42
+ coordinates (tuple[float, float]): The latitude and longitude of the center of the map.
43
+ map_size (int): The size of the map in pixels.
44
+ map_rotated_size (int): The size of the map in pixels after rotation.
45
+ rotation (int): The rotation angle of the map.
46
+ map_directory (str): The directory where the map files are stored.
47
+ logger (Any, optional): The logger to use. Must have at least three basic methods: debug,
48
+ info, warning. If not provided, default logging will be used.
49
+ """
50
+
51
+ def process(self) -> None:
52
+ """Downloads the satellite images for the map."""
53
+ self.image_paths = []
54
+ if not self.map.satellite_settings.download_images:
55
+ self.logger.debug("Satellite images download is disabled.")
56
+ return
57
+
58
+ margin = self.map.satellite_settings.satellite_margin
59
+ overview_size = (self.map_size + margin) * 2
60
+ overwiew_path = os.path.join(self.satellite_directory, "satellite_overview.png")
61
+
62
+ background_size = self.map_size + (Parameters.BACKGROUND_DISTANCE + margin) * 2
63
+ background_path = os.path.join(self.satellite_directory, "satellite_background.png")
64
+
65
+ sizes = [overview_size, background_size]
66
+ self.image_paths = [overwiew_path, background_path]
67
+
68
+ tasks = self.get_tasks(sizes, self.image_paths)
69
+
70
+ for task in tasks:
71
+ try:
72
+ if task.copy_from and os.path.isfile(task.copy_from):
73
+ shutil.copy(task.copy_from, task.output_path)
74
+ continue
75
+
76
+ save_image(
77
+ task.lat,
78
+ task.lon,
79
+ task.size,
80
+ output_path=task.output_path,
81
+ rotation=task.rotation,
82
+ zoom=task.zoom,
83
+ from_center=True,
84
+ logger=self.logger,
85
+ )
86
+
87
+ except Exception as e:
88
+ self.logger.error(f"Failed to download satellite image: {e}")
89
+ continue
90
+
91
+ def get_tasks(self, sizes: list[int], save_paths: list[str]) -> list[SatelliteImage]:
92
+ """Prepares the tasks for downloading the satellite images.
93
+
94
+ Arguments:
95
+ sizes (list[int]): The sizes of the images to download.
96
+ save_paths (list[str]): The paths where to save the images.
97
+
98
+ Returns:
99
+ list[SatelliteImage]: The list of tasks for downloading the satellite images.
100
+ """
101
+ tasks: list[SatelliteImage] = []
102
+
103
+ for size, save_path in zip(sizes, save_paths):
104
+ # Check if in tasks there's already a task with the same size.
105
+ existing_task = next((t for t in tasks if t.size == size), None)
106
+ copy_from = existing_task.output_path if existing_task else None
107
+
108
+ lat, lon = self.coordinates
109
+ tasks.append(
110
+ SatelliteImage(
111
+ lat=lat,
112
+ lon=lon,
113
+ size=size,
114
+ output_path=save_path,
115
+ rotation=self.rotation,
116
+ zoom=self.map.satellite_settings.zoom_level,
117
+ copy_from=copy_from,
118
+ )
119
+ )
120
+
121
+ return tasks
122
+
123
+ def previews(self) -> list[str]:
124
+ """Returns the paths to the preview images.
125
+
126
+ Returns:
127
+ list[str]: List of paths to the preview images.
128
+ """
129
+ previews = []
130
+ for image_path in self.image_paths:
131
+ preview_path = os.path.join(self.previews_directory, os.path.basename(image_path))
132
+ self.resize_to_preview(image_path, preview_path)
133
+ previews.append(preview_path)
134
+
135
+ return previews
maps4fs/generator/game.py CHANGED
@@ -10,7 +10,7 @@ from maps4fs.generator.component.background import Background
10
10
  from maps4fs.generator.component.config import Config
11
11
  from maps4fs.generator.component.grle import GRLE
12
12
  from maps4fs.generator.component.i3d import I3d
13
- from maps4fs.generator.satellite import Satellite
13
+ from maps4fs.generator.component.satellite import Satellite
14
14
  from maps4fs.generator.texture import Texture
15
15
 
16
16
  working_directory = os.getcwd()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: maps4fs
3
- Version: 1.8.173
3
+ Version: 1.8.175
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
@@ -2,10 +2,9 @@ maps4fs/__init__.py,sha256=iq4GcHoQ-by-BK6CzDOfVcdDww6osyi9Wv6pKXub68U,1307
2
2
  maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
3
3
  maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
4
4
  maps4fs/generator/dem.py,sha256=oLN02bWNax73HzFsseRBOV47Azl_1L7qdrzuxHh4i_c,11886
5
- maps4fs/generator/game.py,sha256=YwtdzqwcBJm1FHtc1ehDd3WbfTTW_gBvxK-pzfU48zs,11015
5
+ maps4fs/generator/game.py,sha256=FFAyckuTW6Ix5aRACXOj2eiA72xd3OMCcOARrMhS164,11025
6
6
  maps4fs/generator/map.py,sha256=c5GMhr5iTRdXvTXoBKyVYa2V1tocR3ZCc7D_hpU21k8,11523
7
7
  maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
8
- maps4fs/generator/satellite.py,sha256=t33EfaxWTCjcKYnqoppSlFdQQSekiBe7UFmLgTVhFQI,3650
9
8
  maps4fs/generator/settings.py,sha256=cFlN-gK8QcySqyPtcGm-2fLnxQnlmC3Y9kQufJxwI3Y,6270
10
9
  maps4fs/generator/texture.py,sha256=_IfqIuxH4934VJXKtdABHa6ToPWk3T0xknvlu-rZ5Uc,36570
11
10
  maps4fs/generator/component/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
@@ -13,9 +12,10 @@ maps4fs/generator/component/background.py,sha256=cBBp-ULrJzuNG9wfE_MaxzAn_mR24ne
13
12
  maps4fs/generator/component/config.py,sha256=RitKgFDZPzjA1fi8GcEi1na75qqaueUvpcITHjBvCXc,3674
14
13
  maps4fs/generator/component/grle.py,sha256=aKMjVJNuKHJJ2gsXaH00bz10kWaIbbZXU_JbP-ZAGw4,18990
15
14
  maps4fs/generator/component/i3d.py,sha256=3x38yL-kSJ8ylBwICBb6wPYzRSky4gVj8XCk2jzYSeo,19861
15
+ maps4fs/generator/component/satellite.py,sha256=oZBHjP_QY0ik1-Vk7JqMS__zIG8ffw2voeozB7-HUQc,4946
16
16
  maps4fs/generator/component/base/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
17
- maps4fs/generator/component/base/component.py,sha256=U3XJae0GUvHN08psv2j24Y4PBAAytSkSK3AmD-VjjXE,21404
18
- maps4fs/generator/component/base/component_image.py,sha256=vuiiJqsrKZgYsnK8Qa5yL2Pejqa6nJSTtXNAcBPL29c,3099
17
+ maps4fs/generator/component/base/component.py,sha256=apGuQ7TcwqL0neJZiciNLGO22wZwYyqoDZM7aI1RHw8,21273
18
+ maps4fs/generator/component/base/component_image.py,sha256=fFgY6k2CbLIg3HS7KeiHi9iFQPJXCAxmBueYh2ExlFU,3918
19
19
  maps4fs/generator/component/base/component_mesh.py,sha256=jtsEQZkqiCkycYpueq1M1eqgxdShL_bHaJT6Upu8PLI,8412
20
20
  maps4fs/generator/component/base/component_xml.py,sha256=6OO1dKoceO1ACk7-k1oGtnkfNud8ZN3u3ZNjdNMpTqw,3967
21
21
  maps4fs/generator/dtm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -42,8 +42,8 @@ maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,4
42
42
  maps4fs/toolbox/background.py,sha256=RclEqxEWLbMxuEkkegQP8jybzugwQ1_R3rdfDe0s21U,2104
43
43
  maps4fs/toolbox/custom_osm.py,sha256=X6ZlPqiOhNjkmdD_qVroIfdOl9Rb90cDwVSLDVYgx80,1892
44
44
  maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
45
- maps4fs-1.8.173.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
46
- maps4fs-1.8.173.dist-info/METADATA,sha256=juPm5cwfn3XLlaUemJjP43yHQbW-9NYEljrHscMlGN4,42937
47
- maps4fs-1.8.173.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
48
- maps4fs-1.8.173.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
49
- maps4fs-1.8.173.dist-info/RECORD,,
45
+ maps4fs-1.8.175.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
46
+ maps4fs-1.8.175.dist-info/METADATA,sha256=sJC26EV7F8zHVh9EUwiFRvKN9BlrJuLYk5-QwfySD5c,42937
47
+ maps4fs-1.8.175.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
48
+ maps4fs-1.8.175.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
49
+ maps4fs-1.8.175.dist-info/RECORD,,
@@ -1,91 +0,0 @@
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.component.base.component import Component
10
- from maps4fs.generator.settings import Parameters
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.debug("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 + (Parameters.BACKGROUND_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
- def previews(self) -> list[str]:
69
- """Returns the paths to the preview images.
70
-
71
- Returns:
72
- list[str]: List of paths to the preview images.
73
- """
74
- previews = []
75
- for image_path in self.image_paths:
76
- if not os.path.isfile(image_path):
77
- self.logger.warning(f"File {image_path} does not exist.")
78
- continue
79
- image = cv2.imread(image_path)
80
- if image is None:
81
- self.logger.warning(f"Failed to read image from {image_path}")
82
- continue
83
-
84
- if image.shape[0] > PREVIEW_MAXIMUM_SIZE or image.shape[1] > PREVIEW_MAXIMUM_SIZE:
85
- image = cv2.resize(image, (PREVIEW_MAXIMUM_SIZE, PREVIEW_MAXIMUM_SIZE))
86
-
87
- preview_path = os.path.join(self.previews_directory, os.path.basename(image_path))
88
- cv2.imwrite(preview_path, image)
89
- previews.append(preview_path)
90
-
91
- return previews