当前位置:   article > 正文

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

openlayers kmz

官网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两个方法,在解析之前增加了解压操作。

  1. class KMZ extends KML {
  2. constructor(opt_options) {
  3. const options = opt_options || {};
  4. options.iconUrlFunction = getKMLImage;
  5. super(options);
  6. }
  7. getType() {
  8. return "arraybuffer";
  9. }
  10. readFeature(source, options) {
  11. const kmlData = getKMLData(source);
  12. return super.readFeature(kmlData, options);
  13. }
  14. readFeatures(source, options) {
  15. const kmlData = getKMLData(source);
  16. return super.readFeatures(kmlData, options);
  17. }
  18. }

解压用到了 JSZip库

  1. const zip = new JSZip();
  2. function getKMLData(buffer) {
  3. let kmlData;
  4. zip.load(buffer);
  5. const kmlFile = zip.file(/\.kml$/i)[0];
  6. if (kmlFile) {
  7. kmlData = kmlFile.asText();
  8. }
  9. return kmlData;
  10. }

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

  1. npm i jszip@2.6.1
  2. import JSZip from "jszip";

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

  1. const dragAndDropInteraction = new DragAndDrop({
  2. formatConstructors: [KMZ, GPX, GeoJSON, IGC, KML, TopoJSON],
  3. });
  4. const map = new Map({
  5. interactions: defaultInteractions().extend([dragAndDropInteraction]),
  6. layers: [
  7. new TileLayer({
  8. source: new OSM(),
  9. }),
  10. ],
  11. target: "map",
  12. view: new View({
  13. center: [0, 0],
  14. zoom: 2,
  15. }),
  16. });

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

  1. dragAndDropInteraction.on("addfeatures", function (event) {
  2. const vectorSource = new VectorSource({
  3. features: event.features,
  4. });
  5. map.addLayer(
  6. new VectorLayer({
  7. source: vectorSource,
  8. })
  9. );
  10. map.getView().fit(vectorSource.getExtent());
  11. });

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

  1. map.on("pointermove", function (evt) {
  2. if (evt.dragging) {
  3. return;
  4. }
  5. const pixel = map.getEventPixel(evt.originalEvent);
  6. displayFeatureInfo(pixel);
  7. });
  8. map.on("click", function (evt) {
  9. displayFeatureInfo(evt.pixel);
  10. });

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

  1. const displayFeatureInfo = function (pixel) {
  2. const features = [];
  3. map.forEachFeatureAtPixel(pixel, function (feature) {
  4. features.push(feature);
  5. });
  6. if (features.length > 0) {
  7. const info = [];
  8. let i, ii;
  9. for (i = 0, ii = features.length; i < ii; ++i) {
  10. const description =
  11. features[i].get("description") ||
  12. features[i].get("name") ||
  13. features[i].get("_name") ||
  14. features[i].get("layer");
  15. if (description) {
  16. info.push(description);
  17. }
  18. }
  19. document.getElementById("info").innerHTML =
  20. info.join("<br/>") || "&nbsp";
  21. } else {
  22. document.getElementById("info").innerHTML = "&nbsp;";
  23. }
  24. };

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

下载下来是这样的

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

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

到这个网站

DataV.GeoAtlas地理小工具系列

选择下载文件

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

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

