Select to view content in your preferred language

Capture Synchronization Event

1975
5
02-26-2013 10:41 AM
KierenTinning1
Deactivated User
Does anyone know how to capture, or if it is possible to capture a synchronization event?

For all of my modified features I'd like to know when ArcGIS Mobile starts to synchronize so I can write a value to that group.

Thanks,

E
0 Kudos
5 Replies
AkhilParujanwala
Regular Contributor
You can create your own Synchronization event.
I have disable ESRI's Sync event and wrote my own.

You can search on the forums for code samples some of them may be mine.
My laptop is not with me at the moment, but here's a rough draft of the code.

Get the mobilecache.
Loop through each layer in the mobilecache.
Set a syncdirection.
Your options are uploadonly, downloadonly, bidirectional.
Then tell the layer to synchronize.

When I get my laptop back, I will gladly post it again.

Hope this helps.
0 Kudos
KierenTinning1
Deactivated User
Thank you for the input. I could do that but was hoping to simply capture an event for the sync process which would be much more useful.

Well, off to writing my own I think
0 Kudos
KierenTinning1
Deactivated User
So, it turns out that there is no event to capture and the sync tools cannot really be customized.

The solution to this problem was a complete re-write of the sync functions for both posting and getting data
0 Kudos
AkhilParujanwala
Regular Contributor
Sorry about the delayed response, so busy with work.

Here is the code to perform sync. There are 2 variations, this one gives more control per layer.

mobileCache = new MobileCache("put your path here the folder that contains the cache");

MobileServiceConnection con = new MobileServiceConnection(); 
con.Url = (@"http://" + ServerType._StaticArcGISServerName + "/arcgis/services/Mobile_Services/" + AppSettings._StaticSynchronizationName + "/MapServer/Mobileserver");
con.CreateCache(mobileCache.StoragePath); 
mobileCache.Open();
                                        
foreach (Layer layer in mobileCache.Layers)
{
FeatureLayer featureLayer = (FeatureLayer)layer;
FeatureLayerSyncAgent layerSyncAgent = new FeatureLayerSyncAgent(featureLayer);
layerSyncAgent.MapDocumentConnection = con;
layerSyncAgent.SynchronizationDirection = SyncDirection.UploadOnly;
SyncResults theSyncResults = new SyncResults();
theSyncResults = layerSyncAgent.Synchronize();                                                
}
0 Kudos
KierenTinning1
Deactivated User
Excellent, thank you. I actually did something similar

private void btnGetData_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            QueryFilter qf = MakeCacheQuery();
            IEnumerable<MobileCacheInfo> emi = MobileApplication.Current.Project.EnumerateMobileCacheInfos();

            foreach (MobileCacheInfo mi in emi)
            {
                MobileCache mc = new MobileCache(mi.MobileCache.StoragePath);
               

                if (mc.CacheExists && mc.IsOpen)
                    mc.Close();

                try
                {
                    var con = new MobileServiceConnection();
                    con.Url = mi.MobileServiceConnection.Url;
                    con.CreateCache(mc);
                    mc.Open();
                    ICollection<FeatureLayer> flayers = mc.FeatureLayers;
                    foreach (FeatureLayer fl in flayers)
                    {
                        var flsyncAgent = new FeatureLayerSyncAgent(fl, con);
                        flsyncAgent.SynchronizationDirection = SyncDirection.DownloadOnly;
                        flsyncAgent.DownloadFilter = qf;
                        SyncResults sr = flsyncAgent.Synchronize();
                    }
                }
                finally
                {
                    if (mc != null && mc.CacheExists && mc.IsOpen)
                        mc.Close();
                }

            }
            Cursor.Current = Cursors.Default;
        }

What is really unfortunate here though is the QueryFilter won't accept the GeometricRelationship - I can download all of the data that I have, but not a subset based on the intersection of the layers

private QueryFilter MakeCacheQuery()
        {
            if (cmbDownloadParameter.SelectedIndex < 3)
            {
                GpsConnection gps = Common.Utilities.GPSTools.GpsConnection;
                if (gps == null)
                {
                    gps = MobileApplication.Current.GpsConnectionManager.Connection;
                }

                Coordinate c = MobileApplication.Current.Project.SpatialReference.FromWgs84(gps.Longitude, gps.Latitude);
                Geometry pointGeom = new ESRI.ArcGIS.Mobile.Geometries.Point(c);

                Double dblRad = 100;

                if (cmbDownloadParameter.SelectedItem.ToString().Equals("100 Meters"))
                    dblRad = 100;
                else if (cmbDownloadParameter.SelectedItem.ToString().Equals("500 Meters"))
                    dblRad = 500;
                else if (cmbDownloadParameter.SelectedItem.ToString().Equals("1 Kilometer"))
                    dblRad = 1000;



                Polygon pg = Common.Geography.Geometry.BufferPointFromGpsCoordinate(c, dblRad);
                QueryFilter qf = new QueryFilter(pg, GeometricRelationshipType.Intersect);
                return qf;

            }
}

With the buffering code here

public static class Geometry
    {
        public static Polygon BufferPointFromGpsCoordinate(Coordinate c, Double dblRadius)
        {
            Double dbDegreeToMeter = 0.0000089928;
            Int32 degreeInterval = 1;

            CoordinateCollection coordCollection = new CoordinateCollection();

            for (Double degree = 0; degree < 360; degree += degreeInterval)
            {
                Coordinate radiusCoordinate = new Coordinate();
                radiusCoordinate.X = c.X + (Math.Cos((degree / 360) * 2 * Math.PI) * dbDegreeToMeter * dblRadius);
                radiusCoordinate.Y = c.Y + (Math.Cos((degree / 360) * 2 * Math.PI) * dbDegreeToMeter * dblRadius);

                coordCollection.Add(radiusCoordinate);
            }
           
            return new Polygon(coordCollection);
        }

    }
0 Kudos