Пример #1
0
        private void SetupMapWithBlankPage()
        {
            // Setup the map unit, you want to always use feet or meters for printer layout maps
            Map1.MapUnit = GeographyUnit.Meter;

            // Here we create the default zoom levels for the sample.  We have pre-created a PrinterZoomLevelSet
            // That pre-defines commonly used zoom levels based on percentages of zoom
            Map1.ZoomLevelSet = new PrinterZoomLevelSet(Map1.MapUnit, PrinterHelper.GetPointsPerGeographyUnit(Map1.MapUnit));

            // Here we set the background color to gray so there is contrast with the while page
            //Map1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColors.LightGray);

            // Create the PrinterInteractiveOverlay to contain all of the PrinterLayers.
            // The interactive overlay allows the layers to be interacted with
            PrinterInteractiveOverlay printerOverlay = new PrinterInteractiveOverlay();

            Map1.InteractiveOverlays.Add("PrintPreviewOverlay", printerOverlay);
            Map1.InteractiveOverlays.MoveToBottom("PrintPreviewOverlay");

            // Create the PagePrinterLayer which shows the page boundary and is the area the user will
            // arrange all of the other layer on top of.
            PagePrinterLayer pagePrinterLayer = new PagePrinterLayer(PrinterPageSize.AnsiA, PrinterOrientation.Portrait);

            pagePrinterLayer.Open();
            printerOverlay.PrinterLayers.Add("PageLayer", pagePrinterLayer);

            // Get the pages extent, slightly scale it up, and then set that as the default current extent
            Map1.CurrentExtent = RectangleShape.ScaleUp(pagePrinterLayer.GetPosition(), 10).GetBoundingBox();

            // Set the minimum sscale of the map to the last zoom level
            Map1.MinimumScale = Map1.ZoomLevelSet.ZoomLevel20.Scale;
        }
Пример #2
0
        /// <summary>
        /// Draw the result of an optimized routing request on the map
        /// </summary>
        private void DrawOptimizedRoute(CloudRoutingOptimizationResult optimizedRoutingResult)
        {
            // Get the routing feature layer from the MapView
            InMemoryFeatureLayer routingLayer = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Routing Layer");

            // Clear the previous features from the routing layer
            routingLayer.InternalFeatures.Clear();

            // Create a collection to hold the route segments. These include information like distance, duration, warnings, and instructions for turn-by-turn routing
            List <CloudRoutingSegment> routeSegments = new List <CloudRoutingSegment>();

            //// CloudRoutingOptimizationResult.TspResult.VisitSequences is an ordered array of integers
            //// Each integer corresponds to the index of the corresponding waypoint in the original set of waypoints passed into the query
            //// For example, if the second element in 'VisitSequences' is '3', the second stop on the route is originalWaypointArray[3]

            int index = 0;

            // Add the route visit points and route segments to the map
            foreach (int waypointIndex in optimizedRoutingResult.TspResult.VisitSequences)
            {
                Dictionary <string, string> columnValues = new Dictionary <string, string>();

                // Get the order of the stops and label the point
                // '0' represents the start/end point of the route for a round trip route, so we change the label to indicate that for readability
                columnValues.Add("SequenceNumber", (index == 0 || index == optimizedRoutingResult.TspResult.VisitSequences.Count - 1 ? "Start/End Point" : "Stop " + index));
                PointShape waypoint = routingWaypoints[waypointIndex];

                // Add the point to the map
                routingLayer.InternalFeatures.Add(new Feature(waypoint, columnValues));

                // Increment the index for labeling purposes
                index++;
            }
            foreach (CloudRoutingRoute route in optimizedRoutingResult.TspResult.Routes)
            {
                routingLayer.InternalFeatures.Add(new Feature(route.Shape));
                routeSegments.AddRange(route.Segments);
            }

            //// Set the data source for the list box to the route segments
            lsbRouteSegments.ItemsSource = routeSegments;

            //// Set the map extent to the newly displayed route
            routingLayer.Open();
            mapView.CurrentExtent = RectangleShape.ScaleUp(routingLayer.GetBoundingBox(), 20).GetBoundingBox();
            routingLayer.Close();
            mapView.Refresh();
        }
Пример #3
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();
        }
