GeoConvert 0.1.3
See the version list below for details.
dotnet add package GeoConvert --version 0.1.3
NuGet\Install-Package GeoConvert -Version 0.1.3
<PackageReference Include="GeoConvert" Version="0.1.3" />
<PackageVersion Include="GeoConvert" Version="0.1.3" />
<PackageReference Include="GeoConvert" />
paket add GeoConvert --version 0.1.3
#r "nuget: GeoConvert, 0.1.3"
#:package GeoConvert@0.1.3
#addin nuget:?package=GeoConvert&version=0.1.3
#tool nuget:?package=GeoConvert&version=0.1.3
<img src="/src/icon.png" height="30px"> GeoConvert
Convert maps between geospatial formats, with no third-party dependencies — only the .NET base
class libraries (System.Text.Json, System.Xml, System.IO.Compression). It can also render a
bounding box to a PNG image. Ships as a library and a geoconvert command line tool.
Supported formats
All vector formats can be both read and written; PNG is a write-only raster export.
| Format | Extension(s) | Kind |
|---|---|---|
| GeoJSON | .geojson, .json |
JSON |
| TopoJSON | .topojson |
JSON (topology encoded) |
| Shapefile | .shp (+ .shx, .dbf, .prj) |
Binary |
| FlatGeobuf | .fgb |
Binary (FlatBuffers) |
| KML | .kml |
XML |
| KMZ | .kmz |
Zipped KML |
| GPX | .gpx |
XML |
| WKT | .wkt |
Text |
| WKB | .wkb |
Binary |
| CSV | .csv |
Text (WKT or lon/lat columns) |
| PNG | .png |
Raster image (write-only) |
All coordinates are treated as WGS84 (EPSG:4326) longitude/latitude.
Library
Convert a file to another format (both formats inferred from their extensions):
<a id='snippet-Convert'></a>
// Formats are inferred from the file extensions.
GeoConverter.Convert("cities.geojson", "cities.kml");
GeoConverter.Convert("roads.shp", "roads.fgb");
<sup><a href='/src/Tests/Snippets.cs#L6-L10' title='Snippet source file'>snippet source</a> | <a href='#snippet-Convert' title='Start of snippet'>anchor</a></sup>
Read into the common feature model, then write a different format:
<a id='snippet-ReadModifyWrite'></a>
// Read any supported format into the common feature model.
var collection = GeoConverter.Read("roads.shp");
foreach (var feature in collection)
{
if (feature.Properties.TryGetValue("name", out var name))
{
Console.WriteLine(name);
}
}
// Write it back out as a different format.
GeoConverter.Write(collection, "roads.fgb");
<sup><a href='/src/Tests/Snippets.cs#L15-L29' title='Snippet source file'>snippet source</a> | <a href='#snippet-ReadModifyWrite' title='Start of snippet'>anchor</a></sup>
Build a collection in memory and serialize it:
<a id='snippet-BuildModel'></a>
var collection = new FeatureCollection
{
new Feature(
new Point(new(151.21, -33.87)),
new Dictionary<string, object?> { ["name"] = "Sydney" }),
};
var geoJson = GeoJson.WriteString(collection);
<sup><a href='/src/Tests/Snippets.cs#L34-L43' title='Snippet source file'>snippet source</a> | <a href='#snippet-BuildModel' title='Start of snippet'>anchor</a></sup>
Raster export (PNG)
Render a FeatureCollection to a PNG, clipped to a bounding box, with a software rasterizer and a
hand-written PNG encoder (no third-party dependencies):
<a id='snippet-RenderToPng'></a>
var collection = GeoConverter.Read("countries.geojson");
// Render a specific bounding box (min lon, min lat, max lon, max lat) to a PNG.
var options = new RenderOptions
{
Bounds = new Envelope(-10, 35, 30, 60),
Width = 1200,
Height = 900,
};
MapRenderer.RenderPng(collection, "europe.png", options);
<sup><a href='/src/Tests/Snippets.cs#L49-L61' title='Snippet source file'>snippet source</a> | <a href='#snippet-RenderToPng' title='Start of snippet'>anchor</a></sup>
RenderOptions controls the extent (Bounds), pixel Width/Height (height is derived from the
aspect ratio when left at 0), Padding, and the Background/Stroke/Fill colors. From the command
line, output a .png and pass --bbox and --size:
geoconvert world.geojson europe.png --bbox -10,35,30,60 --size 1200x900
Exampl generated png
All Australian suburbs
<img src="/src/Tests/PngTests.Render_RealMap.verified.png" height="1100px">
Command line
Installed as a .NET tool named
geoconvert:
geoconvert <input> <output> [--from <format>] [--to <format>]
Formats are detected from the file extensions; --from/--to override that. Examples:
geoconvert cities.geojson cities.kml
geoconvert roads.shp roads.fgb
geoconvert data.csv data.geojson --from csv
Run geoconvert --list to see the supported format names, or geoconvert --help for usage.
Model
Everything reads into and writes out of a FeatureCollection:
Feature— aGeometryplus a string-keyedPropertiesdictionary and an optionalId.Geometry—Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygonorGeometryCollection, built fromPositionvalues (X = longitude, Y = latitude, optional Z and M).
Benchmarks
BenchmarkDotNet benchmarks live in src/Benchmarks and must run in
Release:
dotnet run -c Release --project src/Benchmarks -- --filter "*"
ConvertBenchmarks measures reading and writing a 500-polygon collection through each stream format;
RenderBenchmarks measures PNG rasterization. Add --job Dry for a quick smoke run.
Notes and limitations
- Shapefile holds a single geometry category per file; writing a collection that mixes points,
lines and polygons throws. This is mandated by the format, not a GeoConvert choice — the
.shpheader declares one shape type for the whole file, so a mixed collection has no valid encoding and the consumer must split it into one file per geometry type first. Output is 2D: the format does define Z and M variants, but GeoConvert drops those ordinates rather than emit them. A WGS84.prjis emitted. - FlatGeobuf is written without the optional packed R-tree spatial index
(
index_node_size = 0) and is 2D. The index is a query accelerator, not data: it lets a reader fetch features in a bounding box without scanning the whole file, but carries no information the feature records don't. So GeoConvert reads an indexed file by computing the index size and skipping past it — full-file conversion needs every feature anyway — and writes none, leaving output that is still valid FlatGeobuf (GDAL, QGIS and flatgeobuf.org read it fine) for the consumer to re-index on import if it wants spatial queries. Emitting one would mean hand-rolling a Hilbert R-tree to honour the no-dependency rule, which is real complexity for a benefit a conversion tool rarely needs. - GPX has no native area type: polygons are written as a track with one segment per ring, multi polygons flatten every ring into a single track, and geometry collections write each member geometry in turn. Reading a track with several segments yields a multi line string, so polygons do not survive a round trip as polygons.
- WKT and WKB carry geometry only — feature attributes are dropped on write.
- PNG is a write-only raster export; reading a
.pngthrows. It needs an extent — when noBoundsis given, the full extent of the data is used. - Property values are scalars (
string,long,double,bool); nested JSON is flattened.
Icon
Pattern designed by Kim Sun Young from The Noun Project.
| Product | Versions 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. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (3)
Showing the top 3 NuGet packages that depend on GeoConvert:
| Package | Downloads |
|---|---|
|
MapBundle
Core runtime for MapBundle. Loads bundled map data (borders, cities, waterways) that ships as FlatGeobuf in the MapBundle.World and MapBundle.[Region] packages. Data is derived from OpenStreetMap (© OpenStreetMap contributors, ODbL). |
|
|
GeoConvert.Skia
Optional SkiaSharp-backed PNG render backend for GeoConvert. Rasterizes the same projection, styling and labelling pipeline as the built-in renderer through Skia. Unlike GeoConvert itself, this package takes a third-party dependency (SkiaSharp). |
|
|
GeoConvert.ImageSharp
Optional SixLabors.ImageSharp-backed PNG render backend for GeoConvert. Rasterizes the same projection, styling and labelling pipeline as the built-in renderer through ImageSharp. Unlike GeoConvert itself, this package takes a third-party dependency (SixLabors.ImageSharp, under the Six Labors Split License). |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.1 | 124 | 6/8/2026 |
| 1.1.0 | 115 | 6/8/2026 |
| 1.0.1 | 3,312 | 6/6/2026 |
| 1.0.0 | 118 | 6/6/2026 |
| 0.12.0 | 122 | 6/5/2026 |
| 0.11.0 | 6,496 | 6/3/2026 |
| 0.10.1 | 3,306 | 6/3/2026 |
| 0.10.0 | 3,289 | 6/2/2026 |
| 0.9.1 | 3,311 | 6/2/2026 |
| 0.9.0 | 3,321 | 6/2/2026 |
| 0.8.2 | 3,297 | 6/2/2026 |
| 0.8.1 | 98 | 6/2/2026 |
| 0.8.0 | 94 | 6/1/2026 |
| 0.6.0 | 109 | 5/30/2026 |
| 0.5.1 | 115 | 5/28/2026 |
| 0.5.0 | 105 | 5/28/2026 |
| 0.4.0 | 103 | 5/28/2026 |
| 0.3.0 | 97 | 5/27/2026 |
| 0.2.0 | 90 | 5/27/2026 |
| 0.1.3 | 99 | 5/25/2026 |