maps4fs 1.6.81__py3-none-any.whl → 1.7.0__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.

Potentially problematic release.


This version of maps4fs might be problematic. Click here for more details.

maps4fs/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # pylint: disable=missing-module-docstring
2
2
  from maps4fs.generator.dtm.dtm import DTMProvider
3
3
  from maps4fs.generator.dtm.srtm import SRTM30Provider
4
- from maps4fs.generator.dtm.usgs import USGS1mProvider
4
+ from maps4fs.generator.dtm.usgs import USGSProvider
5
5
  from maps4fs.generator.game import Game
6
6
  from maps4fs.generator.map import Map
7
7
  from maps4fs.generator.settings import (
@@ -188,8 +188,7 @@ class Component:
188
188
  self,
189
189
  coordinates: tuple[float, float] | None = None,
190
190
  distance: int | None = None,
191
- project_utm: bool = False,
192
- ) -> tuple[int, int, int, int]:
191
+ ) -> tuple[float, float, float, float]:
193
192
  """Calculates the bounding box of the map from the coordinates and the height and
194
193
  width of the map.
195
194
  If coordinates and distance are not provided, the instance variables are used.
@@ -199,24 +198,23 @@ class Component:
199
198
  of the map. Defaults to None.
200
199
  distance (int, optional): The distance from the center of the map to the edge of the
201
200
  map in all directions. Defaults to None.
202
- project_utm (bool, optional): Whether to project the bounding box to UTM.
203
201
 
204
202
  Returns:
205
- tuple[int, int, int, int]: The bounding box of the map.
203
+ tuple[float, float, float, float]: The bounding box of the map.
206
204
  """
207
205
  coordinates = coordinates or self.coordinates
208
206
  distance = distance or int(self.map_rotated_size / 2)
209
207
 
210
208
  west, south, east, north = ox.utils_geo.bbox_from_point( # type: ignore
211
- coordinates, dist=distance, project_utm=project_utm
209
+ coordinates,
210
+ dist=distance,
212
211
  )
213
212
 
214
213
  bbox = north, south, east, west
215
214
  self.logger.debug(
216
- "Calculated bounding box for component: %s: %s, project_utm: %s, distance: %s",
215
+ "Calculated bounding box for component: %s: %s, distance: %s",
217
216
  self.__class__.__name__,
218
217
  bbox,
219
- project_utm,
220
218
  distance,
221
219
  )
222
220
  return bbox
@@ -225,7 +223,7 @@ class Component:
225
223
  """Saves the bounding box of the map to the component instance from the coordinates and the
226
224
  height and width of the map.
227
225
  """
228
- self.bbox = self.get_bbox(project_utm=False)
226
+ self.bbox = self.get_bbox()
229
227
  self.logger.debug("Saved bounding box: %s", self.bbox)
230
228
 
231
229
  @property
@@ -544,17 +542,10 @@ class Component:
544
542
  """
545
543
 
546
544
  scaling_factor = 1 / self.map.dem_settings.multiplier
547
- self.logger.debug("Z scaling factor including DEM multiplier: %s", scaling_factor)
548
545
 
549
546
  if self.map.shared_settings.height_scale_multiplier:
550
547
  scaling_factor *= self.map.shared_settings.height_scale_multiplier
551
- self.logger.debug(
552
- "Z scaling factor including height scale multiplier: %s", scaling_factor
553
- )
554
548
  if self.map.shared_settings.mesh_z_scaling_factor:
555
549
  scaling_factor *= 1 / self.map.shared_settings.mesh_z_scaling_factor
556
- self.logger.debug(
557
- "Z scaling factor including mesh z scaling factor: %s", scaling_factor
558
- )
559
550
 
560
551
  return scaling_factor
@@ -4,6 +4,7 @@ and specific settings for downloading and processing the data."""
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ from abc import ABC, abstractmethod
7
8
  import os
8
9
  from typing import TYPE_CHECKING, Type
9
10
 
@@ -23,19 +24,22 @@ class DTMProviderSettings(BaseModel):
23
24
  """Base class for DTM provider settings models."""
24
25
 
25
26
 
26
- class DTMProvider:
27
+ # pylint: disable=too-many-public-methods
28
+ class DTMProvider(ABC):
27
29
  """Base class for DTM providers."""
28
30
 
