Hi,
I have updated geoserver to version 2.14 and after the upgrade using the WPF Viewer Example when I do the LoadAsync to get the capabilities of the Workspace:
Uri wmtsUri = new Uri("http://localhost:8070/geoserver/World/gwc/service/wmts?REQUEST=getcapabilities");
myWmtsService = new WmtsService(wmtsUri);
await myWmtsService.LoadAsync();
Solved! Go to Solution.
With 100.5, I dropped an unmodified GeoServer 2.15.1 warfile on my server, and was able to load jpeg and png types, EPSG:900913 and EPSG:4326 using the REST capabilities endpoint. If my basemap was already set to SpatialReferences.WebMercator, I did need to force the TileMatrixSetId, which was not a problem as the WmtsLayer has an overloaded constructor to do this. I just needed to change from the ctor that uses LayerInfo arguments to the one with the URI , layer Id, and TileMatrixSetId arguments. I use a loop over LayerInfos in the WmtsService, creating a WmtsLayer for each. Also, with 100.5 I can use the native GroupLayer now instead of my hacked implementation to contain the layers.
I got an "Invalid XML.: Parser couldn't move inside Keywords." exception.
Hello, Gonzalo! We received several reports of compatibility problems between ArcGIS Runtime and recent GeoServer versions.
You can resolve the "couldn't move inside Keywords" problem by adding at least one keyword for the overall service. This can be done via GeoServer web interface, under Services > WMTS > Service Metadata. You can find technical details here: https://community.esri.com/thread/222268-wmts-retrieval-from-geoserver-with-net-runtime-1001#comment...
Note that even after working around the "Keywords" problem, WMTS services from this GeoServer may not work as expected in Runtime. We are investigating these problems. I'll post more information here when it is available.
Hi Matvei, thanks for the answer.
Ok, I'll be expecting news from you regarding this issue. Apart from this, will there be some improvements in wmts poor performance with arcgis sdk .net?
Regards
Matvei & Gonzalo,
I have been using Runtime SDK .NET and GeoServer. With GeoServer 2.12.1 and Runtime 100.4, WMTS was working quite well for raster layers. After updating GeoServer to 2.14.1 WMTS layers (using the exact same Runtime SDK code) failed to display. I have tracked down the issue to the fact that GeoServer 2.12.1 did not send Layer Resource URL elements in the capabilities documents, and in newer versions it does. To verify this is source of the issue, I modified the Geowebcache gwc-wmts library used by GeoServer to not include the Layer Resource URL elements (in bold below), and my raster layers displayed properly.
Here are the lines in the WMTS Capabilities document which break Runtime SDK WmtsLayer for raster data:
<Layer>
<Style isDefault="true">
<ows:Identifier>raster</ows:Identifier>
<LegendURL format="image/png" xlink:href="http://localhost:8080/geoserver/ows?service=WMS&request=GetLegendGraphic&format=image%2Fpng&width=20..." width="20" height="20"/>
</Style>
...
<ResourceURL format="image/png" resourceType="tile" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format=image/png"/>
<ResourceURL format="image/jpeg" resourceType="tile" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format=image/jpeg"/>
<ResourceURL format="text/plain" resourceType="FeatureInfo" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}?format=text/plain"/>
<ResourceURL format="application/vnd.ogc.gml" resourceType="FeatureInfo" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}?format=application/vnd.ogc.gml"/>
<ResourceURL format="text/xml" resourceType="FeatureInfo" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}?format=text/xml"/>
<ResourceURL format="application/vnd.ogc.gml/3.1.1" resourceType="FeatureInfo" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}?format=application/vnd.ogc.gml/3.1.1"/>
<ResourceURL format="text/xml" resourceType="FeatureInfo" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}?format=text/xml"/>
<ResourceURL format="text/html" resourceType="FeatureInfo" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}?format=text/html"/>
<ResourceURL format="application/json" resourceType="FeatureInfo" template="http://localhost:8080/geoserver/gwc/rest/wmts/TestWS:World/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}?format=application/json"/>
</Layer>
So it looks like GeoServer is advertising tile and feature REST endpoints, but then puking when the client tries to access them. The KVP endpoints still work, as demonstrated in the tile layer preview in GeoServer web app, but the client must ignore the REST capability and use KVP only to work.
Furthermore, upon inspecting the requests generated by Runtime SDK WMTS layer, it seems to choose the "FeatureInfo" "application/json" resource, for which it cannot fill in the parameters correctly (see below). in spite of setting PreferredImageFormat = TileImageFormat.Png before LoadAsync(). That would not work even if GeoServer was properly implementing the REST endpoints. I changed geowebcache to only include the tile Resource URLS and the tile requests were formatted properly, but GeoServer still returns 404 response code.
So it is broken on both ends.
For the time being the only solution seems to be to force KVP. As this was removed on the SDK client side, you'll need to stick with GeoServer 2.12.1 or modify/revert Geowebwebcache gwc-wmts-1xxx.jar
Another alternative may be the TMS service, which I think is supported in GeoServer.
Hope this is helpful,
Charles
Additional information... The 404 responses I saw when I made geowebcache return only "tile" ResourceURLs was due to new authorization configuration in newer GeoServer versions. I made anonymous access OK for gwc REST GETs and it works, but then it seems the {style} placeholder tag in the ResourceURL is not properly populated by WmtsLayer, so once ArcGIS Runtime sorts out the preferred format being ignored and properly handles the {style} placeholder (perhaps an upper/lower case issue?) it should work.
You are correct, Runtime 100.4 had trouble using ResourceURL templates correctly in this case. Specifically:
- WMTSLayer was using the last ResourceURL listed, instead of choosing an appropriate one for the TileImageFormat.
- WMTSLayer was case-sensitive when looking for the {Style} placeholder.
We've fixed these issues internally — expect it to be available in a Runtime update in the near future. I will update this discussion when it is released. We've also expanded our unit-test suite to check interoperability with multiple GeoServer versions.
Note that newer GeoServer/GWC versions also have a few quirks on its end of things, not specific to Runtime. You've already noticed one (anonymous access to GWC REST endpoints is off by default) and we've noticed another one (unnamed WMTS styles will cause RequestRejectedException).
Charles Roberts Gonzalo Muöoz — Good news! — ArcGIS Runtime 100.5.0 was released this week! It makes several improvements to GeoServer/GWC compatibility. Upgrading to this version should resolve the WMTS problems that you are experiencing. Please let us know how it goes!
With 100.5, I dropped an unmodified GeoServer 2.15.1 warfile on my server, and was able to load jpeg and png types, EPSG:900913 and EPSG:4326 using the REST capabilities endpoint. If my basemap was already set to SpatialReferences.WebMercator, I did need to force the TileMatrixSetId, which was not a problem as the WmtsLayer has an overloaded constructor to do this. I just needed to change from the ctor that uses LayerInfo arguments to the one with the URI , layer Id, and TileMatrixSetId arguments. I use a loop over LayerInfos in the WmtsService, creating a WmtsLayer for each. Also, with 100.5 I can use the native GroupLayer now instead of my hacked implementation to contain the layers.
Update:
I am not sure if it is a bug or not, but when I access my service like this:
http://localhost:8888/geoserver/gwc/service/wmts?request=GetCapabilities
I see all published layers in the ServiceInfo.LayerInfos list.
If I access it like this (REST):
http://localhost:8888/geoserver/gwc/service/wmts/rest/WMTSCapabilities.xml
I see only the first layer in the LayerInfos list.