Пример #4
0
        private static TileLayer ProcessTile(FeatureLayer featureLayer, int tileX, int tileY, int zoom, IEnumerable <string> columnNames, int simplificationFactor, int tileSize)
        {
            RectangleShape tileBoundingBox    = GetTileSphericalMercatorBoundingBox(tileX, tileY, zoom, tileSize);
            RectangleShape scaledUpBoudingBox = new RectangleShape(tileBoundingBox.GetWellKnownBinary());

            scaledUpBoudingBox.ScaleUp(5);
            featureLayer.Open();

            Collection <string> allFeatureIds         = featureLayer.FeatureSource.GetFeatureIdsInsideBoundingBox(scaledUpBoudingBox);
            RectangleInt        tileScreenBoundingBox = new RectangleInt()
            {
                XMin = -20,
                YMin = -20,
                XMax = tileSize + 20,
                YMax = tileSize + 20
            };


            TileLayer tileLayer = new TileLayer();

            tileLayer.Extent  = (uint)tileSize;
            tileLayer.Version = 2;
            tileLayer.Name    = featureLayer.Name;

            int IdsCountToExecute = allFeatureIds.Count;
            int startIndex        = 0;

            while (IdsCountToExecute > 0)
            {
                List <string> featureIds = GetSubString(allFeatureIds, startIndex, Math.Min(1000, IdsCountToExecute));
                IdsCountToExecute = IdsCountToExecute - featureIds.Count;
                startIndex        = startIndex + featureIds.Count;
                Collection <Feature> features = GetFeaturesByIds(featureLayer, featureIds, columnNames);

                foreach (Feature feature in features)
                {
                    TileFeature tileFeature = GetVectorTileFeature(feature, zoom, tileSize, tileScreenBoundingBox, simplificationFactor, tileBoundingBox);
                    if (tileFeature.Geometry.Count > 0)
                    {
                        tileLayer.Features.Add(tileFeature);
                    }
                }
            }
            tileLayer.FillInTheInternalProperties();
            return(tileLayer);
        }
Пример #5
0
        /// <summary>
        /// Draw the result of a Cloud Routing request on the map
        /// </summary>
        private void DrawRoute(CloudRoutingGetRouteResult routingResult)
        {
            // Get the routing feature layer from the MapView
            InMemoryFeatureLayer routingLayer = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Routing Layer");

            // Clear the previous features from the routing layer
            routingLayer.InternalFeatures.Clear();

            // Create a collection to hold the route segments. These include information like distance, duration, warnings, and instructions for turn-by-turn routing
            List <CloudRoutingSegment> routeSegments = new List <CloudRoutingSegment>();

            int index = 0;

            // Add the route waypoints and route segments to the map
            foreach (CloudRoutingWaypoint waypoint in routingResult.RouteResult.Waypoints)
            {
                Dictionary <string, string> columnValues = new Dictionary <string, string>();

                // Get the order of the stops and label the point
                // '0' represents the start/end point of the route for a round trip route, so we change the label to indicate that for readability
                columnValues.Add("SequenceNumber", (index == 0 ? "Start Point" : "Stop " + index));
                PointShape routeWaypoint = new PointShape(waypoint.Coordinate);

                // Add the point to the map
                routingLayer.InternalFeatures.Add(new Feature(routeWaypoint, columnValues));

                // Increment the index for labeling purposes
                index++;
            }
            foreach (CloudRoutingRoute route in routingResult.RouteResult.Routes)
            {
                routingLayer.InternalFeatures.Add(new Feature(route.Shape));
                routeSegments.AddRange(route.Segments);
            }

            // Set the data source for the list box to the route segments
            lsbRouteSegments.ItemsSource = routeSegments;

            // Set the map extent to the newly displayed route
            routingLayer.Open();
            mapView.CurrentExtent = RectangleShape.ScaleUp(routingLayer.GetBoundingBox(), 20).GetBoundingBox();

            routingLayer.Close();
            mapView.Refresh();
        }
