文档章节

DotSpatial空间测量图层支持元素识别

妆台秋思
 妆台秋思
发布于 2017/08/14 14:27
字数 988
阅读 27
收藏 0

转载请注明来源:http://blog.csdn.net/caoshiying

以前写的两篇文章:

  距离测量:http://blog.csdn.net/caoshiying/article/details/51820983

  面积测量:http://blog.csdn.net/caoshiying/article/details/51860026

分别讲解基于DotSpatial如何实现距离测量和面积测量,都没有说明暗中存在的问题:不支持元素识别。以数据驱动的方式实现的空间测量图层都属于要素图层。元素识别的时候会对空间测量图层进行元素识别。这两篇文章讲解的空间测量图层的实现方法都没有为要素增加属性信息,元素识别会报错。要解决这个问题,其实也很简单——加上属性信息就可以了。

首先,给要素图层命名并定义属性数据结构,代码如下:

LegendText = "面积测量图层";
            DataSet.DataTable.Columns.Add("编号",typeof(int));
            DataSet.DataTable.Columns.Add("面积", typeof(string));
然后把面积计算方法从DrawMeasureInformation方法中提取出来,代码如下:

public string GetMeasureString(IFeature feature)
        {
            var length = Math.Abs(CgAlgorithms.SignedArea(feature.Coordinates));
            var unit = "平方米";
            if (length > 1000000)
            {
                length /= 1000000;
                unit = "平方公里";
            }
            var draws = length.ToString("F2") + unit;
            return draws;
        }
修改测量图层对应的地图函数,在添加空间要素的信息的位置(在OnMouseDoubleClick方法中)把代码改成如下所示:

coordinates.Add(coordinates.First());
            var coords = new List<Coordinate>();
            coords.AddRange(coordinates);
            var feature = new Feature(new Polygon(coords));
            measureAreaLayer.DataSet.AddFeature(feature);
            feature.ParentFeatureSet = measureAreaLayer.FeatureSet;
            var rows = measureAreaLayer.DataSet.DataTable.Rows;
            rows[rows.Count - 1].SetField<string>(1, measureAreaLayer.GetMeasureString(feature));
            rows[rows.Count - 1].SetField<int>(0, rows.Count);
            feature.UpdateEnvelope();
至此,空间测量实现了支持元素识别,效果如下所示:



空间测量的地图函数完整 代码如下:

