Skip to content

Change coordinates and units

A file keeps the coordinate system and units it was uploaded with. When you need it in others, you make a new version of it: the original stays exactly as it is, the new version records what it was made from and how, and anyone who can read both can see the two side by side. Nothing is converted silently: a file that does not say what it is in, a unit the units table does not hold, or a change no single method covers is refused with a sentence, and nothing is written.

The same change made in Workspace and in Python leaves the same record, because the server makes it in both cases.

In Workspace, open the asset and choose Change coordinate system…. Choose the system to change to and a name for the new version. Before anything is made, the dialog shows the method the server will use and its published accuracy: that figure belongs to the method, not to your data. A grid also asks how values are taken: Smooth between cells (bilinear) or Keep original values (the nearest cell). A grid is resampled once onto cell centres in the new system; the version says how many times it has been resampled in all, and cells outside the original are Not stated.

In Python, preview first, then make the version. Pick the asset you are changing and the system to change to:

points = next(a for a in client.assets() if a["name"] == "Well positions in RD New")
target = "EPSG:32631" # WGS 84 / UTM zone 31N

The preview is stored nowhere. It returns the method record the version would carry and a few positions before and after:

preview = client.preview_change(points["asset_id"], points["revision"], {"kind": "coordinates", "to": target})
print(preview["method"]["parameters"]["operation"], preview["method"]["parameters"]["accuracy_m"])
for sample in preview["samples"]:
print(sample["before"], "->", sample["after"])

Making the version sends the same request with the preview’s method. If the server would now choose a different method, it refuses and asks you to preview again. The command id makes a retry after a lost answer return the same version instead of a second one:

receipt = client.change_coordinates(points["asset_id"], points["revision"], to=target,
name="Well positions in UTM 31N", command_id="positions-to-utm31n")
print(receipt.asset_id, receipt.revision, receipt.method.name)

Between Amersfoort / RD New and ETRS89 the server uses the Dutch national coordinate correction and records the correction grid by its SHA-256. A server without that grid, or with a grid not yet checked against its publisher’s validation points, refuses rather than using a less accurate method.

In Workspace, a log’s Show in controls draw the depth and each curve in another unit of the same kind for that view only; nothing is stored. Make a version in these units… makes a LAS file in those units, with every other curve copied and missing samples still missing. Tops and surveys stay linked to the original log; the new version draws the tops of the original it was made from, converted for display.

In Python, name each curve and its new unit; the depth axis is named by its own mnemonic:

log = next(a for a in client.assets() if a["name"] == "HON-GT-01 logs")
units = client.change_units(log["asset_id"], log["revision"], curves={"DT": "us/m", "DEPTH": "ft"},
name="HON-GT-01 logs in ft", command_id="hon-gt-01-in-ft")
print(units.method.parameters["curves"]["DT"]) # from, to and the coefficients A-D of each

The method record keeps each unit’s coefficients from the units table, so a display conversion can be reproduced from the record alone: a value in the table’s base unit is (A + B x) / (C + D x).

Workspace’s Depth shown as draws a log against measured depth, the survey file’s own vertical depth, or vertical depth calculated by minimum curvature from the survey’s angles. The two vertical depths are kept apart and never substituted for each other. A start is never assumed: the survey starts at measured depth 0, states its vertical depth there, or you supply it. Depths past the last station are not drawn and are counted.

The same calculation in Python:

from ophiolite.transform import vertical_depth
stations = [{"md": 0, "inclination": 0, "azimuth": 0},
{"md": 1000, "inclination": 30, "azimuth": 90},
{"md": 2000, "inclination": 30, "azimuth": 90}]
depth = vertical_depth(stations, [500, 1500, 2500])
print(depth["calculated"], depth["beyond"]) # the depth at 2500 m is None and counted beyond the survey

Coordinate systems · How a result was made