Mapsui / Mapsui

Mapsui is a .NET Map component for: MAUI, WPF, Avalonia, Uno, Blazor, WinUI, Xamarin and Eto
https://mapsui.com
MIT License
1.2k stars 315 forks source link

WFS Provider #1918

Closed asim27 closed 1 year ago

asim27 commented 1 year ago

Describe the bug I am not able to create a wfsprovider from latest version 4.0.0-beta.8 WfsProvider method with URI parameter raises System.NullReferenceException: 'Object reference not set to an instance of an object.' on calling InitAsync() method To Reproduce Steps to reproduce the behavior:

  1. Create a WFSProvidere with image
  2. Call .InitAsync() method on the WFSProvider instance.
  3. Handle the exception
  4. See the error

Expected behavior System.NullReferenceException: 'Object reference not set to an instance of an object.'

Screenshots image

Desktop (please complete the following information):

Smartphone (please complete the following information):

gpsaliola commented 1 year ago

I've same problem with WMS provider. I've tested on 4.0.0-beta.5. This is the code:

            XmlDocument capabilities = new XmlDocument { XmlResolver = null };
            capabilities.Load("http://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities&version=1.3.0");
            WmsProvider provider = new WmsProvider(capabilities)
            {
                CRS = "EPSG:3857",
                ContinueOnError = true,
                TimeOut = 20000
            };

            provider.AddLayer("igm25k_lazio_wgs");
            provider.SetImageFormat((provider.OutputFormats)[0]);
            ILayer imageLayer = new ImageLayer("mainmap")
            {
                DataSource = provider, 
            };

            mapView.Map.Layers.Add(imageLayer);

The behavior is that no map is shown and pan and zoom don't work. I've tested on different map server but the behavios is the same. A question. The CRS of the map must be the same of the provider? Thank you.

inforithmics commented 1 year ago

You should use WfsProvider.CreateAsync ... and WmsProvider.CreateAsync ... because Constructors cannot be asynchronous this methods initialize the wfs and wms provider asynchronous because a http call is involved.

gpsaliola commented 1 year ago

Ok, now i've tried this code:

        protected async override void OnAppearing()
        {
            base.OnAppearing();

            mapView.Map = await CreateMapAsync();

            Mapsui.Widgets.ScaleBar.ScaleBarWidget scale = new Mapsui.Widgets.ScaleBar.ScaleBarWidget(mapView.Map)
            {
                TextAlignment = Alignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top
            };
            mapView.Map.Widgets.Add(scale);

            mapView.Map.Layers.Add(await CreateLayerAsync());
        }

        public static async Task<Mapsui.Map> CreateMapAsync()
        {
            var map = new Mapsui.Map { CRS = "EPSG:3857" };
            map.Layers.Add(await CreateLayerAsync());
            return map;
        }

        public static async Task<ILayer> CreateLayerAsync()
        {
            return new ImageLayer("mainmap") { DataSource = await CreateWmsProviderAsync() };
        }

        private static async Task<WmsProvider> CreateWmsProviderAsync()
        {
            const string wmsUrl = "https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities&version=1.3.0";
            var provider = await WmsProvider.CreateAsync(wmsUrl, persistentCache: null);
            provider.ContinueOnError = true;
            provider.TimeOut = 20000;
            provider.CRS = "EPSG:3857";
            provider.AddLayer("igm25k_lazio_wgs");
            provider.SetImageFormat((provider.OutputFormats)[0]);
            return provider;
        }

I obtain the following error: System.ApplicationException: 'Could not download capabilities'

inforithmics commented 1 year ago

I would try https instead of http.

gpsaliola commented 1 year ago

I corrected the above code and tried again but nothing changes. I tried also:

            const string wmsUrl = "https://wms.pcn.minambiente.it/ogc?map=/ms_ogc/WMS_v1.3/raster/IGM_25000.map&service=wms&request=getCapabilities&version=1.3.0";
            var capabilities = new XmlDocument { XmlResolver = null };
            capabilities.Load(wmsUrl);
            var provider = new WmsProvider(capabilities)
            {
                CRS = "EPSG:4326",
            };

