Specification

.well File Format Specification — Version 2.4: Interoperability

See also: overview.md · format-reference.md · object-schemas.md · water-quality.md

Overview

This part of the .well v2.4 specification covers how .well connects to other standards and tools: the reserved JSON-LD @context and its publication plan, how the format maps onto the OGC GroundWaterML 2 (GWML2) model, and validating files against the published JSON Schema.

Table of contents


JSON-LD Context (Reserved)

The @context top-level field is reserved for JSON-LD interoperability with semantic web tooling and external standards such as GWML2. See § Relationship to GWML2.

v2.0 parser requirements

  • The @context field is optional.
  • v2.0 parsers MUST preserve the @context field on round-trip, per the foreign-members rule.
  • v2.0 parsers MUST NOT reject files that include or omit the field.
  • v2.0 parsers are NOT required to interpret the field as JSON-LD. No semantic processing is mandated by this version of the spec.

A .well file MAY include "@context": "https://welldot.org/context/v2.jsonld" to assert that the file's field names map to the canonical .well v2 JSON-LD context. Tools that understand JSON-LD can then transform the document into RDF for use with SPARQL, triple stores, or GWML2-conformant pipelines.

Context publication plan

The canonical context is staged across six phases (0–5). Each phase publishes a real, fetchable document at the canonical URL — at no phase is the URL a placeholder.

Phase 0 — Reservation (v2.0 ratification)

A minimal valid JSON-LD 1.1 document is published at https://welldot.org/context/v2.jsonld containing only the format-identity terms:

{
  "@context": {
    "@version": 1.1,
    "well": "https://welldot.org/vocab/v2#",
    "version": "well:version",
    "name": "well:name",
    "well_type": "well:well_type"
  }
}

The document advertises itself as a draft via an x-welldot-status: reserved HTTP header and an in-band @version marker. This phase reserves the URL and proves it resolves; it does not yet enable meaningful RDF processing.

Phase 1 — Identity & location (v2.0 + 1 month)

Adds mappings for well_id, well_id.authority, well_id.id, well_id.primary, location, location.lat, location.lng, location.elevation, and construction_date. Aliases location.lat/lng to geo:lat/geo:long from the W3C Geo vocabulary; aliases construction_date to schema:dateCreated from Schema.org.

After Phase 1, a .well document round-trips to a minimal valid RDF graph representing the well's identity and position.

Phase 2 — Constructive blocks (v2.0 + 3 months)

Adds mappings for bore_hole, well_case, well_screen, reduction, surface_case, hole_fill, cement_pad and their fields. Where direct GWML2 alignment is verified against the published XSDs, terms alias to the GWML2-WellConstruction namespace; otherwise terms live under the welldot:vocab/v2# namespace with explanatory rdfs:comment annotations.

Phase 3 — Geological & hydrogeological (v2.0 + 6 months)

Adds mappings for lithology, fractures, caves, texture, texture.code, texture.vocabulary. Aliases lithology to gwml:GW_GeologyLogCoverage once the corresponding GWML2 class name is verified against the OGC schema documents.

Phase 4 — Hydrodynamic & analysis (v2.1)

Adds mappings for well_purpose, centralizers, hydrodynamic_events, aquifer_analysis, history_logs, and supporting types (PumpingStep, LevelReading, RecoveryPhase, Attachment). Maps event readings to O&M's OM_Observation pattern and time-series to TimeseriesML where alignment is verified. This phase ships alongside the v2.1 spec revision.

Phase 5 — Operational blocks (v2.3)

Adds mappings for attachments, Attachment.document_type, pump_installations, PumpInstallation and PumpElectrical fields (including installed_by and removed_by), permits (Permit, VolumeLimit, MonthlyGrant, PermitCondition, ConditionFulfillment, PermitHistoryEntry, and the administrative status), meters (Meter, including manufacturer, model, installed_by, removed_by and attachments), production (MeterReading, EstimatedVolume, with production[].corrects), operating_regime (OperatingRegime), the maintenance and status_change log fields, and hydrodynamic_events[].corrects. Permit dates map to xsd:date and condition durations to xsd:duration; supersedes is a succession relation between two instruments, distinct from corrects. corrects maps to a retraction relation between two observation or ledger records; installation, reading and regime instants map to xsd:dateTime; installed_by and removed_by map to the agent of the installation or removal activity (prov:wasAssociatedWith), kept as a plain literal; attachments alias to schema:MediaObject (uri → schema:contentUrl, media_type → schema:encodingFormat, sha256 → schema:sha256). Units bind to QUDT (unit:KiloW, unit:V, unit:MilliM2, unit:M3 for meter readings and volumes, unit:M3-PER-HR for regime flow rates, unit:HR for daily operating time, unit:MilliM for meter nominal diameter). This phase ships alongside the v2.3 spec revision.

