Hi,
I want to generate a geodatabase which contain all feature layers data so that I can use that database when there is no internet connection but I do not want to give an option to user to select area of interest. All feature layer data should be download automatically in background.
Thanks,
Kamal
Hi Kamal.
For each layer you specify in the AGSGenerateGeodatabaseParameters object that you pass to generateJobWithParameters(), you can specify an AGSGenerateLayerOption object. That object has a useGeometry property that you can set to false.
Below is the code which I am using to download feature layer. Right now I am getting exception "
Geometry cannot be null in generate geodatabase parameters.
". Actually I want to download all feature layer data automatically in background without user selecting area.
private let FEATURE_SERVICE_URL = NSURL(string: "https://services7.arcgis.com/JRY73mi2cJ1KeR7T/arcgis/rest/services/NewYorkHospitalLayer/FeatureServer/0")!
private var syncTask:AGSGeodatabaseSyncTask!
private var generateJob:AGSGenerateGeodatabaseJob!
private var generatedGeodatabase:AGSGeodatabase!
override func viewDidLoad() {
super.viewDidLoad()
self.map = AGSMap(basemap: AGSBasemap.streetsBasemap())
self.syncTask = AGSGeodatabaseSyncTask(URL: self.FEATURE_SERVICE_URL)
self.addFeatureLayers()
self.mapView.map = self.map
self.generateGeodatabase()
}
func addFeatureLayers() {
self.syncTask.loadWithCompletion { [weak self] (error) -> Void in
if let error = error {
print("Could not load feature service \(error)")
} else {
guard let weakSelf = self else {
return
for (index, layerInfo) in weakSelf.syncTask.featureServiceInfo!.layerInfos.enumerate().reverse() {
//For each layer in the serice, add a layer to the map
let layerURL = weakSelf.FEATURE_SERVICE_URL.URLByAppendingPathComponent(String(index))
let featureTable = AGSServiceFeatureTable(URL:layerURL!)
let featureLayer = AGSFeatureLayer(featureTable: featureTable)
featureLayer.name = layerInfo.name
featureLayer.opacity = 0.65
weakSelf.map.operationalLayers.addObject(featureLayer)
func generateGeodatabase() {
//create AGSGenerateLayerOption objects with selected layerIds
var layerOptions = [AGSGenerateLayerOption]()
let layerOption = AGSGenerateLayerOption(layerID: 0)
layerOption.useGeometry = false
layerOptions.append(layerOption)
//parameters
let params = AGSGenerateGeodatabaseParameters()
params.layerOptions = layerOptions
params.returnAttachments = true
params.attachmentSyncDirection = .Bidirectional
//name for the geodatabase
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let fullPath = "\(path)/\(dateFormatter.stringFromDate(NSDate())).geodatabase"
//create a generate job from the sync task
self.generateJob = self.syncTask.generateJobWithParameters(params, downloadFileURL: NSURL(string: fullPath)!)
//start the job
self.generateJob.startWithStatusHandler({ (status: AGSJobStatus) -> Void in
SVProgressHUD.showWithStatus(status.statusString(), maskType: .Gradient)
}) { [weak self] (object: AnyObject?, error: NSError?) -> Void in
SVProgressHUD.showErrorWithStatus(error.localizedDescription)
else {
SVProgressHUD.dismiss()
Print("Database generated successfully")
Hey Kamal,
Could you be a little more specific about what error you're getting?
Hi Nicholas,
I have updated my above code and I am getting below exception:
"Geometry cannot be null in generate geodatabase parameters."
Hi Kamal Mittal,
Maybe you can try this:
1. Based on our REST API, the Create Replica expects you to have geometry for sure:
ArcGIS REST API - Create Replica
2. Then we compare Runtime iOS SDK how to get Envelope. Then we will found this Class: ArcGIS Runtime SDK for iOS: AGSEnvelope Class Reference
3. Then we check generate Geodatabase Class, we saw this property: generateGeodatabaseExtent property
4. The rest we need to do is how to pass the AGSMapView's AGSEnvelope as a parameter to generateGeodatabaseExtent.
5. In AGSMapView Class Reference there is a visibleArea property. it is a AGSPolygon type, if you check this class, you will find there is a property called AGSEnvelope property in AGSPolygon
6. So technically you can use this line of code to assign the mapview extent as generate Geodatabase Extent:
generateGeodatabaseExtent <SPAN class="operator token">=</SPAN> self<SPAN class="punctuation token">.</SPAN>mapview<SPAN class="punctuation token">.</SPAN>visibleArea<SPAN class="punctuation token">.</SPAN>extent<SPAN class="line-numbers-rows"><SPAN></SPAN></SPAN>
http://resources.arcgis.com/en/help/arcgis-rest-api/#/Create_Replica/02r3000000rp000000/<strong></strong>
Hope this can help.
Nathan
Thanks for the additional info, Yue Wu.
Kamal Mittal To clarify, even though you need to provide a geometry to the AGSGenerateGeodatabaseParameters.extent property, setting the layer options as you did should override that and return all data.
Thanks Yue Wu for good explanation
Thanks Nicholas. Now I am able to get all layer data. There is one question for you. Can I include multiple feature layer url's data into same geodatabase and can use it when offline?.
My pleasure. As long as your feature layers are all come from the same feature service url, for example: Sync/WildfireSync (FeatureServer)
In this feature service, there are three feature layers, and you can use REST to create Replica and the download offline geodatabase can be use in offline mode as long as you setup all three layers to be downloaded.
Thanks for the reply.
Actually I have two different csv files which contain hospital and fire-hydrant data. I have uploaded them to ArcGIS online from the Add data option. Then it create two layers under content section and I have save them as a separate layer and publish it to ArcGIS online as feature layer so I get two different feature layer urls. So my question is can I publish these two layers as a single like Sync/WildfireSync from ArcGIS online?
Another thing is that I have one use case like "42 street is not accessible in newyork city". so how I show that usecase into Arcgis online basemap and publish it as a feature layer.
Last thing is that I am bit confuse about "REST to create Replica". How do I use that and how it can be helpful for me in IOS app.
Kamal Mittal
For hosted feature services, you need to use ArcMap to convert all your csv file by right click and choose Display XY Data. Here is a screenshot to illustrate this. For more information, please check our ArcMap doc Adding x,y coordinate data as a layer—Help | ArcGIS for Desktop
Then you can remove all your original .csv file and publish all the layer to your ArcGIS Online as hosted feature service. In this way, you will have one feature service that contains more than one layer. Here is a screenshot:
However for hosted feature service you do not have all the options to manually change prepare the data to use sync capabilities. Based on our doc Prepare data for offline use—Documentation | ArcGIS Enterprise
For the question about how REST create Replica works, I would recommend you first read our REST API doc first:
Create Replica - ArcGIS REST API
Then combine with our Runtime iOS SDK doc talks about Sync offline edits—ArcGIS Runtime SDK for iOS | ArcGIS for Developers
Les membres connectés peuvent publier, suivre les mises à jour, et plus encore. Nouveau ici ? Inscrivez-vous gratuitement.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.