and I obtain: System.Net.WebException: 'Error: TrustFailure (Authentication failed, see inner exception.)' It should be noted that if I launch the link in the browser the capabilities xml file is loaded correctly. With OpenLayers the link above works fine.

gpsaliola commented 1 year ago

I've tried the code posted on Mar 30 (see above) with Mapsui 4.0.0-rc.1. Now there aren't errors but map isn't shown. Note that, after added the layer to the map, mapView.Map.Navigator.Resolutions.Count = 0. Did I do something wrong in the code? I've tried the code on Windows 10 + Android (Samsung A53). Thank you.

inforithmics commented 1 year ago

I fixed here a WMSProvider Bug too. https://github.com/Mapsui/Mapsui/pull/2007

The wms Http request was missing service=wms // newer wms service complain about it. older seem to not care.

inforithmics commented 1 year ago

This should be changed

public static async Task<ILayer> CreateLayerAsync()
        {
            return new ImageLayer("mainmap") { DataSource = await CreateWmsProviderAsync() };
        }

to this

    public static async Task<ILayer> CreateLayerAsync()
    {
        return new ImageLayer("mainmap")
        {
            DataSource = await CreateWmsProviderAsync(),
            Style = new RasterStyle()
        };
    }

Because without the Style = RasterStyle() mapsui does not know how to render the imagelayer

inforithmics commented 1 year ago

this line sets the image format to provider.SetImageFormat((provider.OutputFormats)[0]);

I think this is a missing case that needs to be handled in BitmapHelper.LoadBitmap

image/tiff

pauldendulk commented 1 year ago

Because without the Style = RasterStyle() mapsui does not know how to render the imagelayer

This has caused confusion before. We need to improve it. The behavior needs to be consistent for all styles though.

inforithmics commented 1 year ago

I would suggest that The ImageLayer has RasterStyle set as default. So it would work out of the box. But still be customizable.

gpsaliola commented 1 year ago

I've tried the code suggested by inforithmics without success:

`

    protected async override void OnAppearing()
    {
        base.OnAppearing();

        mapView.Map = await CreateMapAsync();
    }

    public async Task<Map> CreateMapAsync()
    {
        var map = new Map {
            CRS = "EPSG:3857"
        };

        Mapsui.Widgets.ScaleBar.ScaleBarWidget scale = new Mapsui.Widgets.ScaleBar.ScaleBarWidget(mapView.Map)
        {
            TextAlignment = Alignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Top
        };
        map.Widgets.Add(scale);

        map.Layers.Add(await CreateLayerAsync());
        return map;
    }

    public static async Task<ILayer> CreateLayerAsync()
    {
        return new ImageLayer("mainmap")
        {
            DataSource = await CreateWmsProviderAsync(),
            Style = new RasterStyle()
        };
    }

    private static async Task<WmsProvider> CreateWmsProviderAsync()
    {
        const string wmsUrl = "https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities&version=1.3.0";
        var provider = await WmsProvider.CreateAsync(wmsUrl, persistentCache: null);
        provider.ContinueOnError = true;
        provider.TimeOut = 20000;
        provider.CRS = "EPSG:3857";
        provider.AddLayer("igm25k_lazio_wgs");
        provider.SetImageFormat((provider.OutputFormats)[1]);
        return provider;
    }

`

Note that EPSG:3857 is not contained in the xml capabilities. There are only: CRS:84, EPSG:4326, EPSG:0 (what does it mean?). May be this the problem? Thank you.

inforithmics commented 1 year ago

You should use EPSG:4326 and use a projection provider

gpsaliola commented 1 year ago

I've changed provider.CRS = "EPSG:3857"; with provider.CRS = "EPSG:4326"; but results are the same. What do you mean by "projection provider"? If the map CRS is 3857 can CRS provider is 4326? It should be considered that I could add layers with different EPSGs. Is it possible? Thank you.

