基于WebGIS的ShapeFile文件解析系统的设计与实现

2019-06-21 06:06张凯旋邹业斌刘昙昙马文涛
资源环境与工程 2019年2期
关键词:数据格式字符串行政区

张凯旋, 邹业斌, 刘昙昙, 马文涛

(中国矿业大学(北京),北京 100083)

地理信息系统是一种采集、存储、管理、分析、显示与应用地理信息的计算机系统[1],以数字化的形式反映地球空间现势和变迁的各种空间数据并描述这些空间数据特征的属性,以及使用模型化的方法来模拟地球空间对象的行为,在计算机软、硬件的支持下,以特定的格式支持输入/输出、存贮、显示以及进行地理空间信息查询、综合分析、辅助决策,为人们提供处理地理信息最佳的方法和手段[2]。随着互联网技术的发展,大数据和云计算等技术的兴起,使WebGIS应用得到了飞速的发展。利用Internet在Web上发布和出版地理信息,为用户提供空间数据的浏览、查询、制作专题图和分析的功能,从而实现地理信息的共享,已经成为GIS发展的必然趋势[3]。在实际WebGIS开发中会需要上传本地的ShapeFile文件并结合WebGIS系统进行分析,Esri的服务非常昂贵,因此在小规模的GIS平台搭建过程中可搭建本地后台解析系统。本文详细介绍了ShapeFile的文件结构,根据ShapeFile文件的结构,利用.NET技术进行解析,并展示到Web前端。对各学者建设WebGIS平台有所借鉴。

1 ShapeFile图形文件的结构

一个完整的ESRI的ShapeFile文件包括一个主文件*.shp,一个索引文件*.shx,和一个属性文件*.dbf。主文件是一个直接存取,记录长度文件,其中每个记录描述一个由其顶点列表组成的ShapeFile。在索引文件中,每条记录是在主文件中记录对应距离主文件头部的偏移量。*.dbf中记录的是对应主文件中记录的属性记录,每条主文件记录对应*.dbf中的一条属性记录。*.prj文件用于存储坐标系的信息;*.xml文件作为元数据文件,用于存储ShapeFile的相关信息[4]。

1.1 shp文件的数据结构

主文件用来存储地理要素的几何图形,一个.shp文件由文件头和记录实体两部分组成[5]。主文件头100字节长。表1描述了文件头中数据的字节位置、值类型和字节顺序。在表1中,位置是相对于文件头的。文件头的布局如表1所示。

表1 主文件头结构表Table 1 Structure table of main file header

1.2 shx索引文件结构

.shx索引文件是存储图形要素与属性信息索引的文件,主要起到定位的作用,其由文件头和记录两部分组成,文件头的内容与主文件的基本一致[5]。每条记录由8个字节组成,具体内容如表2所示。其中,Offset可以理解为该条记录在.shp文件中的偏移量,Content Length可以理解为该记录的长度。

表2 索引文件记录结构表Table 2 Structure table of index file record

1.3 dbf文件结构

.dbf属性表文件,是由头记录及数据记录组成。头记录定义了该表的结构并包含与表相关的其它信息,它主要对属性文件作一些概括性描述,尤其是对属性文件的记录项信息进行着重性说明,比如对每个记录项的名称、数据类型、精度、长度都作了详细地介绍。

2 整体解析过程

本地文件利用Ajax技术通过Post提交方式异步上传给后台服务端,后台服务端通过HttpPostedFile接受前端传递过来的文件并且通过FileStream类读取文件上传到文件服务器[6]。然后调用WebService服务利用BinaryReader类以二进制文件流的方式对ShapeFile进行解析,以集合的方式返回解析后的数据。将集合数据转换成JSON数据格式,利用ArcGIS for JavaScript库类展示数据,流程如图1。

图1 解析流程图Fig.1 Analytical flow chart

2.1 文件上传

HttpPostedFile postedFile =context.Request.Files[0]; //接收文件

postedFile.SaveAs(context.Request.MapPath(fullDir)); //保存文件

FileStream fo= new System.IO.FileStream

(context.Request.MapPath(shxpath),FileMode.Open,FileAccess.Read);

//文件流形式

以文件流的方式将前端Web Browser上传的文件存储到文件服务器,利用FileStream分别读取.shp、.shx和.dbf文件,FileStream读写操作可以指定为同步或异步操作。同时支持对输入输出流进行缓冲,提高性能。

2.2 文件解析

[WebMethod]

public List file(FileStream shpfo,string passPath,FileStream fs)

BinaryReader bi = new BinaryReader(shpfo); //读取shp文件

BinaryReader br = new BinaryReader(fs); //读取shx文件

for(int n = 0;n < RecorderNumber;n++) //文件解析过程

{ ……

double[] pointsx = new double[Numpoints];

double[]pointsy = new double[Numpoints]; //定义数组

for(int z = 0;z < Numpoints;z++) //for循环读取

{ ……

pointtemp.X = br.ReadDouble();

pointtemp.Y = br.ReadDouble();

shpstr+= "["+ pointtemp.X+ ","+ pointtemp.Y+ "],";

}

list.Add(shpstr);//存入List集合

}

return list;

}

}

public List DbfFile(FileStream dbfo) //读取dbf属性文件

{

BinaryReader br1 = new BinaryReader(dbfo); //读取二进制文件

DataRow dr = dt.NewRow();

tempBytes = br1.ReadBytes(fieldLength[j]);

Regex regex = new Regex("\s+");

tempStr = regex.Replace(tempStr,"");

dt.Rows[i][j] = """+ tempStr+ """;

dbfstr = Regex.Split(result,"},"); //将解析后的属性信息,转字符串数组

return list; //将字符串数组遍历,添加到集合后返回

}

