/// <summary> /// Does batch geocoding. /// </summary> /// <param name="objects">Objects to geocoding.</param> private void _BatchGeocode(IList <AppData.DataObject> objects) { Debug.Assert(null != objects); // created Debug.Assert(0 < objects.Count); // not empty Debug.Assert(null != _checker); // inited try { // create list of addresses Address[] addresses = _CreateAddressList(objects); // start geocode App currentApp = App.Current; AddressCandidate[] candidates = null; if (objects[0] is Order) { // for orders - use local geocoding NameAddress[] namedAddress = _CreateNamedAddressList(objects); var localGeocoder = new LocalGeocoder(currentApp.Geocoder, currentApp.NameAddressStorage); candidates = localGeocoder.BatchGeocode(namedAddress); } else { // for other object - use server geocoder candidates = currentApp.Geocoder.BatchGeocode(addresses); } _checker.ThrowIfCancellationRequested(); // validate geocode _ValidateLocation(addresses, candidates); // If current geocoder is arcgiscomgeocoder - check that we got // candidates from "good" locators. var arcgisgeocoder = App.Current.Geocoder as ArcGiscomGeocoder; if (arcgisgeocoder != null) { for (int i = 0; i < candidates.Count(); i++) { var goodAddressType = arcgisgeocoder.ExactLocatorsTypesNames.Contains(candidates[i].AddressType); if (!goodAddressType) { candidates[i] = new AddressCandidate(); } } } // parse result _ParseBatchGeocodeResult(candidates, objects); } catch (Exception ex) { Logger.Error(ex); // store exception _detectedException = ex; } }
/// <summary> /// Check is location of geocodable object valid and replace it by candidate from local /// geocoder if exists. /// </summary> /// <param name="geocodable">Geocodable object to check.</param> /// <returns>Is geocodable object valid.</returns> private bool _SourceGeocodedObject(IGeocodable geocodable) { Debug.Assert(null != geocodable); // created bool isObjectGeocoded = false; // First check if name address pair exists in local geocoder database. // If exists - overwrite geolocation and address from it. App currentApp = App.Current; var localGeocoder = new LocalGeocoder(currentApp.Geocoder, currentApp.NameAddressStorage); var nameAddress = new NameAddress(); nameAddress.Name = geocodable.ToString(); nameAddress.Address = geocodable.Address.Clone() as Address; AddressCandidate localCandidate = localGeocoder.Geocode(nameAddress); if (localCandidate == null) { // Update from internal object information. AppGeometry.Envelope extent = currentApp.Map.ImportCheckExtent; if (extent.IsPointIn(geocodable.GeoLocation.Value)) { geocodable.Address.MatchMethod = currentApp.FindString("ImportSourceMatchMethod"); isObjectGeocoded = true; // Full address property must be combined from other fields, because // it is not importing field. if (App.Current.Geocoder.AddressFormat == AddressFormat.MultipleFields) { GeocodeHelpers.SetFullAddress(geocodable.Address); } else { // Do nothing: do not update full address since // it is used for geocoding in Single Address Field Format. } } // Else could not locate object using X/Y attributes - need geocode. } else { // Init from local candidate. // Set location. geocodable.GeoLocation = new AppGeometry.Point(localCandidate.GeoLocation.X, localCandidate.GeoLocation.Y); // Set address. localCandidate.Address.CopyTo(geocodable.Address); isObjectGeocoded = true; } return(isObjectGeocoded); }