This is a portolan catalog version of https://developer.trimet.org/gis/ - taking the static data layers there and making them fully cloud-native and interactive.
Public transit rail lines. Includes existing, under construction, and planned MAX, WES, and Portland Streetcar lines. The data have been generalized to improve cartographic display at smaller scales. 171 LineString features, WGS84, one GeoParquet file of 89.6 KB in 1 row group(s).
Reads stream over HTTP range requests — query in place, do not download. The file
is Hilbert-ordered and carries a GeoParquet 1.1 bbox covering column, so a
spatial filter on geometry_bbox prunes row groups from metadata alone. Note
the column name: GDAL writes the covering as <geometry column>_bbox, so it is
geometry_bbox here, not bbox.
The recipes below use bare relative paths ('rail-lines/rail-lines.parquet') for
readability. Prefix them with https://data.source.coop/cholmes/trimet/ to run remotely.
Other formats: rail-lines.pmtiles for map display (layer name rail-lines), and TriMet's
original Shapefile and KML, linked from collection.json as source_shapefile
and source_kml.
The GeoParquet is in EPSG:2913 — NAD83(HARN) / Oregon North, international feet — which is what TriMet surveys and publishes in. It is deliberately not reprojected. Only the PMTiles are in WGS84, because vector tiles are Web Mercator by definition.
The practical consequence is a good one: measurements just work, in feet.
Useful conversions: × 0.3048 for metres, ÷ 5280 for miles, ÷ 43560 for acres, ÷ 27878400 for square miles. 400 m is 1312.34 ft, a quarter mile is 1320 ft.
Two things to watch:
GeoJSON consumers — needs a transform first.always_xy := true when you do transform. Without it DuckDB honours
EPSG:4326's authority-declared latitude-first axis order and every result
comes back Infinity:The bbox covering column is in the same feet, so a spatial filter written
against it uses projected coordinates, not degrees. The collection's STAC
extent stays in WGS84, because STAC requires that regardless of the data's own
CRS.
Nothing here carries a pre-computed length or area except the district boundary,
which has TriMet's own area_sq_mi and acres.
BL/NS; the data contains NS/BLTriMet's metadata page lists a code BL/NS ("Portland Streetcar B Loop and
North/South Line"). That string does not occur in the data. What the data
actually carries is NS/BL, on 2 segments here and 12 stops in rail-stops.
Filter on NS/BL. A query written from the published code list alone returns
nothing.
AUX is in the data and in TriMet's code list, but has no style rule7 segments are AUX — "Auxiliary track. No revenue service", i.e. yard leads and
connecting track. TriMet's own SLD has no rule for AUX, so on TriMet's maps
these segments are invisible. This catalog draws them in neutral gray rather than
dropping them, so be aware they will appear where TriMet's maps show nothing.
Exclude AUX when counting revenue track.
Existing right nowstatus documents Existing, Planned and UC (under construction), but all
171 current segments are Existing. Code that branches on status is not wrong,
it is just untested against this snapshot — and the values will reappear as
TriMet adds projects.
line is a set, encoded as a stringThere is no join table. To ask "which segments does the Blue Line touch", you
must match any code containing B as a component, which is not a substring
test — B appears in BL (B Loop, a streetcar) and BGR. The reliable approach
is an explicit list of the codes that include the line you want; see the
recipes.
TriMet's SLD uses #084C8D for the Blue Line; its GTFS route_color is
#1359AE. Both are authentic TriMet values from different systems. This
collection's default.json follows the SLD, because the SLD is the style written
for this layer; by-type.json follows GTFS.
rail-stops — the stations on these lines, sharing the same line codes and colorsroutes — the operational, non-generalized alignment of the same rail serviceTriMet publishes this as tm_rail_lines at
developer.trimet.org/gis, last updated
September 26, 2024. Every column description in collection.json
comes from TriMet's metadata page — that
page, not this catalog, is the authority on what a field means.
Conversion: ogr2ogr -f Parquet -t_srs EPSG:4326 -lco COMPRESSION=ZSTD -lco SORT_BY_BBOX=YES -lco WRITE_COVERING_BBOX=YES, then tippecanoe with -r1 --no-feature-limit so no feature is dropped at any zoom. See
tools/convert.py.
TriMet distributes these datasets free of charge, but the terms of use do not
grant redistribution rights. Section 4 of TriMet's
Terms of Use reserves
reproduction, modification, distribution and republication of site Content
without written consent; the redistribution license in section 5 covers the Web
Services API, not these GIS downloads. The collections therefore declare
"license": "other" with a link to those terms, rather than claiming an open
license the source does not offer.
Practically: use the data, and contact gis@trimet.org before redistributing it or building a product on it. If you need transit data under clear open terms, TriMet's GTFS feed is the better starting point.