POST
|
I'm running into an issue with the MobileCache object in ArcGIS for Windows 3.1. Basically it seems once you've added your mobile cache to the map control to display the data, you can't delete it any longer even if you've removed the cache layers from from map control. You'll receive a System.IO error saying the mobile cache is in use by another process. I created a test project where I just have a Map control, a MobileServiceConnection, and a MobileCache. If I create and populate cache but don't add the data to the map, I can delete it after I call the Close method on the cache. If I add the cache to the MapLayers collection of the map control, no matter what I do I can't seem to delete the cache any longer - even if I've removed cache from the MapLayers of the map control. I need to Delete the cache because the user can switch projects in our application which then downloads a mobile cache from a different URL. Any suggestions are appreciated.
using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using ESRI.ArcGIS.Mobile.FeatureCaching.Synchronization;
namespace TestMobileCache {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
/// <summary>
/// Create the mobile cache and populate it with data
/// </summary>
private void buttonCreateMobileCache_Click(object sender, EventArgs e) {
//setup the mobile cache and mobile service connection
this.mobileCache1.StoragePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CacheTest");
this.mobileServiceConnection1.WebClientProtocolType = ESRI.ArcGIS.Mobile.FeatureCaching.WebClientProtocolType.BinaryWebService;
this.mobileServiceConnection1.Url = "http://1540sr-gis/arcgis/services/Test/WetlandsFieldSurveyDirect/MapServer/MobileServer";
this.mobileServiceConnection1.CreateCache(this.mobileCache1);
this.mobileCache1.Open();
//download data for all layers
MobileCacheSyncAgent syncAgenct = new MobileCacheSyncAgent(this.mobileCache1);
foreach(var fs in mobileCache1.FeatureSources) {
var fsa = new FeatureSyncAgent(fs);
fsa.MapDocumentConnection = this.mobileServiceConnection1;
fsa.SynchronizationDirection = SyncDirection.DownloadOnly;
syncAgenct.FeatureSyncAgents.Add(fsa);
fsa.Synchronize();
}
}
/// <summary>
/// Attempt to delete the cache
/// </summary>
private void buttonDeleteCache_Click(object sender, EventArgs e) {
//Remove the mobile cache layers from the map control
if (this.map1.MapLayers.Count > 0) {
this.map1.MapLayers.Remove(this.mobileCache1);
}
//Close the cache and attempt to delete it
this.mobileCache1.Close();
this.mobileCache1.DeleteCache();
}
/// <summary>
/// Add the map cache layers to the map control
/// </summary>
private void buttonAddLayerToMap_Click(object sender, EventArgs e) {
this.map1.MapLayers.Add(this.mobileCache1);
}
}
}
... View more
10-15-2012
11:14 AM
|
0
|
0
|
2210
|
POST
|
I realize it was a while ago that you posted your question, but since I recently had a cache problem of my own (and wish these boards were more active!), I figured I'd see if I could help at all. It appears you're doing or have done most of the same things my program does - the main difference I see in the code you use and what I do (I'm on the Win32 version) is that I create and open the cache before synchronizing with FeatureLayerSyncAgents. I remember I was getting the same error as you a while ago when I started developing with the 10 SDK - I fixed it but don't recall the details. Anyway, here's what my code does - I've omitted parts and clipped out some stuff, but you should be able to see the main procedures (sorry it's messy, don't have time to streamline it to make it clear.) Good luck
private void frmMain_Load(object sender, EventArgs e) {
// Specify the mobileservice URL
CacheStoragePath = String.Format(@"{0}\GPS_Cache", Common.GetDataRootPath());
//Setup the layer sync object
InitializeSyncMaster();
//If we're going to create a new map cache, archive the previous one so we don't ever delete data on accident
CacheOpenMode mode = MapHelpers.GetCacheOpenMode();
//set security credentials to connect to the mobile service
ConfigureServiceConnectionSecurity(this.mobileServiceConnection1);
//download or initialize / open the map cache
InitializeCache(this.mobileServiceConnection1, this.mobileCache1, CacheStoragePath, mode);
mobileCache1.Open();
//if we don't have any data in the cache start downloading
if (mobileCache.IsEmpty) {
IsInitializingData = true;
BeginDownloadData(true);
}
}
private CredentialCache ConfigureServiceConnectionSecurity(MobileServiceConnection serviceConnection) {
mobileServiceConnection1.WebClientProtocolType = WebClientProtocolType.BinaryWebService;
//OMITTED CODE WHERE I SET UP MY USER CREDENTIALS
NetworkCredential credentials = new NetworkCredential(String.Format(@"{0}\{1}", serverID, serverLoginUser), serverLoginPassword);
CredentialCache credentialscache = new CredentialCache();
serviceConnection.Url = Common.GetConfigValue("MobileServiceURL");
credentialscache.Add(new Uri(Common.GetConfigValue("MobileServiceURL")), "Basic", credentials);
serviceConnection.WebClientProtocol.Credentials = credentialscache;
return credentialscache;
}
private void InitializeSyncMaster() {
SyncMaster = new MobileCacheSyncAgent(mobileCache1);
SyncMaster.MapDocumentConnection = mobileServiceConnection1;
SyncMaster.ProgressChanged += SyncMaster_ProgressChanged;
SyncMaster.StateChanged += SyncMaster_StateChanged;
this.SyncResults = new SyncResults(this.SyncMaster);
}
public void BeginDownloadData(bool initializeSyncAgents) {
if (initializeSyncAgents) {
SetupSyncAgents();
}
if (this.mobileServiceConnection1.IsValid) {
SyncMaster.BeginDownloadExtent(map1.GetFullExtent(), 0, 0, DownloadExtent, Guid.NewGuid());
}
}
public void SetupSyncAgents(List<string> LayersToSync) {
this.DisplayedNotConnectedErrorMessage = false;
if (SyncMaster.SyncAgents != null && SyncMaster.SyncAgents.Count() > 0) {
this.SyncResults.SyncResultsDataTable.Rows.Clear();
SyncMaster.SyncAgents.Clear();
}
foreach (string layerName in LayersToSync) {
Layer l = this.mobileCache.Layers[layerName];
if (l is FeatureLayer) {
var fl = (FeatureLayer)l;
FeatureLayerSyncAgent agent = new FeatureLayerSyncAgent(fl);
agent.ProgressChanged += FeatureLayerAgent_ProgressChanged;
if (Common.IsLayerValidForProjectFilter(agent)) {
agent.DownloadFilter = new QueryFilter(String.Format("ProjectID = {0}", Common.ProjectID));
}
agent.MapDocumentConnection = this.mobileServiceConnection1;
agent.SynchronizationDirection = SyncDirection.DownloadOnly;
SyncMaster.SyncAgents.Add(agent);
}
if (l is RasterLayer) {
var rl = (RasterLayer)l;
RasterLayerSyncAgent agent = new RasterLayerSyncAgent(rl);
agent.Extent = this.map1.GetExtent();
agent.MapDocumentConnection = this.mobileServiceConnection1;
SyncMaster.SyncAgents.Add(agent);
}
}
if (LayersToSync.Count() > 0) {
this.SyncResults.InitializeList();
}
}
public void SetupSyncAgents() {
var layers = new List<string>();
foreach (Layer l in this.mobileCache1.Layers) {
if (!Common.IsSurveyCoverageMode || (Common.IsSurveyCoverageMode && l.Name != Layers.ARCH_SurveyCoverage )) {
layers.Add(l.Name);
}
}
SetupSyncAgents(layers);
}
private void InitializeCache(MobileServiceConnection serviceConnection, MobileCache cache, string cacheStoragePath, CacheOpenMode mode) {
if (cache != null && cache.IsOpen) {
cache.Close();
}
//location of cache files
cache.StoragePath = cacheStoragePath;
try {
this.ConfigureServiceConnectionSecurity(serviceConnection);
switch (mode) {
case CacheOpenMode.Create:
ArchiveMapCache();
cache.DeleteCache();
serviceConnection.CreateCache(cache);
break;
case CacheOpenMode.CreateNew:
if (cache.CacheExists) {
throw new NotSupportedException("Values for CacheOpenMode must be Create, Open, or CreateOrOpen");
}
break;
case CacheOpenMode.OpenOrCreate:
if (!cache.CacheExists) {
serviceConnection.CreateCache(cache);
Log.Write(String.Format("Program was set to CacheOpenMode.OpenOrCreate but not cache file was found at {0}. Downloading a new cache.", this.CacheStoragePath));
}
break;
case CacheOpenMode.Open:
if (!cache.CacheExists) {
serviceConnection.CreateCache(cache);
Log.Write(String.Format("Program was set to CacheOpenMode.Open but no map cache was found at {0}. Downloading a new cache.", this.CacheStoragePath));
}
break;
}
} catch (WebException ex) {
}
}
... View more
05-02-2012
03:37 PM
|
0
|
0
|
186
|
POST
|
Greetings, We have a custom developed windows mobile project which is working fine, users have been saving and submitting data throw the service regularly for over a month. But I believe somehow when a feature was being saved to the cache, it didn't write it correctly. When the user attempts to post the cache, the error message comes back "Guid should contain 32 digits with 4 dashes...Set failure (ParseFailureKindfailure, String failureMessageID, Object failureMessagerFormatArgument, String failureArgumentNAme, Exception inner Exception) " I've opened the .db file with SQL-Lite browser, and I can see the row that I believe is causing the problem. While all other rows have completely valid data, one rows seems to have saved incorrectly - the GlobalID is {9057C3D9-5220-4E44-9D12-51?????????? and all every other field after that has what look like binary values. The example below shows a few valid rows from the table and the last one is the invalid one. What I"d like to do is just delete the offending feature from the mobile cache, however i know I'd have to modify more than one table to completely remove that feature. I deleted the row from layer0_current_feature, but then I get a different error when I try to transfer. Has anybody dug into the inner workings of the mobile cache, or would any ESRI folks care to let me know if this happens again how I can delete an invalid row from the mobile cache? Thanks for any ideas. -77 1 0 229256665 1 ????I?? 0 {32A124F8-32B6-40FF-9D9E-80C1CCF81268} 042712TLC2 Shovel Test -96.1400231 36.75092488 4/27/2012 11:43 urscorp 4/27/2012 11:43 urscorp 31 4/27/2012 11:43
-75 1 0 650062530 1 ?C??@<?? 0 {028AC7BF-4567-4F36-BBC2-998C022B5D64} 042712CSB2 Shovel Test -96.13957125 36.75091072 4/27/2012 11:40 urscorp 4/27/2012 11:40 urscorp 31 4/27/2012 11:40
-73 1 0 1463101579 1 ?????6?? 0 {84DDE0D3-2D8D-4D22-AFE2-77E6DA36A03F} 042712MDA1 Shovel Test -96.13948947 36.75063283 4/27/2012 11:39 urscorp 4/27/2012 11:39 urscorp 31 4/27/2012 11:39
-71 1 0 982395837 1 7 ??'x?? 0 {E247B599-BC79-4A18-AC68-E96ADC1D15DC} 042712TLC1 Shovel Test -96.13906772 36.75179097 4/27/2012 11:32 urscorp 4/27/2012 11:32 urscorp 31 4/27/2012 11:32
-69 1 0 1175529696 1 2?? ?? 0 {9057C3D9-5220-4E44-9D12-51?????????? ????q???? ?????l???ww -1.24E+67 2.75E+91 ????07??????w=:31 w????? ??7v???????????9:?y }r?o?? -1 ?q5?m<?=???{5?>???{
... View more
05-01-2012
10:24 AM
|
0
|
0
|
584
|
POST
|
I'm tasked with building an application that will run on at least iOS devices. I'd much prefer to make it an HTML5 app and use the Geolocation features provided by that spec. What I haven't been able to find reliable information on is: If you use an external GPS device while hooked to an iPad/Droid/Whatever, will the external unit's GPS data be available from the iOS/Droid/Whatever browser, or will it just use the built in GPS? Basically we need the accuracy of the external GPS device from the ArcGIS Javascript API - or we'll have to build platform specific apps, which wouldn't be good given our overall goals. Thanks for any help.
... View more
02-01-2012
08:55 PM
|
0
|
2
|
844
|
POST
|
Here's a video which explains the the integration of the mobile SDK with the Pathfinder Field Toolkit http://media.esri.com/videos/events/devsummit/2011/DS2011highaccuracydata.wmv Now I have to say, getting a hold of this functionality is a bit of a hassle, you have to fill out a form to be accepted to the Developer community I believe to even be able to try it out, and from what I understand there's a per installation fee they can charge you for your application (I don't know what it is.) It turned me off to the whole thing even though we have a need for similar functionality.
... View more
10-11-2011
08:37 AM
|
0
|
0
|
782
|
POST
|
I realize this is probably a bit late to be answering, but if you have ArcGIS server, I'd go with the mobile SDK - as it allow you to program against both Win32 and various mobile devices, and you can sync the data between various clients by connecting to a single map service you publish your shape files through.
... View more
10-11-2011
08:09 AM
|
0
|
0
|
119
|
POST
|
I remember at some point I was running into issues with case sensitivity, although I don't recall if this was a mobile version issue, or a SQL issue, or a problem with my code. I know I wrote a function below, however apparently I didn't end up using it. I have filters like this in a lot of places in my code though: string whereClause = String.Format("GlobalID = '{{{0}}}'", globalID.ToString().ToUpper());
public static string GetGlobalIDWhereClause(string columnName, GlobalId globalID) {
return String.Format("({0} = '{{{1}}}' OR {0} = '{{{2}}}')", columnName, globalID.ToString().ToUpper(), globalID.ToString());
}
... View more
10-11-2011
07:52 AM
|
0
|
0
|
166
|
POST
|
Greetings, I'm afraid I don't have a direct answer, although I'll offer you an opinion. Now granted I don't know the size and scope of your project, but from what admittedly little I know about SOE's, it seems like it might a lot of work - and you may be able to alleviate your security concern in a different manner. I do like your idea though, and let me know if you follow through with that path. As an alternative, say you do require the client to call multiple web services - you could enforce that the syncing would fail by adding a column to each layer with an AuditID. Your pre-sync audit service does it's thing and stores a result in the DB "SyncLog" with a Guid or something, which is then returned to the client. You could then update the features's AuditID with the Guid, and have triggers on the DB that check for that value against your SyncLog table, and don't allow the updates/inserts if things don't check out, therefore the sync would fail. I realize that may be a bit of work too, and definitely more of a hack, but in the event that the SOE route isn't feasible, just another thought.
... View more
10-11-2011
07:44 AM
|
0
|
0
|
146
|
POST
|
After you've created your cache, loop through the layers you want to sync and add them to a MobileCacheSyncAgent, then you can call BeginDownloadExtent on the MobileCacheSyncAgent and it will do async downloads for you. Sorry it's not complete code - I just pulled bits and pieces to show the concepts.
//property for mobile sync agent
public MobileCacheSyncAgent SyncMaster { get; set; }
//snippet which initializes the sync agents for download
SyncMaster.SyncAgents.Clear();
SetupSyncAgents();
SyncMaster.BeginDownloadExtent(mobileCache1.GetInitialExtent(), 0, 0, DownloadExtent, Guid.NewGuid());
//procedure to setup the sync agents for downloads
private void SetupSyncAgents() {
foreach (Layer l in this.mobileCache1.Layers) {
if (l is FeatureLayer) {
var fl = (FeatureLayer)l;
FeatureLayerSyncAgent agent = new FeatureLayerSyncAgent(fl);
agent.MapDocumentConnection = this.mobileServiceConnection1;
agent.SynchronizationDirection = SyncDirection.DownloadOnly;
SyncMaster.SyncAgents.Add(agent);
}
if (l is RasterLayer) {
var rl = (RasterLayer)l;
RasterLayerSyncAgent agent = new RasterLayerSyncAgent(rl);
agent.Extent = this.map1.GetExtent();
agent.MapDocumentConnection = this.mobileServiceConnection1;
SyncMaster.SyncAgents.Add(agent);
}
}
}
... View more
10-10-2011
10:25 AM
|
0
|
0
|
259
|
POST
|
We have a contract which has the following requirements for all GPS points collected. We're using SX-BLUE II receivers with the mobile SDK. A table listing the attribute data for all vertices of each polygon, line, or data point surveyed and mapped must be provided. The table must include the following information for each point surveyed: 1. Unique Name / Number 2. NAD 1983 UTM Coordinate 3. Number of Satellites (Minimum 4) 4. PDOP (position dilution of precision) value of 6 or less 5. 2D RMS (root mean square) calculation. The GPS unit must produce a 2D RMS sub-meter accuracy (within 1 meter of the indicated position 95% of the time) 6. Distances between each consecutively numbered survey point I understand and know how to provide everything there except for the 2D RMS line - I've read about how it's essentially a calculation of accuracy (e.g EPE (2drms) = 2 * HDOP * SQRT [URE^2 + UEE^2]) - however I'm not sure from these requirements if they're stating they want to know the value for each point collected, or just that the receiver is capable of doing so. If it IS that they want the value for each point being calculated, is there some standard way of getting this through the mobile SDK? The formula I listed above included two factors (URE and UEE) that I wouldn't know how to go about calculating. If anyone is a bit more familiar with this stuff and has any input it would be appreciated. Much thanks
... View more
10-10-2011
06:42 AM
|
0
|
0
|
638
|
POST
|
I fixed it, though it wasn't a problem with anything except my setup. If anyone is experiencing a similar issue, our IIS server somehow had regained Anonymous Access privileges for the rest services virtual directory, despite the services being secured at the ArcGIS Server Manager level. This isn't the first time I've dealt with "creeping permissions" on this server, I guess they like to keep me on my toes. As far as why it works in 3.5 with that configuration but not 4.0, I'll leave that to the smart people 🙂
... View more
04-11-2011
08:25 PM
|
0
|
0
|
184
|
POST
|
Greetings, I believe this has been posted about before, but I didn't find a clear answer. My issue is that using the basic proxy.ashx handler with basic authentication on Secured ArcGIS services (as advised in http://resources.esri.com/help/9.3/arcgisserver/apis/silverlight/help/Secure_services.htm), it works fine under the .net framework 3.5, however if I switch the web app which hosts the silverlight app to the 4.0 framework the same requests directly through the proxy.ashx handler will return a 499 Unauthorized access. I admit there is more debugging that I could do before posting here, but I'm currently waiting on some configuration work to be done on one of our servers before I can proceed with that, and was hoping somebody had a quick answer. So basically, does anyone have a proxy.ashx handler working with basic authentication and the .net framework 4.0? If so, was there any configuration you needed to do which was different than the default. I guess I should also note that I'm attempting to use this in a WCF enabled silverlight application with Telerik Open Access ORM, which did make configuration changes to the web app, but I was hoping somebody might know the exact setting causing the issue without me going to hunt it down. One can always hope 😉 Thanks for any help.
... View more
04-11-2011
12:05 PM
|
0
|
2
|
795
|
POST
|
Thanks much for the reply. Let me make sure I understand. When you say "Viewing through REST query layers directly on SQlServer views", are you referring to the standard ESRI map REST services, secured via AD authentication? coupled with "This pattern does not secure data transport properly. We still have to implement a data-secure pattern such that relevant attributes in the database (like login user-identities) are resolved in the server" If I'm understanding correctly, your services were secure for viewing at the role level, but could describe briefly how the row level security came into play? Were the sql views hardcoded for particular roles (or role "labels") , thus if you could access a map service, you could see all the rows included in that service, or was there another mechanism used which limited rows to the role? Just want to be sure you didn't just point out "the missing link" and I didn't catch it 🙂 Our situation truly is 300 or so "roles" or "users", basically one for every agency of a certain type allowed to see only their data. So I think it's down to a where clause, or a couple hundred rest endpoints with security (in a single service.) Thanks again for your time and any further insight. Steven
... View more
03-22-2011
02:29 PM
|
0
|
0
|
303
|
POST
|
Greetings, I'm looking into a way to incorporate row level security, if at all possible on the database side (due to a client's needs), while still using ESRI's rest services. The scenario is, they have an sde database with several million rows, and about 300 hundred users. Each user will only be able to access certain rows based on their login. I know ArcGIS manager can be configured to use the ActiveDirectoryProiver, but to secure in this fashion, wouldn't we have to publish several hundred services? Additionally I've considered using a single service with a spatial view for each user (indexing performance enhancements and all), and publishing them with Map & Feature access, and then limiting access to the different layers through the proxy config. I'm aware I could simply use the QueryTask along with a where string, but I don't believe the client will be satisfied with this solution. Also there's the matter of obtaining the security context within the silverlight app - I was planning on just calling a simple web service which would check the Membership provider and get and info I needed from there. Any thoughts, or suggestions? Please tell me I'm missing something very simple 🙂 Thanks for any help
... View more
03-16-2011
01:21 PM
|
0
|
4
|
1214
|
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|