inforithmics commented 1 year ago

Mapsui Projection.

https://mapsui.com/documentation/projections.html

inforithmics commented 1 year ago

There is something special about this wms service. Because in the sample I created here it still does not get the right data. My guess it fetches the wrong coordinates. But still investigating.

https://github.com/Mapsui/Mapsui/pull/2008

gpsaliola commented 1 year ago

Thank you for info. I've made another test with this server (Spain orthophoto): https://www.ign.es/wms-inspire/pnoa-ma?service=wms&request=getCapabilities the layer is: OI.OrthoimageCoverage

Test 1: map CRS: EPSG:3857, CRS provider: EPSG:3857 => it works fine Test 2: map CRS: EPSG:3857, CRS provider: EPSG:4326 => map is shown but scale is wrong and perhaps coordinates Test 3: map CRS: EPSG:4326, CRS provider: EPSG:4326 => as above

May be test 2 needs implementing Mapsui projection as inforithmics said. Sincerely I don't understand how set a working projection. I've seen the example in https://mapsui.com/documentation/projections.html but it seems incomplete or I don't understand the mechanism. Why test 3 doesn't work? It doens't need a reprojection. Thank you.

inforithmics commented 1 year ago

The wms server you are using is an Archivs server. Maybe you can use mapsui.Archie's to fetch the data.

gpsaliola commented 1 year ago

Sorry but I'm a bit confused. Where do you know that the server is Archivs (or Archie)? I've never heard of it before. In other environments (eg: OpenLayers) it is a WMS server like any other.

inforithmics commented 1 year ago

Auto correction error. I meant ArcGis

gpsaliola commented 1 year ago

How do you know it's an ArcGIS server? Is there any documentation or examples on Masui.ArcGIS?

inforithmics commented 1 year ago

It's only a guess because it has arcgis in it's url.

Sample

https://github.com/Mapsui/Mapsui/blob/master/Samples/Mapsui.Samples.Common/Maps/DataFormats/ArcGISImageServiceSample.cs

gpsaliola commented 1 year ago

Thank you. I'll try it. However it responds with a classic XSD WMS version 1.3.0. In OpenLayers the provider used for both my examples is the same (ol.source.TileWMS).

pauldendulk commented 1 year ago

The ArcGIS WMS is supposed to follow the OGC standard. It can always be a bit different but I would expect the implementation is correct. It probably works correctly in a QGIS client as well.

inforithmics commented 1 year ago

It seems that mapsui needs to url encode more parameters.

qgis: (working) https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=12.09808213048060566%2C40.88629975158094254%2C13.48224200548060736%2C42.92140100000000302&CRS=CRS%3A84&WIDTH=1186&HEIGHT=1744&LAYERS=igm25k_lazio_wgs&STYLES=&FORMAT=image%2Fpng&DPI=144&MAP_RESOLUTION=144&FORMAT_OPTIONS=dpi%3A144&TRANSPARENT=TRUE

mapsui: (notWorking) https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?REQUEST=GetMap&BBOX=11.547795320602058,40.606196044092115,13.988179679397943,43.09675795590789&SERVICE=WMS&WIDTH=909&Height=891&Layers=igm25k_lazio_wgs&FORMAT=image/png&CRS=EPSG:4326&VERSION=1.3.0&TRANSPARENT=true&Styles=

inforithmics commented 1 year ago

It is the crs: with EPSG:4326 the axis are changed. So it doesn't load the data, I think the problem is that the extent is initially wrong because this needs to be changed too. see: https://github.com/Mapsui/Mapsui/issues/1925#issuecomment-1493411132

gpsaliola commented 1 year ago

The "DPI", "MAP_RESOLUTION" and "FORMAT_OPTIONS" parameters are not actually needed. So both link are identical except the order of the coordinates. I know post #1925, I reported this issue but I thought the release candidate version fixed it. I've tried the following code:

