protected override void DrawCore(GeoCanvas canvas)
 {
     if (highlightFeature != null)
     {
         highlightFeatureLayer.Clear();
         highlightFeatureLayer.InternalFeatures.Add(highlightFeature);
         highlightFeatureLayer.Draw(canvas, new Collection <SimpleCandidate>());
     }
 }
Beispiel #2
0
        /// <summary>
        /// Clear the previously displayed features from the map, and add new features
        /// </summary>
        private void ClearMapAndAddFeatures(Collection <Feature> validatedFeatures, Collection <Feature> resultFeatures, Collection <Feature> filterFeatures = null)
        {
            // Get the InMemoryFeatureLayers from the MapView
            InMemoryFeatureLayer validatedFeaturesLayer = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Validated Features");
            InMemoryFeatureLayer filterFeaturesLayer    = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Filter Features");
            InMemoryFeatureLayer resultFeaturesLayer    = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Result Features");

            validatedFeaturesLayer.Open();
            filterFeaturesLayer.Open();
            resultFeaturesLayer.Open();

            // Clear the existing features from each layer
            validatedFeaturesLayer.Clear();
            filterFeaturesLayer.Clear();
            resultFeaturesLayer.Clear();

            // Add (blue) filter features to the map, if there are any
            if (filterFeatures != null)
            {
                foreach (Feature filterFeature in filterFeatures)
                {
                    filterFeaturesLayer.InternalFeatures.Add(filterFeature);
                }
            }

            // Add (green) validated features to the map
            foreach (Feature validatedFeature in validatedFeatures)
            {
                validatedFeaturesLayer.InternalFeatures.Add(validatedFeature);
            }

            // Add (red) invalid features to the map
            foreach (Feature resultFeature in resultFeatures)
            {
                resultFeaturesLayer.InternalFeatures.Add(resultFeature);
            }

            // Refresh/redraw the layers and reset the map extent
            LayerOverlay featureOverlay = (LayerOverlay)mapView.Overlays["Features Overlay"];

            mapView.CurrentExtent = RectangleShape.ScaleUp(featureOverlay.GetBoundingBox(), 20).GetBoundingBox();
            mapView.Refresh();

            validatedFeaturesLayer.Close();
            filterFeaturesLayer.Close();
            resultFeaturesLayer.Close();
        }
Beispiel #3
0
        /// <summary>
        /// When a location is selected in the UI, draw the matching feature found and center the map on it
        /// </summary>
        private void lsbSearchResults_SelectionChanged(object sender, EventArgs e)
        {
            ListView selectedResultList = (ListView)sender;

            if (selectedResultList.SelectedItem != null)
            {
                // Get the selected location
                Feature locationFeature = ((CloudReverseGeocodingLocation)selectedResultList.SelectedItem).LocationFeature;

                // Get the 'Result Feature' layer from the MapView
                InMemoryFeatureLayer selectedResultItemFeatureLayer = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Result Feature Geometry");

                // Clear the existing features and add the geometry of the selected location
                selectedResultItemFeatureLayer.Clear();
                selectedResultItemFeatureLayer.InternalFeatures.Add(new Feature(locationFeature.GetShape()));

                // Center the map on the chosen location
                mapView.CurrentExtent = locationFeature.GetBoundingBox();
                mapView.ZoomToScale(mapView.ZoomLevelSet.ZoomLevel18.Scale);
                mapView.Refresh();
            }
        }
Beispiel #4
0
        /// <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();
        }
