|
|
@@ -1,314 +0,0 @@
|
|
|
-<!--
|
|
|
- * @Description:
|
|
|
- * @Version:
|
|
|
- * @Author: 黄先伟
|
|
|
- * @Date: 2024-01-10 17:04:41
|
|
|
--->
|
|
|
-<template>
|
|
|
- <div class="d-flex j-sb" style="padding: 10px 0 20px;">
|
|
|
- <el-space :size="20">
|
|
|
- <el-button @click="addLayers()" color="#02a7f0">添加卫星图层</el-button>
|
|
|
- <el-button @click="removeLayers()" type="warning">移除卫星图层</el-button>
|
|
|
- <template v-if="query.mode !== '1'">
|
|
|
- <el-button type="primary" @click="createPolygon">新建地块</el-button>
|
|
|
- <el-button @click="endPolygon" type="info" plain>取消选中</el-button>
|
|
|
- <el-button @click="removePolygon" type="danger" plain>删除选中地块</el-button>
|
|
|
- <el-button @click="clearPolygon" type="danger" plain>删除所有地块</el-button>
|
|
|
- </template>
|
|
|
- </el-space>
|
|
|
- <el-select
|
|
|
- filterable
|
|
|
- remote
|
|
|
- v-model="keywords"
|
|
|
- reserve-keyword
|
|
|
- placeholder="请输入关键字定位到你的园区"
|
|
|
- :remote-method="remoteMethod"
|
|
|
- @change="searchKeywords"
|
|
|
- :loading="loading"
|
|
|
- style="width: 240px"
|
|
|
- >
|
|
|
- <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- <div :id="el" ref="mapViewRef" class="map-container"></div>
|
|
|
- <btm-wrap v-if="query.mode !== '1'">
|
|
|
- <el-space :size="24">
|
|
|
- <el-button @click="$router.go(-1)">取消</el-button>
|
|
|
- <el-button @click="save" type="primary">保存</el-button>
|
|
|
- </el-space>
|
|
|
- </btm-wrap>
|
|
|
-</template>
|
|
|
-<script name="MapContainer" setup lang="ts">
|
|
|
-
|
|
|
-import { onMounted, onUnmounted, getCurrentInstance } from 'vue';
|
|
|
-import html2canvas from 'html2canvas';
|
|
|
-import AMapLoader from '@amap/amap-jsapi-loader';
|
|
|
-import cache from '@/plugins/cache';
|
|
|
-import { dataURLtoBlob } from '@/utils/ruoyi';
|
|
|
-import { uploadFile } from '@/api/system/oss';
|
|
|
-import { useRoute, onBeforeRouteLeave } from 'vue-router';
|
|
|
-import router from '@/router';
|
|
|
-
|
|
|
-const route = useRoute();
|
|
|
-const { query } = route;
|
|
|
-const { proxy, appContext } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
-const { Bus } = appContext.config.globalProperties;
|
|
|
-const loading = ref(false);
|
|
|
-const options = ref<any[]>([]);
|
|
|
-const flag = ref(false)
|
|
|
-const props = defineProps({
|
|
|
- el: {
|
|
|
- type: String,
|
|
|
- default: 'container'
|
|
|
- },
|
|
|
- pathsList: {
|
|
|
- type: Array<any>,
|
|
|
- default: []
|
|
|
- }
|
|
|
-});
|
|
|
-let mapData = reactive<any>({
|
|
|
- map: null,
|
|
|
- polyEditor: null,
|
|
|
- AMap: null,
|
|
|
- Satellite: null
|
|
|
-});
|
|
|
-const keywords = ref('');
|
|
|
-const searchKeywords = (event: string) => {
|
|
|
- const item = options.value.find(({ id }) => id === event);
|
|
|
- const { location, name } = item;
|
|
|
- if (location) {
|
|
|
- console.log(location);
|
|
|
- mapData.map.setCenter(location);
|
|
|
- } else if (name) {
|
|
|
- mapData.map.setCity(name);
|
|
|
- }
|
|
|
-};
|
|
|
-const remoteMethod = (keywords: string) => {
|
|
|
- if (!keywords) {
|
|
|
- return;
|
|
|
- }
|
|
|
- loading.value = true;
|
|
|
- let autoComplete = new mapData.AMap.Autocomplete();
|
|
|
- autoComplete.search(keywords, function (status: string, result: any) {
|
|
|
- const tips = result.tips.filter((item: any) => item.id);
|
|
|
- options.value = [...tips];
|
|
|
- loading.value = false;
|
|
|
- });
|
|
|
-};
|
|
|
-const paths = ref<any>({});
|
|
|
-const initMap = (positions: any[] = []) => {
|
|
|
- AMapLoader.load({
|
|
|
- key: '26b919a68880ad60637f5cabd6c94a76', // 申请好的Web端开发者Key,首次调用 load 时必填
|
|
|
- version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
|
|
- plugins: [
|
|
|
- 'AMap.PolygonEditor',
|
|
|
- 'AMap.GeometryUtil',
|
|
|
- 'AMap.ToolBar',
|
|
|
- 'AMap.ControlBar',
|
|
|
- 'AMap.MouseTool',
|
|
|
- 'AMap.PlaceSearch',
|
|
|
- 'AMap.AutoComplete'
|
|
|
- ] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
|
|
- })
|
|
|
- .then((AMap) => {
|
|
|
- mapData.AMap = AMap;
|
|
|
- mapData.Satellite = new mapData.AMap.TileLayer.Satellite({
|
|
|
- zooms: [1, 24],
|
|
|
- zIndex: 8,
|
|
|
- heightFactor: 2 // 2
|
|
|
- });
|
|
|
- mapData.map = new AMap.Map(props.el, {
|
|
|
- // 设置地图容器id
|
|
|
- viewMode: '3D', // 是否为3D地图模式
|
|
|
- zoom: 14.8, // 初始化地图级别
|
|
|
- resizeEnable: true,
|
|
|
- center: [102.705207, 25.049848],
|
|
|
- WebGLParams: {
|
|
|
- preserveDrawingBuffer: true
|
|
|
- }
|
|
|
- });
|
|
|
- mapData.map.addLayer(mapData.Satellite);
|
|
|
- const toolbar = new AMap.ToolBar(); //缩放工具条实例化
|
|
|
- mapData.map.addControl(toolbar);
|
|
|
- const ControlBar = new AMap.ControlBar(); //缩放工具条实例化
|
|
|
- mapData.map.addControl(ControlBar);
|
|
|
- // 获取传入的path
|
|
|
- const curPaths = positions.map((path) =>
|
|
|
- path.filter(({ lat, lng }: any, index: number) => !(lat === path[0].lat && path[0].lng === lng) || !index)
|
|
|
- );
|
|
|
- const addPolygon = curPaths.map((path) => new AMap.Polygon({ path: path.map(({ lat, lng }: any) => new AMap.LngLat(lng, lat)) }));
|
|
|
- mapData.map.add(addPolygon);
|
|
|
- mapData.map.setFitView(addPolygon, false, [60, 60, 60, 60], 16);
|
|
|
- if (query.mode !== '1') {
|
|
|
- mapData.polyEditor = new AMap.PolygonEditor(mapData.map);
|
|
|
- mapData.polyEditor.addAdsorbPolygons(addPolygon);
|
|
|
- for (let index = 0; index < addPolygon.length; index++) {
|
|
|
- const polygon = addPolygon[index];
|
|
|
- setPaths(polygon);
|
|
|
- polygon.on('dblclick', () => {
|
|
|
- mapData.polyEditor.setTarget(polygon);
|
|
|
- mapData.polyEditor.open();
|
|
|
- });
|
|
|
- }
|
|
|
- mapData.polyEditor.on('add', function (data: any) {
|
|
|
- let polygon = data.target;
|
|
|
- mapData.polyEditor.addAdsorbPolygons(polygon);
|
|
|
- setPaths(polygon);
|
|
|
- polygon.on('dblclick', () => {
|
|
|
- mapData.polyEditor.setTarget(polygon);
|
|
|
- mapData.polyEditor.open();
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- })
|
|
|
- .catch((e) => {
|
|
|
- console.log(e);
|
|
|
- });
|
|
|
-};
|
|
|
-const addLayers = () => {
|
|
|
- mapData.map.addLayer(mapData.Satellite);
|
|
|
-};
|
|
|
-const removeLayers = () => {
|
|
|
- mapData.map.removeLayer(mapData.Satellite);
|
|
|
-};
|
|
|
-const createPolygon = () => {
|
|
|
- mapData.polyEditor.close();
|
|
|
- mapData.polyEditor.setTarget();
|
|
|
- mapData.polyEditor.open();
|
|
|
-};
|
|
|
-
|
|
|
-const setPaths = (polygon: any) => {
|
|
|
- const path = polygon.getPath();
|
|
|
- const _amap_id = polygon._amap_id;
|
|
|
- const areaNum = ringArea(path);
|
|
|
- paths.value[_amap_id] = { path, areaNum };
|
|
|
- return paths.value;
|
|
|
-};
|
|
|
-const endPolygon = () => {
|
|
|
- mapData.polyEditor.close();
|
|
|
- const polygon = mapData.polyEditor.getTarget();
|
|
|
- if (polygon) {
|
|
|
- setPaths(polygon);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const save = () => {
|
|
|
- if (flag.value) {
|
|
|
- return
|
|
|
- }
|
|
|
- proxy?.$modal.loading('保存中');
|
|
|
- flag.value = true
|
|
|
- mapData.polyEditor.close();
|
|
|
- const polygon = mapData.polyEditor.getTarget();
|
|
|
- if (polygon) {
|
|
|
- setPaths(polygon);
|
|
|
- }
|
|
|
- const bounds = mapData.map.setFitView();
|
|
|
- if (bounds) {
|
|
|
- setTimeout(() => {
|
|
|
- getImageCover();
|
|
|
- }, 1000)
|
|
|
- }
|
|
|
-};
|
|
|
-const removeIds = ref<any[]>([]);
|
|
|
-const removePolygon = () => {
|
|
|
- mapData.polyEditor.close();
|
|
|
- const polygon = mapData.polyEditor.getTarget();
|
|
|
- const _amap_id = polygon._amap_id;
|
|
|
- delete paths.value[_amap_id];
|
|
|
- removeIds.value.push(_amap_id);
|
|
|
- mapData.polyEditor.removeAdsorbPolygons([polygon]);
|
|
|
- mapData.map.remove(polygon);
|
|
|
-};
|
|
|
-const clearPolygon = () => {
|
|
|
- paths.value = {};
|
|
|
- if (mapData.polyEditor) {
|
|
|
- mapData.polyEditor.close();
|
|
|
- mapData.polyEditor.clearAdsorbPolygons();
|
|
|
- if (mapData.map.getAllOverlays('polygon')) {
|
|
|
- const mapPolyArr = mapData.map.getAllOverlays('polygon');
|
|
|
- let arr: any[] = [];
|
|
|
- mapPolyArr.forEach((polygon: any) => {
|
|
|
- arr.push(polygon);
|
|
|
- });
|
|
|
- mapData.map.remove(arr);
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-const ringArea = (path: any) => {
|
|
|
- const squareMeters: number = mapData.AMap.GeometryUtil.ringArea(path);
|
|
|
- return squareMeterToAcre(squareMeters);
|
|
|
-};
|
|
|
-const squareMeterToAcre = (squareMeters: number) => {
|
|
|
- return squareMeters / (60 * 175); // 将平方米转换为亩数
|
|
|
-};
|
|
|
-const mapViewRef = ref<HTMLElement>();
|
|
|
-const getImageCover = async () => {
|
|
|
- const canvas = await html2canvas(mapViewRef.value as HTMLElement, {
|
|
|
- scale: 1,
|
|
|
- logging: false,
|
|
|
- useCORS: false
|
|
|
- });
|
|
|
- let type = 'png';
|
|
|
- let imgData = canvas.toDataURL(type);
|
|
|
- // 照片格式处理
|
|
|
- let _fixType = function (type: string) {
|
|
|
- type = type.toLowerCase().replace(/jpg/i, 'jpeg');
|
|
|
- let r: any = type.match(/png|jpeg|bmp|gif/);
|
|
|
- return 'image/' + r ? r[0] : '';
|
|
|
- };
|
|
|
- imgData = imgData.replace(_fixType(type), 'image/octet-stream');
|
|
|
- const blobFile: Blob = dataURLtoBlob(imgData);
|
|
|
- getImgUrl(blobFile);
|
|
|
-};
|
|
|
-const getImgUrl = async (blobFile: Blob) => {
|
|
|
- const formdata = new FormData();
|
|
|
- let fileBlob = new File([blobFile], new Date().getTime() + '.png');
|
|
|
- formdata.append('file', fileBlob);
|
|
|
- const res = await uploadFile(formdata);
|
|
|
- if (!res || res.code !== 200) return;
|
|
|
- const postionImg = res.data.url;
|
|
|
- const pos: any[] = [];
|
|
|
- let area = 0;
|
|
|
- Object.entries(paths.value).forEach(([key, value]: any) => {
|
|
|
- if (!removeIds.value.includes(+key)) {
|
|
|
- const arrPath = value.path.map(({ lat, lng }: any) => ({ lat, lng }));
|
|
|
- pos.push([...arrPath, arrPath[0]]);
|
|
|
- area += value.areaNum;
|
|
|
- }
|
|
|
- });
|
|
|
- area = Math.round(area * 100) / 100;
|
|
|
- cache.session.setJSON('changeArea', { postionImg: pos && pos.length ? postionImg : '', positions: [...pos], area });
|
|
|
- clearPolygon();
|
|
|
- proxy?.$modal.closeLoading()
|
|
|
- flag.value = false
|
|
|
- router.go(-1);
|
|
|
-};
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- const positions = ref<any[]>([]);
|
|
|
- positions.value = cache.session.getJSON('positions');
|
|
|
- initMap(positions.value);
|
|
|
- cache.session.remove('positions');
|
|
|
-});
|
|
|
-onUnmounted(() => {
|
|
|
- mapData.map?.destroy();
|
|
|
-});
|
|
|
-
|
|
|
-onBeforeRouteLeave((to, from, next) => {
|
|
|
- cache.session.remove('positions');
|
|
|
- try {
|
|
|
- console.log('hehe');
|
|
|
- clearPolygon();
|
|
|
- next();
|
|
|
- } catch {
|
|
|
- next();
|
|
|
- }
|
|
|
-});
|
|
|
-</script>
|
|
|
-<style scoped>
|
|
|
-.map-container {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-</style>
|