ArcGIS Runtime 自定义动态点符号

现在我有一个需求,使用ArcGIS Runtime,根据图层的某些特殊属性,比如统计某区域男女比例,用扇形图展现出来,应该怎么来实现呢?

大概效果如下

从文档可以知道,ArcGIS Runtime的Geometry没有提供复杂图形的绘制,所以我们得另寻他法。

最后,从Graphics这个类中找到了可以绘制复杂图形的方法,包括扇形。

那问题就转到,如何能画出扇形,那应该定位到地图上,我们看它的参数,可以看到,它的图形是绘制在Rectangle图形之上的,就类似得有一张画布。

而从Rectangle类的方法中,我们可以发现,Rectangle的定位是用Point来定位的,这明显与MapPoint是不同的。

经过一番查找与试验,终于得到的一个相对还OK的办法。

就是利用ArcGIS Runtime的PictureMarkerSymbol点符号方法,来实现

这里只是显示一个例子,具体如何实现扇形的比值跟随图层设置动态变化,自己再完善~

  private void PieRender_Click(object sender, RoutedEventArgs e)
  {
      Bitmap bitmap = new Bitmap(400,400); // 新建的位图对象
      bitmap.MakeTransparent();  // 设置背景为透明
      Graphics graphics = Graphics.FromImage(bitmap);  // 从指定的 System.Drawing.Image 创建新的 System.Drawing.Graphics
      graphics.SmoothingMode = SmoothingMode.AntiAlias;  // 设置此 System.Drawing.Graphics 的呈现质量
      Pen pen = new Pen(Color.Red);  // 扇形的边框颜色
      Rectangle rct = new Rectangle(0, 0, 400, 400);  // 扇形的画布,设置大小与位图的一致
      Brush brush1 = new SolidBrush(Color.Pink);
      graphics.DrawPie(pen, rct, 0, 120);//绘制扇形
      graphics.FillPie(brush1, rct, 0, 120);//填充扇形;

      Brush brush2 = new SolidBrush(Color.BlueViolet);
      graphics.DrawPie(pen, rct, 120, 240);//绘制扇形
      graphics.FillPie(brush2, rct, 120, 240);//填充扇形;
      pen.Dispose();
      graphics.Dispose();

      MapPoint mp = new MapPoint(433057.512512913, 2561911.18374385);  // 这个就是MapPoint了,可以设置成动态,扇形位置就跟随它变化
      RuntimeImage runtimeImage = new RuntimeImage(BitmapToByte(bitmap));
      PictureMarkerSymbol pSymbol = new PictureMarkerSymbol(runtimeImage);
      pSymbol.Width = 100;
      pSymbol.Height = 100;
      pSymbol.OffsetY = pSymbol.Height / 2;
      Graphic pGraphic = new Graphic(mp, pSymbol);
      _routeGraphicsOverlay.Graphics.Add(pGraphic);
  }

  public static byte[] BitmapToByte(System.Drawing.Bitmap bitmap)
  {
      // 1.先将BitMap转成内存流
      System.IO.MemoryStream ms = new System.IO.MemoryStream();
      bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);  // 必须是PNG
      ms.Seek(0, System.IO.SeekOrigin.Begin);
      // 2.再将内存流转成byte[]并返回
      byte[] bytes = new byte[ms.Length];
      ms.Read(bytes, 0, bytes.Length);
      ms.Dispose();
      return bytes;
  }
posted @ 2022-06-08 13:01  槑孒  阅读(240)  评论(0编辑  收藏  举报