`

    protected async override void OnAppearing()
    {
        base.OnAppearing();

        mapView.Map = await CreateMapAsync();
    }

    public async Task<Map> CreateMapAsync()
    {
        var map = new Map {
            CRS = "EPSG:3857"
        };

        Mapsui.Widgets.ScaleBar.ScaleBarWidget scale = new Mapsui.Widgets.ScaleBar.ScaleBarWidget(mapView.Map)
        {
            TextAlignment = Alignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Top
        };
        map.Widgets.Add(scale);

        map.Layers.Add(await CreateLayerAsync());
        return map;
    }

    public static async Task<ILayer> CreateLayerAsync()
    {
        return new ImageLayer("mainmap")
        {
            DataSource = await CreateWmsProviderAsync(),
            Style = new RasterStyle(), 
            Attribution = new Hyperlink() { 
                Text = "attributions"
            } 
        };
    }

    private static async Task<WmsProvider> CreateWmsProviderAsync()
    {
        const string wmsUrl = "https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities&version=1.3.0";
        var provider = await WmsProvider.CreateAsync(wmsUrl, persistentCache: null);
        provider.ContinueOnError = true;
        provider.TimeOut = 20000;
        provider.CRS = "CRS:84";
        provider.AddLayer("igm25k_lazio_wgs");
        provider.SetImageFormat((provider.OutputFormats)[1]);
        return provider;
    }
}

` The map is shown but there is an error on scale and coordinates. Zoom flickers.

gpsaliola commented 1 year ago

I've tried this server also but the map isn't shown: https://geoportale.regione.lazio.it/geoserver/ows?service=wms&request=getCapabilities&version=1.3.0 layer: "geonode:ctr_5k_retiled" However, it should be considered that not all services have CRS:84.

inforithmics commented 1 year ago

After the pull request with the fixes goes on this sample should work now.

using Mapsui.Cache;
using Mapsui.Layers;
using Mapsui.Providers.Wms;
using System.Threading.Tasks;
using Mapsui.Nts.Extensions;
using Mapsui.Providers;
using Mapsui.Styles;
using NetTopologySuite.Geometries;

namespace Mapsui.Samples.Common.Maps.DataFormats;

public class WmsProjectionSample : ISample
{
    public string Name => " 6 WMS Projection";
    public string Category => "Data Formats";
    public static IUrlPersistentCache? DefaultCache { get; set; }

    public async Task<Map> CreateMapAsync()
    {
        var map = new Mapsui.Map
        {
            CRS = "EPSG:3857",
        };

        // The WMS request needs a CRS
        map.Layers.Add(await CreateLayerAsync());
        return map;
    }

    public static async Task<ILayer> CreateLayerAsync()
    {
        var dataSource = new ProjectingProvider(await CreateWmsProviderAsync())
        {
            CRS = "EPSG:3857"
        };

        return new ImageLayer("mainmap")
        {
            DataSource = dataSource,
            Style = new RasterStyle()
        };
    }

    private static async Task<WmsProvider> CreateWmsProviderAsync()
    {
        const string wmsUrl = "https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities&version=1.3.0";
        var provider = await WmsProvider.CreateAsync(wmsUrl, persistentCache: DefaultCache);
        provider.ContinueOnError = true;
        provider.TimeOut = 20000;
        provider.CRS = "EPSG:4326";
        provider.AddLayer("igm25k_lazio_wgs");
        provider.SetImageFormat((provider.OutputFormats)[1]);
        return provider;
    }
}
gpsaliola commented 1 year ago

I've tried this code:

`

using System.Threading.Tasks;
using Xamarin.Forms;
using Mapsui;
using Mapsui.Layers;
using Mapsui.Providers.Wms;
using Mapsui.Extensions;
using Mapsui.Widgets;
using Mapsui.Styles;
using Mapsui.Cache;
using System.ComponentModel;
using Mapsui.Projections;
using System.Collections.Generic;

namespace OkMap.Views
{
    public partial class Maps : ContentPage
    {
        public static IUrlPersistentCache DefaultCache { get; set; }

        public  Maps()
        {
            InitializeComponent();
        }

        protected async override void OnAppearing()
        {
            base.OnAppearing();

            mapView.Map = await CreateMapAsync();
            mapView.Map.Navigator.ViewportChanged += mapView_ViewPortChanged;
        }

        public async Task<Map> CreateMapAsync()
        {
            var map = new Map {
                CRS = "EPSG:3857"
            };

            Mapsui.Widgets.ScaleBar.ScaleBarWidget scale = new Mapsui.Widgets.ScaleBar.ScaleBarWidget(mapView.Map)
            {
                TextAlignment = Alignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top
            };
            map.Widgets.Add(scale);

            map.Layers.Add(await CreateLayerAsync());
            return map;
        }

        public static async Task<ILayer> CreateLayerAsync()
        {
            return new ImageLayer("mainmap")
            {
                DataSource = await CreateWmsProviderAsync(),
                Style = new RasterStyle(), 
                Attribution = new Hyperlink() { 
                    Text = "attributions"
                } 
            };
        }

        private static async Task<WmsProvider> CreateWmsProviderAsync()
        {
            const string wmsUrl = "https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities&version=1.3.0";
            //const string wmsUrl = "https://geoportale.regione.lazio.it/geoserver/ows?service=wms&request=getCapabilities&version=1.3.0";
            //const string wmsUrl = "https://www.ign.es/wms-inspire/pnoa-ma?service=wms&request=getCapabilities";

            var provider = await WmsProvider.CreateAsync(wmsUrl, persistentCache: DefaultCache);
            provider.ContinueOnError = true;
            provider.TimeOut = 20000;
            provider.CRS = "EPSG:4326";

            provider.AddLayer("igm25k_lazio_wgs");
            //provider.AddLayer("geonode:ctr_5k_retiled");
            //provider.AddLayer("OI.OrthoimageCoverage");

            provider.SetImageFormat((provider.OutputFormats)[1]);
            return provider;
        }

        private void mapView_ViewPortChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            (double lon, double lat) mapCenter = SphericalMercator.ToLonLat(mapView.Map.Navigator.Viewport.CenterX, mapView.Map.Navigator.Viewport.CenterY);

            Device.BeginInvokeOnMainThread(() => {
                lblCoordinates.Text = mapView.Map.Navigator.Viewport.CenterY.ToString() + " " + mapView.Map.Navigator.Viewport.CenterX.ToString() + " " + GetZoom().ToString();
            });
        }

        private int GetZoom()
        {
            IReadOnlyList<double> resolutions = mapView.Map.Navigator.Resolutions;
            for (int i = 0; i <= resolutions.Count - 1; i++)
            {
                if (mapView.Map.Navigator.Viewport.Resolution >= resolutions[i])
                    return i + 1;
            }
            return resolutions.Count;
        }
    }
}

`

1- Shown scale is wrong 2- Map in streched horizzontally (grid is formed by rectangle and not by square) 3- This statement mapView.Map.Navigator.Resolutions return zero length array I downloaded the latest version 4.0.0-rc.2. What am I doing wrong? Thank you.

charlenni commented 1 year ago

I'm not followed the whole discussion, so I might be wrong.

If you read this info, and compare it with your last code, then I fear, that you try to fit EPSG:4326 tiles in a EPSG:3857 map, which, with my understanding, doesn't work.

gpsaliola commented 1 year ago

I know the difference between datum and projection and between EPSG.4326 and EPSG:3857. Based on Mapsui official documentation (see below), I thought Mapsui was able to convert between these two systems. However even if I crete the map with EPSG:4326 CRS the problem remains the same.

Supported coordinate systems (CRSes)

Out of the box Mapsui only supports the projection between two coordinate systems.

charlenni commented 1 year ago

Yes, Mapsui knows both, but I could not find any conversion from one format to another. What you could do is convert coordinates from one of these projections to Mapsui and vice versa. But there isn't a conversion of raster data.

