1
概述
Introduction to new functions
没想到我还搞GIS开发吧,我也没有想到(手动狗头)。
别人的生活最多撞一下腰,我的生活总是出其不意给我一刀,我说最后一题烧绳子你说时间到了交卷了,我说要躺下你说同志醒醒还有个bug,我说不想再学了你说GIS开发了解一下。
突然就被迫营业地新开一个技能树:GIS开发,为了摸索一下GIS开发的有关知识,抽空做了一个GIS框架程序,在这里做一下学习笔记。
准备了一个系列四篇文章,分别是:
- 基础框架
- 绘制多边形
- 搜索地址名称
- 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坐标”为例,实现坐标转换功能。(另文介绍)