mirror of
https://github.com/enzet/map-machine.git
synced 2025-08-06 10:09:52 +02:00
Issue #69: add documentation.
This commit is contained in:
parent
3f5b88fd20
commit
9015cbe6b3
3 changed files with 92 additions and 38 deletions
32
README.md
32
README.md
|
@ -28,7 +28,7 @@ Röntgen features:
|
|||
* detailed icons to display subtypes like [power tower design](#power-tower-design),
|
||||
* can display multiple icons for one entity to cover more features,
|
||||
* use color to visualize [`colour`](https://wiki.openstreetmap.org/wiki/Key:colour) and other features like plant types,
|
||||
* display [privitive 3D shapes](#levels) for buildings,
|
||||
* display [primitive 3D shapes](#levels) for buildings,
|
||||
* display [directions](#direction) with gradient sectors,
|
||||
* use width to display roads.
|
||||
|
||||
|
@ -171,14 +171,23 @@ Command: `tile`.
|
|||
| `--cache` | path for temporary OSM files, default value: `cache` |
|
||||
| `-b`, `--boundary-box` | construct the minimum amount of tiles that cover requested boundary box |
|
||||
|
||||
### Generate one tile ###
|
||||
|
||||
Specify tile coordinates:
|
||||
|
||||
```bash
|
||||
python roentgen.py tile --tile ${OSM_ZOOM_LEVEL}/${X}/${Y}
|
||||
```
|
||||
|
||||
or specify any geographical coordinates inside a tile:
|
||||
|
||||
```bash
|
||||
python roentgen.py tile \
|
||||
-c ${LATITUDE},${LONGITUDE} \
|
||||
-s ${OSM_ZOOM_LEVEL}
|
||||
--coordinates ${LATITUDE},${LONGITUDE} \
|
||||
--scale ${OSM_ZOOM_LEVEL}
|
||||
```
|
||||
|
||||
Tile will be stored as SVG file to `out/tiles/tile_<zoom level>_<x>_<y>.svg`, where `x` and `y` are tile coordinates.
|
||||
Tile will be stored as SVG file `out/tiles/tile_<zoom level>_<x>_<y>.svg` and PNG file `out/tiles/tile_<zoom level>_<x>_<y>.svg`, where `x` and `y` are tile coordinates.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -186,7 +195,18 @@ Example:
|
|||
python roentgen.py tile -c 55.7510637,37.6270761 -s 18
|
||||
```
|
||||
|
||||
will generate SVG file `out/tiles/tile_18_158471_81953.svg`.
|
||||
will generate SVG file `out/tiles/tile_18_158471_81953.svg` and PNG file `out/tiles/tile_18_158471_81953.png`.
|
||||
|
||||
### Generate a set of tiles ###
|
||||
|
||||
Specify boundary box to get the minimal set of tiles that covers the area:
|
||||
|
||||
```bash
|
||||
python roentgen.py tile \
|
||||
--boundary-box ${LONGITUDE_1},${LATITUDE_1},${LONGITUDE_2},${LATITUDE_2}
|
||||
```
|
||||
|
||||
Boundary box will be extended to the boundaries of the minimal tile set that covers the area, then it will be extended a bit more to avoid some artifacts on the edges, and finally boundary box coordinates will be rounded to 3 digits after the decimal point. Map with new boundary box coordinates will be written to the cache directory as SVG and PNG files. All tiles will be stored as SVG files `out/tiles/tile_<zoom level>_<x>_<y>.svg` and PNG files `out/tiles/tile_<zoom level>_<x>_<y>.svg`, where `x` and `y` are tile coordinates.
|
||||
|
||||
MapCSS 0.2 generation
|
||||
---------------------
|
||||
|
@ -201,7 +221,7 @@ To create MapCSS with only Röntgen icons run `python roentgen.py mapcss --no-wa
|
|||
|---|---|
|
||||
| `--icons` | add icons for nodes and areas, set by default |
|
||||
| `--ways` | add style for ways and relations, set by default |
|
||||
| `--lifecycle` | add icons for lifecycle tags, set by default |
|
||||
| `--lifecycle` | add icons for lifecycle tags; be careful: this will increase the number of node and area selectors by 9 times, set by default |
|
||||
|
||||
### Use Röntgen as JOSM map paint style ###
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ Röntgen features\:
|
|||
{detailed icons to display subtypes like \ref {#power-tower-design} {power tower design},}
|
||||
{can display multiple icons for one entity to cover more features,}
|
||||
{use color to visualize \osm {colour} and other features like plant types,}
|
||||
{display \ref {#levels} {privitive 3D shapes} for buildings,}
|
||||
{display \ref {#levels} {primitive 3D shapes} for buildings,}
|
||||
{display \ref {#direction} {directions} with gradient sectors,}
|
||||
{use width to display roads.}
|
||||
|
||||
|
@ -154,7 +154,7 @@ Visualize element creation time with \m {--mode time}.
|
|||
|
||||
\image {doc/time.png} {Creation time mode}
|
||||
|
||||
\3 {Author mode} {autor_mode}
|
||||
\3 {Author mode} {author_mode}
|
||||
|
||||
Every way and node displayed with the random color picked for each author with \m {--mode user-coloring}.
|
||||
|
||||
|
@ -193,17 +193,35 @@ Command\: \m {tile}.
|
|||
|
||||
\options {tile}
|
||||
|
||||
\code {python roentgen.py tile \\
|
||||
-c $\{LATITUDE\},$\{LONGITUDE\} \\
|
||||
-s $\{OSM_ZOOM_LEVEL\}} {bash}
|
||||
\3 {Generate one tile} {generate-one-tile}
|
||||
|
||||
Tile will be stored as SVG file to \m {out/tiles/tile_<zoom level>_<x>_<y>.svg}, where \m {x} and \m {y} are tile coordinates.
|
||||
Specify tile coordinates\:
|
||||
|
||||
\code {python roentgen.py tile --tile $\{OSM_ZOOM_LEVEL\}/$\{X\}/$\{Y\}} {bash}
|
||||
|
||||
or specify any geographical coordinates inside a tile\:
|
||||
|
||||
\code {python roentgen.py tile \\
|
||||
--coordinates $\{LATITUDE\},$\{LONGITUDE\} \\
|
||||
--scale $\{OSM_ZOOM_LEVEL\}} {bash}
|
||||
|
||||
Tile will be stored as SVG file \m {out/tiles/tile_<zoom level>_<x>_<y>.svg} and PNG file \m {out/tiles/tile_<zoom level>_<x>_<y>.svg}, where \m {x} and \m {y} are tile coordinates.
|
||||
|
||||
Example\:
|
||||
|
||||
\code {python roentgen.py tile -c 55.7510637,37.6270761 -s 18} {bash}
|
||||
|
||||
will generate SVG file \m {out/tiles/tile_18_158471_81953.svg}.
|
||||
will generate SVG file \m {out/tiles/tile_18_158471_81953.svg} and PNG file \m {out/tiles/tile_18_158471_81953.png}.
|
||||
|
||||
\3 {Generate a set of tiles} {generate-a-set-of-tiles}
|
||||
|
||||
Specify boundary box to get the minimal set of tiles that covers the area\:
|
||||
|
||||
\code {python roentgen.py tile \\
|
||||
--boundary-box $\{LONGITUDE_1\},$\{LATITUDE_1\},$\{LONGITUDE_2\},$\{LATITUDE_2\} \\
|
||||
--scale $\{OSM_ZOOM_LEVEL\}} {bash}
|
||||
|
||||
Boundary box will be extended to the boundaries of the minimal tile set that covers the area, then it will be extended a bit more to avoid some artifacts on the edges rounded to 3 digits after the decimal point. Map with new boundary box coordinates will be written to the cache directory as SVG and PNG files. All tiles will be stored as SVG files \m {out/tiles/tile_<zoom level>_<x>_<y>.svg} and PNG files \m {out/tiles/tile_<zoom level>_<x>_<y>.svg}, where \m {x} and \m {y} are tile coordinates.
|
||||
|
||||
\2 {MapCSS 0.2 generation} {mapcss-0-2-generation}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ from roentgen.workspace import workspace
|
|||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
TILE_WIDTH, TILE_HEIGHT = 256, 256
|
||||
|
||||
|
||||
@dataclass
|
||||
class Tiles:
|
||||
|
@ -87,9 +89,9 @@ class Tiles:
|
|||
for tile in self.tiles:
|
||||
file_path: Path = tile.get_file_name(directory)
|
||||
if not file_path.exists():
|
||||
tile.draw_for_map(osm_data, directory)
|
||||
tile.draw_with_osm_data(osm_data, directory)
|
||||
else:
|
||||
logging.info(f"File {file_path} already exists.")
|
||||
logging.debug(f"File {file_path} already exists.")
|
||||
|
||||
output_path: Path = file_path.with_suffix(".png")
|
||||
if not output_path.exists():
|
||||
|
@ -99,7 +101,7 @@ class Tiles:
|
|||
)
|
||||
logging.info(f"SVG file is rasterized to {output_path}.")
|
||||
else:
|
||||
logging.info(f"File {output_path} already exists.")
|
||||
logging.debug(f"File {output_path} already exists.")
|
||||
|
||||
def draw(self, directory: Path, cache_path: Path) -> None:
|
||||
"""
|
||||
|
@ -113,7 +115,6 @@ class Tiles:
|
|||
self.boundary_box.get_format() + ".png"
|
||||
)
|
||||
self.draw_image(cache_path)
|
||||
width, height = 256, 256
|
||||
|
||||
with input_path.open("rb") as input_file:
|
||||
image = Image.open(input_file)
|
||||
|
@ -121,11 +122,14 @@ class Tiles:
|
|||
for tile in self.tiles:
|
||||
x = tile.x - self.tile_1.x
|
||||
y = tile.y - self.tile_1.y
|
||||
cropped = image.crop(
|
||||
(x * width, y * height, (x + 1) * width, (y + 1) * height)
|
||||
area = (
|
||||
x * TILE_WIDTH,
|
||||
y * TILE_HEIGHT,
|
||||
(x + 1) * TILE_WIDTH,
|
||||
(y + 1) * TILE_HEIGHT,
|
||||
)
|
||||
print(x * width, y * height, (x + 1) * width, (y + 1) * height)
|
||||
cropped.crop((0, 0, width, height)).save(
|
||||
cropped = image.crop(area)
|
||||
cropped.crop((0, 0, TILE_WIDTH, TILE_HEIGHT)).save(
|
||||
tile.get_file_name(directory).with_suffix(".png")
|
||||
)
|
||||
logging.info(f"Tile 18/{tile.x}/{tile.y} is created.")
|
||||
|
@ -173,7 +177,7 @@ class Tiles:
|
|||
with output_path.open("w+") as output_file:
|
||||
svg.write(output_file)
|
||||
else:
|
||||
logging.info(f"File {output_path} already exists.")
|
||||
logging.debug(f"File {output_path} already exists.")
|
||||
|
||||
png_path: Path = cache_path / f"{self.boundary_box.get_format()}.png"
|
||||
if not png_path.exists():
|
||||
|
@ -181,7 +185,7 @@ class Tiles:
|
|||
cairosvg.svg2png(file_obj=input_file, write_to=str(png_path))
|
||||
logging.info(f"SVG file is rasterized to {png_path}.")
|
||||
else:
|
||||
logging.info(f"File {png_path} already exists.")
|
||||
logging.debug(f"File {png_path} already exists.")
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -197,7 +201,12 @@ class Tile:
|
|||
|
||||
@classmethod
|
||||
def from_coordinates(cls, coordinates: np.array, scale: int):
|
||||
"""Code from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames"""
|
||||
"""
|
||||
Code from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
||||
|
||||
:param coordinates: any coordinates inside tile
|
||||
:param scale: OpenStreetMap zoom level
|
||||
"""
|
||||
lat_rad = np.radians(coordinates[0])
|
||||
n: float = 2.0 ** scale
|
||||
x: int = int((coordinates[1] + 180.0) / 360.0 * n)
|
||||
|
@ -262,7 +271,7 @@ class Tile:
|
|||
|
||||
def draw(self, directory_name: Path, cache_path: Path) -> None:
|
||||
"""
|
||||
Draw tile to SVG file.
|
||||
Draw tile to SVG and PNG files.
|
||||
|
||||
:param directory_name: output directory to storing tiles
|
||||
:param cache_path: directory to store SVG and PNG tiles
|
||||
|
@ -270,12 +279,14 @@ class Tile:
|
|||
try:
|
||||
osm_data: OSMData = self.load_osm_data(cache_path)
|
||||
except NetworkError as e:
|
||||
raise NetworkError(f"Map does not loaded. {e.message}")
|
||||
raise NetworkError(f"Map is not loaded. {e.message}")
|
||||
|
||||
self.draw_for_map(osm_data, directory_name)
|
||||
self.draw_with_osm_data(osm_data, directory_name)
|
||||
|
||||
def draw_for_map(self, osm_data: OSMData, directory_name: Path) -> None:
|
||||
"""Draw tile using existing map."""
|
||||
def draw_with_osm_data(
|
||||
self, osm_data: OSMData, directory_name: Path
|
||||
) -> None:
|
||||
"""Draw SVG and PNG tile using OpenStreetMap data."""
|
||||
lat1, lon1 = self.get_coordinates()
|
||||
lat2, lon2 = Tile(self.x + 1, self.y + 1, self.scale).get_coordinates()
|
||||
|
||||
|
@ -302,9 +313,14 @@ class Tile:
|
|||
painter: Map = Map(flinger=flinger, svg=svg, scheme=scheme)
|
||||
painter.draw(constructor)
|
||||
|
||||
logging.info(f"Writing output SVG {output_file_name}...")
|
||||
with output_file_name.open("w") as output_file:
|
||||
svg.write(output_file)
|
||||
logging.info(f"Tile is drawn to {output_file_name}.")
|
||||
|
||||
output_path: Path = output_file_name.with_suffix(".png")
|
||||
with output_file_name.open() as input_file:
|
||||
cairosvg.svg2png(file_obj=input_file, write_to=str(output_path))
|
||||
logging.info(f"SVG file is rasterized to {output_path}.")
|
||||
|
||||
|
||||
def ui(options) -> None:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue