转载自http://wenku.baidu.com/link?url=3TG7c0cERbdnZwFBLq6n2v-chB-k4ja5ikNYSyRQHyLf4yvYCGBEGrlhch8GD5e-96PfkAi-r_98QwDqLe6kw-4Ek8aBTLh1yFaKOXic2w7

ESRI的Shapefile文件向Google Earth中KML文件的格式转换

摘要】:21世纪,是科学技术与信息技术高速发展的时期,地理信息技术也不例外。为了促进GIS技术与产业的发展,促进地理信息系统的开发,实现海量地理数据的共享和存储,我们有必要从实际应用出发,研究地理信息系统开发过程中出现的各种数据结构、数据格式以及它们之间的转换。本文以ESRI的Shapefile文件和Google Earth中KML文件为例,利用ArcGIS软件中的二次开发功能,以VBA语言为依托,将Shapefile文件转换为Google Earth中KML文件,并给出最终的转换结果和程序代码。

关键词】:KML文件  Shapefile文件  ArcGIS 地理信息系统 Google Earth

1.引言

Shapefile文件是美国环境系统研究所(ESRI)所研制的GIS文件系统格式文件,是工业标准的矢量数据文件。 Shapefile将空间特征表中的非拓扑几何对象和属性信息存储在数据集中,特征表中的几何对象存为以坐标点集表示的图形文件—SHP文件,Shapefile文件并不含拓扑(Topological)数据结构。一个Shape文件包括三个文件:一个主文件(*.shp),一个索引文件(*.shx),和一个dBASE(*.dbf)表。主文件是一个直接存取,变长度记录的文件,其中每个记录描述构成一个地理特征(Feature)的所有vertices坐标值。在索引文件中,每条记录包含对应主文件记录距离主文件头开始的偏移量,dBASE表包含SHP文件中每一个Feature的特征属性,表中几何记录和属性数据之间的一一对应关系是基于记录数目的ID。在dBASE文件中的属性记录必须和主文件中的记录顺序是相同的。图形数据和属性数据通过索引号建立一一对应的关系。

Shapefile中坐标文件(.shp)由固定长度的文件头和接着的变长度空间数据记录组成。文件头由100字节的说明信息组成,主要说明文件的长度、Shape类型、整个Shape图层的范围等等,这些信息构成了空间数据的元数据。在导入空间数据时首先要读入文件头获取Shape文件的基本信息,并以此信息为基础建立相应的元数据表。而变长度空间数据记录是由固定长度的记录头和变长度记录内容组成,其记录结构基本类似,每条记录都由记录头和记录内容组成(空间坐标对)。记录头的内容包括记录号(Record Number)和坐标记录长度(Content Length)两个记录项,Shapefile文件中的记录号都是从1开始的,坐标记录长度是按16位字来衡量的。记录内容包括目标的几何类型(ShapeType)和具体的坐标记录(X,Y),记录内容因要素几何类型的不同,其具体的内容和格式都有所不同。

属性文件(.dbf)用于记录属性信息。它是一个标准的DBF文件,也是由头文件和实体信息两部分构成。其中文件头部分的长度是不定长的,它主要对DBF文件作了一些总体说明,其中最主要的是对这个DBF文件的记录项的信息进行了详细的描述,比如对每个记录项的名称,数据类型,长度等信息都有具体的说明。属性文件的实体信息部分就是一条条属性记录,每条记录都是由若干个记录项构成,因此只要依次循环读取每条记录就可以了。

索引文件(.shx)主要包含坐标文件的索引信息,文件中每个记录包含对应的坐标文件记录距离坐标文件的文件头的偏移量。通过索引文件可以很方便地在坐标文件中定位到指定目标的坐标信息。索引文件也是由文件头和实体信息两部分构成的,其中文件头部分是一个长度固定(100 bytes)的记录段,其内容与坐标文件的文件头基本一致。它的实体信息以记录为基本单位,每一条记录包括偏移量(Offset)和记录段长度(Content Length)两个记录项。

KML全称是Keyhole Markup Language (KML),是一个基于XML语法和文件格式的文件,用来描述和保存地理信息如点、线、图片、折线并在Google Earth客户端之中显示(图2),(KML以前的版本能够被Google Earth读取并保存为KML 2.0) KML 2.0提供以下功能:

(1)指定一个地点的图标和标注来区分每一个地点

(2)为每一个视图指定明确的视角来创建不同的特写镜头

(3)使用指定到屏幕或地理位置的图片标注

(4)为特定种类的标注定义显示样式

(5)为标注指定基于简单HTML语法的描述,支持超级链接和图片的显示

(6)使用目录(folders)对标注进行树形的分类管理(为了便于理解和符合习惯,将"folder"翻译为"目录",实际上是代表一组地理标注,请谅解)

(7)基于时间戳记的标注可以用来进行动态的播放

(8)从本地或远程的网络地址动态的加载KML文件

图1

图2

2.课题研究的背景

2.1国内外研究现状

由于编辑XML文件并不复杂,只要懂编程就可以进行一些简单的KML文件编程。尽管如此,在网上还是很难找到关于KML文件编程的详细教程,一般都是一些基础性的说明文档,以GOOGLE官方说明文档居多。GE虽然很有名,但对普通用户来说,只要能使用GE软件进行一些基本的操作就够了,一般不涉及编程。而会编程的人员却不一定懂得GIS的开发,或是从事其它方面的软件开发,或是出于对软件知识产权的保护而不公开相关的开发代码和研究资料。所以就国内来说,本科生从事相关研究还是很少见的。

2.2 GE地标点的编程研究还未结束

随着Internet应用的普及,社会经济的发展,GIS的应用越来越广范。而GE正处于起步阶段,但发展很迅速,且KML文件已成为地理信息系统行业标准。从网上搜索来看,GE编程的资料还是偏少的。一般以其它文件格式转化为KML文件格式较常见,而KML格式转换为其它格式的资料几乎搜索不到。

2.3 课题的研究意义

(1)GE地标点文件的转换可以加快地理信息系统软件的开发和应用,使GIS软件开发模块化,GE地标点文件的编程转换可作为GIS软件的一个模块来运行。而KML文件已成为一种通用的数据格式,GE所产生的地标点数据是非常大的,如果能够转换,可以实现数据共享,促进地理信息系统的开发。

(2)研究此课题可更加深入的学习GIS相关的知识,为更深入的编程打下基础。

(3)做为大学学习的总结,提高自己的学习能力,实现自我价值

3.GE地标点文件概述

GE地标点文件是一种KML文件格式的文件。KML,是 Keyhole 标记语言(KeyholeMarkup Language)的缩写,是一种采用 XML 语法与格式的语言,用于描述和保存地理信息(如点、线、图像、多边形和模型等),可以被 Google Earth 和 Google Maps 识别并显示。KML是XML的一种派生语言,所以KML和XML语言的语言格式差不多。下面分别对XML文件和KML文件的格式做一简单的介绍。

3.1 XML文件格式简介

XML是可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Markup Language,标准通用标记语言)。XML是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据。XML文件格式如下:

<?xml version ="1.0" encoding="GB2312" standalone="yes" ?>

<?XML-stylesheettype="text/xsl" href="yxfqust.xsl" ?>

<!--以下是一个学生名单-->

<学生名单>

<学生>

<学号>0507079054〈学号〉  <姓名>朱明</姓名>

<班级>

05地理</班级>

</学生>

<学生>

</学生名单>

其中,文件头:<?xmlversion ="1.0" encoding ="GB2312"standalone="yes" ?>是XML文件的标记,“GB2312”是指文件的编码类型,除此外还有UTF8,ANSI,UNICODE等文件格式。而<*>里面的则是XML树里的节点。和XML格式相似,KML格式也有类似的结构。KML的格式如下:

<?xml version="1.0"encoding="UTF-8"?>

<kmlxmlns="http://www.opengis.net/kml/2.2" xmlnsx="http://www.google.com/kml/ext/2.2"

<Document>

<name>KmlFile</name>

……,省略部分代码
<href></href>

……,省略部分代码

<Placemark>

<name>兴国县社富乡(我的家乡)</name>

<description>社富乡是兴国县南部的一个边沿山区乡,位于兴国、于都、赣县三县交界处,东邻于都仙下乡和岭背镇,南界于都县贡江镇,西连赣县三溪乡和兴国县龙口镇,北接兴国县埠头乡和杰村乡。http://www1.xingguo.gov.cn/show.asp?id=9494</description>

<LookAt>

<longitude>115.3689541920244</longitude>,此为经度数据

<latitude>26.17239754751898</latitude>,纬度数据

<altitude>0</altitude>

<range>10173.49883527657</range>

<tilt>0</tilt>

<heading>-3.631742550437015</heading>

<altitudeMode>relativeToGround</altitudeMode>

</LookAt>

<styleUrl>#msn_ylw-pushpin</styleUrl>

<Point>,坐标点

<coordinates>115.3659223922057,26.16505347899991,0</coordinate>

</Point>

</Placemark>,标签

</Document>