Пример #6
0
        private void GenerateGrid(string filename)
        {
            //Point based shapefile used to create the GRID (sample points of pH level of a field)
            ShapeFileFeatureLayer pointLayer = new ShapeFileFeatureLayer(@"..\..\data\sample_ph_2.shp");

            //Sets the extent of the grid based on the extent of the sample points shapefile and slightly larger.
            pointLayer.Open();
            RectangleShape gridExtent = pointLayer.GetBoundingBox();

            gridExtent.ScaleUp(5);

            //Gets the data (points with their pH value) to build the GRID.
            Collection <Feature>            features   = pointLayer.FeatureSource.GetAllFeatures(new string[] { "PH" });
            Dictionary <PointShape, double> dataPoints = new Dictionary <PointShape, double>();

            pointLayer.Close();

            foreach (Feature feature in features)
            {
                PointShape pointShape = (PointShape)feature.GetShape();
                double     value      = double.Parse(feature.ColumnValues["PH"]);
                dataPoints.Add(pointShape, value);
            }

            //Cell size based on the width of the extent divided by 100.
            double cellSize = gridExtent.Width / 100;
            //Sets the definition of the GRID with its extent, the cell size, the non value, and the data (point locations with their value)
            //For more information on GRID definition see http://en.wikipedia.org/wiki/ASCII_GRID
            GridDefinition definition = new GridDefinition(gridExtent, cellSize, -9999, dataPoints);

            //Inverse Distance Weighted (IDW) is the interpolation model used for the GRID for assigning values to unknown points
            //based on known neighbor points.
            //http://en.wikipedia.org/wiki/Inverse_distance_weighting
            GridInterpolationModel interpolationModel = new InverseDistanceWeightedGridInterpolationModel();

            FileStream outputStream = new FileStream(filename, FileMode.Create);

            GridFeatureSource.GenerateGrid(definition, interpolationModel, outputStream);
        }
Пример #7
0
        protected override void DrawCore(GeoCanvas canvas, Collection <SimpleCandidate> labelsInAllLayers)
        {
            GeoImage       miniImage         = new GeoImage(width, height);
            RectangleShape scaledWorldExtent = MapEngine.GetDrawingExtent(canvas.CurrentWorldExtent, width, height);

            scaledWorldExtent.ScaleUp(300);
            GdiPlusGeoCanvas minCanvas = new GdiPlusGeoCanvas();

            minCanvas.BeginDrawing(miniImage, scaledWorldExtent, canvas.MapUnit);
            foreach (Layer layer in layers)
            {
                layer.Draw(minCanvas, labelsInAllLayers);
            }

            minCanvas.DrawArea(RectangleShape.ScaleDown(minCanvas.CurrentWorldExtent, 1), new GeoPen(GeoColor.StandardColors.Gray, 2), DrawingLevel.LevelOne);
            minCanvas.DrawArea(canvas.CurrentWorldExtent, new GeoPen(GeoColor.StandardColors.Black, 2), DrawingLevel.LevelOne);

            minCanvas.EndDrawing();

            ScreenPointF drawingLocation = GetDrawingLocation(canvas, width, height);

            canvas.DrawScreenImageWithoutScaling(miniImage, (drawingLocation.X + width / 2) + 10, (drawingLocation.Y + height / 2) - 10, DrawingLevel.LevelOne, 0, 0, 0);
        }
Пример #8
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();
        }