using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Topology;
using System;
using System.Data;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CustomLayer
{
    class MeasureAreaFunction : MapFunction
    {
        private MeasureAreaLayer measureAreaLayer;
        private List<Coordinate> coordinates;
        private Bitmap backBufferImage = null;
        private bool bMouseDown = false;
        private bool bDoubleClicked = false;
        private bool bMeasuring = false;

        internal MeasureAreaFunction(IMap mapCtrl, MeasureAreaLayer measureAreaLayer) :
            base(mapCtrl)
        {
            this.measureAreaLayer = measureAreaLayer;
            coordinates = new List<Coordinate>();
        }

        protected override void OnActivate()
        {
            base.OnActivate();
            coordinates.Clear();
            backBufferImage = new Bitmap(Map.ClientRectangle.Width, Map.ClientRectangle.Height, PixelFormat.Format32bppArgb);
            Map.MapFrame.SaveLayersToBitmap(new List<Extent>() { Map.ViewExtents }, backBufferImage, measureAreaLayer);
            bMouseDown = false;
            bDoubleClicked = false;
        }
        protected override void OnMouseDown(GeoMouseArgs e)
        {
            base.OnMouseDown(e);
            bMouseDown = true;
            bMeasuring = true;
        }

        protected override void OnMouseDoubleClick(GeoMouseArgs e)
        {
            base.OnMouseDoubleClick(e);
            if (coordinates.Count < 3)
                return;
            coordinates.Add(coordinates.First());
            var coords = new List<Coordinate>();
            coords.AddRange(coordinates);
            var feature = new Feature(new Polygon(coords));
            measureAreaLayer.DataSet.AddFeature(feature);
            feature.ParentFeatureSet = measureAreaLayer.FeatureSet;
            var rows = measureAreaLayer.DataSet.DataTable.Rows;
            rows[rows.Count - 1].SetField<string>(1, measureAreaLayer.GetMeasureString(feature));
            rows[rows.Count - 1].SetField<int>(0, rows.Count);
            feature.UpdateEnvelope();
            measureAreaLayer.DataSet.InitializeVertices();
            measureAreaLayer.Invalidate();
            backBufferImage.Dispose();
            backBufferImage = new Bitmap(Map.ClientRectangle.Width, Map.ClientRectangle.Height, PixelFormat.Format32bppArgb);
            Map.MapFrame.SaveLayersToBitmap(new List<Extent>() { Map.ViewExtents }, backBufferImage, measureAreaLayer);
            coordinates.Clear();
            bDoubleClicked = true;
            bMeasuring = false;
        }

        protected override void OnMouseUp(GeoMouseArgs e)
        {
            base.OnMouseUp(e);
            if (bDoubleClicked == false)
                coordinates.Add(e.GeographicLocation);
            bDoubleClicked = false;
            bMouseDown = false;
        }

        protected override void OnMouseMove(GeoMouseArgs e)
        {
            base.OnMouseMove(e);
            if (bMouseDown)
                return;
            if (!bMeasuring)
                return;
            var cs = new List<Coordinate>();
            var img1 = new Bitmap(Map.ClientRectangle.Width, Map.ClientRectangle.Height, PixelFormat.Format32bppArgb);
            var img2 = new Bitmap(Map.ClientRectangle.Width, Map.ClientRectangle.Height, PixelFormat.Format32bppArgb);
            cs.AddRange(coordinates);
            cs.Add(e.GeographicLocation);
            measureAreaLayer.SaveToBitmap(img1, Map.ClientRectangle, Map.ViewExtents, cs);
            var g2 = Graphics.FromImage(img2);
            g2.DrawImage(backBufferImage, 0, 0);
            g2.DrawImage(img1, 0, 0);
            var g = (Map as DotSpatial.Controls.Map).CreateGraphics();
            g.DrawImage(img2, 0, 0);
            g2.Dispose();
            g.Dispose();
            img1.Dispose();
            img2.Dispose();
        }


        protected override void OnDeactivate()
        {
            base.OnDeactivate();
            if (backBufferImage != null)
                backBufferImage.Dispose();
            coordinates.Clear();
            bMeasuring = false;
            bMouseDown = false;
            bDoubleClicked = false;
        }
    }
}

面积测量图层完整代码如下所示:

using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;
using DotSpatial.Topology;
using DotSpatial.Topology.Algorithm;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CustomLayer
{
    class MeasureAreaLayer : MapPolygonLayer
    {
        private Font font = new Font("微软雅黑", 14);
        public MeasureAreaLayer()
        {
            LegendText = "面积测量图层";
            DataSet.DataTable.Columns.Add("编号",typeof(int));
            DataSet.DataTable.Columns.Add("面积", typeof(string));
        }

        public override void DrawRegions(MapArgs args, List<Extent> regions)
        {
            base.DrawRegions(args, regions);
            DrawMeasureInformation(FeatureSet.Features, args);
        }

        public void SaveToBitmap(Image img, Rectangle rc, Extent ext, List<Coordinate> coordinates)
        {
            var g = Graphics.FromImage(img);
            var a = new MapArgs(rc, ext, g);
            var p = new MapPointLayer() { Projection = MapFrame.Projection };
            var l = new MapLineLayer() { Projection = MapFrame.Projection };
            var n = new MapPolygonLayer() { Projection = MapFrame.Projection };
            var e = new List<Extent>() { ext };

            n.Symbolizer = Symbolizer;
            p.Symbolizer = new PointSymbolizer(Color.Blue, DotSpatial.Symbology.PointShape.Ellipse, 4);
            l.Symbolizer = new LineSymbolizer(Color.Blue, 1);
            if (coordinates.Count > 2)
                n.FeatureSet.Features.Add(new Feature(FeatureType.Polygon, coordinates));
            else if (coordinates.Count == 1)
                p.FeatureSet.AddFeature(new Feature(FeatureType.Point, coordinates));
            else if (coordinates.Count == 2)
                l.FeatureSet.AddFeature(new Feature(FeatureType.Line, coordinates));
            n.DrawRegions(a, e);
            p.DrawRegions(a, e);
            l.DrawRegions(a, e);
            if (coordinates.Count > 2)
                DrawMeasureInformation(n.FeatureSet.Features, a);
            n.Dispose();
            p.Dispose();
            l.Dispose();
            g.Dispose();
        }

        private void DrawMeasureInformation(IFeatureList features, MapArgs args)
        {
            if (double.IsInfinity(args.Dx) || double.IsInfinity(args.Dy) || double.IsInfinity(args.MinX) || double.IsInfinity(args.MaxY))
                return;

            foreach (var feature in features)
            {
                var original = args.Device.Transform;
                var shift = original.Clone();
                var tool = new CentroidArea();
                tool.Add(feature.Coordinates.ToArray());
                var coord = tool.Centroid;
                var pt = new PointF((float)((coord.X - args.MinX) * args.Dx), (float)((args.MaxY - coord.Y) * args.Dy));
                if (double.IsNaN(coord.X) || double.IsInfinity(coord.X))
                {
                    Console.WriteLine("已跳过一行。");
                    continue;
                }
                shift.Translate(pt.X, pt.Y);
                args.Device.Transform = shift;
                var draws = GetMeasureString(feature);
                args.Device.DrawString(draws, font, Brushes.Red, new PointF(-args.Device.MeasureString(draws, font).Width / 2, 0));
                args.Device.Transform = original;
                shift.Dispose();
            }
        }

        public string GetMeasureString(IFeature feature)
        {
            var length = Math.Abs(CgAlgorithms.SignedArea(feature.Coordinates));
            var unit = "平方米";
            if (length > 1000000)
            {
                length /= 1000000;
                unit = "平方公里";
            }
            var draws = length.ToString("F2") + unit;
            return draws;
        }
    }
}



