高级 KML 文档
本段描述了部分必须用文本编辑器编写的 KML 元素,如几何图形的共享样式、地标的突出显示图标和屏幕叠加层。手动编写 KML 比用 Google 地球界面创建和修改地图项略微难一些,但只需稍加练习,多数用户都能自如地编辑 KML 文件以添加这些效果。
几何图形样式
在 Google 地球中创建地图项并检查了 Google 地球生成的 KML 代码后,您会注意到样式是您数据显示方式中多么重要的一部分。高级用户可能希望学习如何定义他们自己的样式。
如果您在 KML 文档开始处定义了样式,并定义了它的 ID,就可以在文档其他地方定义的几何图形、地标和叠加层中使用该样式。因为可有多个元素使用同一个样式,以这种方式定义和使用的样式称为共享样式。只需定义给定样式一次,即可用 <styleUrl> 元素多次引用它。如果样式定义于同一文件内,请在样式 ID 前加 # 号<styleUrl>#transBluePoly</styleUrl>。如果样式定义于外部文件中,请在 <styleUrl> 元素中包含完整的 URL。
KML Samples 文件包含许多共享样式,每一个都在文件开始处用 ID 定义。请注意,如果您的 ID 是描述性的字符串,您可以很容易判断其作用,就会很方便。以下是一个样式的示例 ("transBluePoly"),它定义多边形面为透明蓝色,多边形边缘线宽 1.5,使用默认的白色。Google 园区 41 号楼的示例会使用该样式(在 Polygons 文件夹中):
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<Style id="transBluePoly">
<LineStyle>
<width>1.5</width>
</LineStyle>
<PolyStyle>
<color>7dff0000</color>
</PolyStyle>
</Style> <Placemark>
<name>41 号楼</name>
<styleUrl>#transBluePoly</styleUrl>
<Polygon>
<extrude>1</extrude>
<altitudeMode>relativeToGround</altitudeMode>
<outerBoundaryIs>
<LinearRing>
<coordinates> -122.0857412771483,37.42227033155257,17
-122.0858169768481,37.42231408832346,17
-122.085852582875,37.42230337469744,17
-122.0858799945639,37.42225686138789,17
-122.0858860101409,37.4222311076138,17
-122.0858069157288,37.42220250173855,17
-122.0858379542653,37.42214027058678,17
-122.0856732640519,37.42208690214408,17
-122.0856022926407,37.42214885429042,17
-122.0855902778436,37.422128290487,17
-122.0855841672237,37.42208171967246,17
-122.0854852065741,37.42210455874995,17
-122.0855067264352,37.42214267949824,17
-122.0854430712915,37.42212783846172,17
-122.0850990714904,37.42251282407603,17
-122.0856769818632,37.42281815323651,17
-122.0860162273783,37.42244918858722,17
-122.0857260327004,37.42229239604253,17
-122.0857412771483,37.42227033155257,17 </coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
请注意,<StyleUrl> 元素是 <Placemark> 的子元素(而不是它影响的几何图形的子元素)。
突出显示图标的样式
该文档定义两种样式,一种用于 "normalPlacemark",另一种用于 "highlightPlacemark"(光标在图标上滚动时显示)。<StyleMap> 元素有两个将每个图标样式映射到图标状态的键/值对。有两种图标状态:普通和突出显示。
这里所示的基本步骤如下:
- 为地标的普通图标定义 <Style>,并为它分配 ID(此处是 "normalPlacemark")。 <Style> 包含一个 <Icon>,并带有对使用的实际图像的 <href>,如下所示。
- 为地标的突出显示图标定义 <Style>,并为它分配 ID(此处是 "highlightPlacemark")。
- 创建 <StyleMap> 元素,并为它分配 ID ("exampleStyleMap")。地标将指向该 ID。
- 在 <StyleMap> 元素中,为普通状态指定 "#normalPlacemark"。
- 在 <StyleMap> 元素中,为突出显示状态指定 "#highlightPlacemark"。
- 在地标中添加指向 "#exampleStyleMap 的 <styleUrl> 元素。
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<name>突出显示的图标</name>
<description>请将您的鼠标置于图标之上,以观察它显示新图标</description>
<Style id="highlightPlacemark">
<IconStyle>
<Icon>
<href>http://maps.google.com/mapfiles/kml/paddle/red-stars.png</href>
</Icon>
</IconStyle>
</Style>
<Style id="normalPlacemark">
<IconStyle>
<Icon>
<href>http://maps.google.com/mapfiles/kml/paddle/wht-blank.png</href>
</Icon>
</IconStyle>
</Style>
<StyleMap id="exampleStyleMap">
<Pair>
<key>normal</key>
<styleUrl>#normalPlacemark</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#highlightPlacemark</styleUrl>
</Pair>
</StyleMap>
<Placemark>
<name>在图标上滚动</name>
<styleUrl>#exampleStyleMap</styleUrl>
<Point>
<coordinates>-122.0856545755255,37.42243077405461,0</coordinates>
</Point>
</Placemark>
</Document>
</kml>
屏幕叠加层
屏幕叠加层(对屏幕来说的叠加)<ScreenOverlay>无法直接在 Google 地球中编写,因此比地面叠加层(对地图来说的经纬度叠加)更难于创建。KML Samples 文件的中的 Screen Overlays 文件夹中包含丰富的示例。
作为示例,在 KML Samples 文件中启用“Absolute Positioning: Top left”文件夹,您就会在视图窗口左上角看到屏幕叠加层。它是由以下 KML 代码创建的:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<ScreenOverlay>
<name>绝对定位:左上角</name>
<Icon>
<href>http://code.google.com/apis/kml/documentation/top_left.jpg</href>
</Icon>
<overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
<screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
</ScreenOverlay>
</kml>
叠加层的定位是通过将用 <overlayXY> 指定的图像中的点映射到用 <screenXY> 指定的屏幕上的点来控制的。在这种情况下,图像左上角 (0,1) 与屏幕的同一点重合。
请检查该文件夹中的其他示例,看看可以如何获取其他固定位置,并创建大小随屏幕大小动态调整的图像。(请注意,xunits 和 yunits 也可以按“像素”指定,以便精确控制。)进一步的详细信息请参见 KML 2.2 参考。
网络链接
网络链接包含用于加载文件且带有 <href>(超链接引用)的 <Link> 元素。<href> 可指定为本地文件或绝对 URL。除了名称外,<NetworkLink> 不需要从网络加载文件。
链接中的 <href> 可指定以下任意对象的位置:
- 图标使用的图像文件,用于图标样式、地面叠加层和屏幕叠加层
- <Model> 元素中使用的模型文件
- 网络链接加载的 KML 或 KMZ 文件
指定的文件可以是本地文件,也可以是远程服务器上的文件。网络链接的最简单形式是将一个大的 KML 文件分割为同一台计算机上较小且更易于管理的多个文件。
到目前为止,我们的所有示例都要求从本地计算机将 KML 代码提供给 Google 地球。网络链接使您能从远程计算机提供内容,并且常用于向大量用户分发数据。用这种方式分发数据,如果需要修改数据,只需在源位置修改,所有用户就会自动收到更新后的数据。
KML 的 CGI 脚本
除了指向包含静态数据的文件外,网络链接的 <href> 可指向动态生成的数据—例如由网络服务器上 CGI 脚本生成的数据。如果您有 PHP、Python 或 Perl 之类脚本语言的知识,就可以创建将 KML 数据流(或文件)传递到每个网络链接的脚本。
通过网络 CGI 传递 KML 时,有两件事是必须的:
从客户端(Google 地球)调用至服务器时,服务器必须
(1) 返回响应代码 HTTP 200 并且
(2) 设置响应的内容类型为 text/plain
或 application/vnd.google-earth.kml+xml.
响应必须是有效的 KML。对于复杂的应用程序,对错误进行正确的处理非常重要。
提示:处理错误的简单途径是将服务器的错误语法解析为文件夹名称的文本。
例如,您可以让服务器返回<Folder><name>无法连接服务器</name></Folder>
的字符串。这比让连接断开提供了更多信息,对用户也更友好。
以下示例使用 Python,但它们在任何其他脚本语言中也同样有效。
生成随机地标
以下 Python 脚本生成纬度和经度的随机整数值,然后将那些值插入 <Point> 的 <coordinates> 元素中。每当网络链接刷新时,Python 脚本将再次运行,用新的经纬度值生成 KML。
#!/usr/bin/python import random latitude = random.randrange(-90, 90) longitude = random.randrange(-180, 180) kml = ( '<?xml version="1.0" encoding="UTF-8"?>\n' '<kml xmlns="http://earth.google.com/kml/2.2">\n' '<Placemark>\n' '<name>随机地标</name>\n' '<Point>\n' '<coordinates>%d,%d</coordinates>\n' '</Point>\n' '</Placemark>\n' '</kml>' ) %(longitude, latitude) print 'Content-Type: application/vnd.google-earth.kml+xml\n' print kml
以下是包含加载该 Python 脚本的网络链接的 KML 文件示例:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Folder>
<name>网络链接</name>
<visibility>0</visibility>
<open>0</open>
<description>网络链接示例 1</description>
<NetworkLink>
<name>随机地标</name>
<visibility>0</visibility>
<open>0</open>
<description>每次调用时生成新的随机
地标的简单服务器端脚本</description>
<refreshVisibility>0</refreshVisibility>
<flyToView>0</flyToView>
<Link>
<href>http://您的服务器.com/cgi-bin/randomPlacemark.py</href>
</Link>
</NetworkLink>
</Folder>
</kml>
基于视图刷新查询
标准网络链接是单向链接:数据只从服务器流向 Google 地球。基于视图的刷新允许进行双向通讯。激活基于视图的刷新时,Google 地球会在指定时间将视图坐标返回给服务器。这一指定时间可以是每 n 秒、分钟、小时或视图停止移动后经过的一段时间。请参见 KML 2.2 参考中的 <viewRefreshMode>。
坐标以如下附加坐标的 HTTP GET 方式返回给服务器(这是默认的边框信息):
GET /path/to/sever/script/query?BBOX=[longitude_west, latitude_south, longitude_east, latitude_north] HTTP/1.1
如果用户俯瞰旧金山时发出请求,坐标可能看上去如下:
GET /path/to/server/script/query?BBOX=-122.497790,37.730385,-122.380087,37.812331 HTTP/1.1
该功能可以有一些很富创意的应用,但是为帮助您入门,下面只提供了一个简单的示例。
跟踪正位于您视图下的点
以下服务器端 Python 脚本会对 Google 地球发送的返回消息进行语法分析,并用屏幕中心的地标作为响应。每次刷新网络链接时,都会生成新的地标。
#!/usr/bin/python import cgi url = cgi.FieldStorage() bbox = url['BBOX'].value bbox = bbox.split(',') west = float(bbox[0]) south = float(bbox[1]) east = float(bbox[2]) north = float(bbox[3]) center_lng = ((east - west) / 2) + west center_lat = ((north - south) / 2) + south kml = ( '<?xml version="1.0" encoding="UTF-8"?>\n' '<kml xmlns="http://earth.google.com/kml/2.2">\n' '<Placemark>\n' '<name>视图居中地标</name>\n' '<Point>\n' '<coordinates>%.6f,%.6f</coordinates>\n' '</Point>\n' '</Placemark>\n' '</kml>' ) %(center_lng, center_lat) print 'Content-Type: application/vnd.google-earth.kml+xml\n' print kml
以下是加载 Python 脚本的网络链接的 KML:重点
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Folder>
<name>网络链接</name>
<visibility>0</visibility>
<open>0</open>
<description>网络链接示例 2</description>
<NetworkLink>
<name>视图居中地标</name>
<visibility>0</visibility>
<open>0</open>
<description>基于视图的刷新允许远程服务器计算
屏幕中心并返回地标。</description>
<refreshVisibility>0</refreshVisibility>
<flyToView>0</flyToView>
<Link>
<href>http://您的服务器.com/cgi-bin/viewCenteredPlacemark.py</href>
<refreshInterval>2</refreshInterval>
<viewRefreshMode>onStop</viewRefreshMode>
<viewRefreshTime>1</viewRefreshTime>
</Link>
</NetworkLink>
</Folder>
</kml>
该示例中所示原理可用于一些很复杂的应用。例如,如果您有地理信息数据库,可提取观察者坐标,从数据库调用该视图专有数据,以 KML 形式返回给 Google 地球。
KML MIME 类型
响应来自 Google 地球(或任何 Google 地球浏览器)的请求时,KML 服务器必须遵循特定的一组规则,以便 Google 地球能正确解释其响应。
成功后,服务器必须返回响应代码 HTTP 200,并设置响应的内容类型为合适的 MIME 类型,如这里所述。
Google 地球将读取 KML 和 KMZ 文件。
KML 文件的 MIME 类型是
application/vnd.google-earth.kml+xml
KMZ 文件的 MIME 类型是
application/vnd.google-earth.kmz
对 Apache,将以下行添加到 httpd.conf 文件:
AddType application/vnd.google-earth.kml+xml .kml
AddType application/vnd.google-earth.kmz .kmz
关于在 Microsoft 的 IIS 上设置 MIME 类型的详细信息,请参见 Microsoft 文档。
响应的正文必须包含有效的 KML 数据,包括 XML 声明 (<?xml version="1.0" encoding="UTF-8"?>
)。如果服务器返回无效的 KML,网络链接将停止、停用,并输出错误消息。