使用 ThinkGeo,我需要在 Windows 窗体 C# 中单击鼠标选择多边形并对其进行样式设置 - 突出显示边框 -

问题描述 投票:0回答:1

是否有更简单、更优雅的方法来选择多边形并使用 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();
    }

}
    
geospatial windowsformsintegration
1个回答
0
投票

您的解决方案是正确的,并且可能是“最佳”实现。 我知道为一种形状创建单独的 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();
© www.soinside.com 2019 - 2024. All rights reserved.