夏 军
(西华师范大学 国土资源学院,四川 南充 637002)
随着电子信息化时代的到来,地图在人们的日常工作和生活中的地位越来越重要。从户外导航、位置查询,到灾害救援、建设规划等,地图服务于社会经济发展的方方面面,为人们提供方便。随着地图服务需求的增加,对于各类地图的制作显得尤为重要。而传统地图制作方法[1-3],需要专业的地图制作软件,如ArcGIS、ARC/INFO、MapGIS、MapInfo、AutoCAD等。对于这些专业GIS软件,安装和学习的门槛较高,往往需要专业人士操作。
随着国内外地理信息产业的迅猛发展,网络地理信息资源越来越丰富[4]。近些年,谷歌地图、天地图、百度地图等的兴起,让人们可以通过网络地图API轻易获取到丰富的地图资源和服务应用[5]。利用这些免费的地图资源制作各类专题地图[6]、地形图[7]、交通位置图[8]、救灾应急地图[9-13]、导航地图[14]、旅游地理信息系统[15-17]、卫星影像图[18]以及其他公共服务系统[19-20]等的研究已有很多。在某些情况下,可能只需要一张简单的地图,传统的方法一般是利用卫星遥感影像、行政区划、道路、河流和地名等专题地图,再通过专业GIS软件制作成地图,这种方法繁琐复杂、效率低下,而且需要具有一定GIS专业知识的技术人员才能完成。那么研究开发一款操作简单、不需要专业知识,并能够快速成图的软件系统,无论从制图效率、成本和实用性上来说都具有重要的意义和必要性。
本文在分析快速制图系统功能需求基础上,对地图格网坐标值自动获取算法进行研究和试验,并采用C#编程语言,在Visual Studio 2010集成开发环境下,调用百度地图API,设计并开发快速制图系统。该软件系统可以制作带经纬网格、经纬度和用户自定义标注的行政区划图、卫星影像图和交通位置图等,简单美观,适用于项目报告、PPT演示等文档插图、以及海报、广告展板等。该制图系统出图快速、操作简单,非专业人士也能轻松制图。
对制图系统的基本要求是简单、快速,方便操作,具有部分用户自定义功能,能够在数分钟之内制作出美观的小幅地图,基本功能如下:
1)地图加载。百度地图、卫星影像图、道路(地名),可选择切换地图类型;
2)地图基本操作。鼠标和导航控件控制地图移动、放大、缩小等;
3)绘图。点、线、面、文字+地标,编辑图形,删除图形;
4)测距。边画边测路线长度;
5)搜索地名、搜行政区域边界;
6)截图;
7)设置出图样式,包括标题文字、图框、经纬度网格线、颜色等;
8)输出带坐标网格图像。
针对制图系统的功能需求,在Visual Studio 2010集成开发环境下,选用C#编程语言,将C/S和B/S模式相结合,把地图页面嵌入到系统主窗体的WebBrowser控件,实现客户端调用网络地图的功能。网络地图数据源选择百度地图,具有美观简洁、内容丰富和免费开源的API等特点。该制图系统结构功能如图1所示。
图1 制图系统功能结构图
百度地图[21]是百度提供的一项网络地图搜索服务,覆盖了国内近400个城市、数千个区县。在百度地图里,用户可以查询街道、商场、楼盘的地理位置,也可以找到离用户最近的所有餐馆、学校、银行、公园等。除了提供丰富的公交换乘、驾车导航等查询功能,还为用户提供最适合的路线规划。不仅知道要找的地点在哪,还可以知道如何前往。同时,百度地图还为用户提供了完备的地图功能(如搜索提示、视野内检索、全屏、测距等),便于更好的的使用地图,便捷的找到所求。
百度地图JavaScript API[22]是一套由JavaScript语言编写的应用程序接口,可帮助您在网站中构建功能丰富、交互性强的地图应用,支持PC端和移动端基于浏览器的地图应用开发,且支持HTML5特性的地图开发。另外,2014-01-09,极速版JavaScript API全新上线,此版本专门针对简单功能的移动端浏览器开发提供。百度地图API免费对外开放,自v1.5版本起,您需先申请密钥(ak)才可使用,接口(除发送短信功能外)无使用次数限制。
通过屏幕截图,不仅可以获得地图图片,还可以得到地图图片的4个顶点相对于屏幕左上角的像素坐标(pixelX, pixelY),再调用百度地图API的“map.pixelToPoint()”将像素坐标转换为WGS84地理坐标系下的经纬度坐标,代码(JavaScript)如下:
function pointXY2LngLat(pixelX, pixelY){
var lngLat = map.pixelToPoint({x: pixelX, y: pixelY});
return lngLat.lng+','+lngLat.lat;
}
地图格网绘制需要预先知道它的经纬度坐标值,合理的格网分布可以使地图更加规范和实用。通过大量试验,利用本算法可以实现格网经度值和纬度值的自动计算,得到优化合理的坐标值,算法思路如下:预先设定最小格网数目和格网经线间隔值数组,再根据截图范围的经度差值,计算出合适的经线格网间隔值,再将格网经线间隔值乘以k(k=1,2,3……)得到0~360°范围内的格网经度值,而介于截图范围内的这些值就是经线网格的经度值,核心代码(C#)如下:
ArrayList GridLonArr = new ArrayList(); //定义网格经线值数组(待求)
double DMapLon = MapLonMax -MapLonMin; //地图范围经度差值(已知)
double[] GridDLonArr = new double[] { 50, 40, 30, 20, 10, 5, 2, 1 }; //预先设定的网格经度间隔数组(自定义)
int GridLonMinCount = 3; //经线网格的最小条数(自定义)
for (int i = 0; i < GridDLonArr.Length; i++)
{
if (DMapLon / GridDLonArr[i] >= GridLonMinCount)
{
double GridLon = 0; //初始化经线网格经度值
int k = 0;
while (GridLon <= 360) //360为经度值上限
{
GridLon = GridDLonArr[i] * k; //计算所有经线网格值
if (GridLon >= MapLonMin && GridLon <= MapLonMax) //选取介于截图范围的经线网格
{
GridLonArr.Add(GridLon); //将得到的网格经度值添加到数组
}
k++;
}
}
}
该算法简单、易于实现,运算速度快。格网纬度值计算方法与经度值相似,只是取值范围不同,经度值是0~360°,而纬度值范围为0~90°。
该系统实现了电子地图的基本功能,主要包括:地图显示、缩放、平移、地图类型切换、图形绘制、距离测量、地名搜索和行政区划边界显示等,并继承了百度地图简洁美观、易于操作的特点。地图类型包括:行政区划地图、卫星影像图和叠加了道路地名的卫星影像图。图形绘制包括:文字、地标、路线、多边形、圆和矩形。
虽然百度API是免费开放的,但从v1.5版本后需要申请密匙。所以在满足开发功能需求的前提下,选择v1.4版本的API。创建名称为“index.html”的html文件,通过百度地图API加载百度地图,代码(Html、CSS和JavaScript)如下:
body, html,#container {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
var map = new BMap.Map('container'); //定义百度地图对象,将“container”作为地图容器
map.centerAndZoom(new BMap.Point(104.15, 34.68), 5); //初始化视图:中心点和缩放级别
map.enableScrollWheelZoom(); //允许通过鼠标滚轮缩放地图
map.addControl(new BMap.MapTypeControl({mapTypes: [ BMAP_NORMAL_MAP, BMAP_HYBRID_MAP, BMAP_SATELLITE_MAP], anchor: BMAP_ANCHOR_TOP_LEFT, offset: new BMap.Size(80, 70)})); //添加地图类型
map.addControl(new BMap.NavigationControl({anchor: BMAP_ANCHOR_TOP_LEFT, offset: new BMap.Size(10, 60)})); //添加导航控件
map.addControl(new BMap.ScaleControl({anchor: BMAP_ANCHOR_BOTTOM_RIGHT, offset: new BMap.Size(150, 100)})); //添加比例尺控件
以上调用百度地图API加载了地图,具有地图显示、导航控制、地图类型切换等功能。根据功能需求,还加入了绘图工具、搜索和地图制作工具等。在Visual Studio 2010中新建项目,新建窗体,创建WebBrowser控件,将“index.html”网页加载进去,实现B/S和C/S模式相结合,制作成桌面版的网络地图。软件运行的主界面如图2所示。
图2 制图系统主界面
Geocoding API 是一类简单的HTTP接口,用于提供从地址到经纬度坐标或者从经纬度坐标到地址的转换服务。通过创建“new BMap.Geocoder()”实例可以实现对地名的搜索和定位,代码(JavaScript)如下:
var geocoder = new BMap.Geocoder();
geocoder.getPoint(address, function(point){
//此处解析返回结果,获得位置坐标
}
Boundary服务类可实现对行政区划的搜索和边界的显示,该服务类只能搜索并显示县级或更高级别行政区域边界,无法搜索乡镇和村的边界。通过实例化对象“new BMap.Boundary()”可以返回行政区域边界坐标,代码(JavaScript)如下:
var boundary = new BMap.Boundary();
boundary.get(place, function(rs){
//此处解析返回结果,获得边界坐标
}
距离测量功能使用百度地图的“BMapLib.DistanceTool”类,它是一套基于百度地图API二次开发的开源的代码库,对外开放。允许用户在地图上点击完成距离的测量,可以自定义测距线段的相关样式,例如线宽、颜色、测距结果所用的单位制等。该类基于Baidu Map API 1.2,主入口类是DistanceTool,通过实例化,即可调用该类提供的open 方法开启测距状态,代码(JavaScript)如下:
var distance = new BMapLib.DistanceTool(map);
distance.open();
图形绘制功能采用百度地图开源库的“BMapLib.DrawingManager”类,提供鼠标绘制点、线、面、多边形(矩形、圆)的编辑工具条。且用户可使用JavaScript API对应覆盖物(点、线、面等)类接口对其进行属性(如颜色、线宽等)设置、编辑(如开启线顶点编辑等)等功能。该类是基于Baidu Map API 1.4,实例化后,即可调用该类提供的open 方法开启绘制模式状态,还可加入工具栏进行选择操作。实例化鼠标绘图工具代码(JavaScript)如下:
var drawingManager = new BMapLib.DrawingManager(map, {
isOpen: false, //默认不开启绘制模式,用户通过选择绘图工具开启
circleOptions: styleOptions, //圆的样式
polylineOptions: styleOptions, //线的样式
polygonOptions: styleOptions, //多边形的样式
rectangleOptions: styleOptions //矩形的样式
});
还可以加入鼠标监听事件,对绘图整个绘图过程进行响应,如以下代码(JavaScript)当绘图完成时执行。
drawingManager.addEventListener(“overlaycomplete”, function(e){
//当绘图完成时触发该事件
}
制作一张基本的地图,需要添加一些地图要素,包括:图框、格网、标注、指南针、四周的文字、比例尺和图例等,而它们的位置和样式直接影响到地图的美观性。该系统可以快速制作简单美观的小幅地图,可以自动生成地图内外图框、经纬网、经纬度标注、标题,并可以修改它们的颜色和线条粗细。地图比例尺采用百度地图默认的比例尺样式,坐标系为WGS84,投影为Web墨卡托。制图过程顺序如下:地图截图→加内外图框→加经纬网→加经纬度标注→加指北针→加标题→输出地图。
地图整饰主要是调用C#的“Graphics”类,另外新建一个绘图类“Draw”,将“Graphics”类的添加文字、图形等功能封装起来,方便调用。以下是“Draw”类的定义,具体代码(C#)省略。
public class Draw
{
public void drawBorder(){ } //绘制地图图框
public void drawGrid(){ } //绘制经纬网格
public void drawLongitudeLatitude(){ } //绘制经纬度标注
public void drawNorthArrow(){ } //绘制指北针
public void drawTitle(){ } //绘制地图标题
}
在以上方法中,地图格网的绘制是难点,采用本文设计的格网坐标自动获取算法,根据地图经度和纬度跨度,结合地图宽高像素值,合理计算需要绘制的经线和纬线条数以及它们在地图上的位置。
利用该制图系统制作地图非常简单快速,操作步骤主要分3步:①调整地图。选择地图源,放大、缩小地图到合适比例尺,移动地图到需要的范围,调整比例尺到右下角位置,还可以对地图进行文字和图形标注;②截图。点“截图”按钮,调整截图窗口到合适位置,并可以对截图进行文字和图形的添加,双击鼠标左键完成截图;③出图。点“出图”按钮,系统自动制作地图,以“Jpeg”图片格式保存到出图文件目录下面,并自动打开图像,方便进行浏览。
以四川省成都市为例,搜索行政区域名称“四川省成都市”,系统自动获取边界坐标并绘制出红色边界;在地图上进行“郫都区”和“都江堰景区”标注,利用测距工具标示出距离,从成都市三环路到郫都区直线距离为15.6 km,到都江堰景区距离为50.4 km;调整地图窗口到合适位置,将地图原有比例尺包含在内;点“截图”按钮,调整截图范围,如图3所示;再点“出图”按钮,地图制作成果如图4所示。该制图系统制作出的地图默认上方向为正北方向。
图3 截图过程界面
图4 地图制作成果图
日常生活和工作中经常会用到地图,而地图的制作需要相关的专业知识、庞大的GIS软件和复杂的操作步骤。本文通过对快速制图的需求分析,实现了地图格网经度值和纬度值坐标的自动获取算法,并以百度地图作为地图源,采用C#、JavaScript等编程语言进行开发,通过对百度地图API进行调用,设计并开发了快速制图系统。通过该制图系统可以方便快速地制作出各类示意性地图和专题图,如:项目研究区、交通位置图、行政区划图、旅游景点分布图等的示意地图。用户可以自定义部分地图样式,包括:地图图框、经纬网格、地图标题、经纬度标注等。制作出的地图简单美观,适用于项目报告、PPT等文档插图,以及海报、广告展板等,也可用于应急情况下的紧急制图,服务于社会经济生活。该制图系统操作简单,制图效率高,使用者不需要地图相关知识,也不需要复杂的GIS专业软件,对制图工作起到事半功倍的效果。
快速制图系统在制图方面的优势,重在于快捷、简单和美观,无需专业软件和专业知识,为非专业人士提供了一个简单而快速的制图途径。但相比传统专业GIS软件,还存在一些不足,暂时无法制作大幅的高分辨率地图,还不能自动生成图例,不能导入已有数据,今后将不断完善,输出结果将支持更多格式。