-
-
Notifications
You must be signed in to change notification settings - Fork 492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Map viewer - support to add layers from ESRI Rest services #5931
Conversation
Good idea. See how this may improve the REST harvester as well. Beacuse REST harvesting from ESRI does not work. The Portal I mean. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't tested it but I made some comments on the code, hope that helps! cheers
addEsriRestFromScratch: function(map, url, name, createOnly, md) { | ||
if (url === '') { | ||
var error = "Trying to add an ESRI layer with no service URL. Layer name is " + name + ". Check the metadata or the map."; | ||
console.warn(error); | ||
return $q.reject(error); | ||
} | ||
var serviceUrl = url.replace(/(.*\/MapServer).*/, '$1'); | ||
var layer = !!name && parseInt(name).toString() === name | ||
var layer = angular.isNumber(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does not work with the comment block above, which is stating that name
is a string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name is not a string, at least from my tests. Check https://land.discomap.eea.europa.eu/arcgis/rest/services/Agriculture/agri_extensification_on_HNVfarmland06/MapServer?f=pjson
The name
is taken from the layer ids, also id=0 is valid, and caused issues with !!name
that was evaluated to false
"layers": [
{
"id": 0,
* If the md object is given, we add it to the layer, or we try | ||
* to retrieve it in the catalog |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This contradicts the name of the methods wich ends with FromScratch
; I think it makes sense to rename this method addEsriRestLayer
for example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method already existed, it's not from this pull request. Can you explain why contradicts the name of the methods which ends with FromScratch
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method already existed, it's not from this pull request.
I know, but this doesn't mean we cannot rename it.
"From scratch" means, in the context of the GN map service, that it does not need to be fed a capabilities document; besides, there is usually another "from capabilities" function that comes with it. For ESRI services it does not work like that so I suggest we remove the "from scratch" from the method name as it is misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I don't see that much of an issue to use the FromScratch
suffix (the method was already there, hasn't been added in this pull request), as the method doesn't use a capabilities document. But if it makes the code more clear will update it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand, but I also disagree: while it may appear minor, an incorrect/misleading function name can significantly diminish the readability of the code. A widely accepted good practice is that whichever piece of code you alter should be cleaner after your changes than prior; this can include minor refactorings like this.
That said, I was simply making a comment about something that striked me as incorrect, not specifically requesting changes on your behalf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's already updated
* | ||
* @param {ol.Map} map to add the layer | ||
* @param {string} url of the service | ||
* @param {string} name of the layer (identifier) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this was admittedly not clear at all before, the name
parameter is optional I think. If not present, the name will be inferred from the URL. Why this is like that, I'm not sure... The logic around name
and layer
in this method is unclear to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me was quite confusing the usage of that parameters, just tried to document it. Please check as at least part of the original code was added by you, maybe you can remember the logic for that variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so I looked in more details and the name
parameter is basically a stringified number used to identify a layer in a map. So 0
, 1
, 2
etc. The weird thing is that this variable is reused later on to store an arbitrary "layer name" in the form of mapId layerNumber
, so for example my-map 0
. On the other hand, the layer
variable is used to store the layer name instead...
The confusing part is that a service url can contain a layer name (e.g. my-map/MapServer/0
) and as such we can infer the layer name from the service url in case the provided layer name argument is incorrect (i.e. not a valid number in string format). This is all unnecessarily complicated, but I understand that this was out of your PR scope. I guess the bare minimum would be to make sure that the function is properly documented (especially the name
and url
arguments).
? name | ||
: url.replace(/.*\/([^\/]*)\/MapServer\/?(.*)/, '$2'); | ||
name = url.replace(/.*\/([^\/]*)\/MapServer\/?(.*)/, '$1 $2'); | ||
|
||
var olLayer = getTheLayerFromMap(map, name, url); | ||
// Use the url and the layer identifier to check if the layer exists | ||
var olLayer = getTheLayerFromMap(map, layer, url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're switching from layer
to name
here, is that intentional? It looks like this could break things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getTheLayerFromMap
was not supporting ESRI Rest layers, so that code was useless and should be used the layer
that is the idenfifier, not the string value that is also unclear why is implemented like this:
name = url.replace(/.*\/([^\/]*)\/MapServer\/?(.*)/, '$1 $2');
For example for https://land.discomap.eea.europa.eu/arcgis/rest/services/Agriculture/agri_extensification_on_HNVfarmland06/MapServer
sets name
to agri_extensification_on_HNVfarmland06
sets name
to agri_extensification_on_HNVfarmland06 0
it's totally unclear the reason for that, but that can't be used to identify the layer in the map.
<div class="flex-col flex-grow"> | ||
<a href="" | ||
class="truncate" | ||
data-ng-click="addLayer(null, $event)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addLayer()
would be enough here I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, will update, copied from similar existing code for WMS services.
evt.stopPropagation(); | ||
}; | ||
|
||
scope.addLayer = function(c) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused function argument
'$translate', | ||
function($translate) { | ||
|
||
var label= $translate.instant('filter'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should go on the scope and be used as {{ ::label }}
in the template (might as well use angularjs for templating 😉 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also this would remove the dependency to $translate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was copied for similar code in other existing directive...
controller.addEsriRestLayer(scope.member); | ||
}; | ||
|
||
scope.isParentNode = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is weird, looks like this directive is built to handle nested layers, but does not actually support it. IIRC layers in ESRI map services are not organized in a tree like in the WMS, so I guess you could get rid of everything related to layer groups and simplify the whole thing.
Future maintainers will thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was copied from other directive for WMS, will cleanup this as I was not sure if nested was supported. I leaved in case that is supported to extend it later.
if (url) { | ||
url = url + '?f=json'; | ||
|
||
if (gnUrlUtils.isValid(url)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the URL is not valid the returned promise will never resolve nor reject; I think you can remove this check and let $http
fail like it should on a malformed URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, will update.
timeout: timeout | ||
}) | ||
.success(function(data, status, headers, config) { | ||
if (!!data.mapName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this check mean? This might require a comment, because it looks like you received a valid response and still decided to throw a "capabilities failed" error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checks if the response has a property mapName
, that is expected to be in the ESRI Rest service document, to avoid you configure any url like https://github.com
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, then it would make sense to return another error, like "The response was not a valid ESRI Rest document" or something like that. I'm not sure this is what happens with other services, we probably just let them fail once they try to parse a non existent property or because of the content-type.
…nMap.addEsriRestFromScratch method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the improvements! The AddEsriLayer
method is still very confusing in its logic, but at least it is better documented now.
Great addition - I believe. I have just refreshed and built a brand new GN 4 instance. Do I need some configuration setting to get the ESRI option under Services? |
@matself the pull request is not yet merged in the About the harvester, that's another feature, not the scope of this pull request. I recommend to open a new issue for this topic. Generally, contributions to GeoNetwork are made through user pull requests or if don't have the skills by hiring a developer who can develop the feature and make a pull request. At https://geonetwork-opensource.org/ you can find a list of some of the companies (among others) that work on GeoNetwork. |
…into esrirest_services
Extend the Add a Layer from > Services with ESRI Rest services: