2.13.2.1. pycsamt.stratagem.gis_correct#

stratagem.gis_correct#

Coordinate injection and station-ordering tools for Stratagem surveys.

Background#

WinGLink exports EDI files with placeholder coordinates (LAT=0:00:00.00, LONG=0:00:00.00). The actual survey positions are recorded separately in a GPS table (CSV / XLS / XLSX) using a local projected coordinate system (typically Beijing 1954 / Gauss-Kruger for Chinese surveys, EPSG 15921).

CoordinateInjector reads that table, converts each projected point to WGS84 decimal degrees via project_point_utm2ll(), and writes the result into each EDI file’s >HEAD section (LAT, LONG, ELEV).

StationLocator handles the common mismatch between Stratagem acquisition order (hardware numbers stations from the first measurement point) and the GPS table row order (which follows the physical profile direction, often opposite to acquisition).

Column auto-detection#

Chinese Gauss-Kruger tables frequently use column names longitude and latitude for what are actually UTM-style easting and northing values. CoordinateInjector auto-detects which column is easting and which is northing by comparing the median values: the column with the larger median is assumed to be northing (N-S distance from equator), the smaller is easting. This heuristic is correct for all standard UTM / GK zones in the northern hemisphere, but it only has a sound basis when exactly two numeric candidate columns remain after elev_col/station_col/step exclusion — with a third (e.g. a station-index or chainage column), min/max selection has no guarantee of picking the actual coordinate pair, so auto-detection raises ValidationError instead of guessing. Pass explicit easting_col / northing_col to resolve that, or to override the heuristic outright.

Classes

CoordinateInjector(*[, coordinate_system, ...])

Inject GPS coordinates into WinGLink EDI files.

StationLocator(*[, order, mapping, verbose])

Resolve the mapping between EDI acquisition order and GPS table rows.

class pycsamt.stratagem.gis_correct.CoordinateInjector(*, coordinate_system='utm', epsg=15921, utm_zone='49N', datum='WGS84', order='auto', verbose=0)[source]

Bases: PyCSAMTObject, MetadataMixin

Inject GPS coordinates into WinGLink EDI files.

Reads a coordinate table (CSV / XLS / XLSX), converts projected coordinates to WGS84 using project_point_utm2ll(), and writes the resulting latitude, longitude, and elevation into each EDI file’s >HEAD section. The injection is in-memory until export() is called.

Parameters:
  • coordinate_system (str, default 'utm') – Coordinate type of the input table (currently 'utm' is the only supported value; geographic tables can be loaded with easting_col / northing_col pointing to decimal-degree columns and epsg=4326).

  • epsg (int, default 15921) – EPSG code for the projected CRS. 15921 = Beijing 1954 / Gauss-Kruger Zone 49 (standard for Chinese AMT surveys in that belt). Change to match your survey area.

  • utm_zone (str, default '49N') – UTM zone string passed to project_point_utm2ll when epsg is not provided. Ignored when epsg is set.

  • datum (str, default 'WGS84')

  • order ({‘auto’, ‘forward’, ‘reversed’, ‘mapping’}, default 'auto') – Passed to StationLocator.

  • verbose (int, default 0)

Variables:
  • latitudes (ndarray, shape (n_stations,)) – WGS84 latitudes in decimal degrees, in GPS table order.

  • longitudes (ndarray, shape (n_stations,))

  • elevations (ndarray, shape (n_stations,))

  • station_ids (list) – Station labels from the station_col column of the GPS table.

  • edi_objects (list of EDIFile) – EDI objects with >HEAD coordinates updated in-memory. These are the same objects that were loaded into the supplied EDIBatch; pass copy=True to fit() to leave the source batch unchanged.

  • reversed (bool) – Whether StationLocator detected a reversed ordering.

Examples

Typical Stratagem workflow:

>>> from pycsamt.stratagem import EDIBatch, CoordinateInjector
>>> batch  = EDIBatch("2/2EDI").fit()
>>> injector = CoordinateInjector(epsg=15921, utm_zone="49N")
>>> injector.fit(batch, "2.csv")
CoordinateInjector(epsg=15921, ...)
>>> paths = injector.export("2/2EDI_coords")

