You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

767 lines
20 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div :id="mapContainerName" class="map-container">
<div class="search-container-box">
<SearchComponent @toPosition="toPosition" @handlerFilter="handlerFilter"></SearchComponent>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, defineExpose, defineEmits } from "vue";
import { generateUUID } from '@/components/MapboxMaps/src/tool'
import { WktToGeojson } from '@/components/MapboxMaps/src/WktGeojsonTransform';
import mapboxgl, { Map, Popup } from 'mapbox-gl';
import { MAPBOX_TOKEN, TINADITU_TOKEN, MAP_VIEWER } from '@/views/sys/exception/Converge/config'
import { getPolygonCenter, getUserOrgs } from '@/api/tiankongdi'
import axios from 'axios'
import SearchComponent from './SearchComponent/index.vue'
const { VITE_GLOB_YINGXIANG_SERVER } = getAppEnvConfig();
import { getAppEnvConfig } from '@/utils/env';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const VITE_GLOB_API_URL_VAR = ref<String>(VITE_GLOB_API_URL);
const mapContainerName = ref<String>()
mapContainerName.value = "mapContainer-" + generateUUID();
//
const emits = defineEmits(["onload", "handlerGetDetails"])
let map: Map;
// init map
const initMap = () => {
return new mapboxgl.Map({
container: mapContainerName.value,
language: 'zh-cmn',
projection: 'equirectangular', // wgs84参考系
style: {
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
version: 8,
sources: {
'raster-tiles': {
type: 'raster',
tiles: [
`http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${TINADITU_TOKEN}`,
],
tileSize: 256,
},
'raster-tiles-font': {
type: 'raster',
tiles: [
`https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${TINADITU_TOKEN}`,
],
tileSize: 256,
},
// 'raster-tiles-geo': {
// type: 'raster',
// tiles: [
// VITE_GLOB_YINGXIANG_SERVER,
// ],
// tileSize: 256,
// }
},
layers: [
{
id: 'tdt-vec-tiles',
type: 'raster',
source: 'raster-tiles-font',
maxZoom: 32,
},
{
id: 'tdt-img-tiles',
type: 'raster',
source: 'raster-tiles',
maxZoom: 32,
},
// {
// id: 'tdt-wms-tiles',
// type: 'raster',
// source: 'raster-tiles-geo',
// },
],
},
maxZoom: 22,
minZoom: 8,
zoom: 10,
pitch: 0,
center: [117.984425, 35.270654],
});
};
// 获取线索面数据
const mainPolygonVisibility = ref<String>("visible");
const isRootLevel = ref<Boolean>(false)
async function handlerCheckUserOrgs() {
let orgs = await getUserOrgs({});
let isLevel = orgs.find((item, index) => {
return (item.name == "临沂市" || item.parentId == 0 || item.parentName == "根节点");
})
if (isLevel) {
isRootLevel.value = true;
handlerLoadPolygon("", "", "", "1")
} else {
isRootLevel.value = false;
handlerLoadPolygon()
}
}
function handlerLoadPolygon(code = "", filter = "", type = "", level = "") {
let sql_filter;
if (code) {
sql_filter = "&filter=\"countyid\"=\'" + code + "\'";
} else {
sql_filter = ""
}
let main_map_filter;
switch (filter) {
case "合法":
main_map_filter = ["all", ["==", ["get", "is_illegal"], 1], ["==", ["get", "handle_status_id"], 99]];
break;
case "其他":
main_map_filter = ["all", ["==", ["get", "is_illegal"], 3], ["==", ["get", "handle_status_id"], 99]];
break;
case "开采违法":
main_map_filter = ["all", ["==", ["get", "is_illegal"], 2], ["==", ["get", "typename"], "开采"], ["==", ["get", "handle_status_id"], 99]];
break;
case "加工违法":
main_map_filter = ["all", ["==", ["get", "is_illegal"], 2], ["==", ["get", "typename"], "加工"], ["==", ["get", "handle_status_id"], 99]];
break;
default:
main_map_filter = ["!=", ["get", "gid"], 0];
}
if (map.getSource("mainHistoryLayerLine")) {
mainPolygonVisibility.value = map.getLayoutProperty('mainHistoryLayerLine', 'visibility');
map.removeLayer("mainHistoryLayerLine")
map.removeLayer("mainHistoryLayerFill")
map.removeSource("mainHistoryLayerLine")
map.removeSource("mainHistoryLayerFill");
}
if (level) {
} else {
sql_filter = '&filter=streetid in ( select CAST(\"OrgId\" AS VARCHAR) from sys_userorg where \"UserId\" = ' + localStorage.getItem('userid') + ') or countyid in ( select CAST(\"OrgId\" AS VARCHAR) from sys_userorg where \"UserId\" = ' + localStorage.getItem('userid') + ')'
}
map.addLayer(
{
'id': 'mainHistoryLayerLine',
'type': 'line',
'source': {
type: 'vector',
tiles: [VITE_GLOB_API_URL_VAR.value + '/api/DroneCaseInfoSingle/QueryVectorTileByTable?z={z}&x={x}&y={y}&table=view_drone_caseinfo_minerals' + sql_filter + '&field=\"gid\",\"handle_status_id\",\"is_illegal\",\"typename\",\"Id\",'],
minzoom: 1,
maxzoom: 20,
'cluster': true, // 启用聚合
'clusterMaxZoom': 0, // 最大聚合缩放级别
'clusterRadius': 0 // 聚合半径
},
"source-layer": "view_drone_caseinfo_minerals",
'layout': {
'line-join': 'round',
'line-cap': 'round',
'visibility': mainPolygonVisibility.value,
},
'filter': main_map_filter,
'paint': {
'line-color': [
"case",
["all", ["==", ["get", "is_illegal"], 1], ["==", ["get", "handle_status_id"], 99]], //合法
"#0AF703",
["all", ["==", ["get", "is_illegal"], 3], ["==", ["get", "handle_status_id"], 99]], //其他
"#0382F7",
["all", ["==", ["get", "is_illegal"], 2], ["==", ["get", "handle_status_id"], 99], ["==", ["get", "typename"], '加工']], //加工违法
"#AD04F4",
["all", ["==", ["get", "is_illegal"], 2], ["==", ["get", "handle_status_id"], 99], ["==", ["get", "typename"], '开采']], //开采违法
"#F70303",
// 默认
"#F4E004",
],
'line-width': 5
}
}
)
map.addLayer({
'id': 'mainHistoryLayerFill',
'type': 'fill',
'source': {
type: 'vector',
tiles: [VITE_GLOB_API_URL_VAR.value + '/api/DroneCaseInfoSingle/QueryVectorTileByTable?z={z}&x={x}&y={y}&table=view_drone_caseinfo_minerals' + sql_filter + '&field=\"gid\",\"handle_status_id\",\"is_illegal\",\"typename\",\"Id\",'],
minzoom: 1,
maxzoom: 20,
cluster: false
},
"source-layer": "view_drone_caseinfo_minerals",
'filter': main_map_filter,
'layout': {
'visibility': mainPolygonVisibility.value,
},
'paint': {
'fill-color': [
"case",
["all", ["==", ["get", "is_illegal"], 1], ["==", ["get", "handle_status_id"], 99]], //合法
"#0AF703",
["all", ["==", ["get", "is_illegal"], 3], ["==", ["get", "handle_status_id"], 99]], //其他
"#0382F7",
["all", ["==", ["get", "is_illegal"], 2], ["==", ["get", "handle_status_id"], 99], ["==", ["get", "typename"], '加工']], //加工违法
"#AD04F4",
["all", ["==", ["get", "is_illegal"], 2], ["==", ["get", "handle_status_id"], 99], ["==", ["get", "typename"], '开采']], //开采违法
"#F70303",
// 默认
"#F4E004",
],
'fill-opacity': 0.5
}
})
emits("onload");
map.on("click", "mainHistoryLayerFill", (e) => {
emits("handlerGetDetails", e.features[0].properties);
})
}
// 获取和处理线索点数据
const currentCode = ref("")
async function handlerDealPoint(code = "") {
let sql_filter;
if (code) {
sql_filter = "\"countyid\"=\'" + code + "\'";
} else {
sql_filter = ""
}
let points = await getPolygonCenter({ tablename: "view_drone_caseinfo_wpxf", filter: sql_filter })
let heatdata = {
type: "FeatureCollection",
features: []
}
points?.forEach((item, index) => {
let geometry = WktToGeojson(item['centroid_point']);
let feature = {
geometry: geometry,
properties: {
mag: 1
}
}
heatdata.features.push(feature);
})
handlerLoadHeatLayer(heatdata);
if (map.getLayer('clusters')) {
map.moveLayer("clusters", "heatLayer");
map.moveLayer("cluster-count", "heatLayer")
map.moveLayer("unclustered-point", "heatLayer")
}
}
function toPosition(item) {
handlerLocation(item, 17.2);
handlerLoadSearchResult(item);
}
function handlerFilter(item) {
console.log(item)
// handlerLoadPolygon("",item);
if (isRootLevel.value) {
handlerLoadPolygon("", item, "", "1");
} else {
handlerLoadPolygon("", item, "", "");
}
}
function handlerLoadSearchResult(item) {
let geojson = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: item.location,
},
properties: {
name: item.id,
},
},
],
};
}
// 加载热力图线索数据
function handlerLoadHeatLayer(heatdata) {
if (map.getSource("heatSource")) {
map.getSource("heatSource").setData(heatdata);
} else {
map.addSource('heatSource', {
'type': 'geojson',
'data': heatdata
});
map.addLayer(
{
'id': 'heatLayer',
'type': 'heatmap',
'source': 'heatSource',
'maxzoom': 13,
'minzoom': 7,
'layout': {
"visibility": "none"
},
'paint': {
'heatmap-weight': [
'interpolate',
['linear'],
['get', 'mag'],
0,
1,
7,
0
],
'heatmap-intensity': [
'interpolate',
['linear'],
['zoom'],
0,
1,
9,
3
],
'heatmap-color': [
'interpolate',
['linear'],
['heatmap-density'],
0,
'rgba(33,102,172,0)',
0.2,
'rgba(103,169,207,0.8)',
0.4,
'rgba(209,229,240,0.8)',
0.6,
'rgba(253,219,199,0.8)',
0.8,
'rgba(239,138,98,0.8)',
1,
'rgba(178,24,43,0.8)'
],
'heatmap-radius': [
'interpolate', ['linear'], ['zoom'],
4,
7,
11,
20
],
'heatmap-opacity': [
'interpolate',
['linear'],
['zoom'],
7,
0,
8,
1
]
}
}
);
}
if (map.getLayer('heatLayer')) {
map.moveLayer('heatLayer', 'historyLayerLine');
map.moveLayer('heatLayer', 'historyLayerFill');
if (map.getLayer('clusters')) {
map.moveLayer("clusters", "heatLayer");
map.moveLayer("cluster-count", "heatLayer")
map.moveLayer("unclustered-point", "heatLayer")
}
}
}
// 地图定位
function handlerLocation(lngLat, zoom) {
map.flyTo({
center: lngLat,
zoom: zoom,
bearing: 0,
speed: 1, // 飞行速度
curve: 2, // 飞行曲线
essential: true,
easing(t) {
// 飞行动画函数
return t;
},
});
};
// 获取县区边界数据
const handlerDealCountry = (countyName: String = "临沂市"): void => {
let center = {};
let zoom;
let filterName = "";
if (countyName == '临沂市') {
center = { lng: 118.72504868812163, lat: 35.180072027132915 }
zoom = 7.848587811931849;
handlerLocation([center['lng'], center['lat']], zoom);
} else if (countyName) {
center = MAP_VIEWER[countyName].center;
zoom = MAP_VIEWER[countyName].zoom;
handlerLocation([center['lng'], center['lat']], zoom);
filterName = countyName;
}
axios({
method: "get",
// url:`http://175.27.168.120:8080/geoserver/linyishi/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=linyishi%3Axianjie&maxFeatures=50&outputFormat=application%2Fjson&cql_filter=xzqmc%20like%20%27%25${filterName}%25%27`,
url: `http://120.222.154.7:8090/geoserver/linyishi/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=linyishi%3Axianjie&maxFeatures=50&outputFormat=application%2Fjson`
}).then(res => {
handlerLoadPanelLayer(res.data);
handlerLoadCountyLayer(res.data);
})
}
/**
*
* 县区边界countyLayer
* 县区面板图层countyPanelLayer
* 乡镇边界streetLayer
* 乡镇名称图层streetLabelLayer
* 遮罩图层mb-tag
* 线索线historyLayerLine
* 线索面historyLayerFill
*
* */
// 渲染县区边界数据
const handlerLoadCountyLayer = (geojson) => {
// 绘制线
if (map.getSource("countySource")) {
map.getSource("countySource").setData(geojson);
} else {
map.addSource("countySource", {
type: "geojson",
data: geojson
})
map.addLayer(
{
"id": "countyLayer",
"type": "line",
"source": "countySource",
"paint": {
'line-color': '#6f7ff4', // 设置线的颜色
'line-width': 3 // 设置线的宽度
}
}
)
if (map.getLayer("countyPanelLayer")) {
map.moveLayer("countyLayer", "countyPanelLayer")
}
}
}
// 渲染县界白板图层
const handlerLoadPanelLayer = (geojson) => {
if (map.getSource("countyPanelLayer")) {
map.getSource("countyPanelSource").setData(geojson);
} else {
map.addSource("countyPanelSource", {
type: "geojson",
data: geojson
})
map.addLayer(
{
"id": "countyPanelLayer",
"type": "fill",
"source": "countyPanelSource",
"layout": {
'visibility': 'none'
},
"paint": {
'fill-color': [
'case',
['==', ['get', 'xzqdm_1'], "371302"],
"#49B0F9",
['==', ['get', 'xzqdm_1'], "371311"],
"#3EABFA",
['==', ['get', 'xzqdm_1'], "371312"],
"#27A2FB",
['==', ['get', 'xzqdm_1'], "3713122"],
"#34E6B1",
['==', ['get', 'xzqdm_1'], "3713001"],
"#1099FB",
['==', ['get', 'xzqdm_1'], "3713271"],
"#0695FB",
['==', ['get', 'xzqdm_1'], "371321"],
"#058DEE",
['==', ['get', 'xzqdm_1'], "371322"],
"#09C78E",
['==', ['get', 'xzqdm_1'], "371323"],
"#047DD4",
['==', ['get', 'xzqdm_1'], "371324"],
"#94D515",
['==', ['get', 'xzqdm_1'], "371325"],
"#0568B0",
['==', ['get', 'xzqdm_1'], "371326"],
"#3EABFA",
['==', ['get', 'xzqdm_1'], "371327"],
"#49B0F9",
['==', ['get', 'xzqdm_1'], "371328"],
"#27A2FB",
['==', ['get', 'xzqdm_1'], "371329"],
"#94D515",
"#1099FB",
],
'fill-opacity': 0.9
}
},
)
}
}
function getMaskData() {
axios({
method: "get",
url: `http://120.222.154.7:8090/geoserver/linyishi/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=linyishi%3Ashijie&maxFeatures=50&outputFormat=application%2Fjson`,
}).then(res => {
let geojson = { DATA: res.data.features[0].geometry.coordinates[0][0] }
handlerLoadMaskLayer(geojson);
});
}
// 加载地图遮罩
function handlerLoadMaskLayer(geojson) {
map.addLayer({
//蒙版图层 //通过边界数据反选 达到挖洞效果
id: 'mb-tag',
type: 'fill',
source: {
type: 'geojson',
data: {
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [
[
// 多边形外围 需要进行遮罩的点 这里是给世界地图加遮罩 所以是世界的四个端点
[-180, 90],
[180, 90],
[180, -90],
[-180, -90],
],
geojson.DATA,
],
},
},
},
paint: {
'fill-color': '#ffffff',
'fill-opacity': 1 /* 透明度 */,
},
layout: {
visibility: 'visible',
},
});
}
// 获取乡镇数据
const handlerDealStreet = (countyName: String = "临沂市"): void => {
axios({
method: "get",
url: `http://175.27.168.120:8080/geoserver/linyishi/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=linyishi%3Azhenjie&maxFeatures=10000&outputFormat=application%2Fjson`,
}).then(res => {
handlerLoadStreetLayer(res.data);
})
}
// 渲染乡镇边界数据
const handlerLoadStreetLayer = (geojson) => {
// 绘制线
if (map.getSource("streetSource")) {
map.getSource("streetSource").setData(geojson);
} else {
map.addSource("streetSource", {
type: "geojson",
data: geojson,
minzoom: 10,
maxzoom: 24,
})
map.addLayer(
{
"id": "streetLayer",
"type": "line",
"source": "streetSource",
"paint": {
'line-color': '#42befb', // 设置线的颜色
'line-width': 2 // 设置线的宽度
},
minzoom: 10,
maxzoom: 24,
}
)
map.addLayer({
'id': 'streetLabelLayer',
'type': 'symbol',
'source': 'streetSource',
'layout': {
'text-field': ['get', 'xzqmc'],
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],
'text-size': 12,
'text-anchor': 'center',
},
'paint': {
'text-color': '#041B36',
'text-halo-color': '#fff',
'text-halo-width': 2,
}
});
}
}
let VillageGeojson = {};
const handlerLoadVillageLayer = () => {
// 绘制线
if (map.getSource("villageSource")) {
map.getSource("villageSource").setData(VillageGeojson);
} else {
map.addSource("villageSource", {
type: "geojson",
data: VillageGeojson,
minzoom: 12,
maxzoom: 24,
})
map.addLayer(
{
"id": "villageLayer",
"type": "line",
"source": "villageSource",
"paint": {
'line-color': '#42befb', // 设置线的颜色
'line-width': 2 // 设置线的宽度
},
minzoom: 12,
maxzoom: 24,
}
)
map.addLayer({
'id': 'villageLabelLayer',
'type': 'symbol',
'source': 'villageSource',
'layout': {
'text-field': ['get', 'zldwmc'],
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],
'text-size': 12,
'text-anchor': 'center',
},
'paint': {
'text-color': '#041B36',
'text-halo-color': '#fff',
'text-halo-width': 2,
}
});
}
}
// 控制图层显示隐层
/**
* 热力图heatLayer
*
* 线索线historyLayerLine
*
* 线索面historyLayerFill
*
* 行政区划countyLayer
*
*
*
* */
function handlerChangeLayerVisible(layerName, checked) {
if (checked) {
map.setLayoutProperty(layerName, 'visibility', 'visible');
} else {
map.setLayoutProperty(layerName, 'visibility', 'none');
}
if (layerName == 'countyPanelLayer') {
if (map.getLayer("countyPanelLayer")) {
map.moveLayer("countyPanelLayer", "streetLayer");
map.moveLayer("countyPanelLayer", "streetLabelLayer");
map.moveLayer("countyPanelLayer", "countyLayer");
map.moveLayer("countyPanelLayer", "historyLayerFill");
map.moveLayer("countyPanelLayer", "historyLayerLine");
}
}
}
// // 切换县区
// function handlerChangeCounty(county,type=""){
// handlerLoadPolygon(county.code,type);
// handlerDealPoint(county.code);
// handlerDealCountry(county.name);
// }
onMounted(() => {
mapboxgl.accessToken = MAPBOX_TOKEN;
map = initMap();
map.on("load", () => {
handlerCheckUserOrgs();
getMaskData();
handlerDealStreet();
handlerDealCountry();
map.flyTo({
center: [118.30207505530701, 35.30123435040745],
zoom: 8,
}),
map.on("click", (e) => {
var center = map.getCenter(); // 获取当前视图中心点
var zoom = map.getZoom(); // 获取当前视图缩放级别
console.log(zoom);
console.log(center);
})
})
map && map.flyTo({
center: [118.30207505530701, 35.30123435040745],
zoom: 8,
})
})
// 抛出函数
defineExpose({
// handlerChangeCounty, // 切换县区
handlerChangeLayerVisible, // 控制图层显示隐藏
handlerLoadPolygon,
});
</script>
<style type="less" scoped>
.map-container {
width: 100%;
height: 100%;
position: relative;
}
.search-container-box {
position: absolute;
width: 330px;
height: 40px;
top: 72px;
left: 73px;
z-index: 9999;
}
::v-deep .mapboxgl-ctrl-logo {
display: none !important;
}
</style>