gpsaliola commented 1 year ago

However even if the CRS of the map = EPSG:4326 and the CRS of the provider = EPSG:4326 there are problems about map streching, map scale and map resolutions (mapView.Map.Navigator.Resolutions return zero length array). If the CRS of the map = EPSG:3857 and the CRS of the provider = EPSG:3857, the map is not streched, map scale is ok but the statement mapView.Map.Navigator.Resolutions always return zero length array.

Test with url: https://www.ign.es/wms-inspire/pnoa-ma?service=wms&request=getCapabilities layer: OI.OrthoimageCoverage

inforithmics commented 1 year ago

My fixes are not yet in 4.0.0-rc.2. so they should be in the next rc or release. As far as I know only tile layers support resolutions and because it is a wms layer it hasn't one.

sample for tiling a wms server (makes it faster too).

  public Task<Map> CreateMapAsync()
    {
        var map = new Map();
        map.Layers.Add(CreateLayer());
        return Task.FromResult(map);
    }

    public static ILayer CreateLayer()
    {
        return new TileLayer(CreateTileSource()) { Name = "Omgevingswarmte (PDOK)" };
    }

    public static ITileSource CreateTileSource()
    {
        const string url = "https://geodata.nationaalgeoregister.nl/omgevingswarmte/wms?SERVICE=WMS&VERSION=1.1.1";
        // You need to know the schema. This can be a problem. Usally it is GlobalSphericalMercator
        var schema = new WkstNederlandSchema { Format = "image/png", Srs = "EPSG:28992" };
        var request = new WmscRequest(new Uri(url), schema, new[] { "koudegeslotenwkobuurt" }.ToList(), Array.Empty<string>().ToList());
        var provider = new HttpTileProvider(request, DefaultCache);
        return new TileSource(provider, schema) { Name = "Omgevingswarmte (PDOK)" };
    }
gpsaliola commented 1 year ago

Actually the list of resolutions is only for me to determine the zoom factor (integer 1-20). Is there another way to determine the zoom factor?

Your solution uses the WkstNederlandSchema class which inherits from TileSchema. I tested it and works fine. Does that mean I have to implement a class for each CRS?

In my software (OkMap Mobile for iOS and Android) the user chooses the TMS/WMS server and the app should work in any case. So far I could only implement TMS (XYZ) because I found a lot of problems with WMS. In the dekstop app (OkMap Desktop) I use Openlayers without problems and the user chooses his server from a list of more than 200 and can define his own. There is no need to supply the CRS in the code because, I suppose, OpenLayers does all the necessary conversions. I would like to do a similar thing with OkMap Mobile and Mapsui. I'll wait for the next rc and I'll do more tests. Thanks so much for the support.

gpsaliola commented 1 year ago

I've made new tests with 4.0.0-rc.3 version. The issue doesn't seem solved (no map was shown). I've tryed these servers with EPSG:3857:

https://www.ign.es/wms-inspire/pnoa-ma?service=wms&request=getCapabilities layer: OI.OrthoimageCoverage

https://wms.geo.admin.ch?service=wms&request=getCapabilities layer: ch.swisstopo.pixelkarte-farbe

I also tried these servers with EPSG:4326:

https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities layer: igm25k_lazio_wgs

https://geoportale.regione.lazio.it/geoserver/ows?service=wms&request=getCapabilities layer: geonode:ctr_5k_retiled

The first seems works but:

  1. Scale is wrong
  2. Map is streched horizontally
  3. Coordinates seems wrong
  4. The zoom level cannot be determined

Is it possible to manage at least these CRS? (the most important) EPSG:3857, EPSG:4326, CRS:84

