Renaming Geodatabase received from AGSGDBSync

5271
5
Jump to solution
06-04-2014 03:53 PM
mikedavis2
New Contributor II
Is it possible to rename the file(s) received after downloading a .geodatabase from an ArcGIS Server request?  They are named with some sort of timestamp by default, but it would be handy if we could then save them with a different name.

Thanks
0 Kudos
1 Solution

Accepted Solutions
ShiminCai
Occasional Contributor III
Did it in the completion block of the generateGeodatabaseWithParameters method.

@property (nonatomic, strong) AGSGDBSyncTask *gdbTask;

[self.gdbTask generateGeodatabaseWithParameters:params downloadFolderPath:nil useExisting:YES
                                                 status:^(AGSResumableTaskJobStatus status, NSDictionary *userInfo)
         {
             if(status == AGSResumableTaskJobStatusFetchingResult)
             {
                 _newlyDownloaded = YES;
             }
            
             [self logStatus:[NSString stringWithFormat:@"Status: %@", [self statusMessageForAsyncStatus:status]]];
            
         }
         completion:^(AGSGDBGeodatabase *geodatabase, NSError *error)
         {
             if (error)
             {
                 _goingOffline = NO;
                 _offline = NO;
                 [self logStatus:[NSString stringWithFormat:@"error taking feature layers offline: %@", error]];
                 [SVProgressHUD showErrorWithStatus:@"Couldn't download features"];
                
                 [self updateUI];
             }
             else
             {
                 _goingOffline = NO;
                 _offline = YES;
                 [self logStatus:@"now viewing local data"];
                
                 ////Remove all live feature layers
                 for (AGSLayer* lyr in self.mapView.mapLayers)
                 {
                     if([lyr isKindOfClass:[AGSFeatureLayer class]])
                     {
                         [self.mapView removeMapLayer:lyr];
                     }
                 }
                
                 //rename the database
                 NSString *orginalFilePath = geodatabase.path;
                 NSString *directoryPath = [orginalFilePath stringByDeletingLastPathComponent];
                 NSString *directoryPathNameWithoutExtension = [orginalFilePath stringByDeletingPathExtension];
                 NSString *orginalFilePathShm = [directoryPathNameWithoutExtension stringByAppendingString:@".geodatabase-shm"];
                 NSString *orginalFilePathWal = [directoryPathNameWithoutExtension stringByAppendingString:@".geodatabase-wal"];
                 NSString *newFilePath = [directoryPath stringByAppendingString:@"/HFDPlanning.geodatabase"];
                 NSString *newFilePathShm = [directoryPath stringByAppendingString:@"/HFDPlanning.geodatabase-shm"];
                 NSString *newFilePathWal = [directoryPath stringByAppendingString:@"/HFDPlanning.geodatabase-wal"];
                
                 [FCNSWUtils renameFile:orginalFilePath :newFilePath];
                 [FCNSWUtils renameFile:orginalFilePathShm :newFilePathShm];
                 [FCNSWUtils renameFile:orginalFilePathWal :newFilePathWal];
                
                 AGSGDBGeodatabase *gdb = [[AGSGDBGeodatabase alloc]initWithPath:newFilePath error:nil];
                 self.geodatabase = gdb;
                 geodatabase = gdb;
                
                 //Add local feature/table layers
                 for (AGSFeatureTable* fTable in geodatabase.featureTables)
                 {
                     if ([fTable hasGeometry])
                     {
                         AGSFeatureTableLayer *ftl = [[AGSFeatureTableLayer alloc]initWithFeatureTable:fTable];
                         ftl.delegate = self;
                        
                         [self.mapView addMapLayer:ftl];
                     }
                 }
                
                 if (_newlyDownloaded)
                 {
                     [SVProgressHUD showSuccessWithStatus:@"Finished \n downloading"];
                 }
                 else
                 {
                     [SVProgressHUD dismiss];
                     [self showEditsInGeodatabaseAsBadge:geodatabase];
                     UIAlertView* av = [[UIAlertView alloc]initWithTitle:@"Found local data" message:@" It may contain edits or may be out of date. Do you want synchronize it with the service?" delegate:nil cancelButtonTitle:@"Later" otherButtonTitles:@"Yes", nil];
                     [av showWithCompletion:^(UIAlertView *alertView, NSInteger buttonIndex)
                      {
                          switch (buttonIndex)
                          {
                              case 0: //do nothing
                                  break;
                              case 1: //Yes, sync
                                  [self syncAction:nil];
                                  break;
                              default:
                                  break;
                          }
                      }];
                 }
                
                 [self updateUI];
             }
         }];


