Select to view content in your preferred language

Download Data from ArcGIS Server using Out-of-the-Box Solution

5336
19
10-14-2010 12:31 PM
AkhilParujanwala
Regular Contributor
Hi,

I am trying to download data from my server without having to click on Manage Edits > Get Data, I want have a single click button to download the data.

The code posted below should work with a fully customized solution, but I am curious as to how I can modify the code so that it can be used to download data just like the Get Data method that ESRI provides.

MobileCache m_mobileCache1;
m_mobileCache1 = new MobileCache(@"C:\user\MobileCache");            
m_mobileCache1.Open();                        
Map mMap = new Map();
mMap.MapLayers.AddRange(m_mobileCache1);
            
if (m_mobileCache1.CacheExists)
{
   m_mobileCache1.Close();
   m_mobileCache1.DeleteCache();
}

MobileServiceConnection con = new MobileServiceConnection();
con.Url = @"http://server/arcgis/services/Test_Mobile_Services/Radiation_Data_V1_B11/MapServer/Mobileserver";
con.CreateCache(m_mobileCache1);
m_mobileCache1.Open();
            
            
MobileCacheSyncAgent agent = new MobileCacheSyncAgent(m_mobileCache1);
agent.MapDocumentConnection = con;            
agent.DownloadExtent(m_mobileCache1.GetExtent(), 0, 0);           
mMap.MapLayers.AddRange(m_mobileCache1);


Thanks,

Akhil P.
0 Kudos
19 Replies
AkhilParujanwala
Regular Contributor
Ok this is what I go so far in terms of downloading the data, remember I am a heavily customized Out-of-the-box solution, Windows Tablet platform (not Mobile).

The data appears to download properly, I see new modified files in the cache folder, however I am unable to display the newly downloaded layers on the map. look in code for my problem at the end.

MobileCache mobileCache1 = new MobileCache();
            Map map1 = new Map();
            MapControl mapControl1 = new MapControl();
            MobileServiceConnection mobileServiceConnection1 = new MobileServiceConnection();

            //mobileServiceConnection1.CreateCache("Rad_Data");
            try
            {
                mobileCache1.StoragePath = @"C:\Akhil\ArcGIS_Mobile_Projects\P_Radiation_Data_V3_B1\Radiation_Data";
                //Uncomment these lines if you are using your own service
                mobileCache1.DeleteCache();
                mobileServiceConnection1.Url = @"http://emapappdev/arcgis/services/Test_Mobile_Services/Radiation_Data/MapServer/MobileServer";
                MobileCacheSyncAgent mobileSync = new MobileCacheSyncAgent(mobileCache1, mobileServiceConnection1);
                MobileCacheSyncResults mobileResults = new MobileCacheSyncResults();
                //get the schema to determine list of layers
                mobileServiceConnection1.CreateCache(mobileCache1);
                mobileCache1.Open();
                mobileSync.Synchronize();
                //map1.DataSources.Add(mobileCache1); <-- THIS DOES NOT WORK
                //mapControl1.Map.Content = (mobileCache1); <-- THIS DOES NOT WORK
                
            }
            catch
            {
                MessageBox.Show("Cannot open map cache");
            }


Mind you i don't get an error nor does the application crash.

Please help, thanks in advance,

Akhil P.
0 Kudos
AkhilParujanwala
Regular Contributor
I have also tried.

mapControl.Map.MapLayers.AddRange(mobileCache1);  


Still doesn't work, but no errors either.
0 Kudos
AkhilParujanwala
Regular Contributor
I tried this:
MobileApplication.Current.Map.MapLayers.AddRange(mobileCache1);


This makes a lot more sense, it seems to do something, once I tigger this event "Download_Data()" for the second time it says:

"The process cannot access the file 'c:\temp\MapCache\MobileCache.db' because it is being used by another process."

This shows that somehow it is sort of working, but I still don't see any downloaded data on the map.

For example I have two data collectors, one collecting green dots and the other collecting red dots. When the person triggers Download_Data() it should download the data and display the red dots collected by the other person. Both collectors are posting updates every minute as well.

As you can see I am trying to create a system in which data is being uploaded to the server in near real time and downloaded also in near real time. The problem is trying to make this Download_Data() procedure to work the way I want.

Can someone shed some light on this please.

Thanks,

Akhil P.
0 Kudos
MelindaFrost
Frequent Contributor
If you start looking under the hood at what mobileSync is doing through debugger- it basically ends up looping through each feature layer and calling a full featurelayersyncagent on each one.
What you can do instead is loop through each feature layer, create a featurelayersync and set download direction and download filter. These greatly speeds up the sync process time.
If you still do not see the new data- try calling a map refresh.
You could also dive into your featurelayersynresult and see if any exceptions are occuring. I have found any exceptions that happen in the sync do not bubble up to the application. You have to wrtie code to check all the exceptions and if any display the error.
0 Kudos
AkhilParujanwala
Regular Contributor
Thanks buddha,

