路线规划

This commit is contained in:
cxc
2023-01-13 17:42:17 +08:00
parent d3d5ffa713
commit 2772f5ade1
10 changed files with 1468 additions and 205 deletions

47
src/api/line/line.js Normal file
View File

@ -0,0 +1,47 @@
import request from '@/utils/request'
// 查询线路规划列表
export function listLine(query) {
return request({
url: '/line/line/list',
method: 'get',
params: query
})
}
// 查询线路规划详细
export function getLine(lineId,uuid) {
return request({
url: '/line/line/' + lineId + '/' + uuid,
method: 'get'
})
}
// 新增线路规划
export function addLine(data) {
return request({
url: '/line/line',
method: 'post',
data: data
})
}
// 修改线路规划
export function updateLine(data) {
return request({
url: '/line/line',
method: 'put',
data: data
})
}
// 删除线路规划
export function delLine(lineId) {
return request({
url: '/line/line',
method: 'delete',
data: {
ids: lineId
}
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

29
src/utils/map.js Normal file
View File

@ -0,0 +1,29 @@
import AMapLoader from "@amap/amap-jsapi-loader";
// 初始化地图
export const loadAMap = async (plugins) => {
try {
const AMap = await AMapLoader.load({
key: "377d7c36dd385e2a722f29d4c6e1ffbf", // 申请好的Web端开发者Key首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins, // 需要使用的的插件列表,如比例尺'AMap.Scale'等
AMapUI: {
// 是否加载 AMapUI缺省不加载
version: "1.1", // AMapUI 版本
plugins: ["overlay/SimpleMarker"], // 需要加载的 AMapUI ui插件
},
Loca: {
// 是否加载 Loca 缺省不加载
version: "2.0", // Loca 版本
},
});
// const map = new AMap.Map("map-container", {
// zoom: 16, // 缩放级别
// center: [117.290345, 31.797813], // 中心点
// });
return AMap;
} catch (error) {
console.log(error);
throw new Error("地图创建失败");
}
};

View File

@ -10,16 +10,28 @@
<div class="search-bar"> <div class="search-bar">
<el-row :gutter="10"> <el-row :gutter="10">
<!-- <el-col :span="7"> --> <!-- <el-col :span="7"> -->
<el-button type="info" size="small">返回上层</el-button> <el-button type="info" size="small" @click="back"
>返回上层</el-button
>
<!-- </el-col> --> <!-- </el-col> -->
<el-col :span="10"> <el-col :span="10">
<el-input size="small"></el-input> <el-input
v-model="searchKeyword"
size="small"
@keypress.enter="searchPoint"
placeholder="请输入地名或点击地图选点"
></el-input>
</el-col> </el-col>
<!-- <el-col :span="7"> --> <!-- <el-col :span="7"> -->
<el-button type="primary" size="small" icon="search" <el-button
type="primary"
size="small"
icon="search"
@click="searchPoint"
>搜索</el-button >搜索</el-button
> >
<!-- </el-col> --> <!-- </el-col> -->
<el-button type="primary" plain size="small">卫星模式</el-button>
</el-row> </el-row>
</div> </div>
<div id="map-container"></div> <div id="map-container"></div>
@ -76,13 +88,13 @@
placeholder="请输入报警时段" placeholder="请输入报警时段"
/> />
</el-form-item> </el-form-item>
<el-form-item label="围栏地图数据" prop="fencePath"> <!-- <el-form-item label="围栏地图数据" prop="fencePath">
<el-input <el-input
v-model="form.fencePath" v-model="form.fencePath"
type="textarea" type="textarea"
placeholder="请输入内容" placeholder="请输入内容"
/> />
</el-form-item> </el-form-item> -->
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-button <el-button
@ -113,16 +125,22 @@
import tab from "@/plugins/tab"; import tab from "@/plugins/tab";
import { onMounted } from "vue"; import { onMounted } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import AMapLoader from "@amap/amap-jsapi-loader"; // import AMapLoader from "@amap/amap-jsapi-loader";
import { addFence, updateFence, getFence } from "@/api/fence"; import { addFence, updateFence, getFence } from "@/api/fence";
import markBsPng from "@/assets/images/mark_bs.png";
import mapPinPng from "@/assets/images/map-pin.png";
import { loadAMap } from "@/utils/map";
const route = useRoute(); const route = useRoute();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const AMap = shallowRef(null); const AMap = shallowRef(null);
const map = shallowRef(null); const map = shallowRef(null);
const placeSearch = shallowRef(null); const placeSearch = shallowRef(null);
// const fencePaths = ref([]); const searchResultMarkers = shallowRef([]); // 搜索结果表笔列表
const turningPointMarker = shallowRef([]);
const resultInfoWindow = shallowRef(null);
const fencePolygon = shallowRef(null); const fencePolygon = shallowRef(null);
const searchKeyword = ref("");
const data = reactive({ const data = reactive({
form: {}, form: {},
rules: { rules: {
@ -145,60 +163,44 @@ const data = reactive({
const { form, rules } = toRefs(data); const { form, rules } = toRefs(data);
// 初始化地图
const initMap = async () => {
try {
AMap.value = await AMapLoader.load({
key: "377d7c36dd385e2a722f29d4c6e1ffbf", // 申请好的Web端开发者Key首次调用 load 时必填
// key: "7891f1238368a895ff1967c79643102d", // 申请好的Web端开发者Key首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
// "AMap.Driving",
"AMap.Scale",
"AMap.PlaceSearch",
// "AMap.AutoComplete",
// "AMap.Geocoder",
// "AMap.TruckDriving",
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
AMapUI: {
// 是否加载 AMapUI缺省不加载
version: "1.1", // AMapUI 版本
plugins: ["overlay/SimpleMarker"], // 需要加载的 AMapUI ui插件
},
Loca: {
// 是否加载 Loca 缺省不加载
version: "2.0", // Loca 版本
},
});
// geocoder.value = new AMap.value.Geocoder();
map.value = new AMap.value.Map("map-container", {
zoom: 16, // 缩放级别
center: [117.290345, 31.797813], // 中心点
city: "合肥",
});
map.value.on("click", handleMapClick);
// 地点搜索插件
placeSearch.value = new AMap.value.PlaceSearch({
// map: map.value,
city: "0551",
});
fencePolygon.value = new AMap.value.Polygon({});
map.value.add(fencePolygon.value);
map.value.addControl(new AMap.value.Scale());
return "success";
} catch (error) {
console.log(error);
}
};
const handleMapClick = (ev) => { const handleMapClick = (ev) => {
console.log(ev);
if (map.value.getAllOverlays("polygon").length === 0) { if (map.value.getAllOverlays("polygon").length === 0) {
map.value.add(fencePolygon.value); map.value.add(fencePolygon.value);
} }
form.value.fencePath.push(ev.lnglat); form.value.fencePath.push(ev.lnglat);
console.log(JSON.stringify(form.value.fencePath));
turningPointMarker.value.push(
new AMap.value.Marker({
map: map.value,
position: ev.lnglat,
content: `
<div
style="
background-image: url(${mapPinPng});
width: 21px;
height: 22.5px;
background-size: cover;
color: #fff;
text-align: center;
font-size: 12px;
padding-top: 3px;
"
>
</div>
`,
anchor: "bottom-right",
})
);
if (form.value.fencePath.length > 2) {
turningPointMarker.value.forEach((el) => {
el.hide();
});
} else {
turningPointMarker.value.forEach((el) => {
el.show();
});
}
fencePolygon.value.setPath( fencePolygon.value.setPath(
// AMap.value.GeometryUtil.makesureClockwise( // AMap.value.GeometryUtil.makesureClockwise(
// form.value.fencePath.map((el) => new AMap.value.LngLat(el.lng, el.lat)) // form.value.fencePath.map((el) => new AMap.value.LngLat(el.lng, el.lat))
@ -206,6 +208,55 @@ const handleMapClick = (ev) => {
// ) // )
); );
}; };
const handleResultClick = (ev) => {
resultInfoWindow.value.setContent(`
<div>
${ev.target.getExtData().name}</div>
`);
resultInfoWindow.value.open(map.value, [ev.lnglat.lng, ev.lnglat.lat]);
};
// 根据名称搜索地图标点
const searchPoint = (val /** 搜索建议选项 */, type) => {
map.value.clearMap();
form.value.fencePath = [];
placeSearch.value.search(searchKeyword.value, (status, result) => {
console.log(status, result);
// TODO: 添加搜索结果标记
if (status === "complete") {
searchResultMarkers.value = result.poiList.pois.map((el, index) => {
const marker = new AMap.value.Marker({
map: map.value,
position: new AMap.value.LngLat(el.location.lng, el.location.lat),
extData: el,
content: `
<div
style="
background-image: url(${markBsPng});
width: 19px;
height: 31px;
background-size: cover;
color: #fff;
text-align: center;
font-size: 12px;
padding-top: 3px;
"
>
${index + 1}
</div>
`,
});
marker.on("mouseover", handleResultClick);
marker.on("click", handleMapClick);
marker.on("mouseout", (ev) => {
resultInfoWindow.value.close();
});
return marker;
});
map.value.setFitView(searchResultMarkers.value);
}
});
};
/** 提交按钮 */ /** 提交按钮 */
function submitForm() { function submitForm() {
proxy.$refs["fenceRef"].validate((valid) => { proxy.$refs["fenceRef"].validate((valid) => {
@ -254,7 +305,25 @@ function back() {
reset(); reset();
onMounted(() => { onMounted(() => {
initMap().then(() => { loadAMap(["AMap.Scale", "AMap.PlaceSearch"]).then((_AMap) => {
AMap.value = _AMap;
map.value = new AMap.value.Map("map-container", {
zoom: 16, // 缩放级别
center: [117.290345, 31.797813], // 中心点
city: "合肥",
});
map.value.on("click", handleMapClick);
// 地点搜索插件
placeSearch.value = new AMap.value.PlaceSearch({
// map: map.value,
city: "0551",
});
resultInfoWindow.value = new AMap.value.InfoWindow({
anchor: "bottom-center",
});
fencePolygon.value = new AMap.value.Polygon({});
map.value.add(fencePolygon.value);
map.value.addControl(new AMap.value.Scale());
if (route.query.fenceId && route.query.uuid) { if (route.query.fenceId && route.query.uuid) {
getFence(route.query.fenceId, route.query.uuid).then((resp) => { getFence(route.query.fenceId, route.query.uuid).then((resp) => {
form.value = { form.value = {

View File

@ -94,11 +94,7 @@
<el-table-column label="围栏ID" align="center" prop="fenceId" /> <el-table-column label="围栏ID" align="center" prop="fenceId" />
<el-table-column label="围栏名称" align="center" prop="fenceName" /> <el-table-column label="围栏名称" align="center" prop="fenceName" />
<el-table-column label="限速(km/h)" align="center" prop="speed" /> <el-table-column label="限速(km/h)" align="center" prop="speed" />
<el-table-column <el-table-column label="报警类型" align="center" prop="${field}">
label="报警类型(0不1进2出3都)"
align="center"
prop="${field}"
>
<template #default="{ row }"> <template #default="{ row }">
{{ reportTypeMap.get(row.reportType) ?? "未知" }} {{ reportTypeMap.get(row.reportType) ?? "未知" }}
</template> </template>

View File

@ -0,0 +1,166 @@
<template>
<div class="description">
<el-scrollbar height="20">
<div class="roads">
<div class="road-item" v-for="(road, index) in roadsList" :key="road">
{{ road }}
<ElIcon v-if="index != roadsList.length - 1">
<ArrowRight />
</ElIcon>
</div>
</div>
</el-scrollbar>
<div class="time-distance">
<span class="time"
>{{ (routeData.routes[0].time / 60).toFixed(1) }}分钟</span
>
(<span class="distance">{{ routeData.routes[0].distance }}</span>)
<span class="seg">|</span>
<span class="policy">
{{ routeData.routes[0].policy }}
</span>
</div>
</div>
<div
@click="emit('start-click')"
class="steps-item start"
v-if="routeData.routes[0].steps.length"
>
<div
class="icon"
:style="{
backgroundPosition: stepIconMap.get('起点'),
}"
></div>
<div class="content">起点</div>
</div>
<div
v-for="(item, index) in routeData.routes[0].steps"
:key="item.start_location.lng"
class="steps-item"
@click="handleRouteClick(item, index)"
>
<div
class="icon"
:style="{
backgroundPosition: stepIconMap.get(item.action) ?? '-46px -23px',
}"
></div>
<div class="content">
{{ item.instruction }}
</div>
</div>
<div
@click="emit('end-click')"
class="steps-item start"
v-if="routeData.routes[0].steps.length"
>
<div
class="icon"
:style="{
backgroundPosition: stepIconMap.get('终点'),
}"
></div>
<div class="content">终点</div>
</div>
</template>
<script setup name="StepsList">
import { ArrowRight } from "@element-plus/icons-vue";
import { computed, toRefs } from "vue";
const emit = defineEmits(["step-click", "start-click", "end-click"]);
const props = defineProps({
routeData: { type: Object, required: true },
// routeExtData: {
// type: Object,
// required: true,
// },
});
const { routeData } = toRefs(props);
const roadsList = computed(() =>
routeData.value.routes[0].steps
? [
...new Set(
routeData.value.routes[0].steps
.map((el) => el.road)
.filter((el) => !!el)
),
]
: []
);
const stepIconMap = new Map([
["靠左", "-406px -23px"],
["靠右", "-445px -23px"],
["左转", "-87px -23px"],
["右转", "-124px -23px"],
["左转调头", "-327px -23px"],
["向左前方行驶", "-165px -23px"],
["向右前方行驶", "-206px -23px"],
["向左后方行驶", "-246px -23px"],
["减速行驶", "-524px -23px"],
["终点", "-126px -104px"],
["起点", "-47px -104px"],
]);
const handleRouteClick = (data, index) => {
emit("step-click", data, index);
};
</script>
<style scoped lang="scss">
.description {
border-bottom: 1px solid #e6e6e6;
padding: 8px 8px;
.roads {
display: flex;
align-items: center;
font-size: 13px;
font-weight: bold;
.road-item {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: flex;
align-items: center;
flex-shrink: 0;
}
}
.time-distance {
display: flex;
margin-top: 5px;
font-size: 13px;
.seg {
margin: 0px 3px;
}
}
}
.steps-item {
display: flex;
align-items: center;
cursor: pointer;
padding-bottom: 5px;
padding-top: 5px;
&:not(:last-child) {
// margin-bottom: 10px;
border-bottom: 1px solid #f0f0f0;
}
.icon {
margin-right: 8px;
width: 20px;
height: 20px;
color: #fff;
line-height: 20px;
border-radius: 50%;
border: 1px solid #ddd;
background-color: #fff;
// background-position: -47px -104px;
background-image: url(https://webapi.amap.com/theme/v1.3/images/newpc/diricon.png);
}
.content {
font-size: 12px;
}
&.start .content {
font-size: 14px;
font-weight: 700;
}
}
</style>

View File

@ -0,0 +1,666 @@
<template>
<div class="wrap">
<div class="form-drawer" v-show="drawerOpen">
<el-scrollbar class="form-container">
<div
:style="{
width: '96%',
margin: '0 auto',
}"
>
<el-form
ref="routeFormRef"
id="route-form"
:model="formData"
:rules="rules"
>
<el-row justify="center">
<el-form-item prop="carType">
<el-radio-group v-model="formData.carType" size="small">
<el-radio-button label="0">小车</el-radio-button>
<el-radio-button label="1">货车</el-radio-button>
</el-radio-group>
</el-form-item>
</el-row>
<el-row :gutter="10" justify="space-between">
<el-col :span="2">
<div
:style="{
height: '66px',
display: 'flex',
alignItems: 'center',
}"
>
<el-icon color="#30a1f0"><Sort /></el-icon>
</div>
</el-col>
<el-col :span="20">
<el-form-item prop="startAddress">
<el-popover
:width="300"
:visible="showStartSuggestion && !!formData.startAddress"
title="搜索建议"
>
<div
v-for="item in searchTips"
:key="item.id"
class="suggestion-item"
@click="searchPoint(item.name, 'start')"
>
{{ item.name }}
</div>
<template #reference>
<!-- TODO: @input="handleInput('start', $event)" -->
<el-input
v-model="formData.startAddress"
size="small"
@keydown.enter="
searchPoint(formData.startAddress, 'start')
"
@focus="
nowSearch = 'start';
showStartSuggestion = true;
"
@blur="
showStartSuggestion = false;
nowSearch = '';
"
:suffix-icon="
formData?.startLngLat?.length
? `circle-check-filled`
: null
"
>
<template #prepend>起</template>
</el-input>
</template>
</el-popover>
</el-form-item>
<el-form-item prop="endAddress">
<el-popover
:width="300"
:visible="showEndSuggestion && !!formData.endAddress"
title="搜索建议"
>
<div
v-for="item in searchTips"
:key="item.id"
class="suggestion-item"
@click="searchPoint(item.name, 'end')"
>
{{ item.name }}
</div>
<template #reference>
<!--TODO: @input="getAutoComplete" -->
<el-input
v-model="formData.endAddress"
size="small"
@keydown.enter="searchPoint(formData.endAddress, 'end')"
@focus="
nowSearch = 'end';
// map.clearMap();
showEndSuggestion = true;
"
@blur="
showEndSuggestion = false;
nowSearch = '';
// searchTips = [];
"
:suffix-icon="
formData?.endLngLat?.length
? `circle-check-filled`
: null
"
>
<template #prepend>终</template>
</el-input>
</template>
</el-popover>
</el-form-item>
</el-col>
<el-col :span="2">
<div
:style="{
height: '66px',
display: 'flex',
alignItems: 'center',
}"
>
<el-icon color="#30a1f0"><CirclePlusFilled /></el-icon>
</div>
</el-col>
</el-row>
<el-row
justify="space-between"
:style="{
width: '90%',
marginBottom: '18px',
marginLeft: 'auto',
marginRight: 'auto',
}"
>
<el-button link @click="clearRoute" size="small"
>清除路线</el-button
>
<el-button type="primary" @click="searchRoute" size="small"
>查询</el-button
>
</el-row>
<el-tabs
type="border-card"
v-if="showStepPane"
v-model="formData.lineType"
@tab-change="handleTabChange"
>
<el-tab-pane name="0" label="费用最低">
<route-step-list
:route-data="formData.lineJson"
@step-click="handleRouteClick"
@start-click="map.setFitView([startMarker])"
@end-click="map.setFitView([endMarker])"
/>
</el-tab-pane>
<el-tab-pane name="1" label="时间最短">
<route-step-list
:route-data="formData.lineJson"
@step-click="handleRouteClick"
@start-click="map.setFitView([startMarker])"
@end-click="map.setFitView([endMarker])"
/>
</el-tab-pane>
<el-tab-pane name="2" label="距离最短">
<route-step-list
:route-data="formData.lineJson"
@step-click="handleRouteClick"
@start-click="map.setFitView([startMarker])"
@end-click="map.setFitView([endMarker])"
/>
</el-tab-pane>
</el-tabs>
<el-form-item
label="路径名称"
prop="lineName"
:style="{
marginTop: '18px',
}"
>
<el-input v-model="formData.lineName" size="small"></el-input>
</el-form-item>
<el-form-item label="报警开关" prop="reportType">
<el-checkbox-group
size="small"
v-model="formData.reportType"
class="ml-4"
>
<el-checkbox label="1">进入起点</el-checkbox>
<el-checkbox label="2">偏离路径</el-checkbox>
<el-checkbox label="3">到达终点</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-row class="submit-bar" :gutter="10">
<el-col :span="12">
<el-button size="small" type="danger" @click="back"
>返回上层</el-button
>
</el-col>
<el-col :span="12">
<el-button size="small" type="primary" @click="submitForm"
>保存</el-button
>
</el-col>
</el-row>
</el-form-item>
</el-form>
</div>
</el-scrollbar>
</div>
<el-button
id="drawer-switch"
type="primary"
plain
circle
:icon="drawerOpen ? 'ArrowLeftBold' : 'ArrowRightBold'"
@click="switchDrawer"
></el-button>
<div id="map-container"></div>
</div>
</template>
<script setup name="AddLine">
import tab from "@/plugins/tab";
import { onMounted } from "vue";
import { useRoute } from "vue-router";
import { loadAMap } from "@/utils/map";
import { ElMessage } from "element-plus";
import endPng from "@/assets/images/end.png";
import RouteStepList from "./RouteStepList.vue";
import startPng from "@/assets/images/start.png";
import { addLine, getLine, updateLine } from "@/api/line/line";
const route = useRoute();
const AMap = shallowRef(null);
const map = shallowRef(null);
const driving = shallowRef(null); // 驾车路线规划插件
const truckDriving = shallowRef(null); // 卡车路线规划插件
const geocoder = shallowRef(null); // 经纬度转地址插件
const placeSearch = shallowRef(null); // 地点搜索插件
const autoComplete = shallowRef(null); // 搜索建议插件
const startMarker = shallowRef(null); // 起点标记
const endMarker = shallowRef(null); // 终点标记
const resultInfoWindow = shallowRef(null);
const searchResultMarkers = ref([]); // 搜索结果表笔列表
const stepsPolylines = ref([]); // 路线步骤标记列表
const stepsList = ref([]);
const drawerOpen = ref(true);
const routeFormRef = ref(null);
const searchTips = ref([]);
const nowSearch = ref("");
const showStartSuggestion = ref(false);
const showEndSuggestion = ref(false);
const activeTabName = ref("LEAST_FEE");
const showStepPane = computed(
() =>
formData.value?.startLngLat?.length === 2 &&
formData.value?.endLngLat?.length === 2 &&
formData.value.lineJson
);
const policyMap = new Map([
["0", "LEAST_FEE"],
["1", "LEAST_TIME"],
["2", "LEAST_DISTANCE"],
]);
const data = reactive({
formData: {
carType: "0",
startLngLat: [],
endLngLat: [],
lineType: "0",
lineJson: null,
},
routeExtData: {
distance: 0,
time: 0,
policy: "",
},
rules: {
lineName: [
{
required: true,
message: "请输入路线名称",
trigger: "blur",
},
],
reportType: [
{
required: true,
message: "请选择报警开关",
trigger: "change",
},
],
},
});
const { formData, rules } = toRefs(data);
// 切换左侧面板显示隐藏
const switchDrawer = () => {
drawerOpen.value = !drawerOpen.value;
if (drawerOpen.value) {
document.querySelector("#drawer-switch").style.left = "25%";
document.querySelector("#drawer-switch").style.transform =
"translate(-50%, -50%)";
} else {
document.querySelector("#drawer-switch").style.left = "0";
document.querySelector("#drawer-switch").style.transform =
"translate(0, -50%)";
}
};
// 地图点击
const handleMapClick = (ev) => {
// ev.preventDefault();
// 起点输入框 focus 时
if (nowSearch.value === "start") {
map.value.clearMap();
if (formData.value?.endLngLat?.length === 2) {
map.value.add(endMarker.value);
}
startMarker.value.setPosition(
new AMap.value.LngLat(ev.lnglat.lng, ev.lnglat.lat)
);
map.value.add(startMarker.value);
regeoCode([ev.lnglat.lng, ev.lnglat.lat])
.then((address) => {
formData.value.startAddress = address;
})
.catch((e) => {
console.log(e);
formData.value.startAddress = `${ev.lnglat.lng}, ${ev.lnglat.lat}`;
});
formData.value.startLngLat = [ev.lnglat.lng, ev.lnglat.lat];
}
// 终点输入框 focus 时
else if (nowSearch.value === "end") {
map.value.clearMap();
if (formData.value?.startLngLat?.length === 2) {
map.value.add(startMarker.value);
}
endMarker.value.setPosition(
new AMap.value.LngLat(ev.lnglat.lng, ev.lnglat.lat)
);
map.value.add(endMarker.value);
regeoCode([ev.lnglat.lng, ev.lnglat.lat])
.then((address) => {
formData.value.endAddress = address;
})
.catch((e) => {
console.log(e);
formData.value.endAddress = `${ev.lnglat.lng}, ${ev.lnglat.lat}`;
});
formData.value.endLngLat = [ev.lnglat.lng, ev.lnglat.lat];
}
};
// 根据经纬度获取地址
const regeoCode = (lnglat /** [lng, lat] */) => {
return new Promise((resolve, reject) => {
geocoder.value.getAddress(lnglat, (status, result) => {
if (status === "complete" && result.regeocode) {
const address = result.regeocode.formattedAddress;
resolve(address);
} else {
reject("根据经纬度查询地址失败");
}
});
});
};
// 搜索路线
const searchRoute = () => {
if (!driving.value) return;
return new Promise((resolve, reject) => {
const policy = policyMap.get(formData.value.lineType);
if (policy) {
driving.value.opt.policy =
AMap.value.DrivingPolicy[policyMap.get(formData.value.lineType)];
} else {
return;
}
console.log("123");
const startLngLat = formData.value.startLngLat;
const endLngLat = formData.value.endLngLat;
driving.value.search(startLngLat, endLngLat, (status, result) => {
// 未出错时result即是对应的路线规划方案
if (status === "complete") {
console.log(result);
formData.value.lineJson = result;
stepsList.value = result.routes[0].steps;
drawRoute(result);
resolve(result);
} else {
reject("获取路线失败");
}
});
});
};
// 绘制路线
const drawRoute = (result) => {
// 绘制路线之前,清除地图上所有标记
map.value.clearMap();
const startLngLat = formData.value.startLngLat;
const endLngLat = formData.value.endLngLat;
// 重新添加开始和结束标记
startMarker.value.setPosition(startLngLat);
endMarker.value.setPosition(endLngLat);
map.value.add(startMarker.value);
map.value.add(endMarker.value);
// 起点到开始驾驶地点距离以虚直线表示
new AMap.value.Polyline({
map: map.value,
strokeWeight: 8,
strokeOpacity: 1,
strokeColor: "#808080",
strokeStyle: "dashed",
path: [
new AMap.value.LngLat(...startLngLat),
result.routes[0].steps[0].start_location,
],
});
// 结束驾驶地点到终点距离以虚直线表示
new AMap.value.Polyline({
map: map.value,
strokeWeight: 8,
strokeOpacity: 1,
strokeColor: "#808080",
strokeStyle: "dashed",
path: [
result.routes[0].steps[result.routes[0].steps.length - 1].end_location,
new AMap.value.LngLat(...endLngLat),
],
});
// 在地图上绘制路线标记,并添加到数组中
stepsPolylines.value = result.routes[0].steps.map((el) => {
return new AMap.value.Polyline({
map: map.value,
strokeWeight: 8,
strokeOpacity: 1,
strokeColor: "#1bac2e",
showDir: true,
path: el.path,
});
});
map.value.setFitView(stepsPolylines.value);
};
const handleRouteClick = (data, index) => {
console.log(data, index);
map.value.setFitView([stepsPolylines.value[index]]);
};
// 清除路线reset form
const clearRoute = () => {
formData.value.lineJson = null;
formData.value.startAddress = "";
formData.value.endAddress = "";
formData.value.startLngLat = null;
formData.value.endLngLat = null;
stepsList.value = [];
map.value.clearMap();
};
// tab点击事件
const handleTabChange = (tab) => {
if (formData.value.startLngLat.length && formData.value.endLngLat.length) {
searchRoute();
} else {
// ElMessage.error("err");
}
};
/** 提交按钮 */
function submitForm() {
routeFormRef.value.validate((valid) => {
if (valid) {
if (formData.value.lineId != null) {
updateLine({
...formData.value,
lineJson: JSON.stringify(formData.value.lineJson),
reportType: formData.value.reportType.join(","),
}).then((response) => {
ElMessage.success("修改成功");
back();
});
} else {
addLine({
...formData.value,
lineJson: JSON.stringify(formData.value.lineJson),
reportType: formData.value.reportType.join(","),
}).then((response) => {
ElMessage.success("新增成功");
back();
});
}
}
});
}
const reset = () => {
formData.value = {
// lineId: null,
lineName: null,
carType: "0",
lineType: "0",
startAddress: null,
endAddress: null,
reportType: [],
lineJson: null,
// linePath: null,
// createBy: null,
// createTime: null,
// uuid: null,
// tenantId: null,
};
routeFormRef.value && routeFormRef.value.resetFields();
};
const getFormData = async () => {
if (route.query.lineId && route.query.uuid) {
getLine(route.query.lineId, route.query.uuid).then((resp) => {
let lineJson;
try {
lineJson = JSON.parse(resp.data.lineJson);
} catch (error) {
lineJson = null;
}
const reportType = resp.data.reportType
? resp.data.reportType.split(",")
: [];
const startLngLat = lineJson?.start.location;
const endLngLat = lineJson?.end.location;
formData.value = {
...resp.data,
lineJson,
reportType,
startLngLat,
endLngLat,
};
return "success";
});
} else {
return "success";
}
};
function back() {
reset();
tab.closeOpenPage({ path: "/basic/line" });
}
onMounted(async () => {
reset();
document.getElementById("map-container").onmousedown = (ev) => {
ev.preventDefault();
};
await getFormData();
loadAMap([
"AMap.Driving",
"AMap.Scale",
"AMap.PlaceSearch",
"AMap.AutoComplete",
"AMap.Geocoder",
// "AMap.TruckDriving",
]).then((_AMap) => {
AMap.value = _AMap;
map.value = new AMap.value.Map("map-container", {
zoom: 16, // 缩放级别
center: [117.290345, 31.797813], // 中心点
city: "合肥",
});
/** 加载插件 */
// 驾车路线规划插件
driving.value = new AMap.value.Driving();
// 卡车路线规划插件 TODO:
// truckDriving.value = new AMap.value.TruckDriving();
// 地点搜索插件
placeSearch.value = new AMap.value.PlaceSearch({
// map: map.value,
city: "0551",
});
geocoder.value = new AMap.value.Geocoder();
// 搜索建议插件
autoComplete.value = new AMap.value.AutoComplete({});
/** 加载插件结束 */
startMarker.value = new AMap.value.Marker({
icon: startPng,
anchor: "bottom-center",
});
endMarker.value = new AMap.value.Marker({
icon: endPng,
anchor: "bottom-center",
});
map.value.on("click", handleMapClick);
// 当修改时,从返回数据中读取路线数据绘制
if (formData.value.lineJson) {
drawRoute(formData.value.lineJson);
}
});
});
</script>
<style scoped lang="scss">
.wrap {
position: relative;
#map-container {
width: 100%;
height: calc(100vh - 84px);
}
.form-drawer {
padding: 20px;
display: flex;
flex-direction: column;
position: absolute;
left: 0;
top: 0;
z-index: 99;
background-color: #fff;
box-sizing: border-box;
overflow: hidden;
width: 25%;
height: 100vh;
box-shadow: rgba(0, 0, 0, 0.08) 0px 16px 48px 16px,
rgba(0, 0, 0, 0.12) 0px 12px 32px 0px,
rgba(0, 0, 0, 0.16) 0px 8px 16px -8px;
transition: all 0.3s;
:deep(.el-input__suffix) {
color: #67c23a;
}
:deep(.el-scrollbar.form-container) {
height: calc(100vh - 84px - 40px);
}
:deep(.el-form-item__label) {
font-size: 12px;
}
:deep(.el-checkbox) {
margin-right: 8px;
.el-checkbox__label {
padding-left: 3px;
}
}
:deep(.submit-bar) {
width: 100%;
.el-button {
width: 100%;
}
}
}
:deep(#drawer-switch) {
position: absolute;
left: 25%;
top: 50%;
z-index: 100;
transform: translate(-50%, -50%);
}
}
</style>

View File

@ -0,0 +1,344 @@
<template>
<div class="app-container">
<el-form
ref="queryRef"
:inline="true"
:model="queryParams"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="线路名称" prop="lineName">
<el-input
clearable
@keyup.enter="handleQuery"
placeholder="请输入线路名称"
v-model="queryParams.lineName"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['line:line:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['line:line:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['line:line:export']"
>导出</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="lineList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="线路ID" align="center" prop="lineId" />
<el-table-column label="线路名称" align="center" prop="lineName" />
<el-table-column label="车型" align="center" prop="${field}">
<template #default="{ row }">
{{
row.carType == "0" ? "小车" : row.carType == "1" ? "货车" : "未知"
}}
</template>
</el-table-column>
<el-table-column label="线路类型" align="center" prop="${field}">
<template #default="{ row }">
{{
row.lineType == "0"
? "费用最低"
: row.lineType == "1"
? "时间最短"
: row.lineType == "2"
? "距离最短"
: "未知"
}}
</template>
</el-table-column>
<!-- <el-table-column label="起点" align="center" prop="startAddress" />
<el-table-column label="终点" align="center" prop="endAddress" />
<el-table-column label="报警开关" align="center" prop="${field}">
<template #default="{ row }">
{{ "未知" }}
</template>
</el-table-column>
<el-table-column label="线路JSON" align="center" prop="lineJson" />
<el-table-column label="线路PATH" align="center" prop="linePath" />
<el-table-column label="租户ID" align="center" prop="tenantId" /> -->
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['line:line:edit']"
>修改</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改线路规划对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="lineRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="线路名称" prop="lineName">
<el-input v-model="form.lineName" placeholder="请输入线路名称" />
</el-form-item>
<el-form-item label="车型" prop="carType">
<el-radio-group v-model="form.carType" class="ml-4">
<el-radio label="0" size="large">小车</el-radio>
<el-radio label="1" size="large">货车</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="线路类型" prop="lineType">
<el-radio-group v-model="form.lineType" class="ml-4">
<el-radio label="0" size="large">费用最低</el-radio>
<el-radio label="1" size="large">时间最短</el-radio>
<el-radio label="2" size="large">距离最短</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="起点" prop="startAddress">
<el-input v-model="form.startAddress" placeholder="请输入起点" />
</el-form-item>
<el-form-item label="终点" prop="endAddress">
<el-input v-model="form.endAddress" placeholder="请输入终点" />
</el-form-item>
<el-form-item label="报警开关" prop="reportType">
<el-radio-group v-model="form.reportType" class="ml-4">
</el-radio-group>
</el-form-item>
<el-form-item label="线路JSON" prop="lineJson">
<el-input v-model="form.lineJson" placeholder="请输入线路JSON" />
</el-form-item>
<el-form-item label="线路PATH" prop="linePath">
<el-input v-model="form.linePath" placeholder="请输入线路PATH" />
</el-form-item>
<el-form-item label="租户ID" prop="tenantId">
<el-input v-model="form.tenantId" placeholder="请输入租户ID" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Line">
import {
listLine,
getLine,
delLine,
addLine,
updateLine,
} from "@/api/line/line";
import { useRouter } from "vue-router";
const router = useRouter();
const { proxy } = getCurrentInstance();
const lineList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
lineName: null,
carType: null,
lineType: null,
},
rules: {},
});
const { queryParams, form, rules } = toRefs(data);
/** 查询线路规划列表 */
function getList() {
loading.value = true;
listLine(queryParams.value).then((response) => {
lineList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
// 取消按钮
function cancel() {
open.value = false;
reset();
}
// 表单重置
function reset() {
form.value = {
lineId: null,
lineName: null,
carType: null,
lineType: null,
startAddress: null,
endAddress: null,
reportType: null,
lineJson: null,
linePath: null,
createBy: null,
createTime: null,
uuid: null,
tenantId: null,
};
proxy.resetForm("lineRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map((item) => {
return { id: item.lineId, uuid: item.uuid };
});
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
router.push({
path: "/basic/line/add",
});
}
/** 修改按钮操作 */
function handleUpdate(row) {
const { lineId, uuid } = row;
router.push({
path: "/basic/line/add",
query: {
lineId,
uuid,
},
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["lineRef"].validate((valid) => {
if (valid) {
if (form.value.lineId != null) {
updateLine(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addLine(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _lineIds = row.lineId
? [{ id: row.lineId, uuid: row.uuid }]
: ids.value;
proxy.$modal
.confirm(
'是否确认删除线路规划编号为"' +
_lineIds.map((el) => el.lineId).join(",") +
'"的数据项?'
)
.then(function () {
return delLine(_lineIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download(
"line/line/export",
{
...queryParams.value,
},
`line_${new Date().getTime()}.xlsx`
);
}
getList();
</script>

View File

@ -2,7 +2,11 @@
<div> <div>
<el-row class="search-bar" :gutter="10"> <el-row class="search-bar" :gutter="10">
<el-col :span="18"> <el-col :span="18">
<el-input size="small"></el-input> <el-input
size="small"
placeholder="请输入地名或点击地图选点"
@keypress.enter="searchPoint"
></el-input>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" size="small" icon="search">搜索</el-button> <el-button type="primary" size="small" icon="search">搜索</el-button>
@ -81,16 +85,19 @@
</template> </template>
<script setup> <script setup>
import { listSiteGroup } from "@/api/site/group";
import AMapLoader from "@amap/amap-jsapi-loader";
import CitySelect from "@/components/CitySelect";
import { addSite, getSite, updateSite } from "@/api/site/site";
import tab from "@/plugins/tab"; import tab from "@/plugins/tab";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { loadAMap } from "@/utils/map";
import { listSiteGroup } from "@/api/site/group";
import CitySelect from "@/components/CitySelect";
import { addSite, getSite, updateSite } from "@/api/site/site";
const route = useRoute(); const route = useRoute();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const geocoder = shallowRef(null); // 经纬度转地址插件 const geocoder = shallowRef(null); // 经纬度转地址插件
const placeSearch = shallowRef(null);
const searchResultMarkers = shallowRef([]); // 搜索结果表笔列表
const searchKeyword = ref("");
const AMap = shallowRef(null); const AMap = shallowRef(null);
const map = shallowRef(null); const map = shallowRef(null);
const siteGroupList = ref([]); const siteGroupList = ref([]);
@ -102,88 +109,7 @@ const data = reactive({
}); });
const { form, rules } = toRefs(data); const { form, rules } = toRefs(data);
// 初始化地图
const initMap = async () => {
try {
AMap.value = await AMapLoader.load({
key: "377d7c36dd385e2a722f29d4c6e1ffbf", // 申请好的Web端开发者Key首次调用 load 时必填
// key: "7891f1238368a895ff1967c79643102d", // 申请好的Web端开发者Key首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
// "AMap.Driving",
"AMap.Scale",
// "AMap.PlaceSearch",
// "AMap.AutoComplete",
"AMap.Geocoder",
// "AMap.TruckDriving",
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
AMapUI: {
// 是否加载 AMapUI缺省不加载
version: "1.1", // AMapUI 版本
plugins: ["overlay/SimpleMarker"], // 需要加载的 AMapUI ui插件
},
Loca: {
// 是否加载 Loca 缺省不加载
version: "2.0", // Loca 版本
},
});
geocoder.value = new AMap.value.Geocoder();
map.value = new AMap.value.Map("map-container", {
zoom: 16, // 缩放级别
center: [117.290345, 31.797813], // 中心点
city: "合肥",
});
window.mapins = map.value;
/** 加载插件 */
// 驾车路线规划插件
// driving.value = new AMap.value.Driving({
// // 驾车路线规划策略AMap.DrivingPolicy.LEAST_TIME是最快捷模式
// // policy: AMap.DrivingPolicy.MULTI_POLICIES,
// // map: map.value,
// panel: "panel",
// });
// 卡车路线规划插件 TODO:
// truckDriving.value = new AMap.value.TruckDriving({ map: map.value });
// // 地点搜索插件
// placeSearch.value = new AMap.value.PlaceSearch({
// // map: map.value,
// city: "0551",
// });
// geocoder.value = new AMap.value.Geocoder();
// // 搜索建议插件
// autoComplete.value = new AMap.value.AutoComplete({});
// /** 加载插件结束 */
// resultInfoWindow.value = new AMap.value.InfoWindow({
// anchor: "bottom-center",
// });
// startMarker.value = new AMap.value.Marker({
// icon: startPng,
// anchor: "bottom-center",
// });
// endMarker.value = new AMap.value.Marker({
// icon: endPng,
// anchor: "bottom-center",
// });
// city: "010", //城市设为北京,默认:“全国”
// radius: 1000, //范围默认500
// AMap.value.Event.addListener(placeSearch.value, "markerClick", (e) => {
// //添加事件
// console.log(e); //获取点标注位置
// if (nowSearch.value === "start") {
// formData.value.startName = e.data.name;
// formData.value.startLngLat = [e.data.location.lng, e.data.location.lat];
// } else if (nowSearch.value === "end") {
// formData.value.endName = e.data.name;
// formData.value.endLngLat = [e.data.location.lng, e.data.location.lat];
// }
// });
map.value.on("click", handleMapClick);
map.value.addControl(new AMap.value.Scale());
} catch (error) {
console.log(error);
}
};
// 根据经纬度获取地址 // 根据经纬度获取地址
const regeoCode = (lnglat /** [lng, lat] */) => { const regeoCode = (lnglat /** [lng, lat] */) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -225,6 +151,49 @@ function submitForm() {
}); });
} }
// 根据名称搜索地图标点
const searchPoint = (val /** 搜索建议选项 */, type) => {
map.value.clearMap();
form.value.fencePath = [];
placeSearch.value.search(searchKeyword.value, (status, result) => {
console.log(status, result);
// TODO: 添加搜索结果标记
if (status === "complete") {
searchResultMarkers.value = result.poiList.pois.map((el, index) => {
const marker = new AMap.value.Marker({
map: map.value,
position: new AMap.value.LngLat(el.location.lng, el.location.lat),
extData: el,
content: `
<div
style="
background-image: url(${markBsPng});
width: 19px;
height: 31px;
background-size: cover;
color: #fff;
text-align: center;
font-size: 12px;
padding-top: 3px;
"
>
${index + 1}
</div>
`,
});
marker.on("mouseover", handleResultClick);
marker.on("click", handleMapClick);
marker.on("mouseout", (ev) => {
resultInfoWindow.value.close();
});
return marker;
});
map.value.setFitView(searchResultMarkers.value);
}
});
};
function back() { function back() {
reset(); reset();
tab.closeOpenPage({ path: "/basic/site" }); tab.closeOpenPage({ path: "/basic/site" });
@ -249,14 +218,25 @@ function reset() {
proxy.resetForm("siteRef"); proxy.resetForm("siteRef");
} }
// 取消按钮 onMounted(async () => {
function cancel() { const _AMap = await loadAMap([
open.value = false; "AMap.Scale",
reset(); "AMap.Geocoder",
} "AMap.PlaceSearch",
]);
onMounted(() => { AMap.value = _AMap;
initMap(); map.value = new AMap.value.Map("map-container", {
zoom: 16, // 缩放级别
center: [117.290345, 31.797813], // 中心点
});
// 地点搜索插件
placeSearch.value = new AMap.value.PlaceSearch({
// map: map.value,
city: "0551",
});
geocoder.value = new AMap.value.Geocoder();
map.value.on("click", handleMapClick);
map.value.addControl(new AMap.value.Scale());
}); });
listSiteGroup().then((resp) => { listSiteGroup().then((resp) => {

View File

@ -141,6 +141,7 @@ import { listSite, delSite } from "@/api/site/site";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import AMapLoader from "@amap/amap-jsapi-loader"; import AMapLoader from "@amap/amap-jsapi-loader";
import { shallowRef, ref, reactive, toRefs } from "vue"; import { shallowRef, ref, reactive, toRefs } from "vue";
import { loadAMap } from "@/utils/map";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const router = useRouter(); const router = useRouter();
@ -188,14 +189,9 @@ function getList() {
map.value.setFitView(siteMarkerList.value); map.value.setFitView(siteMarkerList.value);
}); });
} }
const handleRowClick = (row, col, ev) => { const handleRowClick = (row) => {
if (map.value && row.marker) { if (map.value && row.marker) {
map.value.setFitView(row.marker); map.value.setFitView(row.marker);
// siteInfoWindow.value.setContent(`
// <div>
// ${123434}</div>
// `);
// siteInfoWindow.value.open(map.value, row.coordinate.split(","));
} }
}; };
/** 搜索按钮操作 */ /** 搜索按钮操作 */
@ -269,50 +265,20 @@ function handleExport() {
`site_${new Date().getTime()}.xlsx` `site_${new Date().getTime()}.xlsx`
); );
} }
// 初始化地图
const initMap = async () => {
try {
AMap.value = await AMapLoader.load({
key: "377d7c36dd385e2a722f29d4c6e1ffbf", // 申请好的Web端开发者Key首次调用 load 时必填
// key: "7891f1238368a895ff1967c79643102d", // 申请好的Web端开发者Key首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
// "AMap.Driving",
"AMap.Scale",
// "AMap.PlaceSearch",
// "AMap.AutoComplete",
// "AMap.Geocoder",
// "AMap.TruckDriving",
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
AMapUI: {
// 是否加载 AMapUI缺省不加载
version: "1.1", // AMapUI 版本
plugins: ["overlay/SimpleMarker"], // 需要加载的 AMapUI ui插件
},
Loca: {
// 是否加载 Loca 缺省不加载
version: "2.0", // Loca 版本
},
});
// geocoder.value = new AMap.value.Geocoder();
map.value = new AMap.value.Map("map-container", {
zoom: 16, // 缩放级别
center: [117.290345, 31.797813], // 中心点
city: "合肥",
});
siteInfoWindow.value = new AMap.value.InfoWindow({
anchor: "bottom-center",
});
// map.value.on("click", handleMapClick);
map.value.addControl(new AMap.value.Scale());
return "success";
} catch (error) {
console.log(error);
}
};
onMounted(() => { onMounted(() => {
initMap() loadAMap(["AMap.Scale"])
.then(() => { .then((_AMap) => {
AMap.value = _AMap;
map.value = new AMap.value.Map("map-container", {
zoom: 16, // 缩放级别
center: [117.290345, 31.797813], // 中心点
city: "合肥",
});
siteInfoWindow.value = new AMap.value.InfoWindow({
anchor: "bottom-center",
});
map.value.addControl(new AMap.value.Scale());
getList(); getList();
}) })
.catch(() => { .catch(() => {