从零开始搭建GIS开发小框架(一)——基本框架

2022-06-14 15:44:30 浏览数 (1)

1

概述

Introduction to new functions

没想到我还搞GIS开发吧,我也没有想到(手动狗头)。

别人的生活最多撞一下腰,我的生活总是出其不意给我一刀,我说最后一题烧绳子你说时间到了交卷了,我说要躺下你说同志醒醒还有个bug,我说不想再学了你说GIS开发了解一下。

突然就被迫营业地新开一个技能树:GIS开发,为了摸索一下GIS开发的有关知识,抽空做了一个GIS框架程序,在这里做一下学习笔记。

准备了一个系列四篇文章,分别是:

  1. 基础框架
  2. 绘制多边形
  3. 搜索地址名称
  4. CGCS2000坐标转换到WGS84

凑满这些功能,煎饼果子一套就齐全了,实乃居家旅行,论文私活,必备良药。

2

技术选型

Technology

选择GMap.NET,GMap.NET是一个强大、免费、跨平台、开源的.NET控件,它在Windows Forms 和WPF环境中可以基于Http协议加载各个公司的地图,例如:Google, Yahoo!, Bing, OpenStreetMap, ArcGIS, Pergo, SigPac等地图,主要原理是通过解析各个公司的地图服务的URL,传入相应的参数得到对应的切片底图(Tiled map),并可以实现寻找路径、地理编码以及地图展示功能,并支持缓存和运行在Mobile环境中。

3

底图功能实现

Major Function

底图功能是整个GIS展现的基础,一般有在线和离线两种方式,各有利弊,因为是摸索,所以我把两种效果都试了试;

1

方式一:在线地图

高德在线地图显示效果:

高德地图的GMapProvider类的实现:

代码语言:javascript复制
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.Projections;
using System;

namespace GMap
{
    public abstract class GaodeMapProviderBase : GMapProvider//, GeocodingProvider
    {
        private string ClientKey = "这个Key在高德开发平台可以免费申请";

        public GaodeMapProviderBase()
        {
            MaxZoom = null;
            RefererUrl = "http://www.amap.com/";
            Copyright = string.Format("©{0} Corporation, ©{0} 高德地图, ©{0}", DateTime.Today.Year);
        }

        public override PureProjection Projection
        {
            get
            {
                return MercatorProjection.Instance;
            }
        }

        private GMapProvider[] overlays;
        public override GMapProvider[] Overlays
        {
            get
            {
                if (overlays == null)
                {
                    overlays = new GMapProvider[] { this };
                }
                return overlays;
            }
        }
    }

    public class GaodeMapProvider : GaodeMapProviderBase
    {
        public static readonly GaodeMapProvider Instance;

        private readonly Guid id = new Guid("608748FC-5FDD-4d3a-9027-356F24A755E5");
        public override Guid Id
        {
            get
            {
                return id;
            }
        }

        private readonly string name = "GaoDe";
        public override string Name
        {
            get
            {
                return name;
            }
        }

        static GaodeMapProvider()
        {
            Instance = new GaodeMapProvider();
        }

        public override PureImage GetTileImage(GPoint pos, int zoom)
        {
            string url = MakeTileImageUrl(pos, zoom, LanguageStr);

            return GetTileImageUsingHttp(url);
        }

        private string MakeTileImageUrl(GPoint pos, int zoom, string language)
        {
            var num = (pos.X   pos.Y) % 4   1;
            //string url = string.Format(UrlFormat, num, pos.X, pos.Y, zoom);
            string url = string.Format(UrlFormat, pos.X, pos.Y, zoom);
            return url;
        }

        private static readonly string UrlFormat = "http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={0}&y={1}&z={2}";
    }  
}

主程序里的GMap.Net控件通过load方法调用地图资源:

代码语言:javascript复制
private void load()
{
    MainMap.MapProvider = GaodeMapProvider.Instance;       //高德
    //MainMap.MapProvider = BaiduMapProvider.Instance;  //百度
    MainMap.CacheLocation = @"D:GisMap";
    MainMap.Manager.Mode = AccessMode.ServerAndCache;
    MainMap.MinZoom = 8;                                                     //最小比例
    MainMap.MaxZoom = 18;                                                    //最大比例
    MainMap.Zoom = 13;                                                       //当前比例
    MainMap.ShowCenter = false;                                              //不显示中心十字点
    MainMap.DragButton = MouseButtons.Left;
    //高德35.014532, 110.998649
    //百度66.286011,21.677210 坐标有问题
    MainMap.Position = new PointLatLng(30.594479, 114.304233);   //lat是纬度,lng是经度  武汉
    MainMap.Overlays.Add(overlay);                              //将图层添加到地图
    MainMap.Overlays.Add(polygonAuxiliaryLinelay);  //将图层添加到地图
    //MainMap.HelperLineOption = HelperLineOptions.ShowAlways;
    this.lbZoomStatus.Text = MainMap.Zoom.ToString();
}

2

方式二:离线地图(瓦片地图)

用地图下载器(用于生成GMDB格式离线地图文件)greatmaps虽然下载到源码,但是编译运行报错,我用他自带的bin目录下的exe运行打开下载器。

type选OpenCycleMap,mode选ServerAndCache

按住alt,鼠标左键框选需要下载的地图,进行地图下载,点击Prefetch selected area按钮。我选择是下载到18或者20,速度有点慢,慢慢等。

下载完毕后导出:

导出后得到gmdb文件:

主程序里的GMap.Net控件通过load方法调用地图资源

代码语言:javascript复制
string mapPath = System.Windows.Forms.Application.StartupPath   "\Gmdb\DataExp15to18.gmdb";//地图路径
GMaps.Instance.ImportFromGMDB(mapPath);//如果使用内部包,直接不要前面这两句
MainMap.Manager.Mode = AccessMode.ServerAndCache;
MainMap.MapProvider = GMapProviders.OpenCycleMap;
MainMap.MinZoom = 4;      //最小比例
MainMap.MaxZoom = 18;     //最大比例
MainMap.Zoom = 10;        //当前比例
MainMap.ShowCenter = false;//不显示中心十字标记
this.MainMap.DragButton = System.Windows.Forms.MouseButtons.Left;//左键拖拽地图
MainMap.MouseWheelZoomType = MouseWheelZoomType.MousePositionAndCenter;//鼠标缩放模式
MainMap.Position = new PointLatLng(30.594479, 114.304233);//地图中心坐标,(纬度,经度)
MainMap.Overlays.Add(overlay);                  //将图层添加到地图
MainMap.Overlays.Add(polygonAuxiliaryLinelay);  //将图层添加到地图

瓦片地图显示效果:

4

扩展功能

Function

主菜单:

1

定位到具体坐标

这个功能是GIS项目最基本的功能,根据精确坐标寻址。

代码语言:javascript复制
MainMap.Zoom = 17;
MainMap.Position = new PointLatLng(30.595772, 114.299644);   //lng是经度,lat是纬度

2

双击添加标记点Marker

这个功能是后续会较多使用的功能,POI数据都是以点的形式体现,Marker是最基本的绘制点的工具,并可以为点设置不同的图标,满足业务多样化的需要。

代码语言:javascript复制
PointLatLng p = this.MainMap.FromLocalToLatLng(e.X, e.Y);  //将鼠标点击点坐标转换为经纬度坐标

//创建标记,并设置位置及样式
GMapMarker marker = new GMarkerGoogle(new PointLatLng(p.Lat, p.Lng), GMarkerGoogleType.blue_pushpin);

marker.ToolTipMode = MarkerTooltipMode.OnMouseOver;
marker.ToolTipText = "标记的显示文字";
marker.Tag = string.Format("{0},{1}", p.Lat, p.Lng);

//将标记添加到图层
overlay.Markers.Add(marker);

3

绘制多边形

这个功能是后续会较多使用的功能,有价值的地理数据很多是以区域的形式体现,多边形是最基本的绘制区域的工具。(另文介绍)

4

搜索地址

这个功能是GIS项目最基本的功能,根据模糊地址寻找精确坐标。(另文介绍)

5

坐标转换

以“国家CGCS2000坐标转换为WGS84坐标”为例,实现坐标转换功能。(另文介绍)

0 人点赞