That's very interesting, yes at the moment it appears to loop through all the layers in my service and downloads them all.

I definitely only want to download 3 layers from the service, not all, so your suggestion of looping through the layers would will work.

I am currently just playing around with this code just to test it out, the problem is that I don't know how to refresh the map.

I understand there is a Refresh() -> void, but I can't seem to call it, because none of my objects can call upon it.

MobileApplication.Current.Map........????


I have tried a number of combinations, am I suppose to make an instance of the map/mapcontrol. This has been puzzling me for two weeks now. :confused:

Thanks,

Akhil P.
0 Kudos
AkhilParujanwala
Regular Contributor
I have also tried this, partially what you said Buddha.


public static void Download_Data()
        {
            ESRI.ArcGIS.Mobile.Client.Windows.MessageBox.ShowDialog("This is where the automatic download of data occurs!");
            // Create an instance of MobileCache, and set StoragePath
            MobileCache mobileCache = new MobileCache();
            mobileCache.StoragePath = @"C:\Akhil\ArcGIS_Mobile_Projects\P_Radiation_Data_V1_B1\Radiation_Data_V1";

            try
            {
               

                if (mobileCache.CacheExists)
                {
                    mobileCache.Close();

                }

                mobileCache.Open();
                MobileServiceConnection con = new MobileServiceConnection();
                con.Url = "http://emapappdev/arcgis/services/Test_Mobile_Services/Radiation_Data_V1/MapServer/MobileServer";

                FeatureLayerSyncAgent agent0 = new FeatureLayerSyncAgent(mobileCache.FeatureLayers[0]);
                agent0.MapDocumentConnection = con;
                agent0.StateChanged += new EventHandler(agent_StateChanged);
                agent0.Synchronize();

                FeatureLayerSyncAgent agent1 = new FeatureLayerSyncAgent(mobileCache.FeatureLayers[1]);
                agent1.MapDocumentConnection = con;
                //agent1.StateChanged += new EventHandler(agent_StateChanged);
                agent1.StateChanged += new EventHandler(agent_StateChanged);
                agent1.Synchronize();

                FeatureLayerSyncAgent agent2 = new FeatureLayerSyncAgent(mobileCache.FeatureLayers[2]);
                agent2.MapDocumentConnection = con;
                agent2.StateChanged += new EventHandler(agent_StateChanged);
                agent2.Synchronize();

catch (Exception exception)
            {
                if (mobileCache.CacheExists)
                {
                    if (mobileCache.IsOpen)
                    {
                        mobileCache.Close();
                    }
                }
            }


I am still unable to figure out how to display the newly downloaded content, the cache does download. Please shed some light on this.

Thanks,

Akhil P.
0 Kudos
AngelGonzalez
Frequent Contributor
See the ESRI sample "DataCollection_Win" which should be installed locally. By looking at the sample I made the following changes to your code.


MobileCache m_mobileCache1;
m_mobileCache1 = new MobileCache(@"C:\user\MobileCache");           
m_mobileCache1.Open();                       
Map mMap = new Map();
//mMap.MapLayers.AddRange(m_mobileCache1);

// Delete the above line since your doing this at the end of your code
  

        
if (m_mobileCache1.CacheExists)
{
   m_mobileCache1.Close();
   m_mobileCache1.DeleteCache();
}
else
{
   //You did a m_mobileCache1.Open(); twice if cache does not exist
   // Once above and once below. You need to close it here since you are opening it below

   m_mobileCache1.Close(); 
}


MobileServiceConnection con = new MobileServiceConnection();
con.Url = @"http://server/arcgis/services/Test_Mobile_Services/Radiation_Data_V1_B11/MapServer/Mobileserver";
con.CreateCache(m_mobileCache1.StoragePath); // Per ESRI sample
m_mobileCache1.Open();
           
           
MobileCacheSyncAgent agent = new MobileCacheSyncAgent(m_mobileCache1, con);
agent.MapDocumentConnection = con;
agent.Synchronize();  // See if Synchronize works instead of line below
//agent.DownloadExtent(m_mobileCache1.GetExtent(), 0, 0);          
mMap.MapLayers.AddRange(m_mobileCache1);




If the above changes does not work try adding the following at the end of your code:
LoadData();
mMap.Refresh();
0 Kudos
AkhilParujanwala
Regular Contributor
Thank you for the help Angel, but same problem, the map does not show the update/synchronized data points.

For example, I can make 5 points on the map using the mobile application, then I would go into ArcMap and delete 4 points, leaving 1 point. This is while the application is running, then I trigger Download_Data and sure the cache appears to be updated, since the modified time changed, but the map I see still displays 5 points.

But if I go to Tasks > Manage Edits > Get Data... (this is the Out-of-the-box solution) it will properly download the data, and display the map with 1 point.

The concept of opening, deleting and creating the cache makes sense to me, I have successfully done this as well, the problem is the application will not render the newly created cache, even tho we are telling it to.

At the end of the code I tried invalidate, refresh and LoadData, neither of them work.
public static void Download_Data()
        {
            MobileCache m_mobileCache1;
            m_mobileCache1 = new MobileCache(@"C:\Akhil\MobileCache");
            MessageBox.Show("before opening mobile cache");
            m_mobileCache1.Open();
            Map mMap = new Map();
            MessageBox.Show("new map");
            //mMap.MapLayers.AddRange(m_mobileCache1);

            // Delete the above line since your doing this at the end of your code


            if (m_mobileCache1.CacheExists)
            {
                m_mobileCache1.Close();
                m_mobileCache1.DeleteCache();
                MessageBox.Show("deletes cache");
            }
            else
            {
                //You did a m_mobileCache1.Open(); twice if cache does not exist
                // Once above and once below. You need to close it here since you are opening it below

                m_mobileCache1.Close();
                MessageBox.Show("closes cache");
            }
            MessageBox.Show("creating mobile connection");
            MobileServiceConnection con = new MobileServiceConnection();
            MessageBox.Show("after creating mobile connection");
            con.Url = @"http://emapappdev/arcgis/services/Test_Mobile_Services/Radiation_Data_V1/MapServer/Mobileserver";                        
            MessageBox.Show("sets the URL");
            con.CreateCache(m_mobileCache1.StoragePath); // Per ESRI sample
            m_mobileCache1.Open();
            MessageBox.Show("opens cache");


            MobileCacheSyncAgent agent = new MobileCacheSyncAgent(m_mobileCache1, con);
            agent.MapDocumentConnection = con;
            //agent.Synchronize(); // See if Synchronize works instead of line below            
            agent.DownloadExtent(m_mobileCache1.GetExtent(), 0, 0);
            MessageBox.Show("after synch");
            mMap.MapLayers.AddRange(m_mobileCache1);
            MessageBox.Show("adds to map");
            //LoadData();
            //mMap.Refresh();
            mMap.Invalidate();
        }
0 Kudos
AngelGonzalez
Frequent Contributor
Instead of using a new map control why not reference the original map control mapControl1


public static void Download_Data()
        {
            MobileCache m_mobileCache1;
            m_mobileCache1 = new MobileCache(@"C:\Akhil\MobileCache");
            MessageBox.Show("before opening mobile cache");
            m_mobileCache1.Open();
           // Map mMap = new Map();// kill this line
            MessageBox.Show("new map");
            //mMap.MapLayers.AddRange(m_mobileCache1);

            // Delete the above line since your doing this at the end of your code


            if (m_mobileCache1.CacheExists)
            {
                m_mobileCache1.Close();
                m_mobileCache1.DeleteCache();
                MessageBox.Show("deletes cache");
            }
            else
            {
                //You did a m_mobileCache1.Open(); twice if cache does not exist
                // Once above and once below. You need to close it here since you are opening it below

                m_mobileCache1.Close();
                MessageBox.Show("closes cache");
            }
            MessageBox.Show("creating mobile connection");
            MobileServiceConnection con = new MobileServiceConnection();
            MessageBox.Show("after creating mobile connection");
            con.Url = @"http://emapappdev/arcgis/services/Test_Mobile_Services/Radiation_Data_V1/MapServer/Mobileserver";                       
            MessageBox.Show("sets the URL");
            con.CreateCache(m_mobileCache1.StoragePath); // Per ESRI sample
            m_mobileCache1.Open();
            MessageBox.Show("opens cache");


            MobileCacheSyncAgent agent = new MobileCacheSyncAgent(m_mobileCache1, con);
            agent.MapDocumentConnection = con;
            //agent.Synchronize(); // See if Synchronize works instead of line below           
            agent.DownloadExtent(m_mobileCache1.GetExtent(), 0, 0);
            MessageBox.Show("after synch");
            //mMap.MapLayers.AddRange(m_mobileCache1);   // kill this line
             mapControl1.MapLayers.AddRange(m_mobileCache1);

            MessageBox.Show("adds to map");
            //LoadData();
            //mMap.Refresh();
            mMap.Invalidate();
        }
0 Kudos