SharpMap as WMS Server

Topics: SharpMap v0.9 / v1.x
Aug 6, 2011 at 7:25 PM

I am trying to setup a demo, using SharpMap v0.9 as WMS server and a client application based on ESRI ArcGIS API for Silverlight.

The WMS service is setup as found in SharpMap's DemoWebSite project (Wms.ashx). The Silverlight client is created using the ESRI Standard Map Application Visual Studio template; a WMSLayer layer - from the ArcGIS Silverlight Toolkit - is used, in order to display the WMS service data.

When running the silverlight application, no map is displayed - as soon as MaxWidth & MaxHeight, in WMS service description, are set to 0, the client is displaying the map.

Although, the map is stretched; when trying to pan/zoom-in the map, the new map lags - it is not on the correct position as supposed!

Does anyone have any previous experience in a similar environment or offer any pointers why is that behavior?

 

Thanks,
George J.

Developer
Aug 8, 2011 at 7:46 AM

 

>When running the silverlight application, no map is displayed - as soon as MaxWidth & MaxHeight, in WMS service description, are set to 0, the client is displaying the map.

Have you set propertly the SRID for the datasource in both the DataSource and The WmsLayer?

Can you post the wms url that the map sends to the server? Simply put a breakpoint in the wms.ashx and debug the HttpRequest.RawURL

 

Developer
Aug 8, 2011 at 7:18 PM
Edited Aug 8, 2011 at 7:19 PM

In addition to D Guidi: when you have this rawUrl, copy and paste it into a browser and see the result there.

Furthermore, it is correct behaviour of a WMS to stretch the image, because you put both the boundingbox you want and the image size into the request and any WMS will render the given boundingbox into the given image size.

And finally, try one of the public available WMS-servers into your silverlight api to see whether that one works.

P.s.: it should work together, because the founding father of SharpMap works at Esri today and he probably has worked on this Silverlight Api as well, because he also did on the Windows Phone Api and I saw him hanging around in the forum over there giving support on this ;-)

Aug 9, 2011 at 7:14 AM

@PeaceNlove: I was counting on this, when I started...

By default default map application template has a ArcGISTiledMapServiceLayer - debugging the problem as D_Guidi suggested, I found out, although the custom WMS service is stating that it supports only EPSG:4326, it gets a request to serve on EPSG:102100

http://localhost:12346/Wms.ashx?SERVICE=WMS&REQUEST=GetMap&WIDTH=1920&HEIGHT=984&FORMAT=image/png&LAYERS=Countries,Rivers,Cities,CountryLabels,CityLabels&STYLES=&BGCOLOR=0xFFFFFF&TRANSPARENT=TRUE&VERSION=1.3.0&CRS=EPSG:102100&BBOX=-20037508.3427892,-10269223.0256795,20037508.3427892,10269223.0256795

When removing ArcGISTiledMapServiceLayer, the request changes to

http://localhost:12346/Wms.ashx?SERVICE=WMS&REQUEST=GetMap&WIDTH=1920&HEIGHT=984&FORMAT=image/png&LAYERS=Countries,Rivers,Cities,CountryLabels,CityLabels&STYLES=&BGCOLOR=0xFFFFFF&TRANSPARENT=TRUE&VERSION=1.3.0&CRS=EPSG:4326&BBOX=-92.25,-183.15198059082,92.25,176.84801940918

which looks correct. Although when I copy/paste this request on my browser I get the stretched I see on the Silverlight client.

This is normal?

 

Developer
Aug 9, 2011 at 7:29 AM

Is reprojecting the data at your WMS from EPSG:4326 to EPSG:102100 an option for you? It looks like a projection mismatch and the most straigthforward solution would be to reproject the data which you have.

OGR2OGR from FWTools can do the reprojecting and if you have ArcGIS9.3 or above, you can use that one as well.

I also had the projection issues when working with Windows Phone api and my solution was to stick to the Windows Phone supported projections.

Developer
Aug 9, 2011 at 7:43 AM
Edited Aug 9, 2011 at 7:43 AM