29
31
  _code: str | None = None
30
32
  _name: str | None = None
31
33
  _region: str | None = None
32
34
  _icon: str | None = None
33
- _resolution: float | None = None
35
+ _resolution: float | str | None = None
34
36
 
35
37
  _url: str | None = None
36
38
 
37
39
  _author: str | None = None
40
+ _contributors: str | None = None
38
41
  _is_community: bool = False
42
+ _is_base: bool = False
39
43
  _settings: Type[DTMProviderSettings] | None = None
40
44
 
41
45
  _instructions: str | None = None
@@ -120,6 +124,24 @@ class DTMProvider:
120
124
  """
121
125
  return cls._author
122
126
 
127
+ @classmethod
128
+ def contributors(cls) -> str | None:
129
+ """Contributors of the provider.
130
+
131
+ Returns:
132
+ str: Contributors of the provider.
133
+ """
134
+ return cls._contributors
135
+
136
+ @classmethod
137
+ def is_base(cls) -> bool:
138
+ """Is the provider a base provider.
139
+
140
+ Returns:
141
+ bool: True if the provider is a base provider, False otherwise.
142
+ """
143
+ return cls._is_base
144
+
123
145
  @classmethod
124
146
  def is_community(cls) -> bool:
125
147
  """Is the provider a community-driven project.
@@ -190,7 +212,8 @@ class DTMProvider:
190
212
  """
191
213
  providers = {}
192
214
  for provider in cls.__subclasses__():
193
- providers[provider._code] = provider.description() # pylint: disable=W0212
215
+ if not provider.is_base():
216
+ providers[provider._code] = provider.description() # pylint: disable=W0212
194
217
  return providers # type: ignore
195
218
 
196
219
  def download_tile(self, output_path: str, **kwargs) -> bool:
@@ -235,6 +258,7 @@ class DTMProvider:
235
258
  """
236
259
  raise NotImplementedError
237
260
 
261
+ @abstractmethod
238
262
  def get_numpy(self) -> np.ndarray:
