f0956b0cc84257b6909b43c302412ddcc5344240.svn-base 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. <template>
  2. <div style="position: relative; display: flex">
  3. <a-button size="large" @click="handleSplit" v-if="!model" v-show="false" class="splitScreen">分屏</a-button>
  4. <div id="map" ref="map" :style="{'height':height}" class="map">
  5. <div class="mapSwitcher">
  6. <div id="vecMap" class="mapType vecMap" :class="{ active: vecActive }" @click="vecMapClick">
  7. <div class="lblImgType">地图</div>
  8. </div>
  9. <div id="imgMap" class="mapType imgMap" :class="{ active: imgActive }" @click="imgMapClick">
  10. <div class="lblImgType">影像</div>
  11. </div>
  12. </div>
  13. <toolbar ref="toolbar" :tools="tools" v-if="toolbar"></toolbar>
  14. <div class="legendPanel" v-show="legendImg">
  15. <img :src="legendImg"/>
  16. </div>
  17. <locate-by-geoinfo ref="locateByGeoinfo"></locate-by-geoinfo>
  18. </div>
  19. <div id="map2" ref="map2" :style="{'height':height}" class="map" v-if="twoMap">
  20. <div class="mapSwitcher">
  21. <div id="vecMap2" class="mapType vecMap" :class="{ active: vecActive2 }" @click="vecMapClick2">
  22. <div class="lblImgType">地图</div>
  23. </div>
  24. <div id="imgMap2" class="mapType imgMap" :class="{ active: imgActive2 }" @click="imgMapClick2">
  25. <div class="lblImgType">影像</div>
  26. </div>
  27. </div>
  28. <toolbar ref="toolbar2" :tools="['isRes']" v-if="toolbar" :splitScreen="true"></toolbar>
  29. <div class="legendPanel" v-show="legendImg">
  30. <img :src="legendImg"/>
  31. </div>
  32. <locate-by-geoinfo ref="locateByGeoinfo"></locate-by-geoinfo>
  33. </div>
  34. </div>
  35. </template>
  36. <script>
  37. import {Map, View} from "ol";
  38. import 'ol/ol.css';
  39. import {get as getProjection, Projection, addProjection} from 'ol/proj';
  40. import {defaults, ZoomToExtent, FullScreen, ScaleLine, MousePosition} from 'ol/control'
  41. import {DragPan, MouseWheelZoom, DragRotate, defaults as defaultsInteraction, DragBox} from 'ol/interaction'
  42. import {createStringXY} from 'ol/coordinate';
  43. import proj4 from 'proj4';
  44. // 加载图层
  45. import * as baseLayerFn from '@/utils/oneMap/baseLayer.js';
  46. import * as bussLayerFn from '@/utils/oneMap/bussLayer';
  47. //组件
  48. import Toolbar from '@/components/BasicMap/Tools/Toolbar.vue';
  49. import {getAction} from "../../api/manage";
  50. import LocateByGeoinfo from "./Tools/LocateByGeoinfo";
  51. import {platformModifierKeyOnly} from "ol/events/condition";
  52. export default {
  53. name: 'basicMap',
  54. components: {
  55. Toolbar,
  56. LocateByGeoinfo
  57. },
  58. created() {
  59. proj4.defs("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs");
  60. let projection2000 = new Projection({
  61. code: "EPSG:4490",
  62. worldExtent: [-180, -90, 180, 90],
  63. extent: [-180, -90, 180, 90],
  64. units: "degrees",
  65. axisOrientation: "neu"
  66. })
  67. addProjection(projection2000);
  68. if (this.list.length === 0) {
  69. this.loadList();
  70. }
  71. },
  72. data() {
  73. return {
  74. map: {},
  75. map2: {},
  76. vecActive: true,
  77. imgActive: false,
  78. vecActive2: true,
  79. imgActive2: false,
  80. list: [],
  81. list2: [],
  82. toolbarShow: false,
  83. geoinfo: '',
  84. twoMap: false
  85. };
  86. },
  87. props: {
  88. legendImg: {
  89. type: String
  90. },
  91. //标绘传出。
  92. value: {},
  93. drawType: {},
  94. queryUrl: {},
  95. layersUrl: {
  96. require: true
  97. },
  98. model: {},
  99. toolbar: {
  100. type: Boolean,
  101. default: false
  102. },
  103. tools: {
  104. type: Array,
  105. default: function () {
  106. return []
  107. }
  108. },
  109. height: {
  110. type: String,
  111. default() {
  112. let calcHeight = window.document.documentElement.clientHeight - 222;
  113. let m_height = calcHeight.toString() + 'px';
  114. return m_height;
  115. }
  116. },
  117. center: {
  118. type: Array,
  119. default: function () {
  120. return [116.689, 37.238]
  121. }
  122. },
  123. extent: {
  124. type: Array,
  125. default: function () {
  126. return [115.75550079345703, 36.407955169677734, 117.60053253173828, 38.01062774658203]
  127. }
  128. },
  129. projection: {
  130. type: String,
  131. default: "EPSG:4490"
  132. },
  133. zoom: {
  134. type: Number,
  135. default: 9.3
  136. }
  137. },
  138. provide() {
  139. return {
  140. baseMap: this,
  141. }
  142. },
  143. watch: {
  144. geoinfo: function () {
  145. this.$emit('input', this.geoinfo)
  146. }
  147. },
  148. methods: {
  149. handleSplit() {
  150. this.twoMap = !this.twoMap;
  151. setTimeout(() => {
  152. undefined
  153. this.map.updateSize();
  154. this.map2.updateSize();
  155. }, 100);
  156. },
  157. async loadList() {
  158. let {result, success, message} = await getAction(this.layersUrl);
  159. if (success) {
  160. this.list = result;
  161. this.ininMap();
  162. } else {
  163. this.$message.error(message);
  164. }
  165. },
  166. ininMap() {
  167. /*const zoomExtent = new ZoomToExtent({
  168. extent: this.extent
  169. });
  170. let mousePositionControl = new MousePosition({
  171. coordinateFormat: createStringXY(6),
  172. projection: 'EPSG:4490',
  173. // target: this.$refs.mousePosition,
  174. });*/
  175. let view = new View({
  176. projection: this.projection,
  177. center: this.center,
  178. zoom: this.zoom,
  179. maxZoom: 18
  180. })
  181. this.map = new Map({
  182. target: "map",
  183. view: view,
  184. controls: defaults().extend([new ScaleLine(), new ZoomToExtent({extent: this.extent}), new MousePosition({coordinateFormat: createStringXY(6)}), new FullScreen()]),
  185. interactions: defaultsInteraction().extend([
  186. new DragPan(),
  187. new MouseWheelZoom()
  188. ])
  189. });
  190. // 加载图层
  191. baseLayerFn.loadBaseLayer(this.map);
  192. this.getTreeExpandKeys(this.list, this.map);
  193. /*this.map2 = new Map({
  194. target: "map2",
  195. view: view,
  196. controls: defaults().extend([new ScaleLine(), new ZoomToExtent({extent: this.extent}), new MousePosition({coordinateFormat: createStringXY(6)}), new FullScreen()]),
  197. interactions: defaultsInteraction().extend([
  198. new DragPan(),
  199. new MouseWheelZoom()
  200. ])
  201. });
  202. // 加载图层
  203. baseLayerFn.loadBaseLayer(this.map2);
  204. this.getTreeExpandKeys(this.list, this.map2);
  205. this.list2=this.list.slice(0);*/
  206. if (this.toolbar) {
  207. this.$refs.toolbar.initPopup();
  208. }
  209. if (this.model) {
  210. this.$refs.locateByGeoinfo.locate(this.model, this.map);
  211. }
  212. let myThis = this;
  213. window.onresize = () => {
  214. myThis.mapResize();
  215. }
  216. },
  217. locateByCoords(model) {
  218. this.$refs.locateByGeoinfo.locate(model, this.map);
  219. },
  220. // 递归查找
  221. getTreeExpandKeys(obj, map) {
  222. // obj是传入的array
  223. if (obj && obj.length !== 0) {
  224. obj.forEach((item, index) => {
  225. if (item.visible) {
  226. bussLayerFn.loadBussLayer(map, item.url, item.name, item.alias, item.sourceName,
  227. item.zIndex,
  228. item.visible);
  229. // console.log(item);
  230. }
  231. // 如果此列表有children, 进行递归
  232. if (item.layers) {
  233. // console.log(index)
  234. this.getTreeExpandKeys(item.layers, map)
  235. }
  236. })
  237. }
  238. },
  239. vecMapClick() {
  240. baseLayerFn.vecMapClick(this.map.getTarget());
  241. this.vecActive = true;
  242. this.imgActive = false;
  243. },
  244. imgMapClick() {
  245. baseLayerFn.imgMapClick(this.map.getTarget());
  246. this.vecActive = false;
  247. this.imgActive = true;
  248. },
  249. vecMapClick2() {
  250. baseLayerFn.vecMapClick(this.map2.getTarget());
  251. this.vecActive2 = true;
  252. this.imgActive2 = false;
  253. },
  254. imgMapClick2() {
  255. baseLayerFn.imgMapClick(this.map2.getTarget());
  256. this.vecActive2 = false;
  257. this.imgActive2 = true;
  258. },
  259. mapResize() {
  260. this.map.updateSize();
  261. }
  262. }
  263. };
  264. </script>
  265. <style>
  266. .toolBar .ant-card {
  267. cursor: auto;
  268. }
  269. .toolBar .ant-card .ant-card-bordered {
  270. border: 0.1px solid #e8e8e8;
  271. }
  272. .toolBar .ant-card .ant-card-head {
  273. background-color: rgba(24, 129, 253, 0.8);
  274. color: #FFFFFF;
  275. cursor: move;
  276. }
  277. .toolBar .ant-card .ant-card-head-title, .ant-card .ant-card-extra {
  278. padding: 12px 0;
  279. }
  280. .toolBar .ant-card-head .ant-card-head-wrapper {
  281. align-items: unset;
  282. }
  283. .toolBar .resCatalog .ant-card-body {
  284. padding: 0;
  285. }
  286. .toolBar .resCatalog .ant-collapse > .ant-collapse-item-active > .ant-collapse-header {
  287. color: #0c8fcf;
  288. }
  289. .resCatalog .ant-collapse .ant-collapse > .ant-collapse-item > .ant-collapse-header {
  290. margin-left: 15px;
  291. }
  292. .resCatalog .ant-collapse-content > .ant-collapse-content-box {
  293. padding: 0px;
  294. }
  295. .popup {
  296. opacity: 0.95;
  297. color: #000;
  298. font-weight: bold !important;
  299. transform: translate(-50%, -99%);
  300. }
  301. .popup .ant-descriptions-bordered .ant-descriptions-row {
  302. border-bottom: 1px solid #e8e8e8;
  303. /* width: 220px; */
  304. display: flex;
  305. align-items: center;
  306. }
  307. .popup .ant-descriptions-bordered .ant-descriptions-item-label,
  308. .popup .ant-descriptions-bordered .ant-descriptions-item-content {
  309. padding: 6px 6px;
  310. border-right: 1px solid #e8e8e8;
  311. display: inline-block;
  312. /* font-size: 13px; */
  313. }
  314. .popup .ant-descriptions-row > th,
  315. .popup .ant-descriptions-row > td {
  316. padding-bottom: 0px;
  317. }
  318. .popup .ant-descriptions-bordered .ant-descriptions-item-label {
  319. color: rgb(24, 129, 253);
  320. width: 33%;
  321. text-align: end;
  322. flex-shrink: 0
  323. }
  324. .popup .ant-descriptions-bordered .ant-descriptions-item-label,
  325. .popup .ant-descriptions-bordered .ant-descriptions-item-content {
  326. padding: 6px 6px;
  327. }
  328. .popup .ant-descriptions-bordered td.ant-descriptions-item-content {
  329. width: 100%;
  330. }
  331. .popup .ant-popover-inner-content {
  332. /* padding-top: 0; */
  333. }
  334. .splitScreen {
  335. position: absolute;
  336. top: 0.8em;
  337. left: 50%;
  338. transform: translateX(-50%);
  339. margin: 0;
  340. z-index: 2;
  341. box-shadow: 0 0 5px #357ee5;
  342. opacity: 0.9;
  343. }
  344. .ol-mouse-position {
  345. /* margin-left: -50%; */
  346. top: auto;
  347. right: auto;
  348. bottom: 1em;
  349. left: 50%;
  350. transform: translateX(-50%);
  351. position: absolute;
  352. color: rgba(24, 129, 253, 0.8);
  353. font-weight: bold;
  354. min-width: 180px;
  355. height: 24px;
  356. line-height: 24px;
  357. text-align: center;
  358. vertical-align: middle;
  359. z-index: 1;
  360. font-size: 1em;
  361. }
  362. .ol-rotate {
  363. top: 2.5em;
  364. }
  365. .map {
  366. width: 100%;
  367. height: 500px;
  368. position: relative;
  369. }
  370. .res-list {
  371. width: 200px;
  372. position: absolute;
  373. top: 100px;
  374. left: 500px;
  375. }
  376. .mapSwitcher {
  377. border-radius: 3px;
  378. width: 164px;
  379. height: 84px;
  380. position: absolute;
  381. bottom: 0.5em;
  382. right: 0.5em;
  383. background-color: #ffffff;
  384. box-shadow: 0 0 5px #357ee5;
  385. z-index: 2;
  386. padding: 2px;
  387. margin: 0;
  388. }
  389. .mapType {
  390. border: 2px solid #fff;
  391. top: 4px;
  392. cursor: pointer;
  393. position: absolute;
  394. width: 76px;
  395. height: 76px;
  396. }
  397. .mapType.active {
  398. border: 2px solid #409eff;
  399. }
  400. .vecMap {
  401. background-image: url("../../assets/maptype.jpg");
  402. background-position: 0 0;
  403. right: 4px;
  404. }
  405. .imgMap {
  406. background-image: url("../../assets/maptype.jpg");
  407. background-position: 0 -228px;
  408. left: 4px;
  409. }
  410. .lblImgType {
  411. position: absolute;
  412. right: 1px;
  413. bottom: 1px;
  414. width: 35px;
  415. height: 20px;
  416. line-height: 20px;
  417. font-size: 14px;
  418. background-color: rgba(0, 121, 210, .5);
  419. color: #fff;
  420. text-align: center;
  421. }
  422. .mousePosition {
  423. position: absolute;
  424. min-width: 180px;
  425. height: 24px;
  426. line-height: 24px;
  427. bottom: 1em;
  428. left: calc(50% - 85px);
  429. text-align: center;
  430. vertical-align: middle;
  431. z-index: 1;
  432. font-weight: bold;
  433. color: rgba(24, 129, 253, 0.8);
  434. font-size: 1em;
  435. }
  436. .ol-control button {
  437. background-color: rgba(24, 129, 253, 0.6);
  438. }
  439. .ol-control button:focus,
  440. .ol-control button:hover {
  441. text-decoration: none;
  442. background-color: rgba(24, 129, 253, .8)
  443. }
  444. .ol-scale-line {
  445. background-color: rgba(24, 129, 253, 0.6);
  446. }
  447. .legendPanel {
  448. display: block;
  449. position: absolute;
  450. left: 0.5em;
  451. bottom: 3em;
  452. z-index: 1;
  453. }
  454. </style>