| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 | using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using Comal.Classes;using InABox.Core;using InABox.Database;using System;namespace Comal.Stores{    public class GPSTrackerLocationStore : BaseStore<GPSTrackerLocation>    {        private static ConcurrentDictionary<string, Guid> _cache;        private static ConcurrentBag<Tuple<double, double, string>> _addresses;        public override void Init()        {            Logger.Send(LogType.Information, "", "Initializing GPS Tracker Caches");            _addresses = new ConcurrentBag<Tuple<double, double, string>>(                Provider.Query(                    new Filter<GPSTrackerLocation>(x => x.Location.Address).IsNotEqualTo(""),                    Columns.None<GPSTrackerLocation>().Add(                        x => x.Location.Address,                        x => x.Location.Longitude,                        x => x.Location.Latitude                    ),                    null,                    null,                    true,                    true                ).Rows.Select(r => new Tuple<double, double, string>(                        r.Get<GPSTrackerLocation, double>(c => c.Location.Latitude),                        r.Get<GPSTrackerLocation, double>(c => c.Location.Longitude),                        r.Get<GPSTrackerLocation, string>(c => c.Location.Address)                    )                ));            _cache = new ConcurrentDictionary<string, Guid>(                Provider.Query(                    new Filter<GPSTracker>(x => x.DeviceID).IsNotEqualTo(Guid.Empty),                    Columns.None<GPSTracker>().Add(x => x.DeviceID).Add(x => x.ID)                ).Rows.Select(r => new KeyValuePair<String, Guid>(r.Get<GPSTracker, String>(c => c.DeviceID), r.Get<GPSTracker, Guid>(c => c.ID)))            );        }        public string ReverseGeocode(double latitude, double longitude)        {            var tuple = _addresses.FirstOrDefault(x => Equals(x.Item1, latitude) && Equals(x.Item2, longitude));            if (tuple == null)            {                var address = StoreUtils.ReverseGeocode(latitude, longitude);                if (!string.IsNullOrWhiteSpace(address))                {                    tuple = new Tuple<double, double, string>(latitude, longitude, address);                    _addresses.Add(tuple);                }            }            return tuple != null ? tuple.Item3 : "";        }        protected override void BeforeSave(GPSTrackerLocation entity)        {            base.BeforeSave(entity);                        if (Equals(entity.Tracker.ID, Guid.Empty))            {                if (!_cache.ContainsKey(entity.DeviceID))                {                    Logger.Send(LogType.Information, "", string.Format("- Tracker Cache Update Required: {0}", entity.DeviceID));                    var row = Provider.Query(                        new Filter<GPSTracker>(x => x.DeviceID).IsEqualTo(entity.DeviceID),                        Columns.None<GPSTracker>().Add(x => x.ID)                    ).Rows.FirstOrDefault();                    if (row != null)                    {                        entity.Tracker.ID = row.Get<GPSTracker, Guid>(x => x.ID);                        _cache[entity.DeviceID] = entity.Tracker.ID;                        Logger.Send(LogType.Information, "",                            string.Format("- Adding Tracker to Cache: {0} => {1}", entity.DeviceID, entity.Tracker.ID));                    }                }                else                {                    entity.Tracker.ID = _cache[entity.DeviceID];                }            }            if (!Equals(entity.Tracker.ID, Guid.Empty)                && string.IsNullOrWhiteSpace(entity.Location.Address)                && !Equals(entity.Location.Latitude, 0.0D)                && !Equals(entity.Location.Longitude, 0.0D)               )                entity.Location.Address = ReverseGeocode(entity.Location.Latitude, entity.Location.Longitude);        }        private void UpdateTrackers(IEnumerable<GPSTrackerLocation> entities, ref string auditnote)        {            var updates = new List<GPSTracker>();            foreach (var entity in entities)            {                if (entity.Tracker.IsValid())                {                    var tracker = new GPSTracker();                    tracker.ID = entity.Tracker.ID;                    tracker.Location.Longitude = entity.Location.Longitude;                    tracker.Location.Latitude = entity.Location.Latitude;                    tracker.Location.Timestamp = entity.Location.Timestamp;                    tracker.Location.Address = entity.Location.Address;                    tracker.BatteryLevel = entity.BatteryLevel;                    tracker.Hours = entity.Hours;                    tracker.Distance = entity.Distance;                    tracker.Counter1 = entity.Counter1;                    tracker.Counter2 = entity.Counter2;                    tracker.Counter3 = entity.Counter3;                    tracker.Counter4 = entity.Counter4;                    updates.Add(tracker);                }                else                {                    Logger.Send(LogType.Error, "", string.Format("Skipping GPS Tracker Update (Cache Size={0})", _cache.Count));                }            }            if (updates.Any())            {                Provider.Save(updates);                AuditTrail(updates, new[] { auditnote });            }            auditnote = null;        }        protected override void OnSave(GPSTrackerLocation[] entities, ref string auditnote)        {            var updates = entities.Where(x => !Equals(x.Tracker.ID, Guid.Empty)).ToArray();            if (updates.Any())            {                UpdateTrackers(updates, ref auditnote);                base.OnSave(updates, ref auditnote);            }        }        protected override void OnSave(GPSTrackerLocation entity, ref string auditnote)        {            if (Equals(entity.Tracker.ID, Guid.Empty))                return;            UpdateTrackers(new[] { entity }, ref auditnote);            base.OnSave(entity, ref auditnote);        }    }}
 |