inforithmics commented 1 year ago
 public async Task<Map> CreateMapAsync()
    {
        var map = new Mapsui.Map
        {
            CRS = "EPSG:3857",
        };

        // The WMS request needs a CRS
        map.Layers.Add(await CreateLayerAsync());
        return map;
    }

    public static async Task<ILayer> CreateLayerAsync()
    {
        var dataSource = new ProjectingProvider(await CreateWmsProviderAsync())
        {
            CRS = "EPSG:3857"
        };

        return new ImageLayer("mainmap")
        {
            DataSource = dataSource,
            Style = new RasterStyle()
        };
    }

    private static async Task<WmsProvider> CreateWmsProviderAsync()
    {
        const string wmsUrl = "https://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer?service=wms&request=getCapabilities&version=1.3.0";
        var provider = await WmsProvider.CreateAsync(wmsUrl, persistentCache: DefaultCache);
        provider.ContinueOnError = true;
        provider.TimeOut = 20000;
        provider.CRS = "EPSG:4326";
        provider.AddLayer("igm25k_lazio_wgs");
        provider.SetImageFormat((provider.OutputFormats)[1]);
        return provider;
    }

This Code works (is the sample that the map displays). A Projection Provider needs to be used so that the WmsCalls are projected from EPSG:4326 to EPSG:3857 and the projection needs to be set on the map

gpsaliola commented 1 year ago

Perfect, everything is clear and thank you for the precious answers. I take advantage of the availability to ask you a couple of things that I haven't understood yet. 1) I don't understand why maps that have both EPSG:4326 and EPSG:3857 only work if I use EPSG:4326 as provider.CRS while they don't work with EPSG:3857 (no conversion should be needed in that case). 2) If a map doesn't have CRS:3857 and CRS:4326 (ex: Italy cadastre https://wms.cartografia.agenziaentrate.gov.it/inspire/wms/ows01.php?service=WMS&request=getcapabilities), if I use EPSG:6706 it doesn't work. Perhaps there is a need to write a conversion routine but there is no documentation on this. 3) The command mapView.Map.Navigator.ZoomToLevel(n) has no effect and the property mapView.Map.Navigator.Resolutions.Counts = 0. How is it possible to set a zoom level and know the current zoom level of the map? PS if I use an XYZ layer and an overlapping WMS layer, the zoom works.

I hope these considerations are also valuable for other users. Thank you very much!!!

inforithmics commented 1 year ago
  1. The Wms Service only supports CRS:84 EPSG:4326, EPSG:0
  2. Needs Mapsui.Extensions and the DotSpatial Projections. (Should know EPSG:6706) (Projection / Shapefile with Projection). It seems DotSpatial does not know this Projection investigating it. https://github.com/Mapsui/Mapsui/pull/2073 Here I found 1 Bug and 1 Missing functionalilty I think this will be released in the next BugFix Release
  3. Does not work because this is not a Tiled Wms Layer, You have to convert the WMS To Tiled. (Data Formats/ 4 WMS called tiled)
gpsaliola commented 1 year ago

Thank you very much. Is it possible to speculate when the release 4 will be released?

inforithmics commented 1 year ago

I think this will take some time but with this link a mapsui version with the fixes can be downloaded and then with a local nuget package folder used.

<configuration>
  <config>
    <add key="local" value="C:\path\to\custom\folder" />
  </config>
</configuration>

C:\path\to\custom\folder

there you put the custom nuget files

https://github.com/Mapsui/Mapsui/suites/13681044682/artifacts/756030684

gpsaliola commented 1 year ago

Many thanks!

gpsaliola commented 1 year ago

Two question.

  1. These files https://github.com/Mapsui/Mapsui/suites/13681044682/artifacts/756030684 are evergreen or where it's possible to download the latest versions?
  2. Which is the file where i should put these tags?
    <configuration>
    <config>
    <add key="local" value="C:\path\to\custom\folder" />
    </config>
    </configuration>

    Thank you!

inforithmics commented 1 year ago

you can add a nuget.config file.

with following content.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="local-packages" value="path/to/your/local/package/folder" />
  </packageSources>
</configuration>
gpsaliola commented 1 year ago

Ok, thank you!

pauldendulk commented 1 year ago

Answered and fixed with https://github.com/Mapsui/Mapsui/pull/2073