Esempio n. 1
0
        public List <GeohashRange> GetRanges(double latitude, double longitude, int rangeBitDepth = 16) // 156.5km
        {
            long geohash = GeoHash.EncodeInt(latitude, longitude, bitDepth: rangeBitDepth);

            long[] neighbours  = GeoHash.NeighborsInt(geohash, bitDepth: rangeBitDepth);
            var    ranges      = new List <GeohashRange>(neighbours.Length);
            var    rangeLength = geohash.ToString().Length;

            foreach (var neighbour in neighbours)
            {
                var  latLong   = GeoHash.DecodeInt(neighbour, bitDepth: rangeBitDepth);
                long geoHash   = GeoHash.EncodeInt(latLong.Coordinates.Lat, latLong.Coordinates.Lon);
                var  padAmount = geoHash.ToString().Length;

                // Now produce the min / max value of this based on the range length
                // So 21345 becomes 213450000000 to 21345999999
                var leftPart = geoHash.ToString().Substring(0, rangeLength);
                var min      = Convert.ToInt64(leftPart.PadRight(padAmount, '0'));
                var max      = Convert.ToInt64(leftPart.PadRight(padAmount, '9'));

                ranges.Add(new GeohashRange {
                    Min = min, Max = max
                });
            }

            return(ranges);
        }
Esempio n. 2
0
        public Task <MessageHandlerResults> ProcessMessageAsync(Message msg, string pipelineName, int idx)
        {
            //TODO: Handle incorrect messages that doesn't have the required properties
            var lat = double.Parse(msg.Properties[InputLatProperty]);
            var lon = double.Parse(msg.Properties[InputLonProperty]);

            var precision = GeoHashPrecision;
            var geoHash   = GeoHash.EncodeInt(lat, lon, precision);

            msg.Properties[GeoHashProperty] = geoHash.ToString();
            msg.Properties[GeoHashProperty + "Precision"] = precision.ToString();

            if (CalculateGeoHashCenterCoordinates)
            {
                var x = GeoHash.DecodeInt(geoHash, precision);

                msg.Properties[GeoHashCenterLatProperty] = x.Coordinates.Lat.ToString();
                msg.Properties[GeoHashCenterLonProperty] = x.Coordinates.Lon.ToString();

                var originCoordinates = new GeoCoordinate(lat, lon);
                var geoHashCenter     = new GeoCoordinate(x.Coordinates.Lat, x.Coordinates.Lon);

                msg.Properties[GeoHashCenterDistProperty] = originCoordinates.GetDistanceTo(geoHashCenter).ToString("0");
            }

            return(Task.FromResult(MessageHandlerResults.Success));
        }
Esempio n. 3
0
        public void DecodeInt_WhenHashStringIntHasDefaultBitDepth_ReturnsCoordinatesWithinStandardPrecision()
        {
            var geoHashDecodeResult = GeoHash.DecodeInt(HashStringInt);

            Assert.True(Math.Abs(Latitude - geoHashDecodeResult.Coordinates.Lat) < 0.0001, "(37.8324 - " + geoHashDecodeResult.Coordinates.Lat + " was >= 0.0001");
            Assert.True(Math.Abs(Longitude - geoHashDecodeResult.Coordinates.Lon) < 0.0001, "(112.5584 - " + geoHashDecodeResult.Coordinates.Lon + " was >= 0.0001");
        }
Esempio n. 4
0
        public async Task HandleLocationEventAsync(GameEventData data)
        {
            const int GeoHashBitPrecision = 32;                //bits
            const int LocationLookupGeoHashBitPrecistion = 30; //bits

            var inEvent = JsonConvert.DeserializeObject <IncommingLocationEvent>(data.Data);

            var geoHash = GeoHash.EncodeInt(inEvent.Lat, inEvent.Lon, GeoHashBitPrecision);
            var geoHashCenterCoordinates = GeoHash.DecodeInt(geoHash, GeoHashBitPrecision).Coordinates;
            var locationLookupGeoHash    = GeoHash.EncodeInt(inEvent.Lat, inEvent.Lon, LocationLookupGeoHashBitPrecistion);

            var l        = new LocationEventHandler(_locationLookupProvider);
            var location = l.LookupGeoHash(locationLookupGeoHash, LocationLookupGeoHashBitPrecistion);

            var outEvent = new OutgoingLocationEvent
            {
                EnqueueTime      = data.EnqueuedTime,
                DequeueTime      = data.DequeuedTime,
                ClientUtcTime    = inEvent.ClientUtcTime,
                GameSessionId    = inEvent.GameSessionId,
                Lat              = inEvent.Lat,
                Lon              = inEvent.Lon,
                GeoHash          = geoHash,
                GeoHashPrecision = GeoHashBitPrecision,
                GeoHashCenterLat = geoHashCenterCoordinates.Lat,
                GeoHashCenterLon = geoHashCenterCoordinates.Lon,
                Country          = location.Country,
                District         = location.District,
                City             = location.City,
                Properties       = inEvent.Properties
            };

            //TODO: Optimize this so we don't serialize back to JSON first and then to CSV

            var jsonObject = JsonConvert.SerializeObject(
                outEvent,
                Formatting.Indented,
                new JsonSerializerSettings {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });

            data.Data = jsonObject;

            var csvObject = data.ToCsv("gameSessionId", "lat", "lon",
                                       "geoHash", "geoHashPrecision",
                                       "geoHashCenterLat", "geoHashCenterLon", "country", "district", "city");

            // Output CSV to BLOB Storage and JSON to StreamAnalytics (via EventHub)
            await _blobOutputManager.QueueAppendToBlobAsync(data, csvObject);

            await _eventHubOutputManager.SendToEventHubAsync(data, jsonObject);
        }