</kml>

注意:“,”后面为注释部分.

其中<?xmlversion="1.0" encoding="UTF-8"?>是其文件头,其中的编码是UTF8格式。

中间<name>兴国县社富乡(我的家乡)</name>是地标点的名字,下面还包含文本,链接地址等。

<coordinates>115.3659223922057,26.16505347899991,0</coordinates>则是地标点所在地标。如果只有三个数据,则是个点文件,如果包含多个数据则是一个线或是轨迹和多边形,〈〉里面的都是KML的元素或标签。

3.2KML文件格式介绍

基本格式的KML文件是指可以直接由Google Earth创建的KML文件,它包括地点标记、叠层、路线和多边形,下面分别介绍。

3.2.1文件格式

(1) 地点标记(Placemarks)

上一节我们给出了一个地点标记(Placemarks)的示例。地点标记是Google Earth中最常用的地理特征,它使用一个黄色的图钉在地球表面标记一个位置。一个简单的地点标记的KML代码如下所示:

<?xml version="1.0"encoding="UTF-8"?>

<kmlxmlns="http://earth.google.com/kml/2.1">

<Placemark>

<name>Simpleplacemark</name>

<description>Attached to the ground.Intelligently places itself

at the height of the underlying terrain.

</description>

<Point>

<coordinates>-122.0822035425683,37.42228990140251,0</coordinates>

</Point>

</Placemark>

</kml>

它包括以下几个部分:

①XML头:<?xmlversion="1.0" encoding="UTF-8"?>

②KML命名空间定义:<kml xmlns="http://earth.google.com/kml/2.1">

③地点标记对象,包括:

名称(name):用于对地点标记进行注记。

描述(description):对地点标记进行描述,“气球(ballon)”中的显示内容。

点(Point):指定地点标记的位置。

(2)使用HTML描述地点标记

有两种方式来使用HTML描述地点标记,一种是直接在<description>,<Snippet>和<BalloonStyle>中的<text>标记中写入标准HTTP超链接地址,如www.google.com,这样Google Earth 4.0及更高版本将利用Auto-Markup技术自动把它显示为超链接。另一种是使用CDATA元素在<description>标记中写入自己的HTML标记语言,如下所示:

<?xml version="1.0"encoding="UTF-8"?><kmlxmlns="http://earth.google.com/kml/2.1">

<Document>

<Placemark>

<name>CDATA example</name>

<description>

<![CDATA]

<h1>CDATA Tags are useful!</h1>

<p><font color="red">Text is <i>morereadable</i> and

<b>easier to write</b> when you can avoid using entity

references.</font></p>

]]>

</description>

<Point>

<coordinates>102.595626,14.996729</coordinates>

</Point>

</Placemark>

</Document>

</kml>

当然,还有一种使用转义字符来表示特殊符号的方式,这就不需要CDATA元素,如下所示:

<?xml version="1.0"encoding="UTF-8"?><kmlxmlns="http://earth.google.com/kml/2.1">

<Document>

<Placemark>

<name>Entity references example</name>

<description>

&lt;h1&gt;Entity referencesare hard to type!&lt;/h1&gt;

&lt;p&gt;&lt;fontcolor="green"&gt;Text is

&lt;i&gt;more readable&lt;/i&gt;

and &lt;b&gt;easier to write&lt;/b&gt;

when you can avoid using entity references.&lt;/font&gt;&lt;/p&gt;

</description>

<Point>

<coordinates>102.594411,14.998518</coordinates>

</Point>

</Placemark>

</Document>

</kml>

(3)叠层

叠层是覆盖在地球表面的图像。一个简单的叠层KML代码如下所示:

<?xml version="1.0"encoding="UTF-8"?><kmlxmlns="http://earth.google.com/kml/2.1">

<Folder>

<name>GroundOverlays</name>

<description>Examples of groundoverlays</description>

<GroundOverlay>

<name>Large-scale overlay onterrain</name>

<description>Overlay shows Mount Etnaerupting on July 13th, 2001.</description>

<Icon>

<href>http://code.google.com/apis/kml/documentation/etna.jpg</href>

</Icon>

<LatLonBox>

<north>37.91904192681665</north>

<south>37.46543388598137</south>

<east>15.35832653742206</east>

<west>14.60128369746704</west>

<rotation>-0.1556640799496235</rotation>

</LatLonBox>

</GroundOverlay>

</Folder>

</kml>

在<GroundOverlay>中,它包含两个较新的标记:

<Icon>:指定图片的URL;

<LatLonBox>:指定图片的位置和范围。

