Spots ↔ FieldSites ↔ Checkins Conversion API
code changes can be view in this PR #251
Base URL: http://dev.macrostrat.org/api/v3/dev
Endpoint: POST /convert/field-site?in=<spot|fieldsite|checkin>&out=<spot|fieldsite|checkin>
Purpose
- This endpoint converts payloads between StraboSpot, FieldSite, and Rockd Checkin formats.
- Conversions are selected using the
in and out query params.
Supported Conversions
in=spot&out=fieldsite returns list[FieldSite].
in=spot&out=checkin returns list[checkin].
in=fieldsite&out=checkin returns list[checkin].
in=fieldsite&out=spot returns a GeoJSON FeatureCollection.
in=checkin&out=fieldsite returns list[FieldSite].
in=checkin&out=spot returns a GeoJSON FeatureCollection.
- Any other
in/out pair returns 400 with a string detail.
- Unsupported conversions return 400 with
detail as a string.
- Successful conversions may return an empty list (for example, if all Spot features are skipped).
- Invalid items inside a list are silently skipped rather than returning an error.
Input Shapes
- Spot input may be a
FeatureCollection, a single Feature, or a list of FeatureCollection|Feature.
- Checkin input may be a single dict or a list of dicts.
- FieldSite input may be a single FieldSite dictionaries or a list of FieldSite dictionaries.
Spot → FieldSite (in=spot&out=fieldsite)
- Only GeoJSON features with
geometry.type == "Point" are converted.
- Any feature with
properties.image_basemap (image-annotation points) is skipped.
- Any feature missing
properties.id is skipped.
- Any feature with invalid coordinates is skipped.
- Coordinates use
properties.lat/lng if present, otherwise they are read from geometry.coordinates as [lng, lat].
created is parsed from properties.time or properties.date, otherwise it defaults to “now” in UTC.
updated is parsed from properties.modified_timestamp (milliseconds), otherwise it falls back to created.
notes comes from properties.notes.
- If
properties.images exists, only the first image is mapped to photos[0] as rockd://photo/<id>.
- If
properties.orientation_data contains a planar orientation, only the first valid {strike, dip} is mapped to observations[0].data.
- The planar facing is always set to
"upright".
Spot → Checkin (in=spot&out=checkin)
- This path uses
Spot → FieldSite → Checkin.
- If the payload is already a converted FieldSite, it skips Spot parsing and converts directly to checkins.
fieldsite.location assumes there is only one fieldsite object in the request. fieldsite[i].location assumes there are i fieldsite objects in the request body.
FieldSite → Checkin (in=fieldsite&out=checkin)
- If the request body is a list, the response is a list of checkins.
- If the request body is a single dict, the response is a list of one checkin.
- Each output checkin includes both
checkin_id and spot_id, and both are set to FieldSite.id.
lat/lng are taken from FieldSite.location.latitude/longitude.
created and added are formatted as strings like "October 19, 2023".
- If
photos exists, only photos[0].id is mapped to photo.
- If a planar observation exists, only the first planar is mapped to
observations = [{"orientation": {"strike": ..., "dip": ...}}].
- If no planar exists,
observations is an empty list.
FieldSite → Spot (in=fieldsite&out=spot)
- The response is always a GeoJSON
FeatureCollection.
- A single FieldSite input returns a
FeatureCollection with one Feature.
- A list of FieldSites returns a
FeatureCollection with one Feature per FieldSite.
- Each feature is a Point with coordinates
[longitude, latitude].
properties.id is set to FieldSite.id.
properties.time and properties.date are emitted as ISO strings ending in Z.
properties.modified_timestamp is emitted in milliseconds from updated.
properties.lat/lng are also included.
- If
photos exists, only the first photo is mapped into properties.images[0].
- If a planar observation exists, only the first planar is mapped into
properties.orientation_data[0].
Checkin → FieldSite (in=checkin&out=fieldsite)
- A single checkin dict returns a list of one FieldSite.
- A list of checkins returns a list of FieldSites.
FieldSite.id is set from checkin.checkin_id.
- Location is set from
checkin.lat and checkin.lng.
created is parsed from checkin.created and accepts ISO strings or "Month DD, YYYY", otherwise it defaults to “now” in UTC.
updated is parsed from checkin.added, otherwise it falls back to created.
notes comes from checkin.notes.
- If
photo is an int, it becomes photos[0] with a rockd://photo/<id> URL.
- If
observations contains an orientation with numeric strike/dip, only the first valid one becomes [observations[0].data.]
- The planar facing is always set to
"upright".
Checkin → Spot (in=checkin&out=spot)
- This path uses
Checkin → FieldSite → Spot.
- If one checkin is provided, the output FeatureCollection contains one feature.
- If multiple checkins are provided, the output FeatureCollection contains multiple features, matching the Strabospot data structure.
Spots ↔ FieldSites ↔ Checkins Conversion API
code changes can be view in this PR #251
Base URL:
http://dev.macrostrat.org/api/v3/devEndpoint:
POST /convert/field-site?in=<spot|fieldsite|checkin>&out=<spot|fieldsite|checkin>Purpose
inandoutquery params.Supported Conversions
in=spot&out=fieldsitereturnslist[FieldSite].in=spot&out=checkinreturnslist[checkin].in=fieldsite&out=checkinreturnslist[checkin].in=fieldsite&out=spotreturns a GeoJSONFeatureCollection.in=checkin&out=fieldsitereturnslist[FieldSite].in=checkin&out=spotreturns a GeoJSONFeatureCollection.in/outpair returns 400 with a stringdetail.detailas a string.Input Shapes
FeatureCollection, a singleFeature, or a list ofFeatureCollection|Feature.Spot → FieldSite (
in=spot&out=fieldsite)geometry.type == "Point"are converted.properties.image_basemap(image-annotation points) is skipped.properties.idis skipped.properties.lat/lngif present, otherwise they are read fromgeometry.coordinatesas[lng, lat].createdis parsed fromproperties.timeorproperties.date, otherwise it defaults to “now” in UTC.updatedis parsed fromproperties.modified_timestamp(milliseconds), otherwise it falls back tocreated.notescomes fromproperties.notes.properties.imagesexists, only the first image is mapped tophotos[0]asrockd://photo/<id>.properties.orientation_datacontains a planar orientation, only the first valid{strike, dip}is mapped toobservations[0].data."upright".Spot → Checkin (
in=spot&out=checkin)Spot → FieldSite → Checkin.fieldsite.locationassumes there is only one fieldsite object in the request.fieldsite[i].locationassumes there areifieldsite objects in the request body.FieldSite → Checkin (
in=fieldsite&out=checkin)checkin_idandspot_id, and both are set toFieldSite.id.lat/lngare taken fromFieldSite.location.latitude/longitude.createdandaddedare formatted as strings like"October 19, 2023".photosexists, onlyphotos[0].idis mapped tophoto.observations = [{"orientation": {"strike": ..., "dip": ...}}].observationsis an empty list.FieldSite → Spot (
in=fieldsite&out=spot)FeatureCollection.FeatureCollectionwith oneFeature.FeatureCollectionwith oneFeatureper FieldSite.[longitude, latitude].properties.idis set toFieldSite.id.properties.timeandproperties.dateare emitted as ISO strings ending inZ.properties.modified_timestampis emitted in milliseconds fromupdated.properties.lat/lngare also included.photosexists, only the first photo is mapped intoproperties.images[0].properties.orientation_data[0].Checkin → FieldSite (
in=checkin&out=fieldsite)FieldSite.idis set fromcheckin.checkin_id.checkin.latandcheckin.lng.createdis parsed fromcheckin.createdand accepts ISO strings or"Month DD, YYYY", otherwise it defaults to “now” in UTC.updatedis parsed fromcheckin.added, otherwise it falls back tocreated.notescomes fromcheckin.notes.photois an int, it becomesphotos[0]with arockd://photo/<id>URL.observationscontains anorientationwith numericstrike/dip, only the first valid one becomes [observations[0].data.]"upright".Checkin → Spot (
in=checkin&out=spot)Checkin → FieldSite → Spot.