I am using sharpmap to render borders (geometry) from MSSQL as PNG image. It all works well, except countries are looking too "wide" on flat image format.
As I understand, I need to create transformation to EPSG:3857 projection, but I have no idea how to do it.
Here's my code
var map = new Map(new Size(request.Width, request.Height));
map.BackColor = Color.Transparent;
var countryGeometry = GeometryFromWKT.Parse(dto.CountryWkt);
IProvider countryProvider = new GeometryFeatureProvider(countryGeometry);
var countryLayer = new VectorLayer("country", countryProvider);
var borderColor = System.Drawing.ColorTranslator.FromHtml("#525252");
countryLayer.Style.EnableOutline = true;
countryLayer.Style.Outline = new Pen(borderColor);
countryLayer.Style.Fill = Brushes.Transparent;
//does not work with this
countryLayer.CoordinateTransformation = new
ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory().CreateFromCoordinateSystems(
ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84,
ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator);
map.Layers.Add(countryLayer);
map.ZoomToBox(new Envelope(dto.Envelope.BottomLeft.Longitude,
dto.Envelope.TopRight.Longitude,
dto.Envelope.BottomLeft.Latitude,
dto.Envelope.TopRight.Latitude
));
var img = map.GetMap();
WKT Can be found here https://pastebin.com/PEbpAdxT
Any help is appreciated.
EDIT:
This is the image i get now for france and it's region "Limousin". As you can see, it's too "wide".
This is the image when i apply transformation, which can be found under code comment does not work with this
EDIT 2
I've also tried following for transformation, but this renders blank png (without red cross over it)
public ICoordinateTransformation Wgs84toGoogleMercator
{
get
{
if (_wgs84ToGoogle == null)
{
CoordinateSystemFactory csFac = new ProjNet.CoordinateSystems.CoordinateSystemFactory();
CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();
IGeographicCoordinateSystem wgs84 = csFac.CreateGeographicCoordinateSystem(
"WGS 84", AngularUnit.Degrees, HorizontalDatum.WGS84, PrimeMeridian.Greenwich,
new AxisInfo("north", AxisOrientationEnum.North), new AxisInfo("east", AxisOrientationEnum.East));
// var a = csFac.CreateFromWkt("aa");
List<ProjectionParameter> parameters = new List<ProjectionParameter>();
parameters.Add(new ProjectionParameter("semi_major", 6378137.0));
parameters.Add(new ProjectionParameter("semi_minor", 6378137.0));
parameters.Add(new ProjectionParameter("latitude_of_origin", 0.0));
parameters.Add(new ProjectionParameter("central_meridian", 0.0));
parameters.Add(new ProjectionParameter("scale_factor", 1.0));
parameters.Add(new ProjectionParameter("false_easting", 0.0));
parameters.Add(new ProjectionParameter("false_northing", 0.0));
IProjection projection = csFac.CreateProjection("Google Mercator", "mercator_1sp", parameters);
IProjectedCoordinateSystem epsg900913 = csFac.CreateProjectedCoordinateSystem(
"Google Mercator", wgs84, projection, LinearUnit.Metre, new AxisInfo("East", AxisOrientationEnum.East),
new AxisInfo("North", AxisOrientationEnum.North));
((CoordinateSystem)epsg900913).DefaultEnvelope = new [] { -20037508.342789, -20037508.342789, 20037508.342789, 20037508.342789 };
_wgs84ToGoogle = ctFac.CreateFromCoordinateSystems(wgs84, epsg900913);
}
return _wgs84ToGoogle;
}
}
CoordinateTransformation
that you used actually works.
You are getting blank image because your ZoomToBox
coordinates are wrong, so it actually shows you the blank part of the image. If you use map.ZoomToExtents();
function instead, to view the whole image before you zoom, it looks something like this:
Now, if I zoom manually in browser to get close-up image of France with this transformation applied, you can see that it's not actually stretched anymore.
As a conclusion, I'd say that you only need to fix your ZoomToBox
coordinates and everything will work just fine. Hope it helps. :)