Newer
Older
KaiFengPC / src / views / floodSys / floodVideo / gisMapVideo.vue
@zhangdeliang zhangdeliang on 23 May 9 KB 初始化项目
  1. <template>
  2. <!-- GIS地图 -->
  3. <div class="videoMapGis">
  4. <!-- <gisMap></gisMap> -->
  5. <MapBox :initJson="`/static/libs/mapbox/style/floodOneMap.json`"></MapBox>
  6. </div>
  7. </template>
  8.  
  9. <script setup name="page">
  10. // import gisMap from '../../gisMapPage/gisMapCommonPage.vue';
  11. import { pagecameraResource } from '@/api/cameraResource/cameraResource';
  12. import SPIcon from '@/assets/newImgs/layerIcon/SP2.png';
  13. import { nextTick } from 'vue';
  14. import { getImageUrl } from '@/utils/ruoyi';
  15. import MapBox from '@/views/gisMapPage/gisMapBox1'; //gis地图
  16. import bus from '@/bus';
  17.  
  18. const { proxy } = getCurrentInstance();
  19. const allData = reactive({
  20. videoGeojson: {},
  21. });
  22. function getList() {
  23. let queryParams = {
  24. pageNum: 1,
  25. pageSize: 999,
  26. };
  27. pagecameraResource(queryParams).then(response => {
  28. let videoData = response.data;
  29. console.log(videoData);
  30. allData.videoGeojson = getVideoGeojson(videoData);
  31. console.log(allData.videoGeojson);
  32. //initCluster(newfiberMap.getMap(), allData.videoGeojson, 'videoMonitor', SPIcon);
  33. // addGeoJsonPoint(allData.videoGeojson, 'videoMonitor', SPIcon);
  34. setTimeout(() => {
  35. bus.emit('setGeoJSON', { json: allData.videoGeojson, key: 'video' });
  36. bus.emit('setLayerVisible', { layername: 'video', isCheck: true });
  37. }, 2000);
  38. });
  39. }
  40. function getVideoGeojson(list) {
  41. return {
  42. type: 'FeatureCollection',
  43. features: list.map(item => {
  44. let geometry = {
  45. type: 'Point',
  46. coordinates: [Number(item.x), Number(item.y)],
  47. };
  48. return { type: 'Feature', geometry, properties: item };
  49. }),
  50. };
  51. }
  52. //添加点状图层
  53. function addGeoJsonPoint(geojson, type, icon) {
  54. console.log('geojsongeojson', geojson);
  55.  
  56. // geojson.features.forEach(feature => {
  57. // let name =
  58. // feature.properties.name ||
  59. // feature.properties.dickName ||
  60. // feature.properties.architectureName ||
  61. // feature.properties.dikeName ||
  62. // feature.properties.warehouseName ||
  63. // feature.properties.siteName;
  64. // feature.properties = Object.assign(feature.properties, {
  65. // style_: {
  66. // id: type,
  67. // name,
  68. // type: NewFiberMap.Enum.VectorType.ICON,
  69. // options: {
  70. // show: true,
  71. // name:
  72. // feature.properties.name ||
  73. // feature.properties.dickName ||
  74. // feature.properties.architectureName ||
  75. // feature.properties.dikeName ||
  76. // feature.properties.warehouseName ||
  77. // feature.properties.siteName,
  78. // id: type,
  79. // url: icon, //styleSet.iconUrl,
  80. // width: 45, //styleSet.width || 75,
  81. // height: 79, //styleSet.height || 45,
  82. // pixelOffset: [0, 0],
  83. // distanceDisplayCondition: [Number.MIN_VALUE, 700000],
  84. // },
  85. // labelOptions: {
  86. // font: '15px PingFang SC',
  87. // color: 'rgba(255, 255, 255,1)',
  88. // pixelOffset: [0, -20],
  89. // backgroundColor: 'rgba(0,0,0,0.7)',
  90. // showBackground: false,
  91. // distanceDisplayCondition: [Number.MIN_VALUE, 7000000],
  92. // },
  93. // },
  94. // });
  95. // });
  96. // if (newfiberMap.getLayers([type]).length > 0) {
  97. // return;
  98. // } else {
  99. // newfiberMap.geojsonToMap(geojson);
  100. // }
  101. }
  102. function initCluster(viewer, geojson, layerid, imgurl) {
  103. let dataSource = newfiberMap.getLayers([layerid])[0];
  104. if (!!!dataSource) {
  105. new Cesium.GeoJsonDataSource().load(geojson).then(dataSource => {
  106. dataSource.id = layerid;
  107. viewer.dataSources.add(dataSource);
  108. dataSource.clustering.enabled = true;
  109. dataSource.clustering.pixelRange = 10;
  110. dataSource.clustering.minimumClusterSize = 3;
  111. //根据层级判断是否聚合
  112. let getNowZoom;
  113. let handler = new Cesium.ScreenSpaceEventHandler(newfiberMap.getMap().scene.canvas);
  114. handler.setInputAction(function (movement) {
  115. getNowZoom = newfiberMap.getCameraParams().height;
  116. if (getNowZoom < 1500) {
  117. dataSource.clustering.enabled = false;
  118. } else {
  119. dataSource.clustering.enabled = true;
  120. }
  121. }, Cesium.ScreenSpaceEventType.WHEEL);
  122. // 添加监听函数
  123. dataSource.clustering.clusterEvent.addEventListener(function (clusteredEntities, cluster) {
  124. // 关闭自带的显示聚合数量的标签
  125. cluster.label.show = false;
  126. cluster.billboard.show = true;
  127. cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
  128.  
  129. // 根据聚合数量的多少设置不同层级的图片以及大小
  130. if (clusteredEntities.length >= 20) {
  131. cluster.billboard.image = combineIconAndLabel(getImageUrl('clusterIcon1.png', 'newImgs/layerIcon'), clusteredEntities.length, 68);
  132. // cluster.billboard.width = 38;
  133. // cluster.billboard.height = 38;
  134. } else if (clusteredEntities.length >= 12) {
  135. cluster.billboard.image = combineIconAndLabel(getImageUrl('clusterIcon2.png', 'newImgs/layerIcon'), clusteredEntities.length, 64);
  136. // cluster.billboard.width = 34;
  137. // cluster.billboard.height = 34;
  138. } else if (clusteredEntities.length >= 8) {
  139. cluster.billboard.image = combineIconAndLabel(getImageUrl('clusterIcon3.png', 'newImgs/layerIcon'), clusteredEntities.length, 50);
  140. // cluster.billboard.width = 30;
  141. // cluster.billboard.height = 30;
  142. } else {
  143. cluster.billboard.image = combineIconAndLabel(getImageUrl('clusterIcon4.png', 'newImgs/layerIcon'), clusteredEntities.length, 50);
  144. }
  145. });
  146. setDataSourceEntitysStyle(dataSource);
  147. });
  148. }
  149.  
  150. new Cesium.GeoJsonDataSource().load(geojson).then(e => {
  151. e.entities.values.forEach(entity => {
  152. dataSource.entities.add(entity);
  153. });
  154. setDataSourceEntitysStyle(dataSource);
  155. });
  156.  
  157. function setDataSourceEntitysStyle(dataSource) {
  158. // foreach用于调用数组的每个元素,并将元素传递给回调函数。
  159. dataSource.entities.values.forEach(entity => {
  160. let properties = entity.properties.getValue();
  161. // 将点拉伸一定高度,防止被地形压盖
  162. entity.position._value.z += 130.0;
  163. // 使用大小为64*64的icon,缩小展示poi
  164. entity.billboard = {
  165. image: imgurl,
  166. width: 45,
  167. height: 79,
  168. };
  169. entity.label = getLabelOptions({
  170. ...properties.labelOptions,
  171. name: properties.name,
  172. pixelOffset: [0, -75],
  173. });
  174. });
  175. }
  176.  
  177. function getLabelOptions(options) {
  178. return {
  179. // 文本。支持显式换行符“ \ n”
  180. text: options.name + '' || '测试名称',
  181. // 字体样式,以CSS语法指定字体
  182. font: options.font || '15px Source Han Sans CN',
  183. fillColor: Cesium.Color.fromCssColorString(!!options.color ? options.color : 'rgba(255,255,255,1)'),
  184. // 背景颜色
  185. backgroundColor: Cesium.Color.fromCssColorString(!!options.backgroundColor ? options.backgroundColor : 'rgba(0,0,0,1)'),
  186. // 是否显示背景颜色
  187. showBackground: options.showBackground || false,
  188. // 字体边框
  189. outline: options.outline || false,
  190. // 字体边框颜色
  191. outlineColor: !!options.outlineColor ? Cesium.Color.fromCssColorString(options.outlineColor) : Cesium.Color.WHITE,
  192. // 字体边框尺寸
  193. outlineWidth: options.outlineWidth || 10,
  194. // 应用于图像的统一比例。比例大于会1.0放大标签,而比例小于会1.0缩小标签。
  195. scale: options.scale || 1.0,
  196. // 设置样式:FILL:填写标签的文本,但不要勾勒轮廓;OUTLINE:概述标签的文本,但不要填写;FILL_AND_OUTLINE:填写并概述标签文本。
  197. style: options.style || Cesium.LabelStyle.FILL,
  198. // 相对于坐标的水平位置
  199. verticalOrigin: options.verticalOrigin || Cesium.VerticalOrigin.CENTER,
  200. // 相对于坐标的水平位置
  201. horizontalOrigin: options.horizontalOrigin || Cesium.HorizontalOrigin.CENTER,
  202. // 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
  203. pixelOffset: new Cesium.Cartesian2((options.pixelOffset || [])[0] || 0, (options.pixelOffset || [])[1] || 20),
  204. //1000000000 内不受地形影响 遮挡
  205. disableDepthTestDistance: options.disableDepthTestDistance || Number.POSITIVE_INFINITY,
  206. clampToGround: options.clampToGround ?? true,
  207. heightReference: options.heightReference ?? Cesium.HeightReference.CLAMP_TO_GROUND,
  208. eyeOffset: new Cesium.Cartesian3(...(options.eyeOffset || [0, 0, -10])),
  209. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
  210. ...(options.distanceDisplayCondition || [Number.MIN_VALUE, Number.POSITIVE_INFINITY])
  211. ),
  212. };
  213. }
  214. }
  215. function combineIconAndLabel(url, label, width, height) {
  216. height = height || width;
  217. // 创建画布对象
  218. let canvas = document.createElement('canvas');
  219. canvas.width = width;
  220. canvas.height = height;
  221. let ctx = canvas.getContext('2d');
  222.  
  223. let promise = new Cesium.Resource.fetchImage(url).then(image => {
  224. // 异常判断
  225. try {
  226. ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
  227. } catch (e) {
  228. console.log(e);
  229. }
  230.  
  231. // 渲染字体
  232. // font属性设置顺序:font-style, font-variant, font-weight, font-size, line-height, font-family
  233. ctx.fillStyle = Cesium.Color.WHITE.toCssColorString();
  234. ctx.font = 'bold 15px Microsoft YaHei';
  235. ctx.textAlign = 'center';
  236. ctx.textBaseline = 'middle';
  237. ctx.fillText(label, width / 2, height / 2);
  238.  
  239. return canvas;
  240. });
  241. return promise;
  242. }
  243.  
  244. onMounted(() => {
  245. getList();
  246. });
  247. </script>
  248. <style lang="scss">
  249. .videoMapGis {
  250. width: 100%;
  251. height: calc(100vh - 120px);
  252. background: rgba(0, 0, 0, 0.05);
  253. }
  254. </style>