civilpy.transportation package

Roadway geometric design, curve calculations, alignments and terrain models (OGRIP/3DEP LiDAR with a notebook map picker), and FHWA National Bridge Inventory utilities.

Subpackages

Submodules

civilpy.transportation.alignment module

Composed roadway alignment: a chained horizontal geometry (tangents and circular curves) with a vertical profile, exposing the station/offset placement contract every bridge object is located by.

This is the native placement object for the bridge/analysis pipeline. The individual curve primitives live in civilpy.transportation.curves (HorizontalCurve, VerticalCurve); this module chains them head to tail so a component can ask for a 3D point at (station, offset).

Conventions

  • Plan coordinates are (x=East, y=North) in feet.

  • Bearings are azimuths in degrees, clockwise from North (+y); the unit direction of increasing station is d = (sin az, cos az).

  • Positive offset is to the right of the direction of increasing station (r = (cos az, -sin az)), matching the usual roadway right-is-positive offset sense.

  • Elevation comes from the vertical profile; when a profile is omitted the alignment is flat at z = 0.

Superelevation/cross-slope is not yet applied to offset elevations (offsets sit at the centerline profile elevation).

Examples

A tangent, a 500-ft-radius curve turning right through 30 deg, then a tangent, starting at the origin headed due north, stationed from 10+00:

>>> from civilpy.transportation.curves import HorizontalCurve
>>> al = Alignment(
...     start_point=(0.0, 0.0), start_bearing_deg=0.0, start_station_ft=1000.0,
...     elements=[Tangent(200.0),
...               Curve(radius_ft=500.0, delta_deg=30.0, direction="R"),
...               Tangent(200.0)])
>>> round(al.length_ft, 3)
661.799
>>> x, y, z = al.point_at(1000.0, 0.0)          # start, on centerline
>>> round(x, 6), round(y, 6), round(z, 6)
(0.0, 0.0, 0.0)
>>> round(al.bearing_at(1100.0), 6)             # still on first tangent
0.0
>>> x, y, _ = al.point_at(1100.0, 25.0)         # 25 ft right of a north tangent
>>> round(x, 6), round(y, 6)
(25.0, 100.0)
>>> sta, off = al.station_offset_of((25.0, 100.0))
>>> round(sta, 6), round(off, 6)
(1100.0, 25.0)
class civilpy.transportation.alignment.Alignment(start_point: tuple[float, float], start_bearing_deg: float, elements: list, profile: VerticalProfile | None = None, start_station_ft: float = 0.0)[source]

Bases: object

A chained horizontal alignment with an optional vertical profile.

Parameters:
  • start_point ((float, float)) – Plan (x, y) of the alignment start, feet.

  • start_bearing_deg (float) – Azimuth of increasing station at the start (deg, cw from North).

  • elements (list[Tangent | Curve]) – Ordered horizontal elements laid head to tail.

  • profile (VerticalProfile, optional) – Vertical profile; when omitted the alignment is flat at z = 0.

  • start_station_ft (float) – Station value at start_point.

bearing_at(station_ft: float) float[source]

Azimuth (deg, cw from North) of increasing station at station.

classmethod between_points(p0: tuple[float, float], p1: tuple[float, float], *, start_station_ft: float = 0.0, radius_ft: float | None = None, direction: Literal['R', 'L'] = 'R', start_elev_ft: float | None = None, end_elev_ft: float | None = None, terrain=None) Alignment[source]

Build an alignment between two plan points, deriving bearing, length, and grade – the conceptual-design workflow where you can’t drape an alignment on the ground but can pick two endpoints and a curvature.

With no radius_ft the horizontal alignment is a single tangent from p0 to p1 (bearing = the azimuth p0->p1, length = the distance). Give radius_ft and the two points are joined by one circular arc of that radius turning direction (“R”/”L”); the required deflection and start bearing are back-computed from the chord.

Grade comes from the endpoint elevations: pass start_elev_ft / end_elev_ft directly, or a terrain (anything with elevation_at(x, y)) to sample the ground at each point. When no elevations are available the alignment is flat (z = 0). The profile is a single straight grade; add crest/sag VerticalProfile PVIs later for a real vertical curve.

elevation_at(station_ft: float) float[source]

Profile elevation at station (0.0 with no profile).

property end_station: float
frame_at(station_ft: float) dict[source]

Local frame at station: point (x, y, z), unit tangent and unit right (both plan) for sweeping templates.