完整代码:

  1. <template>
  2. <div class="box">
  3. <h1>拖拽KMZ, GPX, GeoJSON, IGC, KML, TopoJSON文件到地图上直接绘制矢量图层</h1>
  4. <div id="map"></div>
  5. <br />
  6. <div id="info">&nbsp;</div>
  7. </div>
  8. </template>
  9. <script>
  10. import Map from "ol/Map.js";
  11. import View from "ol/View.js";
  12. import {
  13. DragAndDrop,
  14. defaults as defaultInteractions,
  15. } from "ol/interaction.js";
  16. import { GPX, GeoJSON, IGC, KML, TopoJSON } from "ol/format.js";
  17. import { OSM, Vector as VectorSource } from "ol/source.js";
  18. import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
  19. import JSZip from "jszip";
  20. export default {
  21. name: "",
  22. components: {},
  23. data() {
  24. return {
  25. map: null,
  26. };
  27. },
  28. computed: {},
  29. created() {},
  30. mounted() {
  31. const zip = new JSZip();
  32. function getKMLData(buffer) {
  33. let kmlData;
  34. zip.load(buffer);
  35. const kmlFile = zip.file(/\.kml$/i)[0];
  36. if (kmlFile) {
  37. kmlData = kmlFile.asText();
  38. }
  39. return kmlData;
  40. }
  41. function getKMLImage(href) {
  42. const index = window.location.href.lastIndexOf("/");
  43. if (index !== -1) {
  44. const kmlFile = zip.file(href.slice(index + 1));
  45. if (kmlFile) {
  46. return URL.createObjectURL(new Blob([kmlFile.asArrayBuffer()]));
  47. }
  48. }
  49. return href;
  50. }
  51. class KMZ extends KML {
  52. constructor(opt_options) {
  53. const options = opt_options || {};
  54. options.iconUrlFunction = getKMLImage;
  55. super(options);
  56. }
  57. getType() {
  58. return "arraybuffer";
  59. }
  60. readFeature(source, options) {
  61. const kmlData = getKMLData(source);
  62. return super.readFeature(kmlData, options);
  63. }
  64. readFeatures(source, options) {
  65. const kmlData = getKMLData(source);
  66. return super.readFeatures(kmlData, options);
  67. }
  68. }
  69. const dragAndDropInteraction = new DragAndDrop({
  70. formatConstructors: [KMZ, GPX, GeoJSON, IGC, KML, TopoJSON],
  71. });
  72. const map = new Map({
  73. interactions: defaultInteractions().extend([dragAndDropInteraction]),
  74. layers: [
  75. new TileLayer({
  76. source: new OSM(),
  77. }),
  78. ],
  79. target: "map",
  80. view: new View({
  81. center: [0, 0],
  82. zoom: 2,
  83. }),
  84. });
  85. dragAndDropInteraction.on("addfeatures", function (event) {
  86. const vectorSource = new VectorSource({
  87. features: event.features,
  88. });
  89. map.addLayer(
  90. new VectorLayer({
  91. source: vectorSource,
  92. })
  93. );
  94. map.getView().fit(vectorSource.getExtent());
  95. });
  96. const displayFeatureInfo = function (pixel) {
  97. const features = [];
  98. map.forEachFeatureAtPixel(pixel, function (feature) {
  99. features.push(feature);
  100. });
  101. if (features.length > 0) {
  102. const info = [];
  103. let i, ii;
  104. for (i = 0, ii = features.length; i < ii; ++i) {
  105. const description =
  106. features[i].get("description") ||
  107. features[i].get("name") ||
  108. features[i].get("_name") ||
  109. features[i].get("layer");
  110. if (description) {
  111. info.push(description);
  112. }
  113. }
  114. document.getElementById("info").innerHTML =
  115. info.join("<br/>") || "&nbsp";
  116. } else {
  117. document.getElementById("info").innerHTML = "&nbsp;";
  118. }
  119. };
  120. map.on("pointermove", function (evt) {
  121. if (evt.dragging) {
  122. return;
  123. }
  124. const pixel = map.getEventPixel(evt.originalEvent);
  125. displayFeatureInfo(pixel);
  126. });
  127. map.on("click", function (evt) {
  128. displayFeatureInfo(evt.pixel);
  129. });
  130. },
  131. methods: {},
  132. };
  133. </script>
  134. <style lang="scss" scoped>
  135. #map {
  136. width: 100%;
  137. height: 500px;
  138. }
  139. .box {
  140. height: 100%;
  141. }
  142. #info {
  143. width: 100%;
  144. height: 24rem;
  145. overflow: scroll;
  146. display: flex;
  147. align-items: baseline;
  148. border: 1px solid black;
  149. justify-content: flex-start;
  150. }
  151. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/928281
推荐阅读
相关标签
  

闽ICP备14008679号