/// <summary> /// Perform the reverse geocode using the ReverseGeocodingCloudClient and update the UI /// </summary> private async void PerformReverseGeocode() { // Perform some simple validation on the input text boxes if (await ValidateSearchParameters()) { CloudReverseGeocodingOptions options = new CloudReverseGeocodingOptions(); // Set up the CloudReverseGeocodingOptions object based on the parameters set in the UI string[] coordinates = txtCoordinates.Text.Split(','); double lat = double.Parse(coordinates[0].Trim()); double lon = double.Parse(coordinates[1].Trim()); int searchRadius = int.Parse(txtSearchRadius.Text); DistanceUnit searchRadiusDistanceUnit = DistanceUnit.Meter; int pointProjectionInSrid = 3857; PointShape searchPoint = new PointShape(lon, lat); options.MaxResults = int.Parse(txtMaxResults.Text); switch ((string)cboLocationCategories.SelectedItem) { case "All": options.LocationCategories = CloudLocationCategories.All; break; case "Common": options.LocationCategories = CloudLocationCategories.Common; break; case "None": options.LocationCategories = CloudLocationCategories.None; break; default: options.LocationCategories = CloudLocationCategories.All; break; } // Show a loading graphic to let users know the request is running loadingIndicator.IsRunning = true; loadingLayout.IsVisible = true; // Run the reverse geocode CloudReverseGeocodingResult searchResult = await reverseGeocodingCloudClient.SearchPointAsync(lon, lat, pointProjectionInSrid, searchRadius, searchRadiusDistanceUnit, options); // Hide the loading graphic loadingIndicator.IsRunning = false; loadingLayout.IsVisible = false; // Handle an exception returned from the service if (searchResult.Exception != null) { await DisplayAlert("Alert", searchResult.Exception.Message, "Error"); return; } // Update the UI DisplaySearchResults(searchPoint, searchRadius, searchResult); } }
/// <summary> /// Update the UI based on the search results from the reverse geocode /// </summary> private void DisplaySearchResults(PointShape searchPoint, int searchRadius, CloudReverseGeocodingResult searchResult) { // Get the 'Search Radius' layer from the MapView InMemoryFeatureLayer searchRadiusFeatureLayer = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Search Radius"); // Clear the existing features and add new features showing the area that was searched by the reverse geocode searchRadiusFeatureLayer.Clear(); searchRadiusFeatureLayer.InternalFeatures.Add(new Feature(new EllipseShape(searchPoint, searchRadius))); searchRadiusFeatureLayer.InternalFeatures.Add(new Feature(searchPoint)); // Get the 'Result Feature' layer and clear it InMemoryFeatureLayer selectedResultItemFeatureLayer = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Result Feature Geometry"); selectedResultItemFeatureLayer.Clear(); // If a match was found for the geocode, update the UI if (searchResult?.BestMatchLocation != null) { // Get the 'Best Match' PopupOverlay from the MapView and clear it PopupOverlay bestMatchPopupOverlay = (PopupOverlay)mapView.Overlays["Best Match Popup Overlay"]; bestMatchPopupOverlay.Popups.Clear(); // Get the location of the 'Best Match' found within the search radius PointShape bestMatchLocation = searchResult.BestMatchLocation.LocationFeature.GetShape().GetClosestPointTo(searchPoint, GeographyUnit.Meter); if (bestMatchLocation == null) { bestMatchLocation = searchResult.BestMatchLocation.LocationFeature.GetShape().GetCenterPoint(); } // Create a popup to display the best match, and add it to the PopupOverlay Popup bestMatchPopup = new Popup(); bestMatchPopup.Content = "Best Match: " + searchResult.BestMatchLocation.LocationName; bestMatchPopup.Position = bestMatchLocation; bestMatchPopupOverlay.Popups.Add(bestMatchPopup); // Sort the locations found into three groups (Addresses, Places, Roads) based on their LocationCategory Collection <CloudReverseGeocodingLocation> nearbyLocations = new Collection <CloudReverseGeocodingLocation>(searchResult.NearbyLocations); Collection <CloudReverseGeocodingLocation> nearbyAddresses = new Collection <CloudReverseGeocodingLocation>(); Collection <CloudReverseGeocodingLocation> nearbyPlaces = new Collection <CloudReverseGeocodingLocation>(); Collection <CloudReverseGeocodingLocation> nearbyRoads = new Collection <CloudReverseGeocodingLocation>(); foreach (CloudReverseGeocodingLocation foundLocation in nearbyLocations) { if (foundLocation.LocationCategory.ToLower().Contains("addresspoint")) { nearbyAddresses.Add(foundLocation); } else if (nameof(CloudLocationCategories.Aeroway).Equals(foundLocation.LocationCategory) || nameof(CloudLocationCategories.Road).Equals(foundLocation.LocationCategory) || nameof(CloudLocationCategories.Rail).Equals(foundLocation.LocationCategory) || nameof(CloudLocationCategories.Waterway).Equals(foundLocation.LocationCategory)) { nearbyRoads.Add(foundLocation); } else if (!nameof(CloudLocationCategories.Intersection).Equals(foundLocation.LocationCategory)) { nearbyPlaces.Add(foundLocation); } } // Set the data sources for the addresses, roads, and places list boxes lsbAddresses.ItemsSource = nearbyAddresses; lsbRoads.ItemsSource = nearbyRoads; lsbPlaces.ItemsSource = nearbyPlaces; lsbPlaces.IsVisible = true; txtSearchResultsBestMatch.Text = "Best Match: " + searchResult.BestMatchLocation.Address; } else { txtSearchResultsBestMatch.Text = "No address or place matches found for this location"; } // Set the map extent to show the results of the search mapView.CurrentExtent = RectangleShape.ScaleUp(searchRadiusFeatureLayer.GetBoundingBox(), 20).GetBoundingBox(); mapView.Refresh(); }