239
263
  """Get numpy array of the tile.
240
264
  Resulting array must be 16 bit (signed or unsigned) integer and it should be already
@@ -1,37 +1,47 @@
1
- """This module contains provider of USGS 1m data."""
1
+ """This module contains provider of USGS data."""
2
2
 
3
3
  import os
4
4
  from datetime import datetime
5
+ from zipfile import ZipFile
5
6
 
6
7
  import numpy as np
7
- import rasterio # type: ignore
8
+ import rasterio
8
9
  import requests
9
- from rasterio._warp import Resampling # type: ignore # pylint: disable=E0611
10
- from rasterio.merge import merge # type: ignore
11
- from rasterio.warp import calculate_default_transform, reproject # type: ignore
12
- from rasterio.windows import from_bounds # type: ignore
10
+ from rasterio.enums import Resampling
11
+ from rasterio.merge import merge
12
+ from rasterio.warp import calculate_default_transform, reproject
13
+ from rasterio.windows import from_bounds
13
14
 
14
15
  from maps4fs.generator.dtm.dtm import DTMProvider, DTMProviderSettings
15
16
 
16
17
 
17
- class USGS1mProviderSettings(DTMProviderSettings):
18
- """Settings for the USGS 1m provider."""
18
+ class USGSProviderSettings(DTMProviderSettings):
19
+ """Settings for the USGS provider."""
19
20
 
20
21
  max_local_elevation: int = 255
22
+ dataset: tuple | str = (
23
+ 'Digital Elevation Model (DEM) 1 meter',
24
+ 'Alaska IFSAR 5 meter DEM',
25
+ 'National Elevation Dataset (NED) 1/9 arc-second',
26
+ 'National Elevation Dataset (NED) 1/3 arc-second',
27
+ 'National Elevation Dataset (NED) 1 arc-second',
28
+ 'National Elevation Dataset (NED) Alaska 2 arc-second',
29
+ 'Original Product Resolution (OPR) Digital Elevation Model (DEM)',
30
+ )
21
31
 
22
32
 
23
- # pylint: disable=W0223
24
- class USGS1mProvider(DTMProvider):
33
+ class USGSProvider(DTMProvider):
25
34
  """Provider of USGS."""
26
35
 
27
- _code = "USGS1m"
28
- _name = "USGS 1m"
36
+ _code = "USGS"
37
+ _name = "USGS"
29
38
  _region = "USA"
30
39
  _icon = "🇺🇸"
31
- _resolution = 1
40
+ _resolution = 'variable'
32
41
  _data: np.ndarray | None = None
33
- _settings = USGS1mProviderSettings
42
+ _settings = USGSProviderSettings
34
43
  _author = "[ZenJakey](https://github.com/ZenJakey)"
44
+ _contributors = "[kbrandwijk](https://github.com/kbrandwijk)"
35
45
  _is_community = True
36
46
  _instructions = (
37
47
  "ℹ️ Set the max local elevation to approx the local max elevation for your area in"
@@ -40,8 +50,8 @@ class USGS1mProvider(DTMProvider):
40
50
  )
41
51
 
42
52
  _url = (
43
- "https://tnmaccess.nationalmap.gov/api/v1/products?prodFormats=GeoTIFF,IMG&prodExtents="
44
- "10000 x 10000 meter&datasets=Digital Elevation Model (DEM) 1 meter&polygon="
53
+ "https://tnmaccess.nationalmap.gov/api/v1/products?prodFormats=GeoTIFF,IMG"
54
+
45
55
  )
46
56
 
47
57
  def __init__(self, *args, **kwargs):
@@ -64,7 +74,8 @@ class USGS1mProvider(DTMProvider):
64
74
  (north, south, east, west) = self.get_bbox()
65
75
  response = requests.get( # pylint: disable=W3101
66
76
  self.url # type: ignore
67
- + f"{west} {south},{east} {south},{east} {north},{west} {north},{west} {south}&="
77
+ + f"&datasets={self.user_settings.dataset}" # type: ignore
78
+ + f"&bbox={west},{north},{east},{south}"
68
79
  )
69
80
  self.logger.debug("Getting file locations from USGS...")
70
81
 
@@ -75,7 +86,7 @@ class USGS1mProvider(DTMProvider):
75
86
  items = json_data["items"]
76
87
  for item in items:
77
88
  urls.append(item["downloadURL"])
78
- self.download_tif_files(urls)
89
+ # self.download_tif_files(urls)
79
90
  else:
80
91
  self.logger.error("Failed to get data. HTTP Status Code: %s", response.status_code)
81
92
  except requests.exceptions.RequestException as e:
@@ -108,12 +119,24 @@ class USGS1mProvider(DTMProvider):
108
119
  for chunk in response.iter_content(chunk_size=8192): # Download in chunks
109
120
  file.write(chunk)
110
121
  self.logger.info("File downloaded successfully: %s", file_path)
122
+ if file_name.endswith('.zip'):
123
+ with ZipFile(file_path, "r") as f_in:
124
+ f_in.extract(file_name.replace('.zip', '.img'), self.shared_tiff_path)
125
+ tif_files.append(file_path.replace('.zip', '.img'))
126
+ else:
127
+ tif_files.append(file_path)
111
128
  except requests.exceptions.RequestException as e:
112
129
  self.logger.error("Failed to download file: %s", e)
113
130
  else:
114
131
  self.logger.debug("File already exists: %s", file_name)
132
+ if file_name.endswith('.zip'):
133
+ if not os.path.exists(file_path.replace('.zip', '.img')):
134
+ with ZipFile(file_path, "r") as f_in:
135
+ f_in.extract(file_name.replace('.zip', '.img'), self.shared_tiff_path)
136
+ tif_files.append(file_path.replace('.zip', '.img'))
137
+ else:
138
+ tif_files.append(file_path)
115
139
 
116
- tif_files.append(file_path)
117
140
  return tif_files
118
141
 
119
142
  def merge_geotiff(self, input_files: list[str], output_file: str) -> None:
@@ -183,5 +183,5 @@ class SatelliteSettings(SettingsModel):
183
183
  """
184
184
 
185
185
  download_images: bool = False
186
- satellite_margin: int = 100
186
+ satellite_margin: int = 0
187
187
  zoom_level: int = 14
@@ -336,19 +336,12 @@ class Texture(Component):
336
336
  # pylint: disable=W0201
337
337
  def _read_parameters(self) -> None:
338
338
  """Reads map parameters from OSM data, such as:
339
- - minimum and maximum coordinates in UTM format
339
+ - minimum and maximum coordinates
340
340
  - map dimensions in meters
341
341
  - map coefficients (meters per pixel)
342
342
  """
343
- north, south, east, west = self.get_bbox(project_utm=True)
344
-
345
- # Parameters of the map in UTM format (meters).
346
- self.minimum_x = min(west, east)
347
- self.minimum_y = min(south, north)
348
- self.maximum_x = max(west, east)
349
- self.maximum_y = max(south, north)
350
- self.logger.debug("Map minimum coordinates (XxY): %s x %s.", self.minimum_x, self.minimum_y)
351
- self.logger.debug("Map maximum coordinates (XxY): %s x %s.", self.maximum_x, self.maximum_y)
343
+ bbox = ox.utils_geo.bbox_from_point(self.coordinates, dist=self.map_rotated_size / 2)
344
+ self.minimum_x, self.minimum_y, self.maximum_x, self.maximum_y = bbox
352
345
 
353
346
  def info_sequence(self) -> dict[str, Any]:
354
347
  """Returns the JSON representation of the generation info for textures."""
@@ -576,29 +569,19 @@ class Texture(Component):
576
569
  cv2.imwrite(layer_path, img)
577
570
  self.logger.debug("Base texture %s saved.", layer_path)
578
571
 
579
- def get_relative_x(self, x: float) -> int:
580
- """Converts UTM X coordinate to relative X coordinate in map image.
572
+ def latlon_to_pixel(self, lat: float, lon: float) -> tuple[int, int]:
573
+ """Converts latitude and longitude to pixel coordinates.
581
574
 
582
575
  Arguments:
583
- x (float): UTM X coordinate.
576
+ lat (float): Latitude.
577
+ lon (float): Longitude.
584
578
 
585
579
  Returns:
586
- int: Relative X coordinate in map image.
580
+ tuple[int, int]: Pixel coordinates.
587
581
  """
588
- return int(self.map_rotated_size * (x - self.minimum_x) / (self.maximum_x - self.minimum_x))
589
-
590
- def get_relative_y(self, y: float) -> int:
591
- """Converts UTM Y coordinate to relative Y coordinate in map image.
592
-
593
- Arguments:
594
- y (float): UTM Y coordinate.
595
-
596
- Returns:
597
- int: Relative Y coordinate in map image.
598
- """
599
- return int(
600
- self.map_rotated_size * (1 - (y - self.minimum_y) / (self.maximum_y - self.minimum_y))
601
- )
582
+ x = int((lon - self.minimum_x) / (self.maximum_x - self.minimum_x) * self.map_rotated_size)
583
+ y = int((lat - self.maximum_y) / (self.minimum_y - self.maximum_y) * self.map_rotated_size)
584
+ return x, y
602
585
 
603
586
  def np_to_polygon_points(self, np_array: np.ndarray) -> list[tuple[int, int]]:
604
587
  """Converts numpy array of polygon points to list of tuples.
@@ -623,11 +606,13 @@ class Texture(Component):
623
606
  Returns:
624
607
  np.ndarray: Numpy array of polygon points.
625
608
  """
626
- xs, ys = geometry.exterior.coords.xy
627
- xs = [int(self.get_relative_x(x)) for x in xs.tolist()]
628
- ys = [int(self.get_relative_y(y)) for y in ys.tolist()]
629
- pairs = list(zip(xs, ys))
630
- return np.array(pairs, dtype=np.int32).reshape((-1, 1, 2))
609
+ coords = list(geometry.exterior.coords)
610
+ pts = np.array(
611
+ [self.latlon_to_pixel(coord[1], coord[0]) for coord in coords],
612
+ np.int32,
613
+ )
614
+ pts = pts.reshape((-1, 1, 2))
615
+ return pts
631
616
 
632
617
  def _to_polygon(
633
618
  self, obj: pd.core.series.Series, width: int | None
@@ -664,9 +649,20 @@ class Texture(Component):
664
649
  Returns:
665
650
  shapely.geometry.polygon.Polygon: Polygon geometry.
666
651
  """
667
- polygon = geometry.buffer(width)
652
+ polygon = geometry.buffer(self.meters_to_degrees(width) if width else 0)
668
653
  return polygon
669
654
 
