| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- <template>
- <div class="container">
- <div class="map-container" v-if="isShow == 1">
- <div id="skysceneryContainer"></div>
- <div class="infoDialog" v-show="infoDialogShow">
- <div class="close" @click="closeWin">×</div>
- <div class="content" v-if="nowPoint != null">
- <el-scrollbar>
- <div class="item" v-for="info in nowPointInfo" :key="info">{{info.key}}: {{ info.value }}</div>
- </el-scrollbar>
- </div>
- </div>
- </div>
- <div class="page-content" v-if="isShow == 2">
- <vue-office-excel
- :src="excelUrl"
- :options="{
- xls: true,
- xlsx: true,
- }"
- @rendered="onRendered"
- @error="onError"
- />
- </div>
- <div class="page-content" v-if="isShow == 3">
- <div style="height: 100%; display: flex; align-items: center; justify-content: center;">
- <el-empty class="custom-empty" description="不支持的文件类型" />
- </div>
- </div>
- </div>
- </template>
- <script>
- import { ElMessage } from 'element-plus'
- import VueOfficeExcel from '@vue-office/excel'
- import '@vue-office/excel/lib/index.css'
- import { toRaw } from "vue";
- export default {
- name: "",
- components: {
- VueOfficeExcel
- },
- data() {
- return {
- dataJson:[],
- pointImg:require('@static/images/point.png'),
- geometryArr:[],
- mapHandle:null,
- infoDialogShow:false,
- nowPoint: null,
- nowPointInfo:null,
- excelUrl:'',
- loading:false,
- error:'',
- isShow:1,
- };
- },
- created() {
-
- },
- mounted() {
- const queryParams = new URLSearchParams(window.location.search);
- let url = queryParams.get('url');
- console.log(queryParams.get('url')); // 输出: value1
- if(url){
- let arr = url.split('.');
- let type = arr[arr.length-1];
- if(type == 'json' || type == 'geojson'){
- let param = {url:url}
- this.isShow = 1
- window.SkySceneryConfig = {};
- window.loadScripts([systemConfig.scriptMain]).then(() => {
- this.creatMap();
- setTimeout(() => {
- this.getVectorData(param);
- }, 1000)
-
- });
- }else if(type == 'xlsx' || type == 'xls'){
- this.isShow = 2
- this.excelUrl = url
- this.loadExcel();
- }else{
- this.isShow = 3
- // ElMessage.error('不支持的文件类型')
- }
- }
- },
-
- methods: {
- onRendered() {
- // ElMessage.success('Excel文件渲染完成')
- },
- loadExcel() {
- if (!this.excelUrl) {
- // this.error = '请输入Excel文件在线地址'
- return
- }
- this.loading = true
- this.error = ''
- // 加载Excel文件,实际加载由VueOfficeExcel组件处理
- setTimeout(() => {
- this.loading = false
- }, 1000)
- },
- onError(err) {
- ElMessage.error('Excel文件加载失败:', err)
- // this.error = 'Excel文件加载失败,请检查文件地址是否正确'
- this.loading = false
- },
- creatMap() {
- window.viewer = new SkyScenery.Viewer("skysceneryContainer", {
- animation: false, //是否创建动画小器件,左下角仪表
- baseLayerPicker: false, //是否显示图层选择器
- imageryProvider: new SkyScenery.SingleTileImageryProvider({
- url: (function createColorCanvas(color) {
- var width = 1,
- height = 1;
- var canvas = document.createElement("canvas");
- canvas.width = width;
- canvas.height = height;
- var ctx = canvas.getContext("2d");
- ctx.fillStyle = color;
- ctx.fillRect(0, 0, width, height);
- return canvas.toDataURL();
- })("#ffffff00"),
- rectangle: SkyScenery.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
- }),
- fullscreenButton: false, //是否显示全屏按钮
- geocoder: false, //是否显示geocoder小器件,右上角查询按钮
- homeButton: false, //是否显示Home按钮
- infoBox: false, //是否显示信息框
- sceneModePicker: false, //是否显示3D/2D选择器
- selectionIndicator: false, //是否显示选取指示器组件
- timeline: false, //是否显示时间轴
- navigationHelpButton: false, //是否显示右上角的帮助按钮
- scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
- shouldAnimate: false, //是否自动播放
- // 性能优化配置
- requestRenderMode: true,
- maximumRenderTimeChange: Infinity,
- preserveDrawingBuffer: false,
- useBrowserRecommendedResolution: true,
- });
- // 添加地图服务
- viewer.imageryLayers.addImageryProvider(
- new SkyScenery.ArcGisMapServerImageryProvider({
- url:
- "https://szlszxdt.qpservice.org.cn/internal_map/?servertype=shmap_blue_web&proxyToken=" +
- SkySceneryConfig.token,
- enablePickFeatures: false, // 禁用要素拾取功能以提高性能
- })
- );
- // 定位
- viewer.camera.setView({
- destination: SkyScenery.Cartesian3.fromDegrees(121.1158994,31.15205574, 30000.0), // 设置位置
- orientation: {
- heading: SkyScenery.Math.toRadians(0.0), // 方向
- pitch: SkyScenery.Math.toRadians(-90.0), // 倾斜角度
- roll: 0,
- },
- });
-
- },
- closeWin() {
- this.infoDialogShow = false;
- this.nowPoint = null;
- this.nowPointInfo = null;
- },
- dwanMap(){
- let that = this;
- if(that.geometryArr.length>0){
- that.geometryArr.map(function (info) {
- viewer.entities.remove(info)
- })
- }
- that.geometryArr = that.dataJson.features.map(function (info) {
- if(info.geometry.type == "Point"){
- return that.addPoint(info)
- }else if(info.geometry.type == "LineString"){
- return that.addLine(info)
- }else{
- return that.addPolygon(info)
- }
-
- })
- that.pointTCHandle();
- },
- addPolygon(param){
- let arr = [];
- param.geometry.coordinates.forEach(element => {
- element.forEach(e => {
- arr.push(e[0]);
- arr.push(e[1]);
- })
- });
- return viewer.entities.add(new SkyScenery.Entity({
- name: " polygon",
- polygon: {
- hierarchy: {
- positions: SkyScenery.Cartesian3.fromDegreesArray(arr)
- },
- heightReference: SkyScenery.HeightReference.CLAMP_TO_GROUND,
- material: SkyScenery.Color.CYAN.withAlpha(0.5)
- },
- info: {
- coor: [arr[0], arr[1]],
- properties: param.properties
- },
- }));
- },
- addLine(param){
- return viewer.entities.add({
- name: "line",
- polyline: {
- //经纬度数组转世界坐标,带高度的话是fromDegreesArrayHeights
- positions: SkyScenery.Cartesian3.fromDegreesArray(param.geometry.coordinates),
- width: 2,
- material: SkyScenery.Color.CYAN,
- info: {
- properties: param.properties
- },
- }
- });
- },
- addPoint(param){
- let that = this;
- return viewer.entities.add(new SkyScenery.Entity({
- name:"point",
- position: SkyScenery.Cartesian3.fromDegrees(param.geometry.coordinates[0], param.geometry.coordinates[1]),
- type: "point",
- info: {
- coor: [param.geometry.coordinates[0], param.geometry.coordinates[1]],
- properties: param.properties
- },
- billboard: {
- image: that.pointImg,
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
- scale: 0.3,
- horizontalOrigin: SkyScenery.HorizontalOrigin.CENTER,
- verticalOrigin: SkyScenery.VerticalOrigin.BOTTOM,
- }
- }));
- },
- // 点击事件绑定
- pointTCHandle() {
- let that = this;
- if (!this.mapHandle) {
- this.mapHandle = new SkyScenery.ScreenSpaceEventHandler(viewer.canvas, this);
- this.mapHandle.setInputAction(function (movement) {
- that.infoDialogShow = false
- const pickedObject = viewer.scene.pick(movement.position);
- let cartesian = viewer.camera.pickEllipsoid(
- movement.position,
- viewer.scene.globe.ellipsoid
- );
- // 空间坐标转世界坐标(弧度)
- let cartographic = SkyScenery.Cartographic.fromCartesian(cartesian);
- // 弧度转为角度(经纬度)
- let lon = SkyScenery.Math.toDegrees(cartographic.longitude); // 经度值
- let lat = SkyScenery.Math.toDegrees(cartographic.latitude); // 纬度值
- let center = [lon,lat]
- if (SkyScenery.defined(pickedObject) && SkyScenery.defined(pickedObject.id)) {
- const entity = pickedObject.id;
- that.infoDialogShow = true
- that.nowPoint = entity.info;
- that.nowPointInfo = Object.keys(that.nowPoint.properties).map(key => ({ key, value: that.nowPoint.properties[key] }));
- that.nowPoint["type"] = "info";
- // let xy = that.lonlatConvertToScreenXY(entity.info.coor)
- let xy = that.lonlatConvertToScreenXY(center)
- document.querySelector(".infoDialog").style.top = (xy.y - 230) + "px";
- document.querySelector(".infoDialog").style.left = (xy.x - 100) + "px";
- } else {
- // console.log('未拾取到实体');
- }
- }, SkyScenery.ScreenSpaceEventType.LEFT_CLICK);
- viewer.scene.postRender.addEventListener(that.updatePosition, this);
- } else {
- toRaw(this.mapHandle).destroy();
- this.mapHandle = null
- that.nowPointInfo = null
- viewer.scene.postRender.removeEventListener(that.updatePosition, this);
- }
- },
- // 经纬度转屏幕坐标
- lonlatConvertToScreenXY(lonlat) {
- // 定义经纬度
- var longitude = SkyScenery.Math.toRadians(lonlat[0]); // 例如:东经116.391度
- var latitude = SkyScenery.Math.toRadians(lonlat[1]); // 例如:北纬39.907度
- var height = 0; // 高度,通常在地表为0
- // 将经纬度转换为笛卡尔坐标
- // var cartographic = SkyScenery.Cartographic.fromDegrees(longitude, latitude, height);
- var cartesian = SkyScenery.Cartesian3.fromRadians(longitude, latitude, height, viewer.scene.globe.ellipsoid);
- // 将笛卡尔坐标转换为窗口坐标
- var canvasCoordinates = viewer.scene.cartesianToCanvasCoordinates(cartesian);
- return canvasCoordinates
- },
- // 位置更新
- updatePosition() {
- try {
- if (this.nowPoint != null) {
- const obj = toRaw(this.nowPoint);
- let xy = this.lonlatConvertToScreenXY(obj.coor)
- if (!xy) {
- document.querySelector(".infoDialog").style.top = "-9999px";
- document.querySelector(".infoDialog").style.left = "-9999px";
- } else {
- document.querySelector(".infoDialog").style.top = (xy.y - 230) + "px";
- document.querySelector(".infoDialog").style.left = (xy.x - 100) + "px";
- }
- }
- } catch (error) {
- // debugger
- }
- },
-
- getVectorData(param){
- let that = this;
- fetch(param.url, {
- method: 'GET',
- }).then(response => response.json()) // 假设服务器返回 JSON 数据
- .then(data => {
- console.log('[ eee ] >')
- that.dataJson = data;
- that.closeWin()
- that.dwanMap()
- })
- },
- },
- beforeDestroy() {
- viewer = undefined
- }
- };
- </script>
- <style lang="less" scoped>
- .container {
- width: 100%;
- height: 100%;
- padding: 0px;
- margin: 0 auto;
- overflow: hidden;
- }
- .map-container {
- width: 100%;
- height: 100%;
- }
- .page-content {
- width: 100%;
- height: 100%;
- background-color: #fff;
- border-radius: 4px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- overflow: hidden;
- }
- .infoDialog {
- position: absolute;
- top: 0px;
- left: 0px;
- max-width: 500px;
- height: 200px;
- // background: #01346f99;
- background: #ffffff;
- border-radius: 10px;
- .close {
- font-size: 24px;
- position: absolute;
- top: 6px;
- right: 8px;
- line-height: 24px;
- width: 24px;
- height: 24px;
- cursor: pointer;
- // color: #ffffff;
- color: #000000;
- }
- .content {
- height: 160px;
- // color: #ffffff;
- color: #000000;
- margin: 30px 0px 10px 20px;
- overflow: auto;
- .item {
- line-height: 30px;
- margin-right: 20px;
- }
- }
- }
- </style>
|