/// <summary> /// Performs Address Verification on the provided <see cref="Rock.Model.Location" />. /// </summary> /// <param name="location">A <see cref="Rock.Model.Location" /> to verify.</param> /// <param name="reVerify">if set to <c>true</c> [re verify].</param> public void Verify(Location location, bool reVerify) { string inputLocation = location.ToString(); // Create new context to save service log without affecting calling method's context var rockContext = new RockContext(); Model.ServiceLogService logService = new Model.ServiceLogService(rockContext); // Try each of the verification services that were found through MEF foreach (var service in Rock.Address.VerificationContainer.Instance.Components) { if (service.Value.Value.IsActive) { string result; bool success = service.Value.Value.VerifyLocation(location, reVerify, out result); if (!string.IsNullOrWhiteSpace(result)) { // Log the results of the service Model.ServiceLog log = new Model.ServiceLog(); log.LogDateTime = RockDateTime.Now; log.Type = "Location Verify"; log.Name = service.Value.Metadata.ComponentName; log.Input = inputLocation; log.Result = result.Left(200); log.Success = success; logService.Add(log); } if (success) { break; } } } rockContext.SaveChanges(); }
/// <summary> /// Geocodes the specified <see cref="Location"/> /// </summary> /// <param name="location">The location.</param> /// <param name="personId">The person id.</param> public void Geocode(Location location, int?personId) { Model.ServiceLogService logService = new Model.ServiceLogService(); string inputLocation = location.ToString(); // Try each of the geocoding services that were found through MEF foreach (KeyValuePair <int, Lazy <Rock.Address.GeocodeComponent, Rock.Extension.IComponentData> > service in Rock.Address.GeocodeContainer.Instance.Components) { if (!service.Value.Value.AttributeValues.ContainsKey("Active") || bool.Parse(service.Value.Value.AttributeValues["Active"][0].Value)) { string result; bool success = service.Value.Value.Geocode(location, out result); // Log the results of the service Model.ServiceLog log = new Model.ServiceLog(); log.Time = DateTime.Now; log.Type = "Location Geocode"; log.Name = service.Value.Metadata.ComponentName; log.Input = inputLocation; log.Result = result; log.Success = success; logService.Add(log, personId); logService.Save(log, personId); // If succesful, set the results and stop processing if (success) { location.GeocodeService = service.Value.Metadata.ComponentName; location.GeocodeResult = result; location.GeocodeDate = DateTime.Now; break; } } } location.GeocodeAttempt = DateTime.Now; }
/// <summary> /// Gets the mapCoordinate from postalcode. /// </summary> /// <param name="postalCode">The postalcode.</param> /// <returns></returns> public MapCoordinate GetMapCoordinateFromPostalCode(string postalCode) { Address.SmartyStreets smartyStreets = new Address.SmartyStreets(); string resultMsg = string.Empty; var coordinate = smartyStreets.GetLocationFromPostalCode(postalCode, out resultMsg); // Log the results of the service if (!string.IsNullOrWhiteSpace(resultMsg)) { var rockContext = new RockContext(); Model.ServiceLogService logService = new Model.ServiceLogService(rockContext); Model.ServiceLog log = new Model.ServiceLog(); log.LogDateTime = RockDateTime.Now; log.Type = "Mapcoordinate from postalcode"; log.Name = smartyStreets.TypeName; log.Input = postalCode; log.Result = resultMsg.Left(200); log.Success = coordinate != null; logService.Add(log); rockContext.SaveChanges(); } return(coordinate); }
/// <summary> /// Performs Address Verification on the provided <see cref="Rock.Model.Location" />. /// </summary> /// <param name="location">A <see cref="Rock.Model.Location" /> to verify.</param> /// <param name="reVerify">if set to <c>true</c> [re verify].</param> public void Verify( Location location, bool reVerify ) { string inputLocation = location.ToString(); // Create new context to save service log without affecting calling method's context var rockContext = new RockContext(); Model.ServiceLogService logService = new Model.ServiceLogService( rockContext ); // Try each of the verification services that were found through MEF foreach ( var service in Rock.Address.VerificationContainer.Instance.Components ) { if ( service.Value.Value.IsActive ) { string result; bool success = service.Value.Value.VerifyLocation( location, reVerify, out result ); if ( !string.IsNullOrWhiteSpace( result ) ) { // Log the results of the service Model.ServiceLog log = new Model.ServiceLog(); log.LogDateTime = RockDateTime.Now; log.Type = "Location Verify"; log.Name = service.Value.Metadata.ComponentName; log.Input = inputLocation; log.Result = result.Left( 200 ); log.Success = success; logService.Add( log ); } } } rockContext.SaveChanges(); }
/// <summary> /// Performs Address Verification on the provided <see cref="Rock.Model.Location" />. /// </summary> /// <param name="location">A <see cref="Rock.Model.Location" /> to verify.</param> /// <param name="reVerify">if set to <c>true</c> [re verify].</param> public bool Verify(Location location, bool reVerify) { bool success = false; // Do not reverify any locked locations if (location == null || (location.IsGeoPointLocked.HasValue && location.IsGeoPointLocked.Value)) { return(false); } string inputLocation = location.ToString(); // Create new context to save service log without affecting calling method's context var rockContext = new RockContext(); Model.ServiceLogService logService = new Model.ServiceLogService(rockContext); bool standardized = location.StandardizeAttemptedDateTime.HasValue && !reVerify; bool geocoded = location.GeocodeAttemptedDateTime.HasValue && !reVerify; bool anyActiveStandardizationService = false; bool anyActiveGeocodingService = false; // Save current values for situation when first service may successfully standardize or geocode, but not both // In this scenario the first service's values should be preserved string street1 = location.Street1; string street2 = location.Street2; string city = location.City; string county = location.County; string state = location.State; string country = location.Country; string postalCode = location.PostalCode; string barcode = location.Barcode; DbGeography geoPoint = location.GeoPoint; // Try each of the verification services that were found through MEF foreach (var service in Rock.Address.VerificationContainer.Instance.Components) { var component = service.Value.Value; if (component != null && component.IsActive && ( (!standardized && component.SupportsStandardization) || (!geocoded && component.SupportsGeocoding))) { string resultMsg = string.Empty; var result = component.Verify(location, out resultMsg); if (!standardized && component.SupportsStandardization) { anyActiveStandardizationService = true; // Log the service and result location.StandardizeAttemptedServiceType = service.Value.Metadata.ComponentName; location.StandardizeAttemptedResult = resultMsg; // As long as there wasn't a connection error, update the attempted datetime if ((result & Address.VerificationResult.ConnectionError) != Address.VerificationResult.ConnectionError) { location.StandardizeAttemptedDateTime = RockDateTime.Now; } // If location was successfully geocoded, update the timestamp if ((result & Address.VerificationResult.Standardized) == Address.VerificationResult.Standardized) { location.StandardizedDateTime = RockDateTime.Now; standardized = true; // Save standardized address in case another service is called for geocoding street1 = location.Street1; street2 = location.Street2; city = location.City; county = location.County; state = location.State; country = location.Country; postalCode = location.PostalCode; barcode = location.Barcode; } } else { // Reset the address back to what it was originally or after previous service successfully standardized it location.Street1 = street1; location.Street2 = street2; location.City = city; location.County = county; location.State = state; location.Country = country; location.PostalCode = postalCode; location.Barcode = barcode; } if (!geocoded && component.SupportsGeocoding) { anyActiveGeocodingService = true; // Log the service and result location.GeocodeAttemptedServiceType = service.Value.Metadata.ComponentName; location.GeocodeAttemptedResult = resultMsg; // As long as there wasn't a connection error, update the attempted datetime if ((result & Address.VerificationResult.ConnectionError) != Address.VerificationResult.ConnectionError) { location.GeocodeAttemptedDateTime = RockDateTime.Now; } // If location was successfully geocoded, update the timestamp if ((result & Address.VerificationResult.Geocoded) == Address.VerificationResult.Geocoded) { location.GeocodedDateTime = RockDateTime.Now; geocoded = true; // Save the lat/long in case another service is called for standardization geoPoint = location.GeoPoint; } } else { // Reset the lat/long back to what it was originally or after previous service successfully geocoded it location.GeoPoint = geoPoint; } // Log the results of the service if (!string.IsNullOrWhiteSpace(resultMsg)) { Model.ServiceLog log = new Model.ServiceLog(); log.LogDateTime = RockDateTime.Now; log.Type = "Location Verify"; log.Name = service.Value.Metadata.ComponentName; log.Input = inputLocation; log.Result = resultMsg.Left(200); log.Success = success; logService.Add(log); } // If location has been successfully standardized and geocoded, break to get out, otherwise next service will be attempted if (standardized && geocoded) { break; } } } // If there is only one type of active service (standardization/geocoding) the other type's attempted datetime // needs to be updated so that the verification job will continue to process additional locations vs just getting // stuck on the first batch and doing them over and over again because the other service type's attempted date is // never updated. if (anyActiveStandardizationService && !anyActiveGeocodingService) { location.GeocodeAttemptedDateTime = RockDateTime.Now; } if (anyActiveGeocodingService && !anyActiveStandardizationService) { location.StandardizeAttemptedDateTime = RockDateTime.Now; } rockContext.SaveChanges(); return(standardized || geocoded); }
/// <summary> /// Performs Address Verification on the provided <see cref="Rock.Model.Location" />. /// </summary> /// <param name="location">A <see cref="Rock.Model.Location" /> to verify.</param> /// <param name="reVerify">if set to <c>true</c> [re verify].</param> public void Verify(Location location, bool reVerify) { string inputLocation = location.GetFullStreetAddress(); var processDate = DateTime.Now; if (string.IsNullOrWhiteSpace(inputLocation)) { // If there is no address to geoode, mark this entry to avoid further processing. location.GeocodeAttemptedDateTime = processDate; location.GeocodeAttemptedServiceType = null; location.GeocodeAttemptedResult = "ignored"; location.StandardizeAttemptedDateTime = processDate; location.StandardizeAttemptedServiceType = null; location.StandardizeAttemptedResult = "ignored"; return; } // Create new context to save service log without affecting calling method's context using (var rockContext = new RockContext()) { Model.ServiceLogService logService = new Model.ServiceLogService(rockContext); // Try each of the active verification services that were found through MEF var activeComponents = Rock.Address.VerificationContainer.Instance.Components.Where(x => x.Value.Value.IsActive).Select(x => x.Value); foreach (var component in activeComponents) { var service = component.Value; string componentName = component.Metadata.ComponentName; string logMessage = null; string resultMessage = null; bool success = false; try { success = service.VerifyLocation(location, reVerify, out resultMessage); } catch (Exception ex) { resultMessage = "Failed. Refer to Service Log for details."; logMessage = ex.Message; } finally { // Update the Location record with the details of this verification attempt. //string serviceName = service.GetType().Name; if (string.IsNullOrWhiteSpace(resultMessage)) { resultMessage = null; } else { resultMessage = resultMessage.ToStringSafe().Left(50); } location.StandardizeAttemptedDateTime = processDate; location.StandardizeAttemptedServiceType = componentName; location.StandardizeAttemptedResult = resultMessage; location.GeocodeAttemptedDateTime = processDate; location.GeocodeAttemptedServiceType = componentName; location.GeocodeAttemptedResult = resultMessage; } if (string.IsNullOrWhiteSpace(logMessage)) { logMessage = resultMessage; } if (!string.IsNullOrWhiteSpace(logMessage)) { // Log the results of the service Model.ServiceLog log = new Model.ServiceLog(); log.LogDateTime = RockDateTime.Now; log.Type = "Location Verify"; log.Name = componentName; log.Input = inputLocation; log.Result = logMessage.Left(200); log.Success = success; logService.Add(log); } if (success) { break; } } rockContext.SaveChanges(); } }
/// <summary> /// Performs Address Verification on the provided <see cref="Rock.Model.Location" />. /// </summary> /// <param name="location">A <see cref="Rock.Model.Location" /> to verify.</param> /// <param name="reVerify">if set to <c>true</c> [re verify].</param> public bool Verify( Location location, bool reVerify ) { bool success = false; // Do not reverify any locked locations if ( location == null || ( location.IsGeoPointLocked.HasValue && location.IsGeoPointLocked.Value ) ) { return false; } string inputLocation = location.ToString(); // Create new context to save service log without affecting calling method's context var rockContext = new RockContext(); Model.ServiceLogService logService = new Model.ServiceLogService( rockContext ); bool standardized = location.StandardizeAttemptedDateTime.HasValue && !reVerify; bool geocoded = location.GeocodeAttemptedDateTime.HasValue && !reVerify; bool anyActiveStandardizationService = false; bool anyActiveGeocodingService = false; // Save current values for situation when first service may successfully standardize or geocode, but not both // In this scenario the first service's values should be preserved string street1 = location.Street1; string street2 = location.Street2; string city = location.City; string county = location.County; string state = location.State; string country = location.Country; string postalCode = location.PostalCode; string barcode = location.Barcode; DbGeography geoPoint = location.GeoPoint; // Try each of the verification services that were found through MEF foreach ( var service in Rock.Address.VerificationContainer.Instance.Components ) { var component = service.Value.Value; if ( component != null && component.IsActive && ( ( !standardized && component.SupportsStandardization ) || ( !geocoded && component.SupportsGeocoding ) ) ) { string resultMsg = string.Empty; var result = component.Verify( location, out resultMsg ); if ( !standardized && component.SupportsStandardization ) { anyActiveStandardizationService = true; // Log the service and result location.StandardizeAttemptedServiceType = service.Value.Metadata.ComponentName; location.StandardizeAttemptedResult = resultMsg; // As long as there wasn't a connection error, update the attempted datetime if ( ( result & Address.VerificationResult.ConnectionError ) != Address.VerificationResult.ConnectionError ) { location.StandardizeAttemptedDateTime = RockDateTime.Now; } // If location was successfully geocoded, update the timestamp if ( ( result & Address.VerificationResult.Standardized ) == Address.VerificationResult.Standardized ) { location.StandardizedDateTime = RockDateTime.Now; standardized = true; // Save standardized address in case another service is called for geocoding street1 = location.Street1; street2 = location.Street2; city = location.City; county = location.County; state = location.State; country = location.Country; postalCode = location.PostalCode; barcode = location.Barcode; } } else { // Reset the address back to what it was originally or after previous service successfully standardized it location.Street1 = street1; location.Street2 = street2; location.City = city; location.County = county; location.State = state; location.Country = country; location.PostalCode = postalCode; location.Barcode = barcode; } if ( !geocoded && component.SupportsGeocoding ) { anyActiveGeocodingService = true; // Log the service and result location.GeocodeAttemptedServiceType = service.Value.Metadata.ComponentName; location.GeocodeAttemptedResult = resultMsg; // As long as there wasn't a connection error, update the attempted datetime if ( ( result & Address.VerificationResult.ConnectionError ) != Address.VerificationResult.ConnectionError ) { location.GeocodeAttemptedDateTime = RockDateTime.Now; } // If location was successfully geocoded, update the timestamp if ( ( result & Address.VerificationResult.Geocoded ) == Address.VerificationResult.Geocoded ) { location.GeocodedDateTime = RockDateTime.Now; geocoded = true; // Save the lat/long in case another service is called for standardization geoPoint = location.GeoPoint; } } else { // Reset the lat/long back to what it was originally or after previous service successfully geocoded it location.GeoPoint = geoPoint; } // Log the results of the service if ( !string.IsNullOrWhiteSpace( resultMsg ) ) { Model.ServiceLog log = new Model.ServiceLog(); log.LogDateTime = RockDateTime.Now; log.Type = "Location Verify"; log.Name = service.Value.Metadata.ComponentName; log.Input = inputLocation; log.Result = resultMsg.Left( 200 ); log.Success = success; logService.Add( log ); } // If location has been succesfully standardized and geocoded, break to get out, otherwise next service will be attempted if ( standardized && geocoded ) { break; } } } // If there is only one type of active service (standardization/geocoding) the other type's attempted datetime // needs to be updated so that the verification job will continue to process additional locations vs just getting // stuck on the first batch and doing them over and over again because the other service type's attempted date is // never updated. if ( anyActiveStandardizationService && !anyActiveGeocodingService ) { location.GeocodeAttemptedDateTime = RockDateTime.Now; } if ( anyActiveGeocodingService && !anyActiveStandardizationService ) { location.StandardizeAttemptedDateTime = RockDateTime.Now; } rockContext.SaveChanges(); return standardized || geocoded; }