二十二、openlayers官网示例Custom Drag-and-Drop (KMZ)解析——拖拽KMZ,、GPX、GeoJSON、IGC、 KML、 TopoJSON文件到地图上解析成矢量图层

官网demo地址: 

Custom Drag-and-Drop (KMZ)icon-default.png?t=N7T8https://openlayers.org/en/latest/examples/drag-and-drop-custom-kmz.html

 这个示例展示了如何拖拽文件到地图上并实时解析成矢量图层 

首先来看看什么是KMZ

KMZ和KML有什么区别?

KML格式:
  1. 文件格式:KML文件是基于XML的纯文本文件。
  2. 文件扩展名:.kml
  3. 内容
    • 包含地理要素和数据,例如点、线、面、图像叠加以及其他地理信息。
    • 结构清晰,可读性强,可以用文本编辑器打开查看和编辑。
  4. 大小:因为是纯文本文件,KML文件可能会变得非常大,尤其是包含大量详细地理数据时。
KMZ 格式:
  1. 文件格式:KMZ文件是KML文件的压缩版本。
  2. 文件扩展名:.kmz
  3. 内容
    • KMZ文件是一个ZIP压缩包,里面包含一个或多个KML文件以及其他相关资源(如图片、模型等)。
    • 主KML文件通常命名为doc.kml
    • 可以包含多个文件和文件夹,使得相关资源可以一起分发。
  4. 大小:由于KMZ是压缩文件,通常比对应的KML文件要小,便于分发和下载。
  5. 多媒体资源:KMZ文件可以打包包括图片、3D模型(如Collada文件)等多媒体资源,这些资源可以在解压后保持相对路径关系。

 由此可知,KMZ格式转化成KML格式只需要进行解压,所以这里创建了一个KMZ类继承了KML,重写了readFeature和readFeatures两个方法,在解析之前增加了解压操作。

 class KMZ extends KML {
      constructor(opt_options) {
        const options = opt_options || {};
        options.iconUrlFunction = getKMLImage;
        super(options);
      }

      getType() {
        return "arraybuffer";
      }

      readFeature(source, options) {
        const kmlData = getKMLData(source);
        return super.readFeature(kmlData, options);
      }

      readFeatures(source, options) {
        const kmlData = getKMLData(source);
        return super.readFeatures(kmlData, options);
      }
    }

解压用到了 JSZip库

 const zip = new JSZip();
    function getKMLData(buffer) {
      let kmlData;
      zip.load(buffer);
      const kmlFile = zip.file(/\.kml$/i)[0];
      if (kmlFile) {
        kmlData = kmlFile.asText();
      }
      return kmlData;
    }

我们也来下载一下,官网用的版本是2.6.1,如果下最新版用法可能会不一样,所以下载的时候指定一下版本号。

npm i jszip@2.6.1

import  JSZip from "jszip";

 然后是拖拽操作,创建了一个交互DragAndDrop, defaultInteractions() 就是获取了OpenLayers提供的默认交互集合,包括地图的平移、缩放、双击缩放、鼠标滚轮缩放等基本交互。

 const dragAndDropInteraction = new DragAndDrop({
      formatConstructors: [KMZ, GPX, GeoJSON, IGC, KML, TopoJSON],
    });

    const map = new Map({
      interactions: defaultInteractions().extend([dragAndDropInteraction]),
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
      ],
      target: "map",
      view: new View({
        center: [0, 0],
        zoom: 2,
      }),
    });

监听addfeatures事件,当有新feature添加之后会增加一个矢量图层,并且让地图定位到feature的位置。

dragAndDropInteraction.on("addfeatures", function (event) {
      const vectorSource = new VectorSource({
        features: event.features,
      });
      map.addLayer(
        new VectorLayer({
          source: vectorSource,
        })
      );
      map.getView().fit(vectorSource.getExtent());
    });

鼠标在地图上经过或点击就会获取feature上的属性展示到表格中 

 map.on("pointermove", function (evt) {
      if (evt.dragging) {
        return;
      }
      const pixel = map.getEventPixel(evt.originalEvent);
      displayFeatureInfo(pixel);
    });

    map.on("click", function (evt) {
      displayFeatureInfo(evt.pixel);
    });

 能展示的前提是数据里有这些属性。

const displayFeatureInfo = function (pixel) {
      const features = [];
      map.forEachFeatureAtPixel(pixel, function (feature) {
        features.push(feature);
      });
      if (features.length > 0) {
        const info = [];
        let i, ii;
        for (i = 0, ii = features.length; i < ii; ++i) {
          const description =
            features[i].get("description") ||
            features[i].get("name") ||
            features[i].get("_name") ||
            features[i].get("layer");
          if (description) {
            info.push(description);
          }
        }
        document.getElementById("info").innerHTML =
          info.join("<br/>") || "&nbsp";
      } else {
        document.getElementById("info").innerHTML = "&nbsp;";
      }
    };

接下来把官网提供的KMZ样例数据下载下来就可以测试了

下载下来是这样的

 然后拖到地图上就可以显示了。

除了KML数据我们也下一个GeoJson数据试试。

到这个网站

DataV.GeoAtlas地理小工具系列

选择下载文件

下载之后是json文件,手动把文件后缀名改成GeoJson。 

 然后拖到地图上即可解析。

完整代码:

<template>
  <div class="box">
    <h1>拖拽KMZ, GPX, GeoJSON, IGC, KML, TopoJSON文件到地图上直接绘制矢量图层</h1>
    <div id="map"></div>
    <br />
    <div id="info">&nbsp;</div>
  </div>
</template>

<script>
import Map from "ol/Map.js";
import View from "ol/View.js";
import {
  DragAndDrop,
  defaults as defaultInteractions,
} from "ol/interaction.js";
import { GPX, GeoJSON, IGC, KML, TopoJSON } from "ol/format.js";
import { OSM, Vector as VectorSource } from "ol/source.js";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
import  JSZip from "jszip";
export default {
  name: "",
  components: {},
  data() {
    return {
      map: null,
    };
  },
  computed: {},
  created() {},
  mounted() {
    const zip = new JSZip();
    function getKMLData(buffer) {
      let kmlData;
      zip.load(buffer);
      const kmlFile = zip.file(/\.kml$/i)[0];
      if (kmlFile) {
        kmlData = kmlFile.asText();
      }
      return kmlData;
    }

    function getKMLImage(href) {
      const index = window.location.href.lastIndexOf("/");
      if (index !== -1) {
        const kmlFile = zip.file(href.slice(index + 1));
        if (kmlFile) {
          return URL.createObjectURL(new Blob([kmlFile.asArrayBuffer()]));
        }
      }
      return href;
    }

   

    class KMZ extends KML {
      constructor(opt_options) {
        const options = opt_options || {};
        options.iconUrlFunction = getKMLImage;
        super(options);
      }

      getType() {
        return "arraybuffer";
      }

      readFeature(source, options) {
        const kmlData = getKMLData(source);
        return super.readFeature(kmlData, options);
      }

      readFeatures(source, options) {
        const kmlData = getKMLData(source);
        return super.readFeatures(kmlData, options);
      }
    }


    const dragAndDropInteraction = new DragAndDrop({
      formatConstructors: [KMZ, GPX, GeoJSON, IGC, KML, TopoJSON],
    });

    const map = new Map({
      interactions: defaultInteractions().extend([dragAndDropInteraction]),
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
      ],
      target: "map",
      view: new View({
        center: [0, 0],
        zoom: 2,
      }),
    });

    dragAndDropInteraction.on("addfeatures", function (event) {
      const vectorSource = new VectorSource({
        features: event.features,
      });
      map.addLayer(
        new VectorLayer({
          source: vectorSource,
        })
      );
      map.getView().fit(vectorSource.getExtent());
    });

    const displayFeatureInfo = function (pixel) {
      const features = [];
      map.forEachFeatureAtPixel(pixel, function (feature) {
        features.push(feature);
      });
      if (features.length > 0) {
        const info = [];
        let i, ii;
        for (i = 0, ii = features.length; i < ii; ++i) {
          const description =
            features[i].get("description") ||
            features[i].get("name") ||
            features[i].get("_name") ||
            features[i].get("layer");
          if (description) {
            info.push(description);
          }
        }
        document.getElementById("info").innerHTML =
          info.join("<br/>") || "&nbsp";
      } else {
        document.getElementById("info").innerHTML = "&nbsp;";
      }
    };

    map.on("pointermove", function (evt) {
      if (evt.dragging) {
        return;
      }
      const pixel = map.getEventPixel(evt.originalEvent);
      displayFeatureInfo(pixel);
    });

    map.on("click", function (evt) {
      displayFeatureInfo(evt.pixel);
    });
  },
  methods: {},
};
</script>

<style lang="scss" scoped>
#map {
  width: 100%;
  height: 500px;
}
.box {
  height: 100%;
}

#info {
  width: 100%;
  height: 24rem;
  overflow: scroll;
  display: flex;
  align-items: baseline;
  border: 1px solid black;
  justify-content: flex-start;
}
</style>

GeoJSON是一种用于表示地理空间数据的开放格式标准,它基于JSON格式,可以被广泛地应用于Web地图开发和GIS领域。而OpenLayers则是一个开源的JavaScript库,用于在Web页面上展示地图和地理空间数据。它可以与GeoJSON格式的数据结合使用,实现地图的呈现、交互和分析功能。 使用GeoJSONOpenLayers可以实现很多地图功能,比如地图数据的加载、标记的展示、地图样式的定制、地图的导航与交互等。通过GeoJSON格式的地理空间数据,用户可以将各种地图要素(如点、线、面)以及其相关属性(如名称、类型、坐标等)进行统一的描述和存储,而OpenLayers则提供了一系列的功能接口和方法,可以帮助用户实现在Web地图中展示和处理这些地理空间数据。 在使用GeoJSONOpenLayers时,用户可以根据自己的需求,选择合适的地理空间数据来加载和展示,也可以根据实际需求定制地图的样式和交互方式。例如,用户可以通过GeoJSON加载地图数据,然后利用OpenLayers矢量图和样式控制功能,将数据以各种符号、颜色和标注展现在地图上。同时,OpenLayers还提供了丰富的交互功能,比如地图拖拽、放大缩小、点击事件等,使用户可以更加灵活和直观地与地图进行交互操作。 总之,GeoJSONOpenLayers的结合为Web地图开发提供了便利,使用户可以更加轻松地展示和处理地理空间数据,实现丰富多样的地图功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值