+(BOOL) renameFile:(NSString *)oldFilePath :(NSString *)newFilePath
{
    //to rename a file just need to move the file to a different name in the same directory.
    //so the oldFilePath and newFilePath should point to the same directory but wiht different file names.
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error = nil;
    bool success = NO;
   
    success = [fileManager moveItemAtPath:oldFilePath toPath:newFilePath error:&error];
    if(success)
    {
        NSLog(@"File renamed.");
    }
    else
    {
        NSLog(@"%@", [error localizedDescription]);
    }
   
    return success;
}

View solution in original post

0 Kudos
5 Replies
ShiminCai
Occasional Contributor III
Did it in the completion block of the generateGeodatabaseWithParameters method.

@property (nonatomic, strong) AGSGDBSyncTask *gdbTask;

[self.gdbTask generateGeodatabaseWithParameters:params downloadFolderPath:nil useExisting:YES
                                                 status:^(AGSResumableTaskJobStatus status, NSDictionary *userInfo)
         {
             if(status == AGSResumableTaskJobStatusFetchingResult)
             {
                 _newlyDownloaded = YES;
             }
            
             [self logStatus:[NSString stringWithFormat:@"Status: %@", [self statusMessageForAsyncStatus:status]]];
            
         }
         completion:^(AGSGDBGeodatabase *geodatabase, NSError *error)
         {
             if (error)
             {
                 _goingOffline = NO;
                 _offline = NO;
                 [self logStatus:[NSString stringWithFormat:@"error taking feature layers offline: %@", error]];
                 [SVProgressHUD showErrorWithStatus:@"Couldn't download features"];
                
                 [self updateUI];
             }
             else
             {
                 _goingOffline = NO;
                 _offline = YES;
                 [self logStatus:@"now viewing local data"];
                
                 ////Remove all live feature layers
                 for (AGSLayer* lyr in self.mapView.mapLayers)
                 {
                     if([lyr isKindOfClass:[AGSFeatureLayer class]])
                     {
                         [self.mapView removeMapLayer:lyr];
                     }
                 }
                
                 //rename the database
                 NSString *orginalFilePath = geodatabase.path;
                 NSString *directoryPath = [orginalFilePath stringByDeletingLastPathComponent];
                 NSString *directoryPathNameWithoutExtension = [orginalFilePath stringByDeletingPathExtension];
                 NSString *orginalFilePathShm = [directoryPathNameWithoutExtension stringByAppendingString:@".geodatabase-shm"];
                 NSString *orginalFilePathWal = [directoryPathNameWithoutExtension stringByAppendingString:@".geodatabase-wal"];
                 NSString *newFilePath = [directoryPath stringByAppendingString:@"/HFDPlanning.geodatabase"];
                 NSString *newFilePathShm = [directoryPath stringByAppendingString:@"/HFDPlanning.geodatabase-shm"];
                 NSString *newFilePathWal = [directoryPath stringByAppendingString:@"/HFDPlanning.geodatabase-wal"];
                
                 [FCNSWUtils renameFile:orginalFilePath :newFilePath];
                 [FCNSWUtils renameFile:orginalFilePathShm :newFilePathShm];
                 [FCNSWUtils renameFile:orginalFilePathWal :newFilePathWal];
                
                 AGSGDBGeodatabase *gdb = [[AGSGDBGeodatabase alloc]initWithPath:newFilePath error:nil];
                 self.geodatabase = gdb;
                 geodatabase = gdb;
                
                 //Add local feature/table layers
                 for (AGSFeatureTable* fTable in geodatabase.featureTables)
                 {
                     if ([fTable hasGeometry])
                     {
                         AGSFeatureTableLayer *ftl = [[AGSFeatureTableLayer alloc]initWithFeatureTable:fTable];
                         ftl.delegate = self;
                        
                         [self.mapView addMapLayer:ftl];
                     }
                 }
                
                 if (_newlyDownloaded)
                 {
                     [SVProgressHUD showSuccessWithStatus:@"Finished \n downloading"];
                 }
                 else
                 {
                     [SVProgressHUD dismiss];
                     [self showEditsInGeodatabaseAsBadge:geodatabase];
                     UIAlertView* av = [[UIAlertView alloc]initWithTitle:@"Found local data" message:@" It may contain edits or may be out of date. Do you want synchronize it with the service?" delegate:nil cancelButtonTitle:@"Later" otherButtonTitles:@"Yes", nil];
                     [av showWithCompletion:^(UIAlertView *alertView, NSInteger buttonIndex)
                      {
                          switch (buttonIndex)
                          {
                              case 0: //do nothing
                                  break;
                              case 1: //Yes, sync
                                  [self syncAction:nil];
                                  break;
                              default:
                                  break;
                          }
                      }];
                 }
                
                 [self updateUI];
             }
         }];


