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 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);
        }
        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);
        }
Esempio n. 5
0
 public long Encode(double latitude, double longitude)
 {
     return(GeoHash.EncodeInt(latitude, longitude));
 }
Esempio n. 6
0
        public void EncodeInt_WhenTheBitDepthIsProvided_ReturnsHashStringIntWithTheProvidedBitDepth()
        {
            var actualHashStringInt = GeoHash.EncodeInt(Latitude, Longitude, 26);

            Assert.Equal(60572995, actualHashStringInt);
        }
Esempio n. 7
0
        public void EncodeInt_WhenTheBitDepthIsNotProvided_ReturnsHashStringIntWithTheDefaultBitDepth()
        {
            var actualHashStringInt = GeoHash.EncodeInt(Latitude, Longitude);

            Assert.Equal(HashStringInt, actualHashStringInt);
        }
Esempio n. 8
0
        public void BboxesInt_ReturnsHashStringsIntBetweenCoordinates()
        {
            var bBoxes = GeoHash.BboxesInt(30, 120, 30.0001, 120.0001, 8);

            Assert.Equal(GeoHash.EncodeInt(30.0001, 120.0001, 8), bBoxes[bBoxes.Length - 1]);
        }