Google Earth支持JPEG,BMP, GIF, TIFF, TGA和PNG等格式的图像。

(4)路线

在KML里面,路线由<LineString>元素来创建。如下所示:

<?xml version="1.0"encoding="UTF-8"?><kmlxmlns="http://earth.google.com/kml/2.1">

<Document>

<name>Paths</name>

<description>Examples of paths. Notethat the tessellate tag is by default     set to 0. If you want to create tessellated lines, they must beauthored      (or edited) directly inKML.</description>

<Styleid="yellowLineGreenPoly">

<LineStyle>

<color>7f00ffff</color>

<width>4</width>

</LineStyle>

<PolyStyle>

<color>7f00ff00</color>

</PolyStyle>

</Style>

<Placemark>

<name>AbsoluteExtruded</name>

<description>Transparent green wallwith yellow outlines</description>     <styleUrl>#yellowLineGreenPoly</styleUrl>

<LineString>

<extrude>1</extrude>

<tessellate>1</tessellate>

<altitudeMode>absolute</altitudeMode>

<coordinates>

-112.2550785337791,36.07954952145647,2357         -112.2549277039738,36.08117083492122,2357         -112.2552505069063,36.08260761307279,2357          -112.2564540158376,36.08395660588506,2357         -112.2580238976449,36.08511401044813,2357          -112.2595218489022,36.08584355239394,2357         -112.2608216347552,36.08612634548589,2357         -112.262073428656,36.08626019085147,2357          -112.2633204928495,36.08621519860091,2357         -112.2644963846444,36.08627897945274,2357          -112.2656969554589,36.08649599090644,2357

</coordinates>

</LineString>

</Placemark>

</Document>

</kml>

(5)多边形

多边形由<Polygon>定义,包括<outerBoundaryIs>和<innerBoundaryIs>,如下所示:

<?xml version="1.0"encoding="UTF-8"?><kmlxmlns="http://earth.google.com/kml/2.1">

<Placemark>

<name>The Pentagon</name>

<Polygon>

<extrude>1</extrude>

<altitudeMode>relativeToGround</altitudeMode>

<outerBoundaryIs>

<LinearRing>

<coordinates>

-77.05788457660967,38.87253259892824,100            -77.05465973756702,38.87291016281703,100            -77.05315536854791,38.87053267794386,100            -77.05552622493516,38.868757801256,100            -77.05844056290393,38.86996206506943,100             -77.05788457660967,38.87253259892824,100

</coordinates>

</LinearRing>

</outerBoundaryIs>

<innerBoundaryIs>

<LinearRing>

<coordinates>

-77.05668055019126,38.87154239798456,100            -77.05542625960818,38.87167890344077,100            -77.05485125901024,38.87076535397792,100            -77.05577677433152,38.87008686581446,100            -77.05691162017543,38.87054446963351,100            -77.05668055019126,38.87154239798456,100

</coordinates>

</LinearRing>

</innerBoundaryIs>

</Polygon>

</Placemark>

</kml>

3.2.2 语法规则

和任何程序语言与脚本语言一样,KML有一些必须遵循的语法规则。

文档结构  一个KML文档应该完全遵循KML格式,文档也和基本的XML语法规则差不多,有以下几点要特别注意的地方。

XML标签必须关闭,XML标签是大小写敏感的。对于KML语法,首字母大写的标签是复合标签,否则就是单一标签,在实体和标签介绍之中有更多相关信息。XML标签必须正确嵌套XML文档,必须只有一个根标签对于KML文件,这意味着你可以使用<kml></kml>, <Document></Document><Folder></Folder>甚至 <Placemark></Placemark>作为根标签属性,必须用引号包围起来,CR/LF(回车符)被认为是插入一个新行(在HTML描述之中,被转化为<br>) 。