The v2.3 water quality terms ship in the same phase: water_samples (WaterSample, SamplingPoint, Purge, PurgeReading, Laboratory, Result, Parameter, Filtration, Validation) and history_logs[].sample_ids. Collection, receipt, analysis and validation instants map to xsd:dateTime; a _resolution: "day" sibling maps the value to xsd:date semantics. Each welldot parameter code gets a term URI under https://welldot.org/vocab/water-quality/ (versioned with the published vocabulary), aligned where verified to the corresponding observable property in QUDT, ChEBI or the SOSA/SSN observable-property pattern. A cas parameter maps to the CAS Common Chemistry URI of its registry number, for example { "code": "71-43-2", "vocabulary": "cas" } → https://commonchemistry.cas.org/detail?cas_rn=71-43-2; a welldot code with a published CAS equivalence carries an owl:sameAs-style link to the same URI. x- vocabularies are left unmapped. Units bind to QUDT (unit:MilliGM-PER-L, unit:MicroS-PER-CentiM, unit:DEG_C, unit:MilliV, unit:BQ-PER-L, unit:MicroM); turbidity, color and microbiological count units without a QUDT term keep their UCUM code as a literal.

Versioning and stability

  • The Phase-0 document is replaced in-place as phases ship, but term URIs under welldot:vocab/v2# are append-only and never re-purposed within v2.
  • If a term needs to change meaning, it gets a new URI in welldot:vocab/v3#. v2 consumers continue to resolve the old term.
  • Each phase increments an internal version marker on the context document; client tools can detect which phase they're consuming.
  • A CHANGELOG.md is published alongside the context at https://welldot.org/context/v2.changelog.md documenting every term added.

Optional fallback

If publishing infrastructure fails, files may inline the context object directly under @context instead of referencing the URL. This is supported by JSON-LD 1.1 and parsers MUST accept both forms.


Relationship to GWML2

GroundWaterML 2 (GWML2) is the OGC international standard for groundwater data exchange. It was developed and ratified by an international consortium that includes the Geological Survey of Canada (GSC), U.S. Geological Survey (USGS), CSIRO and the Bureau of Meteorology (Australia), BRGM (France), Federation University Australia, and Salzburg University, with contributing input from the British Geological Survey, the EU INSPIRE Joint Research Centre, the Polish and German geological surveys, and UNESCO's International Groundwater Resources Assessment Centre.

Two versions of the standard are currently in use:

  • OGC 16-032r2 — WaterML 2: Part 4 — GroundWaterML 2 (GWML2), version 2.2, ratified in 2016 and published in 2017
  • OGC 19-013 — GWML2 version 2.2.1, ratified in 2019 and published in 2021, which updates 16-032r2 by aligning with GeoSciML 4.1 and Observations & Measurements 2.0

GWML2 defines its model in three stages — a conceptual UML schema, a logical UML schema specialized for OGC standards, and an XML/GML encoding — and explicitly anticipates future JSON or RDF encodings. The standard is organized into six modular packages: GWML2-Main, GWML2-Constituent, GWML2-Flow, GWML2-Well, GWML2-WellConstruction, and GWML2-AquiferTest.

.well is a JSON-native format that scopes down to the static record plus operational history of a single well. It is not a competing conceptual model — it is an opinionated encoding for a subset of the GWML2 domain, designed for tooling and developer adoption. The optional JSON-LD @context (see § JSON-LD Context) is the technical bridge that allows a .well document to also be interpreted as a GWML2-aligned RDF graph.

Authoritative references

ReferenceLocation
GWML2 v2.2 specification (16-032r2)https://docs.ogc.org/is/16-032r2/16-032r2.html
GWML2 v2.2.1 specification (19-013)https://docs.ogc.org/is/19-013/19-013.html
GWML2 XML schemas (XSD)http://schemas.opengis.net/gwml/2.2/
OGC Hydrology DWG GWML2 wikihttps://external.ogc.org/twiki_public/HydrologyDWG/

Scope correspondence

