map.toJSON() not exporting feature layers data

849
6
Jump to solution
09-07-2019 08:36 AM
ManuelGomez
New Contributor

I pull data from a web map that's transitioning to a different end point with updated information and layers. Before, I used to be able to save the whole map to JSON including all feature layers and their features using the map.toJSON() method. In the new web map, I get the map's information (basemapLayers, spatialReference, etc.) and links to the feature layers REST end points, but not the actual data in the layers.

I use this toJSON() to cache the feature layers since they're small enough and has worked great in the past because they only change every few weeks, saving queries to the server.

I'm using iOS SDK 100.6.

What can be causing this? Any server side configuration?

EDIT:

Sample of new layer information when downloading the map:

"operationalLayers" : [
{
"itemId" : "xxxx",
"layerType" : "ArcGISFeatureLayer",
"visibility" : true,
"id" : "xxxx",
"title" : "xxxxx",
"opacity" : 0.88,
"url" : "https:\/\/services.arcgis.com\/xxxxx\/arcgis\/rest\/services\/xxxxx\/FeatureServer\/0"
},

...

Sample of old layer information:

"operationalLayers" : [
{
"visibility" : true,
"id" : "xxx",
"title" : "xxx",
"layerType" : "ArcGISFeatureLayer",
"opacity" : 0.80000000000000004,
"featureCollection" : {
"layers" : [
{
"featureSet" : {
"geometryType" : "esriGeometryPolygon",
"features" : [
{
"attributes" : {
...
},
"geometry" : {
"rings" : [
[
...
]
],
"spatialReference" : {
"latestWkid" : 3857,
"wkid" : 102100
}
}
},
...
]
},
"layerDefinition" : {
"allowGeometryUpdates" : true,
"hasZ" : false,
"maxScale" : 0,
"supportedQueryFormats" : "JSON, geoJSON",
"isDataVersioned" : false,
"drawingInfo" : {
"fixedSymbols" : true,
"renderer" : {
"type" : "simple",
"symbol" : {
"outline" : {
"style" : "esriSLSSolid",
"type" : "esriSLS",
"width" : 3,
"color" : [
38,
115,
0,
255
]
},
"style" : "esriSFSSolid",
"type" : "esriSFS",
"color" : [
38,
115,
0,
88
]
}
},
"transparency" : 0,
"labelingInfo" : [
{
...
}
]
},
"extent" : {
"xmin" : -999999,
"xmax" : -999999,
"spatialReference" : {
"latestWkid" : 3857,
"wkid" : 102100
},
"ymin" : 999999,
"ymax" : 999999
},
"hasAttachments" : false,
"objectIdField" : "xxxx",
"supportsRollbackOnFailureParameter" : true,
"name" : "xxxx",
"geometryType" : "esriGeometryPolygon",
"supportsAdvancedQueries" : true,
"capabilities" : "Create,Delete,Query,Update,Editing",
"supportsStatistics" : true,
"type" : "Feature Layer",
"hasM" : false,
"minScale" : 3988894,
"supportsAttachmentsByUploadId" : true,
"supportsCalculate" : true,
"defaultVisibility" : true,
"supportsValidateSql" : true,
"spatialReference" : {
"latestWkid" : 3857,
"wkid" : 102100
},
"fields" : [
{
"editable" : false,
"alias" : "xxx",
"length" : 0,
"name" : "xxx",
"nullable" : false,
"type" : "esriFieldTypeOID"
},
...
],
"hasStaticData" : false,
"currentVersion" : 10.41
},
"nextObjectId" : 89,
"popupInfo" : {
"showAttachments" : false,
"title" : "xxxx",
"fieldInfos" : [
{
"format" : {
"places" : 0,
"digitSeparator" : true
},
"stringFieldOption" : "textbox",
"isEditableOnLayer" : false,
"visible" : false,
"isEditable" : false,
"label" : "xxx",
"fieldName" : "xxx"
},
...
]
},
"title" : "xxxx"
}
],
"showLegend" : true
}
}

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
Nicholas-Furness
Esri Regular Contributor

Hi.

In the old JSON, you had a map with a featureCollection in it. That is a specific type of FeatureLayer which is, essentially, an in-memory feature layer. When the WebMap is serialized to JSON, you'll see the features included.

In your new JSON, your map is pointing to a feature service. The JSON represents the connection to the service, and the content is obtained by the Runtime as needed as you pan around the map. However, it's not serialized.

You should see the same JSON for 100.5 and 100.6 in each case. It looks like you're using a different map in the two cases.

Let me know if this helps.

View solution in original post

6 Replies
Nicholas-Furness
Esri Regular Contributor

Hi.

In the old JSON, you had a map with a featureCollection in it. That is a specific type of FeatureLayer which is, essentially, an in-memory feature layer. When the WebMap is serialized to JSON, you'll see the features included.

In your new JSON, your map is pointing to a feature service. The JSON represents the connection to the service, and the content is obtained by the Runtime as needed as you pan around the map. However, it's not serialized.

You should see the same JSON for 100.5 and 100.6 in each case. It looks like you're using a different map in the two cases.

Let me know if this helps.

ManuelGomez
New Contributor

We just realized this morning that what you say is exactly what's happening. It's not about the 100.6 upgrade, it's about the map feature layer changing to service.

Which way do you recommend to download the map data in the feature services for offline use, generating a geodatabase or using a manual cache on the Service feature table? Does either expire? Any licensing restrictions?

Old trail data was about 15MB, I doubt it's much bigger now.

Thank youNicholas Furness‌!

0 Kudos
Nicholas-Furness
Esri Regular Contributor

I would recommend the generate geodatabase of those two (the manual cache is meant for in-memory control of features in a given session. You would likely run into problems serializing and deserializing that).

If your data is read-only on the client, and if it doesn't change very often, generating a geodatabase once and distributing that to your clients could be the best way. We have many customers who do this.

And for read-only data (i.e. your Runtime app will not be editing it - you can of course edit the data stored in the service), this can be done with the free Lite license. Also the geodatabase does not expire.

Also note that there is a preplanned workflow for taking the entire map offline if that helps. It depends a lot on the nature of your data, but the preplanned workflow allows you to schedule your data packaging and there is an ArcGIS Online user interface for managing this.

ManuelGomez
New Contributor

Hi Nick!

I was able to make it work and I can download the layers into an offline map using geodatabase files and load them into the map from the device filesystem. The only issue I'm having is one of the layers is not downloading. I believe this layer is composed of different other layers. From the map maintainers: "The new layers are really just one layer.  It’s a hosted feature service which is copied and symbolized different ways in the map."

Do you know what could be happening here? Anything special they would need to do on that specific layer?

 

Thanks!

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Good to hear it's working.

For the problematic layer, layers do have to be "offline enabled" to participate. Assuming it's public, can you share the URL to the layer (DM me if you like)?

By default, new layers created in ArcGIS Online are offline enabled, but some older layers might not be. If it's self-hosted, the owner will likely need to explicitly enable offline capabilities.

You should see errors when taking the layer offline if it's not offline enabled. When you create the AGSGeodatabaseSyncTask and load it, you can then check the featureServiceInfo property and see if syncEnabled is true.

Something like this should work:

gdbSyncTask.load { error in
    if let error = error {
        print("Error loading GDB Sync Task: \(error.localizedDescription)")
        return
    }
    
    guard let info = gdbSyncTask.featureServiceInfo else {
        preconditionFailure("Feature Service Info is not set!")
    }
    
    print("Service can be taken offline: \(info.isSyncEnabled)")
}

Let me know if that helps.

0 Kudos
ManuelGomez
New Contributor

I'll take a look at the sync option. Right now I'm using a AGSOfflineMapTask to get the layers.

It is a public layer but I'd rather DM it. Can you follow me so I can DM? Thanks!

0 Kudos