Beispiel #5
0
        /// <summary>
        /// Get elevation data using the ElevationCloudClient and update the UI
        /// </summary>
        private async Task PerformElevationQuery(BaseShape queryShape)
        {
            // Get feature layers from the MapView
            LayerOverlay         elevationPointsOverlay = (LayerOverlay)mapView.Overlays["Elevation Features Overlay"];
            InMemoryFeatureLayer drawnShapesLayer       = (InMemoryFeatureLayer)elevationPointsOverlay.Layers["Drawn Shape Layer"];
            InMemoryFeatureLayer elevationPointsLayer   = (InMemoryFeatureLayer)elevationPointsOverlay.Layers["Elevation Points Layer"];

            // Clear the existing shapes from the map
            elevationPointsLayer.Open();
            elevationPointsLayer.Clear();
            elevationPointsLayer.Close();
            drawnShapesLayer.Open();
            drawnShapesLayer.Clear();
            drawnShapesLayer.Close();

            // Add the drawn shape to the map
            drawnShapesLayer.InternalFeatures.Add(new Feature(queryShape));

            // Set options from the UI and run the query using the ElevationCloudClient
            Collection <CloudElevationPointResult> elevationPoints = new Collection <CloudElevationPointResult>();
            int projectionInSrid = 3857;

            // Show a loading graphic to let users know the request is running
            loadingIndicator.IsRunning = true;
            loadingLayout.IsVisible    = true;

            // The point interval distance determines how many elevation points are retrieved for line and area queries
            int pointIntervalDistance = (int)intervalDistance.Value;

            switch (queryShape.GetWellKnownType())
            {
            case WellKnownType.Point:
                PointShape drawnPoint = (PointShape)queryShape;
                double     elevation  = await elevationCloudClient.GetElevationOfPointAsync(drawnPoint.X, drawnPoint.Y, projectionInSrid);

                // The API for getting the elevation of a single point returns a double, so we manually create a CloudElevationPointResult to use as a data source for the Elevations list
                elevationPoints.Add(new CloudElevationPointResult(elevation, drawnPoint));

                // Update the UI with the average, highest, and lowest elevations
                txtAverageElevation.Text = $"Average Elevation: {elevation:0.00} feet";
                txtHighestElevation.Text = $"Highest Elevation: {elevation:0.00} feet";
                txtLowestElevation.Text  = $"Lowest Elevation: {elevation:0.00} feet";
                break;

            case WellKnownType.Line:
                LineShape drawnLine = (LineShape)queryShape;
                var       result    = await elevationCloudClient.GetElevationOfLineAsync(drawnLine, projectionInSrid, pointIntervalDistance, DistanceUnit.Meter, DistanceUnit.Feet);

                elevationPoints = result.ElevationPoints;

                // Update the UI with the average, highest, and lowest elevations
                txtAverageElevation.Text = $"Average Elevation: {result.AverageElevation:0.00} feet";
                txtHighestElevation.Text = $"Highest Elevation: {result.HighestElevationPoint.Elevation:0.00} feet";
                txtLowestElevation.Text  = $"Lowest Elevation: {result.LowestElevationPoint.Elevation:0.00} feet";
                break;

            case WellKnownType.Polygon:
                PolygonShape drawnPolygon = (PolygonShape)queryShape;
                result = await elevationCloudClient.GetElevationOfAreaAsync(drawnPolygon, projectionInSrid, pointIntervalDistance, DistanceUnit.Meter, DistanceUnit.Feet);

                elevationPoints = result.ElevationPoints;

                // Update the UI with the average, highest, and lowest elevations
                txtAverageElevation.Text = $"Average Elevation: {result.AverageElevation:0.00} feet";
                txtHighestElevation.Text = $"Highest Elevation: {result.HighestElevationPoint.Elevation:0.00} feet";
                txtLowestElevation.Text  = $"Lowest Elevation: {result.LowestElevationPoint.Elevation:0.00} feet";
                break;

            default:
                break;
            }

            // Add the elevation result points to the map and list box
            foreach (CloudElevationPointResult elevationPoint in elevationPoints)
            {
                elevationPointsLayer.InternalFeatures.Add(new Feature(elevationPoint.Point));
            }
            lsbElevations.ItemsSource = elevationPoints;

            // Hide the loading graphic
            loadingIndicator.IsRunning = false;
            loadingLayout.IsVisible    = false;

            // Set the map extent to the elevation query feature
            drawnShapesLayer.Open();
            mapView.CenterAt(drawnShapesLayer.GetBoundingBox().GetCenterPoint());
            drawnShapesLayer.Close();
            mapView.Refresh();
        }