GWML2 ModuleNamespace.well coverage
GWML2-Mainhttp://www.opengis.net/gwml-main/2.2Out of scope (aquifers, fluid bodies, hydrogeological units as standalone features)
GWML2-Constituenthttp://www.opengis.net/gwml-constituent/2.2Partially covered (water_samples, v2.3): measured constituents and properties of sampled water
GWML2-Flowhttp://www.opengis.net/gwml-flow/2.2Out of scope (recharge, discharge, inter-flow)
GWML2-Wellhttp://www.opengis.net/gwml-well/2.2Covered: top-level well identity, location, well_id, well-as-sampling-feature semantics
GWML2-WellConstructionhttp://www.opengis.net/gwml-wellconstruction/2.2Covered: bore_hole, well_case, well_screen, reduction, surface_case, hole_fill, cement_pad
GWML2-AquiferTesthttp://www.opengis.net/gwml-aquifertest/2.2Covered: hydrodynamic_events, aquifer_analysis

Conceptual alignment

A .well document corresponds conceptually to a GWML2 GW_Well feature, which itself specializes O&M's SF_SamplingCurve — wells in GWML2 are modeled as sampling features along whose length observations are made. Boreholes (Borehole from GWML2-WellConstruction) are physical engineering artifacts distinct from wells in GWML2; in .well v2, both are collapsed into the constructive blocks of a single record since the format describes one composite well.

A .well Lithology array corresponds to a GWML2 GW_GeologyLogCoverage, which is a realization of CV_DiscreteCoverage over depth intervals. Each lithology interval references a GW_HydrogeologicalUnit — GWML2's specialization of GeoSciML's GeologicUnit — via the geologic_unit field; .well does not model the hydrogeological unit itself as a standalone feature.

Class mapping (informative)

The mapping below is informative, not normative. Class names in italics are verified against published GWML2 documentation (the OGC 16-032r2 specification, the Hydrogeology Journal and Open Geospatial Data, Software and Standards papers, and the OGC Hydrology DWG wiki). Class names marked with ? are approximate — they describe the GWML2 module a .well construct belongs to but the exact class name was not verified at the time of writing this draft. Implementers building converters should verify these against the authoritative XSDs at http://schemas.opengis.net/gwml/2.2/ before relying on them.

.well constructGWML2 moduleClass / property
Well (top-level)GWML2-WellGW_Well (specializes O&M:SF_SamplingCurve)
well_id[]GWML2-WellGW_Well identifier property (?)
locationGWML2-WellGW_Well shape / position property (?)
bore_hole[]GWML2-WellConstructionBorehole (?)
well_case[]GWML2-WellConstructionCasing (?)
surface_case[]GWML2-WellConstructionCasing with surface depth range (?)
well_screen[]GWML2-WellConstructionScreen (?)
reduction[]GWML2-WellConstructionNo direct equivalent — casing transition
hole_fill[]GWML2-WellConstructionAnnular fill / gravel pack / seal (?)
cement_padGWML2-WellConstructionNo direct equivalent — wellhead furniture
centralizers[]GWML2-WellConstructionNo verified equivalent — casing accessory (?)
well_purpose[]GWML2-WellGW_Well purpose / use property (?)
lithology[]GWML2-WellGW_GeologyLogCoverage (realizes CV_DiscreteCoverage)
lithology[].geologic_unitGWML2-MainGW_HydrogeologicalUnit (specializes GeoSciML GeologicUnit)
fractures[]GWML2-WellFracture log interval (?)
caves[]GWML2-WellVoid / cavity log interval (?)
hydrodynamic_events[]GWML2-AquiferTestGW_AquiferTest (?) plus OM_Observation series via TimeseriesML
aquifer_analysis[]GWML2-AquiferTestAquifer test result properties (?)
history_logs[]n/aNo direct equivalent — operational record outside GWML2 scope
pump_installations[]GWML2-WellConstructionPump / wellhead equipment (?) — pending check against the XSD
permits[]n/aNo direct equivalent — operational record outside GWML2 scope
meters[]n/aNo direct equivalent — operational record outside GWML2 scope
production[]n/aNo direct equivalent — operational record outside GWML2 scope
operating_regime[]n/aNo direct equivalent — operational record outside GWML2 scope
attachments[] (root)n/aNo direct equivalent — documents referenced by URL
hydrodynamic_events[].correctsn/aNo direct equivalent — ledger correction outside GWML2 scope
water_samples[]GWML2-ConstituentSF_Specimen (?) — the sample taken from the GW_Well
water_samples[].results[]GWML2-ConstituentOM_Measurement (?) on the specimen, observed property = parameter
water_samples[].correctsn/aNo direct equivalent — ledger correction outside GWML2 scope

