Skip to content

DHI.Services.MIKECore for GIS — Internal Developer Guide

This guide is the practical how-to for using the MIKECore GIS providers behind DHI.Services.GIS. It explains what each provider returns, the exact ID grammar you pass in, how to wire them via connections or code. See also: MIKECore Providers for MIKECore details.


What these providers do

  • DFS2 → polygons (grid cells) Reads a single time slice from a DFS2 raster and returns one rectangle polygon per cell, with one attribute column per DFS item (float).

  • DFSU → polygons (mesh elements) Reads a DFSU unstructured mesh, returns one closed polygon per element, plus attributes for either all items or one selected item at a chosen time.

Both providers load via the common GisService<string> surface, so your app and Web API can treat them like any other GIS source.


Capabilities & limitations (at a glance)

Operation DFS2 DFSU
Get(id) (single collection) ✓ (requires DateTime)
Get(id, associations, outSpatialReference) ✓ but ignores both params ✓ but ignores both params
Get(id, filter, …) ✗ (not implemented) ✓ (method exists) but filter is ignored
GetAll() ✓ (folder/prefix enumeration of *.dfsu)
GetEnvelope / GetFootprint / GetIds(filter)
Bounding box filter ✓ (BoundingBox=…) ✓ (BoundingBox=…)
Per-feature edits n/a (read model) n/a (read model)

Why are some methods “ignored”? The class overrides exist to satisfy the base interface, but the current implementations either don’t support those operations or always compute the full collection (e.g., DFSU doesn’t apply attribute filters yet).


How coordinates are produced

  • DFS2 (rotated grid aware) The repository reads the raster’s projection WKT + origin (lon/lat) + orientation and computes cell center coordinates in projected space. It then offsets centers to four corners to make rectangles. If BoundingBox is specified, a cell is kept only if all 4 corners are inside the box.

  • DFSU (mesh) For each element, the provider builds a polygon from its node coordinates (X, Y) and closes the ring (repeats the first node at the end). Elements are kept only if all vertices are inside the BoundingBox (strict containment).

outSpatialReference is currently accepted but not applied by either provider. You receive coordinates in the native space of the file.


Wiring options

Add entries to your connections.json:

"dfs2": {
  "$type": "DHI.Services.GIS.WebApi.GisServiceConnection, DHI.Services.GIS.WebApi",
  "ConnectionString": "[AppData]dfs2\\R20141001.dfs2",
  "RepositoryType": "DHI.Services.Provider.MIKECore.Dfs2FeatureRepository, DHI.Services.Provider.MIKECore",
  "Name": "DFS2 reader",
  "Id": "dfs2"
},
"dfsu": {
  "$type": "DHI.Services.GIS.WebApi.GisServiceConnection, DHI.Services.GIS.WebApi",
  "ConnectionString": "[AppData]",
  "RepositoryType": "DHI.Services.Provider.MIKECore.DfsuFeatureRepository, DHI.Services.Provider.MIKECore",
  "Name": "DFSU reader",
  "Id": "dfsu"
}
  • For DFS2, the connection points to a specific file.
  • For DFSU, the connection points to a folder root (after [AppData] resolution). The provider will enumerate *.dfsu when you call GetAll().

Once registered, your Web API exposes GET /api/featurecollections/{connectionId}/{id} etc.

B) Programmatic registration

// DFS2: exact file
ServiceLocator.Register(
  new GisService(
    new DHI.Services.Provider.MIKECore.Dfs2FeatureRepository(@"C:\data\dfs2\R20141001.dfs2")
  ),
  "dfs2"
);