+(BOOL) renameFile:(NSString *)oldFilePath :(NSString *)newFilePath
{
    //to rename a file just need to move the file to a different name in the same directory.
    //so the oldFilePath and newFilePath should point to the same directory but wiht different file names.
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error = nil;
    bool success = NO;
   
    success = [fileManager moveItemAtPath:oldFilePath toPath:newFilePath error:&error];
    if(success)
    {
        NSLog(@"File renamed.");
    }
    else
    {
        NSLog(@"%@", [error localizedDescription]);
    }
   
    return success;
}
0 Kudos
DiveshGoyal
Esri Regular Contributor
Renaming the geodatabase file is fine, but note that once you do that, setting the useExisting parameter on generateGeodatabaseWithParameters:downloadFolderPath:useExisting:status:completion: method to YES will no longer be able to find the local database that matches your parameters. The way it works is that the default name of the gdb file is basically a hash of the parameters provided; this allows the API to easily search for an existing one before requesting the service. If you change the name, that will no longer work.
0 Kudos
ShiminCai
Occasional Contributor III
Renaming the geodatabase file is fine, but note that once you do that, setting the useExisting parameter on generateGeodatabaseWithParameters:downloadFolderPath:useExisting:status:completion: method to YES will no longer be able to find the local database that matches your parameters. The way it works is that the default name of the gdb file is basically a hash of the parameters provided; this allows the API to easily search for an existing one before requesting the service. If you change the name, that will no longer work.


Thanks Divesh for the advice.

In our case it is necessary to rename the geodatabase because our app has many modules and each module has its own geodatabase (strictly speaking, each module could be a separate app and the reason to include them in one app is to be able to share tile packages among the modules/apps.) When our app goes offline, if the local geodatabase for the current module is found it is used and the layers in it are loaded into the map view, otherwise the app generates a new geodatabase for the module and downloads features within the visible map extent, and the database is being renamed in the downing process. When sync, an instance of AGSGDBGeodatabase is created with the renamed geodatabase file and registered with the feature service from which the geodatabase is generated. So I think the parameter 'useExisting' does not have any effect in our process and so far everything has seemed to be working as expected...

Cheers,

Shimin
0 Kudos
SteveBein
New Contributor

Is there any software can read .geodatabase and .geodatabase-shm and .geodatabase.wal files?

If I am in offline mode and find sync data with error so I decide to get these three files through i-tune and

place these on Windows System. But what's kind of software can read it and paste the data to ArcMap?

Please advise. Thanks!

0 Kudos
MichaelDavis3
Occasional Contributor III

The easiest thing to do is use the Copy Runtime Geodatabase to File Geodatabase tool in ArcToolbox 10.3.  I've found I can only make this work if I have the source files on the C: drive.

The .geodatabse is a SQLite database with Esri's special sauce, so you can rename the files to xxx.sqlite, xxx.sqlite-wal, xxx.sqlite-shm and open them in any SQLite editior if you want to look at the guts.

0 Kudos