property length_ft: float
point_at(station_ft: float, offset_ft: float = 0.0) tuple[float, float, float][source]

3D point at (station, offset). Positive offset is to the right of increasing station; elevation is the centerline profile elevation.

station_offset_of(point: tuple[float, float]) tuple[float, float][source]

Nearest (station, offset) for a plan point (x, y).

Offset is signed (right positive). Ties resolve to the earliest station.

class civilpy.transportation.alignment.Curve(radius_ft: float, delta_deg: float, direction: Literal['R', 'L'] = 'R')[source]

Bases: object

A circular arc of radius_ft sweeping delta_deg to the left (direction='L') or right (direction='R').

delta_deg: float
direction: Literal['R', 'L'] = 'R'

"R" (right) or "L".

Type:

Turn direction looking up-station

property hcurve: HorizontalCurve

The underlying HorizontalCurve (for T, L, D, E, M).

property length: float

Arc length R * delta.

radius_ft: float
property sign: int

+1 for a right turn (azimuth increases), -1 for a left turn.

class civilpy.transportation.alignment.Tangent(length_ft: float)[source]

Bases: object

A straight run of length length_ft along the current bearing.

property length: float
length_ft: float
class civilpy.transportation.alignment.VerticalProfile(pvis: list[tuple[float, float, float]])[source]

Bases: object

Elevation as a function of station from a list of PVIs.

pvis is an ordered list of (station_ft, elevation_ft, curve_len_ft). The first and last entries are the profile ends and should use curve_len_ft = 0. Between consecutive PVIs the grade is straight; interior PVIs with a non-zero curve length carry an equal-tangent parabola (built on VerticalCurve).

elevation_at(station_ft: float) float[source]
pvis: list[tuple[float, float, float]]

civilpy.transportation.curves module

Roadway geometric design: vertical (parabolic) and horizontal (circular) curves with the standard plan/profile sketches.

Vertical curves use the equal-tangent parabola: elevations from the grades and curve length, K = L/|A|, and the high/low point where the grade passes through zero. Horizontal curves use the arc definition: T, L, C, E, M from radius and deflection angle, plus the point-mass superelevation relation e + f = V^2/(15 R).

US units: feet, percent grades, mph, degrees.

Examples

A 600-ft crest curve, +3% to -2%, PVI at sta 25+00 el 482.00:

>>> vc = VerticalCurve(g1_pct=3.0, g2_pct=-2.0, length_ft=600.0,
...                    pvi_station_ft=2500.0, pvi_elevation_ft=482.0)
>>> round(vc.k_value, 0)
120.0
>>> round(vc.elevation_at(vc.bvc_station), 2)   # BVC elevation
473.0
>>> sta, el = vc.high_low_point()
>>> station_str(sta), round(el, 2)
('25+60.00', 478.4)
>>> hc = HorizontalCurve(radius_ft=1145.92, delta_deg=24.0,
...                      pi_station_ft=11500.0)
>>> round(hc.tangent_ft, 1), round(hc.length_ft, 1)
(243.6, 480.0)
>>> round(hc.degree_of_curve_deg, 1)
5.0
class civilpy.transportation.curves.HorizontalCurve(radius_ft: float, delta_deg: float, pi_station_ft: float = 0.0)[source]

Bases: object

Simple circular curve (arc definition) with deflection angle delta_deg between tangents.

property chord_ft: float

Long chord C = 2R sin(delta/2).

property degree_of_curve_deg: float

Arc-definition degree of curve, D = 100 ft / R in degrees.

property external_ft: float

E = R (sec(delta/2) - 1), PI to curve midpoint.

property length_ft: float

Arc length L = R*delta.

property middle_ordinate_ft: float

M = R (1 - cos(delta/2)), chord to curve midpoint.

static min_radius(speed_mph: float, e_max: float, f_max: float) float[source]

Point-mass minimum radius R = V^2 / (15 (e + f)).

property pc_station: float
plot(ax=None, n: int = 200)[source]

Plan view with the back tangent entering along +x: tangents dashed to the PI, the curve arc, and PC/PI/PT labeled with their stations. Returns the figure.

property pt_station: float

PC + L (not PI + T).

Type:

PT runs along the arc

side_friction_demand(speed_mph: float, superelevation: float) float[source]

Friction factor the curve demands at speed_mph with cross slope superelevation (ft/ft): f = V^2/(15 R) - e.

property tangent_ft: float

T = R tan(delta/2).