© 著作权归作者所有

妆台秋思
粉丝 0
博文 66
码字总数 67163
作品 0
深圳
Android工程师
私信 提问
地理信息系统库--DotSpatial

DotSpatial是一个使用.NET 4.0实现的地理信息系统库。它允许开发者将空间数据,分析和地图功能结合进他们自己的应用程序中或向社区贡献GIS扩展。DotSpatial为.NET提供了一个地图控件。...

匿名
2013/01/16
7.4K
1
第八章 Android 中View的工作原理

  Android中的View在Android的知识体系中扮演着重要的角色。简单来说,View就是Android在视觉的体现。我们所展现的页面就是Android提供的GUI库中控件的组合。但是当要求不能满足于控件的时...

忆念成风
2017/11/21
0
0
ECCV 2018 | 如何让RNN神经元拥有基础通用的注意力能力

     编者按:循环神经网络(RNNs)是序列建模中被广泛使用的网络结构,它通过控制当前信息以及历史信息的贡献大小来实现序列信息的积累。RNN神经元将当前时刻的输入向量作为一个整体,通...

微软亚洲研究院
2018/09/04
0
0
专栏 | 用神经网络来判定量子纠缠?这里有一篇简单易懂的方法解读

  机器之心专栏   作者:马悦驰(Yue-Chi Ma)、翁文康(Man-Hong Yung)      近日,来自清华大学交叉信息研究院量子信息中心、南方科技大学量子科学与工程研究所的马悦驰、翁文康所...

机器之心
2018/08/13
0
0
MnasNet:终端轻量化模型新思路

雷锋网(公众号:雷锋网) AI 科技评论按,本文作者陈泰红(ahong007@yeah.net),他为 AI 科技评论撰写了关于 MnasNet 的独家解读文章。 1. Motivation CNN 模型近年发展非常迅猛,在多项视觉...

思颖
2018/08/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 我,小小编辑,食人族酋长

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享娃娃的单曲《飘洋过海来看你》: #今日歌曲推荐# 《飘洋过海来看你》- 娃娃 手机党少年们想听歌,请使劲儿戳(这里) @宇辰OSC...

小小编辑
今天
717
10
MongoDB系列-- SpringBoot 中对 MongoDB 的 基本操作

SpringBoot 中对 MongoDB 的 基本操作 Database 库的创建 首先 在MongoDB 操作客户端 Robo 3T 中 创建数据库: 增加用户User: 创建 Collections 集合(类似mysql 中的 表): 后面我们大部分都...

TcWong
今天
40
0
spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
今天
26
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
75
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
74
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部