<template> <div class="container"> <h4> <input style="margin-top: 16px" type="file" id="fileselect" accept=".csv" /> </h4> <div id="vue-openlayers"></div> <div id="popup-box" class="ol-popup"> <div id="popup-content"> <div class="oneline">经度:{{lon}}</div> <div class="oneline">纬度:{{lat}}</div> <div class="oneline">时间:{{time}}</div> </div> </div> <div style="position: fixed;right: 0;top: 0; width: 200px;height: 40px;background: #ddd;"> <div class="oneline">开始时间:{{firstTime}}</div> <div class="oneline">结束时间:{{lastTime}}</div> </div> </div> </template> <script> import 'ol/ol.css' import Map from 'ol/Map' import View from 'ol/View' import SourceVector from 'ol/source/Vector' import LayerVector from 'ol/layer/Vector' import Tile from 'ol/layer/Tile'; import XYZ from 'ol/source/XYZ' import Feature from 'ol/Feature' import Overlay from 'ol/Overlay'; import Point from "ol/geom/Point" import LineString from "ol/geom/LineString" import Style from 'ol/style/Style' import Icon from 'ol/style/Icon' import Fill from 'ol/style/Fill' import Text from 'ol/style/Text' import Stroke from 'ol/style/Stroke' import CircleStyle from 'ol/style/Circle' import { fromLonLat } from 'ol/proj' import GeoJSON from 'ol/format/GeoJSON' import Papa from 'papaparse/papaparse.min.js' //处理csv,需要安装 npm install papaparse --save export default { name: 'CSVJSON', data() { return { map: null, source: new SourceVector(), lineLayer:null, dropLayer:null, fileName: '', lat: '', lon: '', time: '', firstTime:'', lastTime:'' } }, methods: { // 设置点的大小样式 featureStyle(c,s, t) { let Styles = [] Styles.push( new Style({ /*image: new CircleStyle({ //点样式 radius: s, fill: new Fill({ color: c }), }),*/ image: new Icon({ src: require('../assets/circle.png'), color:c, scale:0.3 }) }) ) return Styles }, // 点击点出现弹出信息 clickPoint() { const box = document.getElementById('popup-box'); this.overlayer = new Overlay({ element: box, autoPan: { animation: { duration: 250, }, }, }); this.map.addOverlay(this.overlayer); // 显示内容 let _that = this; this.map.on('click', (e) => { if(_that.map.hasFeatureAtPixel(e.pixel)){ _that.map.forEachFeatureAtPixel( e.pixel, (feature, layer) => { if(feature.values_.pointdata){ let pointInfo = feature.get('pointdata') _that.lon = pointInfo.jd; _that.lat = pointInfo.wd; _that.time = pointInfo.wzsj; _that.overlayer.setPosition(e.coordinate); } // return feature } ) }else { _that.overlayer.setPosition(undefined); } /*let feature = */ /**/ }); }, // 上传文件并在地图展示信息 readAndShowPoints() { this.source.clear(); let _that = this let fileselect = document.querySelector('#fileselect') fileselect.addEventListener('change', (e) => { _that.dropLayer.getSource().clear() _that.lineLayer.getSource().clear() let files = e.target.files; if (files.length === 0) { alert("没有数据,请重新上传新文件!") return } let file = files[0]; this.fileName = file.name.split('.').slice(0, -1).join('.'); Papa.parse(file, { header: true, complete: (results) => { let arr = results.data; let features = []; let lineArr = []; let type = '' let s='' let c='' let scale = 0 let startPoint = [Number(arr[0].jd), Number(arr[0].wd)] for (let i = 0; i < arr.length; i++) { let d= arr.length-2; if(i == arr.length-1) continue lineArr.push([Number(arr[i].jd), Number(arr[i].wd)]) let lineFeature = new Feature({ geometry: new LineString(lineArr), type:'line' }) _that.lineLayer.getSource().addFeature(lineFeature) if (i == 0) { c = "#f00" //起点 s = 12 scale = 0.6 startPoint = [Number(arr[i].jd), Number(arr[i].wd)] } else if (i == d) { c = "#0f0" //终点 s = 12 scale = 0.6 } else { c = "#f0f" s = 6 scale = 0.3 } let feature = new Feature({ c, geometry: new Point([Number(arr[i].jd), Number(arr[i].wd)]), pointdata: arr[i], type, scale }) _that.dropLayer.getSource().addFeatures(features) let view = this.map.getView() view.animate({center:startPoint}) } }); }) }, // 初始化地图 initMap() { this.map = new Map({ target: 'vue-openlayers', layers: [ new Tile({ //加载谷歌地图 source: new XYZ({ url: 'http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=2&scale=1&style=8', crossOrigin: "anonymous" }) }), new LayerVector({ //加载csv信息层 source: this.source, declutter: true, }) ], view: new View({ projection: "EPSG:4326", center: [-116.77542, 37.56855], zoom: 4, }) }) this.clickPoint() }, initPointLayer(){ this.dropLayer = new LayerVector({ source:new SourceVector(), style:function (feature){ // let c = feature.values_.c return new Style({ image: new Icon({ src: require('../assets/circle.png'), color: feature.values_.c, scale: feature.values_.scale, }) }) } }) this.map.addLayer(this.dropLayer) }, initLineLayer(){ this.lineLayer = new LayerVector({ source: new SourceVector(), style: new Style({ stroke: new Stroke({ color: '#00f', width: 2 }) }) }) this.map.addLayer(this.lineLayer) } }, mounted() { this.initMap() this.initLineLayer() this.initPointLayer() this.readAndShowPoints() } } </script> <style scoped> .container { width: 100%; height: 590px; } #vue-openlayers { width: 100%; height: 100vh; position: relative; } .ol-popup { position: absolute; padding: 5px; bottom: 12px; left: -50px; min-width: 120px; } #popup-content { width: 180px; height: 60px; background-color: aquamarine; padding: 10px; } .oneline { line-height: 20px; font-size: 13px; text-align: left; } </style>