Skip to content

Commit

Permalink
Custom OSM maps
Browse files Browse the repository at this point in the history
* Custom OSM maps.

* Linter updates.

* README update.

* README update.

* STL widget update.

* Dev scripts update.

* Docs update.
  • Loading branch information
iwatkot authored Dec 28, 2024
1 parent 1e0b48e commit a3e2286
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 6 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
🌲 Automatically generates forests 🆕<br>
🌊 Automatically generates water planes 🆕<br>
🌍 Based on real-world data from OpenStreetMap<br>
🗺️ Supports [custom OSM maps](/docs/custom_osm.md)<br>
🏞️ Generates height map using SRTM dataset<br>
📦 Provides a ready-to-use map template for the Giants Editor<br>
🚜 Supports Farming Simulator 22 and 25<br>
Expand Down Expand Up @@ -502,4 +503,5 @@ But also, I want to thank the people who helped me with the project in some way,
- [OneSunnySunday](https://www.artstation.com/onesunnysunday) - for expert advice on Blender, help in processing background terrain, and compiling detailed tutorials on how to prepare the OBJ files for use in Giants Editor.
- [BFernaesds](https://github.com/BFernaesds) - for the manual tests of the app.
- [gamerdesigns](https://github.com/gamerdesigns) - for the manual tests of the app.
- [Tox3](https://github.com/Tox3) - for the manual tests of the app.
- [Tox3](https://github.com/Tox3) - for the manual tests of the app.
- [Lucandia](https://github.com/Lucandia) - for the awesome StreamLit [widget to preview STL files](https://github.com/Lucandia/streamlit_stl).
2 changes: 1 addition & 1 deletion dev/clean_trash.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Directories to be removed
$dirs = @(".mypy_cache", ".pytest_cache", "htmlcov", "dist", "archives", "cache", "logs", "maps", "temp", "osmps")
$dirs = @(".mypy_cache", ".pytest_cache", "htmlcov", "dist", "archives", "cache", "logs", "maps", "temp", "osmps", "tests/data")

# Files to be removed
$files = @(".coverage", "queue.json")
Expand Down
2 changes: 1 addition & 1 deletion dev/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ pyproj
trimesh
pympler
pydoc-markdown
streamlit-stl==0.0.2
streamlit-stl==0.0.4
35 changes: 35 additions & 0 deletions docs/custom_osm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## How to create a custom OSM file

If you don't want to bother yourself editing the public version of the OSM data, deal with the community and so on, you can easily create your own OSM file and do there whatever you want. Here is a step-by-step guide on how to do it.

1. Download the JOSM editor from the [official website](https://josm.openstreetmap.de/) or directly from the [Windows Store](https://apps.microsoft.com/detail/xpfcg1gv0wwgzx) with one click.

2. Create a new layer (Ctrl + N).

3. Add imagery to see the map (Ctrl + Shift + N). You can use any map provider you want, in this example I'm using Bing.

![Add imagery](https://github.com/user-attachments/assets/8b6f0a68-821f-42d4-aff7-fda56485c175)

4. Download the OSM data: **File** -> **Download data** (Ctrl + Shift + Down).

![Download OSM data](https://github.com/user-attachments/assets/35b78426-73f8-4332-94dc-952510e025f1)

5. Draw the area of your ROI (region of interest). You don't need precision here, just ensure that it's large enough to cover the area you want to work with.
After selecting the area, click **Download**.
If you see the error message "Download area too large", download it in parts.

![Draw the area](https://github.com/user-attachments/assets/ba033f1a-adcb-4215-9852-4f01dfe1e4ef)

6. Now you should see all the data from the selected area.

7. You need to remove all the relations, otherwise the file can not be read by the `osmnx` library. To do it, go to the **Relations** tab, select everything and delete it.

![Remove relations](https://github.com/user-attachments/assets/65e1ef68-fdc2-4117-8032-2429cbaeb574)

8. Pay attention to the fact, that removing relations may lead to some areas to disappear, which was not defined separately from another objects. You can't do anything with it; if you miss something, you'll need to add it manually.

9. You can start editing your map. You can add new objects, remove existing ones, change their properties, etc. And there will be no one to tell you that you're doing something wrong or reverse your changes.

10. Save the file: **File** -> **Save as** (Ctrl + Shift + S).
Now, you can use this file in the generator.
Friendly reminder: save your file in some safe place, so you won't lose your changes.
6 changes: 5 additions & 1 deletion maps4fs/generator/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class TextureSettings(NamedTuple):
skip_drains: bool = False


# pylint: disable=R0913, R0902
# pylint: disable=R0913, R0902, R0914
class Map:
"""Class used to generate map using all components.
Expand All @@ -99,6 +99,7 @@ def __init__( # pylint: disable=R0917
rotation: int,
map_directory: str,
logger: Any = None,
custom_osm: str | None = None,
dem_settings: DEMSettings = DEMSettings(),
background_settings: BackgroundSettings = BackgroundSettings(),
grle_settings: GRLESettings = GRLESettings(),
Expand Down Expand Up @@ -126,6 +127,9 @@ def __init__( # pylint: disable=R0917

self.logger.info("Game was set to %s", game.code)

self.custom_osm = custom_osm
self.logger.info("Custom OSM file: %s", custom_osm)

self.dem_settings = dem_settings
self.logger.info("DEM settings: %s", dem_settings)
self.background_settings = background_settings
Expand Down
5 changes: 4 additions & 1 deletion maps4fs/generator/texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,10 @@ def polygons(
"""
is_fieds = info_layer == "fields"
try:
objects = ox.features_from_bbox(bbox=self.new_bbox, tags=tags)
if self.map.custom_osm is not None:
objects = ox.features_from_xml(self.map.custom_osm, tags=tags)
else:
objects = ox.features_from_bbox(bbox=self.new_bbox, tags=tags)
except Exception: # pylint: disable=W0718
self.logger.debug("Error fetching objects for tags: %s.", tags)
return
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ geopy
trimesh
pyproj
fast-simplification
streamlit-stl==0.0.2
streamlit-stl==0.0.4
pympler
maps4fs
30 changes: 30 additions & 0 deletions webui/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,29 @@ def add_left_widgets(self) -> None:

st.info(Messages.AUTO_PRESET_DISABLED)

self.custom_osm_path = None

st.write("[ALPHA] Custom OSM:")
self.custom_osm_enabled = st.checkbox(
"Upload custom OSM file",
value=False,
key="custom_osm_enabled",
)

if self.custom_osm_enabled:
st.warning("⚠️ ALPHA FEATURE: Use it at your own risk.")
st.info(Messages.CUSTOM_OSM_INFO)

uploaded_file = st.file_uploader("Choose a file", type=["osm"])
if uploaded_file is not None:
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
self.custom_osm_path = os.path.join(
config.INPUT_DIRECTORY, f"custom_osm_{timestamp}.osm"
)
with open(self.custom_osm_path, "wb") as f:
f.write(uploaded_file.read())
st.success(f"Custom OSM file uploaded: {uploaded_file.name}")

# Add checkbox for advanced settings.
st.write("Advanced settings:")
self.advanced_settings = st.checkbox(
Expand Down Expand Up @@ -589,13 +612,19 @@ def generate_map(self) -> None:
st.error("Invalid tree schema!")
return

if self.custom_osm_enabled:
osm_path = self.custom_osm_path
else:
osm_path = None

mp = mfs.Map(
game,
coordinates,
height,
self.rotation,
map_directory,
logger=self.logger,
custom_osm=osm_path,
dem_settings=dem_settings,
background_settings=background_settings,
grle_settings=grle_settings,
Expand Down Expand Up @@ -699,6 +728,7 @@ def show_preview(self, mp: mfs.Map) -> None:
auto_rotate=True,
height="400",
key=None,
max_view_distance=10000,
)
except Exception:
continue
5 changes: 5 additions & 0 deletions webui/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,8 @@ class Messages:
"This section contains the schema which is used to generate the trees. "
"Any changes here can lead to errors or completely broken map. "
)
CUSTOM_OSM_INFO = (
"To prepare the custom OSM file, please refer to the [documentation]("
"https://github.com/iwatkot/maps4fs/blob/main/docs/custom_osm.md). \n"
"Note, that incorrect file can lead to errors or completely broken map."
)

0 comments on commit a3e2286

Please sign in to comment.