123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- <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="自适应" @click="handleTest" />
- <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="请选择行政区划"
- class="w-32" />
- </el-form-item>
- </el-form>
- <!-- 单点选择滑动条 -->
- <div class="slider-bg single-slider" :class="{ disabled: form.meshRange === '自适应' }">
- <div class="slider">
- <div
- v-for="(point, index) in DenseData"
- :key="index"
- class="marker"
- :class="{ 'key-point': form.meshLevel === point.level }"
- :style="{ left: index * (100 / (DenseData.length - 1)) + '%' }"
- @click="selectPoint(point)">
- <span class="label">{{ point.label }}</span>
- <span class="des">{{ point.des }}</span>
- </div>
- </div>
- </div>
- <!-- 范围选择滑动条 -->
- <el-slider
- class="slider-bg range-slider"
- :class="{ disabled: form.meshRange === '自适应' }"
- v-model="form.meshHeights"
- :min="0"
- :max="600"
- range
- :marks="marks"
- tooltip-class="range-tooltip"
- placement="bottom"
- :format-tooltip="(val) => val + 'm'" />
- </div>
- </template>
- <script setup>
- import { ref, onBeforeUnmount, watch, reactive, nextTick } 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'
- const mapStore = useMapStore()
- const layoutStore = useLayoutStore()
- const form = ref({
- meshType: '三维',
- grade: true,
- deepShow: false,
- meshRange: '自适应',
- meshLevel: '',
- meshHeights: [0, 0],
- })
- const marks = reactive({
- 0: '0m',
- 100: '100m',
- 200: '200m',
- 300: '300m',
- 400: '400m',
- 500: '500m',
- 600: '600m',
- })
- let lastEvaluation
- let rings
- 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 }
- )
- watch(
- () => mapStore.currentCubeLevel,
- (val) => {
- if (val) {
- form.value.meshLevel = val
- const maxHeight = Number(DenseData.find((d) => d.level == val).des.slice(1, -2))
- form.value.meshHeights = [0, Math.min(600, maxHeight)]
- }
- }
- )
- const DenseData = reactive([
- // { label: '1/8″网格', level: 24, size: { x: 3.3055614085396883, y: 3.8513467134689563, z: 3.3678982462941303 }, des: '(3.9m)'},
- { 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)',
- },
- // { label: '2′网格', level: 14, size: { x: 2984.4, y: 2984.4, z: 2984.4 }, des: '(2984.4m)'},
- ])
- function clearPoints() {
- form.value.meshLevel = ''
- form.value.meshHeights = [0, 0]
- nextTick(() => {
- const toolsTips = document.getElementsByClassName('range-tooltip')
- for (let i = 0; i < toolsTips.length; i++) {
- toolsTips[i].style.visibility = 'hidden'
- }
- const sliderBtns = document.getElementsByClassName('el-slider__button-wrapper')
- for (let i = 0; i < toolsTips.length; i++) {
- sliderBtns[i].addEventListener('mousedown', () => {
- toolsTips[i].style.visibility = 'visible'
- })
- }
- })
- }
- // 单点选择逻辑
- const selectPoint = (point) => {
- form.value.meshLevel = point.level
- showGrid()
- }
- let timer_showGrid
- // 显示网格
- const showGrid = () => {
- if (timer_showGrid) {
- clearTimeout(timer_showGrid)
- }
- timer_showGrid = setTimeout(() => {
- console.log('showGrid')
- console.log('rings:', rings)
- console.log('form', form.value)
- if (!rings) return
- const { grade, deepShow, meshLevel, meshHeights } = form.value
- if (!meshLevel || meshHeights.every((h) => h === 0)) return
- clearQueryCube()
- setTimeout(() => {
- QueryCube({
- id: 'query_cube_kysg',
- evaluation: grade,
- deepShow: deepShow,
- show: true,
- level: meshLevel,
- minZ: meshHeights[0],
- maxZ: meshHeights[1],
- rings: rings,
- })
- }, 300)
- lastEvaluation = 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
- }
- const [h1, h2] = form.value.meshHeights
- console.log('h1&h2:', h1, h2)
- let height = h2 - h1
- let tempRings = []
- for (let i = 0; i < rings[0].length; i++) {
- tempRings.push([rings[0][i][0], rings[0][i][1], h1 - 0.01])
- }
- 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()
- })
- </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;
- }
- :deep(.top-form) {
- height: 55px;
- display: flex;
- flex-wrap: nowrap;
- align-items: center;
- margin: 15px 12px 0;
- .el-form-item {
- margin-right: 10px;
- }
- .el-radio-group {
- flex-wrap: nowrap;
- }
- }
- .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;
- &.disabled {
- pointer-events: none;
- cursor: not-allowed;
- }
- }
- .slider {
- position: relative;
- height: 100%;
- }
- .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;
- }
- .single-slider {
- margin-top: 50px;
- .label {
- font-size: 14px;
- }
- .key-point span {
- font-size: 16px;
- }
- }
- :deep(.range-slider) {
- margin-top: 53px;
- --el-slider-height: 22px;
- .el-slider__runway {
- background: none;
- .el-slider__bar {
- background: linear-gradient(
- 0deg,
- rgba(255, 212, 0, 0.2) 0%,
- rgba(255, 212, 0, 0.6) 40%,
- rgba(255, 212, 0, 0.7) 50%,
- rgba(255, 212, 0, 0.6) 60%,
- rgba(255, 212, 0, 0.2) 100%
- );
- }
- .el-slider__button-wrapper {
- top: -6px;
- // pointer-events: none;
- .el-slider__button {
- width: 14px;
- height: 14px;
- border-radius: 0;
- transform: rotateZ(45deg);
- box-shadow: 0 0 2px 3px #ffd9003e;
- background-color: #ffd700;
- border-color: #fffcf5;
- border-width: 2px;
- }
- }
- .el-slider__marks .el-slider__marks-text {
- top: -43px;
- font-size: 16px;
- color: #9daac7;
- }
- .el-slider__marks-stop {
- top: 7px;
- width: 8px;
- height: 8px;
- transform: translateX(-50%) rotateZ(45deg);
- border: 2px solid #6495ed;
- border-radius: 0;
- background: transparent;
- }
- }
- }
- </style>
- <style lang="scss">
- .range-tooltip {
- display: block !important;
- background: none !important;
- border: none !important;
- margin-top: -7px;
- visibility: hidden;
- span {
- color: #ddd;
- font-size: 16px;
- }
- .el-popper__arrow {
- display: none;
- }
- }
- </style>
|