|
|
|
<template>
|
|
|
|
<div class="m-map" :class="{ 'z-td': mapType == 'td' }">
|
|
|
|
<div id="map" :style="{ transform: `scale(${zoom})` }"></div>
|
|
|
|
<div class="btn" v-if="mapStyleType == 'light'" v-show="false" @click="shiftMapStyle('dark')">切换深色模式</div>
|
|
|
|
<div class="btn" v-show="false" v-else @click="shiftMapStyle('light')">切换浅色模式</div>
|
|
|
|
<!-- :style="{ transform: `scale(${zoom})` }" -->
|
|
|
|
<cpt-popup ref="popup" @clickListItem="handleClickDotListItem" @operate="handleClickDotBtn"/>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import {requestPost} from "@/js/dai/request";
|
|
|
|
import nextTick from "dai-js/tools/nextTick";
|
|
|
|
import {Scene, PolygonLayer, LineLayer, MarkerLayer, RasterLayer, PointLayer, Marker, Popup} from "@antv/l7";
|
|
|
|
import {GaodeMap, Map} from "@antv/l7-maps";
|
|
|
|
import {spliceIntoChunks} from "@/utils/index";
|
|
|
|
import {mapType, searchNearby} from "@/utils/dai-map";
|
|
|
|
import tdtWp from "@/utils/tdt-wp";
|
|
|
|
import tdtWpZw from "@/utils/tdt-wp-zw";
|
|
|
|
import cptPopup from "./popup";
|
|
|
|
|
|
|
|
let myMap;
|
|
|
|
let scene;
|
|
|
|
let polygonLayer;
|
|
|
|
let lineLayer;
|
|
|
|
let textLayer;
|
|
|
|
let posLayer;
|
|
|
|
let circleLayer;
|
|
|
|
let dotLayer;
|
|
|
|
let dotBgLayer;
|
|
|
|
let dotLayer2;
|
|
|
|
let searchMarker;
|
|
|
|
let searchBgLayer;
|
|
|
|
let numMarker;
|
|
|
|
let pointMarker;
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: "l7",
|
|
|
|
inject: ["refresh"],
|
|
|
|
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
mapType,
|
|
|
|
zoom: 0,
|
|
|
|
mapStyleType: localStorage.getItem("mapStyle") || "dark",
|
|
|
|
// srcGridData: {},
|
|
|
|
darkStyle: {
|
|
|
|
style: "amap://styles/blue",
|
|
|
|
polygonColor: [
|
|
|
|
// "rgba(255, 100, 60, 0.5)",
|
|
|
|
// "rgba(43, 231, 253, 0.35)",
|
|
|
|
"rgba(0, 127, 241, .3)",
|
|
|
|
// "rgba(255, 255, 50, 0.35)",
|
|
|
|
],
|
|
|
|
lineColor: [
|
|
|
|
// "rgba(255, 180, 150, 0.9)",
|
|
|
|
// "rgba(43, 231, 253, 0.7)",
|
|
|
|
"rgba(0, 127, 241, .6)",
|
|
|
|
// "rgba(255, 255, 50, 0.7)",
|
|
|
|
],
|
|
|
|
circleColor: [
|
|
|
|
// "rgba(255, 180, 150, 0.99)",
|
|
|
|
// "rgba(43, 231, 253, 0.99)",
|
|
|
|
"rgba(0, 127, 241, 0.99)",
|
|
|
|
// "rgba(255, 255, 50, 0.99)",
|
|
|
|
],
|
|
|
|
textColor: [
|
|
|
|
// "rgba(255, 100, 60, 0.99)",
|
|
|
|
// "rgba(43, 231, 253, 0.99)",
|
|
|
|
"rgba(126, 187, 255, 1)",
|
|
|
|
// "rgba(255, 255, 50, 0.99)",
|
|
|
|
],
|
|
|
|
textStrokeColor: "#fff",
|
|
|
|
},
|
|
|
|
|
|
|
|
lightStyle: {
|
|
|
|
style: "amap://styles/whitesmoke",
|
|
|
|
polygonColor: [
|
|
|
|
// "rgba(255, 100, 60, 0.3)",
|
|
|
|
"rgba(43, 231, 253, 0.3)",
|
|
|
|
// "rgba(255, 255, 50, 0.3)",
|
|
|
|
],
|
|
|
|
lineColor: [
|
|
|
|
// "rgba(220, 150, 120, 0.9)",
|
|
|
|
"rgba(33, 201, 223, 0.8)",
|
|
|
|
// "rgba(200, 200, 50, 0.9)",
|
|
|
|
],
|
|
|
|
circleColor: [
|
|
|
|
// "rgba(255, 180, 150, 0.99)",
|
|
|
|
"rgba(13, 181, 203, 0.8)",
|
|
|
|
// "rgba(255, 255, 50, 0.99)",
|
|
|
|
],
|
|
|
|
textColor: [
|
|
|
|
// "rgba(200, 50, 10, 0.99)",
|
|
|
|
"rgba(0, 130, 153, 0.99)",
|
|
|
|
// "rgba(120, 120, 0, 0.99)",
|
|
|
|
],
|
|
|
|
textStrokeColor: "#666",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
props: {
|
|
|
|
pitch: {
|
|
|
|
type: Number,
|
|
|
|
default: 60,
|
|
|
|
},
|
|
|
|
|
|
|
|
srcGridData: {
|
|
|
|
type: Object,
|
|
|
|
default: null,
|
|
|
|
},
|
|
|
|
|
|
|
|
dotList: {
|
|
|
|
type: Array,
|
|
|
|
default: () => [],
|
|
|
|
},
|
|
|
|
|
|
|
|
dotIcoList: {
|
|
|
|
type: Object,
|
|
|
|
default: () => ({}),
|
|
|
|
},
|
|
|
|
|
|
|
|
dotList2: {
|
|
|
|
type: Array,
|
|
|
|
default: () => [],
|
|
|
|
},
|
|
|
|
|
|
|
|
dotIcoList2: {
|
|
|
|
type: Object,
|
|
|
|
default: () => ({}),
|
|
|
|
},
|
|
|
|
level: {
|
|
|
|
type: String,
|
|
|
|
default: ''
|
|
|
|
}
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
cptPopup,
|
|
|
|
},
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
polygonData() {
|
|
|
|
const {srcGridData} = this;
|
|
|
|
if (!srcGridData || !srcGridData.children || !Array.isArray(srcGridData.children)) {
|
|
|
|
return {type: "FeatureCollection", features: []};
|
|
|
|
}
|
|
|
|
const polygon = [
|
|
|
|
...srcGridData.children
|
|
|
|
.filter((item) => item.coordinates.length > 0)
|
|
|
|
.map((item) => ({
|
|
|
|
type: "Feature",
|
|
|
|
properties: {
|
|
|
|
// id: item.id,
|
|
|
|
// name: item.name,
|
|
|
|
// level: item.level,
|
|
|
|
center: [item.longitude, item.latitude],
|
|
|
|
...item,
|
|
|
|
},
|
|
|
|
geometry: {
|
|
|
|
type: "Polygon",
|
|
|
|
coordinates: [
|
|
|
|
spliceIntoChunks(
|
|
|
|
item.coordinates.split(",").map((item) => parseFloat(item)),
|
|
|
|
2
|
|
|
|
).filter((item) => item.length == 2),
|
|
|
|
],
|
|
|
|
},
|
|
|
|
})),
|
|
|
|
];
|
|
|
|
return {type: "FeatureCollection", features: polygon};
|
|
|
|
},
|
|
|
|
|
|
|
|
polygonDotData() {
|
|
|
|
const {srcGridData} = this;
|
|
|
|
if (!srcGridData || !srcGridData.children || !Array.isArray(srcGridData.children)) {
|
|
|
|
return {type: "FeatureCollection", features: []};
|
|
|
|
}
|
|
|
|
const polygon = [
|
|
|
|
...srcGridData.children
|
|
|
|
.filter((item) => item.coordinates.length > 0)
|
|
|
|
.map((item) => ({
|
|
|
|
type: "Feature",
|
|
|
|
properties: {
|
|
|
|
// id: item.id,
|
|
|
|
// name: item.name,
|
|
|
|
// level: item.level,
|
|
|
|
center: [item.longitude, item.latitude],
|
|
|
|
...item,
|
|
|
|
},
|
|
|
|
geometry: {
|
|
|
|
type: "Polygon",
|
|
|
|
coordinates: [
|
|
|
|
item.latitude
|
|
|
|
? [[item.longitude, item.latitude]]
|
|
|
|
: spliceIntoChunks(
|
|
|
|
item.coordinates.split(",").map((item) => parseFloat(item)),
|
|
|
|
2
|
|
|
|
).filter((item) => item.length == 2),
|
|
|
|
],
|
|
|
|
},
|
|
|
|
})),
|
|
|
|
];
|
|
|
|
return {type: "FeatureCollection", features: polygon};
|
|
|
|
},
|
|
|
|
|
|
|
|
dotData() {
|
|
|
|
const {dotList} = this;
|
|
|
|
return {
|
|
|
|
type: "FeatureCollection",
|
|
|
|
features: [
|
|
|
|
...dotList
|
|
|
|
.filter((item) => item.latitude)
|
|
|
|
.map((item) => ({
|
|
|
|
type: "Feature",
|
|
|
|
properties: {
|
|
|
|
...item,
|
|
|
|
},
|
|
|
|
geometry: {
|
|
|
|
type: "Point",
|
|
|
|
coordinates: [parseFloat(item.longitude), parseFloat(item.latitude)],
|
|
|
|
},
|
|
|
|
})),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
dotData2() {
|
|
|
|
const {dotList2} = this;
|
|
|
|
return {
|
|
|
|
type: "FeatureCollection",
|
|
|
|
features: [
|
|
|
|
...dotList2
|
|
|
|
.filter((item) => item.latitude)
|
|
|
|
.map((item) => ({
|
|
|
|
type: "Feature",
|
|
|
|
properties: {
|
|
|
|
...item,
|
|
|
|
},
|
|
|
|
geometry: {
|
|
|
|
type: "Point",
|
|
|
|
coordinates: [parseFloat(item.longitude), parseFloat(item.latitude)],
|
|
|
|
},
|
|
|
|
})),
|
|
|
|
],
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
watch: {
|
|
|
|
srcGridData(val, oldValue) {
|
|
|
|
if (oldValue == null) {
|
|
|
|
this.iniMap();
|
|
|
|
} else {
|
|
|
|
this.updateGrid();
|
|
|
|
}
|
|
|
|
this.zoomInABit();
|
|
|
|
},
|
|
|
|
dotList(val, oldValue) {
|
|
|
|
this.updateDot();
|
|
|
|
},
|
|
|
|
dotList2(val, oldValue) {
|
|
|
|
this.updateDot();
|
|
|
|
},
|
|
|
|
"$store.state.chooseArea.realScale"(n, v) {
|
|
|
|
this.setStartScale(n);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
async mounted() {
|
|
|
|
// 临时这么用吧
|
|
|
|
window._AMapSecurityConfig = {
|
|
|
|
securityJsCode: "92ea2c965c6cf1ba7ee3a8fe01449ef2",
|
|
|
|
};
|
|
|
|
const scale = this.$store.state.chooseArea.realScale;
|
|
|
|
console.log(scale);
|
|
|
|
if (scale) {
|
|
|
|
this.setStartScale(scale);
|
|
|
|
}
|
|
|
|
this.iniMap();
|
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
setStartScale(n) {
|
|
|
|
const scale = 1 / n;
|
|
|
|
this.zoom = scale;
|
|
|
|
},
|
|
|
|
|
|
|
|
iniMap() {
|
|
|
|
const {darkStyle, lightStyle, srcGridData} = this;
|
|
|
|
if (!srcGridData) return false;
|
|
|
|
|
|
|
|
let styleConfig = darkStyle;
|
|
|
|
if (this.mapStyleType == "light") {
|
|
|
|
styleConfig = lightStyle;
|
|
|
|
}
|
|
|
|
|
|
|
|
const iniCenter = [srcGridData.longitude || this.$store.state.user.longitude || 116.39743841556731, srcGridData.latitude || this.$store.state.user.latitude || 39.9088810666821];
|
|
|
|
|
|
|
|
if (mapType != "qq") {
|
|
|
|
myMap = new Map({
|
|
|
|
center: iniCenter,
|
|
|
|
mapStyle: "amap://styles/darkblue",
|
|
|
|
zoom: 18,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
myMap = new GaodeMap({
|
|
|
|
// pitch: this.pitch,
|
|
|
|
mapStyle: "amap://styles/darkblue",
|
|
|
|
// style: styleConfig.style,
|
|
|
|
center: iniCenter,
|
|
|
|
token: "fc14b42e0ca18387866d68ebd4f150c1",
|
|
|
|
zoom: 18,
|
|
|
|
isHotspot: false,
|
|
|
|
resizeEnable: true,
|
|
|
|
doubleClickZoom: false,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
scene = new Scene({
|
|
|
|
id: "map",
|
|
|
|
logoVisible: false,
|
|
|
|
map: myMap,
|
|
|
|
});
|
|
|
|
|
|
|
|
scene.on("loaded", async () => {
|
|
|
|
if (mapType == "td") {
|
|
|
|
this.iniMapBase(scene);
|
|
|
|
} else if (mapType == "tdzw") {
|
|
|
|
this.iniMapBase2(scene);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.iniMapGrid(scene);
|
|
|
|
// this.iniMapDot(scene);
|
|
|
|
// this.iniMapDot2(scene);
|
|
|
|
// await nextTick(0);
|
|
|
|
this.zoomInABit();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
// 初始化底图
|
|
|
|
iniMapBase(scene) {
|
|
|
|
console.log("-----------------iniMapBase");
|
|
|
|
// 底图服务
|
|
|
|
const baseLayer = new RasterLayer({
|
|
|
|
zIndex: 1,
|
|
|
|
});
|
|
|
|
baseLayer
|
|
|
|
.source("http://t7.tianditu.com/DataServer?T=vec_w&tk=8a08c117ab9ee45d508686b01cc8d397&x={x}&y={y}&l={z}", {
|
|
|
|
parser: {
|
|
|
|
type: "rasterTile",
|
|
|
|
tileSize: 256,
|
|
|
|
// minZoom: 6,
|
|
|
|
// maxZoom: 15,
|
|
|
|
zoomOffset: 0,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.style({
|
|
|
|
opacity: 0.7,
|
|
|
|
});
|
|
|
|
|
|
|
|
// 注记服务
|
|
|
|
const annotionLayer = new RasterLayer({
|
|
|
|
zIndex: 2,
|
|
|
|
});
|
|
|
|
annotionLayer
|
|
|
|
.source("http://t7.tianditu.com/DataServer?T=cva_w&tk=8a08c117ab9ee45d508686b01cc8d397&x={x}&y={y}&l={z}", {
|
|
|
|
parser: {
|
|
|
|
type: "rasterTile",
|
|
|
|
tileSize: 256,
|
|
|
|
// minZoom: 6,
|
|
|
|
// maxZoom: 15,
|
|
|
|
zoomOffset: 0,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.style({
|
|
|
|
opacity: 0.5,
|
|
|
|
});
|
|
|
|
|
|
|
|
scene.addLayer(baseLayer);
|
|
|
|
scene.addLayer(annotionLayer);
|
|
|
|
},
|
|
|
|
|
|
|
|
// 初始化底图 天地图山东政务网瓦片
|
|
|
|
iniMapBase2(scene) {
|
|
|
|
console.log("-----------------iniMapBase");
|
|
|
|
// 底图服务
|
|
|
|
const baseLayer = new RasterLayer({
|
|
|
|
zIndex: 1,
|
|
|
|
});
|
|
|
|
baseLayer
|
|
|
|
.source(tdtWpZw.vec, {
|
|
|
|
parser: {
|
|
|
|
type: "rasterTile",
|
|
|
|
tileSize: 256,
|
|
|
|
zoomOffset: 0,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
.style({
|
|
|
|
opacity: 0.7,
|
|
|
|
});
|
|
|
|
|
|
|
|
scene.addLayer(baseLayer);
|
|
|
|
},
|
|
|
|
|
|
|
|
iniMapGrid(scene) {
|
|
|
|
const {darkStyle, lightStyle, polygonData, polygonDotData} = this;
|
|
|
|
|
|
|
|
let styleConfig = darkStyle;
|
|
|
|
if (this.mapStyleType == "light") {
|
|
|
|
styleConfig = lightStyle;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("地图初始化数据", polygonData);
|
|
|
|
|
|
|
|
// 画区域面积
|
|
|
|
polygonLayer = new PolygonLayer({
|
|
|
|
autoFit: true,
|
|
|
|
})
|
|
|
|
// .size(0)
|
|
|
|
.source(polygonData)
|
|
|
|
.color("name", styleConfig.polygonColor)
|
|
|
|
// .shape("extrude")
|
|
|
|
.shape("fill")
|
|
|
|
.style({
|
|
|
|
opacityLinear: {
|
|
|
|
enable: true, // true - false
|
|
|
|
dir: "out", // in - out
|
|
|
|
},
|
|
|
|
opacity: 1,
|
|
|
|
// heightfixed: true,
|
|
|
|
// pickLight: true,
|
|
|
|
raisingHeight: 0,
|
|
|
|
// sourceColor: "#333",
|
|
|
|
// targetColor: "rgba(255,255,255, 0.5)",
|
|
|
|
});
|
|
|
|
|
|
|
|
scene.addLayer(polygonLayer);
|
|
|
|
|
|
|
|
// 画区域边
|
|
|
|
lineLayer = new LineLayer({
|
|
|
|
zIndex: 2,
|
|
|
|
name: "line2",
|
|
|
|
})
|
|
|
|
.source(polygonData)
|
|
|
|
.shape("line")
|
|
|
|
.size(1)
|
|
|
|
.color("name", styleConfig.lineColor)
|
|
|
|
.style({
|
|
|
|
opacity: 1,
|
|
|
|
})
|
|
|
|
.animate({
|
|
|
|
interval: 1, // 间隔
|
|
|
|
duration: 2, // 持续时间,延时
|
|
|
|
trailLength: 2, // 流线长度
|
|
|
|
});
|
|
|
|
scene.addLayer(lineLayer);
|
|
|
|
|
|
|
|
// 画区域中心点的波纹小圆圈
|
|
|
|
circleLayer = new PolygonLayer({
|
|
|
|
zIndex: 3,
|
|
|
|
})
|
|
|
|
.source(polygonDotData)
|
|
|
|
.color("name", styleConfig.circleColor)
|
|
|
|
.shape("circle")
|
|
|
|
.active(true)
|
|
|
|
.animate(true)
|
|
|
|
.size(50)
|
|
|
|
.style({
|
|
|
|
offsets: [0, -10], // 文本相对锚点的偏移量 [水平, 垂直]
|
|
|
|
opacity: 1,
|
|
|
|
});
|
|
|
|
// scene.addLayer(circleLayer);
|
|
|
|
scene.addImage("pos-red", require("@/assets/img/shuju/grid/pos-red.png"));
|
|
|
|
scene.addImage("pos-green", require("@/assets/img/shuju/grid/pos-green.png"));
|
|
|
|
scene.addImage("pos-yellow", require("@/assets/img/shuju/grid/pos-yellow.png"));
|
|
|
|
|
|
|
|
posLayer = new PointLayer({
|
|
|
|
zIndex: 4,
|
|
|
|
name: 'gridPoint',
|
|
|
|
visible: false
|
|
|
|
})
|
|
|
|
.source(polygonDotData)
|
|
|
|
.shape("name", [
|
|
|
|
// "pos-red",
|
|
|
|
"pos-green",
|
|
|
|
// "pos-yellow"
|
|
|
|
])
|
|
|
|
.size(12)
|
|
|
|
.style({
|
|
|
|
options: this.level === 'grid' ? 1 : 0,
|
|
|
|
offsets: [0, 0],
|
|
|
|
|
|
|
|
});
|
|
|
|
// scene.addLayer(posLayer);
|
|
|
|
console.log(this.level)
|
|
|
|
/* if (this.level === 'grid') {
|
|
|
|
posLayer.show()
|
|
|
|
} else {
|
|
|
|
posLayer.hide()
|
|
|
|
}*/
|
|
|
|
textLayer = new PolygonLayer({
|
|
|
|
zIndex: 20,
|
|
|
|
})
|
|
|
|
.source(polygonData)
|
|
|
|
.color("name", styleConfig.textColor)
|
|
|
|
.shape("name", "text")
|
|
|
|
.size(16)
|
|
|
|
.style({
|
|
|
|
textAnchor: "center", // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
|
|
|
textOffset: [0, 40], // 文本相对锚点的偏移量 [水平, 垂直]
|
|
|
|
spacing: 2, // 字符间距
|
|
|
|
padding: [2, 2], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
|
|
|
stroke: styleConfig.textStrokeColor, // 描边颜色
|
|
|
|
strokeWidth: 0.1, // 描边宽度
|
|
|
|
strokeOpacity: 0.8,
|
|
|
|
textAllowOverlap: true,
|
|
|
|
})
|
|
|
|
.active(true);
|
|
|
|
scene.addLayer(textLayer);
|
|
|
|
|
|
|
|
polygonLayer.on("mousemove", (e) => {
|
|
|
|
if (this.level === 'grid') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
const popup = new Popup({
|
|
|
|
offsets: [60, 60],
|
|
|
|
closeButton: false,
|
|
|
|
maxWidth: 400,
|
|
|
|
})
|
|
|
|
.setLnglat(e.lngLat)
|
|
|
|
.setHTML(`
|
|
|
|
<div class="jw-popup-container">
|
|
|
|
<div class="jw-popup-bg"></div>
|
|
|
|
<div class="jw-popup-con">
|
|
|
|
<div class="jw-popup-title">
|
|
|
|
${e.feature.properties.name}
|
|
|
|
</div>
|
|
|
|
<div class="jw-popup-des">
|
|
|
|
${e.feature.properties.description ? e.feature.properties.description : ''}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
`);
|
|
|
|
scene.addPopup(popup);
|
|
|
|
});
|
|
|
|
polygonLayer.on("click", (e) => {
|
|
|
|
console.log(this.level)
|
|
|
|
if (this.level === 'grid') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (numMarker) {
|
|
|
|
scene.removeMarkerLayer(numMarker);
|
|
|
|
|
|
|
|
}
|
|
|
|
if (pointMarker) {
|
|
|
|
scene.removeMarkerLayer(pointMarker);
|
|
|
|
}
|
|
|
|
console.log("e", e);
|
|
|
|
this.$emit("clickAgency", e.feature.properties);
|
|
|
|
|
|
|
|
});
|
|
|
|
posLayer.on('click', (e) => {
|
|
|
|
console.log(e)
|
|
|
|
});
|
|
|
|
|
|
|
|
},
|
|
|
|
clearMarkert() {
|
|
|
|
if (numMarker) {
|
|
|
|
scene.removeMarkerLayer(numMarker);
|
|
|
|
|
|
|
|
}
|
|
|
|
if (pointMarker) {
|
|
|
|
scene.removeMarkerLayer(pointMarker);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
iniMapDot(scene) {
|
|
|
|
const {darkStyle, lightStyle, dotIcoList, dotData} = this;
|
|
|
|
Object.keys(dotIcoList).forEach((k) => {
|
|
|
|
scene.addImage(k, dotIcoList[k]);
|
|
|
|
});
|
|
|
|
dotBgLayer = new PointLayer({
|
|
|
|
zIndex: 20,
|
|
|
|
})
|
|
|
|
.source(dotData)
|
|
|
|
.shape("circle")
|
|
|
|
.color("rgba(255,255,255,0.8)")
|
|
|
|
.size(20)
|
|
|
|
.style({
|
|
|
|
strokeWidth: 3,
|
|
|
|
strokeOpacity: 0.1,
|
|
|
|
stroke: "#000",
|
|
|
|
});
|
|
|
|
scene.addLayer(dotBgLayer);
|
|
|
|
|
|
|
|
dotLayer = new PointLayer({
|
|
|
|
zIndex: 21,
|
|
|
|
})
|
|
|
|
.source(dotData)
|
|
|
|
.shape("categoryKey", (k) => k)
|
|
|
|
.size(10)
|
|
|
|
.style({
|
|
|
|
offsets: [0, 0],
|
|
|
|
layerType: "fillImage",
|
|
|
|
});
|
|
|
|
scene.addLayer(dotLayer);
|
|
|
|
|
|
|
|
dotBgLayer.on("click", (e) => {
|
|
|
|
console.log(e.feature.properties);
|
|
|
|
this.$emit("clickDot", e.feature.properties);
|
|
|
|
});
|
|
|
|
|
|
|
|
dotBgLayer.on("mousemove", (e) => {
|
|
|
|
// console.log(e);
|
|
|
|
if (e.feature.properties.content) {
|
|
|
|
const popup = new Popup({
|
|
|
|
offsets: [0, -0],
|
|
|
|
closeButton: false,
|
|
|
|
})
|
|
|
|
.setLnglat(e.feature.geometry.coordinates)
|
|
|
|
.setHTML(`<span>${e.feature.properties.content}</span>`);
|
|
|
|
scene.addPopup(popup);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
dotBgLayer.on("unmousemove", (e) => {
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
iniMapDot2(scene) {
|
|
|
|
const {dotIcoList2: dotIcoList, dotData2: dotData} = this;
|
|
|
|
Object.keys(dotIcoList).forEach((k) => {
|
|
|
|
scene.addImage(k, dotIcoList[k]);
|
|
|
|
});
|
|
|
|
|
|
|
|
dotLayer2 = new PointLayer({
|
|
|
|
zIndex: 21,
|
|
|
|
})
|
|
|
|
.source(dotData)
|
|
|
|
.shape("categoryKey", (k) => k)
|
|
|
|
.size(20)
|
|
|
|
.style({
|
|
|
|
offsets: [0, 0],
|
|
|
|
layerType: "fillImage",
|
|
|
|
});
|
|
|
|
scene.addLayer(dotLayer2);
|
|
|
|
|
|
|
|
dotLayer2.on("click", (e) => {
|
|
|
|
console.log(e.feature.properties);
|
|
|
|
this.$emit("clickDot", e.feature.properties);
|
|
|
|
});
|
|
|
|
|
|
|
|
dotLayer2.on("mousemove", (e) => {
|
|
|
|
// console.log(e);
|
|
|
|
if (e.feature.properties.content) {
|
|
|
|
const popup = new Popup({
|
|
|
|
offsets: [0, -0],
|
|
|
|
closeButton: false,
|
|
|
|
})
|
|
|
|
.setLnglat(e.feature.geometry.coordinates)
|
|
|
|
.setHTML(`<span>${e.feature.properties.content}</span>`);
|
|
|
|
scene.addPopup(popup);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
dotLayer2.on("unmousemove", (e) => {
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
// 把地图缩放等级在原来基础上大一点
|
|
|
|
zoomInABit() {
|
|
|
|
let current = scene.getZoom();
|
|
|
|
scene.setZoomAndCenter(current + 0.5);
|
|
|
|
},
|
|
|
|
|
|
|
|
shiftMapStyle(type) {
|
|
|
|
this.mapStyleType = type;
|
|
|
|
localStorage.setItem("mapStyle", type);
|
|
|
|
this.refresh();
|
|
|
|
},
|
|
|
|
|
|
|
|
updateMap() {
|
|
|
|
this.updateGrid();
|
|
|
|
this.updateDot();
|
|
|
|
this.updateDot2();
|
|
|
|
},
|
|
|
|
|
|
|
|
updateGrid() {
|
|
|
|
const {polygonData, polygonDotData} = this;
|
|
|
|
if (polygonLayer) {
|
|
|
|
polygonLayer.setData(polygonData);
|
|
|
|
lineLayer.setData(polygonData);
|
|
|
|
textLayer.setData(polygonDotData);
|
|
|
|
/* posLayer.setData(polygonDotData);
|
|
|
|
// let gridPoint = scene.getLayerByName('gridPoint')
|
|
|
|
if (this.level === 'grid') {
|
|
|
|
posLayer.show()
|
|
|
|
} else {
|
|
|
|
posLayer.hide()
|
|
|
|
}*/
|
|
|
|
circleLayer.setData(polygonDotData);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
updateDot() {
|
|
|
|
const {dotData} = this;
|
|
|
|
if (dotLayer) {
|
|
|
|
console.log(dotData);
|
|
|
|
dotLayer.setData(dotData);
|
|
|
|
dotBgLayer.setData(dotData);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
updateDot2() {
|
|
|
|
const {dotData2: dotData} = this;
|
|
|
|
if (dotLayer2) {
|
|
|
|
console.log(dotData);
|
|
|
|
dotLayer2.setData(dotData);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
drawSearchBg(lng, lat) {
|
|
|
|
function getPoints(lng, lat) {
|
|
|
|
// lng 经度;lat 纬度;dis 距离(千米)
|
|
|
|
let r = 6371; //地球半径千米
|
|
|
|
let dis = 0.25; //3千米距离
|
|
|
|
let dlng = 2 * Math.asin(Math.sin(dis / (2 * r)) / Math.cos((lat * Math.PI) / 180));
|
|
|
|
dlng = (dlng * 180) / Math.PI; // 经度半径
|
|
|
|
let dlat = dis / r;
|
|
|
|
dlat = (dlat * 180) / Math.PI; // 纬度半径
|
|
|
|
// 圆形每一度 都算出一个经纬度
|
|
|
|
for (let sides = 1; sides <= 360; sides++) {
|
|
|
|
var angle = Math.PI * (1 / sides - 1 / 2);
|
|
|
|
var rotatedAngle, x, y;
|
|
|
|
var points = [];
|
|
|
|
for (var i = 0; i < sides; ++i) {
|
|
|
|
rotatedAngle = angle + (i * 2 * Math.PI) / sides;
|
|
|
|
x = lng + dlng * Math.cos(rotatedAngle);
|
|
|
|
y = lat + dlat * Math.sin(rotatedAngle);
|
|
|
|
points.push([x, y]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log("points=======", points);
|
|
|
|
return points;
|
|
|
|
}
|
|
|
|
|
|
|
|
let sourceData;
|
|
|
|
if (lng) {
|
|
|
|
sourceData = {
|
|
|
|
type: "FeatureCollection",
|
|
|
|
features: [
|
|
|
|
{
|
|
|
|
type: "Feature",
|
|
|
|
properties: {
|
|
|
|
center: [lng, lat],
|
|
|
|
},
|
|
|
|
geometry: {
|
|
|
|
type: "Polygon",
|
|
|
|
coordinates: [getPoints(lng, lat)],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
sourceData = {
|
|
|
|
type: "FeatureCollection",
|
|
|
|
features: [],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (searchBgLayer) {
|
|
|
|
console.log("searchBgLayer已经存在了", searchBgLayer);
|
|
|
|
searchBgLayer.setData(sourceData);
|
|
|
|
} else {
|
|
|
|
searchBgLayer = new PolygonLayer({
|
|
|
|
// autoFit: true,
|
|
|
|
})
|
|
|
|
.source(sourceData)
|
|
|
|
.color("#f0f")
|
|
|
|
.shape("fill")
|
|
|
|
.style({
|
|
|
|
opacityLinear: {
|
|
|
|
enable: true, // true - false
|
|
|
|
dir: "out", // in - out
|
|
|
|
},
|
|
|
|
opacity: 0.3,
|
|
|
|
raisingHeight: 0,
|
|
|
|
});
|
|
|
|
|
|
|
|
scene.addLayer(searchBgLayer);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setPoint(data) {
|
|
|
|
this.clearMarkert()
|
|
|
|
pointMarker = new MarkerLayer({
|
|
|
|
name: 'pointMarker'
|
|
|
|
})
|
|
|
|
for (let i in data) {
|
|
|
|
console.log(data[i].longitude * 1, data[i].latitude * 1)
|
|
|
|
var el = document.createElement('div');
|
|
|
|
el.className = 'label-point-class';
|
|
|
|
el.classList.add(data[i].type)
|
|
|
|
// el.textContent = data[i].peopleType+':'+data[i].personnelNum;
|
|
|
|
const pointMarkerItem = new Marker({
|
|
|
|
offsets: [0, 0],
|
|
|
|
element: el,
|
|
|
|
}).setLnglat([data[i].longitude * 1, data[i].latitude * 1]);
|
|
|
|
let popup
|
|
|
|
pointMarkerItem.on("mouseover", () => {
|
|
|
|
popup = new Popup({
|
|
|
|
offsets: [60, 60],
|
|
|
|
closeButton: false,
|
|
|
|
maxWidth: 400,
|
|
|
|
})
|
|
|
|
.setLnglat([data[i].longitude * 1, data[i].latitude * 1])
|
|
|
|
.setHTML(`
|
|
|
|
<div class="jw-popup-container">
|
|
|
|
<div class="jw-popup-con">
|
|
|
|
<div class="jw-popup-title">
|
|
|
|
${data[i].name}
|
|
|
|
</div>
|
|
|
|
<div class="jw-popup-type">网格类型:<span class="${data[i].type}">${
|
|
|
|
data[i].type === 'red' ? "红" :
|
|
|
|
data[i].type === 'yellow' ? "黄" :
|
|
|
|
data[i].type === 'green' ? "绿色" : ''}</span>
|
|
|
|
</div>
|
|
|
|
<div class="jw-popup-num-list">
|
|
|
|
<div>户数:<span>${data[i].houseNum ? data[i].houseNum : 0}</span></div>
|
|
|
|
<div>需求:<span>${data[i].demandNum ? data[i].demandNum : 0}</span></div>
|
|
|
|
<div>事件:<span>${data[i].eventNum ? data[i].eventNum : 0}</span></div>
|
|
|
|
<div>重点人群:<span>${data[i].importanceNum ? data[i].importanceNum : 0}</span></div>
|
|
|
|
<div>安全隐患:<span>${data[i].safetyNum ? data[i].safetyNum : 0}</span></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
`);
|
|
|
|
scene.addPopup(popup);
|
|
|
|
});
|
|
|
|
pointMarkerItem.on("mouseout", () => {
|
|
|
|
popup.remove()
|
|
|
|
})
|
|
|
|
pointMarkerItem.on("click", () => {
|
|
|
|
this.$router.push('/homeDetails/index?id='+data[i].id)
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
pointMarker.addMarker(pointMarkerItem)
|
|
|
|
|
|
|
|
}
|
|
|
|
scene.addMarkerLayer(pointMarker);
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
setNum(data) {
|
|
|
|
if (numMarker) {
|
|
|
|
scene.removeMarkerLayer(numMarker);
|
|
|
|
}
|
|
|
|
numMarker = new MarkerLayer({
|
|
|
|
name: 'numMarker'
|
|
|
|
})
|
|
|
|
for (let i in data) {
|
|
|
|
var el = document.createElement('label');
|
|
|
|
el.className = 'label-num-class';
|
|
|
|
el.textContent = data[i].peopleType + ':' + data[i].personnelNum;
|
|
|
|
const numMarkerItem = new Marker({
|
|
|
|
element: el,
|
|
|
|
offsets: [0, 40],
|
|
|
|
}).setLnglat([data[i].longitude * 1, data[i].latitude]);
|
|
|
|
numMarker.addMarker(numMarkerItem)
|
|
|
|
}
|
|
|
|
scene.addMarkerLayer(numMarker);
|
|
|
|
},
|
|
|
|
async setDotMarker(item, posArr) {
|
|
|
|
this.removeDotMarker();
|
|
|
|
this.drawSearchBg(...posArr);
|
|
|
|
const marker = new Marker({
|
|
|
|
offsets: [0, -20],
|
|
|
|
}).setLnglat(posArr);
|
|
|
|
|
|
|
|
const res = await this.$refs.popup.show(item);
|
|
|
|
if (res) {
|
|
|
|
const popup = new Popup({
|
|
|
|
closeButton: true,
|
|
|
|
closeOnClick: true,
|
|
|
|
maxWidth: 400,
|
|
|
|
})
|
|
|
|
.setLnglat(posArr)
|
|
|
|
.setDOMContent(this.$refs.popup.$el);
|
|
|
|
marker.setPopup(popup);
|
|
|
|
}
|
|
|
|
|
|
|
|
marker.on("click", (e) => {
|
|
|
|
console.log("click", e);
|
|
|
|
// this.handleClickDot(item, posArr);
|
|
|
|
marker.openPopup();
|
|
|
|
});
|
|
|
|
|
|
|
|
scene.addMarker(marker);
|
|
|
|
scene.setZoomAndCenter(14, posArr);
|
|
|
|
marker.openPopup();
|
|
|
|
searchMarker = marker;
|
|
|
|
},
|
|
|
|
|
|
|
|
removeDotMarker() {
|
|
|
|
console.log("removeDotMarker");
|
|
|
|
if (searchMarker) {
|
|
|
|
searchMarker.remove();
|
|
|
|
}
|
|
|
|
if (searchBgLayer) {
|
|
|
|
console.log("removeDotMarker-----searchBgLayer");
|
|
|
|
this.drawSearchBg();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
async handleClickDot(item, posArr) {
|
|
|
|
console.log("handleClickDot", item, posArr);
|
|
|
|
const res = await this.$refs.popup.show(item);
|
|
|
|
if (res) {
|
|
|
|
const popup = new Popup({
|
|
|
|
closeButton: true,
|
|
|
|
closeOnClick: true,
|
|
|
|
maxWidth: 400,
|
|
|
|
})
|
|
|
|
.setLnglat(posArr)
|
|
|
|
.setDOMContent(this.$refs.popup.$el);
|
|
|
|
scene.addPopup(popup);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
handleClickDotBtn(type, info) {
|
|
|
|
console.log(type, info);
|
|
|
|
this.$emit("clickDotBtn", type, info);
|
|
|
|
},
|
|
|
|
|
|
|
|
handleClickDotListItem(item) {
|
|
|
|
console.log("handleClickDotListItem", item);
|
|
|
|
this.handleClickDot(item, [parseFloat(item.longitude), parseFloat(item.latitude)]);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.m-map {
|
|
|
|
position: relative;
|
|
|
|
height: 100%;
|
|
|
|
border-radius: 10px;
|
|
|
|
overflow: hidden;
|
|
|
|
background: transparent;
|
|
|
|
|
|
|
|
&::after {
|
|
|
|
position: absolute;
|
|
|
|
content: "";
|
|
|
|
display: block;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
right: 0;
|
|
|
|
bottom: 0;
|
|
|
|
pointer-events: none;
|
|
|
|
background: radial-gradient(rgba(#020c38, 0) 0%, rgba(#020c38, 0) 60%, rgba(#020c38, 1) 85%, rgba(#020c38, 1) 100%);
|
|
|
|
}
|
|
|
|
|
|
|
|
&.z-td {
|
|
|
|
#app {
|
|
|
|
/deep/ .l7-scene {
|
|
|
|
canvas {
|
|
|
|
background-color: rgba(43, 51, 73, 0.82);
|
|
|
|
background-image: radial-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3), #000);
|
|
|
|
}
|
|
|
|
|
|
|
|
.gray {
|
|
|
|
-webkit-filter: grayscale(100%);
|
|
|
|
filter: grayscale(100%);
|
|
|
|
opacity: 0.7;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .l7-popup {
|
|
|
|
z-index: 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .l7-popup-content {
|
|
|
|
//background: rgba(#fff, 1);
|
|
|
|
background: rgba(3, 31, 73, 0.72);
|
|
|
|
border: 1px solid #74C9FF;
|
|
|
|
opacity: 0.9;
|
|
|
|
border-radius: 5px;
|
|
|
|
color: #fff;
|
|
|
|
box-shadow: 0 0 20px 3px inset rgba(#22f, 0.1);
|
|
|
|
width: 416px;
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .l7-popup-close-button {
|
|
|
|
padding: 4px;
|
|
|
|
font-size: 36px;
|
|
|
|
color: rgba(#fff, 0.8);
|
|
|
|
}
|
|
|
|
|
|
|
|
#map {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
#searchMap {
|
|
|
|
position: absolute;
|
|
|
|
width: 200px;
|
|
|
|
height: 200px;
|
|
|
|
visibility: hidden;
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.btn {
|
|
|
|
position: absolute;
|
|
|
|
bottom: 0;
|
|
|
|
left: 0;
|
|
|
|
width: 100px;
|
|
|
|
line-height: 36px;
|
|
|
|
height: 36px;
|
|
|
|
text-align: center;
|
|
|
|
color: #ffffff;
|
|
|
|
font-size: 14px;
|
|
|
|
background-color: rgba(#000, 0.2);
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
/deep/ .label-num-class {
|
|
|
|
font-size: 16px;
|
|
|
|
font-weight: 500;
|
|
|
|
color: #FFFFFF;
|
|
|
|
background: rgba(3, 31, 73, 0.72);
|
|
|
|
border: 1px solid #74C9FF;
|
|
|
|
opacity: 0.9;
|
|
|
|
border-radius: 100px;
|
|
|
|
padding: 3px 13px;
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .l7-popup-tip {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .jw-popup-bg {
|
|
|
|
background: url('@/assets/images/overview/map-pop-img.png') no-repeat;
|
|
|
|
width: 80px;
|
|
|
|
height: 80px;
|
|
|
|
margin-right: 10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .jw-popup-container {
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .jw-popup-con {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .jw-popup-title {
|
|
|
|
font-size: 20px;
|
|
|
|
font-family: HYShuYuanHeiJ;
|
|
|
|
font-weight: 400;
|
|
|
|
color: #FFFFFF;
|
|
|
|
background: linear-gradient(0deg, #2DC1FF 0%, #FFFFFF 58.5205078125%);
|
|
|
|
-webkit-background-clip: text;
|
|
|
|
-webkit-text-fill-color: transparent;
|
|
|
|
margin-bottom: 16px;
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .jw-popup-des {
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: 400;
|
|
|
|
color: #FFFFFF;
|
|
|
|
line-height: 22px;
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .label-point-class {
|
|
|
|
width: 32px;
|
|
|
|
height: 32px;
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
|
|
|
&.green {
|
|
|
|
background-image: url("@/assets/images/overview/green.png");
|
|
|
|
}
|
|
|
|
|
|
|
|
&.red {
|
|
|
|
background-image: url("@/assets/images/overview/red.png");
|
|
|
|
}
|
|
|
|
|
|
|
|
&.yellow {
|
|
|
|
background-image: url("@/assets/images/overview/yellow.png");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .jw-popup-type {
|
|
|
|
margin: 16px 0 21px;
|
|
|
|
|
|
|
|
.red {
|
|
|
|
color: #FC561F;
|
|
|
|
}
|
|
|
|
|
|
|
|
.yellow {
|
|
|
|
color: #FAB93F;
|
|
|
|
}
|
|
|
|
|
|
|
|
.green {
|
|
|
|
color: #08EBAD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/deep/ .jw-popup-num-list {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
& > div {
|
|
|
|
flex: 0 0 131px;
|
|
|
|
width: 131px;
|
|
|
|
height: 14px;
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: 400;
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
|
|
|
span {
|
|
|
|
font-size: 18px;
|
|
|
|
font-weight: 500;
|
|
|
|
color: #FFAA01;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|