As a suggestion, I think (I hope, actually: I'm absolutely not sure) that EPSG:102100 is a code for web mercator: http://forums.esri.com/Thread.asp?c=93&f=984&t=288607)

If your source data is EPSG 4326, define with this code your datasource and add a CoordinateTransformation from 4326 to 900913, and see if your data is shown well :)

With this you can reproject on-the-fly your data source, that of course is slower respect to reproject once your data using OGR2OGR

Developer
Aug 9, 2011 at 9:16 AM
Edited Aug 9, 2011 at 9:16 AM

If you reproject to 900913, you still have to set the SRID in your WMS at EPSG:102100

I'm not sure whether this affects the CoordinateTransformation you also set when you do it on the fly. Have never done that.

Developer
Aug 9, 2011 at 10:33 AM
Edited Aug 9, 2011 at 10:35 AM
PeaceNlove wrote:

If you reproject to 900913, you still have to set the SRID in your WMS at EPSG:102100

I'm not sure whether this affects the CoordinateTransformation you also set when you do it on the fly. Have never done that.

>If you reproject to 900913, you still have to set the SRID in your WMS at EPSG:102100

http://sharpmap.codeplex.com/SourceControl/changeset/view/91733#1779839 can be useful

Aug 9, 2011 at 7:15 PM

I am trying to create the transformation with the following code - based on Morten Nielsen post http://www.sharpgis.net/post/2006/07/07/Applying-on-the-fly-transformation-in-SharpMap.aspx:

        public static ProjNet.CoordinateSystems.Transformations.ICoordinateTransformation TransformationToWebMercatorAuxiliarySphere(ProjNet.CoordinateSystems.ICoordinateSystem sourceCoordinateSystem)
        {
            string Wkt_102100 = "PROJCS[\"WGS_1984_Web_Mercator_Auxiliary_Sphere\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator_Auxiliary_Sphere\"],PARAMETER[\"False_Easting\",0.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],PARAMETER[\"Standard_Parallel_1\",0.0],PARAMETER[\"Auxiliary_Sphere_Type\",0.0],UNIT[\"Meter\",1.0],AUTHORITY[\"ESRI\",\"102100\"]]";
 
            ProjNet.CoordinateSystems.CoordinateSystemFactory csFactory = new ProjNet.CoordinateSystems.CoordinateSystemFactory();
            ProjNet.CoordinateSystems.ICoordinateSystem targetCoordinateSystem = csFactory.CreateFromWkt(Wkt_102100);
 
            ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory ctFactory = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory();
            return ctFactory.CreateFromCoordinateSystems(sourceCoordinateSystem, targetCoordinateSystem);
        } 

The WKT code for World Mercator Auxiliary Sphere, is taken from ESRI support page http://support.esri.com/en/knowledgebase/techarticles/detail/37329 (attached .zip file contains an xml file that includes it).

The code on the return statement, I get the exception:

{"Projection Mercator_Auxiliary_Sphere is not supported."}

   at ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.CreateCoordinateOperation(IProjection projection, IEllipsoid ellipsoid, ILinearUnit unit) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:line 274
   at ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.Geog2Proj(IGeographicCoordinateSystem source, IProjectedCoordinateSystem target) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:line 124
   at ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.CreateFromCoordinateSystems(ICoordinateSystem sourceCS, ICoordinateSystem targetCS) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:line 49
   at Standard.Map.App.Web.MapHelper.TransformationToWebMercatorAuxiliarySphere(ICoordinateSystem sourceCoordinateSystem) in C:\Projects\Silverlight\Standard.Map.Solution\Standard.Map.App.Web\MapHelper.cs:line 130
   at Standard.Map.App.Web.MapHelper.InitializeMap(Size size) in C:\Projects\Silverlight\Standard.Map.Solution\Standard.Map.App.Web\MapHelper.cs:line 41
   at Standard.Map.App.Web.Wms.ProcessRequest(HttpContext context) in C:\Projects\Silverlight\Standard.Map.Solution\Standard.Map.App.Web\Wms.ashx.cs:line 52
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Is this a limitation for Proj.NET? Any suggestions to create the transformation?


Developer
Aug 10, 2011 at 7:31 AM
Edited Aug 10, 2011 at 7:33 AM