调用WebService服务对文件流通过BinaryReader类的ReadInt和ReadByte等方法,根据文件结构以二进制流的方式对ShapeFile文件的.shp、.dbf、.shx文件进行解析,获取点、线、面数据类型,以及点坐标和属性文件。最后将解析后的数据以List集合方式返回,坐标list集合中每条点数据格式如图2,属性list集合中每条属性数据格式图3所示。

图2 坐标List集合中每条数据格式图Fig.2 Each data format chart in the coordinate List set

图3 属性List集合中每条数据格式图Fig.3 Each data format graph in the attribute List collection

2.3 JSON格式传输数据

JSON是一种轻量级的数据交换格式[7],易于阅读和编写,同时也易于机器解析。每条JSON消息都是包含在大括号之内的,键值对组合中的键名写在前面并用双引号包含,键和值使用冒号分隔,冒号后面紧接着值,如:“key”:“value”;数组是用方括号包含起来的,如:[“zhou”,“zhang”]。相较于xml,JSON在传输的过程中采用了压缩技术,传输的过程中更加节省宽带而且传输更加高效。当大量的坐标信息以及属性信息传递给前端浏览器的时候为了不引起浏览器卡顿,用户等待时间过长,所以后台需要将list集合进行遍历,然后将字符串拼接成JSON格式的字符串再传递给前端。

以线的ShapeFile文件的解析为例。根据ArcGIS for JavaScript库类提供的线的数据格式,将数据拼接成如下格式:

var myLine =[{ attributes:{“TNODE”:”7”,”LPOLY”:”2”},geometry:{"paths":[[[-91.40625,6.328125],[6.328125,19.3359375]]],

"spatialReference":{"wkid":4326}},

"symbol":{"color":[0,0,0,255],"width":1,"type":"esriSLS","style":"esriSLSSolid"}}];

核心代码如下:

if(Convert.ToInt32(type)==3)

{

bdfstring1 = "{"+ ""attributes""+ ":"+bdfstring[i].ToString()+ "},"+ shapetype; //通过for循环,添加属性信息

dbfstr = "["+ str.Remove(0,1)+ "]],"+ ""spatialReference""+ ":"+ "{"+ ""wkid""+ ":"+ 4326+ " }"+ "},"+ ""type""+ ":"+3+"},"; //通过for循环,添加坐标系信息

}

传递给前端的JSON字符串格式如图4。

2.4 利用ArcGIS for JavaScript库类展示数据

ArcGIS for JavaScript库类是ESRI根据JavaScript技术实现的一组脚本,可以将ArcGIS Server提供的地图资源和其它资源(ArcGIS Online)嵌入到Web应用中。有丰富的网络资源、基于功能强大的Dojo JavaScript工具包、开发和部署都是完全免费的等优点。

前台通过调用ArcGIS for JavaScript的GraphicLayer、Graphic和Geometry等接口对后台还回的JSON数据进行解析。创建一个新的图层,然后根据ArcGIS for JavaScript 框架提供的Graphic类new Graphic(geometry?,symbol?,attributes?,infoTemplate?)将解析后的数据传递给浏览器渲染展示。通过InfoTemplate类new InfoTemplate(JSON)将属性信息展示出来。

图5 中国省级行政区界线读取Fig.5 Reading of China’s provincial administrative boundaries

图6 中国省级行政区界线面读取Fig.6 Reading the boundary surface of provincial administrative regions in China

图4 传递给前端的JSON字符串格式Fig.4 JSON string format passed to the front end

//设置线的颜色宽度

var myLine = {"symbol":{ "color":[0,0,0,255],"width":2,"type":"esriSLS","style":"esriSLSSolid" }};

//设置属性窗口

var infoTemplate = new mapAPI.InfoTemplate("Attributes",JSON.parse(attri));

//创建一个新的图层

var countyLayer = new map.GraphicsLayer();

//将图层添加到地图上

countyLayer.add(gra);

map.addLayer(countyLayer);

3 实例验证

本文采用中国省级行政区界.shp矢量地图数据,用来验证编写的系统读写ShapeFile 图形文件的功能。采用谷歌浏览器,利用VS 2012,在.NET 4.5的环境下完成。Esri提供的底图是WGS 84坐标系。

(1) 读取中国省级行政区界.shp,如图5所示。

(2) 读取中国省级行政区界.shp面信息,以及属性信息,如图6所示。

(3) 中国省级行政区界属性信息的读取展示,如图7所示。

4 结论

本文首先介绍了Shapefile图形文件的基本结构,根据ShapeFile文件的结构在.NET环境下利用 Microsoft Visual Studio2012平台开发了可以展示ShapeFile图形及其属性信息的WebGIS系统,加深了对网络传输、JSON字符串、以二进制文件流的方式解析文件、WebGIS系统开发以及ShapeFile文件结构等的理解,对后期各学者建设WebGIS平台提供借鉴。

图7 中国省级行政区界属性信息显示Fig.7 Attribute information display of provincial administrative boundaries in China

猜你喜欢
数据格式字符串行政区
京字头
基于文本挖掘的语词典研究
上榜派出所统计表
上榜派出所统计表
MIT—BIH心率失常数据库的识读
基于RFID的户外广告监管系统的设计与实现
SQL server 2008中的常见的字符串处理函数
倍增法之后缀数组解决重复子串的问题
一种融合多业务的信息化系统框架研究
最简单的排序算法(续)