class civilpy.transportation.curves.VerticalCurve(g1_pct: float, g2_pct: float, length_ft: float, pvi_station_ft: float = 0.0, pvi_elevation_ft: float = 0.0)[source]

Bases: object

Equal-tangent parabolic vertical curve between grades g1_pct and g2_pct (percent, signed), centered on the PVI.

property a_pct: float

Algebraic grade difference A = g2 - g1 (percent); negative for a crest, positive for a sag.

property bvc_elevation: float
property bvc_station: float
elevation_at(station_ft: float) float[source]

Profile elevation: on the tangents outside BVC/EVC, on the parabola between them.

property evc_elevation: float
property evc_station: float
external_distance() float[source]

Offset from the PVI to the curve, e = A*L/800 (ft).

grade_at(station_ft: float) float[source]

Instantaneous grade (percent) along the curve.

high_low_point() tuple[float, float] | None[source]

(station, elevation) of the curve’s high (crest) or low (sag) point — None when the grades don’t change sign.

property is_crest: bool
property k_value: float

K = L/|A| — feet of curve per percent grade change.

plot(ax=None, n: int = 200)[source]

Profile view: tangents dashed, curve solid, BVC/PVI/EVC and the high/low point labeled with stations. Returns the figure.

civilpy.transportation.curves.station_str(station_ft: float) str[source]

Format feet as a roadway station: 2560.0 -> ‘25+60.00’.

civilpy.transportation.roadway module

AASHTO roadway geometric and roadside design functions.

Sight distance, vertical-curve length, superelevation transition, and roadside-barrier length-of-need calculations from AASHTO A Policy on Geometric Design of Highways and Streets (the “Green Book”) and the Roadside Design Guide (RDG). These complement the curve geometry in civilpy.transportation.curves.

Only equations and the standard design-control tables are reproduced here (no policy prose). The design tables (SSD, crest/sag K) are cross-checked against their generating equations in the test suite.

US customary units throughout: speeds in mph, distances in feet, grades as a decimal (0.04 = 4%) unless a name says _pct, cross slopes / relative gradients as a decimal.

civilpy.transportation.roadway.DEFAULT_DECELERATION = 11.2

AASHTO default deceleration for sight-distance braking, ft/s^2 (Green Book): a comfortable deceleration most drivers can achieve.

civilpy.transportation.roadway.DEFAULT_REACTION_TIME = 2.5

AASHTO default brake-reaction time for SSD, seconds.

civilpy.transportation.roadway.DRIVER_EYE_HEIGHT = 3.5

Driver eye height and object heights for crest curves, feet (Green Book).

civilpy.transportation.roadway.FLARE_RATE_RIGID = {40: 13, 45: 16, 50: 18, 55: 18, 60: 20, 65: 22, 70: 24, 75: 26, 80: 26}

lateral) inside the shy line by design speed (Roadside Design Guide Table 5-7), rigid barriers.

Type:

Suggested barrier flare rates (longitudinal

civilpy.transportation.roadway.G_FT_S2 = 32.2

Standard gravitational acceleration, ft/s^2.

civilpy.transportation.roadway.K_CREST = {15: 3, 20: 7, 25: 12, 30: 19, 35: 29, 40: 44, 45: 61, 50: 84, 55: 114, 60: 151, 65: 193, 70: 247, 75: 312, 80: 384}

Design crest-curve rate of vertical curvature K = L/A for SSD, ft per percent (Green Book Table 3-34, rounded).

civilpy.transportation.roadway.K_SAG = {15: 10, 20: 17, 25: 26, 30: 37, 35: 49, 40: 64, 45: 79, 50: 96, 55: 115, 60: 136, 65: 157, 70: 181, 75: 206, 80: 231}

Design sag-curve rate of vertical curvature K = L/A for SSD, ft per percent (Green Book Table 3-36, rounded).

civilpy.transportation.roadway.MAX_RELATIVE_GRADIENT_PCT = {15: 0.78, 20: 0.74, 25: 0.7, 30: 0.66, 35: 0.62, 40: 0.58, 45: 0.54, 50: 0.5, 55: 0.47, 60: 0.45, 65: 0.43, 70: 0.4, 75: 0.38, 80: 0.35}

Maximum relative gradient between profile of edge and centerline, percent, by design speed (Green Book Table 3-15).

civilpy.transportation.roadway.PSD_DESIGN = {20: 400, 25: 450, 30: 500, 35: 550, 40: 600, 45: 700, 50: 800, 55: 900, 60: 1000, 65: 1100, 70: 1200, 75: 1300, 80: 1400}

Design passing sight distance for two-lane highways, ft (Green Book Table 3-4, 2011/2018).

civilpy.transportation.roadway.SSD_DESIGN = {15: 80, 20: 115, 25: 155, 30: 200, 35: 250, 40: 305, 45: 360, 50: 425, 55: 495, 60: 570, 65: 645, 70: 730, 75: 820, 80: 910}

Design stopping sight distance on level grade, ft (Green Book Table 3-1).

civilpy.transportation.roadway.barrier_length_of_need(runout_length: float, lateral_extent: float, barrier_offset: float, flare_rate: float | None = None, back_offset: float | None = None) float[source]

Length of need X (ft) of a roadside barrier upstream of a hazard (Roadside Design Guide length-of-need method).

runout_length LR is the runout length for the design speed/volume (RDG Table 5-39), lateral_extent LA the distance from the edge of the travelled way to the far side of the area of concern, and barrier_offset L1 the lateral offset of the barrier at the hazard.

For a barrier parallel to the road (flare_rate=None): X = LR (LA - L1) / LA.

For a flared barrier give flare_rate as the longitudinal:lateral run b/a and back_offset L2 (lateral offset where the barrier meets the length of need): X = (LA + (b/a) L2 - L1) / ((b/a) + LA/LR).

civilpy.transportation.roadway.braking_distance(speed_mph: float, friction: float | None = None, grade: float = 0.0, deceleration: float = 11.2) float[source]

Braking distance (ft) from speed_mph.

With friction given, uses d = V^2 / (30 (f +/- G)); otherwise uses the AASHTO deceleration form d = V^2 / (30 (a/g +/- G)). grade is a decimal, positive uphill (which shortens braking).

civilpy.transportation.roadway.crest_curve_length(a_pct: float, sight_distance: float, h1: float = 3.5, h2: float = 2.0) float[source]

Minimum crest vertical-curve length (ft), Green Book Eq. 3-43/3-44.

a_pct is the algebraic grade difference |G2 - G1| in percent. Uses the larger of the two branches so the result is valid whether the sight distance is shorter or longer than the curve.

civilpy.transportation.roadway.decision_sight_distance(speed_mph: float, maneuver: str) float[source]

Decision sight distance (ft), Green Book Eq. 3-3/3-4.

maneuver is one of the five avoidance maneuvers:

"A" stop on rural road, "B" stop on urban road (both DSD = 1.47 V t + braking); "C" / "D" / "E" speed/path/ direction change on rural / suburban / urban roads (DSD = 1.47 V t, pre-maneuver + maneuver time).

civilpy.transportation.roadway.intersection_sight_distance(speed_mph_major: float, time_gap: float) float[source]

Intersection sight distance along the major road (ft), Green Book Eq. 9-1: ISD = 1.47 V_major t_g. time_gap (s) is the critical gap for the maneuver (e.g. 7.5 s left turn from stop, passenger car).

civilpy.transportation.roadway.min_radius(speed_mph: float, e_max: float, f_max: float) float[source]

Minimum horizontal curve radius (ft), Green Book Eq. 3-8: R = V^2 / (15 (e_max + f_max)). e_max/f_max are decimals.

civilpy.transportation.roadway.runoff_adjustment_factor(lanes_rotated: float) float[source]

Adjustment factor bw for multilane rotation (Green Book Table 3-16): bw = (1 + 0.5 (n1 - 1)) / n1.

civilpy.transportation.roadway.sag_curve_length(a_pct: float, sight_distance: float) float[source]

Minimum sag vertical-curve length (ft) by the headlight-sight- distance criterion, Green Book Eq. 3-47/3-48 (headlight height 2.0 ft, 1-degree upward beam): denominator 400 + 3.5 S.

civilpy.transportation.roadway.stopping_sight_distance(speed_mph: float, grade: float = 0.0, reaction_time: float = 2.5, deceleration: float = 11.2) float[source]

Stopping sight distance (ft), Green Book Eq. 3-1/3-2.

SSD = 1.47 V t + V^2 / (30 (a/g +/- G)). grade decimal, positive uphill.

civilpy.transportation.roadway.superelevation_runoff_length(superelevation: float, lane_width: float, lanes_rotated: float, max_relative_gradient: float, adjustment_factor: float = 1.0) float[source]

Superelevation runoff length Lr (ft), Green Book Eq. 3-23.

Lr = (w n1 ed / Delta) bw, where superelevation ed and the max_relative_gradient Delta are decimals (use the Table 3-15 value divided by 100), lane_width w in feet, lanes_rotated n1, and adjustment_factor bw (Table 3-16, = (1 + 0.5(n1-1))/n1 for the common case).

civilpy.transportation.roadway.tangent_runout_length(runoff_length: float, superelevation: float, normal_cross_slope: float) float[source]

Tangent runout length Lt (ft), Green Book Eq. 3-24: Lt = (eNC / ed) Lr.

civilpy.transportation.roadway.vertical_curve_length_from_k(k: float, a_pct: float) float[source]

Curve length L = K*|A| (ft) from a design K value and the grade difference in percent.

civilpy.transportation.terrain module

Terrain: a source-agnostic ground surface that answers elevation_at.

The bridge/analysis pipeline places objects by station and offset along an Alignment; the vertical position of anything that meets grade (abutment seats, wingwall foreslopes, footing cutoff, approach grades) comes from the ground surface, which this object models as a triangulated irregular network (TIN).

The query core (elevation_at by barycentric interpolation over the TIN) is pure numpy + scipy so it runs and tests anywhere. The heavier ingestion paths are lazy:

  • from_las() reads OGRIP LiDAR .las/.laz (imports laspy only when called) — the early-design / demo source.

  • from_landxml() reads a survey-shot TIN (LandXML Surface) with its own faces/breaklines — the Stage-3 production source.

  • to_open3d_mesh() exports a mesh (imports open3d only when called).

Coordinates are (x=East, y=North, z=Elevation) in feet, matching civilpy.transportation.alignment.

Examples

>>> import numpy as np
>>> # a plane tilted 2% east, 1% north, sampled on a coarse grid
>>> gx, gy = np.meshgrid(np.linspace(0, 100, 6), np.linspace(0, 100, 6))
>>> z = 500.0 + 0.02 * gx + 0.01 * gy
>>> pts = np.column_stack([gx.ravel(), gy.ravel(), z.ravel()])
>>> t = Terrain.from_points(pts)
>>> round(t.elevation_at(50.0, 50.0), 6)      # 500 + 1.0 + 0.5
501.5
>>> t.elevation_at(-10.0, 50.0) is None        # outside the hull
True
class civilpy.transportation.terrain.BboxPicker(center=(40.004, -83.005), zoom=14, height='480px')[source]

Bases: object

Interactive notebook map for picking a WGS84 bounding box.

Draw a rectangle on the map and .bbox holds (xmin, ymin, xmax, ymax) in decimal degrees (lon, lat) — the tuple Terrain.from_ogrip() and Terrain.from_ohio_dem() take. Drawing a new rectangle replaces the previous pick. Displaying the picker (last expression in a cell) shows the map; a corner readout updates live so the chosen bbox is also visible on screen.

Navigation: hybrid imagery by default — Esri satellite with Esri’s transparent road and place-label reference tiles on top (both can be unticked, and a plain streets base map selected, from the layer toggle at top right) — plus scroll-wheel zoom, a fullscreen control, and a search box (top left, Nominatim) that flies to a typed address or place name — the quick way to land on a jobsite before drawing the rectangle.

Requires ipyleaflet (pip install ipyleaflet), which gives the two-way widget link a static folium map cannot: the drawn geometry lands in the Python kernel with no copy/paste.

class civilpy.transportation.terrain.Terrain(points, faces=None)[source]

Bases: object

A triangulated ground surface.

Parameters:
  • points (array_like) – (N, 3) array of (x, y, z) ground points, feet.

  • faces (array_like, optional) – (M, 3) triangle vertex indices (a supplied TIN, e.g. from a survey with breaklines). When omitted the XY projection is Delaunay-triangulated.

OH_DEM_IMAGESERVER = 'https://gis.ohiodnr.gov/image/rest/services/OH_DEM_test/ImageServer'

Ohio DNR statewide DEM (OSIP LiDAR-derived, 2.5 ft, F32), an ArcGIS ImageServer that returns real elevations by query – no gigabyte tile downloads. Native SR is EPSG:3754 (NAD83 Ohio South State Plane, ft).

OH_DEM_SR = 3754
property bounds: tuple[float, float, float, float]

(xmin, ymin, xmax, ymax) of the point set.

clip_to_bbox(xmin: float, ymin: float, xmax: float, ymax: float) Terrain[source]

Return a new re-triangulated Terrain of the points inside the box (used to keep just the project corridor).

clip_to_corridor(alignment, half_width_ft: float, *, step_ft: float = 25.0) Terrain[source]

Return a new Terrain of points within half_width_ft of the alignment (a station-sampled corridor), for trimming LiDAR to a site.

elevation_along(alignment, station_ft: float, offset_ft: float = 0.0) float | None[source]

Ground elevation at (station, offset) on alignment.

elevation_at(x: float, y: float) float | None[source]

Ground elevation at plan (x, y) by barycentric interpolation on the TIN; None when the point is outside the triangulated area.

classmethod from_landxml(path, *, surface: str | None = None) Terrain[source]

Build from a LandXML Surface TIN (survey deliverable).

Honors the supplied faces (breaklines preserved). LandXML point coordinates are northing easting elevation; they are stored as (easting, northing, elevation). Faces are 1-indexed; faces with a negative index (LandXML’s deleted/invisible marker) are dropped.

classmethod from_las(path, *, ground_only: bool = True, bbox=None, thin: int = 1, preprocess: bool = False, voxel_size: float | None = None, nb_neighbors: int = 20, std_ratio: float = 2.0) Terrain[source]

Build from an OGRIP LiDAR .las/.laz file (lazy laspy).

ground_only keeps only ASPRS class 2 (ground) returns; bbox is an optional (xmin, ymin, xmax, ymax) clip; thin keeps every thin-th point to cap density.

If preprocess is True, use Open3D for statistical outlier removal and voxel downsampling (requires open3d).

classmethod from_ogrip(bbox_wgs84, out_dir='temp_las', **kwargs) Terrain[source]

Fetch OGRIP/3DEP LiDAR tiles for a WGS84 bbox and build a Terrain.

Requires requests. Tiles are ZIP archives (~50-120 MB each, holding one LAS) downloaded to out_dir and extracted there; both survive for reuse on the next call. When flights overlap (OSIP and 3DEP cover the same ground) only the newest collection year is used. Remaining kwargs are passed to from_las().

classmethod from_ohio_dem(bbox, *, spacing_ft: float = 50.0, wgs84: bool = True, service: str | None = None, chunk: int = 400) Terrain[source]

Build a Terrain from real Ohio LiDAR by sampling the ODNR OH_DEM ImageServer over bbox – the practical alternative to downloading LAS tiles.

Parameters:
  • bbox (tuple) – (xmin, ymin, xmax, ymax). When wgs84 (default) these are longitude/latitude degrees, projected to Ohio South State Plane feet (EPSG:3754, pyproj required); otherwise they are already in EPSG:3754 feet.

  • spacing_ft (float) – Grid spacing of the elevation samples, feet.

  • service (str, optional) – Override the ImageServer URL (defaults to OH_DEM_IMAGESERVER).

  • chunk (int) – Points per getSamples request (batched multipoint POST).

Returns:

Points (easting_ft, northing_ft, elevation_ft) in EPSG:3754 – a feet frame consistent with the rest of the bridge stack. Cells the DEM marks NoData are dropped.

Return type:

Terrain

Notes

Requires requests (and pyproj when wgs84). Needs network access to the ODNR service; unlike from_ogrip there is no local file, so keep it out of import-time paths.

classmethod from_points(points, faces=None) Terrain[source]

Build from an (N, 3) array of ground points.

classmethod from_xyz_file(path, *, skiprows: int = 0, cols: tuple[int, int, int] = (0, 1, 2)) Terrain[source]

Build from a whitespace/CSV .xyz/.txt file of point rows.

property n_points: int
property n_triangles: int
profile(alignment, stations, offset_ft: float = 0.0) list[source]

Ground elevations along alignment at each of stations.

to_open3d_mesh(poisson: bool = False, depth: int = 9)[source]

Build an open3d triangle mesh (lazy import) for display/Rhino.

If poisson is True, use Poisson Surface Reconstruction instead of the internal TIN (good for noisy LiDAR; requires depth parameter).

civilpy.transportation.terrain.bbox_picker(center=(40.004, -83.005), zoom=14) BboxPicker[source]

A BboxPicker centered on center (lat, lon) — display it, draw a rectangle, then read picker.bbox.

Module contents

Transportation engineering package.

Roadway geometric design (roadway), horizontal/vertical curve calculations (curves), and FHWA National Bridge Inventory utilities (civilpy.transportation.FHWA).