123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- <template>
- <div class="slider-container" v-if="!layoutStore.footerCollapse">
- <el-form v-model="form" inline class="top-form">
- <el-form-item label="类型" prop="meshType">
- <el-radio-group v-model="form.meshType">
- <el-radio label="二维" value="二维" />
- <el-radio label="三维" value="三维" />
- </el-radio-group>
- </el-form-item>
- <el-form-item>
- <el-checkbox v-model="form.grade">三维评分</el-checkbox>
- </el-form-item>
- <el-form-item>
- <el-checkbox v-model="form.deepShow">深度显示</el-checkbox>
- </el-form-item>
- <el-form-item label="范围" prop="meshRange">
- <el-radio-group v-model="form.meshRange">
- <el-radio label="自适应" value="自适应" />
- <el-radio label="自定义" value="自定义" />
- <el-radio label="行政区划" value="行政区划" />
- </el-radio-group>
- </el-form-item>
- <el-form-item v-if="form.meshRange === '自定义'">
- <el-button class="btn-secondary" @click="handleDraw">绘制</el-button>
- </el-form-item>
- <el-form-item v-if="form.meshRange === '行政区划'">
- <el-cascader v-model="form.district" @change="handleSelectDistrict" :options="districtList"
- :props="cascaderProps" placeholder="请选择行政区划" />
- </el-form-item>
- </el-form>
-
- <div class="slider-bg single-slider">
- <div class="slider">
- <div v-for="(point, index) in DenseData" :key="index" class="marker"
- :class="{ 'key-point': selectedPoint === index }"
- :style="{ left: index * (100 / (DenseData.length - 1)) + '%' }" @click="selectPoint(index)">
- <span class="label">{{ point.label }}</span>
- <span class="des">{{ point.des }}</span>
- </div>
- </div>
- </div>
-
- <div class="slider-bg range-slider">
- <div class="slider">
-
- <div class="range-highlight" v-if="rangeStart !== null && rangeEnd !== null" :style="{
- left: rangeStart * (100 / (heightData.length - 1)) + 1.5 + '%',
- width: (rangeEnd - rangeStart) * (100 / (heightData.length - 1)) + '%',
- }"></div>
-
- <div v-for="(point, index) in heightData" :key="index" class="marker" :class="{
- 'active': (rangeStart !== null && rangeEnd === null && index === rangeStart) || (rangeStart !== null && rangeEnd !== null && index >= rangeStart && index <= rangeEnd),
- 'hover': shouldHighlightOnHover(index),
- 'key-point': index === rangeStart || index === rangeEnd
- }" :style="{ left: index * (100 / (heightData.length - 1)) + '%' }" @click="selectRange(index)"
- @mouseover="handleMouseOver(index)" @mouseleave="handleMouseLeave">
- <span class="label">{{ point.label }}</span>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { ref, reactive, onMounted, onBeforeUnmount, watch } from 'vue';
- import { addKysgScale, DrawPolygon, QueryDistrict, QueryCube, clearDraw } from "@/utils/map/addLayer.js";
- import useLayoutStore from '@/store/layout';
- import { useMapStore } from '@/store/map';
- import { GetDistrictTree } from '@/service/http';
- import {geometryMeshEffect} from "@/utils/map/addTool.js";
- export default {
- setup(props, { emit }) {
- const mapStore = useMapStore()
- const layoutStore = useLayoutStore()
- const form = ref({
- meshType: '二维',
- grade: true,
- deepShow:false,
- meshRange: '自适应'
- })
- let lastEvaluation
- let rings
- const selectedPoint = ref(null);
- const rangeStart = ref(null);
- const rangeEnd = ref(null);
- const hoverIndex = ref(null);
- const districtList = ref([])
- function handleSelectDistrict(val) {
- QueryDistrict(val)
- }
- const cascaderProps = {
- expandTrigger: 'hover',
- checkStrictly: true
- }
- watch(() => form.value.meshRange, (val) => {
- console.log(val)
- clearDraw()
- clearQueryCube()
- rings = null
- if (val === '自适应') {
- layoutStore.toggleGlobalLoading(true)
- setTimeout(() => {
- layoutStore.toggleGlobalLoading(false)
- }, 3000);
- addKysgScale(true)
- clearPoints()
- } else {
- addKysgScale(false)
- if (val === '行政区划' && !districtList.value.length) {
- GetDistrictTree().then(res => {
- if (!Array.isArray(res.data)) {
- ElMessage({ offset: 90, type: 'warning', message: '行政区划获取失败' })
- return
- }
- districtList.value = res.data
- }).catch(() => {
- ElMessage({ offset: 90, type: 'warning', message: '行政区划获取失败' })
- })
- }
- }
- }, { immediate: true })
- watch(form, (val) => {
- showGrid()
- }, { deep: true })
- function handleDraw() {
- clearQueryCube();
- getMesh("hide");
- DrawPolygon({ hasZ: true })
- }
- watch(() => mapStore.draw_geometry, (val) => {
- rings = val?.rings
- clearDraw();
- getMesh("show");
- showGrid()
- }, { deep: true })
- watch(() => mapStore.queryResult, (val) => {
- rings = val[0].geometry.rings
- showGrid()
- }, { deep: true })
- const DenseData = reactive([
-
- { label: '1/4″网格', level: 23, size: { x: 6.7358, y: 7.7024, z: 6.6111 }, des: '(7m)' },
- { label: '1/2″网格', level: 22, size: { x: 13.222978864358083, y: 15.406742669116284, z: 13.471596544164798 }, des: '(15m)' },
- { label: '1′网格', level: 21, size: { x: 26.44107169853396, y: 30.815525255577086, z: 26.943221541824816 }, des: '(30.9m)' },
- { label: '2′网格', level: 20, size: { x: 52.887881893650956, y: 61.627412608112536, z: 53.887012166300096 }, des: '(61m)' },
- { label: '4′网格', level: 19, size: { x: 105.79869494173579, y: 123.43930203184209, z: 107.77356906534683 }, des: '(123.7m)' },
- { label: '8′网格', level: 18, size: { x: 211.66439868324142, y: 246.49964316944533, z: 215.5489592181181 }, des: '(247.4m)' },
- { label: '16′网格', level: 17, size: { x: 424.0518521273334, y: 492.09123171765896, z: 431.1052029077298 }, des: '(376.7m)' },
- { label: '32′网格', level: 16, size: { x: 844.8477050379952, y: 990.1345935064928, z: 862.239544684298 }, des: '(746.4m)' },
- { label: '1′网格', level: 15, size: { x: 1582.2726823222256, y: 1856.6079667204758, z: 1724.5956527210265 }, des: '(1850m)' },
-
- ]);
- const heightData = reactive([
- { label: "0m", value: 0 },
- { label: "20m", value: 20 },
- { label: "40m", value: 40 },
- { label: "60m", value: 60 },
- { label: "80m", value: 80 },
- { label: "100m", value: 100 },
- { label: "120m", value: 120 },
- { label: "200m", value: 200 },
- { label: "300m", value: 300 },
- { label: "600m", value: 600 },
- { label: "1000m", value: 1000 },
- ]);
- function clearPoints() {
- selectedPoint.value = null
- rangeStart.value = null
- rangeEnd.value = null
- }
-
- const selectPoint = (index) => {
- selectedPoint.value = index;
- showGrid()
- };
-
- const selectRange = (index) => {
- if (rangeStart.value === null || rangeEnd.value !== null) {
-
- rangeStart.value = index;
- rangeEnd.value = null;
- } else {
-
- rangeEnd.value = index;
- if (rangeEnd.value < rangeStart.value) {
-
- [rangeStart.value, rangeEnd.value] = [rangeEnd.value, rangeStart.value];
- }
- }
- showGrid()
- };
- const handleMouseOver = (index) => {
- hoverIndex.value = index;
- };
- const handleMouseLeave = () => {
- hoverIndex.value = null;
- };
- const shouldHighlightOnHover = (index) => {
- if ((hoverIndex.value !== null && rangeStart.value === null) || (rangeStart.value !== null && rangeEnd.value !== null)) {
-
- return index === hoverIndex.value;
- } else if (hoverIndex.value !== null && rangeStart.value !== null && rangeEnd.value === null) {
-
- return (
- (index >= rangeStart.value && index <= hoverIndex.value) ||
- (index <= rangeStart.value && index >= hoverIndex.value)
- );
- }
- return false;
- };
- let timer_showGrid
-
- const showGrid = () => {
- if (timer_showGrid) {
- clearTimeout(timer_showGrid)
- }
- timer_showGrid = setTimeout(() => {
- console.log('showGrid')
- console.log('rings:',rings)
- console.log('points',selectedPoint.value, rangeStart.value, rangeEnd.value)
- if (!rings) return
- if (selectedPoint.value===null || rangeStart.value===null || rangeEnd.value===null) return
- clearQueryCube()
- setTimeout(() => {
- QueryCube({
- id: 'query_cube_kysg',
- evaluation: form.value.grade,
- deepShow: form.value.deepShow,
- show: true,
- level: DenseData[selectedPoint.value].level,
- minZ: heightData[rangeStart.value].value,
- maxZ: heightData[rangeEnd.value].value,
- rings: rings
- })
- }, 300);
- lastEvaluation = form.value.grade
- }, 1000)
- };
- function clearQueryCube() {
- QueryCube({
- id: 'query_cube_kysg',
- evaluation: lastEvaluation,
- show: false,
- })
- }
-
- function getMesh(status){
- if(status == "hide"){
- geometryMeshEffect({
- id: 'sgzy_mesh',
- status: "hide"
- })
- return
- }
- let height = heightData[rangeEnd.value].value - heightData[rangeStart.value].value;
- let tempRings = [];
- for(let i = 0; i < rings[0].length; i++){
- tempRings.push([rings[0][i][0],rings[0][i][1],heightData[rangeStart.value].value - 0.01])
- }
- debugger
- geometryMeshEffect({
- id: 'sgzy_mesh',
- status:"show",
- data: [{
- type: 'polygon',
- shape: {
- height: height,
- rings: [tempRings],
- color: [0,255,0,0.2]
- }
- }]
- })
- }
- onBeforeUnmount(() => {
- addKysgScale(false);
- getMesh("hide")
- clearDraw()
- clearQueryCube()
- })
- return {
- layoutStore,
- form,
- DenseData,
- heightData,
- selectedPoint,
- rangeStart,
- rangeEnd,
- selectPoint,
- selectRange,
- handleMouseOver,
- handleMouseLeave,
- shouldHighlightOnHover,
- handleDraw,
- handleSelectDistrict,
- cascaderProps,
- districtList
- };
- },
- };
- </script>
- <style lang="scss" scoped>
- .slider-container {
- position: absolute;
- top: calc(var(--aside-height) - 246px - var(--footer-height));
- left: calc(50% - 448px);
- width: 896px;
- height: 260px;
- background: rgba(0, 10, 30, 0.6);
- box-shadow: 0px 1px 6px 0px rgba(37, 37, 37, 0.6);
- border: 1px solid #98baffb6;
- visibility: visible;
- }
- .top-form {
- display: flex;
- flex-wrap: nowrap;
- align-items: center;
- margin: 15px 12px 0;
- .el-form-item {
- margin-right: 10px;
- }
- }
- .type-list {
- width: 100%;
- height: 60px;
- display: flex;
- flex-direction: row;
- justify-content: center;
- align-items: center;
- }
- .slider-bg {
- width: calc(100% - 10px);
- height: 25px;
- background: url('../../../assets/images/page/slider-bg.png') no-repeat;
- background-size: 100% 100%;
- padding: 0 70px 0 60px;
- margin-right: 10px;
- }
- .slider {
- position: relative;
- height: 100%;
- /* background-color: #2a2f3a; */
- }
- .marker {
- position: absolute;
- width: 25px;
- height: 25px;
- cursor: pointer;
- transition: background-color 0.3s;
- &::before {
- content: '';
- position: absolute;
- display: block;
- top: 9px;
- left: 8px;
- width: 8px;
- height: 8px;
- transform: rotateZ(45deg);
- border: 2px solid #6495ed;
- }
- &.active::before {
- border-color: #ffd700;
- }
- &.hover::before {
- background-color: #ffd700;
- }
- &.key-point {
- span {
- font-weight: bold;
- font-size: 18px;
- color: #FFFFFF;
- }
- &::before {
- border-color: #FFFCF5;
- box-shadow: 0 0 4px 5px #ffd90062;
- background-color: #ffd700;
- }
- }
- }
- .label {
- position: absolute;
- top: -45px;
- left: 50%;
- transform: translateX(-50%);
- white-space: nowrap;
- font-size: 16px;
- color: #9DAAC7;
- }
- .des {
- position: absolute;
- top: -25px;
- left: 50%;
- transform: translateX(-50%);
- white-space: nowrap;
- font-size: 14px;
- color: #9DAAC7;
- }
- .range-highlight {
- position: absolute;
- top: 3px;
- height: 80%;
- background-color: rgba(255, 212, 0, 0.2);
- z-index: 1;
- }
- .single-slider {
- margin-top: 50px;
- .label {
- font-size: 14px;
- }
- .key-point span {
- font-size: 16px;
- }
- }
- .range-slider {
- margin-top: 53px;
- .slider .marker {
- z-index: 2;
- }
- .label {
- top: -25px;
- }
- }
- </style>
|