XML的注释方法和HTML是一样的,要了解更多信息,可以去查阅XML参考文档或语法向导。如果你的KML文档结构不符合XML文档规范,将会在Google Earth中产生一个解析错误的对话框 (查看http://www.w3.org/XML/了解根多关于XML的信息。) 注意: XML Schema 验证还没有被Google Earth支持。

标记类型  有两种基本的KML标记类型: 单一标签和复合标签。复合标签的标签名首字母是大写的,而单一标签都是小写的,复合标签能够作为其他标签(单一标签或复合标签)的父元素,而单一标签只能是其他复合标签的子元素,而自身不能包含其他元素。

字符串  在KML文件中的任何字符串,例如 name 和 description标签中的值,都可以是utf-8或者Unicode编码的字符串。

KML标签列表这一节包含所有能用的KML标签的参考,按字母顺序排列,每一段列出了该标签正确的大小写格式,类型、值和层次(省略)。

KML标签列表:

<address> <altitudeMode> <begin> <color><coordinates> <description> <Document> <drawOrder><east> <end> <extrude> <fill> <Folder><geomColor> <GeometryCollection> <geomScale><GroundOverlay> <h> <heading> <href> <Icon><IconStyle> <innerBoundaryIs> <labelColor> <latitude><LatLonBox> <LinearRing> <LineString> <longitude><LookAt> <name> <NetworkLink> <north><ObjArrayField> <ObjField> <open> <outerBoundaryIs><outline> <overlayXY> <Pair> <parent> <Placemark><Point> <Polygon> <PolyStyle> <range><refreshInterval> <refreshVisibility> <rotation><Schema> <scale> <ScreenOverlay> <screenXY> <SimpleArrayField><SimpleField> <size> <south> <snippet> <Style><StyleMap> <styleUrl> <tessellate> <tilt><TimePeriod> <TimeInstant> <timePosition> <type><href> <Url> <viewRefreshMode> <viewRefreshTime><visibility> <w> <west> <x> <y>

4.编程实现Shapefile文件向KML文件的转换

4.1 编程实现的理论

目前,大量的空间数据都是以特定的文本数据格式进行存储的,最常见的GIS数据格式包括ArcInfo公司的Shp文件,MapInfo公司的Mif文件等等。根据GML3规范中Schema的描述、Shp文件和Mif文件的格式,就能将Shp文件和Mif文件转换为KML文件。在转换过程中,首先要创建一个KML格式文档,添加KML描述信息,然后循环将Shp或者Mif文件中的地理信息元素转换为KML中的几何图元。

实现Shapefile格式数据到KML格式数据的转换过程可分为两个大步骤,一是依据Shapefile数据文档资料获取数据,二是依据KML标准构建KML格式数据。从上面对shapefile数据格式和KML格式的分析可知,对shapefile的文档资料的获取主要是读取坐标文件和属性文件,根据dbf的字段信息描述创建相应的Schema文件,将dbf的字段名作为Feature元素的孩子节点,根据shp文件存储的几何类型选取KML的Geometry定义的标记作为其标记。构建KML的过程就是将读取的shapefile数据以KML的格式存储起来。

ArcGIS的地图数据分为3个文件进行存储,即

1) shp文件:主要存储几何数据,它有自己的专有格式,具体的格式可以参看ShapeFile的技术白皮书,可以通过ArcInfo提供的组件来读取,转换为内存中的几何对象。一般一个shp文件表达了一个图层的几何数据。

2) dbf文件:存储相对应的shp文件的属性数据。

3) shx文件:连接shp文件中空间数据和dbf文件中的属性数据。

以上三种文件是Shapefile文件所必需的文件,而其他如sbn,sbx,fbn,xml等是可选文件。在ShapeFile文件中,dbf记录的属性数据是完全按照顺序记录的,而几何数据是有变化的,需要通过shx索引文件中的偏移量,来获得与属性表中的每条相应的几何记录在shp文件中的偏移量,即空间数据和属性数据的对应要依靠shx索引文件计算偏移量。ShapeFile文件的几何类型与KML中的元素之间的对应关系见表1。

转换规则如下:

1)  Point类型的转换:ShapeFile文件的Point类型转化为KML文件中的Point类型,Point类中包含的x,y属性,直接对应写入KML的Point元素的coordinates标签。

2)  Polyline类型的转换:ShapeFile文件中的Polyline类型是一个Path的集合。一个Path由一系列的点连接而成,它还不完全等价于KML中的LineString。一个Path又是一个Segment的集合,Segment是2个点之间的一种连接,最简单的是直线,还有可能是Bezier曲线或者其他曲线,可以把Path看作一个LineString。在转换时,如果Polyline只包括一个Path,就转为Linestring,通过把该Path转换为PointCollection,得到该Path的节点坐标,写入LineString的coordinates标签。

3)  Polygon类型的转换:ShapeFile文件中的Polygon和KML的Polygon元素定义不完全相同,因为ShapeFile文件中的Polygon允许有多个外环,所以如果它的ExteriorRingCount数目为1,就把它转为一个Polygon元素,其中,外环的坐标序列别写入<outerBoundaryIs><LinearRing>的coordinates标签。如果有内环的话,写入<innerBoundaryIs><LinearRing>的coordinates标签。

转换步骤如下:

首先,定义一个新的ShapefileInfo类,利用该类获取Shapefile文件中数据类型的描述信息、记录数信息,并存放在一个temp向量中。接着存入temp向量的还有DBF文件中的字段名、字段类型、字段描述信息,ShapefileInfo类中的坐标范围、字段个数、记录个数、字段的长度信息。最终存入temp向量的是SimpleClassData类,包含Shapefile类型描述、空间数据配色表与文件名信息。至此,数据的解析过程就算结束,接下来,要进行KML文档的构建。

Shape文件是按照地物类型来组织的。地物类型可以分为简单的点(Point)、线(Line)、面(Polygon)三种类型,一个Shape文件中只能包括一种类型的地物,即只能包括点、线或者面状地物中的一种。对于点、线、面三种类型,构建KML数据的流程如下所示。

第一步,生成一个后缀为KML的文件,写入XML的声明。第二步,从temp向量中获取KML数据的坐标范围,并且定义FeatureMember标记。第三步,依据FeatureMember判断出数据的类型。根据数据的类型调用不同的构建过程。对于点、线、面,其具体的构建过程基本相似,下面以线为例进行探讨。如果是线,那么写入LineString标记,同时构建当前线元素。此时,重复以上判断,当完成SHP数据中所有类型的数据转换之后,将这几种类型的KML标记整合到一个KML文件中,SHP数据到KML数据的转换便成功完成。

4.2编程实现的过程

1)实现的准备阶段

分析KML文件的结构和特点,发现其数据结构是以树的形式来存储的,而KML文件也是一种派生的XML文件。以ArcGIS中的VBA语言为平台对数据格式进行转换,而且COM对象中也有Microsoft提供的XML对象,可供VBA调用。除此之外,KML还可以用记事本程序编辑,可作为一种txt文档或Word文档进行处理,这时就可以运行txt文档处理的相关技术。处理文字的利器是正则表达式,用正则表达式提取出满足一定条件的数据。如:<longitude>-122.0839</longitude>-122.0839</longitude>

可用正则表达式搜索。除了用正则表达式外,还可以采用文本分割的方式,找一个分割标记,如<longitude>为分割标记,把文本分成三部分,中间部分-122.0839则是要取出的数据。

2) 程序的实现阶段

如果你精通一门语言,你很快就能理解。各种编程语言其实在语法上是差不多的,无论是C语言,Delphi, VB语言还是易语言都各有特色。但其共同点就是:面向对象的可视化编程。而且每种语言都提供了不同的函数以实现不同的功能,这些都可抽象为一种接口。使用这种面向对象的编程方法可以节省很多时间,减少重复的代码。

KML语法的灵活性,使得KML文件中的标签组织结构并不是固定的。简单的KML只有少许标签,主要包含名字,经度,纬度,和坐标,且每一标签都是唯一的。但复杂的KML文件里则包含多个名字,多个点,甚至包含线条,多边形,轨迹点的形式,这样每个标签就不是单一的结构。采用处理文本的方式无疑增加了难度。我们不能只开发能读取和转换一部分格式的程序,否则就不能被广范使用。编码的问题,由于生成KML的方式不同导致有两种编码:UTF8和ANSI。如果你搜索到名字为乱码,可以换一种编码模式搜索。地标点,轨迹点(路径),多边形,暂只可转换多边形文件,其实转换点状和线状也不难,但程序结构更加复杂。只要搜索<coordinates>(.*?)</coordinates>标签,然后用“,0”来分割文本,放入数组再循环显示出来就可以了。

5.核心代码部分

SubShapefileTOkml()

DimpMx As IMxDocument

SetpMx = ThisDocument

DimpFL As IFeatureLayer

SetpFL = pMx.FocusMap.Layer(1)

LayerName= pFL.Name

m_strAltitudeMode= "clampedToGround"

Dimpfc As IFeatureClass

Setpfc = pFL.FeatureClass

DimpQF As IQueryFilter    '查询过滤器

SetpQF = New QueryFilter

pQF.WhereClause= ""

DimpSRF As ISpatialReferenceFactory2  '空间系统厂,类似于工作空间厂

SetpSRF = New SpatialReferenceEnvironment

DimpGCS As IGeographicCoordinateSystem

SetpGCS = pSRF.CreateGeographicCoordinateSystem(esriSRGeoCS_WGS1984)

DimpGeodataset As esriGeoDatabase.IGeoDataset

Set pGeodataset = pFL

Dimpsr As IProjectedCoordinateSystem '定义为投影坐标

Setpsr = pSRF.CreateProjectedCoordinateSystem(102008)'esriSRProjCS_NAD1983N_AmericaAlbers,North America Albers

