<template>
<div>
<!-- 地图容器 -->
<div id='rtsmap' class="rtsmap" ref="rtsmap"></div>
<!-- 悬浮按钮组、非领导不需要ksh按钮 -->
<div class="rop_div">
<!-- 图层管理 -->
<div class="rop_item_div" id="tc_btn" v-on:click="openLy">
<img :src="tcMbTogget ? require('@/assets/tc_xz.png') : require('@/assets/tc.png')" class="rop_item_img" />
</div>
<!-- 属性查询 -->
<div class="rop_item_div" id="sx_btn" v-on:click="openSxLy">
<img :src="sxGnTogget ? require('@/assets/cx_xz.png') : require('@/assets/cx.png')" class="rop_item_img" />
</div>
<!-- 可视化开关 -->
<div class="rop_item_div" id="ksh_btn" v-on:click="openKshLy">
<img :src="tjGnTogget ? require('@/assets/ksh_xz.png') : require('@/assets/ksh.png')"
class="rop_item_img" />
</div>
<!-- 实际定位 -->
<div class="rop_item_div" id="dw_btn" v-on:click="startLoction">
<img :src="dwGnTogget ? require('@/assets/gps_xz.png') : require('@/assets/gps.png')"
class="rop_item_img" />
</div>
</div>
<!-- 图层管理面板 -->
<div class="mb_layer_mgr" id="mb_layer_mgr" :hidden="!tcMbTogget">
<div class="mb_title_div" id="ly_close_btn" v-on:click="closeLy">
<img src="../assets/close.png" class="mb_title_img" />
</div>
<div class="zdmbtm">
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item title="遥感影像" name="1">
<el-row justify="start" :gutter="20" class="row_fcc">
<el-col :span="8" v-for="(item, index) in layerDatas.ygyx" :key="index">
<div class="dt_item" :class="item.isChoice ? 'checkfont' : 'checkfont_no'"
@click="clickTcItem(0, index)">
<img src="../assets/pic_2023.png" class="dt_item_img"
:class="item.isChoice ? 'checktc' : 'checktc_no'" />
<div>{{ item.name }}</div>
</div>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="调查范围界" name="2">
<el-row justify="start" :gutter="20" class="row_fcc">
<el-col :span="8" v-for="(item, index) in layerDatas.dcfwj" :key="index">
<div class="dt_item" :class="item.isChoice ? 'checkfont' : 'checkfont_no'"
@click="clickTcItem(1, index)">
<img src="../assets/pic_fw.png" class="dt_item_img"
:class="item.isChoice ? 'checktc' : 'checktc_no'" />
<div>{{ item.name }}</div>
</div>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="林地小班" name="3">
<el-row justify="start" :gutter="20" class="row_fcc">
<el-col :span="8" v-for="(item, index) in layerDatas.ldxb" :key="index">
<div class="dt_item" :class="item.isChoice ? 'checkfont' : 'checkfont_no'"
@click="clickTcItem(2, index)">
<img src="../assets/pic_xb.png" class="dt_item_img"
:class="item.isChoice ? 'checktc' : 'checktc_no'" />
<div>{{ item.name }}</div>
</div>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="天地图" name="4">
<el-row justify="start" :gutter="20" class="row_fcc">
<el-col :span="8">
<div class="dt_item checkfont" @click="clickTcItem(-1, index)">
<img src="../assets/pic_tdt.png" class="dt_item_img checktc" />
<div>天地图影像</div>
</div>
</el-col>
<el-col :span="8">
<div class="dt_item checkfont" @click="clickTcItem(-1, index)">
<img src="../assets/pic_td.png" class="dt_item_img checktc" />
<div>天地图标注</div>
</div>
</el-col>
</el-row>
</el-collapse-item>
</el-collapse>
</div>
</div>
<!-- i键弹窗 -->
<div style="text-align: left;">
<el-dialog title="属性信息" :visible.sync="sxVisible" width="80%" min-height="90vh">
<!-- <p>图层:1715918085241077760</p> -->
<p><label>经度:</label>{{ geomCoor[0] }}</p>
<p><label>纬度:</label>{{ geomCoor[1] }}</p>
<!-- <p :key="item.pk_uid">
{{ item }}
</p> -->
<div v-if="dcshuju == undefined || dcshuju.length == 0">
<p> 当前位置没有小班数据 </p>
</div>
<div v-else>
<div v-for="obj in dcshuju">
<p v-for="(value, key) in obj" :key="key" v-if="key != 'geom'">
{{ key }} : {{ value }}
</p>
<p style="width:100%;height: 1px;color: #ddd;"></p>
</div>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import "ol/ol.css";
import { Map, View, Feature } from "ol";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import XYZ from "ol/source/XYZ";
import { Point } from "ol/geom";
import { Style, Icon } from "ol/style";
import { transform, fromLonLat } from "ol/proj";
import { OverviewMap, ScaleLine, defaults } from "ol/control"
export default {
data() {
return {
//影像服务 token
appToken: "填写影像服务token",
//图层面板开关
tcMbTogget: false,
//属性功能开关
sxGnTogget: false,
//定位功能开关
dwGnTogget: false,
//统计功能开关
tjGnTogget: false,
//属性弹窗展示
sxVisible: false,
//图层面板类型展开记录
activeNames: ['1', '2', '3', '4'],
//全局地图对象
rtsMapObj: null,
//定位点对象
positionNav: null,
//当前位置经纬度
geomCoor: [],//当前位置经纬度
//默认mark
defaultMark: require('@/assets/defaultIcon.png'),
//定位mark
positionImg: require('@/assets/position.png'),
//定位方向
rotate: {},
//图层管理
layerDatas: {
ygyx: [],
dcfwj: [],
ldxb: []
},
dcshuju: [],
}
},
components: {
},
/**
* 钩子函数
*/
mounted() {
//初始化服务id
this.initLayersData();
//初始化地图
this.initMap();
//注册Android交互回调
window.operationAndroidKshBord = this.operationAndroidKshBord
},
methods: {
/**
* 初始化可加载地图 (这块数据初始化可以弄成在线接口返回,后端不配合)
*/
initLayersData() {
let that = this;
//添加遥感影像
that.layerDatas.ygyx.push(
{
name: "2023年影像",
mapId: "",
dataId: -1,
isChoice: true,
}
)
that.layerDatas.ygyx.push(
{
name: "2022年影像",
mapId: "",
dataId: -1,
isChoice: false,
}
)
//添加调查范围界
that.layerDatas.dcfwj.push(
{
name: "三区范围",
mapId: "",
dataId: "",
isChoice: false,
}
)
//林地小班
that.layerDatas.ldxb.push(
{
name: "林地小班2020",
mapId: "",
dataId: "",
isChoice: false,
}
)
},
/**
* 通过数据id生成栅格图层
* @param {*} mapId
*/
initLayersInfoByData(mapId) {
let that = this;
return new TileLayer({
source: new XYZ({
crossOrigin: "anonymous",
projection: "EPSG:4326",
// tileGrid: tileGrid,
tileUrlFunction(tileCoord) {
var z = tileCoord[0];
var x = tileCoord[1];
var y = tileCoord[2];
let offsetZ = z
return 拼接的影像瓦片地址;
},
wrapX: true,
})
})
},
/**
* 点击图层管理切换按钮
* @param {*} typeNum
* @param {*} contentIndex
*/
clickTcItem(typeNum, contentIndex) {
if (typeNum == -1) {
this.$message({
message: '当前类型底图不允许关闭',
type: 'warning'
});
return;
} else {
if (typeNum == 0) {
this.layerDatas.ygyx.forEach(element => {
element.isChoice = false;
});
this.layerDatas.ygyx[contentIndex].isChoice = true
} else if (typeNum == 1) {
if (!this.layerDatas.dcfwj[contentIndex].isChoice) {
this.layerDatas.dcfwj.forEach(element => {
element.isChoice = false;
});
}
this.layerDatas.dcfwj[contentIndex].isChoice = !this.layerDatas.dcfwj[contentIndex].isChoice
} else if (typeNum == 2) {
if (!this.layerDatas.ldxb[contentIndex].isChoice) {
this.layerDatas.ldxb.forEach(element => {
element.isChoice = false;
});
}
this.layerDatas.ldxb[contentIndex].isChoice = !this.layerDatas.ldxb[contentIndex].isChoice
}
//重置地图
this.resetZsMap()
}
},
/**
* 操作切换图层
* return 所有加载的图层
*/
optionLayer() {
let tileArr = [];
this.layerDatas.ygyx.forEach(element => {
if (element.isChoice) {
//生成TileLayer
let item = this.initLayersInfoByData(element.mapId)
tileArr.push(item)
}
});
//添加标注
tileArr.push(this.initLayersInfoByData("1715918445162692608"))
this.layerDatas.dcfwj.forEach(element => {
if (element.isChoice) {
//生成TileLayer
let item = this.initLayersInfoByData(element.mapId)
tileArr.push(item)
}
});
this.layerDatas.ldxb.forEach(element => {
if (element.isChoice) {
//生成TileLayer
let item = this.initLayersInfoByData(element.mapId)
tileArr.push(item)
}
});
return tileArr
},
/**
* 获取天地图底图和标注
*/
getBaseTdMap() {
let tdArr = []
//天地图底图
var tiandiLayer = new TileLayer({
source: new XYZ({
url: 'https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=2b5ee7d7bc5d7816935c790d7d112a51',
//url: 'https://tiles1.geovisearth.com/base/v1/img/{z}/{x}/{y}?token=3d2f2191d56246452b6a2635ecf2d6f584d76f9ffa738c7bf7a2e85b7e354229&tmsIds=w',
}),
isGroup: true,
name: '天地图路网'
});
//天地图标注
var tiandiLayerBz = new TileLayer({
source: new XYZ({
url: 'https://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=2b5ee7d7bc5d7816935c790d7d112a51'
}),
isGroup: true,
name: '天地图文字标注',
});
tdArr.push(tiandiLayer)
tdArr.push(tiandiLayerBz)
return tdArr;
},
/**
* 初始化地图
*/
initMap() {
let that = this;
//初始中西点坐标,最大最小缩放等级设置
const options = {
center: [108.956220, 34.979541],
zoom: 6,
minZoom: 0,
maxZoom: 18
}
//初始化地图
let layersBase = this.getBaseTdMap(); //天地图底图
let layersExts = []; //扩展图层
layersExts = this.optionLayer()
this.rtsMapObj = new Map({
// controls: ol.control.defaults({
// attribution: false
// }).extend([]),
target: 'rtsmap',
layers: [...layersBase, ...layersExts],
view: new View({
center: fromLonLat(options.center),
zoom: options.zoom,
minZoom: options.minZoom,
maxZoom: options.maxZoom
}),
controls: [new ScaleLine({ units: "metric" })]
});
},
/**
* 切换图层后重新加载地图
*/
resetZsMap() {
let allLay = this.rtsMapObj.getLayerGroup().getLayers().getArray();
for (let index = allLay.length - 1; index >= 0; index--) {
this.rtsMapObj.removeLayer(allLay[index])
}
//添加天地圖底圖
this.getBaseTdMap().forEach(element => {
this.rtsMapObj.addLayer(element)
});
//添加打開圖層
this.optionLayer().forEach(element => {
this.rtsMapObj.addLayer(element)
});
//关闭面板
this.closeLy()
},
/**
* 关闭图层面板
*/
closeLy() {
this.tcMbTogget = false;
},
/**
* 打开图层面板
*/
openLy() {
this.tcMbTogget = true;
},
/**
* 定位到当前位置
*/
startLoction() {
this.dwGnTogget = !this.dwGnTogget
if (this.dwGnTogget) {
this.positionNav = this.createLayer(this.rtsMapObj, "position");
window.addEventListener("deviceorientation", this.orientationHandler, false);
} else {
//去除监听,清理定位图标
window.removeEventListener("deviceorientation", this.orientationHandler, false);
this.clearDwMark()
}
},
/**
* 定位事件监听
* @param {*} event
*/
orientationHandler(event) {
// console.dir(event)
this.rotate = event.alpha;
if (window.navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.dwSuccCall, this.dwFailCall, {
enableHighAccuracy: true,
timeout: 1000,
maximumAge: 0,
provider: "system",
coordsType: "wgs84",
geocode: true
})
}
},
/**
* 定位成功回调
* @param {*} position
*/
dwSuccCall(position) {
// 这个网页获取到的坐标
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
// 这个公司位置的坐标,测试使用
var Currentposition = transform([longitude, latitude], "EPSG:4326", "EPSG:3857");
this.positionNav.getSource().clear();
this.addPointToMap(Currentposition, { rotation: this.rotate }, this.positionNav)
this.rtsMapObj.getView().setCenter(Currentposition);
},
/**
* 定位失败回调
* @param {*} error
*/
dwFailCall(error) {
this.positionNav.getSource().clear();
this.addPointToMap(center, { rotation: this.rotate }, this.positionNav)
map.getView().setCenter(center);
// var text;
switch (error.code) {
case error.PERMISSION_DENIED:
text = "用户拒绝对获取地理位置的请求。";
break;
case error.POSITION_UNAVAILABLE:
text = "位置信息是不可用的。";
break;
case error.TIMEOUT:
text = "请求用户地理位置超时。";
break;
case error.UNKNOWN_ERROR:
text = "未知错误。";
break;
}
},
/**
* 给地图上添加Mark
* @param {*} lngLat
* @param {*} optionsPar
* @param {*} layer
*/
addPointToMap(lngLat, optionsPar, layer) {
const options = optionsPar || {};
const name = options.name || '标注点';
const newFeature = new Feature({
geometry: new Point(lngLat), // 几何信息
name,
});
newFeature.attr = options.attr;
options.src = this.positionImg;
newFeature.setStyle(this.createIconStyle(options)); // 设置要素样式
layer.getSource().addFeature(newFeature)
},
/**
* 清除定位图标
*/
clearDwMark() {
this.positionNav.getSource().clear();
},
/**
* 创建一个图层
* @param {*} layerName
*/
createLayer(map, layerName) {
if (map) {
const vectorSource = new VectorSource({
features: [],
name: layerName,
});
const layer = new VectorLayer({
source: vectorSource,
});
layer.name = layerName;
map.addLayer(layer);
return layer;
} else {
}
},
/**
* 创建Mark样式
* @param {} optionsPar
*/
createIconStyle(optionsPar) {
const options = optionsPar || {};
const src = options.src || this.defaultMark;
const rotation = options.rotation * Math.PI / 180.0 || 0;
const anchorLeft = optionsPar.anchorLeft || 0.5;
const anchorTop = optionsPar.anchorTop || 0.5;
const scale = optionsPar.scale || 0.6;
return new Style({
image: new Icon({
anchor: [anchorLeft, anchorTop], // 锚点
anchorOrigin: 'bottom-right', // 锚点源
anchorXUnits: 'fraction', // 锚点X值单位
anchorYUnits: 'pixels', // 锚点Y值单位
offsetOrigin: 'top-right', // 偏移原点
opacity: 0.75,
src: src, // 图标的URL
rotation: -rotation,
// scale: width * 0.3 / 168.0,
scale: 0.5, //图标大小
offset: [0, 0]
}),
});
},
/**
* 打开属性面板
*/
openSxLy() {
let that = this;
that.sxGnTogget = !that.sxGnTogget;
if (that.sxGnTogget) {
//地图可点
that.rtsMapObj.on("click", (e) => {
const pixel = that.rtsMapObj.getEventPixel(e.originalEvent);
//console.dir(pixel)
let cor = that.rtsMapObj.getCoordinateFromPixel(pixel)
//console.dir(cor)
that.geomCoor = transform(cor, "EPSG:3857", "EPSG:4326")
// alert(that.geomCoor)
//这个坐标给后台 让他返回东西 geomCoor
that.getMapData();
})
} else {
//地图不可点击
that.rtsMapObj.on("click", (e) => {
that.sxVisible = false;
})
}
},
/**
* 获取服务中得data数据,且展示
*/
getMapData() {
let that = this;
that.dcshuju = [];
that.geomCoor;
let serviceArr = [];
//获取待查询得图层
that.layerDatas.dcfwj.forEach(element => {
if (element.isChoice == true) {
serviceArr.push(element.dataId)
}
})
that.layerDatas.ldxb.forEach(element => {
if (element.isChoice == true) {
serviceArr.push(element.dataId)
}
})
console.dir(serviceArr)
serviceArr.forEach(element => {
let queryParams = {
serviceId: element,
params: {
page: 1,
size: 10,
GEOJSON: "{ \"coordinates\": [ " + that.geomCoor[0] + ", " + that.geomCoor[1] + " ], \"type\": \"Point\" }"
}
}
let header = {
headers: {
"Content-Type": "application/json",
"accessToken": that.appToken
}
}
that.$axios.post("小班data数据查询地址", queryParams, header).then((res) => {
console.dir(res.data.data.data);
if (res.data.data.data && res.data.data.data.length > 0) {
that.dcshuju.push(res.data.data.data[0])
}
//返回一个数组
})
})
//延长时间执行
setTimeout(() => {
that.sxVisible = true;
}, 300)
},
/**
* 统计面板打开与否
*/
openKshLy() {
let that = this;
that.tjGnTogget = !that.tjGnTogget;
//通知移动端
that.operationAndroidKshBord()
},
/**
* 图层切换面板
* @param {*} val
*/
handleChange(val) {
console.log(val);
},
/**
* 操作Android端可视化面板
*/
operationAndroidKshBord() {
if (undefined !== window.android) {
window.android.callAndroidFun("sendKshBord", this.tjGnTogget);
}
}
},
}
</script>
<style></style>