Custom column names and reversed order:

>>> injector = CoordinateInjector(epsg=15921, order="reversed")
>>> injector.fit(
...     batch, "coords.xlsx",
...     easting_col="E", northing_col="N", elev_col="elevation",
... )
fit(edi_batch, coord_file, *, easting_col=None, northing_col=None, elev_col='elev', station_col='stations', read_kwargs=None, copy=False)[source]

Load coordinates and inject them into EDI HEAD sections.

Parameters:
  • edi_batch (EDIBatch or list of EDIFile) – Source EDI objects. When copy=True each EDIFile is shallow-copied before modification so the originals are not mutated.

  • coord_file (path-like) – GPS coordinate table. Supported: .csv, .xls, .xlsx (and any format registered in Config).

  • easting_col (str, optional) – Column name for the E-W coordinate. Auto-detected by value magnitude when omitted (see module docstring).

  • northing_col (str, optional) – Column name for the N-S coordinate. Auto-detected when omitted.

  • elev_col (str, default 'elev') – Column name for elevation. If absent from the table, elevations default to zero.

  • station_col (str, default 'stations') – Column with station labels (used to populate station_ids_).

  • read_kwargs (dict, optional) – Extra keyword arguments forwarded to the table reader (e.g. {'sheet_name': 1} for multi-sheet Excel files).

  • copy (bool, default False) – When True, shallow-copy each EDIFile before injecting coordinates so the source batch is not mutated.

Return type:

self

export(savepath, *, basename=None, overwrite=False)[source]

Write coordinate-injected EDI files to savepath.

Parameters:
  • savepath (path-like) – Output directory. Created automatically when absent.

  • basename (str, optional) – When given, output files are named {basename}{i+1:03d}.edi (e.g. basename='Z2HX' produces Z2HX001.edi, Z2HX002.edi, …). When omitted the original file name is preserved.

  • overwrite (bool, default False) – Skip files that already exist when False.

Returns:

Paths of the written EDI files.

Return type:

list of Path

coordinate_frame()[source]

Return a DataFrame with station IDs and WGS84 coordinates.

Returns:

Columns: station, latitude, longitude, elevation.

Return type:

pandas.DataFrame

Raises:

NotFittedError – If fit() has not been called.

class pycsamt.stratagem.gis_correct.StationLocator(*, order='auto', mapping=None, verbose=0)[source]

Bases: PyCSAMTObject

Resolve the mapping between EDI acquisition order and GPS table rows.

Stratagem numbers station files from the first measurement point (001, 002, …, 087). The GPS table is ordered along the physical profile direction, which may run from the opposite end. This class detects or specifies the correct correspondence.

Parameters:
  • order ({'auto', 'forward', 'reversed', 'mapping'}, default 'auto') –

    How to align EDI indices with GPS rows:

    'auto'

    Heuristic: compares the median northing of the first half of GPS records against the direction of increasing station numbers. Falls back to 'forward' when the signal is ambiguous.

    'forward'

    EDI index i maps to GPS row i.

    'reversed'

    EDI index i maps to GPS row n - 1 - i.

    'mapping'

    Use the explicit mapping list supplied to the constructor.

  • mapping (list of int, optional) – Required when order='mapping'. mapping[i] is the GPS row index for EDI station i.

  • verbose (int, default 0)

Variables:
  • index_map (list of int) – After fit(), index_map_[i] is the GPS row for EDI i.

  • reversed (bool) – True when the final mapping is the reverse of natural order.

Examples

>>> loc = StationLocator(order="auto")
>>> loc.fit(batch.edi_objects_, lats, lons)
>>> loc.index_map_[:3]
[0, 1, 2]   # or [86, 85, 84] if reversed
fit(edi_objects, latitudes, longitudes)[source]

Compute the index map.

Parameters:
  • edi_objects (list of EDIFile)

  • latitudes (ndarray of shape (n_stations,)) – WGS84 coordinates of the GPS table rows in their original order.

  • longitudes (ndarray of shape (n_stations,)) – WGS84 coordinates of the GPS table rows in their original order.

Return type:

self