// DFSU: folder or file prefix – provider can enumerate
ServiceLocator.Register(
  new GisService(
    new DHI.Services.Provider.MIKECore.DfsuFeatureRepository(@"C:\data\dfsu\")
  ),
  "dfsu"
);

ID grammar (what you put in {id})

Both repositories accept a semicolon-separated set of key=value pairs. Keys are case-sensitive and values are culture-invariant (use . as decimal separator).

DFS2 (Dfs2FeatureCollectionId)

Required

  • DateTime=yyyy-MM-ddTHHmmss Exact format (no colons in the time part). Example: 2014-10-01T120000.

Optional

  • File=<path> If your connection already points at a specific file, you may omit File and just pass the DateTime. If you include it, it is appended to the constructor’s prefix (folder/relative root). You may use \ or /.
  • BoundingBox=minX,minY,maxX,maxY Filters cells fully contained in the bbox. Example: BoundingBox=12.0,55.0,13.0,56.0.

Examples

DateTime=2014-10-01T120000
File=dfs2\R20141001.dfs2;DateTime=2014-10-01T000000
File=C:\data\R20141001.dfs2;DateTime=2014-10-01T120000;BoundingBox=12.0,55.0,13.0,56.0

If the timestamp doesn’t exist in the file, the repository throws “Matching datetime not found”.

DFSU (DfsuFeatureCollectionId)

Optional (but typical)

  • File=<path> Use when your connection is a folder/prefix. If the connection constructed with a file path, File can be omitted.
  • Item=<item name> If omitted, all items are returned as separate attributes.
  • DateTime=<timestamp> You can pass standard DateTime.Parse(...) values (e.g., 2021-09-20T00:00:00) or the compact yyyy-MM-ddTHHmmss. If omitted, the first time step (index 0) is used.
  • BoundingBox=minX,minY,maxX,maxY Keeps only elements fully contained in the bbox.

Reserved (parsed but not used yet)

  • ContourIntervals=a,b,c → parsed to List<double>, currently ignored by the repository.

Examples

File=mesh\my.dfsu;Item=Water Level;DateTime=2021-09-20T00:00:00
Item=Salinity
File=C:\data\mesh.dfsu;BoundingBox=12,55,13,56

Unknown keys throw (e.g., using BBox instead of BoundingBox will fail). Use the spellings above.


What a result looks like

DFS2

  • Collection metadata: Id="DFS2", Name="DFS2" (placeholder naming).
  • Attributes: one float attribute per DFS item (e.g., "Water Level", "Wind U").
  • Features: rectangle polygon per grid cell (4 corners computed from rotated grid).
  • Filters applied: time slice required; optional strict BoundingBox containment.

DFSU

  • Collection metadata: Id=Path.GetFileNameWithoutExtension(file).
  • Attributes: "Id" (1-based element index) + one float attribute per selected item (or all items if Item omitted).
  • Features: closed polygon ring per element (first node repeated at end).
  • Filters applied: optional strict BoundingBox containment; Item/DateTime selection.

Example calls via the Web API

Assuming you registered the above connections and your host resolves [AppData].

DFS2 — one time slice, with bbox

GET /api/featurecollections/dfs2/DateTime=2014-10-01T120000;BoundingBox=12.0,55.0,13.0,56.0?api-version=1
Authorization: Bearer <token>

DFSU — item + time

GET /api/featurecollections/dfsu/File=mesh%5Cmesh.dfsu;Item=Water%20Level;DateTime=2021-09-20T00:00:00?api-version=1
Authorization: Bearer <token>

DFSU — enumerate all files (server-side) Use GetAll() programmatically (not an HTTP route by default):

var svc = Services.Get<GisService<string>>("dfsu");
foreach (var fc in svc.Repository.GetAll()) { /* ... */ }

Using from code (no Web API)

var dfs2 = new DHI.Services.Provider.MIKECore.Dfs2FeatureRepository(@"C:\data\dfs2\R20141001.dfs2");
var id = "DateTime=2014-10-01T120000;BoundingBox=12.0,55.0,13.0,56.0";
var fc = dfs2.Get(id, associations:false, outSpatialReference:null).Value;

// Inspect schema
foreach (var a in fc.Attributes) Console.WriteLine($"{a.Name} : {a.DataType.Name}");

// DFSU
var dfsu = new DHI.Services.Provider.MIKECore.DfsuFeatureRepository(@"C:\data\dfsu\");
var fcMesh = dfsu.Get("File=mesh.dfsu;Item=Water Level;DateTime=2021-09-20T00:00:00", associations:false).Value;

Bounding boxes: semantics & helpers

  • Both providers interpret BoundingBox as full containment: a feature is included only if all its vertices are inside the rectangle.
  • Use the DHI.Spatial.BoundingBox.Parse("xmin,ymin,xmax,ymax") helper when you build IDs programmatically.
  • Conversions for WebMercator are available on BoundingBox (LonLatToGoogle(), GoogleToLonLat()) if you need to translate query UI inputs.

Common pitfalls & troubleshooting

  • DFS2 DateTime format must be yyyy-MM-ddTHHmmss (e.g., 2014-10-01T120000). Using colons (e.g., T12:00:00) will fail to parse. Error: Could not parse id string '...' or later Matching datetime not found.
  • DFSU unknown keys throw. Use BoundingBox=..., not BBox=....
  • Items in DFSU: If you pass Item=... that doesn’t exist, you’ll get an exception listing valid names.
  • Large datasets: DFS2 grid → many polygons; DFSU large meshes → big payloads. Use BoundingBox and select a single Item and DateTime when possible.
  • Projections: The outSpatialReference parameter is ignored; you get file-native coordinates.
  • NotImplemented: Envelope, footprint, and certain list/id calls are intentionally unimplemented. Guard calls by provider type/capability.

Reference

  • Dfs2FeatureCollectionId / DfsuFeatureCollectionId Parse and hold FilePath, DateTime, optional Item/BoundingBox.
  • BoundingBox Immutable (Xmin,Ymin,Xmax,Ymax) with Parse, Contains(Position), Intersects, and WebMercator conversion helpers.
  • FeatureCollection<string> Holds Features and Attributes (schema). GetInfo() yields metadata only.
  • IGeometry & CoordinateReferenceSystem Geometry interfaces used by the GeoJSON converters (DHI.Spatial.GeoJson).

End-to-end recipe

  1. Register the connection(s) (see Connections section above).
  2. Build your ID string:
    • DFS2: DateTime=2014-10-01T120000;BoundingBox=12,55,13,56
    • DFSU: File=mesh\mesh.dfsu;Item=Water Level;DateTime=2021-09-20T00:00:00
  3. Call GET /api/featurecollections/{connectionId}/{id} (or use the service directly).
  4. Serialize the result with the GeoJSON converters already included by DHI.Services.GIS.WebApi.

That’s it. Plug in your UI, keep IDs precise, and lean on BoundingBox + Item/DateTime to keep payloads tight.