// mars3d 实现卫星地图需要下载插件mars3d-tdt 我mars3d是下载的本地资源,无需引入,代码我懒得删
//多余的了,里面有高德地图的代码没有删
import "mars3d-tdt";
<template>
<div style="width: 100%; height: 100%">
<div style="width: 100%; height: 14%; display: flex; flex-wrap: wrap">
<a-select
style="
width: 200px;
height: 30px;
margin-right: 20px;
margin-bottom: 10px;
"
placeholder="请选择省"
@change="changeProvince"
allow-search
v-model="faterData.province_code"
>
<a-option
v-for="item in getProvinceList"
:value="item.code"
:label="item.name"
></a-option>
</a-select>
<a-select
style="
width: 200px;
height: 30px;
margin-right: 20px;
margin-bottom: 10px;
"
placeholder="请选择市"
@change="changeCity"
allow-search
v-model="faterData.city_code"
>
<a-option
v-for="item in getCityList"
:value="item.code"
:label="item.name"
></a-option>
</a-select>
<a-select
style="
width: 200px;
height: 30px;
margin-right: 20px;
margin-bottom: 10px;
"
placeholder="请选择区"
@change="changeArea"
allow-search
v-model="faterData.area_code"
>
<a-option
v-for="item in getAreaList"
:value="item.code"
:label="item.name"
></a-option>
</a-select>
<a-select
style="
width: 200px;
height: 30px;
margin-right: 20px;
margin-bottom: 10px;
"
placeholder="请选择"
@change="changeGetStreet"
allow-search
v-model="faterData.street_code"
>
<a-option
v-for="item in getStreetList"
:value="item.code"
:label="item.name"
></a-option>
</a-select>
<a-button @click="saveBtn"> 保存</a-button>
</div>
<div class="mapFather">
<div id="container" class="map-box"></div>
<div class="mapList">
<a-list
:max-height="516"
@reach-bottom="fetchData"
:scrollbar="scrollbar"
>
<template #header> 当前定位:{{ newPostion }} </template>
<template #scroll-loading>
<div v-if="bottom">没有更多了 </div>
<a-spin v-else />
</template>
<template v-if="mapList.length">
<a-list-item
:class="{ listBgClass: item.stu }"
@click="handleClickMapList(item)"
v-for="item in mapList"
>{{ item.address }}</a-list-item
>
</template>
</a-list>
</div>
</div>
</div>
</template>
<script setup>
import { useMapStore } from "@/store/index";
import {
watch,
ref,
onMounted,
defineProps,
defineEmits,
reactive,
shallowRef,
} from "vue";
import {
getProvince,
getCity,
getArea,
getStreet,
getVillage,
getAddressByCode,
} from "@/api/register";
import { Message } from "@arco-design/web-vue";
import "mars3d-tdt";
import { useUserStore } from "@/store";
let { area_code } = useUserStore();
const centerPosition = ref([105.381849, 30.868752]);
const key = "";
let districtSearch = null;
let map = shallowRef(null);
let levels = ref("country");
let searchText = ref("中国");
let AMapX = null;
let polygons = [];
let loading = ref(false)
let tdtDmLayer = null;
const faterData = ref({});
onMounted(() => {
loading.value = true
faterData.value = Object.assign({}, props.postData);
if (props.postData.long && props.postData.lat) {
// centerPosition.value = props
centerPosition.value[0] = Number(faterData.value.long);
centerPosition.value[1] = Number(faterData.value.lat);
}
getAddressByCodeAC();
searchMapList.province_code = faterData.value.province_code;
searchMapList.city_code = faterData.value.city_code;
searchMapList.area_code = faterData.value.area_code;
getProvinceAC();
getCityAC();
getAreaAC();
getStreetAC();
initMap();
setTimeout(() => {
loading.value = false;
}, 1000);
});
const current = ref(1);
const bottom = ref(false);
const mapList = ref([]);
const scrollbar = ref(true);
let newPostion = ref("未知区域");
const fetchData = () => {
if (mapList.value.length ) {
bottom.value = true;
}
};
const mapOptions = {
basemaps: [{ name: "天地图", type: "tdt", layer: "img_d", show: true }],
scene: {
},
token: {
tianditu: "", // 如果要使用自己的key必须加天地图的key
},
};
let graphicLayer = null;
let graphic = null;
let region = null;
let centerNumbers = ref([]);
const initMap = async () => {
map = new mars3d.Map("container", mapOptions);
tdtDmLayer = new mars3d.layer.TdtDmLayer({
key: mars3d.Token.tianditu, // 如果要使用自己的key必须加天地图的key 没有就删掉
label: {
hasPixelOffset: false,
visibleDepth: false,
clampToGround: true,
setHeight: 0,
scale: 0.6,
font_weight: "bold",
scaleByDistance: true,
},
});
map.addLayer(tdtDmLayer);
graphicLayer = new mars3d.layer.GraphicLayer();
map.addLayer(graphicLayer);
// 最近mars3d tdt的搜索有问题,改使用高德的搜索,是一样的,直接使用
region = new mars3d.query.GaodePOI({
// key: null key可以不填,默认加载mars3d的key
});
map.addLayer(region);
if (!faterData.value.name) {
faterData.value.name = "默认设备";
}
// marker的设置
graphic = new mars3d.graphic.BillboardEntity({
name: faterData.value.name,
position: [props.postData.long, props.postData.lat, 1],
style: {
image: "/src/assets/地图_定位.png",
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
clampToGround: false,
width: 30,
height: 30,
},
attr: { remark: `${faterData.value.name}` },
});
// 有经纬度就设置中心点,根据中心点逆地理编码
if (props.postData.long && props.postData.lat) {
map.setCameraView({
lng: props.postData.long,
lat: props.postData.lat,
alt: 800,
});
graphicLayer.addGraphic(graphic);
region.getAddress({
location: [props.postData.long, props.postData.lat],
success: (e) => {
newPostion.value = e.address;
},
error: (e) => {
// newPostion.value =e.address
},
});
}
// 关闭mars3d的 右键自带菜单
map.unbindContextMenu();
// mars3d 点击地图事件
map.on(mars3d.EventType.click, function (event) {
coordinate(event);
});
};
const coordinate = (event) => {
// 先清空 marker后再得到点击经纬度,再逆地理编码
graphic.remove();
var cartesian = event.cartesian;
var point = mars3d.LngLatPoint.fromCartesian(cartesian);
point.format();
faterData.value.long = point.lng;
faterData.value.lat = point.lat;
funSetMap(point.lng, point.lat);
setTimeout(() => {
region.getAddress({
location: [point.lng, point.lat],
success: (e) => {
if (JSON.stringify(e.address) != "[]") {
newPostion.value = e.address;
} else {
newPostion.value = "未知区域";
}
},
error: (e) => {},
});
}, 500);
// 控制右边地名 背景
if (mapList.value.length) {
mapList.value.forEach((item) => {
item.stu = false;
});
}
};
const funSetMap = (lng, lat, position = "", name = "") => {
if (position) {
newPostion.value = position;
}
if (name) {
newPostion.value = name + ":" + newPostion.value;
}
map.setCameraView({
lng: lng,
lat: lat,
alt: 800,
});
graphic.remove();
faterData.value.long = lng;
faterData.value.lat = lat;
graphic = new mars3d.graphic.BillboardEntity({
position: [lng, lat, 0],
style: {
image: "/src/assets/地图_定位.png",
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
clampToGround: false,
width: 30,
height: 30,
font_size: 20,
visibleDepth: false,
},
});
graphicLayer.addGraphic(graphic);
};
// 点击地图
const handleClickMapList = (val) => {
funSetMap(val.lng, val.lat, val.address, val.name);
mapList.value.forEach((item) => {
item.stu = item.id == val.id;
});
};
function getData(data, levels) {
map.remove(polygons);
polygons = [];
let bounds = data.boundaries;
if (bounds) {
for (var i = 0, l = bounds.length; i < l; i++) {
var polygon = new AMapX.Polygon({
// map: map,
strokeWeight: 1,
strokeColor: "#0091ea",
fillColor: "#80d8ff",
fillOpacity: 0.2,
path: bounds[i],
});
polygons.push(polygon);
}
}
// map.add(polygons)
map.setFitView(polygons); //地图自适应
}
};
const searchMapList = reactive({
page: 1,
pageSize: 1000,
province_code: null,
city_code: null,
area_code: null,
street_code: null,
village_code: null,
});
const props = defineProps({
postData: {
default: {},
type: Object,
},
mapVisible: {
default: false,
type: Boolean,
},
});
const emit = defineEmits(["saveMap"]);
const saveMap = () => {
emit("saveMap", { faterData: faterData.value, mapVisible: false });
Message.success({
content: "保存成功",
});
};
const saveBtn = () => {
if (!faterData.value.long && !faterData.value.lat) {
Message.warning({
content: "保存失败,请点击地图确定设备位置",
});
} else {
saveMap();
}
};
const getAddressByCodeAC = () => {
if (area_code) {
getAddressByCode(area_code).then((res) => {
});
}
};
const getProvinceList = ref();
const getProvinceAC = () => {
getProvince(searchMapList).then((res) => {
getProvinceList.value = res.data.items;
if (faterData.value.province_code) {
searchText.value = getProvinceList.value.filter(
(item) => item.code == faterData.value.province_code
)[0].name;
}
});
};
const dataProvince = ref("");
// 选择上面的省市区的时候,请求附近的地点,
const changeMapPostion = (val) => {
region.autoTip({
text: val,
city: val,
level: 12,
success: (e) => {
mapList.value = e.list.filter((item) => {
if (item.lng && item.lat && JSON.stringify(item.address) != '[]' && JSON.stringify(item.name) != '[]') {
item.stu = false;
return item;
}
});
if (mapList.value.length) {
console.log(mapList.value, "success");
mapList.value[0].stu = true;
funSetMap(
mapList.value[0].lng,
mapList.value[0].lat,
mapList.value[0].address,
mapList.value[0].name
);
}
},
error: (e) => {
// console.log("error", e);
},
});
};
const changeProvince = (value) => {
dataProvince.value = getProvinceList.value.filter(
(item) => item.code === value
)[0].name;
searchMapList.province_code = value;
useMapStore().districtName = dataProvince.value;
// useMapStore().level = 'province'
faterData.value.province_code = value;
faterData.value.location_detail = dataProvince.value;
getCityList.value = [];
getAreaList.value = [];
faterData.value.city_code = "";
faterData.value.area_code = "";
faterData.value.street_code = "";
changeMapPostion(dataProvince.value);
getCityAC();
};
const getCityList = ref();
const getCityAC = () => {
getCity(searchMapList).then((res) => {
getCityList.value = res.data.items;
});
};
const dataCity = ref("");
const changeCity = (value) => {
dataCity.value = getCityList.value.filter(
(item) => item.code === value
)[0].name;
searchMapList.city_code = value;
useMapStore().districtName = dataCity.value;
// useMapStore().level = 'city'
if (dataProvince.value) {
faterData.value.location_detail = dataProvince.value + "/" + dataCity.value;
} else {
dataProvince.value = getProvinceList.value.filter(
(item) => item.code === faterData.value.province_code
)[0].name;
faterData.value.location_detail = dataProvince.value + "/" + dataCity.value;
}
faterData.value.city_code = value;
faterData.value.area_code = "";
faterData.value.street_code = "";
getAreaList.value = [];
getStreetList.value = [];
// getVillageList.value = []
changeMapPostion(dataCity.value);
getAreaAC();
};
const getAreaList = ref();
const getAreaAC = () => {
getArea(searchMapList).then((res) => {
getAreaList.value = res.data.items;
});
};
const dataArea = ref("");
const changeArea = (value) => {
searchMapList.area_code = value;
dataArea.value = getAreaList.value.filter(
(item) => item.code === value
)[0].name;
useMapStore().districtName = dataArea.value;
useMapStore().level = "district";
faterData.value.area_code = value;
if (dataCity.value && dataProvince.value) {
faterData.value.location_detail =
dataProvince.value + "/" + dataCity.value + "/" + dataArea.value;
} else {
dataProvince.value = getProvinceList.value.filter(
(item) => item.code === faterData.value.province_code
)[0].name;
dataCity.value = getCityList.value.filter(
(item) => item.code === faterData.value.city_code
)[0].name;
faterData.value.location_detail =
dataProvince.value + "/" + dataCity.value + "/" + dataArea.value;
}
// searchList.street_code = null
// searchList.village_code = null
faterData.value.street_code = "";
// postData.village_code = ''
getStreetList.value = [];
// getVillageList.value = []
changeMapPostion(dataArea.value);
getStreetAC();
};
const getStreetList = ref();
const getStreetAC = () => {
getStreet(searchMapList).then((res) => {
getStreetList.value = res.data.items;
});
};
const dataGetStreet = ref("");
const changeGetStreet = (value) => {
searchMapList.street_code = value;
dataGetStreet.value = getStreetList.value.filter(
(item) => item.code === value
)[0].name;
useMapStore().districtName = dataGetStreet.value;
useMapStore().level = "district";
faterData.value.street_code = value;
if (dataCity.value && dataProvince.value && dataGetStreet.value) {
faterData.value.location_detail =
dataProvince.value +
"/" +
dataCity.value +
"/" +
dataArea.value +
"/" +
dataGetStreet.value;
} else {
dataProvince.value = getProvinceList.value.filter(
(item) => item.code === faterData.value.province_code
)[0].name;
dataCity.value = getCityList.value.filter(
(item) => item.code === faterData.value.city_code
)[0].name;
dataGetStreet.value = getStreetList.value.filter(
(item) => item.code === faterData.value.area_code
)[0].name;
faterData.value.location_detail =
dataProvince.value +
"/" +
dataCity.value +
"/" +
dataArea.value +
"/" +
dataGetStreet.value;
}
dataGetStreet(dataArea.value);
};
</script>
<style lang="less" scoped>
.mapFather {
width: 100%;
height: 86%;
overflow: hidden;
display: flex;
justify-content: space-between;
}
.map-box {
height: 110%;
flex: 1;
}
.mapList {
width: 240px;
height: 100%;
border-radius: 5px 5px;
margin-left: 20px;
}
a-list-item {
overflow: hidden;
}
.listBgClass {
background-color: #ccc;
}
</style>
示例图如上