SharpMap / SharpMap

An easy-to-use mapping library for use in web and desktop applications
GNU Lesser General Public License v2.1
833 stars 306 forks source link

NotSupportedExc occurs when placing a shapefile on a TileAsyncLayer #266

Closed TimThaler closed 4 months ago

TimThaler commented 4 months ago

This exception occurs in ProjNet but i am posting it here since i might do something wrong with SharpMap. We have a shapefile which we want to use as an overlay for a standard -whole world showing - WMTS Webmercator TileAsyncLayer. The WKT representation of the Shapefiles CRS from its *prj reads like this:

GEOGCS["WGS 84", DATUM["World Geodetic System 1984", 
SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], 
UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]]

In SharpMap the two layers are used like this:

 MapBox.MapImageGeneratorFunction = MapBox.LayerListImageGenerator;
 var gss = new NtsGeometryServices();
 var css = new SharpMap.CoordinateSystems.CoordinateSystemServices(new CoordinateSystemFactory(), new CoordinateTransformationFactory(),  SharpMap.Converters.WellKnownText.SpatialReference.GetAllReferenceSystems());

 var pcs = (ProjectedCoordinateSystem)ProjectedCoordinateSystem.WebMercator;
 css.AddCoordinateSystem((int)pcs.AuthorityCode, pcs);
 GeoAPI.GeometryServiceProvider.Instance = gss;
 Session.Instance.SetGeometryServices(gss).SetCoordinateSystemServices(css).SetCoordinateSystemRepository(css);  

 Map map = new Map(){SRID = 3857};
 var tileSource =  new HttpTileSource(tileSchema: new GlobalSphericalMercator(0, 19, (string)null), urlFormatter: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", serverNodes: new[] { "a", "b", "c" }, apiKey: null, name: null, persistentCache: null, tileFetcher: tileFetcher);
 var world = new TileAsyncLayer(tileSource, "world") { SRID = 3857, TargetSRID = 3857};
 string path ="C:\\Shapefile.shp";
 SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(128, 0, 0, 255));
 var vs = new VectorStyle { EnableOutline = true, Outline = new Pen(Color.Orange), Fill = semiTransBrush };
 FileInfo file = new FileInfo(path);

 string full = file.FullName;
 string name = Path.GetFileNameWithoutExtension(full);
 VectorLayer layer = new VectorLayer(name, new ShapeFile(full, true))
 {
       SRID = 4326,
       TargetSRID = 3857,
       Style = vs,
       SmoothingMode = SmoothingMode.AntiAlias
 };

map.Layers.Add(world);
map.Layers.Add(layer);
map.ZoomToBox(new Envelope(1492633.1458179, 1492733.1458179, 6894355.9492769623, 6894455.9492769623));

The part i really do not understand is that the following exception only occures after we build the final exe on a Jenkins Server. With a Debug or Release configuration in VisualStudio (Running with or without the Debugger) it works as intended!

The callstack of the exception:

System.NotSupportedException: No support for transforming between the two specified coordinate systems
   at ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory.CreateFromCoordinateSystems(ICoordinateSystem sourceCS, ICoordinateSystem targetCS)
   at SharpMap.Layers.Layer.get_CoordinateTransformation()
   at SharpMap.Layers.VectorLayer.get_Envelope()
   at SharpMap.Forms.ImageGenerator.LayerListImageRenderer.Generate()
   at SharpMap.Map.MapViewChangedHandler.Invoke()
   at SharpMap.Map.set_Center(Coordinate value)
   at SharpMap.Forms.MapBox.OnMouseMove(MouseEventArgs e)

To track if maybbe one of the SRIDs got lost i added, not elegantly, some debuggingToFile to the Getter

 public virtual ICoordinateTransformation CoordinateTransformation
 {
     get
     {
         lock (lockobj)
         {
             using (var file = File.Open("C:\\Users\\tim\\Desktop\\output.txt", FileMode.OpenOrCreate))
             {
                 file.Seek(0, SeekOrigin.End);
                 using (var stream = new StreamWriter(file))
                     stream.WriteLine("TargetSRID: " + TargetSRID + " SRID: " + SRID);
             }
             if (_coordinateTransform == null && NeedsTransformation)
             {
                 var css = Session.Instance.CoordinateSystemServices;
                 _coordinateTransform = css.CreateTransformation(
                     css.GetCoordinateSystem(SRID), css.GetCoordinateSystem(TargetSRID));
             }
         }

         return _coordinateTransform;
     }
.....
}

There does not seem to be the problem as the output shows: TargetSRID: 3857 SRD: 4326. In the final installed directory i replaced every Dll from ProjNet to SharpMap.* to NTS ... But everytime the error occurs (only in the installation setup). Running it in VisualStudio it is very smooth and perfectly aligned. This i double checked with loading both layers in QGIS.

Why does this error occur and why only in the installation? Any help apprechiated!

TimThaler commented 4 months ago

The issue was that the method CreateFromCoordinateSystems in CoordinateTransformationFactory received null as the sourceCS parameter. We solved this by loading WGS84 in the CoordinateSystemServices.

 var gcs = GeographicCoordinateSystem.WGS84;
 css.AddCoordinateSystem((int)pcs2.AuthorityCode, gcs);

Why this exception only occured with the installation (e.g. the gsc is loaded/not loaded) remains a mystery though :)