Closed jkerr5 closed 7 years ago
Can you provide examples of the desired responses?
Starting with the highest priority part (maybe we break this into other issues), the provider needs to be able to specify the list of layers and tables that are available. So, in the service info response, the provider should be able to tell koop to produce something like this:
"layers": [
{ "id": 0, "name": "Parcels" },
{ "id": 1, "name": "Buildings" }
],
"tables": [
{ "id": 2, "name": "Owners" }
]
Less important is serviceDescription which seems to be set to "This is a feature service exposed with Koop, an open source project that turns APIs into features. Service Description information may not be available for all services. For more information, check out https://github.com/koopjs/koop " in the template.
Also, I believe there may be a bug in setting the displayField as the template code is looking for displayFieldName but the actual template has displayField (see https://github.com/FeatureServer/FeatureServer/blob/master/src/templates.js#L50).
Fundamentally, I believe the providers should be able to communicate metadata to koop to be able to customize pretty much any and all fields list in the feature service spec for these responses:
I believe this is actually supported already, if you send back an array of geojson objects to a /layers or /featureserver request it should handle the formatting. but of course that's not documented :)
we can both try that out.
I'll take a look at the display field bug and the additional metadata.
actually, it's supported on /layers but not the plain server info. I'll add that support in. I'll have to figure out the best way to support it on the provider side. Need to decide to between something like
[
{type: 'FeatureCollection'},
{type: 'FeatureCollection'}
]
and
{
name: foo,
layers: [
{type: 'FeatureCollection'},
{type: 'FeatureCollection'}
]
}
leaning towards the latter so it's easier to support server-wide metadata
Thanks. We need to make sure that the layer number can be set though as the provider has to be the one to map that number to an actual layer in the backend.
passing a layer number is already supported. it will be in req.params.layer
inside getData
I mean that the provider needs to be able to tell koop what the layer numbers are when producing the service info response. The examples you gave above did not include a way for me to tell koop what the layer numbers are in my response from the getData() call. I guess we could rely on ordering of the layers that we return as long as the provider makes sure it always returns the layer list in the same order.
I'm going to add support for the server info response. And yes it will be up to the provider to maintain a mapping between layer index and underlying data. Just pointing out that you could already pass a layer id and use that to control the query response
I'll document what the path will be but my thinking is that The provider can either pass a layer id in the metadata object or Koop will assign ids starting from 0
Sounds good.
As a side note, the /layers call doesn't change the "params" at all. The only way (that I see) for the provider to know it is a /layers call is to look at the URL in the req object. That works but you might want to set the "method" for those requests.
/layers will change req.url
But I'll see if there is a more natural way to pass that. Btw that code lives in https://github.com/koopjs/Koop-output-geoservices
Looked at this a bit more. You're going to have to parse /layers
out of the URL. I can't make it a parameter because it would conflict with /:layer
OK, will do on the /layers
function.
This was implemented in bdb4fab711b0de95ba6862bc500b784ca95c838f
Was anything implemented for the /:layer
route? I.E. for the FeatureServer/<layer num>
requests as detailed here http://resources.arcgis.com/en/help/arcgis-rest-api/#/Layer/02r3000000w6000000/
That's all going to be in Provider land. We may need to assign a the same layer id that was requested, but I'm not sure that's going to be necessary for the client applications.
Lets say you have two MarkLogic datasets:
0: Foo 1: Bar
/FeatureServer/0 => getData => callback(null, foo)
/FeatureServer/1 => getData => callback(null, bar)
make sense?
As I understand so far, for a call to /FeatureServer
, the provider should respond with an object like this:
const server = {
description: String // Describes the collection of layers below,
layers: [{ // A collection of all the layers managed by the server
type: 'FeatureCollection',
metadata: {
name: String, // The name of the layer
description: String // The description of the layer
extent: Object || Array // valid extent object or 2 coord array
displayField: String // The display field to be used by a client
id: String // unique identifier field
}
features: [// If all the metadata provided above is provided features are optional.
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [125.6, 10.1]
},
properties: {
name: 'Dinagat Islands'
}
}]
}
}]
}
Are you saying for a call to /FeatureServer/0
, it should use the same structure but just include the info for layer "0"?
No, simply pass geojson, with metadata, as you did before.
I'm adding support for a metadata annotation of geometry type so you won't need to pass any features at all if you choose.
So, if wanted to produce the timeInfo
section like:
"timeInfo" : {
"startTimeField" : "<startTimeFieldName>",
"endTimeField" : "<endTimeFieldName>",
"trackIdField" : "<trackIdFieldName>",
"timeExtent" : [<startTime>, <endTime>],
"timeReference" : {
"timeZone" : "<timeZone>",
"respectsDaylightSaving" : <true | false>
},
"timeInterval" : <timeInterval>,
"timeIntervalUnits" : "<timeIntervalUnits>"
},
for layer "0", how would I return that from the provider to koop?
not supported yet. please open an issue on featureserver
Submitted issue #11
I am looking help trying to create a oracle (non SDE) provider.
So far, i have been able to create a provider able to read data using de koop-provider-socrata example and populating «Model.prototype.getData» method with code accessing the database.
Now i want to create new route for addFeature, deleteFeatures and updateFeatures method.
Here the output of the Debug Console once i have added routes: "Geoservices" output routes for the "provider-socrata" provider Methods
/provider-socrata/rest/info GET, POST /provider-socrata/tokens/:method GET, POST /provider-socrata/tokens/ GET, POST /provider-socrata/rest/services/:host/FeatureServer/:layer/:method GET, POST /provider-socrata/rest/services/:host/FeatureServer/layers GET, POST /provider-socrata/rest/services/:host/FeatureServer/:layer GET, POST /provider-socrata/rest/services/:host/FeatureServer GET, POST /provider-socrata/:host/FeatureServer/:layer/:method GET, POST /provider-socrata/:host/FeatureServer/layers GET, POST /provider-socrata/:host/FeatureServer/:layer GET, POST /provider-socrata/:host/FeatureServer GET, POST /provider-socrata/rest/services/:host/FeatureServer GET, POST /provider-socrata/:host/FeatureServer GET, POST /provider-socrata/rest/services/:host/MapServer GET, POST /provider-socrata/:host/MapServer GET, POST
index.js:239
"provider-socrata" provider routes Methods
/provider-socrata/rest/services/:id/FeatureServer/:layer/addFeatures POST
/provider-socrata/rest/services/:id/FeatureServer/:layer/deleteFeatures POST
/provider-socrata/rest/services/:id/FeatureServer/:layer/updateFeatures POST
My problem is the code is not accessing the method of my controler (code example partial) Controller.prototype.updateFeatures = function (req, res) { res.status(200).send('Welcome to Koop update feature!'); };
It like if the «"Geoservices" output routes for the "provider-socrata" provider Methods » have priority over the «"provider-socrata" provider routes Methods», so when i call URL Like «http://localhost:8080/provider-socrata/rest/services/oracle/FeatureServer/0/updateFeatures» i dont enter into my method, but i enter in the «getData» method probably due to the «/provider-socrata/rest/services/:host/FeatureServer/:layer/:method GET, POST» GeoService route.
I did'nt find any example how to change route priority in order to direct the request into my method.
Yes i am trying to make an CRUD provider that will work with Oracle without SDE installation.
I would appreciate any help or link to documentation on how the route parser work.
Thank.
Yes, as you note, the issue is that the GeoServices output route /provider-socrata/rest/services/:host/FeatureServer/:layer/:method
is handling any requests to /provider-socrata/rest/services/:id/FeatureServer/:layer/addFeatures
. This is because it is registered first and addFeatures
is captured by the :method
parameter.
Currently, there is no way to change the route priority. Output plugins have to be registered before provider plugins, otherwise those output-plugin routes won't get attached to the provider. We could try to change the way registration is executed, but it would be a big change. cc @haoliangyu
@labbr01 - this should probably be it's own issue.
@labbr01 - after some review of the code, this may be easier then I originally surmised. Moved this issue to https://github.com/koopjs/FeatureServer/issues/171.
Allow the provider to control more of the service info response. It should be able to set/override all of the available fields including the available layers and tables.
Allow the provider to control more of the layer/table info response for each of the layers/tables. It should be able to set/override all of the available fields.