Dimm_pSpRefInput As ISpatialReference

Set m_pSpRefInput =pGeodataset.SpatialReference

Dim m_pSpRefOutput As ISpatialReference

Set m_pSpRefOutput = pGCS

m_pSpRefOutput.SetFalseOriginAndUnits -180,-90, 1000000

SetpMx.FocusMap.SpatialReference = psr

Dimpfcur As IFeatureCursor

Setpfcur = pfc.Search(pQF, True) '第二个参数表示是否回收记录占用的内存,false表示不回收,当目的是更新和插入时,内存不回收

Dimpf As IFeature

Setpf = pfcur.NextFeature

Open"G:\GXM\Aster.kml" For Output As #1

Print#1, "<?xml version=""1.0""encoding=""UTF-8""?>"

Print#1, "<kml xmlns=""http://earth.google.com/kml/2.2"">"

Print#1, "<Document>"

Print#1, "  <name>" &"GE.kml" & "</name>"

Print#1, " <open>1</open>"

Print#1, "  <SnippetmaxLines=""2""></Snippet>"

Print#1, " <styleUrl>#clean_balloon</styleUrl>"

Print#1, "  <Style id=""clean_balloon"">"

Print#1, "    <BalloonStyle>"

Print#1, "      <description>"

Print#1, "        In Google Earth, enablehistorical imagery and sunlight,"

Print#1, "          then click on eachplacemark to fly to that point in time"

Print#1, "      </description>"

Print#1, "    </BalloonStyle>"

Print#1, "  </Style>"

Print#1, "   <Folder>"

Print#1, "       <Placemark>"

Print#1, "         <name>"& "Feature" & "</name>"

Print#1, "         <SnippetmaxLines=""2""></Snippet>"

Print#1, "         <styleUrl>#" &"#FEATURES" & "</styleUrl>"

Print#1, "        <ExtendedData>"

Print#1, "           <SchemaDataschemaUrl=""#"; "_schema""" & ">

Print #1, "           </SchemaData>"

Print #1, "         </ExtendedData>"

Print #1, "         <TimeSpan>"

Print #1, "           <begin>" & Now &"</begin>"

Print #1, "           <end>" & Now &Time & "</end>"

Print #1, "         </TimeSpan>"

Print#1, "         <Polygon>"

Print #1, "           <extrude>" & 0 &"</extrude>"

Print #1, "           <altitudeMode>" &m_strAltitudeMode & "</altitudeMode>"

Print#1, "          <outerBoundaryIs>"

Print#1, "          <LinearRing>"

Print#1, "             <coordinates>"

DimstrXYZCoordinates(10000) As String

c= 0

Dimm_strXCoord As String

Dimm_strYCoord As String

Dimm_strZCoord As String

DimpPoly As IPolygon

DoUntil pf Is Nothing

Setpf = pfcur.NextFeature

Ifpf.Shape.GeometryType = esriGeometryPolygon Then

Set pPoly = pf.Shape

m_strXCoord = pPoly.FromPoint.X

m_strYCoord = pPoly.FromPoint.Y

m_strZCoord = pPoly.FromPoint.Z

EndIf

strXYZCoordinates(c) = m_strXCoord &"," & m_strYCoord & "," & m_strZCoord

Print #1, "               " &strXYZCoordinates(c)

c = c + 1

Set pf = pfcur.NextFeature

Loop

Print#1, "           </coordinates>"

Print#1, "        </LinearRing>"

Print#1, "           </outerBoundaryIs>"

Print#1, "         </Polygon>"

Print#1, "       </Placemark>"

Print#1, "   </Folder>"

Print#1, " </Document>"

Print#1, " </kml>"

EndSub

【程序测试】

开发环境:WINDOWS  XP SP2,CPU 2.8G, 内存4GB

运行环境:WINDOWS  2000以上, 内存512MB以上 基于ArcGIS中的VBA平台(数据为ArcGIS中自带的country.shp数据)

【参考文献】

1.曹礼刚,王绪本.空间数据转换与考古数据探测WebGIS.计算机工程(

Computer Engineering).2007,33(18)

2. ShapeFile文档技术白皮书[Z]. (2006-08-14). http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf

3. CSDN博客

http://blog.csdn.net/carlbiao/archive/2009/01/02/3685728.aspx

http://blog.csdn.net/suen/archive/2007/07/05/1679983.aspx

4. Google Earth官方网站

http://earth.google.com/

5. 中国XML编程站

http://www.xml.org.cn/index.html

6. GIS帝国论坛

http://www.gisempire.com/bbs/

7. 地理信息系统论坛社区

