Applying on-the-fly transformation to a layer

SharpMap can project between various projections on-the-fly. All you need to know is the spatial reference system of your input-data to enable you to reproject your maps.

Setting up an Universal Transverse Mercator (UTM) projection

SharpMap gives you the full power to specify all the parameters in a projection. The following method demonstrates how to setup a UTM projection:

/// <summary>
/// Creates a UTM projection for the northern/// hemisphere based on the WGS84 datum
/// </summary>
/// <param name="utmZone">Utm Zone</param>
/// <returns>Projection</returns>
private IProjectedCoordinateSystem CreateUtmProjection(int utmZone)
    CoordinateSystemFactory cFac = new SharpMap.CoordinateSystems.CoordinateSystemFactory();

    //Create geographic coordinate system based on the WGS84 datum
    IEllipsoid ellipsoid = cFac.CreateFlattenedSphere("WGS 84", 6378137, 298.257223563, LinearUnit.Metre);
    IHorizontalDatum datum = cFac.CreateHorizontalDatum("WGS_1984", DatumType.HD_Geocentric, ellipsoid, null);
    IGeographicCoordinateSystem gcs = cFac.CreateGeographicCoordinateSystem("WGS 84", AngularUnit.Degrees, datum,
      PrimeMeridian.Greenwich, new AxisInfo("Lon", AxisOrientationEnum.East), 
      new AxisInfo("Lat", AxisOrientationEnum.North));

    //Create UTM projection
    Collection<ProjectionParameter> parameters = new Collection<ProjectionParameter>();
    parameters.Add(new ProjectionParameter("latitude_of_origin", 0));
    parameters.Add(new ProjectionParameter("central_meridian", -183+6*utmZone));
    parameters.Add(new ProjectionParameter("scale_factor", 0.9996));
    parameters.Add(new ProjectionParameter("false_easting", 500000));
    parameters.Add(new ProjectionParameter("false_northing", 0.0));
    IProjection projection = cFac.CreateProjection("Transverse Mercator", "TransverseMercator", parameters);

    return cFac.CreateProjectedCoordinateSystem("WGS 84 / UTM zone "+utmZone.ToString() +"N", gcs,
       projection, LinearUnit.Metre, new AxisInfo("East", AxisOrientationEnum.East), 
       new AxisInfo("North", AxisOrientationEnum.North));

Parsing Well-known Text (WKT) projection strings

If you have a well-known text-representation, you can also create a projection from this. A WKT for an UTM projection might look like this:
PROJCS["WGS 84 / UTM zone 32N",GEOGCS"WGS 84",DATUM"WGS1984",
      SPHEROID"WGS 84",6378137,298.257223563,AUTHORITY"EPSG","7030"]],

SharpMap comes with WKT parsers for parsing a WKT to a coordinate system (note: the current v0.9RC1 has a few bug in its WKT parser, but if you get problems parsing the WKT, use the current source from the repository, where these issues have been resolved)
/// <summary>
/// Create coordinatesystem based on a Well-Known text
/// </summary>
/// <param name="wkt"></param>
/// <returns></returns>
private ICoordinateSystem CreateCoordinateSystemFromWKT(string wkt)
    CoordinateSystemFactory cFac = new CoordinateSystemFactory();
    return cFac.CreateFromWkt(strProj);
If your data is based on shapefile data and they have a .prj file defining the coordinatesystem, you can simply retrieve the CS from the shapefile instead. SharpMap automatically reads and parses the PRJ file.
((myMap.Layers[0] as VectorLayer).DataSource as ShapeFile).CoordinateSystem

Transform from one coordinate system to another

The next step is to create a transformation between two coordinate systems. SharpMap v0.9RC1 only supports transforming between a geographic coordinate system and one of the following projections (this has changed after the RC1 release):
  • Mercator 1-standard parallel (Mercator_1SP)
  • Mercator 2-standard parallels (Mercator_2SP)
  • Transverse mercator (Transverse_Mercator)
  • Lambert Conic Conformal 2-standard parallel (Lambert Conic Conformal (2SP))
  • Albers

Unfortunately datum-shifts and transformations between two projections are also post RC1, so to utilize this feature you will need the newest source and compile.

The following shows how to create a transformation and apply it to a vectorlayer (only vector- and label-layers supports on-the-fly transformations):
//Create zone UTM 32N projection
IProjectedCoordinateSystem utmProj = CreateUtmProjection(32);

//Create geographic coordinate system (lets just reuse the CS from the projection)
IGeographicCoordinateSystem geoCS = utmProj.GeographicCoordinateSystem;

//Create transformation
CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();
ICoordinateTransformation transform = ctFac.CreateFromCoordinateSystems(source, target);

//Apply transformation to a vectorlayer
(myMap.Layers[0] as VectorLayer).CoordinateTransformation = transform;

Last edited Aug 31, 2012 at 1:20 PM by FObermaier, version 12