是否有更简单、更优雅的方法来选择多边形并使用 ThinkGeo 的 MapView 控件突出显示它?
到目前为止我已经实施了这种方法。单击鼠标时,我将预定义图层添加到 ThinkGeo MapView Overlay,该图层是包含所有多边形的“基础”图层的副本,但只有鼠标单击坐标上的一个多边形。
...
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using ThinkGeo.Core;
using ThinkGeo.UI.WinForms;
...
...
private async void frmFullScreenMaps_Load(object sender, EventArgs e)
{
this.control.SuspendLayout();
mapView = new ThinkGeo.UI.WinForms.MapView();
form.Controls.Add(this.mapView); // Add the control to the form
mapView.Location = new System.Drawing.Point(0, 0);
mapView.MapResizeMode = ThinkGeo.Core.MapResizeMode.PreserveScaleAndCenter;
mapView.MaximumScale = 1000000D;
mapView.MinimumScale = 100D;
mapView.RotatedAngle = 0F;
mapView.Size = new System.Drawing.Size(100, 100);
mapView.Dock = DockStyle.Fill;
mapView.MapUnit = GeographyUnit.Feet;
await mapView.RefreshAsync();
this.control.ResumeLayout(false);
this.control.PerformLayout();
...
...
// In memory layer - all polygons
inMemoryFeatureLayer = new InMemoryFeatureLayer();
...
...
// In memory layer - for the (one) selected polygon
inMemoryHighlighLayer = new InMemoryFeatureLayer();
//Styling the inMemoryHighlighLayer
inMemoryHighlighLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoPen(GeoColors.Yellow, 4), new GeoSolidBrush(GeoColors.Transparent));
inMemoryHighlighLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
inMemoryHighlighLayer.Open();
...
...
// Attach mapView Click event handler
maps.mapView.MapClick += MapView_MapClick;
await maps.mapView.RefreshAsync();
}
private async void MapView_MapClick(object sender, MapClickMapViewEventArgs e)
{
this.tabControlMain.SelectedTab = tabPageMap;
PointShape clickedPoint = e.WorldLocation;
// This assume the layer is already open, so we can query it
var clickedFeatures = inMemoryFeatureLayer.QueryTools.GetFeaturesContaining(clickedPoint, ReturningColumnsType.NoColumns);
if (clickedFeatures.Count > 0)
{
// Get the clicked feature
var clickedFeature = clickedFeatures[0];
// Add the clicked feature to the highlight layer
inMemoryHighlighLayer.InternalFeatures.Clear();
inMemoryHighlighLayer.InternalFeatures.Add(clickedFeature);
// Convert world coordinates to screen coordinates
var screenPoint = mapView.ToScreenCoordinate(clickedPoint);
await mapView.RefreshAsync(mapView.CurrentExtent, inMemHighlightOverlay); //zooms to parcel
}
else
{
// Clear the highlight layer if no feature was clicked
inMemoryHighlighLayer.InternalFeatures.Clear();
await mapView.RefreshAsync();
}
}
您的解决方案是正确的,并且可能是“最佳”实现。 我知道为一种形状创建单独的 InMemoryFeatureLayer 有点冗长,但额外层的性能开销非常小,并且拥有完整层会更灵活,并且与 api 更一致。
还有一种使用 MapShape 类的替代实现,如果您需要在每个绘制的形状上使用不同的样式,它也可以工作,但在您的实例中,InMemoryFeatureLayer 可能更好。
请参阅下面的 MapShape 实现,以防万一您想尝试该路线:
// First Initialize the MapShapesLayer as following:
var inMemHighlightOverlay = new LayerOverlay();
wpfMap.Overlays.Add(inMemHighlightOverlay);
var mapshapeLayer = new MapShapeLayer();
inMemHighlightOverlay.Layers.Add(mapshapeLayer);
// Then use the following code to add the feature to highlight
var mapShape = new MapShape(clickedFeature);
mapShape.ZoomLevels.ZoomLevel01.DefaultAreaStyle =
AreaStyle.CreateSimpleAreaStyle(GeoColors.Red);
mapShape.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
mapshapeLayer.MapShapes.Clear();
mapshapeLayer.MapShapes.Add("shape1", mapShape);
await inMemHighlightOverlay.RefreshAsync();