Closed pauldendulk closed 1 year ago
Looks like BruTile is expecting a CRS that is not there. What needs to be done is to reproduce this in a unit test. Store the capabilities, load the stream and try to parse it. This should be added in WmtsTests.cs.
I found an error in the file "Client.cs" in the routine "private XmlDocument GetRemoteXml(string url)". You should call the method "r.Read();" after "var r = new XmlTextReader(url, stReader) { XmlResolver = null };" to avoid return "none" in "doc.Load(r);". This is the correct code
private XmlDocument GetRemoteXml(string url)
{
try
{
var doc = new XmlDocument { XmlResolver = null };
using (var task = _getStreamAsync(url))
{
using (var stReader = new StreamReader(task.Result))
{
var r = new XmlTextReader(url, stReader) { XmlResolver = null };
r.Read();
doc.Load(r);
task.Result.Close();
}
}
_nsmgr = new XmlNamespaceManager(doc.NameTable);
return doc;
}
catch (Exception ex)
{
var message = "Could not download capabilities";
Logger.Log(LogLevel.Warning, message, ex);
throw new ApplicationException(message, ex);
}
}
However some WMS maps works fine but other no. For example "Spain Orthophoto" works fine (url = "https://www.ign.es/wms-inspire/pnoa-ma", layer = "OI.OrthoimageCoverage"). The WMS map "Italy PCN Cartografia di base IGM 25.000 - Lazio" doesn't work (url = "http://sgi2.isprambiente.it/arcgis/services/raster/igm25k_lazio_wgs/ImageServer/WMSServer", layer = "igm25k_lazio_wgs").
@gpsaliola Are you posting on the correct issue?
Started work on this in this PR: https://github.com/BruTile/BruTile/pull/183.
Avoiding the crash is easy, but there is still a problem. In BruTile UnitsPerPixel needs to be calculated. Unfortunately WMTS is designed in such a way that we need information about the specific projection to calculate the UnitsPerPixel. We have stored this information for a number of projections but the projection used in the xml is not supported in this code.
Not sure what would be the best solution. Some thoughts:
I believe most of the maps are projected in Transverse Mercator.
It seems that IGN uses EPSG codes 3857 and 2154 (Lambert 93), maybe Brutile doesn't know 2154 which is typically french.
Yes, EPSG 2154 uses "Lambert Conformal Conic (2SP)" projection. It is typically French, but 90% of the world's maps use Transverse Mercator.
So, what about using Lambert 93 in BruTiles ?
It is typically French, but 90% of the world's maps use Transverse Mercator.
So, what do you suggest to use french maps with Brutiles, as I don't need 90% of the world maps but the IGN ones ?
- It would be great if we would need no projection info at all.
- Add an option for the user to add the missing information
- Perhaps we need to treat WMTS different from all other tile sources in BruTile.
After looking at the code just now it seems to me that the only way to avoid the needs for the specific projection information would be to treat the parser for WMTS different than the other. In that case BruTile should not try to set the Resolution.UnitsPerPixel. A using library like Mapsui should do those calculations instead. This would be a big change with consequences for Mapsui.
The problem in this case was that the authority was unknown. We fix here is to return metre as default. This is not guaranteed to be correct for all cases but we already do this for unknown EPSG codes.
In this case the authority was 'IGNF' and the identifier 'LAMB93', which is equal to 'EPSG:2154' for which metre is correct, https://epsg.io/2154. So, this fix solves the problem in this specific case.
Fixed in 5.0.3.
Thanks for all, I can now use French IGN maps with BruTiles 5.0.3 and Mapsui.Forms 4.0.0-beta.5.
Copied from Mapsui https://github.com/Mapsui/Mapsui/issues/1752
Hello,
I use Mapsui.Forms release 4.0.0-beta.5 in a Xamarin application.
The error comes when I try to parse capabilities from IGN Orthophotos layer, the WmtsParser.Parse method throw this exception :
System.ArgumentException: identifier at BruTile.Wmts.CrsUnitOfMeasureRegistry.get_Item (BruTile.Wmts.CrsIdentifier identifier)
This is the code I use :
The same code with an other provider runs well :