A complete, normative mapping will be published as a separate document once the GWML2 XSDs have been read directly and each verified class name and property path has been confirmed. Until then, this table is a structural guide and not a conversion specification.

Notes on the mapping

  • Wells vs. boreholes in GWML2. GWML2 distinguishes a GW_Well (the construction with hydrogeological purpose) from a Borehole (the physical hole). A single .well document conflates both since it describes one composite installation. A .well → GWML2 converter must emit both features and link them; a GWML2 → .well converter must merge them.
  • Aquifer tests in GWML2. GWML2-AquiferTest uses TimeseriesML (OGC 15-042r2) for time-series readings and O&M's OM_Observation pattern for individual measurements. The .well event types (spot_measurement, constant_rate, step_drawdown, airlift, recovery_only and, since v2.4, logger_series) are pragmatic field-record categories with no direct GWML2 counterpart; a converter must decompose each into one or more GW_AquiferTest features with appropriate OM_Observation results. A logger_series is not a test: a converter maps it to a TimeseriesML series of OM_Observation results on the well, without a GW_AquiferTest.
  • Hydrogeological units. .well stores lithology[].geologic_unit and aquifer_unit as free-text strings. In GWML2 these resolve to references to GW_HydrogeologicalUnit features, which in real GWML2 deployments are typically catalogued in national registries (e.g. French BDLISA, Canadian GIN). A .well → GWML2 converter SHOULD resolve these strings to authoritative unit URIs when a national vocabulary is available; absent that, it emits inline GW_HydrogeologicalUnit features with gml:name set to the string value.
  • Water samples as specimens. A water_samples entry corresponds to an O&M SF_Specimen taken from the well (the sampled feature), with datetime as the sampling time and sampling_point as the sampling location along the well. Each result is an OM_Measurement whose observed property is the parameter (a CAS or welldot term URI), whose result is the value in the code's canonical unit, and whose procedure is method. GWML2-Constituent describes the constituents of a fluid body rather than individual analyses, so a converter maps .well results to O&M observations on the specimen and derives constituent statements only when needed. Censoring (qualifier), detection and quantification limits, lab_flags and validation have no direct GWML2 counterpart and travel as result quality metadata or x- extensions. Field QA/QC links (parent_sample_id), purge data and chain of custody are outside GWML2 scope. Limits and exceedances are never part of the file and have no mapping.
  • History logs are outside GWML2 scope. GWML2 models the well as a static feature and its observations as a time-series. Maintenance interventions, incidents, status changes (status_change), permit condition fulfillment, and operational events are not represented. The same holds for the v2.3 operational blocks (permits, meters, production, operating_regime): metered production is an abstraction record, not an aquifer observation. A converter SHOULD preserve .well history_logs in a GeoSciML observation event sequence or as an x- extension on the GWML2 side, but full lossless round-trip is not guaranteed.

Profiles for regulatory adoption

National regulators with existing data models (Brazil SIAGAS, French BSS / BDLISA, EU INSPIRE hydrogeology) can publish .well profiles that constrain the format to their required fields and vocabularies. Profile schemas may extend the canonical .well v2 schema with regulator-specific requirements (e.g. mandatory well_id entries for the relevant national authority, restricted enums for casing materials, required precision fields) without breaking interoperability with the core spec.


Schema Validation

The canonical JSON Schema for .well v2 is published at:

https://welldot.org/schema/v2/well.schema.json

The schema conforms to JSON Schema 2020-12 (https://json-schema.org/draft/2020-12/schema). Implementers SHOULD use a JSON Schema validator that supports this draft (Ajv 8+, python-jsonschema 4+, NetworkNT json-schema-validator). Earlier-draft validators may work for most fields but are not officially supported.

Files MAY include a $schema field referencing this URL:

{
  "$schema": "https://welldot.org/schema/v2/well.schema.json",
  "version": "2.4",
  ...
}

The schema is generated from the Zod validators in @welldot/core to prevent drift between runtime validation and published schema. The generated file lives at spec/schema/v2/well.schema.json in the repository root, is published at https://welldot.org/schema/v2/well.schema.json and ships in @welldot/core as @welldot/core/well.schema.json. Profile schemas SHOULD extend this canonical schema via allOf + $ref.


.well Format Specification v2.4