C# Vector and Spatial Reference Interfaces

Basic Architecture

The vector interface is within the OSGeo.OGR namespace and the spatial reference interface is within the OSGeo.OSR namespace.

The main classes are as follows

OGR
|
|- DataSource
|
|- Layer
|
|- Feature
|
|- Geometry
OSR
|
|- SpatialReference
|
|- CoordinateTransform

Accessing Feature Geometries

The basic process is DataSource => Layer => Feature => Geometry

Open a DataSource

A DataSource wraps a OGR source (e.g a filename) and is created as follows:

/* -------------------------------------------------------------------- */
/*      Register format(s).                                             */
/* -------------------------------------------------------------------- */
Ogr.RegisterAll();

/* -------------------------------------------------------------------- */
/*      Open data source.                                               */
/* -------------------------------------------------------------------- */
using (DataSource ds = Ogr.Open( "... add your own valid OGR source", 0 ))
{
    if (ds == null) {
        // create an error
    }
    // Do your processing here
}

Access the Layers

Each DataSource will have one or more layers that can be iterated as follows:

/* -------------------------------------------------------------------- */
/*      Iterating through the layers                                    */
/* -------------------------------------------------------------------- */

for( int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++ )
{
    Layer layer = ds.GetLayerByIndex(iLayer);

    if( layer == null )
    {
        // create an error
    }
    // Do your processing here
}

Access a Layer’s Features

Each Layer can have zero or more Feature s. These should be accessed as follows:

layer.ResetReading();
Feature f = null;
do {
    f = layer.GetNextFeature();
    if (f != null)
        // Do your processing here
} while (f != null);

Access a Features’s Geometry

Geometry geom = feature.GetGeometryRef();
wkbGeometryType type = geom.GetGeometryType();

Geometry objects are nested - so for instance:

  • a Geometry of type wkbGeometryType.wkbTIN has multiple daughter Geometry objects of type wkbGeometryType.wkbTriangle,

  • each Geometry object of type wkbGeometryType.wkbTriangle has a daughter Geometry object of type wkbGeometryType.LinearRing,

  • each Geometry of type wkbGeometryType.LinearRing contains a number of points.

When you get to the most basic type - which usually seems to be wkbGeometryType.wkbPoint, wkbGeometryType.wkbLineString or wkbGeometryType.wkbLinearRing or their multi- versions or 25D or ZM versions, you can access the point coordinates as follows:

int count = geom.GetPointCount();
if (count > 0)
    for (int i = 0; i < count; i++) {
        double[] argout = new double[3];
        geom.GetPoint(i, argout);
        // do your processing here
    }

Note

The size of the double[] depends on the number of dimensions of the Geometry.

Access a Feature’s data fields

Each Feature object can have a number of data fields associated. The schema for the data fields is defined in a FieldDefn object. The fields can be fetched a follows:

Dictionary<string, object> ret = new Dictionary<string, object>();
if (feature != null) {
    int fieldCount = feature.GetFieldCount();
    for (int i = 0; i < fieldCount; i++) {
        FieldDefn fd = feature.GetFieldDefnRef(i);
        string key = fd.GetName();
        object value = null;
        FieldType ft = fd.GetFieldType();
        switch (ft) {
            case FieldType.OFTString:
                value = feature.GetFieldAsString(i);
                break;
            case FieldType.OFTReal:
                value = feature.GetFieldAsDouble(i);
                break;
            case FieldType.OFTInteger:
                value = feature.GetFieldAsInteger(i);
                break;
            // Note this is only a sub-set of the possible field types
        }
        ret.Add(key, value);
    }
}

Access a Geometry’s CRS

If there is a CRS (aka SRS) defined for the Geometry it can be retrieved as follows:

SpatialReference crs = geom.GetSpatialReference()

The SpatialReference is the main class for representing the CRS / projection. The CRS can be turned into a WKT string, e.g. for display purposes, as follows:

string wkt;
crs.ExportToWkt(out wkt, null);

Note

Sometimes the CRS defined on the layer does not cascade down to the Feature - you need to refer bak to the Layer

Reproject a Geometry

If the Geometry has a valid SpatialReference defined, then the Geometry can be transformed to a new CRS using this command:

if (geom.TransformTo(newProjection) != 0)
    throw new NotSupportedException("projection failed");

However, often it is better to explicitly define the CoordinateTransform to be used

SpatialReference from_crs = new SpatialReference(null)
    // note - if you are defining from wkt - replace the null with the wkt
from_crs.SetWellKnownGeogCS("EPSG:4326");

SpatialReference to_crs = new SpatialReference(null);
to_crs.ImportFromEPSG(27700);

CoordinateTransform ct = new CoordinateTransform(from_crs, to_crs, new CoordinateTransformationOptions())
    // You can use the CoordinateTransformationOptions to set the operation or area of interet etc

if (geom.Transform(ct) != 0)
    throw new NotSupportedException("projection failed");