POST
|
I'm attempting to recreate all tiles for a tile cache service using the Manage Map Server Cache Tiles geoprocessing tool. I've performed this operation successfully on other services before but this time my client recently upgraded to ArcGIS Pro v2.6.3 and now when I open the tool, the scale parameter is not visible. This is a required parameter, so I cannot run the tool without specifying it. What is causing this behavior? Is there a workaround I can use to run the tile cache creation job?
... View more
12-28-2020
12:25 PM
|
0
|
1
|
805
|
POST
|
That turned out to be exactly the problem. My feature services were added using the "Search for Layer" and selected from the portal. The services were published using the hosting server which is behind the firewall. Adding them from the web and entering the pubic facing url worked like a charm. Thanks so much!
... View more
09-25-2020
05:01 PM
|
0
|
0
|
849
|
POST
|
I have an iOS Runtime SDK application (v 100.7) to which I recently added an offline mode which allows the user to select an area of interest on the map and a replica is created including all the feature services. I followed the pattern described in this article if you want to see implementation details. The AGSOfflineMapTask is created from a web map portal item I created on my company's on-premise Portal (enterprise 10.7.1). We use a reverse proxy server configured like this diagram. Activating offline mode fails and generates the following error for every service contained in the web map: "A server with the specified hostname could not be found", then gives the url of the internal url rather than the public-facing url outside the firewall. I made sure that the url for the web map portal item supplied to the AGSOfflineMapTask uses the public-facing url, but it seems that the call to start() function makes requests to the internal urls and I don't have a way to change that, so the requests are being blocked by the firewall. I'm currently relying on a workaround by temporarily changing the hosting server for portal to the dmz url and republishing all the services contained in the map which works, but this is not a good solution because it violates our security policy. I could use a suggestion for a better way of downloading a portion of the map for offline use.
... View more
09-23-2020
04:07 PM
|
0
|
2
|
898
|
POST
|
I built a web map which uses this vector basemap and is intended to be used offline. The offline function works with both envelope and polygon areas of interest. However, my client requested I replace the basemap with the World Imagery raster basemap which would be more useful to field workers. However, the polygon selection no longer works in the new web map and a rectangle is always returned. The web map is downloaded by an ArcGIS runtime for iOS application following How to Take a Map Offline. I have no explanation for the failure other than the switch from vector to raster. Is there another explanation? Is it possible to deliver both satellite imagery and polygon area of interest to my client?
... View more
05-06-2020
04:15 PM
|
0
|
0
|
441
|
POST
|
I've got an iOS Runtime SDK app which with an Offline Sync mode and I'm trying to add a map image layer to the offline map. I have enabled offline sync for all of the operational feature layers according to this article, but there are business reasons preventing me from publishing the map image layer in the same manner. These are the blocking issues: There are two feature classes which are created from database views, which cannot enable archiving. Three feature classes utilize branch versioning which for business reasons cannot be dropped. The other layers (about two dozen) are not versioned. This mix of versioning is not allowed when enabling sync. Two of the feature classes came from File Geodatabases rather than the necessary Enterprise Geodatabase. My question is if it is possible to include this map image layer in the offline map without publishing it as a sync-enabled feature service. I only have experience publishing layers in that manner, but my instincts tell me image layers need to be handled a different way I am not aware of. The map image layer is effectively readonly, so I wonder if it is necessary to fix all the underlying issues described above.
... View more
04-23-2020
12:51 PM
|
0
|
1
|
739
|
POST
|
Turns out it is necessary to secure any services where editor tracking is enabled. There is no way to keep it available to everyone and for new features to populate the createdby/modifiedby fields. After re-publishing the service, but only making it available to authenticated users, the user id was recorded in these fields.
... View more
04-22-2020
04:44 PM
|
0
|
0
|
691
|
POST
|
I have an app which uses the iOS Runtime SDK v100.6 which loads feature services from an on-premise installation of Portal for ArcGIS v10.7.1. The feature layers were loaded onto the map directly from their urls without requiring the user to authenticate with the portal. When the user creates a new feature and applies the edits, I can view the new feature in ArcGIS Pro, but the CREATIONUSER and LASTUSER fields both have the value "Esri_Anonymous". I recognized that it is necessary to log the user into the portal before making edits, so I modified the initialization to do so (Slight variation from Esri documentation😞 override func viewDidLoad() {
self.portal = AGSPortal(url: NSURL(string: "https://mycompanysserver.com/portal")! as
URL, loginRequired: true)
self.portal?.load(completion: { (err) in
if let error = err {
print(error)
}
else {
print("Successfully logged into portal.")
self.addOperationalLayersFromPortalItem()
}
}
}
func addOperationalLayersFromPortalItem() {
var loadedCount = 0
DispatchQueue.main.async {
SVProgressHUD.showProgress(0, status: "Loading Layer \(loadedCount)/25")
}
self.featureLayers.removeAll()
self.allLayers.removeAll()
if let portal = self.portal {
if let user = portal.user { //If logged in successfully
var loadedCount = 0
DispatchQueue.main.async {
SVProgressHUD.showProgress(0, status: "Loading Layer \(loadedCount)/25")
}
let featureStagingService = AGSPortalItem(portal: portal, itemID: self.featureStagingServiceId)
for i in 1 ... 25 {
let layer = AGSFeatureLayer(item: featureStagingService, layerID: i)
featureLayers.append(layer)
allLayers.append(layer)
layer.load(completion: { (error) in
loadedCount = loadedCount + 1
self.updateLoadingProgress(loadedCount, outOf: 25, withMessage: "Loading Layer")
guard error == nil else {
print("Error loading layer ", i, ": ", error!.localizedDescription)
return
}
})
}
self.onFinishedLoading()
}
}
}
But loading the layers like this fails: Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_kCFStreamErrorCodeKey=8, NSUnderlyingError=0x2839092c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_kCFStreamErrorCodeKey=8, _kCFStreamErrorDomainKey=12}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <340D6EFF-6BD9-47E7-AD68-F9508910203E>.<115>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <340D6EFF-6BD9-47E7-AD68-F9508910203E>.<115>" ), NSLocalizedDescription=A server with the specified hostname could not be found., NSErrorFailingURLStringKey=https://company-server-behind-firewall.com/mapgallery/rest/services/EmergencyManagement/EM_FeatureStaging2/FeatureServer/15?f=json&returnAdvancedSymbols=true, NSErrorFailingURLKey=https://company-server-behind-firewall.com/mapgallery/rest/services/EmergencyManagement/EM_FeatureStaging2/FeatureServer/15?f=json&returnAdvancedSymbols=true, _kCFStreamErrorDomainKey=12} The instance of portal is using a reverse-proxy, and although I'm using the publicly accessible urls to reach the feature services, they are returning the internal urls behind the firewall and the http request fails. With this setup, what is the correct way to load portal items as a logged in user?
... View more
03-13-2020
03:08 PM
|
0
|
1
|
837
|
POST
|
Thanks so much, this is exactly what I needed. Works great now!
... View more
01-08-2020
03:41 PM
|
0
|
0
|
1518
|
POST
|
Mary, The error is triggered from downloadGeodatabaseForLayers. I added this function at the suggestion of an ESRI tech I worked with over the phone. I noticed the geodatabase was being downloaded before I added it (I could see the file in the app container), but none of the features I selected with the areaOfInterest geometry appeared on the downloaded map. The value of testOfflineServiceUrl is Layer: Wildfire Response Points (ID: 0)
... View more
01-07-2020
08:49 AM
|
0
|
1
|
1518
|
POST
|
I'm working on enabling offline sync in an iOS app using ArcGIS runtime 100.6. The back end is ArcGIS Enterprise 10.7.1. I created a web map which only uses the World Topography Map (for Export) as a basemap and a single feature service created by ESRI to as a controlled test to guard against any mistakes I could have made while publishing the services which the production app will need to consume. These should present no problem being taken offline, but this error is generated after I initiate the download: I checked the web map settings on portal. It is shared with everyone and the "offline mode" switch is enabled, so I don't understand how I could be getting this error. To clarify, the basemap loads successfully, but the feature layer does not. The code for initiating offline mode doesn't deviate much from the sample in this article (The function "downloadGeodatabaseForLayers() follows this article😞 func takeMapOffline(areaOfInterest: AGSGeometry) {
//1. Declare offline map task
//let offlineMapTask = AGSOfflineMapTask(onlineMap: self.mapView.map!)
let offlineMap = AGSMap.init(url: URL(string: self.offlineWebMapUrl3)!)
let offlineMapTask = AGSOfflineMapTask(onlineMap: offlineMap!)
//2. Define parameters
offlineMapTask.defaultGenerateOfflineMapParameters(withAreaOfInterest: areaOfInterest, completion: {(parameters, error) in
print("@@@ Generate parameters 1: Start")
if let error = error {
print("@@@ Generate parameters 2b: Error, getting parameters failed")
print(error)
self.showDownloadFailedAlert("Error generating offline parameters: \(error.localizedDescription)")
return
}
guard parameters != nil else {
print("takeMapOffline: No parameters provided")
return
}
if let parameters = parameters {
parameters.maxScale = 3600
parameters.minScale = 30000
parameters.includeBasemap = true
parameters.isDefinitionExpressionFilterEnabled = true
parameters.continueOnErrors = true
parameters.returnSchemaOnlyForEditableLayers = true
parameters.attachmentSyncDirection = .bidirectional
parameters.returnLayerAttachmentOption = .allLayers
print("@@@ Generate parameters 2a: Got parameters!")
//4. Create the job
print("@@@ Generate parameters 3: create job")
let mapStorageURL = self.getNewOfflineMapDirectoryURL()
UserDefaults.standard.set(mapStorageURL, forKey: "OfflineMapDirectoryUrl")
let AGSOfflineMapJob = offlineMapTask.generateOfflineMapJob(with: parameters, downloadDirectory: mapStorageURL)
//5. Run the job
self.startOfflineMapJob(job: AGSOfflineMapJob, areaOfInterest: areaOfInterest)
}
})
}
func startOfflineMapJob(job: AGSGenerateOfflineMapJob, areaOfInterest: AGSGeometry) {
job.start(statusHandler: { (status) in
DispatchQueue.main.async {
//Add canceling logic to SVProgressHUD
SVProgressHUD.showDismissable(with: Float(job.progress.fractionCompleted), status: "Downloading map selection. This may take several minutes. Tap here to cancel.")
}
print("Status [\(String(describing: job.progress.fractionCompleted))]: \(status)")
if job.status == .failed {
DispatchQueue.main.async {
SVProgressHUD.dismiss()
}
self.showDownloadFailedAlert("Server Error")
return
}
}) { (result, error) in
DispatchQueue.main.async {
SVProgressHUD.dismiss()
}
if let error = error {
print(error)
self.showDownloadFailedAlert(error.localizedDescription)
return
}
guard let result = result else {
self.showDownloadFailedAlert("Didn't receive a response.")
return
}
if result.hasErrors {
result.layerErrors.forEach{(layerError) in
print((layerError.key.name), " Error taking this layer offline: ", (layerError.value))
}
result.tableErrors.forEach{(tableError) in
print((tableError.key.tableName), " Error taking this table offline")
}
self.showDownloadFailedAlert("Error taking layers offline.")
}
else {
//display the offline map
self.mapView.map = result.offlineMap
DispatchQueue.main.async {
self.downloadGeodatabaseForLayers(areaOfInterest: areaOfInterest)
}
}
}
}
func downloadGeodatabaseForLayers(areaOfInterest: AGSGeometry) {
print("@@@Downloading geodatabase")
let syncTask = AGSGeodatabaseSyncTask(url: URL(string: testOfflineServiceUrl)!)
syncTask.defaultGenerateGeodatabaseParameters(withExtent: areaOfInterest, completion: {[weak self] (parameters, error) in
if let error = error {
print("@@@Error generating geodatabase:" + error.localizedDescription)
print(error)
return
}
guard parameters != nil else {
print("@@@No parameters")
return
}
if let parameters = parameters {
parameters.syncModel = .layer
// define the layers and features to include
parameters.layerOptions.removeAll()
let layersToInclude = [0]
for val in layersToInclude {
parameters.layerOptions.append(AGSGenerateLayerOption(layerID: val, includeRelated: true))
}
parameters.returnAttachments = false
//Start the download task
let geodatabaseUrl = self?.getNewOfflineMapDirectoryURL().appendingPathExtension(".geodatabase")
let generateJob = syncTask.generateJob(with: parameters, downloadFileURL: (geodatabaseUrl)!)
generateJob.start(statusHandler: { (status) in
DispatchQueue.main.async {
SVProgressHUD.showProgress(Float(generateJob.progress.fractionCompleted), status: "Downloading Geodatabase")
}
}, completion: { (geodatabase, error) in
SVProgressHUD.dismiss()
if let error = error {
print("@@@Error downloading geodatabase: ")
print(error)
return
}
else if let geoDb = geodatabase {
self!.generatedGeodatabase = geoDb
self!.displayLayersFromGeodatabase(geoDb: geoDb)
}
})
}
})
} If I download the app container, I can see both the mmpk file and the geodatabase file, but only the basemap displays. Can someone suggest a solution?
... View more
01-06-2020
09:34 AM
|
0
|
6
|
1660
|
POST
|
I recently republished the feature services hosted on ArcGIS server and a permission issue appears to be denying clients from doing any operation which alters the data. This didn't happen with the previous set of services, so I'm assuming I didn't configure the permissions correctly during publishing. This error is logged in Server Manager after attempting a data-modifying operation: "Operation only allowed by the owner of the version [DEFAULT]" Here is the error output in the console of the client app: This is what I see when I select the layer, then go to Edit > Status. I suspect this has something to do with the branch versioning being enabled. Is there something I do in ArcGIS Pro to modify the layer so clients can edit the data? Let me know what other info would be helpful to solving this.
... View more
12-17-2019
09:36 AM
|
0
|
1
|
652
|
POST
|
The missing extension turned out to be the source of the error. Thanks so much!
... View more
12-04-2019
09:32 AM
|
0
|
0
|
1344
|
POST
|
My app allows the user to create a point feature and attach multiple photos to it. The photos are displayed in a custom callout which appears when the user taps the feature. The point is created and the attachments are added to it successfully; I know because I can see the photos when I select the point on the map and no client-side errors are thrown. However, the attachments are gone the next time I open the app. The point appears and I can see it in ArcGIS Pro on the back end, but there are no attachments in the associated table. This error is logged in the Server Manager: "Unable to complete upload operation, File size or type not supported for this service". The photos are less than 2 MB each and I have never uploaded more than 3 at a time. I know attachments are enabled for the layer because I successfully added this feature with a photo via ArcGIS Pro and it saved to the database. This leads me to believe the failure is either on the front end or perhaps a setting the attachment is violating, but I don't know how to check that. Here are the steps to create the feature and any photo attachments: 1. The user presses a button which transitions to a new screen where they select photos. 2. The user selects any number of photos from the gallery or takes new ones with the camera. This is done using UIImagePickerController. 3. The user presses "done". The app prepares to transition to a view controller where the point attributes are set. The point is created in the "prepare" function. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "create-photo-point-segue" {
let nc = segue.destination as! NewFeatureNavigationController
let vc = nc.topViewController as! CreateFeatureViewController
let template: AGSFeatureTemplate? = (photoFeatureLayer?.featureTable as? AGSServiceFeatureTable)?.featureTemplates[0]
vc.template = template
//Create the new photo point feature with the photo attachments
let newAgsFeature = (photoFeatureLayer?.featureTable as? AGSServiceFeatureTable)?.createFeature(with: template!)
newAgsFeature!.attributes.setValue(primaryLocation?.latitude, forKey: "LATITUDE")
newAgsFeature!.attributes.setValue(primaryLocation?.longitude, forKey: "LONGITUDE")
newAgsFeature!.attributes.setValue(primaryDate, forKey: "TIMESTAMP")
let point = AGSPoint(x: primaryLocation!.longitude , y: primaryLocation!.latitude, spatialReference: .wgs84())
newAgsFeature!.geometry = point
attachTxtDocs(feature: newAgsFeature!, photoArray: photoSelectionData)
vc.feature = newAgsFeature
vc.featureAttachments = photoSelectionData
vc.hasAttachments = true
vc.layer = photoFeatureLayer!
nc.collectionPoint = (self.navigationController as! AddPhotoFeatureNavigationController).collectionPoint
let mapVC = (self.navigationController as! AddPhotoFeatureNavigationController).mapVC
mapVC?.navController = nc
nc.mapVC = mapVC
nc.intermediateVC = self
}
} 3a. The photos are serialized to txt documents (necessary to capture metadata) and attached to the newly-created point. I'm aware that because the attachment is a text document that could be why it doesn't save, but I doubt it because I have an alternate function which does not serialize the photo and it experiences the same problem. func attachTxtDocs(feature:AGSArcGISFeature, photoArray:[[UIImagePickerController.InfoKey:Any]]) {
var i = 0
var tempFileUrls: [URL] = []
DispatchQueue.main.async {
SVProgressHUD.show(withStatus: "Attaching Photos...")
}
for photo in photoArray {
var type: String
if let typeOptional = (photo[UIImagePickerController.InfoKey.imageURL] as! URL?) {
let urlTokens = typeOptional.absoluteString.split(separator: ".")
type = urlTokens[urlTokens.count - 1].description
}
else {
type = "jpg"
}
var imageData: Data?
switch type {
case "jpg", "jpeg":
imageData = (photo[UIImagePickerController.InfoKey.originalImage] as! UIImage).jpegData(compressionQuality: 0.5)!
case "png":
imageData = (photo[UIImagePickerController.InfoKey.originalImage] as! UIImage).pngData()!
default:
print("Invalid type")
}
guard imageData != nil else {
SVProgressHUD.dismiss()
return
}
let fileName = serializePhoto(lat: String(geolocations[i].latitude),
lon: String(geolocations[i].longitude),
timestamp: timestamps[i].description,
fileType: type,
photoData: imageData!)
let fileUrl = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName).appendingPathExtension("txt")
tempFileUrls.append(fileUrl)
do {
let photoData = try Data(contentsOf: fileUrl)
feature.addAttachment(withName: "attachment" + String(i),
contentType: "txt",
data: photoData) { (attachment, error) in
SVProgressHUD.dismiss()
if let error = error {
print(error.localizedDescription)
}
if attachment != nil {
print("Photo successfully attached.")
self.removeTempDoc(fileUrl: fileUrl)
}
}
}
catch {
print("Failed to fetch photo data from " + fileUrl.absoluteString)
return
}
i += 1
}
} 4. The feature's attributes are set and is loaded after the transition to the final view. 5. The user confirms the attributes are correct and hits "save". The edits are applied to the table. func applyEdits(to table:AGSServiceFeatureTable) {
SVProgressHUD.setDefaultMaskType(.black)
DispatchQueue.main.async {
SVProgressHUD.show(withStatus: "Saving")
}
table.applyEdits(completion: { (results, error) in
SVProgressHUD.dismiss()
if let error = error {
print(error)
let alert = UIAlertController(title: "Alert!", message: "Unable to create feature: \(error.localizedDescription)", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
return
}
if self.referenceFeature != nil {
self.deleteReferenceFeature()
} else {
self.navigationController?.dismiss(animated: true, completion: nil)
}
})
} This app uses ArcGIS Runtime v100.6. The back end is ArcServer 10.7.1. Can someone offer a solution?
... View more
12-03-2019
04:09 PM
|
0
|
3
|
1446
|
POST
|
That's correct, the AGSMap is created using a local constructor. I tried substituting self.mapView.map = AGSMap.init(url: URL(string: self.mapLayerUrl)!), but I get this error in the completion block of the load method: "Webmap version is not supported" I know this is a secondary issue, but can you suggest a workaround for this?
... View more
11-13-2019
01:33 PM
|
0
|
1
|
528
|
POST
|
I'm working on an iOS app which gets its feature services from an instance of ArcGIS Enterprise. I'm trying to add the ability to generate an offline map on-demand as described in this article. Currently, the user selects a region of the basemap using a rectangle or polygon and their selection is passed into an OfflineMapTask to generate the parameters, but the completion returns the following error: "Error Domain=com.esri.arcgis.runtime.error Code=6 "Illegal state" UserInfo={NSLocalizedFailureReason=The online map must have an item property which is its online portal item." Here is my function. The error branch is always taken, so I edited out the rest of the function to save space. func takeMapOffline(areaOfInterest: AGSGeometry) {
//1. Declare offline map task
let offlineMapTask = AGSOfflineMapTask(onlineMap: self.mapView.map!)
//2. Define parameters
offlineMapTask.defaultGenerateOfflineMapParameters(withAreaOfInterest: areaOfInterest, completion: {(parameters, error) in
print("@@@ Generate parameters 1: Start")
if let error = error {
print("@@@ Generate parameters 2: Error, getting parameters failed")
print(error)
return
}
//The success branch here never executes
})
} Can someone explain what this error means and how I can fix it?
... View more
11-13-2019
09:53 AM
|
0
|
3
|
603
|
Title | Kudos | Posted |
---|---|---|
1 | 10-02-2019 11:43 AM | |
1 | 10-22-2019 10:22 AM |
Online Status |
Offline
|
Date Last Visited |
01-12-2022
11:45 PM
|