Esempio n. 5
0
        private string Print(DateTime startTime, TimeSpan time, GeoPosition pos)
        {
            const string type    = "location";
            const string version = "1.0.0";

            var enqueueTime   = startTime + time;
            var dequeueTime   = enqueueTime.AddMilliseconds(_random.Next(500));
            var clientUtcTime = enqueueTime.AddMilliseconds(-_random.Next(500));
            // "yyyy-MM-dd HH:mm:ss"
            var hashPos = GeoHash.DecodeInt(pos.GeoHash, 32);

            var line = $"{type}|{version}|{enqueueTime:yyyy-MM-dd HH:mm:ss}|{dequeueTime:yyyy-MM-dd HH:mm:ss}|{clientUtcTime:yyyy-MM-dd HH:mm:ss}|{_gameSessionId}|{pos.Lat:0.############}|{pos.Lon:0.############}|{pos.GeoHash}|{pos.Precision}|{hashPos.Coordinates.Lat}|{hashPos.Coordinates.Lon}|Country N/A|District N/A|City N/A|prop1=tst;prop2=tmp";

            return(line);
        }
Esempio n. 6
0
        public LocationLookupInfo LookupGeoHash(long geoHash, int precision)
        {
            if (s_cache.TryGetValue(geoHash, out LocationLookupInfo info))
            {
                Console.WriteLine($"Cached geohash {geoHash}:{precision} is in {info.City}, {info.District}, {info.Country}");
                return(info);
            }

            Console.WriteLine($"Looking up geohash {geoHash}:{precision}");
            var geoHashCenter = GeoHash.DecodeInt(geoHash, precision).Coordinates;
            var l             = _locationLookupProvider.Lookup(geoHashCenter.Lat, geoHashCenter.Lon);

            l.Wait();
            var location = l.Result;

            Console.WriteLine($"Geohash {geoHash}:{precision} is in {location.City}, {location.District}, {location.Country} according to {_locationLookupProvider.GetType()}");
            s_cache.TryAdd(geoHash, location);

            return(location);
        }
        public async Task <MessageHandlerResults> ProcessMessageAsync(Message msg, string pipelineName, int idx)
        {
            //TODO: Replace all console logging of exceptions to generic log solution

            double lat;
            double lon;

            //TODO: Catch more specific error if property doesn't exist or use another method to get the properties
            try
            {
                lat = double.Parse(msg.Properties[_latProperty]);
                lon = double.Parse(msg.Properties[_lonProperty]);
            }
            catch (Exception)
            {
                Console.WriteLine($"Unable to find required properties: '{_latProperty}' and '{_lonProperty}' on message");
                return(MessageHandlerResults.FailStopProcessing);
            }

            var geoHash = GeoHash.EncodeInt(lat, lon, _geoHashCacheProvider.Precision);

            BingResult bingParsingResult;

            //if we have the result in the cache, fetch it
            if (await _geoHashCacheProvider.ContainsGeoHashAsync(geoHash))
            {
                bingParsingResult = await _geoHashCacheProvider.GetAsync(geoHash);

                Debug.WriteLine("Found in cache");
            }
            //else, query bing directly
            else
            {
                Debug.WriteLine("Not found in cache");
                double geoHashCenterLat, geoHashCenterLon;

                //get the center of the geoHash in order to call Bing API with this {lat,lon}
                var decodedGeoHash = GeoHash.DecodeInt(geoHash, _geoHashCacheProvider.Precision);
                geoHashCenterLat = decodedGeoHash.Coordinates.Lat;
                geoHashCenterLon = decodedGeoHash.Coordinates.Lon;

                var    bingUrl = $"http://dev.virtualearth.net/REST/v1/Locations/{geoHashCenterLat},{geoHashCenterLon}?key={_bingMapsKey}";
                string bingResult;

                try
                {
                    var client = new HttpClient();
                    bingResult = await client.GetStringAsync(bingUrl);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("An exception occurred while calling Bing to Lookup coordinates");
                    Console.WriteLine(ex);

                    return(MessageHandlerResults.FailStopProcessing);
                }

                try
                {
                    var json    = JObject.Parse(bingResult);
                    var address = json["resourceSets"][0]["resources"][0]["address"];

                    //create a bing parsing result instance and cache it
                    bingParsingResult = new BingResult()
                    {
                        City = (string)address["locality"], Country = (string)address["countryRegion"], District = (string)address["adminDistrict"]
                    };
                    await _geoHashCacheProvider.AppendToCacheAsync(geoHash, bingParsingResult);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("An exception occurred while trying to parse Location Lookup results from Bing");
                    Console.WriteLine(ex);

                    return(MessageHandlerResults.FailStopProcessing);
                }
            }

            //add values to msg
            msg.Properties.Add("country", bingParsingResult.Country);
            msg.Properties.Add("district", bingParsingResult.District);
            msg.Properties.Add("city", bingParsingResult.City);

            return(MessageHandlerResults.Success);
        }