Пример #9
0
        /// <summary>
        /// Set up the map with the ThinkGeo Cloud Maps overlay and a feature layer containing Frisco zoning data
        /// </summary>
        protected override void OnAppearing()
        {
            base.OnAppearing();
            // Create the background world maps using vector tiles requested from the ThinkGeo Cloud Service.
            ThinkGeoCloudVectorMapsOverlay thinkGeoCloudVectorMapsOverlay = new ThinkGeoCloudVectorMapsOverlay("9ap16imkD_V7fsvDW9I8r8ULxgAB50BX_BnafMEBcKg~", "vtVao9zAcOj00UlGcK7U-efLANfeJKzlPuDB9nw7Bp4K4UxU_PdRDg~~", ThinkGeoCloudVectorMapsMapType.Light);

            thinkGeoCloudVectorMapsOverlay.VectorTileCache = new FileVectorTileCache(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "cache"), "CloudMapsVector");

            mapView.Overlays.Add(thinkGeoCloudVectorMapsOverlay);

            // Set the Map Unit to meters (used in Spherical Mercator)
            mapView.MapUnit = GeographyUnit.Meter;


            // Create a feature layer to hold the Frisco zoning data
            ShapeFileFeatureLayer zoningLayer = new ShapeFileFeatureLayer(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Shapefile/Zoning.shp"));

            // Convert the Frisco shapefile from its native projection to Spherical Mercator, to match the map
            ProjectionConverter projectionConverter = new ProjectionConverter(2276, 3857);

            zoningLayer.FeatureSource.ProjectionConverter = projectionConverter;

            // Add a style to use to draw the Frisco zoning polygons
            zoningLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            zoningLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle    = AreaStyle.CreateSimpleAreaStyle(GeoColor.FromArgb(50, GeoColors.MediumPurple), GeoColors.MediumPurple, 2);

            // Create a layer to hold the feature we will perform the spatial query against
            InMemoryFeatureLayer queryFeatureLayer = new InMemoryFeatureLayer();

            queryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle    = AreaStyle.CreateSimpleAreaStyle(GeoColor.FromArgb(75, GeoColors.LightRed), GeoColors.LightRed);
            queryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            // Create a layer to hold features found by the spatial query
            InMemoryFeatureLayer highlightedFeaturesLayer = new InMemoryFeatureLayer();

            highlightedFeaturesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle    = AreaStyle.CreateSimpleAreaStyle(GeoColor.FromArgb(90, GeoColors.MidnightBlue), GeoColors.MidnightBlue);
            highlightedFeaturesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            // Add each feature layer to it's own overlay
            // We do this so we can control and refresh/redraw each layer individually
            LayerOverlay layerOverlay = new LayerOverlay();

            layerOverlay.Layers.Add("Frisco Zoning", zoningLayer);
            layerOverlay.Layers.Add("Query Feature", queryFeatureLayer);
            layerOverlay.Layers.Add("Highlighted Features", highlightedFeaturesLayer);

            mapView.Overlays.Add("Layer Overlay", layerOverlay);

            // Add an event to handle new shapes that are drawn on the map
            mapView.TrackOverlay.TrackEnded += OnPolygonDrawn;

            // Add a sample shape to the map for the initial query
            PolygonShape sampleShape = new PolygonShape("POLYGON((-10779148.1848451 3916088.62700432,-10779960.3282662 3913862.39842209,-10777189.4860062 3911913.25450323,-10777179.9313777 3915754.21500743,-10779148.1848451 3916088.62700432))");

            GetFeaturesWithin(sampleShape);

            // Set the map extent to the sample shapes
            mapView.CurrentExtent = RectangleShape.ScaleUp(sampleShape.GetBoundingBox(), 20).GetBoundingBox();

            mapView.Refresh();
        }