655
+ def meters_to_degrees(self, meters: int) -> float:
656
+ """Converts meters to degrees.
657
+
658
+ Arguments:
659
+ meters (int): Meters.
660
+
661
+ Returns:
662
+ float: Degrees.
663
+ """
664
+ return meters / 111320
665
+
670
666
  def _skip(
671
667
  self, geometry: shapely.geometry.polygon.Polygon, *args, **kwargs
672
668
  ) -> shapely.geometry.polygon.Polygon:
@@ -724,46 +720,43 @@ class Texture(Component):
724
720
  except Exception as e: # pylint: disable=W0718
725
721
  self.logger.debug("Error fetching objects for tags: %s. Error: %s.", tags, e)
726
722
  return
727
- objects_utm = ox.projection.project_gdf(objects, to_latlong=False)
728
- self.logger.debug("Fetched %s elements for tags: %s.", len(objects_utm), tags)
723
+ self.logger.debug("Fetched %s elements for tags: %s.", len(objects), tags)
729
724
 
730
725
  method = self.linestrings_generator if yield_linestrings else self.polygons_generator
731
726
 
732
- yield from method(objects_utm, width, is_fieds)
727
+ yield from method(objects, width, is_fieds)
733
728
 
734
729
  def linestrings_generator(
735
- self, objects_utm: pd.core.frame.DataFrame, *args, **kwargs
730
+ self, objects: pd.core.frame.DataFrame, *args, **kwargs
736
731
  ) -> Generator[list[tuple[int, int]], None, None]:
737
732
  """Generator which yields lists of point coordinates which represent LineStrings from OSM.
738
733
 
739
734
  Arguments:
740
- objects_utm (pd.core.frame.DataFrame): Dataframe with OSM objects in UTM format.
735
+ objects (pd.core.frame.DataFrame): Dataframe with OSM objects.
741
736
 
742
737
  Yields:
743
738
  Generator[list[tuple[int, int]], None, None]: List of point coordinates.
744
739
  """
745
- for _, obj in objects_utm.iterrows():
740
+ for _, obj in objects.iterrows():
746
741
  geometry = obj["geometry"]
747
742
  if isinstance(geometry, shapely.geometry.linestring.LineString):
748
- points = [
749
- (self.get_relative_x(x), self.get_relative_y(y)) for x, y in geometry.coords
750
- ]
743
+ points = [self.latlon_to_pixel(x, y) for y, x in geometry.coords]
751
744
  yield points
752
745
 
753
746
  def polygons_generator(
754
- self, objects_utm: pd.core.frame.DataFrame, width: int | None, is_fieds: bool
747
+ self, objects: pd.core.frame.DataFrame, width: int | None, is_fieds: bool
755
748
  ) -> Generator[np.ndarray, None, None]:
756
749
  """Generator which yields numpy arrays of polygons from OSM data.
757
750
 
758
751
  Arguments:
759
- objects_utm (pd.core.frame.DataFrame): Dataframe with OSM objects in UTM format.
752
+ objects (pd.core.frame.DataFrame): Dataframe with OSM objects.
760
753
  width (int | None): Width of the polygon in meters (only for LineString).
761
754
  is_fieds (bool): Flag to determine if the fields should be padded.
762
755
 
763
756
  Yields:
764
757
  Generator[np.ndarray, None, None]: Numpy array of polygon points.
765
758
  """
766
- for _, obj in objects_utm.iterrows():
759
+ for _, obj in objects.iterrows():
767
760
  try:
768
761
  polygon = self._to_polygon(obj, width)
769
762
  except Exception as e: # pylint: disable=W0703
@@ -773,7 +766,9 @@ class Texture(Component):
773
766
  continue
774
767
 
775
768
  if is_fieds and self.map.texture_settings.fields_padding > 0:
776
- padded_polygon = polygon.buffer(-self.map.texture_settings.fields_padding)
769
+ padded_polygon = polygon.buffer(
770
+ -self.meters_to_degrees(self.map.texture_settings.fields_padding)
771
+ )
777
772
 
778
773
  if not isinstance(padded_polygon, shapely.geometry.polygon.Polygon):
