123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646 |
- <template>
- <el-tabs class="multi_level_query_table" v-model="activeName" @tab-click="handleClick" @tab-remove="removeTab"
- v-if="store.state.query_pick_last_pane">
- <el-tab-pane :label="store.state.query_pick_last_pane.name" name="second">
- <div class="list_vector_multi" v-for="(item_last, index) in store.state.query_pick_last_pane.value" :key="index"
- v-if="item_last.filed != 'geom'">
- <span>{{ item_last.filedZH }}:
- {{ item_last.filedZH == '面积' ? item_last.data.toFixed(2) : item_last.data }}</span>
- </div>
- </el-tab-pane>
- <el-tab-pane :closable="item.close" :label="item.name" :name="item.name"
- v-for="(item, index) in store.state.query_pick_pane" :key="index">
- <pie class="echart" :class="item.name == '权属' ? 'echart1' : ''" unit="亩"
- @echartClick="(name) => echartClick(name, item.value)" :ref="`echartRef`"></pie>
- <div>{{ eclickname }}</div>
- <el-collapse v-for="(value, index_item) in echartList[eclickname]" :key="index_item" @change="handleChange">
- <el-collapse-item :title="'地块' + (index_item + 1)" name="1">
- <div class="list_vector_multi" v-for="(value_field, index_field) in value" :key="index_field"
- @click="go(value)" v-if="value_field.filed != 'geom'">
- <div class="filed_box">
- {{ value_field.filedZH }}
- </div>
- :
- <div class="filed_box">
- {{ value_field.filedZH == '面积' ? value_field.data.toFixed(2) : value_field.data }}
- </div>
- </div>
- </el-collapse-item>
- </el-collapse>
- </el-tab-pane>
- <el-tab-pane label="自定义" name="自定义">自定义</el-tab-pane>
- </el-tabs>
- </template>
- <script>
- //这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
- import { GetTableData } from '@/api/cockpitNew'
- import * as wellknown from "wellknown";
- import * as turf from "@turf/turf";
- import pie from "@/components/echartsTemplate/pie.vue";
- let manager_multi_level_query = null;
- let pick_entity = null;
- let manager_multi_level_vector = null;
- let query_click_by_iserver = null;
- export default {
- components: { pie },
- data() {
- return {
- activeName: 'second',
- handler_multi_level_query: null,
- manager_multi_level_query: null,
- manager_multi_level_vector: null,
- pick_entity: null,
- pick_entity_geo: null,
- eclickname: '',
- echartList: {}
- };
- },
- //监听属性 类似于data概念
- computed: {},
- //监控data中的数据变化
- watch: {},
- //方法集合
- methods: {
- removeTab(targetName) {
- let tabs = store.state.query_pick_pane;
- let activeName = this.activeName;
- if (activeName === targetName) {
- tabs.forEach((tab, index) => {
- if (tab.name === targetName) {
- let nextTab = tabs[index + 1] || tabs[index - 1];
- if (nextTab) {
- activeName = nextTab.name;
- }
- }
- });
- }
- this.activeName = activeName;
- store.state.query_pick_pane = tabs.filter(tab => tab.name !== targetName);
- },
- compute(mj) {
- return mj ? (mj * 0.0015).toFixed(2) : 0;
- },
- setEchart(data, type, index) {
- this.$nextTick(() => {
- let max = index == 0 ? 3 : 10
- let legend_right = index == 0 ? "2%" : "10%"
- this.$refs.echartRef[index].setOptions({ data, type, max, legend_right });
- });
- },
- echartClick(name, datas) {
- this.eclickname = name
- // let click = datas.filter((c) => c.name == name);
- // if (click.length > 0) this.gogeojson(click[0].geom );
- },
- switch_show(flag) {
- pick_entity.entities.values.forEach((res) => {
- res.show = flag;
- })
- },
- go(e) {
- const that = this;
- e.forEach(element => {
- if (element.filed == "geom") {
- this.gogeojson(element.data)
- }
- });
- },
- gogeojson(data) {
- let geojson = wellknown.parse(data);
- const twoDArray = geojson.coordinates[0];
- const oneDArray = twoDArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
- this.pick_entity_geo = oneDArray;
- pick_entity.entities.add({
- polygon: {
- // 获取指定属性(positions,holes(图形内需要挖空的区域))
- hierarchy: {
- positions: Cesium.Cartesian3.fromDegreesArray(oneDArray),
- },
- // 边框
- outline: true,
- // 边框颜色
- outlineColor: Cesium.Color.RED,
- // 边框尺寸
- outlineWidth: 2,
- // 填充的颜色,withAlpha透明度
- material: Cesium.Color.GREEN.withAlpha(0),
- // 是否被提供的材质填充
- fill: true,
- // 恒定高度
- height: 1.1,
- // 显示在距相机的距离处的属性,多少区间内是可以显示的
- // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(1000, 10000000),
- // 是否显示
- show: true,
- // 顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
- zIndex: 10
- }
- });
- let flag = true;
- let time = setInterval(() => {
- flag = !flag
- this.switch_show(flag);
- }, 500);
- setTimeout(() => {
- clearInterval(time);
- pick_entity.entities.values.forEach((res) => {
- pick_entity.entities.remove(res);
- })
- }, 6000)
- // 注意:polygon首尾坐标要一致
- var polygon = turf.polygon([geojson.coordinates[0]]);
- var centroid = turf.centroid(polygon).geometry.coordinates;
- viewer.camera.flyTo({
- duration: 1,
- destination: Cesium.Cartesian3.fromDegrees(centroid[0], centroid[1], 3000),
- // destination: {
- // x: -6283267.004204832,
- // y: 28123682.896774407,
- // z: 23709669.98539126
- // },
- orientation: {
- heading: 6.149339593573709,
- pitch: -1.539825618847483,
- roll: 0
- },
- });
- },
- handleChange(val) {
- // console.log(val);
- },
- handleClick(tab, event) {
- this.eclickname = ''
- // console.log(tab, event);
- },
- init_handler() {
- const that = this;
- that.clear_data();
- if (that.handler_multi_level_query == null) {
- that.handler_multi_level_query = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
- }
- that.handler_multi_level_query.setInputAction(async event => {
- let pickObj = viewer.scene.pick(event.position);
- var position = viewer.scene.pickPosition(event.position);
- if (!position)//点击到地球之外
- return false;
- var cartographic = Cesium.Cartographic.fromCartesian(position);
- let longitude = Cesium.Math.toDegrees(cartographic.longitude);
- let latitude = Cesium.Math.toDegrees(cartographic.latitude);
- let height = cartographic.height;
- let heading = viewer.scene.camera.heading;
- let pitch = viewer.scene.camera.pitch;
- // that.addSceneFun()
- if (!position) {
- position = Cesium.Cartesian3.fromDegrees(0, 0, 0);
- }
- manager_multi_level_query.entities.add({
- name: "manager_multi_level_query",
- position: Cesium.Cartesian3.fromDegrees(longitude, latitude, 40),
- billboard: {
- // 图像地址,URI或Canvas的属性
- image: "./static/images/overview/go.png",
- height: 34,
- width: 36,
- scale: 1.0,
- zIndex: 2,
- show: true
- },
- })
- const geojsonPoint = {
- "type": "Point",
- "coordinates": [longitude, latitude] // 注意经纬度顺序
- };
- const wkt = wellknown.stringify(geojsonPoint);
- // let id = store.state.vectorlayerlist[store.state.vectorlayerlist.length - 1].id
- let obj = {
- // "wkt": 'POINT (109.51207847188947 18.311530254307392)', //单面
- "wkt": 'POINT (109.50728022974468 18.318266593715794)', //多面
- // "wkt": wkt,
- "id": 'dd699f839bc04969ae2dc2e1964d0ad1',
- // "id": id,
- }
- GetTableData(obj).then(res => {
- if (res.data.data != undefined) {
- store.state.query_pick_last_pane = {
- name: res.data.dataname,
- value: res.data.data[0],
- close: 'closable'
- };
- }
- if (res.data.child != undefined) {
- store.state.query_pick_pane = [];
- let index = -1;
- res.data.child.forEach(element => {
- if (element.data.length > 1) {
- index++;
- let edata = []
- store.state.query_pick_pane.push({
- name: element.dataname,
- value: [],// element.data
- close: 'closable'
- });
- element.data.forEach(e => {
- e.forEach((res) => {
- if (res.filed == 'geom') {
- let geojson = wellknown.parse(res.data);
- // that.draw_vector(geojson, e,); 暂时不绘制面
- }
- })
- });
- // if(element.dataname == '土地现状'){
- const countByName = element.data.reduce((acc, e) => {
- let name, value = ''
- e.forEach((res) => {
- if (res.filed == 'dlmc' || res.filed == 'qslx') name = res.data
- if (res.filed == 'siweiarea') value = res.data
- })
- acc[name] = (acc[name] || 0) + value;
- if (element.dataname == '权属') {
- if (!this.echartList[name]) this.echartList[name] = []
- this.echartList[name].push(e)
- }
- return acc;
- }, {});
- Object.keys(countByName).forEach((key) => {
- edata.push({ name: key, value: this.compute(countByName[key]) })
- });
- edata.sort((a, b) => b.value - a.value);
- // }
- this.setEchart(edata, 'vertical', index)
- // store.state.query_pick_pane.push({
- // name: element.dataname,
- // value: element.data,
- // });
- // that.draw_vector(e);
- }
- });
- }
- })
- this.highlightResults(longitude, latitude);
- that.handler_multi_level_query.destroy();
- that.handler_multi_level_query = null;
- }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- },
- async highlightResults(longitude, latitude) {
- // 高亮结果
- let queryByIDParameters = {
- getFeatureMode: "BUFFER",
- // getFeatureMode: "SPATIAL",
- spatialQueryMode: "INTERSECT",
- datasetNames: store.state.vectorlayerlist[store.state.vectorlayerlist.length - 1].source.split(","),
- geometry: {
- parts: [1],
- points: [{ y: latitude, x: longitude }],
- type: "POINT",
- },
- bufferDistance: 0.00005,
- hasGeometry: true,
- };
- let response = await axios.post(this.calcIserverURI(store.state.vectorlayerlist[store.state.vectorlayerlist.length - 1].url), queryByIDParameters);
- const outputCoords = this.convertCoordinates(response.data.features[0].geometry.points);
- outputCoords.push(outputCoords[0])
- let f = { "type": "Polygon", "coordinates": [outputCoords] };
- let result = turf.buffer(f, 1 / 99999, {
- units: "kilometers",
- });
- let positions = [];
- const twoDArray = result.geometry.coordinates[0];
- const oneDArray = twoDArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
- positions = oneDArray;
- if (this.isArray2D(oneDArray)) {
- const oneDArray2 = oneDArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
- positions = oneDArray2;
- } else {
- }
- query_click_by_iserver.entities.add({
- polygon: {
- // 获取指定属性(positions,holes(图形内需要挖空的区域))
- hierarchy: {
- positions: Cesium.Cartesian3.fromDegreesArray(positions)
- },
- // 边框
- outline: false,
- // 边框颜色
- outlineColor: Cesium.Color.RED,
- // 边框尺寸
- outlineWidth: 10,
- // 填充的颜色,withAlpha透明度
- material: Cesium.Color.RED,
- // 是否被提供的材质填充
- fill: true,
- // 恒定高度
- height: 1.1,
- // 显示在距相机的距离处的属性,多少区间内是可以显示的
- // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(1000, 10000000),
- // 是否显示
- show: true,
- // 顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
- zIndex: 10
- }
- });
- },
- convertCoordinates(coordArray) {
- return coordArray.map(coord => [coord.x, coord.y]);
- },
- calcIserverURI(url) {
- let uriArr = url.split("/");
- uriArr[5] = uriArr[5].replace("map-", "data-");
- uriArr[7] = "data";
- uriArr[8] = "featureResults.rjson?returnContent=true";
- return uriArr.join("/");
- },
- multiPolygonToPolygons(multiPolygon) {
- const polygons = [];
- multiPolygon.coordinates.forEach(polygonCoordinates => {
- polygons.push({
- type: 'Polygon',
- coordinates: polygonCoordinates
- });
- });
- return polygons;
- },
- clear_data() {
- const that = this;
- store.state.query_pick_last_pane = null;
- store.state.query_pick_pane = [];
- // 图标
- var entities = manager_multi_level_query.entities.values;
- for (var i = entities.length - 1; i >= 0; i--) {
- manager_multi_level_query.entities.remove(entities[i]);
- }
- // 矢量
- manager_multi_level_vector.removeAll();
- // for (let index = 0; index < manager_multi_level_vector._primitives.length; index++) {
- // const element = manager_multi_level_vector._primitives[index];
- // console.log('element: ', element);
- // viewer.scene.primitives.remove(element);
- // }
- this.remove_query_click_by_iserver();
- },
- add_viewer_for_vector(geojson, data) {
- const twoDArray = geojson.coordinates[0];
- const oneDArray = twoDArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
- let polygon = new Cesium.GeometryInstance({
- // id: JSON.stringify(obj),
- geometry: new Cesium.PolygonGeometry({
- minimum: new Cesium.Cartesian3(0, 0, 0),
- maximum: new Cesium.Cartesian3(100000, 100000, 100000),
- polygonHierarchy: new Cesium.PolygonHierarchy(
- Cesium.Cartesian3.fromDegreesArray(oneDArray)
- ),
- height: 1,
- // extrudedHeight: 10,
- })
- })
- let addPolygonGeometry = new Cesium.Primitive({
- geometryInstances: polygon,
- appearance: new Cesium.EllipsoidSurfaceAppearance({
- material: Cesium.Material.fromType('Color', {
- color: Cesium.Color.fromRandom({
- alpha: 0.8
- })
- })
- }),
- show: true,
- })
- manager_multi_level_vector.add(addPolygonGeometry)
- },
- draw_vector(geojson, data) {
- // viewer.dataSources.add(Cesium.GeoJsonDataSource.load(geojson, {
- // stroke: Cesium.Color.HOTPINK,
- // fill: Cesium.Color.PINK,
- // strokeWidth: 3,
- // markerSymbol: '?'
- // }));
- const that = this;
- if (geojson.type == 'MultiPolygon') {
- let polygons = that.multiPolygonToPolygons(geojson);
- polygons.forEach((res) => {
- that.add_viewer_for_vector(res, data);
- })
- } else {
- that.add_viewer_for_vector(geojson, data);
- }
- },
- remove_query_click_by_iserver() {
- for (var i = 0; i < 10; i++) {
- query_click_by_iserver.entities.values.forEach((res) => {
- query_click_by_iserver.entities.remove(res);
- })
- }
- },
- isArray2D(arr) {
- // 首先检查arr是否是数组
- if (!Array.isArray(arr)) {
- return false;
- }
- // 检查数组中的每个元素是否也是数组
- for (let i = 0; i < arr.length; i++) {
- if (!Array.isArray(arr[i])) {
- return false;
- }
- }
- // 如果所有元素都是数组,那么arr是二维数组
- return true;
- },
- },
- beforeCreate() { }, //生命周期 - 创建之前
- created() { }, //生命周期 - 创建完成(可以访问当前this实例)
- beforeMount() { }, //生命周期 - 挂载之前
- mounted() {
- const that = this;
- this.$nextTick(() => {
- that.handler_multi_level_query = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
- manager_multi_level_query = new Cesium.CustomDataSource("manager_multi_level_query");
- viewer.dataSources.add(manager_multi_level_query);
- manager_multi_level_vector = new Cesium.PrimitiveCollection();
- manager_multi_level_vector.destroyPrimitives = false;
- viewer.scene.primitives.add(manager_multi_level_vector);
- pick_entity = new Cesium.CustomDataSource("pick_entity");
- viewer.dataSources.add(pick_entity);
- query_click_by_iserver = new Cesium.CustomDataSource("query_click_by_iserver");
- viewer.dataSources.add(query_click_by_iserver);
- })
- }, //生命周期 - 挂在完成
- beforeUpdate() { }, //生命周期 - 更新之前
- updated() { }, //生命周期 - 更新之后
- beforeDestroy() { }, //生命周期 - 销毁之前
- destroy() { },//生命周期 - 销毁完成
- activated() { }, //若组件实例是 <KeepAlive> 缓存树的一部分,当组件被插入到 DOM 中时调用。
- deactivated() { } //若组件实例是 <KeepAlive> 缓存树的一部分,当组件从 DOM 中被移除时调用。
- };
- </script>
- <style lang="scss">
- .el-collapse {
- // width: 95%;
- border: none;
- background-color: transparent !important;
- }
- .el-scrollbar {
- border: 1px solid #0f7ac8 !important;
- // padding: 0 10px;
- }
- .el-collapse-item__header {
- // border-bottom: 1px solid rgba(102, 126, 143, 0.747);
- background-color: transparent !important;
- color: rgb(217, 237, 254) !important;
- border-color: transparent !important;
- }
- .el-collapse-item__wrap {
- background-color: transparent !important;
- border-color: transparent !important;
- }
- .el-collapse-item__content {
- // background-color: rgba(255, 192, 203, 0.425) !important;
- background-color: transparent !important;
- color: rgb(217, 237, 254) !important;
- }
- </style>
- <style lang="scss" scoped>
- .echart {
- width: 300px;
- height: 420px;
- }
- .echart1 {
- height: 280px;
- }
- .multi_level_query_table {
- position: absolute;
- top: 7rem;
- width: 19rem;
- }
- /* 去掉tabs标签栏下的下划线 */
- ::v-deep .el-tabs__nav-wrap::after {
- position: static !important;
- /* background-color: #fff; */
- }
- /* 下划线切换高亮 */
- ::v-deep .el-tabs__active-bar {
- background-color: #30fdff;
- }
- ::v-deep .el-collapse-item__header {
- color: #64daff !important;
- font-weight: 600;
- }
- .el-tab-pane {
- height: 33rem;
- overflow: auto;
- }
- .list_vector_multi {
- background-image: url("/static/images/ghzc/内容框.png");
- width: 18rem;
- border-top: 1px solid #CCC;
- font-size: 14px;
- padding: 0.1rem 0rem 0.1rem 0rem;
- border-left: 1px solid #CCC;
- border-right: 1px solid #CCC;
- // border-bottom:1px solid #CCC ;
- }
- .list_vector_multi:last-child {
- border-bottom: 1px solid #CCC;
- }
- .filed_box {
- display: inline-block;
- }
- </style>
|