赞
踩
官网demo地址:
Custom Drag-and-Drop (KMZ)https://openlayers.org/en/latest/examples/drag-and-drop-custom-kmz.html
这个示例展示了如何拖拽文件到地图上并实时解析成矢量图层
首先来看看什么是KMZ
doc.kml
。由此可知,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/>") || " ";
- } else {
- document.getElementById("info").innerHTML = " ";
- }
- };
接下来把官网提供的KMZ样例数据下载下来就可以测试了
下载下来是这样的
然后拖到地图上就可以显示了。
除了KML数据我们也下一个GeoJson数据试试。
到这个网站
选择下载文件
下载之后是json文件,手动把文件后缀名改成GeoJson。
然后拖到地图上即可解析。
完整代码:
- <template>
- <div class="box">
- <h1>拖拽KMZ, GPX, GeoJSON, IGC, KML, TopoJSON文件到地图上直接绘制矢量图层</h1>
- <div id="map"></div>
- <br />
- <div id="info"> </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/>") || " ";
- } else {
- document.getElementById("info").innerHTML = " ";
- }
- };
-
- 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>
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。