7.3. 使用矢量KML

KML(Keyhole标记语言)由于与Google Earth和Google Maps的关联,是一种流行的矢量GIS特性格式。KML只是根据一个开放规范格式化的XML,以前由Google维护,但现在已经包含在OGC标准中。尽管KML可以定义栅格图层的位置,但在本课程中我们将重点介绍矢量KML。

KML后面的关键XML标记是placemark。这定义了一个地理特征、一个符号和可以在弹出窗口中显示的额外信息。如果保存example KML file 在文本编辑器中打开它。这不是最干净的文件,但它可以用于查看placemark:

<Placemark>
       <name>Sundial, Plymouth, Devon, UK</name>
               <description><![CDATA[The gnonom is 27 foot high, the pool has 21 feet diameter.  It was designed by architect Carole Vincent from Boscastle in Cornwall and was unveiled by Her Majesty the Queen on Friday July 22nd 1988 for a cost of  cost £70,000 . The sundial runs one hour and seventeen minutes behind local clocks.
    <img src="http://www.photoready.co.uk/people-life/images/sundial-fountain.jpg">
    Image source:<a href="www.photoready.co.uk</a>]]>
           </description>
       <LookAt>
          <longitude>-4.142398271107962</longitude>
          <latitude>50.37145390235462</latitude>
          <altitude>0</altitude>
          <range>63.33410419881957</range>
          <tilt>0</tilt>
          <heading>-0.0001034131369701296</heading>
       </LookAt>
       <styleUrl>#msn_sunny_copy69</styleUrl>
       <Point>
          <coordinates>-4.142446411782089,50.37160252809223,0</coordinates>
       </Point>
    </Placemark>

这个特殊的地点标记只有一个坐标,包含在点标记中。对于多段线和多边形,将分别使用LineString和Polygon标记,尽管这些标记不会出现在上面的示例中。

注意,Description标记可以包含HTML,这使您可以更好地控制弹出窗口的格式。完整的KML文件比上面的代码片段长得多,因为它包含许多点和描述。

Leaflet doesn't offer a way to read KML directly. This is an area where OpenLayers holds an advantage. However, Mapbox has produced a free Leaflet plugin called Omnivore that makes it fairly simple to read in vector file types, including KML. First you need to put a reference to Omnivore in a script tag at the top of your page. You could reference it from a CDN like this:

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-omnivore/0.3.4/leaflet-omnivore.js"></script>

然后可以在层中引用KML,如下所示:

var runLayer = omnivore.kml('sundials.kml')
  .on('ready', function() {
    map.fitBounds(runLayer.getBounds());

    runLayer.eachLayer(function(layer) {
      layer.bindPopup(layer.feature.properties.description);
    });
  })
  .addTo(map);

需要注意的一点是,Omnivore在显示KML之前将其转换为GeoJSON格式(有关GeoJSON的更多信息,请参阅本课的下一节)。因此,地图可能无法显示最初在KML中定义的所有样式。如果你的KML包含了一些点的自定义图片符号,你将需要编写 Leaflet 代码来将该图片应用于标记。但是,请注意,上面的代码确实引入了KML描述,并在弹出窗口中应用了该文本。这是使用层上的bindPopup方法实现的。

再说一遍,不要担心记住所有的语法。在大多数情况下,您应该能够调整上面的示例以连接到您自己的KML。