http://www.gisforum.net/bbs/

ESRI的Shapefile文件向Google Earth中KML文件的格式转换相关推荐

  1. 用户id可以出现在url中吗_下载Google Drive中的文件

    通过Python下载Google Drive中的文件的代码如下: download_googledrive.py import

  2. java遍历给定目录,树形结构输出所有文件,包括子目录中的文件

    http://www.cnblogs.com/jenson138/p/4691418.html import java.io.File;public class ReadDirectory {// 文 ...

  3. android 读写文件 简书,Android 中的文件操作

    Android 文件操作 概述 Android 中的文件操作主要涉及到两个部分,一个是内部存储的读写,一个是外部存储的读写两者的主要区别如下表: 内部存储 外部存储 始终可用 它并非始终可用,因为用户 ...

  4. linux查找文件模糊名字,linux中模糊查找文件

    1.在当前目录下搜索指定文件: find . -name test.txt 2.在当前目录下模糊搜索文件: find . -name '*.txt' 3.在当前目录下搜索特定属性的文件: find . ...

  5. java date 转integer_java 中Date的各种格式转换

    把java.util.Date格式的时间转为java.sql.Date格式的时间 java.sql.Date sqldate = new java.sql.Date(date.getTime()); ...

  6. python日期格式转换_python中有关时间日期格式转换问题

    每次遇到pandas的dataframe某列日期格式问题总会哉坑,下面记录一下常用时间日期函数.... 1.字符串转化为日期 str->date import datetime date_str ...

  7. 如何在谷歌地球上画路线或者运动轨迹?根据纬经高信息在谷歌地球Google earth中画运动轨迹,首先将Excel文件纬经高信息转换为.csv文件,再转换为.kml文件,最终在谷歌地球中显示。

    (制作运动轨迹的前提是装有谷歌地球和CSV2kml转换工具, CSV2kml转换工具的下载可在下列链接中下载https://download.csdn.net/download/howe1233/10 ...

  8. google earth中显示点云

    最近,在想办法将点云数据显示在google earth界面上,今天摸索出一种方法----即以海量点标记的形式表示点云,每个点标记的图标采用圆点形式(默认情形下google earth的点标记图标为黄色 ...

  9. Google earth中的jpg格式转成论文需要的固定宽度tiff格式的方法

    在论文中我们可能会需要通过图片表示数据采集方位,但是我发现google earth pro中的导出的图片只能获得jpg格式,同时不方便进行宽度设置 但是很多期刊只接受固定宽度的图片,格式一般也要求ti ...

最新文章

  1. wget,curl 下载文件
  2. 多角度回顾因果推断的模型方法
  3. pytorch attention 注意力
  4. 想一下,最大公约数怎么求
  5. 2的32次方减1用python,第二章python入门
  6. 图片适应窗口_在word中插入图片,如何避免失真模糊?实用文档建议收藏
  7. 智能音箱音效哪个好_华为支浩:音质好是底线,AI基本功扎实让智能音箱不再是“玩具”...
  8. js中的鼠标右键点击事件
  9. 区块链和比特币的 6 个神话:揭穿了这项技术的有效性
  10. 【狂人小白】MyBatis.001 学习巴提斯!
  11. 重启路由器可以换IP吗
  12. python在冒号处显示语法错误_python for常见语法错误
  13. PPT创作技巧及有用素材
  14. 附录1. DXF组码说明
  15. Mediasoup之RateCalculator(流量统计)
  16. 如何使用python制作一款屏幕颜色提取器,附带exe文件
  17. Unity3d 利用 AvproVideo 播放带透明通道mov视频在部分电脑无法播放的解决方案
  18. 瓦工 -- 叫我怎么相信你
  19. 70-webApp打包:将网站利用hbuilder打包为安卓app
  20. 密歇根安娜堡大学计算机专业硕士,2020年密歇根大学安娜堡分校硕士专业设置...

热门文章

  1. 《计算机系统结构》期末复习
  2. spark 项目应用-topn搜索热词统计
  3. 笑话与趣图微信小程序源码_带广告流量主
  4. 记报错信息:java.lang.IllegalArgumentException: MALFORMED解决方案
  5. html如何设置页脚,如何将HTML页眉和页脚添加到页面?
  6. 模拟电路系列分享-负反馈电路稳定性分析
  7. GOOGLE ADSENSE广告联盟收不到PIN码_快速表单身份验证PIN码方法
  8. 亚马逊MWS开发--商品变体
  9. 联咏 Nt9832x Uboot升级all-in-one流程
  10. 使用IDEA和Maven整合SSH