Closed lindhor closed 3 years ago
This is an age-old problem. Many links that appear in metadata aren't in fact map service links but for example thumbnails, a getmap request (for WMS for example), web pages (for data download), etc. Metadata allows for multiple links, but only one 'type'.
I agree that a more flexible handling of the links would be useful, but perhaps one that doesn't depend on a metadata element (that cannot be trusted anyway), but instead interrogates the links in the metadata and figures out which one(s) can be consumed in ArcGIS Pro for example.
For example, a layer file (.lyrx) can be opened from a URL into ArcGIS Pro, but is it 'LiveData'? or 'downloadable data'?
Thanks for your comment! You are probably right but I'm not sure how we could evaluate the metadata links to understand what type of content they refer to. Do you have any ideas?
For my purposes it is currently only OGC services I'm looking into providing support for. For that purpose I think the value of ./gmd:distributionInfo/gmd:MD_Distribution/gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:onLine/gmd:CI_OnlineResource/gmd:linkage/gmd:URL
(providing a value like https://mapserver:443/MapService/WMS.axd/vmap0) would be enough - if I could find a stable way to understand that it is a OGC service of some kind. Looking into the response from our server the only metadata I see can be used (apart from guessing based on the URL by Store ring matching) is ./gmd:dataQualityInfo/md:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult/gmd:specification/gmd:CI_Citation/md:identifier/gmd:MD_Identifier/gmd:code/gco:CharacterString
, with values like urn:ogc:serviceType:WebMapService:1.3.0
. I don't think it's possible to count on this to exist on all servers however.
Also, if we implement something like this, would you want to configure it per catalog, per profile or central for all? I think per catalog or profile might make sense.
We have a pretty good link processor in the web appbuilder widget: https://github.com/Esri/geoportal-server-catalog/blob/master/geoportal/src/main/webapp/viewer/widgets/GeoportalSearch/common/LinksProcessor.js
it looks at the URL and understands common patterns for Esri and OGC services. also includes some specific extensions for document-like links.
Thanks for the hint. In my opinion this kind of string matching is the last resort, but maybe we will need to go that way. Currently it looks like the OGC handling only supports WMS and also would require the CSW records to include request=getcapabilities
and service=wms
in order to detect it correctly.
In many cases only the base service URL is returned which complicates detection. In our example the link looks like https://mapserver:443/MapService/WMS.axd/vmap0, i.e. without the parameters.
Of course it would be possible to add a check string matching for "WMS" anywhere in the URL or in the path part of the URL, but I would prefer to avoid it if we could find a more generic way. It would definitely not be sure that all CSW records for WMS services include the text "WMS" anywhere in the URL (and similarly for other kind of content.
We could have some kind of configurable mapping between URL substrings and types using regex to make it more flexible than today. That would however only solve the type detection. Looking at the current code we would still need to have code doing the specific service URL extraction from the value processed if I understand it correctly. I.e. stuff like:
href = href.substr(0, href.indexOf("?"));
href = href.substr(href.indexOf("url=")+4);
href = decodeURIComponent(href);
theLinkType = href.split("/").pop().toLowerCase();
indeed. for ArcGIS based services, the analysis of the path is pretty good, as REST + OGC services provided via ArcGIS follow a defined pattern that cannot be changed. An alternative, but one that requires actually interacting with the link, is to test the link with for example a GetCapabilities request with a service parameter. if the response is valid for the service parameter then you know its type. Some metadata includes a link type element/attribute to go with the link. Although there is no enforced relationship between the type element/attribute and the link, it prevents having to interrogate the link itself.
In https://github.com/Esri/geoportal-server-catalog/blob/master/components/CswClient/Pro/CswClient/Common/CswProfile.cs#L351 it is a hardcoded check that only sets
record.IsLiveDataOrMap = true
and thus enables theAdd to map
button if dc:type equalsliveData
ordownloadableData
.Many CSW servers do not use these properties even if they have services that are meant to be possible to add as layers in ArcGIS Pro.
A suggestion would be to add a comma separated list of custom "live" type values in the config file
CswClient.properties
and let the two current values be specified by default.It might also be worth considering changing the logic a bit so that the button is added for servers that do not support type queries according to their profile (
SupportContentTypeQuery=False
inCSWProfiles.xml
). i.e. something like:Or make this behaviour configurable as well, i.e.
AllowAddToMapButtonForAllServices=true/false
inCswClient.properties
or as a new optional tag in theCSWProfiles.xml
if you want to set this per profile.Note that the
*_GetRecords_Request.xslt
files are configurable to the extent of which records are listed based on for example dc:type equalsliveData
below, but that does not affect the Add to map button, since that decision is based on the metadata in the returned record.