Пример #10
0
        /// <summary>
        /// Set up the map with the ThinkGeo Cloud Maps overlay and a feature layer containing Frisco zoning data
        /// </summary>
        protected override void OnAppearing()
        {
            base.OnAppearing();
            // Create the background world maps using vector tiles requested from the ThinkGeo Cloud Service.
            ThinkGeoCloudVectorMapsOverlay thinkGeoCloudVectorMapsOverlay = new ThinkGeoCloudVectorMapsOverlay("9ap16imkD_V7fsvDW9I8r8ULxgAB50BX_BnafMEBcKg~", "vtVao9zAcOj00UlGcK7U-efLANfeJKzlPuDB9nw7Bp4K4UxU_PdRDg~~", ThinkGeoCloudVectorMapsMapType.Light);

            thinkGeoCloudVectorMapsOverlay.VectorTileCache = new FileVectorTileCache(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "cache"), "CloudMapsVector");

            mapView.Overlays.Add(thinkGeoCloudVectorMapsOverlay);

            // Set the Map Unit to meters (used in Spherical Mercator)
            mapView.MapUnit = GeographyUnit.Meter;

            // Create a feature layer to hold the Frisco zoning data
            ShapeFileFeatureLayer zoningLayer = new ShapeFileFeatureLayer(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Shapefile/Zoning.shp"));

            // Convert the Frisco shapefile from its native projection to Spherical Mercator, to match the map
            ProjectionConverter projectionConverter = new ProjectionConverter(2276, 3857);

            zoningLayer.FeatureSource.ProjectionConverter = projectionConverter;

            // Add a style to use to draw the Frisco zoning polygons
            zoningLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            zoningLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle    = AreaStyle.CreateSimpleAreaStyle(GeoColor.FromArgb(50, GeoColors.MediumPurple), GeoColors.MediumPurple, 2);

            // Set the map extent to Frisco, TX
            // mapView.CurrentExtent = new RectangleShape(-10781137.28, 3917162.59, -10774579.34, 3911241.35);

            // Create a layer to hold the feature we will perform the spatial query against
            InMemoryFeatureLayer queryFeatureLayer = new InMemoryFeatureLayer();

            queryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle    = AreaStyle.CreateSimpleAreaStyle(GeoColor.FromArgb(75, GeoColors.LightRed), GeoColors.LightRed);
            queryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            // Create a layer to hold features found by the spatial query
            InMemoryFeatureLayer highlightedFeaturesLayer = new InMemoryFeatureLayer();

            highlightedFeaturesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle    = AreaStyle.CreateSimpleAreaStyle(GeoColor.FromArgb(90, GeoColors.MidnightBlue), GeoColors.MidnightBlue);
            highlightedFeaturesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            // Add each feature layer to it's own overlay
            // We do this so we can control and refresh/redraw each layer individually
            LayerOverlay layerOverlay = new LayerOverlay();

            layerOverlay.Layers.Add("Frisco Zoning", zoningLayer);
            layerOverlay.Layers.Add("Query Feature", queryFeatureLayer);
            layerOverlay.Layers.Add("Highlighted Features", highlightedFeaturesLayer);

            mapView.Overlays.Add("Layer Overlay", layerOverlay);

            // Add an event to handle new shapes that are drawn on the map
            mapView.TrackOverlay.TrackEnded += OnPolygonDrawn;

            // Add a sample shape to the map for the initial query
            PolygonShape sampleShape = new PolygonShape("POLYGON((-10779549.4792414 3915352.92061116,-10777495.2341177 3915859.31592073,-10776214.913901 3914827.41589883,-10776081.1491022 3913384.66699796,-10777906.0831424 3912553.41431997,-10779702.3532971 3914110.81876263,-10779549.4792414 3915352.92061116))");

            GetFeaturesOverlaps(sampleShape);

            // Set the map extent to the sample shapes
            mapView.CurrentExtent = RectangleShape.ScaleUp(sampleShape.GetBoundingBox(), 20).GetBoundingBox();

            mapView.Refresh();
        }
        private void InitGridDefinition()
        {
            var entity = content.DataContext as GridWizardShareObject;

            RectangleShape gridExtent = new RectangleShape();
            List <Feature> features   = new List <Feature>();

            entity.SelectedFeatureLayer.SafeProcess(() =>
            {
                if (entity.HasSelectedFeatures && entity.OnlyUseSelectedFeatures)
                {
                    features   = GisEditor.SelectionManager.GetSelectedFeatures().Where(f => f.Tag != null && f.Tag == entity.SelectedFeatureLayer).ToList();
                    gridExtent = ExtentHelper.GetBoundingBoxOfItems(features);
                    gridExtent.ScaleUp(0.05);
                }
                else
                {
                    features   = entity.SelectedFeatureLayer.FeatureSource.GetAllFeatures(entity.SelectedFeatureLayer.FeatureSource.GetDistinctColumnNames()).ToList();
                    gridExtent = ExtentHelper.GetBoundingBoxOfItems(features);
                }
            });

            Dictionary <PointShape, double> dataPoints = new Dictionary <PointShape, double>();

            foreach (var item in features)
            {
                double columnValue = double.NaN;
                if (double.TryParse(item.ColumnValues[entity.SelectedDataColumn.ColumnName], out columnValue))
                {
                    var shape = item.GetShape();
                    if (shape.GetType().Equals(typeof(MultipointShape)))
                    {
                        foreach (var point in ((MultipointShape)shape).Points)
                        {
                            point.Tag = null;
                            dataPoints.Add(point, columnValue);
                        }
                    }
                    else
                    {
                        PointShape pointShape = (PointShape)shape;
                        pointShape.Tag = null;
                        dataPoints.Add(pointShape, columnValue);
                    }
                }
            }

            double tmpCellSize = 0.0;

            switch (GisEditor.ActiveMap.MapUnit)
            {
            case GeographyUnit.DecimalDegree:
                tmpCellSize = DecimalDegreesHelper.GetLongitudeDifferenceFromDistance(entity.CellSize, entity.SelectedCellSizeDistanceUnit, gridExtent.GetCenterPoint().Y);
                break;

            case GeographyUnit.Feet:
                tmpCellSize = Conversion.ConvertMeasureUnits(entity.CellSize, entity.SelectedCellSizeDistanceUnit, DistanceUnit.Feet);
                break;

            case GeographyUnit.Meter:
                tmpCellSize = Conversion.ConvertMeasureUnits(entity.CellSize, entity.SelectedCellSizeDistanceUnit, DistanceUnit.Meter);
                break;

            default:
                break;
            }

            entity.GridDefinition = new GridDefinition(gridExtent, tmpCellSize, -9999, dataPoints);
        }