便利贴--5{OpenLayers,vue项目}
项目
添加
“ol”: “^6.5.0”,
“olcs”: “^2.12.0”
在package.json中添加
OpenLayers–需要 Cesium
链接: 贴出Cesium下载.
链接: jqurey,drawTree支持下载.
main.vue
由于绘画的Draw.js没有找到想要输出数据的地方,只能自己改,但是每次拉包会重置node_modules所有的文件,所以把Draw.js直接从ol/interaction中拿出来,改好就引用这个js
改的话因为比较长还是放在文件中自己下载
0积分
链接: 下载改好后的Draw.js.
<!--
* @Descripttion:
* @version:
* @Author: song
* @Date: 2021-04-08 15:14:57
* @LastEditors: song
* @LastEditTime: 2021-04-24 11:59:43
-->
<template>
<div id="map" style="height: 100%">
<div class="controlMap">
<el-button-group>
<el-button
type="primary"
icon="el-icon-edit"
@click="getTypeSelected"
:disabled="beginDraw"
>{{ butTitle }}</el-button
>
<el-button
type="primary"
:disabled="!beginDraw"
@click="stopDraw"
icon="el-icon-delete"
>取消</el-button
>
<!-- <el-button type="primary" icon="el-icon-share"></el-button>
<el-button type="primary" icon="el-icon-delete"></el-button> -->
</el-button-group>
</div>
<tip v-show="showTip" :title="tipTitle" :position="position"></tip>
</div>
</template>
<script>
import OLCesium from "olcs/OLCesium.js";
import "ol/ol.css";
import OlView from "ol/View.js";
import XYZ from "ol/source/XYZ";
import OlLayerTile from "ol/layer/Tile.js";
import OlMap from "ol/Map.js";
import tip from "./tip.vue";
import {
// eslint-disable-next-line no-unused-vars
defaults as OlControlDefaults,
defaults,
// 全屏控件
FullScreen,
// 比例尺控件
ScaleLine,
// 缩放滚动条控件
// eslint-disable-next-line no-unused-vars
ZoomSlider,
// 鼠标位置控件
// eslint-disable-next-line no-unused-vars
MousePosition,
// -地图属性控件
Attribution,
// 鹰眼控件
// eslint-disable-next-line no-unused-vars
OverviewMap,
// 缩放到范围控件
// eslint-disable-next-line no-unused-vars
ZoomToExtent,
Rotate,
} from "ol/control.js";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { OSM, TileWMS, Vector } from "ol/source";
//改成自己的 Draw 路径
import Draw from "ol/interaction/Draw";
import Feature from "ol/Feature.js";
import Point from "ol/geom/Point.js";
import LineString from "ol/geom/LineString.js";
import { Icon, Style, Fill, Stroke } from "ol/style.js";
// import drawFence from "./drawFence";
export default {
name: "Map",
components: {
tip,
},
data() {
return {
gunAddlayer: new VectorLayer({
// 图标图层
zIndex: 22,
source: new VectorSource(),
}),
peopleAddlayer: new VectorLayer({
// 图标图层
zIndex: 22,
source: new VectorSource(),
}),
carAddlayer: new VectorLayer({
// 图标图层
zIndex: 22,
source: new VectorSource(),
}),
peopleLineAddlayer: new VectorLayer({
// 图标图层
zIndex: 22,
source: new VectorSource(),
}),
// 存储新增点,线,面,数据的地方
// polygonData: [],
// polygonFlag: false,
// editToolbar: null,
// addPolygonEntitys: null,
typeSelected: "LineString",
drawLayer: null,
draw: null,
coordinates: [],
coordinatesStr: "",
beginDraw: false,
butTitle: "开始绘画",
view: "",
// map: null,
showTip: false,
tipTitle: "",
position: {
w: 200,
h: 10,
},
};
},
mounted() {
const ol2d = new OlMap({
layers: [
new OlLayerTile({
zIndex: 4,
title: "影像",
source: new XYZ({
url: "https://webmap-tile.sf-express.com/MapTileService/rt?fetchtype=static&x={x}&y={y}&z={z}&project=sfmap&pic_size=256&pic_type=png8&data_name=361100&data_format=merged-dat&data_type=normal", // 行政区划
}),
}),
// new OlLayerTile({
// zIndex: 5,
// title: '道路+中文注记',
// source: new XYZ({
// url: 'http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e9533f5acb2ac470b07f406a4d24b4f0' // 注记
// })
// })
],
// 注意地图控件的写法
controls: defaults().extend([
// new FullScreen(),
// new ScaleLine(),
// new MousePosition(),
// new Rotate(),
// new Attribution()
]),
target: "map",
view: new OlView({
center: [0, 0],
zoom: 2,
projection: "EPSG:4326",
}),
});
window.ol2d = ol2d;
var view = ol2d.getView();
// view.setCenter([115.85883507433789, 28.708432053474827])
view.setCenter([115.9032747077233, 28.67433116990186]);
//
view.setZoom(13);
this.view = view;
const ol3d = new OLCesium({ map: window.ol2d });
window.ol3d = ol3d;
ol2d.addLayer(this.gunAddlayer);
ol2d.addLayer(this.peopleAddlayer);
ol2d.addLayer(this.carAddlayer);
ol2d.addLayer(this.peopleLineAddlayer);
// this.addLines()
//监听鼠标位置
var that = this;
//
that.addNewLine();
},
methods: {
goTudefault(x, y) {
this.view.setCenter([x, y]);
this.view.setZoom(14.5);
},
init3D(val) {
window.ol3d.setEnabled(val);
},
addEntitys(item, icon, scale, name, type) {
const iconFeature = new Feature({
geometry: new Point([Number(item.LGTD), Number(item.LTTD)]),
name: name,
attributes: item,
});
const iconStyle = new Style({
// text: new Text({ // 字体, 未成功, 浪费许多时间
// font: 'Normal ' + 12 + 'px ' + 'iconfont',
// text: "\e645",
// fill: new Fill({ color: "green" }),
// }),
image: new Icon({
scale: scale,
opacity: 1,
src: icon,
// src: require('../../assets/Mark.png')
}),
// new CircleStyle({ // 普通样式
// radius: 6,
// fill: new Fill({
// color: 'rgba(200, 155, 155, 0.8)'
// }),
// stroke: new Stroke({
// color: 'black',
// width: 0.3,
// })
// }),
});
iconFeature.setStyle(iconStyle);
this[type].getSource().addFeature(iconFeature);
},
addLines(ringId) {
var that = this;
if (ringId != null && ringId != "") {
$.ajax({
url: "api/routeIn/routein/selectList",
type: "post",
data: {
id: ringId,
},
dataType: "JSON",
success: function (data) {
that.peopleLineAddlayer.getSource().clear();
var entityData = "";
var entityArr = [];
entityData = data.data[0].routeInfo.match(/\(([^)]*)\)/);
// 此时result=["(dsfasjfj3124123)", "dsfasjfj3124123"];
if (entityData && entityData != "") {
entityData = entityData[1].split(",");
for (var j = 0; j < entityData.length; j++) {
entityArr.push([
Number(entityData[j].split(" ")[0]),
Number(entityData[j].split(" ")[1]),
]);
}
}
var lineCoords = entityArr; // 线里点的集合
var view = ol2d.getView();
view.setCenter([
lineCoords[Math.ceil(entityArr.length / 2)][0],
lineCoords[Math.ceil(entityArr.length / 2)][1],
]);
view.setZoom(14.5);
// 要素
// var lineCoords = [[featureInfo.lineString[0][0],featureInfo.lineString[0][0]],[featureInfo.lineString(0),featureInfo.lineString(0)]];
var feature_LineString = new Feature({
geometry: new LineString(lineCoords),
});
feature_LineString.setStyle(
new Style({
//填充色
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
//边线颜色
stroke: new Stroke({
color: "rgb(252, 94, 32)",
width: 5,
}),
})
);
that.peopleLineAddlayer.getSource().addFeature(feature_LineString);
that.butTitle = "修改绘画";
},
error: function (data) {
// 请求失败函数
console.log(data);
},
});
}
},
addNewLine() {
this.map = ol2d;
// console.log(ol2d, 1);
// console.log(drawFence, 2);
// var d = new drawFence(ol2d);
// console.log(d);
// 添加一个绘制的线使用的layer
this.drawLayer = new VectorLayer({
//layer所对应的source
source: new Vector(),
});
//把layer加入到地图中
this.map.addLayer(this.drawLayer);
},
getTypeSelected() {
this.beginDraw = true;
this.draw && this.map.removeInteraction(this.draw);
this.peopleLineAddlayer.getSource().clear();
//再根据typeSelect的值绘制新的Interaction
this.addInteraction();
},
stopDraw() {
this.showTip = false;
this.draw && this.map.removeInteraction(this.draw);
this.beginDraw = false;
this.tipTitle = "";
this.$store.commit("setRotesData", ""); //用vuex传最终数据
},
setTipPosition(x, y, n, m) {
this.position.w = x + n;
this.position.h = y + m;
},
addInteraction() {
this.tipTitle = "单击左键或右键开始绘画";
$("#map")
.off("mousemove")
.mousemove(function (e) {
if (!that.showTip) {
that.showTip = true;
}
that.setTipPosition(e.offsetX, e.offsetY, 10, 10);
// console.log(e.clientX);
// console.log(e.offsetX);
// console.log(e.pageX);
// console.log(e.screenX);
// console.log("================================");
});
this.coordinates = [];
let value = this.typeSelected,
that = this;
if (value !== "None") {
this.draw = new Draw({
source: this.drawLayer.getSource(),
type: this.typeSelected,
style: new Style({
stroke: new Stroke({
color: "red",
width: 3,
}),
}),
coordinate: function (res) {
//画线中的点
that.coordinates.push(res.coordinate_);
that.tipTitle = "可继续,或选择最终位置双击结束";
// console.log(res.coordinate_, 123456);
},
coordinateOver: function (res) {
// 结束绘画 处理数据
// console.log(that.doData(that.coordinates));
let d = that.doData(that.coordinates);
that.addLinesDraw(d);
// console.log(d);
// console.log(that.$store);
that.$store.commit("setRotesData", d); //用vuex传最终数据
// that.coordinatesStr = that.doData(that.coordinates);
},
});
this.map.addInteraction(this.draw);
}
},
doData(val) {
// ` routeInfo: "
// LINESTRING(
// 115.875489096939 28.7179278611352
// ,115.8794051221 28.7176267680684
// ,115.879340749084 28.7143052776491
// ,115.878879409134 28.7140324026424
// ,115.875220876038 28.7150580325974
// ,115.875489096939 28.7179466794231
// ,115.875489096939 28.7179466794231
// )"
// `
let str = "LINESTRING(";
for (let k = 0; k < val.length; k++) {
str += `${val[k][0]} ${val[k][1]}`;
if (k != val.length - 1) {
str += ",";
}
}
str += ")";
return str;
},
addLinesDraw(val) {
var that = this;
// if (ringId != null && ringId != "") {
// $.ajax({
// url: "api/routeIn/routein/selectList",
// type: "post",
// data: {
// id: ringId,
// },
// dataType: "JSON",
// success: function (data) {
that.peopleLineAddlayer.getSource().clear();
var entityData = "";
var entityArr = [];
entityData = val.match(/\(([^)]*)\)/);
// 此时result=["(dsfasjfj3124123)", "dsfasjfj3124123"];
if (entityData && entityData != "") {
entityData = entityData[1].split(",");
for (var j = 0; j < entityData.length; j++) {
entityArr.push([
Number(entityData[j].split(" ")[0]),
Number(entityData[j].split(" ")[1]),
]);
}
}
var lineCoords = entityArr; // 线里点的集合
var view = ol2d.getView();
view.setCenter([
lineCoords[Math.ceil(entityArr.length / 2)][0],
lineCoords[Math.ceil(entityArr.length / 2)][1],
]);
view.setZoom(14.5);
// 要素
// var lineCoords = [[featureInfo.lineString[0][0],featureInfo.lineString[0][0]],[featureInfo.lineString(0),featureInfo.lineString(0)]];
var feature_LineString = new Feature({
geometry: new LineString(lineCoords),
});
feature_LineString.setStyle(
new Style({
//填充色
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
//边线颜色
stroke: new Stroke({
color: "rgb(252, 94, 32)",
width: 5,
}),
})
);
that.peopleLineAddlayer.getSource().addFeature(feature_LineString);
if (that.draw != null) {
that.beginDraw = false;
that.butTitle = "重新绘画";
that.draw.controlDrawing(true);
that.tipTitle = "已结束绘画,点击重新绘画清除上次内容并开始绘画";
$("#map").unbind("mousemove");
// setTimeout(() => {
this.tipTitle = "";
this.showTip = false;
}
},
},
};
</script>
<style scoped lang="scss">
#map {
position: relative;
.controlMap {
position: absolute;
top: 10px;
left: calc(50% - 80px);
z-index: 2 !important;
}
}
</style>
drawFence.js
import ol from "ol";
class drawFence {
constructor(props) {
//这里初始化class的时候需要传map对象进来
this.map = props;
this.source;
this.fenceLayer;
this.draw;
//样式
this.fenceStyle = new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2
}),
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
})
})
})
this.init()
}
init() {
//临时图层的数据源
this.source = new ol.source.Vector();
//新建临时图层,并设置临时图层渲染各种要素的样式
this.fenceLayer = new ol.layer.Vector({
source: this.source,
style: this.fenceStyle
});
this.map.addLayer(this.fenceLayer)
}
drawingEnd(evt) {
let geo = evt.feature.getGeometry()
let type = geo.getType(); //获取类型
console.log(geo)
//根据不同的类型执行不同的操作
const handle = {
'Circle': () => {
//获取中心点和半径
let center = geo.getCenter()
let radius = geo.getRadius()
console.log(center, radius)
},
'Polygon': () => {
//获取坐标点
let points = geo.getCoordinates()
console.log(points)
},
'LineString': () => {
let points = geo.getCoordinates()
console.log(points)
}
}
if (handle[type]) handle[type]()
this.closeDraw()
}
closeDraw() {
this.map.removeInteraction(this.draw);
}
//画图
drawingFence(type) {
this.draw = new ol.interaction.Draw({
source: this.source, //设置要素源,绘制结束后将绘制的要素添加到临时图层
type: type, //绘制的类型
});
this.map.addInteraction(this.draw);
const that = this;
//绘图结束事件回调
this.draw.on('drawend', function (evt) {
that.drawingEnd(evt)
});
}
}
export default drawFence;
tip.vue
<template>
<div
class="mapTip"
:style="{ top: position.h + 'px', left: position.w + 'px' }"
>
{{ title }}
</div>
</template>
<script>
export default {
props: ["title", "position"],
};
</script>
<style lang="scss" scoped>
.mapTip {
background-color: rgb(168, 168, 168);
padding: 5px;
border: 1px solid #000;
position: absolute;
z-index: 10 !important;
border-radius: 5px;
}
</style>
最后用Store传送数据
rotesData: false,
setRotesData(state, data) {
state.rotesData = data;
}