Yes, thats a limitation. Since the Dutch projections are also not supported, I never do reprojecting on the fly in SharpMap and do al the reprojecting once with ArcGIS or with OGR2OGR.

But I haven't used Proj.Net for a while, so things might have changed, so maybe a SharpMapper with more experience here can give you more advice on how to do it within SharpMap.

Developer
Aug 10, 2011 at 7:48 AM

Using EPSG:3857 (or 900913, like the sample I've linked earlier) don't works?

http://forums.esri.com/Thread.asp?c=93&f=984&t=288607

"102100 is now 3857 (definitely for prerelease). 102100 is a projected coordinate system that uses Mercator. Mercator is a conformal projection so it maintains shapes, not areas, and not distances. 4326 is WGS 1984, a geographic coordinate system which can has its own issues with calculating areas and distances. 
One of the reasons (that I've heard) for why ArcGIS.com (ex-ArcGIS Online) is now providing data in Web Mercator is that it makes it easy to mash up data with the big online services, so for that reason, you will want to use 102100/3857. "

Developer
Aug 10, 2011 at 8:00 AM

Try the WKT string from EPSG:3785

PROJCS["Popular Visualisation CRS / Mercator",GEOGCS["Popular Visualisation CRS",DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137,0,AUTHORITY["EPSG","7059"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6055"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4055"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],AUTHORITY["EPSG","3785"],AXIS["X",EAST],AXIS["Y",NORTH]]

more on the EPSG-codes over here: http://spatialreference.org/ref/epsg/3785/

 

 

Aug 10, 2011 at 10:24 AM
PeaceNlove wrote:

Try the WKT string from EPSG:3785

PROJCS["Popular Visualisation CRS / Mercator",GEOGCS["Popular Visualisation CRS",DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137,0,AUTHORITY["EPSG","7059"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6055"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4055"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],AUTHORITY["EPSG","3785"],AXIS["X",EAST],AXIS["Y",NORTH]]

more on the EPSG-codes over here: http://spatialreference.org/ref/epsg/3785/ 

I changed your WKT code to the following because Proj.NET gave me an error about the position of the UNIT over PROJECTION:

PROJCS[\"Popular Visualisation CRS / Mercator\",GEOGCS[\"Popular Visualisation CRS\",DATUM[\"Popular_Visualisation_Datum\",SPHEROID[\"Popular Visualisation Sphere\",6378137,0,AUTHORITY[\"EPSG\",\"7059\"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6055\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4055\"]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"central_meridian\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],AUTHORITY[\"EPSG\",\"3785\"],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]

But it looks that something is missing from the definition:

Exception Details:
System.ArgumentException: Missing projection parameter 'latitude_of_origin'

Source Error:
Line 130:            return ctFactory.CreateFromCoordinateSystems(sourceCoordinateSystem, targetCoordinateSystem);

Stack Trace:
[ArgumentException: Missing projection parameter 'latitude_of_origin']
   ProjNet.CoordinateSystems.Projections.Mercator..ctor(List`1 parameters, Boolean isInverse) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Projections\Mercator.cs:108
   ProjNet.CoordinateSystems.Projections.Mercator..ctor(List`1 parameters) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Projections\Mercator.cs:74
   ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.CreateCoordinateOperation(IProjection projection, IEllipsoid ellipsoid, ILinearUnit unit) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:256
   ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.Geog2Proj(IGeographicCoordinateSystem source, IProjectedCoordinateSystem target) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:124
   ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.CreateFromCoordinateSystems(ICoordinateSystem sourceCS, ICoordinateSystem targetCS) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:49
   ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.Geog2Proj(IGeographicCoordinateSystem source, IProjectedCoordinateSystem target) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:134
   ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.CreateFromCoordinateSystems(ICoordinateSystem sourceCS, ICoordinateSystem targetCS) in D:\Development\Codeplex\Proj.Net\SharpMap.CoordinateSystems\CoordinateSystems\Transformations\CoordinateTransformationFactory.cs:49
   Standard.Map.App.Web.MapHelper.TransformationToWebMercatorAuxiliarySphere(ICoordinateSystem sourceCoordinateSystem) in C:\Projects\Silverlight\Standard.Map.Solution\Standard.Map.App.Web\MapHelper.cs:130
   Standard.Map.App.Web.MapHelper.InitializeMap(Size size) in C:\Projects\Silverlight\Standard.Map.Solution\Standard.Map.App.Web\MapHelper.cs:41
   Standard.Map.App.Web.Wms.ProcessRequest(HttpContext context) in C:\Projects\Silverlight\Standard.Map.Solution\Standard.Map.App.Web\Wms.ashx.cs:52
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +100
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

I get the same I get using the contents from the .prj file from http://spatialreference.org/ref/epsg/3785/

I will post the same issue on Proj.NET discussions, perhaps somebody there can figure it out...

Developer
Aug 10, 2011 at 10:41 AM

BTW try with this code

 public static ICoordinateTransformation LatLonToGoogle()
        {
            CoordinateSystemFactory csFac = new CoordinateSystemFactory();
            CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();
            IGeographicCoordinateSystem sourceCs = csFac.CreateGeographicCoordinateSystem(
                "WGS 84",
                AngularUnit.Degrees,
                HorizontalDatum.WGS84,
                PrimeMeridian.Greenwich,
                new AxisInfo("north", AxisOrientationEnum.North),
                new AxisInfo("east", AxisOrientationEnum.East));

            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 targetCs = csFac.CreateProjectedCoordinateSystem(
                "Google Mercator",
                sourceCs,
                projection,
                LinearUnit.Metre,
                new AxisInfo("East", AxisOrientationEnum.East),
                new AxisInfo("North", AxisOrientationEnum.North));
            return ctFac.CreateFromCoordinateSystems(sourceCs, targetCs);
        }

Aug 10, 2011 at 10:46 AM

I found the correct WKT code from 3785 in Proj.NET documentation: http://projnet.codeplex.com/wikipage?title=CommonWellKnownText

So in order to convert to from any coordinate system to EPSG:3785 is:

        public static ProjNet.CoordinateSystems.Transformations.ICoordinateTransformation TransformationToWebMercatorAuxiliarySphere(ProjNet.CoordinateSystems.ICoordinateSystem sourceCoordinateSystem)
        {
            string EPSG_3785 = "PROJCS[\"Popular Visualisation CRS / Mercator\", GEOGCS[\"Popular Visualisation CRS\", DATUM[\"Popular Visualisation Datum\", SPHEROID[\"Popular Visualisation Sphere\", 6378137, 0, AUTHORITY[\"EPSG\",\"7059\"]], TOWGS84[0, 0, 0, 0, 0, 0, 0], AUTHORITY[\"EPSG\",\"6055\"] ], PRIMEM[\"Greenwich\", 0, AUTHORITY[\"EPSG\", \"8901\"]], UNIT[\"degree\", 0.0174532925199433, AUTHORITY[\"EPSG\", \"9102\"]], AXIS[\"E\", EAST], AXIS[\"N\", NORTH], AUTHORITY[\"EPSG\",\"4055\"] ], PROJECTION[\"Mercator\"], PARAMETER[\"False_Easting\", 0], PARAMETER[\"False_Northing\", 0], PARAMETER[\"Central_Meridian\", 0], PARAMETER[\"Latitude_of_origin\", 0], UNIT[\"metre\", 1, AUTHORITY[\"EPSG\", \"9001\"]], AXIS[\"East\", EAST], AXIS[\"North\", NORTH], AUTHORITY[\"EPSG\",\"3785\"]] "; 

            ProjNet.CoordinateSystems.CoordinateSystemFactory csFactory = new ProjNet.CoordinateSystems.CoordinateSystemFactory();
            ProjNet.CoordinateSystems.ICoordinateSystem targetCoordinateSystem = csFactory.CreateFromWkt(EPSG_3785);

            ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory ctFactory = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory();
            return ctFactory.CreateFromCoordinateSystems(sourceCoordinateSystem, targetCoordinateSystem);
        }

Currently I get no map in my project, but I have to check my code...

Coordinator
Aug 10, 2011 at 10:58 AM

Please - I know I had it wrong all the time - the correct name is (as diego said) EPSG:3857

If you find any reference in this forum to EPSG:3785 or in the repository, let me know.

cheers FObermaier