Topography Formats#

.map - Vector Map#

Text format storing a vector map as polylines: elevation contours, roughness change lines, or lines carrying both. The format is documented in the WAsP help facility, under “Technical reference | WAsP file formats”.

Functions: read_map(), write_map(), format_map()

File layout: four header lines, then one record per polyline:

  1. Description. Free text; the WAsP map editor also records the map’s projection here, which windkit maps to an EPSG code.

  2. Fixed point #1: x_user y_user x_metric y_metric.

  3. Fixed point #2, same fields. Together the fixed points define a transform from the file’s x/y coordinates to metric ones, a relic of digitiser tablets. Modern files carry the identity transform.

  4. Z scale and offset: z_metric = z_scale * (z_user + z_offset), so a map digitised with elevations in feet records z_scale = 0.3048.

Each record is a line header of one to four numbers ending in the point count – elevation and/or the roughness lengths left and right of the line – followed by that many x y pairs, wrapped over any number of physical lines:

Z n            <- height contour
z0l z0r n      <- roughness change line
z0l z0r Z n    <- both

Return structure: one row per polyline, in file order; nan marks an attribute a line does not carry.

{
    "points": [np.ndarray, ...],  # one (n_pts, 2) array of x, y per line
    "elev": np.ndarray,           # (n_lines,) - elevation, nan where absent
    "z0_left": np.ndarray,        # (n_lines,) - roughness left of the line
    "z0_right": np.ndarray,       # (n_lines,) - roughness right of the line
    "header": {
        "description": str,       # the first line, verbatim
        "epsg": int or None,      # EPSG code named in the description
        "fixed_points": np.ndarray,  # (2, 4) - header lines 2 and 3
        "z_scale": float,
        "z_offset": float,
    },
}

read_map returns the header transforms raw and does not apply them; the high-level readers (read_elevation_map(), read_roughness_map()) apply the z scale and offset.

Example:

import numpy as np
from windkit.io.wasp import read_map, write_map

# Read
data = read_map("site.map")
is_elevation = ~np.isnan(data["elev"])
print(data["points"][0].shape)  # (n_pts, 2)

# Round-trip
write_map("out.map", **data)

Note

write_map writes coordinates with one decimal by default, the WAsP GUI’s convention for maps in metres. Pass a larger coord_decimals for a map in geographic coordinates: one decimal of a degree is roughly 11 km.