顺时针路径排序
This commit is contained in:
@ -18,6 +18,8 @@
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
"@element-plus/icons-vue": "2.0.10",
|
||||
"@highlightjs/vue-plugin": "^2.1.0",
|
||||
"@turf/center": "^6.5.0",
|
||||
"@turf/helpers": "^6.5.0",
|
||||
"@vueuse/core": "9.5.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
|
15
src/utils/geoUtils.js
Normal file
15
src/utils/geoUtils.js
Normal file
@ -0,0 +1,15 @@
|
||||
import {points} from "@turf/helpers";
|
||||
import center from "@turf/center";
|
||||
|
||||
// [[-97.522259, 35.4691],
|
||||
// [-97.502754, 35.463455],
|
||||
// [-97.508269, 35.463245]]
|
||||
export const pointSortClockwise = (coordinates) => {
|
||||
const centerCoor = center(points(coordinates)).geometry.coordinates;
|
||||
return coordinates.sort((a, b) => {
|
||||
// 转换为以 centerCoor 为原点的坐标
|
||||
const point_a = [a[0] - centerCoor[0], a[1] - centerCoor[1]]
|
||||
const point_b = [b[0] - centerCoor[0], b[1] - centerCoor[1]]
|
||||
return Math.atan2(...point_b.reverse()) - Math.atan2(...point_a.reverse())
|
||||
})
|
||||
}
|
@ -3,82 +3,85 @@
|
||||
<el-row>
|
||||
<el-col :span="18">
|
||||
<div
|
||||
:style="{
|
||||
:style="{
|
||||
position: 'relative',
|
||||
}"
|
||||
>
|
||||
<div class="search-bar">
|
||||
<el-row :gutter="10">
|
||||
<!-- <el-col :span="7"> -->
|
||||
<el-button type="info" size="small" @click="back"
|
||||
>返回上层</el-button
|
||||
<el-button size="small" type="info" @click="back"
|
||||
>返回上层
|
||||
</el-button
|
||||
>
|
||||
<!-- </el-col> -->
|
||||
<el-col :span="10">
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
size="small"
|
||||
@keypress.enter="searchPoint"
|
||||
placeholder="请输入地名或点击地图选点"
|
||||
v-model="searchKeyword"
|
||||
placeholder="请输入地名或点击地图选点"
|
||||
size="small"
|
||||
@keypress.enter="searchPoint"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<!-- <el-col :span="7"> -->
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon="search"
|
||||
@click="searchPoint"
|
||||
>搜索</el-button
|
||||
icon="search"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="searchPoint"
|
||||
>搜索
|
||||
</el-button
|
||||
>
|
||||
<!-- </el-col> -->
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
@click="switchMapLayer"
|
||||
>{{ isSatelliteMode ? "标准模式" : "卫星模式" }}</el-button
|
||||
plain
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="switchMapLayer"
|
||||
>{{ isSatelliteMode ? "标准模式" : "卫星模式" }}
|
||||
</el-button
|
||||
>
|
||||
</el-row>
|
||||
</div>
|
||||
<div id="map-container"></div>
|
||||
<el-button
|
||||
:style="{
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
right: '20px',
|
||||
top: '20px',
|
||||
}"
|
||||
@click="
|
||||
circle
|
||||
icon="refresh"
|
||||
type="primary"
|
||||
@click="
|
||||
map.clearMap();
|
||||
form.fencePath = [];
|
||||
"
|
||||
type="primary"
|
||||
icon="refresh"
|
||||
circle
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card class="fence-form-card">
|
||||
<el-scrollbar
|
||||
:wrap-style="{
|
||||
:wrap-style="{
|
||||
height: 'calc(100vh - 84px - 35px)',
|
||||
}"
|
||||
>
|
||||
<el-form
|
||||
ref="fenceRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="80px"
|
||||
label-position="top"
|
||||
ref="fenceRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="top"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="围栏名称" prop="fenceName">
|
||||
<el-input
|
||||
v-model="form.fenceName"
|
||||
placeholder="请输入围栏名称"
|
||||
v-model="form.fenceName"
|
||||
placeholder="请输入围栏名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="限速(km/h)" prop="speed">
|
||||
<el-input v-model="form.speed" placeholder="请输入限速(km/h)" />
|
||||
<el-input v-model="form.speed" placeholder="请输入限速(km/h)"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="报警类型" prop="reportType">
|
||||
<el-radio-group v-model="form.reportType" class="ml-4">
|
||||
@ -90,8 +93,8 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="报警时段" prop="reportTime">
|
||||
<el-input
|
||||
v-model="form.reportTime"
|
||||
placeholder="请输入报警时段"
|
||||
v-model="form.reportTime"
|
||||
placeholder="请输入报警时段"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="围栏地图数据" prop="fencePath">
|
||||
@ -104,13 +107,14 @@
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-button
|
||||
:style="{
|
||||
:style="{
|
||||
width: '100%',
|
||||
}"
|
||||
@click="submitForm"
|
||||
type="primary"
|
||||
size="small"
|
||||
>保存</el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="submitForm"
|
||||
>保存
|
||||
</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -127,17 +131,17 @@
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="AddFence">
|
||||
<script name="AddFence" setup>
|
||||
import tab from "@/plugins/tab";
|
||||
import { onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { loadAMap } from "@/utils/map";
|
||||
import {onMounted} from "vue";
|
||||
import {useRoute} from "vue-router";
|
||||
import {loadAMap} from "@/utils/map";
|
||||
import markBsPng from "@/assets/images/mark_bs.png";
|
||||
import mapPinPng from "@/assets/images/map-pin.png";
|
||||
import { addFence, updateFence, getFence } from "@/api/fence";
|
||||
import {addFence, getFence, updateFence} from "@/api/fence";
|
||||
|
||||
const route = useRoute();
|
||||
const { proxy } = getCurrentInstance();
|
||||
const {proxy} = getCurrentInstance();
|
||||
const AMap = shallowRef(null);
|
||||
const map = shallowRef(null);
|
||||
const placeSearch = shallowRef(null);
|
||||
@ -169,7 +173,7 @@ const data = reactive({
|
||||
},
|
||||
});
|
||||
|
||||
const { form, rules } = toRefs(data);
|
||||
const {form, rules} = toRefs(data);
|
||||
|
||||
const addFencePath = (lnglat) => {
|
||||
if (map.value.getAllOverlays("polygon").length === 0) {
|
||||
@ -177,10 +181,10 @@ const addFencePath = (lnglat) => {
|
||||
}
|
||||
form.value.fencePath.push(lnglat);
|
||||
turningPointMarker.value.push(
|
||||
new AMap.value.Marker({
|
||||
map: map.value,
|
||||
position: lnglat,
|
||||
content: `
|
||||
new AMap.value.Marker({
|
||||
map: map.value,
|
||||
position: lnglat,
|
||||
content: `
|
||||
<div
|
||||
style="
|
||||
background-image: url(${mapPinPng});
|
||||
@ -195,8 +199,8 @@ const addFencePath = (lnglat) => {
|
||||
>
|
||||
</div>
|
||||
`,
|
||||
anchor: "bottom-right",
|
||||
})
|
||||
anchor: "bottom-right",
|
||||
})
|
||||
);
|
||||
if (form.value.fencePath.length > 2) {
|
||||
turningPointMarker.value.forEach((el) => {
|
||||
@ -327,7 +331,7 @@ function reset() {
|
||||
|
||||
function back() {
|
||||
reset();
|
||||
tab.closeOpenPage({ path: "/basic/fence" });
|
||||
tab.closeOpenPage({path: "/basic/fence"});
|
||||
}
|
||||
|
||||
reset();
|
||||
@ -355,16 +359,16 @@ onMounted(() => {
|
||||
map.value.add(fencePolygon.value);
|
||||
map.value.addControl(new AMap.value.Scale());
|
||||
if (route.query.fenceId && route.query.uuid) {
|
||||
const routerObj = Object.assign({}, route, { title: "修改电子围栏" });
|
||||
const routerObj = Object.assign({}, route, {title: "修改电子围栏"});
|
||||
tab.updatePage(routerObj);
|
||||
getFence(route.query.fenceId, route.query.uuid).then((resp) => {
|
||||
form.value = {
|
||||
...resp.data,
|
||||
fencePath: resp.data.fencePath
|
||||
? JSON.parse(resp.data.fencePath).map(
|
||||
(el) => new AMap.value.LngLat(...el)
|
||||
? JSON.parse(resp.data.fencePath).map(
|
||||
(el) => new AMap.value.LngLat(...el)
|
||||
)
|
||||
: [],
|
||||
: [],
|
||||
};
|
||||
fencePolygon.value.setPath(form.value.fencePath);
|
||||
map.value.setFitView([fencePolygon.value]);
|
||||
@ -382,10 +386,12 @@ onMounted(() => {
|
||||
left: 20px;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
#map-container {
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
}
|
||||
|
||||
.fence-form-card {
|
||||
height: calc(100vh - 84px);
|
||||
}
|
||||
|
Reference in New Issue
Block a user