779
774
  self.logger.warning("The padding value is too high, field will not padded.")
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: maps4fs
3
- Version: 1.6.81
3
+ Version: 1.7.0
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
@@ -1,8 +1,8 @@
1
- maps4fs/__init__.py,sha256=WbT36EzJ_74GN0RUUrLIYECdSdtRiZaxKl17KUt7pjA,492
1
+ maps4fs/__init__.py,sha256=LrWSsyWaU28Dzcs7sRycywO_LvM-j34UvtafyBhvdx4,490
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=tV4UXvtkNN-OSvv6ujp4jFWRU1xGBgEvSakVGZ1H4nc,24877
5
- maps4fs/generator/component.py,sha256=vn_ThQw3OTcloqYuJWC7vghAvIAnwJsybEm7qMwvsZk,21356
5
+ maps4fs/generator/component.py,sha256=pbpGaWy5C0UzxpcJ72HPY2gMol98snDr-bvNZSX4yY0,20823
6
6
  maps4fs/generator/config.py,sha256=0QmK052B8bxyHVhg3jzCORLfOBMMmqVfhhbqXKf6OMk,4383
7
7
  maps4fs/generator/dem.py,sha256=20gx0dzX0LyO6ipvDitst-BwGfcKogFqgQf9Q2qMH5U,10933
8
8
  maps4fs/generator/game.py,sha256=Nf5r2ubV4YVAVHGzJyhbF2GnOC0qV3HlHYIZBCWciHs,7992
@@ -11,17 +11,17 @@ maps4fs/generator/i3d.py,sha256=pUyHKWKcw43xVCf3Y8iabtbQba05LYxMHi8vziGksIA,2484
11
11
  maps4fs/generator/map.py,sha256=a50KQEr1XZKjS_WKXywGwh4OC3gyjY6M8FTc0eNcxpg,10183
12
12
  maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
13
13
  maps4fs/generator/satellite.py,sha256=_7RcuNmR1mjxEJWMDsjnzKUIqWxnGUn50XtjB7HmSPg,3661
14
- maps4fs/generator/settings.py,sha256=3ASf3hW1nkGt8_3IOvKIKNUd6XAHYTAA8FquuhpSUlU,5668
15
- maps4fs/generator/texture.py,sha256=gIXCHU1vT3evbkaXAV9gLUrgI1wH3xJLgWAtZgFruj0,34013
14
+ maps4fs/generator/settings.py,sha256=9vbXISQrE-aDY7ATpvZ7LVJMqjfwa3-gNl-huI8XLO0,5666
15
+ maps4fs/generator/texture.py,sha256=tDC9lIx2qn8d09Gu6PW_Lbq7EK7s1N4l25p50v92xl8,33548
16
16
  maps4fs/generator/dtm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- maps4fs/generator/dtm/dtm.py,sha256=azy-RWsc5PgenKDtgG0lrddMwWEw1hYzdng9V8zphMk,9167
17
+ maps4fs/generator/dtm/dtm.py,sha256=nCQKQygARLxaz4HkREQQd0Yb03oKOf1Iav5_VoZsFWI,9819
18
18
  maps4fs/generator/dtm/srtm.py,sha256=2-pX6bWrJX6gr8IM7ueX6mm_PW7_UQ58MtdzDHae2OQ,9030
19
- maps4fs/generator/dtm/usgs.py,sha256=ZTi10RNDA3EBrsVg2ZoYrdN4uqiG1Jvk7FzdcKdgNkU,13408
19
+ maps4fs/generator/dtm/usgs.py,sha256=hwVjoSNTNRU6hwnfwJ2d3rOdtOjadCmx2QESA2REn6s,14493
20
20
  maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
21
21
  maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
22
22
  maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
23
- maps4fs-1.6.81.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
24
- maps4fs-1.6.81.dist-info/METADATA,sha256=D38DfL8D4KUjRwcWH9yscOgGvpx7dOgj1W-Qazz4sxk,39161
25
- maps4fs-1.6.81.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
26
- maps4fs-1.6.81.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
27
- maps4fs-1.6.81.dist-info/RECORD,,
23
+ maps4fs-1.7.0.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
24
+ maps4fs-1.7.0.dist-info/METADATA,sha256=MNEtaRLPbGmFgR7jJ_4ViotLPEmDEQ4MydSlOZVJdyg,39160
25
+ maps4fs-1.7.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
26
+ maps4fs-1.7.0.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
27
+ maps4fs-1.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.7.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5