代码之家  ›  专栏  ›  技术社区  ›  j_kaden

如何在C#Mapsui中使用两个EditingWidgets。同时进行WPF?

  •  0
  • j_kaden  · 技术社区  · 2 年前

    我目前正在尝试使用Wpf的C#Mapsui库在地图上绘制多边形和直线。目标是,当我单击“DrawPolygon”按钮时,我可以绘制多边形,而当单击“DrawLines”按钮时也可以绘制线。当一个绘图模式处于活动状态并且单击另一个按钮时,应禁用第一个按钮。为了实现这一点,“绘制”按钮是单选按钮,并且相应的小工具始终具有与按钮的IsChecked属性相同的启用状态。

    所以我可以让它工作,但我确实遇到了一些更棘手的问题。我提出了两种不同的方法,每种方法都有缺点。

    1. 在加载XAML时调用的启动函数中初始化EditManager和Widget时。

    当它们在启动时创建时,我想禁用它们,这样如果我不想的话,我就不会意外地在地图上绘制 似乎永久残疾。因为在ButtonClick()上,它们再次启用,但我什么都画不出来。这很烦人,我不想使用我的另一个选项(见下文),即如果小部件已经存在,我会对每个按钮点击()调用test。这似乎是不必要的,并导致另一个问题(见下文)

      public void LoadModelData(object sender, RoutedEventArgs e)
      {
          DataContext = ViewModel;
    
          // mapsui load new MapControl to XAML-Tag and add OpenStreetMap
          // then add it to Content of ContentControl-Tag
          mapControl = new Mapsui.UI.Wpf.MapControl();
          mapControl.Map?.Layers.Add(Mapsui.Tiling.OpenStreetMap.CreateTileLayer());
          MapContainer.Content = mapControl;
          mapControl.Map.Widgets.Add(new MapInfoWidget(mapControl.Map)); // should always be first widget
          mapControl.Map.Layers.Add(ViewModel.PolygonLayer, ViewModel.LineLayer);
    
          mapControl.Info += MapControlOnInfo;
          mapControl.MouseMove += MapControlOnMouseMove;
    
          
          ViewModel.LineEditManager = new EditManager
          {
              Layer = (WritableLayer)mapControl.Map.Layers.First(l => l.Name == "Line"),
              EditMode = EditMode.AddLine,
          };
          IWidget widget = new EditingWidget(mapControl, ViewModel.LineEditManager, new EditManipulation());
          mapControl.Map.Widgets.Add(widget);
          ViewModel.LineWidgetIndex = mapControl.Map.Widgets.ToList().IndexOf(widget);
    // Especially here seems to be the problem
          mapControl.Map.Widgets.ElementAt(ViewModel.LineWidgetIndex).Enabled = false;
    
          ViewModel.BBoxEditManager = new EditManager
          {
              Layer = (WritableLayer)mapControl.Map.Layers.First(l => l.Name == "Polygon"),
              EditMode = EditMode.AddPolygon,
          };
          widget = new EditingWidget(mapControl, ViewModel.BBoxEditManager, new EditManipulation());
          mapControl.Map.Widgets.Add(widget);
          ViewModel.BBoxWidgetIndex = mapControl.Map.Widgets.ToList().IndexOf(widget);
    // and also here 
          mapControl.Map.Widgets.ElementAt(ViewModel.BBoxWidgetIndex).Enabled = false;
      }
    
    1. 正如在buttonClick()上初始化小部件时所描述的那样,如果还不存在,那就不太好了。然而,如果我这样做,我可以先绘制多边形或直线,但在使用另一个之后,第一个将无法再次绘制。
    /// <summary>
    /// enables or disables Widget for LineLayer
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void DrawLine(object sender, RoutedEventArgs e)
    {
        if (ViewModel.LineEditManager.Layer != ViewModel.LineLayer)
        {
            ViewModel.LineEditManager = new EditManager
            {
                Layer = (WritableLayer)mapControl.Map.Layers.First(l => l.Name == "Line"),
                EditMode = EditMode.AddLine,
            };
            IWidget widget = new EditingWidget(mapControl, ViewModel.LineEditManager, new EditManipulation());
            mapControl.Map.Widgets.Add(widget);
            ViewModel.LineWidgetIndex = mapControl.Map.Widgets.ToList().IndexOf(widget);
        }
    
        mapControl.Map.Widgets.ElementAt(ViewModel.LineWidgetIndex).Enabled = drawSection.IsChecked.Value; 
    }
    
    /// <summary>
    /// enables or disables Widget for PolygonLayer
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void DrawBBox(object sender, RoutedEventArgs e)
    {
        if (ViewModel.BBoxEditManager.Layer != ViewModel.PolygonLayer)
        {
            ViewModel.BBoxEditManager = new EditManager
            {
                Layer = (WritableLayer)mapControl.Map.Layers.First(l => l.Name == "Polygon"),
                EditMode = EditMode.AddPolygon,
            };
            IWidget widget = new EditingWidget(mapControl, ViewModel.BBoxEditManager, new EditManipulation());
            mapControl.Map.Widgets.Add(widget);
            ViewModel.BBoxWidgetIndex = mapControl.Map.Widgets.ToList().IndexOf(widget);
        }
    
        mapControl.Map.Widgets.ElementAt(ViewModel.BBoxWidgetIndex).Enabled = drawBBox.IsChecked.Value; 
    }
    

    如果有人知道如何解决这些方法中的任何一种(甚至另一种),我将不胜感激。

    提前谢谢。

    1 回复  |  直到 2 年前
        1
  •  1
  •   pauldendulk    2 年前

    使用自定义小部件。

    编辑小部件是最近添加到Mapsui的,还不是很复杂。您有一些我们在创建第一个版本时没有考虑到的要求。您最好的选择可能是将事情置于自己的控制之下,并创建一个自定义小部件。

    克隆Mapsui的源代码,并查找CustomWidgetSample.cs和CustomWidgetSkiaRenderer.cs(您需要注册渲染器)。如果你有这样的工作,看看EditingWidget。将该代码复制到您的自定义小部件中,并根据您自己的需要进行修改。