oms

package
v1.0.0-beta.73 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package oms provides the OGC OMS v3.0 Observation document payload type for SemStreams. It is the bidirectional mapper between OMS-natural JSON (the wire shape every Connected Systems API consumer exchanges) and the SemStreams message.BaseMessage envelope that downstream processors route through the payload registry.

What it ships

  • Observation — the OGC OMS v3.0 Observation Go struct. Implements message.Payload (Schema / Validate / MarshalJSON / UnmarshalJSON) and [graph.Graphable] (EntityID / Triples).
  • FeatureOfInterest — accepts either a URI reference or an inline GeoJSON Feature (via Phase 3 graph/geo/geojson).
  • RegisterPayloads — registers ogc.oms.v3 with the payload registry. Aggregated into payloadbuiltins so every production binary picks it up automatically.

Schema identity

The payload Schema is fixed at Type{Domain: "ogc", Category: "oms", Version: "v3"} — abbreviated as "ogc.oms.v3" in registry diagnostics and reactive-rule predicate matching.

Wire shape

Observation.MarshalJSON emits the OMS-natural JSON document per OGC 20-082r4 bundled with CS API v1.0:

{
    "type": "Observation",
    "id": "observation-7f3a",
    "procedure": "http://example.org/procedures/voltmeter",
    "observedProperty": "http://example.org/properties/voltage",
    "featureOfInterest": "http://example.org/features/battery-001",
    "phenomenonTime": "2026-05-15T14:30:00Z",
    "resultTime": "2026-05-15T14:30:00Z",
    "result": 12.4
}

The BaseMessage envelope around an Observation places that JSON in the "payload" field of the SemStreams [message.wireFormat], so the same OMS-natural bytes flow through internal NATS publishes via message.NewDecoder without re-encoding.

Scope

MVP coverage targets the CS API v1.0 critical path:

  • Result as a simple JSON value (number, string, boolean). Quantity (value + uom), Category, and TimeSeries result shapes are deferred — operators producing typed results today should bind their UoM via the SensorML side (Phase 5) or via downstream processors.
  • PhenomenonTime / ResultTime as ISO 8601 instants only. Time intervals ({begin, end}) deferred.
  • FeatureOfInterest as either a URI reference or an inline GeoJSON Feature. Other OGC reference shapes deferred.
  • Parameter, ValidTime, ResultQuality, RelatedObservation — all deferred. Operators needing these should file a follow-up.

See [ADR-044] for the framework / sister-repo split rationale and the dependency chain that places this package in Phase 6.

External references

[graph.Graphable]: ../../graph [ADR-044]: ../../docs/adr/044-ogc-connected-systems-framework-split.md

Index

Constants

View Source
const (
	// PredType is the rdf:type assertion (sosa:Observation IRI).
	PredType = "oms.observation.type"

	// PredHasFeatureOfInterest binds the observation to the
	// SOSA FeatureOfInterest it is about. Maps to
	// sosa:hasFeatureOfInterest.
	PredHasFeatureOfInterest = "oms.observation.hasFeatureOfInterest"

	// PredObservedProperty binds the observation to the SOSA
	// ObservableProperty it measured. Maps to
	// sosa:observedProperty.
	PredObservedProperty = "oms.observation.observedProperty"

	// PredUsedProcedure binds the observation to the SOSA
	// Procedure that produced it. Maps to sosa:usedProcedure.
	PredUsedProcedure = "oms.observation.usedProcedure"

	// PredResultTime carries the ISO 8601 resultTime. Maps to
	// sosa:resultTime.
	PredResultTime = "oms.observation.resultTime"

	// PredPhenomenonTime carries the ISO 8601 phenomenonTime.
	// Maps to sosa:phenomenonTime.
	PredPhenomenonTime = "oms.observation.phenomenonTime"

	// PredHasSimpleResult carries the simple literal Result.
	// Maps to sosa:hasSimpleResult.
	PredHasSimpleResult = "oms.observation.hasSimpleResult"
)

Dotted-name predicate constants for the SemStreams convention. Each is registered to its SOSA IRI at init time so RDF/Turtle export through vocabulary/export emits the compacted sosa: forms. Mirrors parser/sensorml's predicates.go pattern.

View Source
const TypeObservation = "Observation"

TypeObservation is the JSON "type" discriminator value for OMS Observation documents per OGC 20-082r4.

Variables

This section is empty.

Functions

func RegisterPayloads

func RegisterPayloads(reg *payloadregistry.Registry) error

RegisterPayloads registers the ogc.oms.v3 Observation payload with the supplied registry. Called from github.com/c360studio/semstreams/payloadbuiltins.Register at process bootstrap so every production binary picks up the type without extra wiring.

Mirrors the message.RegisterPayloads / agentic.RegisterPayloads shape so the bootstrap aggregator can call this uniformly.

func SchemaType

func SchemaType() message.Type

SchemaType returns the registered payload type for OMS Observations. Useful for callers building a BaseMessage without first constructing the Observation struct.

Types

type FeatureOfInterest

type FeatureOfInterest struct {
	// Href is set when the FoI is a bare URI reference.
	Href string

	// Feature is set when the FoI is an inline GeoJSON Feature.
	Feature *geojson.Feature
}

FeatureOfInterest is either a URI reference to an external feature definition or an inline GeoJSON Feature carrying the spatial extent. Marshaling produces the URI string for the URI case and the GeoJSON object for the inline case; unmarshaling detects the shape and populates the right field.

