public IEnumerable <ImportRequestError> Handle(ImportRequestsCommand message) { var errors = new List <ImportRequestError>(); foreach (var request in message.Requests) { request.Source = RequestSource.Csv; // todo: do basic data validation if (!_context.Requests.Any(r => r.ProviderRequestId == request.ProviderRequestId)) { //If lat/long not provided, use geocoding API to get them if (request.Latitude == 0 && request.Longitude == 0) { //Assume the first returned address is correct var address = _geocoder.Geocode(request.Address, request.City, request.State, request.Zip, string.Empty) .FirstOrDefault(); request.Latitude = address?.Coordinates.Latitude ?? 0; request.Longitude = address?.Coordinates.Longitude ?? 0; } _context.Requests.Add(request); } } _context.SaveChanges(); return(errors); }
public static double GetLatFromCountry(this CountryViewModel country, IGeocoder geocoder) { var addresses = geocoder.Geocode(country.Country); return(addresses.First().Coordinates.Latitude); }
protected override async Task HandleCore(AddApiRequestCommand message) { //TODO mgmccarthy: I can probably move the Request creation to the controller and put the entity on the command instead of the view model mapping code below var request = new Request { RequestId = NewRequestId(), ProviderRequestId = message.ViewModel.ProviderRequestId, ProviderData = message.ViewModel.ProviderData, Address = message.ViewModel.Address, City = message.ViewModel.City, DateAdded = DateTimeUtcNow(), Email = message.ViewModel.Email, Name = message.ViewModel.Name, Phone = message.ViewModel.Phone, State = message.ViewModel.State, Zip = message.ViewModel.Zip, Status = RequestStatus.Unassigned, Source = RequestSource.Api }; var address = geocoder.Geocode(message.ViewModel.Address, message.ViewModel.City, message.ViewModel.State, message.ViewModel.Zip, string.Empty).FirstOrDefault(); request.Latitude = message.ViewModel.Latitude == 0 ? address?.Coordinates.Latitude ?? 0 : message.ViewModel.Latitude; request.Longitude = message.ViewModel.Longitude == 0 ? address?.Coordinates.Longitude ?? 0 : message.ViewModel.Longitude; context.AddOrUpdate(request); await context.SaveChangesAsync(); await mediator.PublishAsync(new ApiRequestAddedNotification { RequestId = request.RequestId }); }
public void RequestGeoCoords(string searchValue, IList <GeoPoint> pointsList) { if (string.IsNullOrEmpty(searchValue)) { throw new ArgumentNullException(@"searchValue"); } if (pointsList == null) { throw new ArgumentNullException(@"pointsList"); } try { IGeocoder geocoder = CreateGeocoder(); IEnumerable <GeoPoint> geoPoints = geocoder.Geocode(searchValue, 1); foreach (GeoPoint pt in geoPoints) { pointsList.Add(pt); } } catch (Exception ex) { Logger.LogWrite("AppHost.RequestGeoCoords(): " + ex.Message); } }
// Returns a tuple containing a latitude and longitude pair // Get things out of tuples using tuple.item1, tuple.item2, et cetera. public Tuple <double, double> GetLatLong(string address) { // This library calls the result class "Address" but it also contains the coordinates // Not sure why it returns a collection of them but I guess we'll find out IEnumerable <Address> results = googleGeocoder.Geocode(address); double latitude = 0.0; double longitude = 0.0; // Converting to double can (and will) throw formatting exceptions we need to handle try { latitude = Convert.ToDouble(results.First().Coordinates.Latitude); longitude = Convert.ToDouble(results.First().Coordinates.Longitude); } catch (FormatException) { Console.Error.WriteLine("Could not convert coordinates {0}, {1} to doubles", latitude, longitude); // If something goes wrong, coordinates will be zeroes } catch (InvalidOperationException e) { Console.Error.WriteLine(e.Message); } var coords = Tuple.Create(latitude, longitude); // Console.WriteLine("Parsed coordinates {0}, {1}", coords.Item1, coords.Item2); return(coords); }
public async Task <Request> Handle(AddApiRequestCommand message) { var requestId = GetRequestId(message.RequestViewModel.RequestId); var request = await _context.Requests.SingleOrDefaultAsync(x => x.RequestId == requestId) ?? new Request { RequestId = requestId }; request.ProviderId = message.RequestViewModel.ProviderId; request.ProviderData = message.RequestViewModel.ProviderData; request.Address = message.RequestViewModel.Address; request.City = message.RequestViewModel.City; request.DateAdded = DateTimeUtcNow(); request.Email = message.RequestViewModel.Email; request.Name = message.RequestViewModel.Name; request.Phone = message.RequestViewModel.Phone; request.State = message.RequestViewModel.State; request.Zip = message.RequestViewModel.Zip; request.Status = ConvertRequestStatusToEnum(message.RequestViewModel.Status); request.Source = RequestSource.Api; var address = _geocoder.Geocode(message.RequestViewModel.Address, message.RequestViewModel.City, message.RequestViewModel.State, message.RequestViewModel.Zip, string.Empty).FirstOrDefault(); request.Latitude = message.RequestViewModel.Latitude == 0 ? address?.Coordinates.Latitude ?? 0 : message.RequestViewModel.Latitude; request.Longitude = message.RequestViewModel.Longitude == 0 ? address?.Coordinates.Longitude ?? 0 : message.RequestViewModel.Longitude; _context.AddOrUpdate(request); await _context.SaveChangesAsync(); //TODO mgmccarthy: find out if/why we need to return the entire Request back to the caller. I would rather us return the RequestId return(request); }
public async Task <Guid> Handle(EditRequestCommand message) { var request = await _context.Requests .Include(l => l.Event) .SingleOrDefaultAsync(t => t.RequestId == message.RequestModel.Id) ?? _context.Add(new Request { Source = RequestSource.UI }).Entity; var addressChanged = DetermineIfAddressChanged(message, request); request.EventId = message.RequestModel.EventId; request.Address = message.RequestModel.Address; request.City = message.RequestModel.City; request.Name = message.RequestModel.Name; request.State = message.RequestModel.State; request.Zip = message.RequestModel.Zip; request.Email = message.RequestModel.Email; request.Phone = message.RequestModel.Phone; //If lat/long not provided or we detect the address changed, then use geocoding API to get the lat/long if ((request.Latitude == 0 && request.Longitude == 0) || addressChanged) { //Assume the first returned address is correct var address = _geocoder.Geocode(request.Address, request.City, request.State, request.Zip, string.Empty) .FirstOrDefault(); request.Latitude = address?.Coordinates.Latitude ?? 0; request.Longitude = address?.Coordinates.Longitude ?? 0; } _context.AddOrUpdate(request); await _context.SaveChangesAsync(); return(request.RequestId); }
public async Task <AddRequestError> Handle(AddRequestCommandAsync message) { AddRequestError error = null; if (message.Request == null) { throw new InvalidOperationException("Request property is required."); } var request = message.Request; try { //todo: I'm not sure if this logic is going to be correct, as this allows an update of status to existing requests. //I added this because the red cross is passing in current status. string providerId = request?.ProviderId; Request entity = await _dataContext.Requests.FirstOrDefaultAsync(x => x.ProviderId == providerId); if (entity == null) { request.RequestId = Guid.NewGuid(); //If lat/long not provided, use geocoding API to get them if (request.Latitude == 0 && request.Longitude == 0) { //Assume the first returned address is correct var address = _geocoder.Geocode(request.Address, request.City, request.State, request.Zip, string.Empty) .FirstOrDefault(); request.Latitude = address?.Coordinates.Latitude ?? 0; request.Longitude = address?.Coordinates.Longitude ?? 0; } entity = request; _dataContext.Requests.Add(entity); } else { entity.Status = request.Status; } await _dataContext.SaveChangesAsync(); } catch (Exception) { // FRAGILE: no other Handlers trap errors, TODO: let this handler throw like the others? error = new AddRequestError { ProviderId = request?.ProviderId ?? "No ProviderId.", Reason = "Failed to add request." }; //todo: Logging for this error } return(error); }
public ActionResult Geocode(string address) { if (String.IsNullOrEmpty(address)) { return(View("Index")); } var addresses = geoCoder.Geocode(address).ToArray(); return(View("Index", addresses)); }
protected override async Task HandleCore(ImportRequestsCommand message) { var orgId = await context.Events.AsNoTracking() .Include(rec => rec.Campaign) .Where(rec => rec.Id == message.EventId) .Select(rec => rec.Campaign.ManagingOrganizationId) .FirstOrDefaultAsync(); if (orgId > 0) { var requests = message.ImportRequestViewModels.Select(viewModel => new Request { OrganizationId = orgId, RequestId = NewRequestId(), ProviderRequestId = viewModel.Id, EventId = message.EventId, ProviderData = viewModel.ProviderData, Address = viewModel.Address, City = viewModel.City, DateAdded = DateTimeUtcNow(), Email = viewModel.Email, Name = viewModel.Name, Phone = viewModel.Phone, State = viewModel.State, Zip = viewModel.Zip, Status = RequestStatus.Unassigned, Source = RequestSource.Csv }).ToList(); context.Requests.AddRange(requests); //TODO mgmccarthy: eventually move IGeocoder invocations to async using azure. Issue #1626 and #1639 foreach (var request in requests) { if (request.Latitude == 0 && request.Longitude == 0) { //Assume the first returned address is correct var address = geocoder.Geocode(request.Address, request.City, request.State, request.Zip, string.Empty).FirstOrDefault(); request.Latitude = address?.Coordinates.Latitude ?? 0; request.Longitude = address?.Coordinates.Longitude ?? 0; } } await context.SaveChangesAsync(); } }
public ActionResult BatchGeocode() { var userAddresses = _service.UserAddresses .GetAll() .Where(x => x.Location == null) .Distinct() .ToList(); var addresses = new Dictionary <string, Tuple <List <int>, List <Address> > >(); userAddresses.ForEach(x => { if (addresses.ContainsKey(x.Formatted)) { addresses[x.Formatted].Item1.Add(x.Id); } else { addresses.Add(x.Formatted, new Tuple <List <int>, List <Address> >(new List <int> { x.Id }, new List <Address>())); } }); foreach (var address in addresses) { try { var codedAddresses = _geocoder.Geocode(address.Key).ToList(); address.Value.Item2.AddRange(codedAddresses); var coordinates = codedAddresses.First().Coordinates; address.Value.Item1.ForEach(x => { var userAddress = userAddresses.Single(y => y.Id.Equals(x)); userAddress.UpdateLocation(coordinates.Latitude, coordinates.Longitude); _service.UserAddresses.Update(userAddress); }); } catch { } } return(View("Index", addresses)); }
public FC.Customer GetOrCreate(CPlus.Models.Customer cPlusCustomer) { var customers = _client.Execute(new GetCustomersRequest(nameLike: cPlusCustomer.Name)); var customer = customers.FirstOrDefault(); if (customer == null) { customer = new FC.Customer() { Name = cPlusCustomer.Name, Email = cPlusCustomer.Email, Phone = cPlusCustomer.Phone, ZipCode = cPlusCustomer.ZipCode, Street = cPlusCustomer.Street, Number = cPlusCustomer.Number, City = cPlusCustomer.City, State = cPlusCustomer.State }; var searchAddress = string.Format("{0}, {1} - {2}, {3} - {4}", customer.Street, customer.Number, customer.City, customer.State, customer.ZipCode ); IEnumerable <Address> addresses = _geoCoder.Geocode(searchAddress); if (!addresses.Any()) { throw new LatitudeLongitudeCouldNotBeDecodedException(searchAddress); } customer.Latitude = Convert.ToDecimal(addresses.First().Coordinates.Latitude); customer.Longitude = Convert.ToDecimal(addresses.First().Coordinates.Longitude); customer = _client.Execute(new CreateCustomerRequest(customer)); } return(customer); }
public void Process(RequestApiViewModel viewModel) { //since this is job code now, it needs to be idempotent, this could be re-tried by Hangire if it fails var requestExists = context.Requests.Any(x => x.ProviderRequestId == viewModel.ProviderRequestId); if (!requestExists) { var request = new Request { RequestId = NewRequestId(), //TODO mgmccarthy: this is hard-coded for now to 1, which is HTBox Org's Id in dev b/c SampleDataGenerator always creates it first. We'll need something more robust when we go to production. OrganizationId = 1, ProviderRequestId = viewModel.ProviderRequestId, ProviderData = viewModel.ProviderData, Address = viewModel.Address, City = viewModel.City, DateAdded = DateTimeUtcNow(), Email = viewModel.Email, Name = viewModel.Name, Phone = viewModel.Phone, State = viewModel.State, Zip = viewModel.Zip, Status = RequestStatus.Unassigned, Source = RequestSource.Api }; //this is a web service call var address = geocoder.Geocode(viewModel.Address, viewModel.City, viewModel.State, viewModel.Zip, string.Empty).FirstOrDefault(); request.Latitude = address?.Coordinates.Latitude ?? 0; request.Longitude = address?.Coordinates.Longitude ?? 0; context.Add(request); context.SaveChanges(); mediator.Publish(new ApiRequestProcessedNotification { ProviderRequestId = viewModel.ProviderRequestId }); } }
public void CanGeocodeAddress() { Address[] addresses = geocoder.Geocode("1600 pennsylvania ave washington dc").ToArray(); addresses[0].AssertWhiteHouse(); }
public static double GetLongFromPlaceName(string place, IGeocoder geocoder) { var addresses = geocoder.Geocode(place); return(addresses.First().Coordinates.Longitude); }
public virtual void CanGeocodeAddress(string address) { Address[] addresses = geocoder.Geocode(address).ToArray(); addresses[0].AssertWhiteHouse(); }