private WorldPoint PollGps()
        {
            WorldPoint point = new WorldPoint();

            if (CheckForGps())
            {
                int interval = PollingInterval;
                if (interval <= 0)
                {
                    interval = 5000;
                }
                Gps.GpsPosition pos = gps.GetPosition(new TimeSpan(0, 0, 0, 0, interval));
                if (pos != null && pos.LongitudeValid && pos.LatitudeValid &&
                    pos.Latitude != 0 && pos.Longitude != 0)
                {
                    point.Latitude  = pos.Latitude;
                    point.Longitude = pos.Longitude;
                    if (pos.SeaLevelAltitudeValid)
                    {
                        point.Altitude = pos.SeaLevelAltitude;
                    }
                    else
                    {
                        point.Altitude = null;
                    }

                    point.FixTime = pos.Time;
                }
            }

            return(point);
        }
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }
            if (obj.GetType() != this.GetType())
            {
                return(false);
            }

            WorldPoint other = (WorldPoint)obj;

            return
                (Latitude.Equals(other.Latitude) &&
                 Longitude.Equals(other.Longitude) &&
                 FixTime.Equals(other.FixTime));
        }
        private WorldPoint PollGsmNetwork()
        {
            WorldPoint point = new WorldPoint();

            if (CountryCode == 0 || NetworkCode == 0 || CellId == 0)
            {
                return(point);
            }
            if (cellCache == null)
            {
                cellCache = new List <CellInfo>();
            }

            CellInfo info = new CellInfo()
            {
                MCC = CountryCode, MNC = NetworkCode, LAC = AreaCode, CID = CellId
            };

            Debug.WriteLine("ID: " + CellId.ToString());
            int index = cellCache.IndexOf(info);

            if (index > -1)
            {
                info = cellCache[index];
            }
            else
            {
                Exception ex = null;
                bool      ok = false;

                if (!ok)
                {
                    try
                    {
                        ok = TranslateCellIdWithGoogle(info, false);
                        if (ok)
                        {
                            info.Service = FixService.Google;
                        }
                    }
                    catch (Exception ext) { ex = ext; }
                }

                if (!ok)
                {
                    ok = TranslateCellIdWithOpenCellId(info);
                    if (ok)
                    {
                        info.Service = FixService.OpenCellOrg;
                    }
                }

                if (!ok)
                {
                    try
                    {
                        ok = TranslateCellIdWithCellDb(info);
                        if (ok)
                        {
                            info.Service = FixService.CellDbOrg;
                        }
                    }
                    catch (Exception ext) { ex = ext; }
                }

                if (ok)
                {
                    cellCache.Add(info);
                }
                else if (ex != null)
                {
                    throw ex;
                }
                else
                {
                    info = null;
                }
            }
            if (info != null &&
                info.Lat.HasValue &&
                info.Lng.HasValue &&
                info.Lat.Value != 0 &&
                info.Lng.Value != 0)
            {
                point.Latitude  = info.Lat.Value;
                point.Longitude = info.Lng.Value;
                point.FixTime   = DateTime.UtcNow;
                FixService      = info.Service;
            }

            return(point);
        }
        private WorldPoint PollGeoIp()
        {
            Exception exception = null;

            WorldPoint point = new WorldPoint();

            HttpWebRequest  req     = null;
            HttpWebResponse res     = null;
            var             culture = System.Globalization.CultureInfo.GetCultureInfo("en-us");


            try
            {
                req = (HttpWebRequest)WebRequest.Create(geoIpTool);

                req.Timeout = 10000;
                req.Method  = "GET";

                res = (HttpWebResponse)req.GetResponse();

                if (res.StatusCode == HttpStatusCode.OK)
                {
                    XmlDocument  doc    = new XmlDocument();
                    StreamReader reader = new StreamReader(res.GetResponseStream());
                    string       xml    = reader.ReadToEnd();
                    doc.LoadXml(xml);

                    XmlNode node = doc.DocumentElement.SelectSingleNode("marker");

                    point.Latitude  = double.Parse(node.Attributes["lat"].Value, culture);
                    point.Longitude = double.Parse(node.Attributes["lng"].Value, culture);
                    point.FixTime   = DateTime.UtcNow;

                    FixService = FixService.GeoIpTool;
                    exception  = null;
                }
                else
                {
                    throw new Exception("Invalid response.");
                }
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            finally
            {
                if (req != null)
                {
                    req = null;
                }

                if (res != null)
                {
                    res.Close();
                    res = null;
                }
            }



            if (exception != null)
            {
                try
                {
                    req = (HttpWebRequest)WebRequest.Create(hostIp);

                    req.Timeout = 10000;
                    req.Method  = "GET";

                    res = (HttpWebResponse)req.GetResponse();
                    if (res.StatusCode == HttpStatusCode.OK)
                    {
                        StreamReader reader = new StreamReader(res.GetResponseStream());
                        string       file   = reader.ReadToEnd();

                        string header = "Latitude: ";
                        int    pos    = file.IndexOf(header);
                        pos += header.Length;
                        int pos2 = file.IndexOf("\n", pos);

                        string toParse = file.Substring(pos, pos2 - pos);
                        point.Latitude = double.Parse(toParse, culture);

                        header = "Longitude: ";
                        pos    = file.IndexOf(header);
                        pos   += header.Length;
                        pos2   = file.IndexOf("\n", pos);

                        toParse = file.Substring(pos, pos2 - pos);

                        point.Longitude = double.Parse(toParse, culture);
                        point.FixTime   = DateTime.UtcNow;
                        FixService      = FixService.HostIp;
                        exception       = null;
                    }
                    else
                    {
                        throw new Exception("Invalid response");
                    }
                }
                catch (Exception ex)
                {
                    exception = ex;
                }
                finally
                {
                    if (req != null)
                    {
                        req = null;
                    }

                    if (res != null)
                    {
                        res.Close();
                        res = null;
                    }
                }
            }

            if (exception != null)
            {
                try
                {
                    req = (HttpWebRequest)WebRequest.Create(geoPlugin);

                    req.Timeout = 10000;
                    req.Method  = "GET";

                    res = (HttpWebResponse)req.GetResponse();

                    if (res.StatusCode == HttpStatusCode.OK)
                    {
                        XmlDocument  doc    = new XmlDocument();
                        StreamReader reader = new StreamReader(res.GetResponseStream());
                        string       xml    = reader.ReadToEnd();
                        doc.LoadXml(xml);

                        point.Latitude  = double.Parse(doc.DocumentElement.SelectSingleNode("geoplugin_latitude").InnerText, culture);
                        point.Longitude = double.Parse(doc.DocumentElement.SelectSingleNode("geoplugin_longitude").InnerText, culture);
                        point.FixTime   = DateTime.UtcNow;
                        FixService      = FixService.GeoPlugin;

                        exception = null;
                    }
                    else
                    {
                        throw new Exception("Invalid response.");
                    }
                }
                catch (Exception ex)
                {
                    exception = ex;
                }
                finally
                {
                    if (req != null)
                    {
                        req = null;
                    }

                    if (res != null)
                    {
                        res.Close();
                        res = null;
                    }
                }
            }
            if (exception != null)
            {
                throw exception;
            }

            return(point);
        }
        private void PeriodicPoll(object state)
        {
            StringBuilder errors = new StringBuilder();

            GetCellTowerInfo();
            WorldPoint point = WorldPoint.Empty;

            if (UseGps)
            {
                try
                {
                    point = PollGps();
                    Debug.WriteLine("Gps");
                }
                catch (Exception ex)
                {
                    errors.Append(ex.Message);
                }

                if (!point.IsEmpty)
                {
                    FixType    = FixType.Gps;
                    FixService = FixService.None;
                }
            }
            else
            {
                if (gps != null && gps.Opened)
                {
                    gps.Close();
                }
            }

            if (UseNetwork && point.IsEmpty)
            {
                try
                {
                    point = PollGsmNetwork();
                    Debug.WriteLine("Gsm");
                    if (!point.IsEmpty)
                    {
                        FixType = FixType.GsmNetwork;
                    }
                }
                catch (Exception ex)
                {
                    if (errors.Length > 0)
                    {
                        errors.Append("\r\n");
                    }
                    errors.Append(ex.Message);
                }
            }

            if (point.IsEmpty && WorldPoint.IsEmpty)
            {
                try
                {
                    point = PollGeoIp();
                    Debug.WriteLine("GeoIp");
                    if (!point.IsEmpty)
                    {
                        FixType = FixType.GeoIp;
                    }
                }
                catch (Exception ex)
                {
                    errors.Append("\r\n");
                    errors.Append(ex.Message);
                }
            }


            if (point.IsEmpty && errors.Length > 0)
            {
                OnError(new ErrorEventArgs(new Exception(errors.ToString())));
            }
            else
            {
                bool changed = false;
                if (!point.IsEmpty && !point.Equals(this.WorldPoint))
                {
                    this.WorldPoint = point;
                    changed         = true;
                }
                if (changed)
                {
                    OnLocationChanged(new EventArgs());
                }
                OnPollHit(new EventArgs());
            }

            lock (this)
            {
                try
                {
                    if (timer != null)
                    {
                        if (PollingInterval > 0)
                        {
                            //reset timer to the next pooling
                            timer.Change(PollingInterval, Timeout.Infinite);
                        }
                        else
                        {
                            timer.Change(Timeout.Infinite, Timeout.Infinite);
                        }
                    }
                }
                catch (ObjectDisposedException) { }
            }
        }