func NewFeatureOfInterestFeature

func NewFeatureOfInterestFeature(f *geojson.Feature) *FeatureOfInterest

NewFeatureOfInterestFeature constructs an inline-GeoJSON FeatureOfInterest.

func NewFeatureOfInterestRef

func NewFeatureOfInterestRef(uri string) *FeatureOfInterest

NewFeatureOfInterestRef constructs a URI-shaped FeatureOfInterest.

func (*FeatureOfInterest) MarshalJSON

func (f *FeatureOfInterest) MarshalJSON() ([]byte, error)

MarshalJSON emits either the bare URI string or the inline GeoJSON Feature shape, depending on which field is populated. When both are populated, Feature wins (the inline payload is strictly more informative). When neither is populated, emits JSON null.

func (*FeatureOfInterest) UnmarshalJSON

func (f *FeatureOfInterest) UnmarshalJSON(data []byte) error

UnmarshalJSON dispatches on the JSON shape: a bare string becomes the Href; a JSON object becomes the inline Feature. JSON null leaves the value unset.

type Observation

type Observation struct {
	// ID is the local identifier for the observation. Required
	// when downstream consumers need to address the observation
	// individually; OMS itself does not mandate it.
	ID string `json:"id,omitempty"`

	// Procedure is the IRI of the SOSA Procedure / SensorML
	// process that produced the observation.
	Procedure string `json:"procedure"`

	// ObservedProperty is the IRI of the SOSA ObservableProperty
	// being measured.
	ObservedProperty string `json:"observedProperty"`

	// FeatureOfInterest is either a URI reference or an inline
	// GeoJSON Feature carrying the spatial extent.
	FeatureOfInterest *FeatureOfInterest `json:"featureOfInterest,omitempty"`

	// PhenomenonTime is the time the phenomenon being observed
	// occurred (ISO 8601 instant). Optional — when absent OMS
	// permits consumers to fall back to ResultTime.
	PhenomenonTime string `json:"phenomenonTime,omitempty"`

	// ResultTime is the time the result was produced (ISO 8601
	// instant). Required by OMS for every Observation.
	ResultTime string `json:"resultTime"`

	// Result is the observed value. Phase 6 MVP carries it as a
	// plain JSON value (number, string, boolean). Quantity,
	// Category, and TimeSeries results are deferred to follow-
	// up tags.
	//
	// JSON round-trip canonicalizes all numeric results to
	// float64 per encoding/json's default. Operators producing
	// integer-valued OMS results that need to preserve int64
	// fidelity through a round-trip should either (a) emit the
	// result as a string and convert at consumption, or (b)
	// wait for the typed Quantity / Category result envelopes
	// that land in a follow-up tag.
	Result any `json:"result,omitempty"`
}

Observation is the OGC OMS v3.0 Observation document. Fields mirror the JSON encoding bundled with CS API v1.0. Pointer- typed optional fields distinguish "absent" from "empty".

The struct implements message.Payload (see payload.go) and [graph.Graphable] (see graphable.go) so it can be carried by a BaseMessage envelope and contribute triples to the graph pipeline.

func (*Observation) EntityID

func (o *Observation) EntityID() string

EntityID implements [graph.Graphable]. Returns the Observation's local ID — operators routing through the graph pipeline are expected to either populate the ID field with a 6-part SemStreams entity ID or rebind via a wrapping payload. Returns the empty string when ID is unset; downstream graph-ingest treats that as "no entity," which is the right fall-through for ingest pipelines doing entity resolution from triples instead of the local ID.

func (*Observation) MarshalJSON

func (o *Observation) MarshalJSON() ([]byte, error)

MarshalJSON emits the OMS-natural JSON document shape per OGC 20-082r4. OMS v3.0 carries a "type" discriminator on the wire for forward-compatibility with sibling shapes (Sample, ObservationCollection, …) that this Go package does not yet implement; the constant is emitted unconditionally because the Go type can only represent the Observation case. Avoids the infinite-recursion footgun by aliasing.

func (*Observation) Schema

func (o *Observation) Schema() message.Type

Schema implements message.Payload. Always returns ogc.oms.v3.

func (*Observation) Triples

func (o *Observation) Triples() []message.Triple

Triples implements [graph.Graphable]. Emits the SOSA-aligned triple set for this observation:

  • rdf:type → sosa:Observation
  • sosa:usedProcedure → procedure IRI
  • sosa:observedProperty → property IRI
  • sosa:hasFeatureOfInterest → FoI IRI (URI ref case) or a synthetic inline-Feature subject (deferred)
  • sosa:resultTime → ISO 8601 timestamp
  • sosa:phenomenonTime → ISO 8601 timestamp (when present)
  • sosa:hasSimpleResult → the literal result value

Inline-GeoJSON FoIs emit a single hasFeatureOfInterest triple pointing at the GeoJSON Feature's id (or empty when the Feature has no id). Richer per-Feature triples would require a second-pass entity emission and are deferred — the graph pipeline can pick up the inline Feature via a dedicated processor.

func (*Observation) UnmarshalJSON

func (o *Observation) UnmarshalJSON(data []byte) error

UnmarshalJSON parses the OMS-natural JSON document, validating the type discriminator before populating the struct fields.

func (*Observation) Validate

func (o *Observation) Validate() error

Validate implements message.Payload. Enforces OMS v3.0's required fields: Procedure, ObservedProperty, ResultTime. Optional fields with present-but-invalid values surface as validation errors.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL