Gml4Net 0.3.0

dotnet add package Gml4Net --version 0.3.0
                    
NuGet\Install-Package Gml4Net -Version 0.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Gml4Net" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Gml4Net" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Gml4Net" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Gml4Net --version 0.3.0
                    
#r "nuget: Gml4Net, 0.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Gml4Net@0.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Gml4Net&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Gml4Net&version=0.3.0
                    
Install as a Cake Tool

Gml4Net

A .NET library for parsing Geography Markup Language (GML) documents. Supports GML 2-3.3, GeoJSON/WKT/KML/CSV export, OWS/WCS integration, and streaming for large documents.

Features

  • GML Parsing -- Geometries, features, feature collections, and coverages
  • Version Support -- GML 2.1.2, 3.0, 3.1, 3.2, 3.3 with automatic version detection
  • GeoJSON Export -- Conversion to GeoJSON via System.Text.Json
  • WKT Export -- Conversion to Well-Known Text
  • KML Export -- Conversion to KML via System.Xml.Linq
  • CSV Export -- Feature collections to CSV with WKT geometry column
  • Generic Builder -- IBuilder<TGeometry, TFeature, TCollection> for custom output formats
  • Coverage Support -- RectifiedGridCoverage, GridCoverage, ReferenceableGridCoverage, MultiPointCoverage
  • WCS Integration -- Request builder and capabilities parser for OGC Web Coverage Service
  • OWS Exceptions -- Detection and parsing of OGC Web Service exception reports
  • Streaming -- Memory-efficient processing of large WFS feature collections with callback-based public API, batch support, feature sinks, and per-feature filtering
  • Zero Dependencies -- Only BCL APIs (System.Xml.Linq, System.Text.Json)

Packages

Package Description
Gml4Net Core library: model, parser, GeoJSON/WKT/KML/CSV interop, OWS, WCS, streaming
Gml4Net.IO Optional package: file and HTTP I/O, streaming from files and URLs

API

Parse GML

using Gml4Net.Parser;

var result = GmlParser.ParseXmlString(xml);

if (!result.HasErrors)
{
    var doc = result.Document!;
    // doc.Root is GmlPoint, GmlFeature, GmlFeatureCollection, or GmlCoverage
}

Also available: GmlParser.ParseBytes(ReadOnlySpan<byte>) and GmlParser.ParseStream(Stream).

Convert to GeoJSON

using Gml4Net.Interop;

var geojson = GeoJsonBuilder.Document(result.Document!);
var jsonString = GeoJsonBuilder.GeometryToJson(point);

Or via the generic builder pattern:

var parser = GmlParser.Create(GeoJsonBuilder.Instance);
var result = parser.Parse(xml);
// result.Geometry, result.Feature, result.Collection are JsonObject

Convert to WKT

using Gml4Net.Interop;

var wkt = WktBuilder.Geometry(point);
// POINT (10 20)

Convert to KML

using Gml4Net.Interop;

var kml = KmlBuilder.Feature(feature);
var kmlString = KmlBuilder.GeometryToKml(point);

Pattern Matching on Root Content

var description = result.Document!.Root switch
{
    GmlFeatureCollection fc => $"{fc.Features.Count} features",
    GmlFeature f            => $"Feature: {f.Id}",
    GmlGeometry g           => $"Geometry: {g.GetType().Name}",
    GmlCoverage c           => $"Coverage: {c.Id}",
    _                       => "Unknown"
};

Stream Large Feature Collections

Callback-based streaming with error handling:

using Gml4Net.Parser;

var parser = new StreamingGmlParser(new StreamingParserOptions
{
    ErrorBehavior = StreamingErrorBehavior.Continue
});

parser.OnFeature(feature =>
{
    Console.WriteLine(feature.Id);
    return ValueTask.CompletedTask;
});

parser.OnError(error =>
{
    Console.Error.WriteLine(error.Exception?.Message ?? "Parse issue");
});

var result = await parser.ParseAsync(stream);
// result.FeaturesProcessed, result.FeaturesFailed

With builder integration:

var result = await StreamingGml.ParseAsync(
    stream,
    GeoJsonBuilder.Instance,
    feature =>
    {
        Console.WriteLine(feature["id"]);
        return ValueTask.CompletedTask;
    });

Batch processing:

var result = await StreamingGml.ParseBatchesAsync(
    stream,
    GeoJsonBuilder.Instance,
    batch => SaveBatchAsync(batch),
    batchSize: 100);

With a feature filter (property-based or spatial):

var result = await StreamingGml.ParseAsync(
    stream,
    GeoJsonBuilder.Instance,
    feature => ProcessAsync(feature),
    options: new StreamingParserOptions
    {
        Filter = f => f.Properties.TryGetValue("status", out var v)
                      && v is GmlStringProperty { Value: "active" }
    });
// result.FeaturesFiltered -- skipped features

With a feature sink (e.g. for database writes):

var result = await StreamingGml.ParseAsync(stream, new PostGisSink(connection));

Low-level streaming via IAsyncEnumerable<GmlFeature>:

using Gml4Net.Parser.Streaming;

await foreach (var feature in GmlFeatureStreamParser.ParseAsync(stream))
{
    Console.WriteLine(feature.Id);
}

File and URL I/O

using Gml4Net.IO;

// Parse from file
var fileResult = GmlIo.ParseFile("data.gml");

// Parse from URL
var urlResult = await GmlIo.ParseUrlAsync(uri);

// Stream features from URL
await foreach (var feature in GmlIo.StreamFeaturesFromUrl(uri))
{
    Console.WriteLine(feature.Id);
}

Supported GML Types

Geometries

Type GML 2 GML 3
Point x x
LineString x x
LinearRing x x
Polygon x x
Envelope - x
Box x -
Curve - x
Surface - x
MultiPoint x x
MultiLineString x x
MultiPolygon x x

Features

  • GmlFeature with typed properties (string, numeric, geometry, nested, raw XML)
  • GmlFeatureCollection with WFS 1.0/1.1/2.0 member variants

Coverages

  • GmlRectifiedGridCoverage (georeferenced grids with affine transform)
  • GmlGridCoverage (non-georeferenced grids)
  • GmlReferenceableGridCoverage (irregular grids)
  • GmlMultiPointCoverage (discrete point coverages)

Error Handling

Parse errors are returned as issues, not thrown as exceptions:

var result = GmlParser.ParseXmlString(xml);

if (result.HasErrors)
{
    foreach (var issue in result.Issues)
    {
        Console.WriteLine($"[{issue.Severity}] {issue.Code}: {issue.Message}");
    }
}

Docker Build and Release

The repository uses a multi-stage Dockerfile for building, testing, and packaging.

  • Build stages: restore, build, test, pack, push
  • Coverage gate: at least 90% line coverage
  • Public API XML documentation comments are required (CS1591 as error)
docker buildx build --target test -t gml4net:test .
docker buildx build --target artifacts --build-arg PACKAGE_VERSION=0.1.0 -o type=local,dest=./artifacts .
docker buildx build --target push --secret id=nuget_api_key,src=/path/to/nuget-api-key.txt --build-arg PACKAGE_VERSION=0.1.0 .

Notes:

  • push publishes generated .nupkg files to https://api.nuget.org/v3/index.json
  • The preferred credential flow is a BuildKit secret named nuget_api_key
  • NUGET_API_KEY is also supported as a build argument for CI systems that cannot mount secrets
  • The example commands use docker buildx build because the Dockerfile relies on BuildKit features
  • The test stage enforces /p:Threshold=90 /p:ThresholdType=line /p:ThresholdStat=total
  • The current test project uses coverlet.msbuild; the 90% gate is enforced via the Docker test stage
  • The library project treats CS1591 as an error, so missing XML comments on public APIs break the Docker build

GitHub Actions

The repository includes GitHub Actions workflows that use the same Dockerfile-based pipeline as local development:

  • .github/workflows/ci.yml
    • runs on pushes to main and on pull requests
    • executes docker buildx build --target test -t gml4net:test .
  • .github/workflows/publish-gml4net.yml
    • publishes the Gml4Net package
    • runs automatically on Git tags matching Gml4Net-v*
    • can also be started manually via workflow_dispatch
  • .github/workflows/publish-gml4net-io.yml
    • publishes the Gml4Net.IO package
    • runs automatically on Git tags matching Gml4Net.IO-v*
    • can also be started manually via workflow_dispatch
  • both publish workflows validate the package version, run the Docker test target, build package-specific NuGet artifacts, upload them as workflow artifacts, and publish to nuget.org

Required GitHub repository setup:

  • create a repository or environment secret named NUGET_API_KEY
  • if you use GitHub environments, the publish workflow targets the nuget environment
  • publish tags must use the format <PackageId>-v<semver>
  • examples:
    • Gml4Net-v0.2.0
    • Gml4Net.IO-v0.2.0

Example release flow:

git tag Gml4Net-v0.2.0
git push origin Gml4Net-v0.2.0

git tag Gml4Net.IO-v0.2.0
git push origin Gml4Net.IO-v0.2.0

Requirements

  • Target: .NET 10.0 (LTS)

Documentation

  • s-gml -- Original TypeScript implementation
  • gml4dart -- Dart port

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Gml4Net:

Package Downloads
Gml4Net.IO

File and HTTP I/O for the Gml4Net GML parsing library. Provides file parsing, URL fetching with OWS exception detection, and streaming feature extraction from large WFS documents.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 204 4/5/2026
0.2.0 183 4/5/2026
0.1.4 394 4/5/2026
0.1.3 182 4/5/2026
0.1.2 184 4/4/2026
0.1.1 402 4/4/2026
0.1.0 192 4/4/2026