Map.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275
  1. import OLMap from 'ol/Map'
  2. import View from 'ol/View'
  3. import * as proj from 'ol/proj'
  4. import * as interaction from 'ol/interaction'
  5. import {Draw,Modify} from 'ol/interaction'
  6. import 'ol/ol.css'
  7. import './css/KMap.css'
  8. import * as Enum from './Enum'
  9. import Common from './Common'
  10. import VectorLayer from './VectorLayer'
  11. import * as Extent from 'ol/extent'
  12. import Overlay from 'ol/Overlay'
  13. import WMTSLayer from './WMTSLayer'
  14. import XYZLayer from './XYZLayer'
  15. import config from "@/api/config.js";
  16. import {Feature} from "ol";
  17. import {GeoJSON, WKT} from 'ol/format'
  18. import { Style, Text } from 'ol/style';
  19. import { Circle, Fill, Stroke } from 'ol/style.js';
  20. import { LineString, Point } from 'ol/geom';
  21. import {getArea} from "ol/sphere"
  22. /**
  23. * @description KMap.Map 地图类
  24. */
  25. class Map {
  26. /**
  27. * @description 地图实例
  28. * @static
  29. * @memberof Map
  30. */
  31. Instance = null
  32. /**
  33. * @description 信息窗体像素对象
  34. * @memberof Map
  35. */
  36. infoWindowPixel = null
  37. /**
  38. * @description 鼠标移动事件弹窗UID
  39. * @memberof Map
  40. */
  41. InfowindowmoveUID = -1
  42. /**
  43. * @description 鼠标点击事件弹窗UID
  44. * @memberof Map
  45. */
  46. InfowindowclickUID = -1
  47. /**
  48. * @description 是否有鼠标移动弹窗
  49. * @memberof Map
  50. */
  51. ClearMouseMoveInfoWindow = false
  52. /**
  53. * @description X方向缩放
  54. * @memberof Map
  55. */
  56. scaleX = 1
  57. /**
  58. * @description Y方向缩放
  59. * @memberof Map
  60. */
  61. scaleY = 1
  62. /**
  63. * @param {string} id DOM元素ID
  64. * @param {number} zoomLevel 地图层级
  65. * @param {number} lng 纬度
  66. * @param {number} lat 经度
  67. * @description Map初始化方法
  68. * @constructor
  69. */
  70. constructor(id,zoomLevel,lng,lat,projection, minZoom,maxZoom){
  71. if(Map.Instance){
  72. Map.Instance = false;
  73. }
  74. if(projection){
  75. projection = proj.get(projection)
  76. }
  77. projection = projection || proj.get("EPSG:4326");
  78. const vm = this
  79. Map.Instance = this
  80. let lnglat = [lng,lat]
  81. if(projection.getCode() == "EPSG:3857"){
  82. lnglat = proj.fromLonLat(lnglat);
  83. }
  84. Common.checkLngLat(lng,lat)
  85. let view = new View({
  86. center: lnglat,
  87. zoom: zoomLevel,
  88. minZoom: minZoom || Common.ShowLevel[0],
  89. maxZoom: maxZoom || Common.ShowLevel[1],
  90. projection:projection
  91. })
  92. this.view = view
  93. this.map = new OLMap({
  94. interactions: interaction.defaults().extend([
  95. new interaction.DragRotateAndZoom()]),
  96. target: id,
  97. layers: [],//vm.baseLayer
  98. view: view,
  99. control: []
  100. })
  101. this.initBaseLayer(projection)
  102. //初始化业务图层
  103. this.initBusinessLayer()
  104. //初始化地图信息弹窗
  105. this.initInfoWindow()
  106. //初始化地图基础事件
  107. this.initMapBaseEvent()
  108. }
  109. /**
  110. * 初始化地图底图图层
  111. * @return {array}
  112. * @memberof Map
  113. */
  114. async initBaseLayer(projection){
  115. const img_wmts = await VE_API.system.getCfg({"k":"img_wmts_mkt","resultType":"json"});
  116. const cva_wmts = await VE_API.system.getCfg({"k":"cva_wmts_mkt","resultType":"json"});
  117. this.tdtImgLayer = new WMTSLayer(img_wmts.data, projection,this);
  118. this.cva_torLayer = new WMTSLayer(cva_wmts.data,projection,this);
  119. }
  120. addXYZLayer(url,options){
  121. let xyz = new XYZLayer(url,options,3);
  122. return xyz;
  123. }
  124. /**
  125. * @description 初始化业务图层
  126. * @memberof Map
  127. */
  128. initBusinessLayer(){
  129. const vm = this
  130. let map = vm.map
  131. //创建默认点标记图层
  132. vm.markerLayer = new VectorLayer("defaultMarkerLayer",101)
  133. //创建默认线标记图层
  134. vm.polyLineLayer = new VectorLayer("defaultPolylineLayer",101)
  135. //创建默认面图层
  136. vm.polygonLayer = new VectorLayer("defaultPolygonLayer",1000)
  137. //创建文本标记图层
  138. vm.labelLayer = new VectorLayer("defaultLabelLayer",99)
  139. map.addLayer(vm.polygonLayer.layer)
  140. map.once('postrender', function(event) {
  141. map.addLayer(vm.markerLayer.layer)
  142. map.addLayer(vm.polyLineLayer.layer)
  143. map.addLayer(vm.labelLayer.layer)
  144. map.on('click',function(evt){
  145. let coordinate = evt.coordinate;
  146. // let newPoints = proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326');
  147. // debugger;
  148. })
  149. // map.addLayer(layer)
  150. })
  151. }
  152. initDraw(callback){
  153. const vm = this
  154. this.draw = new Draw({
  155. type: 'MultiPolygon',
  156. source: this.polygonLayer.source,
  157. free: true,
  158. style: vm.drawStyleFunc
  159. })
  160. this.draw.setActive(false)
  161. this.map.addInteraction(this.draw);
  162. this.draw.on("drawend",callback)
  163. }
  164. startDraw(){
  165. this.draw.setActive(true)
  166. }
  167. endDraw(){
  168. this.draw.setActive(false)
  169. }
  170. modifyDraw(callback) {
  171. this.modify = new Modify({
  172. source: this.polygonLayer.source,
  173. pixelTolerance: 10, //设置吸附像素值
  174. })
  175. this.map.addInteraction(this.modify);
  176. this.modify.on("modifyend",callback)
  177. }
  178. drawStyleFunc(feature) {
  179. const styles = [];
  180. const type = feature.getGeometry().getType();
  181. const coord = feature.getGeometry().getCoordinates();
  182. for (let i = 0; i < coord.length - 1; i++) {
  183. if (i%2) {
  184. styles.push(
  185. new Style({
  186. geometry: new Point(coord[i]),
  187. image: new Circle({
  188. radius: 6,
  189. fill: new Fill({
  190. color: '#06F7A1'
  191. }),
  192. stroke: new Stroke({
  193. color: '#fff',
  194. width: 1
  195. })
  196. })
  197. })
  198. );
  199. } else {
  200. styles.push(
  201. new Style({
  202. geometry: new Point(coord[i]),
  203. image: new Circle({
  204. radius: 6,
  205. fill: new Fill({
  206. color: '#fff'
  207. }),
  208. })
  209. })
  210. );
  211. }
  212. }
  213. if (type === 'LineString') {
  214. for (let i = 0; i < coord.length - 1; i++) {
  215. styles.push(
  216. new Style({
  217. geometry: new LineString([coord[i], coord[i + 1]]),
  218. stroke: new Stroke({
  219. color: '#06F7A1',
  220. width: 2
  221. })
  222. })
  223. );
  224. }
  225. }
  226. return styles;
  227. }
  228. polygonStyle(feature) {
  229. const styles = [];
  230. const coord = feature.getGeometry().getCoordinates()[0];
  231. for (let i = 0; i < coord[0].length - 1; i++) {
  232. if (i%2) {
  233. styles.push(
  234. new Style({
  235. geometry: new Point(coord[0][i]),
  236. image: new Circle({
  237. radius: 4,
  238. fill: new Fill({
  239. color: '#54cb82'
  240. }),
  241. stroke: new Stroke({
  242. color: '#54cb82',
  243. width: 3
  244. })
  245. })
  246. })
  247. );
  248. } else {
  249. styles.push(
  250. new Style({
  251. geometry: new Point(coord[0][i]),
  252. image: new Circle({
  253. radius: 6,
  254. fill: new Fill({
  255. color: '#fff'
  256. })
  257. })
  258. })
  259. );
  260. }
  261. }
  262. let fillStyle = new Style({
  263. fill: new Fill({
  264. color: [1, 41, 52, 0.6]
  265. }),
  266. stroke: new Stroke({
  267. color: '#54cb82',
  268. width: 2
  269. })
  270. })
  271. let geom = feature.getGeometry().clone()
  272. geom.transform(proj.get("EPSG:4326"), proj.get("EPSG:38572"))
  273. let area = getArea(geom)
  274. area = (area + area / 2) / 1000;
  275. let areaValStyle = new Style({
  276. text: new Text({
  277. font: "16px sans-serif",
  278. text: area.toFixed(2) + "亩",
  279. // offsetX: 28,
  280. // offsetY: -100,
  281. fill: new Fill({ color: "#fff" }), // 字体颜色
  282. }),
  283. })
  284. styles.push(fillStyle, areaValStyle);
  285. return styles;
  286. }
  287. getLayerFeatures() {
  288. const vm = this
  289. let features = vm.polygonLayer.source.getFeatures()
  290. return features
  291. }
  292. // 传入geojson,回显到polygon
  293. setLayerPolygon(geometry) {
  294. const vm = this
  295. vm.polygonLayer.source.addFeatures(new GeoJSON().readFeatures(geometry))
  296. }
  297. setLayerWkt(wkt,isView) {
  298. const vm = this
  299. let f = new Feature({geometry:new WKT().readGeometry(wkt)})
  300. const extent = f.getGeometry().getExtent()
  301. vm.polygonLayer.source.addFeature(f)
  302. if(isView){
  303. vm.map.getView().fit(extent, { padding: [20, 20, 20, 20] });
  304. }
  305. }
  306. addLayer(layer){
  307. const vm = this
  308. vm.map.addLayer(layer)
  309. }
  310. removeLayer(layer){
  311. const vm = this
  312. vm.map.removeLayer(layer)
  313. }
  314. /**
  315. * @description 初始化信息弹窗
  316. * @memberof Map
  317. */
  318. initInfoWindow(){
  319. const vm = this
  320. //创建地图弹窗容器
  321. let infoWindowBoxClick = document.createElement("div")
  322. let infoWindowBoxMove = document.createElement("div")
  323. let mapTarget = vm.map.getTargetElement()
  324. infoWindowBoxClick.id = "infowindow-click"
  325. infoWindowBoxMove.id = "infowindow-move"
  326. infoWindowBoxClick.style.zIndex = 999
  327. infoWindowBoxMove.style.zIndex = 999
  328. mapTarget.appendChild(infoWindowBoxClick)
  329. mapTarget.appendChild(infoWindowBoxMove)
  330. vm.infoWindow_click = new Overlay({
  331. element: infoWindowBoxClick
  332. })
  333. vm.infoWindow_move = new Overlay({
  334. element: infoWindowBoxMove
  335. })
  336. //添加点击弹窗
  337. vm.map.addOverlay(vm.infoWindow_click)
  338. //添加悬停弹窗
  339. vm.map.addOverlay(vm.infoWindow_move)
  340. }
  341. /**
  342. * @description 初始化地图基础事件
  343. * @memberof Map
  344. */
  345. initMapBaseEvent(){
  346. const vm = this
  347. var allowTriggerEvent = function(pixel) {
  348. var infoWindowPixel = vm.infoWindowPixel
  349. if(infoWindowPixel == null){
  350. return true
  351. }
  352. var x = pixel[0]
  353. var y = pixel[1]
  354. if(x>=infoWindowPixel[0] && x<=infoWindowPixel[2] &&
  355. y>=infoWindowPixel[1] && y<=infoWindowPixel[3]) {
  356. return false
  357. }
  358. return true
  359. }
  360. vm.map.on('click',function(event){
  361. event.pixel[0] = (event.pixel[0] / vm.scaleX)
  362. event.pixel[1] = (event.pixel[1] / vm.scaleY)
  363. var clickFeature = vm.map.forEachFeatureAtPixel(event.pixel, function(feature){
  364. if(!allowTriggerEvent(event.pixel)) return
  365. // 为点击到的feature发送自定义的click消息
  366. if(feature.dispatchEvent != undefined){
  367. feature.dispatchEvent({type: 'click', event: event})
  368. }
  369. return feature
  370. })
  371. //点击在地图空白处时清空弹窗
  372. if(clickFeature == undefined){
  373. vm.clearInfoWindow()
  374. }
  375. })
  376. //为地图注册鼠标点击事件的监听
  377. vm.map.on('pointermove', function(event) {
  378. event.pixel[0] = (event.pixel[0] / vm.scaleX)
  379. event.pixel[1] = (event.pixel[1] / vm.scaleY)
  380. var mousemoveFeature = vm.map.forEachFeatureAtPixel(event.pixel, function(feature){
  381. if(!allowTriggerEvent(event.pixel)){
  382. return
  383. }
  384. // 为点击到的feature发送自定义的mousemove消息
  385. if(feature.dispatchEvent != undefined){
  386. feature.dispatchEvent({type: 'mousemove', event: event})
  387. }
  388. return feature
  389. })
  390. //悬停在地图空白处时清空悬停弹窗
  391. if(mousemoveFeature == undefined)
  392. {
  393. vm.clearMouseMoveInfoWindow()
  394. }
  395. //设置鼠标悬停到覆盖物上的样式
  396. var mapContainer = vm.getTarget()
  397. if(mousemoveFeature) {
  398. mapContainer.style.cursor = "pointer"
  399. }
  400. else {
  401. mapContainer.style.cursor = "default"
  402. }
  403. })
  404. }
  405. setScale(x, y) {
  406. const vm = this
  407. // var mapContainer = vm.getTarget()
  408. // mapContainer.style.overflow = 'hidden'
  409. // var mapContent = mapContainer.getElementsByClassName('ol-viewport')[0]
  410. // var scaleX = 1 / Number(x);
  411. // var scaleY = 1 / Number(y);
  412. vm.scaleX = Number(x)
  413. vm.scaleY = Number(y)
  414. // mapContent.style.transform = "scale("+scaleX+","+scaleY+")"
  415. }
  416. /**
  417. * @description 清除鼠标点击弹窗
  418. * @memberof Map
  419. */
  420. clearInfoWindow() {
  421. const vm = this
  422. vm.infoWindow_click.setPosition(undefined)
  423. vm.infoWindow_move.setPosition(undefined)
  424. vm.infoWindowPixel = null
  425. vm.InfowindowmoveUID = -1
  426. vm.InfowindowclickUID = -1
  427. }
  428. /**
  429. * @description 清除鼠标移动弹窗
  430. * @memberof Map
  431. */
  432. clearMouseMoveInfoWindow() {
  433. const vm = this
  434. if(vm.ClearMouseMoveInfoWindow) {
  435. vm.infoWindow_move.setPosition(undefined)
  436. vm.infoWindowPixel = null
  437. vm.InfowindowmoveUID = -1
  438. }
  439. }
  440. /**
  441. * @description 获取地图容器div
  442. * @returns 地图容器div
  443. * @memberof Map
  444. */
  445. getTarget() {
  446. let target = this.map.getTargetElement()
  447. return target
  448. }
  449. /**
  450. * @description 获取地图容器尺寸
  451. * @returns KMap.Size格式的尺寸
  452. * @memberof Map
  453. */
  454. getSize() {
  455. let size = this.map.getSize()
  456. console.log(Common)
  457. size = Common.MapSize2KMapSize(size)
  458. return size
  459. }
  460. /**
  461. * @description 获取地图投影EPSG类型
  462. * @returns 地图投影类型
  463. * @memberof Map
  464. */
  465. getProjection() {
  466. let projection = this.view.getProjection()
  467. return projection
  468. }
  469. /**
  470. * @description 获取地图中心
  471. * @returns 地图中心,KMap.LngLat对象格式
  472. * @memberof Map
  473. */
  474. getCenter() {
  475. let center = this.view.getCenter()
  476. center = proj.toLonLat(center)
  477. return Common.MapLngLat2KMapLngLat(center)
  478. }
  479. /**
  480. * @description 获取地图中心
  481. * @returns 地图中心,KMap.LngLat对象格式
  482. * @memberof Map
  483. */
  484. getCenter2() {
  485. let center = this.view.getCenter()
  486. center = proj.toLonLat(center)
  487. return center
  488. }
  489. /**
  490. * @description 设置地图中心
  491. * @param {KMap.LngLat} position 地图中心位置,KMap.LngLat对象格式,必填
  492. * @memberof Map
  493. */
  494. setCenter(position) {
  495. let centerlnglat = Common.KMapLngLat2MapLngLat(position)
  496. let center = proj.fromLonLat(centerlnglat)
  497. this.view.setCenter(center)
  498. }
  499. getView(){
  500. return this.view;
  501. }
  502. /**
  503. * @description 设置地图中心
  504. * @param {KMap.LngLat} position 地图中心位置,KMap.LngLat对象格式,必填
  505. * @memberof Map
  506. */
  507. setCenter2(position) {
  508. this.view.setCenter(position)
  509. }
  510. fitToView(center,zoom,dera) {
  511. this.view.fit(center,{duration: dera})
  512. }
  513. /**
  514. * @description 地图中心点平移至指定点位置
  515. * @param {KMap.LngLat} point 指定点经纬度坐标,KMap.LngLat对象格式,必填
  516. * @param {number} zoom 缩放级别,选填参数,不填则使用当前缩放级别
  517. * @memberof Map
  518. */
  519. panTo(point,zoom) {
  520. point = Common.KMapLngLat2MapLngLat(point)
  521. let center = proj.fromLonLat(point)
  522. if(zoom) {
  523. this.view.animate({center:center},{zoom:zoom})
  524. }
  525. else {
  526. this.view.animate({center:center})
  527. }
  528. }
  529. /**
  530. * @description 地图放大一级显示
  531. * @memberof Map
  532. */
  533. zoomIn() {
  534. this.view.setZoom( this.getZoom() + 1 )
  535. return this.getZoom()
  536. }
  537. /**
  538. * @description 地图缩小一级显示
  539. * @memberof Map
  540. */
  541. zoomOut() {
  542. this.view.setZoom( this.getZoom() - 1)
  543. return this.getZoom()
  544. }
  545. /**
  546. * @description 缩放到点标记图层范围
  547. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  548. * @memberof Map
  549. */
  550. zoomToMarkerLayer(duration) {
  551. const vm = this
  552. duration = (duration != undefined)? duration : 0
  553. let markers = vm.markerLayer.getSource().getFeatures()
  554. let coordinateArray = new Array()
  555. for(let i=0; i<markers.length; i++) {
  556. coordinateArray.push(markers[i].getGeometry().getCoordinates())
  557. }
  558. let extentBound = new Extent.boundingExtent(coordinateArray)
  559. this.view.fit(extentBound,{
  560. duration: duration
  561. })
  562. this.view.fit(vm.markerLayer.getSource().getExtent(),{
  563. duration: duration
  564. })
  565. }
  566. /**
  567. * @description 缩放到点标记集合范围
  568. * @param {Array} markerArray 点标记集合,必填
  569. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  570. * @memberof Map
  571. */
  572. zoomToMarkerArray(markerArray,duration) {
  573. duration = (duration != undefined)? duration : 0
  574. let coordinateArray = new Array()
  575. for(let i=0; i<markerArray.length; i++) {
  576. coordinateArray.push(markerArray[i].Marker.getGeometry().getCoordinates())
  577. }
  578. let extentBound = new Extent.boundingExtent(coordinateArray)
  579. this.view.fit(extentBound,{
  580. duration: duration
  581. })
  582. }
  583. /**
  584. * @description 缩放到文本标记图层范围
  585. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  586. * @memberof Map
  587. */
  588. zoomToLabelLayer(duration) {
  589. const vm = this;
  590. duration = (duration != undefined)? duration : 0
  591. this.view.fit(vm.labelLayer.getSource().getExtent(),{
  592. duration: duration
  593. })
  594. }
  595. /**
  596. * @description 缩放到文本标记集合范围
  597. * @param {Array} labelArray 文本标记集合,必填
  598. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  599. * @memberof Map
  600. */
  601. zoomToLabelArray(labelArray,duration) {
  602. duration = (duration != undefined)? duration : 0
  603. let coordinateArray = new Array()
  604. for(let i=0; i<labelArray.length; i++) {
  605. coordinateArray.push(labelArray[i].Label.getGeometry().getCoordinates())
  606. }
  607. let extentBound = new Extent.boundingExtent(coordinateArray)
  608. this.view.fit(extentBound,{
  609. duration: duration
  610. })
  611. }
  612. /**
  613. * @description 缩放到线图层范围
  614. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  615. * @memberof Map
  616. */
  617. zoomToPolylineLayer(duration) {
  618. const vm = this
  619. duration = (duration != undefined)? duration : 0
  620. this.view.fit(vm.polyLineLayer.getSource().getExtent(),{
  621. duration: duration
  622. })
  623. }
  624. /**
  625. * @description 缩放到线标记集合范围
  626. * @param {Array} lineArray 线标记集合,必填
  627. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  628. * @memberof Map
  629. */
  630. zoomToPolylineArray(lineArray,duration) {
  631. duration = (duration != undefined)? duration : 0
  632. let coordinateArray = new Array()
  633. for(let i=0; i<lineArray.length; i++) {
  634. let coordinates = lineArray[i].polyline.getGeometry().getCoordinates()
  635. for(let z=0; z<coordinates.length; z++) {
  636. coordinateArray.push(coordinates[z])
  637. }
  638. }
  639. let extentBound = new Extent.boundingExtent(coordinateArray)
  640. this.view.fit(extentBound,{
  641. duration: duration
  642. })
  643. }
  644. /**
  645. * @description 缩放到经纬度数组范围
  646. * @param {Array} lngLatArray KMap.LngLat格式的经纬度坐标数组,必填
  647. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  648. * @memberof Map
  649. */
  650. zoomToLngLatArray(lngLatArray,duration) {
  651. duration = (duration != undefined)? duration : 0
  652. let coordinateArray = new Array()
  653. for(let i=0; i<lngLatArray.length; i++) {
  654. let point = Common.KMapLngLat2MapLngLat(lngLatArray[i])
  655. coordinateArray.push(proj.fromLonLat(point))
  656. }
  657. let extentBound = new Extent.boundingExtent(coordinateArray)
  658. this.view.fit(extentBound,{
  659. duration: duration
  660. })
  661. }
  662. /**
  663. * @description 调整地图视角到能够显示所有覆盖物的合适矩形范围
  664. * @param {number} duration 选填参数,动画时长(单位:毫秒),不填则使用默认的0毫秒
  665. * @memberof Map
  666. */
  667. setFitView(duration) {
  668. const vm = this
  669. //获取所有元素坐标点集合
  670. let LonLatArray = new Array()
  671. let markers = vm.markerLayer.getSource().getFeatures()
  672. let labels = vm.labelLayer.getSource().getFeatures()
  673. let polylines = vm.polyLineLayer.getSource().getFeatures()
  674. let features = [markers,labels,polylines]
  675. for(let i=0; i<features.length; i++) {
  676. for(let z=0; z<features[i].length; z++) {
  677. let featureLonLats = features[i][z].getGeometry().getCoordinates()
  678. if(features[i] != polylines) {
  679. LonLatArray.push(featureLonLats)
  680. }
  681. else {
  682. for(let m=0; m<featureLonLats.length; m++) {
  683. LonLatArray.push(featureLonLats[m])
  684. }
  685. }
  686. }
  687. }
  688. //地图视角切换到坐标点集合的矩形范围
  689. duration = (duration != undefined)? duration : 0
  690. let extentBound = new Extent.boundingExtent(LonLatArray)
  691. this.view.fit(extentBound,{
  692. duration: duration
  693. })
  694. }
  695. /**
  696. * @description 获取地图分辨率
  697. * @returns {number} 地图分辨率
  698. * @memberof Map
  699. */
  700. getResolution() {
  701. let resolution = this.view.getResolution()
  702. return resolution
  703. }
  704. /**
  705. * @description 获取地图当前缩放值
  706. * @returns {number} 地图缩放级别
  707. * @memberof Map
  708. */
  709. getZoom() {
  710. let zoom = this.view.getZoom()
  711. return zoom
  712. }
  713. /**
  714. * @description 设置地图当前缩放值
  715. * @param {number}zoom 缩放值,必填
  716. * @memberof Map
  717. */
  718. setZoom(zoom) {
  719. this.view.setZoom(zoom)
  720. }
  721. /**
  722. * @description 获取地图最大缩放值
  723. * @returns {number} 最大缩放值
  724. * @memberof Map
  725. */
  726. getMaxZoom() {
  727. let maxZoom = this.view.getMaxZoom()
  728. return maxZoom
  729. }
  730. /**
  731. * @description 设置地图最大缩放值
  732. * @param {number} zoom 最大缩放值,必填
  733. * @memberof Map
  734. */
  735. setMaxZoom(zoom) {
  736. this.view.setMaxZoom(zoom)
  737. }
  738. /**
  739. * @description 获取地图最小缩放值
  740. * @returns {number} 最小缩放值
  741. * @memberof Map
  742. */
  743. getMinZoom () {
  744. let minZoom = this.view.getMinZoom()
  745. return minZoom
  746. }
  747. /**
  748. * @description 设置地图最小缩放值
  749. * @param {number} zoom 最小缩放值,必填
  750. * @memberof Map
  751. */
  752. setMinZoom(zoom) {
  753. this.view.setMinZoom(zoom)
  754. }
  755. /**
  756. * @description 设置地图中心和缩放级别
  757. * @param {number} zoom 缩放级别,必填
  758. * @param {KMap.LngLat} center 地图中心 KMap.LngLat对象格式,必填
  759. * @param {boolean} animate 选填,是否使用缓冲动画,默认为false
  760. * @memberof Map
  761. */
  762. setZoomAndCenter(zoom,center,animate) {
  763. let centerlnglat = Common.KMapLngLat2MapLngLat(center)
  764. center = proj.fromLonLat(centerlnglat)
  765. if(animate) {
  766. this.view.animate({center:center,zoom:zoom})
  767. }
  768. else {
  769. this.view.setCenter(center)
  770. this.view.setZoom(zoom)
  771. }
  772. }
  773. /**
  774. * @description 获取地图经纬度矩形范围
  775. * @returns {KMap.Bounds} 地图经纬度矩形范围,KMap.Bounds格式
  776. * @memberof Map
  777. */
  778. getBounds() {
  779. const vm = this;
  780. let bounds = vm.view.calculateExtent(vm.map.getSize())
  781. let southWest = proj.toLonLat([bounds[0],bounds[1]])
  782. let northEast = proj.toLonLat([bounds[2],bounds[3]])
  783. bounds = [southWest[0],southWest[1],northEast[0],northEast[1]]
  784. let mapBound = Common.MapBounds2KMapBounds(bounds)//将OL的Bounds格式转换成KMap的Bounds格式
  785. return mapBound
  786. }
  787. /**
  788. * @description 设置地图经纬度矩形范围
  789. * @param {KMap.Bounds} bound 地图经纬度矩形范围,KMap.Bounds格式,必填
  790. * @memberof Map
  791. */
  792. setBounds(bound) {
  793. let lnglatArray = new Array()
  794. let mapBound = Common.KMapBounds2MapBounds(bound)//将KMap的Bounds格式转换成OL的Bounds格式
  795. lnglatArray.push(proj.fromLonLat([mapBound[0],mapBound[1]]))
  796. lnglatArray.push(proj.fromLonLat([mapBound[2],mapBound[3]]))
  797. let bounds = new Extent.boundingExtent(lnglatArray)
  798. this.view.fit(bounds) //地图视角切换到矩阵范围
  799. }
  800. /**
  801. * @description 设置地图经纬度矩形范围
  802. * @param {[minLng,minLat,maxLng,maxLat]} bound 地图经纬度矩形范围,KMap.Bounds格式,必填
  803. * @memberof Map
  804. */
  805. fitBounds(bound) {
  806. let lnglatArray = new Array();
  807. lnglatArray.push(proj.fromLonLat([bound[0],bound[1]]))
  808. lnglatArray.push(proj.fromLonLat([bound[2],bound[3]]))
  809. let bounds = new Extent.boundingExtent(lnglatArray)
  810. this.view.fit(bounds) //地图视角切换到矩阵范围
  811. }
  812. fit(geometryOrExtent,options){
  813. this.view.fit(geometryOrExtent,{ duration:500})
  814. }
  815. /**
  816. * @description 平面地图像素坐标转经纬度坐标
  817. * @param {KMap.Pixel} pixel 平面地图像素坐标,格式为KMap.Pixel对象,必填
  818. * @returns {KMap.LngLat} 经纬度坐标,格式为KMap.LngLat对象
  819. * @memberof Map
  820. */
  821. pixelToLngLat(pixel) {
  822. pixel = Common.KMapPixel2MapPixel(pixel)
  823. let lnglat = new proj.toLonLat(pixel)
  824. return Common.MapLngLat2KMapLngLat(lnglat)
  825. }
  826. /**
  827. * @description 经纬度坐标转平面地图像素坐标
  828. * @param {KMap.LngLat} lnglat 经纬度坐标,格式为KMap.LngLat对象,必填
  829. * @returns {KMap.Pixel} 地图像素坐标,格式为KMap.Pixel对象
  830. * @memberof Map
  831. */
  832. lnglatToPixel(lnglat) {
  833. lnglat = Common.KMapLngLat2MapLngLat(lnglat)
  834. let pixel = proj.fromLonLat(lnglat)
  835. return Common.MapPixel2KMapPixel(pixel)
  836. }
  837. /**
  838. * @description 地图容器屏幕坐标转经纬度坐标
  839. * @param {KMap.Pixel} pixel 地图容器像素,格式为KMap.Pixel对象,必填
  840. * @returns {KMap.LngLat} 返回KMap.LngLat格式的经纬度
  841. * @memberof Map
  842. */
  843. containerToLngLat(pixel) {
  844. pixel = Common.KMapPixel2MapPixel(pixel)
  845. let lnglat =this.map.getCoordinateFromPixel(pixel)
  846. lnglat = proj.toLonLat(lnglat)
  847. lnglat = Common.MapLngLat2KMapLngLat(lnglat)
  848. return lnglat
  849. }
  850. /**
  851. * @description 经纬度坐标转地图容器屏幕坐标
  852. * @param {KMap.LngLat} lnglat 经纬度坐标,KMap.LngLat格式的经纬度,必填
  853. * @returns {KMap.Pixel} 返回地图容器像素,格式为KMap.Pixel对象
  854. * @memberof Map
  855. */
  856. lngLatToContainer(lnglat) {
  857. lnglat = Common.KMapLngLat2MapLngLat(lnglat)
  858. let coordinate = proj.fromLonLat(lnglat)
  859. let container =this.map.getPixelFromCoordinate(coordinate)
  860. return Common.MapPixel2KMapPixel(container)
  861. }
  862. /**
  863. * @description 获取地图顺时针旋转角度
  864. * @returns {number} 顺时针旋转角度(弧度)
  865. * @memberof Map
  866. */
  867. getRotation() {
  868. let rotation = this.view.getRotation()
  869. return rotation
  870. }
  871. /**
  872. * @description 设置地图顺时针旋转角度
  873. * @param {number} rotation 顺时针旋转角度(弧度),必填
  874. * @memberof Map
  875. */
  876. setRotation(rotation) {
  877. this.view.setRotation(rotation)
  878. }
  879. /**
  880. * @description 获取地图插件集合
  881. * @returns {Array} 地图插件集合数组
  882. * @memberof Map
  883. */
  884. getControls() {
  885. let controls =this.map.getControls().array_
  886. return controls
  887. }
  888. /**
  889. * @description 添加插件
  890. * @param {ol.control} control OL原生control对象
  891. * @memberof Map
  892. */
  893. addControl(control) {
  894. let state = true
  895. let controls = this.map.getControls().array_
  896. for(let i=0; i<controls.length; i++) {
  897. if(control == controls[i]) {
  898. state = false
  899. break
  900. }
  901. }
  902. if(state){
  903. this.map.addControl(control)
  904. }
  905. }
  906. /**
  907. * @description 删除插件
  908. * @param {ol.control} control 插件,必填
  909. * @memberof Map
  910. */
  911. removeControl(control) {
  912. let controls = this.map.getControls().array_
  913. for(let i=0; i<controls.length; i++) {
  914. if(control == controls[i]) {
  915. this.map.removeControl(controls[i])
  916. return
  917. }
  918. }
  919. }
  920. /**
  921. * @description 清空默认插件 注意如果要清除默认插件需要在加载其他插件前调用此函数
  922. * @memberof Map
  923. */
  924. removeOriginControls() {
  925. let controls = this.map.getControls().array_
  926. for(let i=0; i<controls.length; i++) {
  927. this.map.removeControl(controls[i])
  928. }
  929. }
  930. /**
  931. * @description 获取地图指针样式
  932. * @memberof Map
  933. */
  934. getDefaultCursor() {
  935. let mapContainer = this.map.getTargetElement()
  936. let cursor = mapContainer.style.cursor
  937. return cursor
  938. }
  939. /**
  940. * @description 设置地图指针样式
  941. * @param {String} cursorStyle 鼠标样式("default"默认指针,"pointer"小手,"move"移动指针, "text"文本指针,"wait"等待状态,"help"帮助),必填
  942. * @memberof Map
  943. */
  944. setDefaultCursor(cursorStyle) {
  945. let mapContainer = this.map.getTargetElement()
  946. if(cursorStyle != undefined) {
  947. mapContainer.style.cursor = cursorStyle
  948. }
  949. else {
  950. mapContainer.style.cursor = "default"
  951. }
  952. }
  953. /**
  954. * @description 设置鼠标悬停在元素上时的样式
  955. * @param {String} cursorStyle 鼠标样式("default"默认指针,"pointer"小手,"move"移动指针, "text"文本指针,"wait"等待状态,"help"帮助),必填
  956. * @memberof Map
  957. */
  958. setFeatureCursor(cursorStyle) {
  959. cursorStyle = (cursorStyle == undefined)? "default" : cursorStyle
  960. let mapContainer = this.map.getTargetElement()
  961. let defaultCursor = mapContainer.style.cursor
  962. this.map.on("pointermove",function(e){
  963. let features = this.map.forEachFeatureAtPixel(e.pixel,function(feature) { return feature })
  964. if(features) {
  965. mapContainer.style.cursor = cursorStyle
  966. }
  967. else {
  968. mapContainer.style.cursor = defaultCursor
  969. }
  970. })
  971. }
  972. /**
  973. * @description 获取地图显示元素种类
  974. * @returns {Array} 地图显示元素种类集合
  975. * @memberof Map
  976. */
  977. getFeatures() {
  978. const vm = this
  979. let features = new Array()
  980. if(vm.baseLayer.getVisible() == true) {
  981. features.push("Tile")
  982. }
  983. if(vm.markerLayer.getVisible() == true){
  984. features.push("Marker")
  985. }
  986. if(vm.labelLayer.getVisible() == true){
  987. features.push("Label")
  988. }
  989. if(vm.polyLineLayer.getVisible() == true){
  990. features.push("PolyLine")
  991. }
  992. return features
  993. }
  994. /**
  995. * @description 设置地图显示元素种类
  996. * @param {JSON} param param 地图元素显示参数,JSON对象,必填
  997. * param.marker true/false,点标记是否显示,选填
  998. * param.label true/false,文本标记是否显示,选填
  999. * param.polyline true/false,线标记是否显示,选填
  1000. * @memberof Map
  1001. */
  1002. setFeatures(param) {
  1003. const vm = this
  1004. if(param.marker == true || param.marker == false){
  1005. vm.markerLayer.setVisible(param.marker)
  1006. }
  1007. if(param.label == true || param.label == false){
  1008. vm.labelLayer.setVisible(param.label)
  1009. }
  1010. if(param.polyline == true || param.polyline == false){
  1011. vm.polyLineLayer.setVisible(param.polyline)
  1012. }
  1013. }
  1014. /**
  1015. * @description 获取地图状态(双击缩放/拖拽/滚动鼠标中间缩放)
  1016. * @returns {JSON} 地图状态
  1017. * {"DoubleClickZoom": true, "DragAndDrop": true, "MouseWheelZoom": true}
  1018. * @memberof Map
  1019. */
  1020. getStates() {
  1021. let interactions =this.map.getInteractions().array_
  1022. let DoubleClickZoom,DragAndDrop,MouseWheelZoom
  1023. for(let i=0; i<interactions.length; i++) {
  1024. if(i==1) DoubleClickZoom = interactions[i].getActive()
  1025. if(i==2) DragAndDrop = interactions[i].getActive()
  1026. if(i==7) MouseWheelZoom = interactions[i].getActive()
  1027. }
  1028. let states = {
  1029. "DoubleClickZoom": DoubleClickZoom,
  1030. "DragAndDrop": DragAndDrop,
  1031. "MouseWheelZoom": MouseWheelZoom
  1032. }
  1033. return states
  1034. }
  1035. /**
  1036. * @description 设置地图状态(双击缩放/拖拽/滚动鼠标中间缩放)
  1037. * @param {JSON} param 地图状态 JSON对象,必填
  1038. * param.DoubleClickZoom true/false(双击缩放地图),选填
  1039. * param.DragAndDrop true/false(地图拖拽),选填
  1040. * param.MouseWheelZoom true/false(滚动鼠标中间缩放地图),选填
  1041. * @memberof Map
  1042. */
  1043. setStates(param) {
  1044. let interactions =this.map.getInteractions().array_
  1045. if(param.DoubleClickZoom == true || param.DoubleClickZoom == false)
  1046. interactions[1].setActive(param.DoubleClickZoom)
  1047. if(param.DragAndDrop == true || param.DragAndDrop == false)
  1048. interactions[2].setActive(param.DragAndDrop)
  1049. if(param.MouseWheelZoom == true || param.MouseWheelZoom == false)
  1050. interactions[7].setActive(param.MouseWheelZoom)
  1051. }
  1052. /**
  1053. * @description 清空地图所有元素
  1054. * @memberof Map
  1055. */
  1056. clearMap() {
  1057. const vm = this
  1058. //清空图层元素
  1059. vm.markerLayer.getSource().clear()
  1060. vm.labelLayer.getSource().clear()
  1061. vm.polyLineLayer.getSource().clear()
  1062. vm.polygonLayer.getSource().clear()
  1063. //清空地图弹窗
  1064. vm.clearInfoWindow()
  1065. }
  1066. /**
  1067. * @description 清除地图对象并清空地图容器(建议少使用此API,容易造成报错)
  1068. * @memberof Map
  1069. */
  1070. destroy() {
  1071. //清空地图对象
  1072. // this.map.destroy()
  1073. //清空地图容器
  1074. let target =this.map.getTargetElement()
  1075. target.innerHTML = ""
  1076. Common.UseBaiDuOnlineLayer = false;
  1077. Common.UseGaoDeOnlineLayer = false;
  1078. Common.UseWGS84OnlineLayer = false;
  1079. }
  1080. /**
  1081. * @description 获取地图图层数组
  1082. * @return {Array} 地图图层数组
  1083. * @memberof Map
  1084. */
  1085. getLayers() {
  1086. let layers =this.map.getLayers().array_
  1087. return layers
  1088. }
  1089. /**
  1090. * @description 设置地图各个图层显示/隐藏
  1091. * @param {JSON} param 地图图层显示参数,JSON对象,必填
  1092. * param.Marker true/false,点标记图层显示/隐藏,选填
  1093. * param.Label true/false,文本标记图层显示/隐藏,选填
  1094. * param.PolyLine true/false,线标记图层显示/隐藏,选填
  1095. * @memberof Map
  1096. */
  1097. setLayers(param) {
  1098. const vm = this
  1099. if(param.Marker == true || param.Marker == false){
  1100. vm.markerLayer.setVisible(param.Marker)
  1101. }
  1102. if(param.Label == true || param.Label == false){
  1103. vm.labelLayer.setVisible(param.Label)
  1104. }
  1105. if(param.PolyLine == true || param.PolyLine == false){
  1106. vm.polyLineLayer.setVisible(param.PolyLine)
  1107. }
  1108. }
  1109. /**
  1110. * @description 获取地图各个图层index值
  1111. * @returns {JSON} JSON对象
  1112. * {"markerLayer": 0, "labelLayer": 0, "polyLineLayer": 0}
  1113. * @memberof Map
  1114. */
  1115. getLayersIndex() {
  1116. const vm = this
  1117. let index = {}
  1118. index.markerLayer = vm.markerLayer.getZIndex()
  1119. index.labelLayer = vm.labelLayer.getZIndex()
  1120. index.polyLineLayer = vm.polyLineLayer.getZIndex()
  1121. return index
  1122. }
  1123. /**
  1124. * @description 设置地图各个图层index值,index值大的图层显示在上方,值相同时后加载的图层显示在上方
  1125. * @param {JSON} param 图层索引JSON对象,必填
  1126. * param.marker 点标记图层index值,选填
  1127. * param.label 文字标记图层index值,选填
  1128. * param.polyLine 线标记图层index值,选填
  1129. * @memberof Map
  1130. */
  1131. setLayersIndex(param) {
  1132. const vm = this
  1133. let markerIndex = (param.marker)? param.marker : vm.markerLayer.getZIndex()
  1134. let labelIndex = (param.label)? param.label : vm.labelLayer.getZIndex()
  1135. let polyLineIndex = (param.polyLine)? param.polyLine : vm.polyLineLayer.getZIndex()
  1136. vm.markerLayer.setZIndex(markerIndex)
  1137. vm.labelLayer.setZIndex(labelIndex)
  1138. vm.polyLineLayer.setZIndex(polyLineIndex)
  1139. }
  1140. /**
  1141. * @description 注册地图事件
  1142. * @param {String} eventName 地图操作事件类型,必填
  1143. * "click":单击地图,双击将触发两次;"singleclick":单击地图;"dblclick":双击地图;"movestart":开始移动地图;
  1144. * "moveend":移动地图结束;"postrender":渲染地图后;"pointerdrag":拖动指针时;"mousemove":移动指针时
  1145. * @param {funciton} callback 操作事件触发时调用的函数,必填
  1146. * @memberof Map
  1147. */
  1148. on(eventName,callback) {
  1149. if(eventName == "mousemove"){
  1150. eventName = "pointermove"
  1151. }
  1152. if(eventName == "load"){
  1153. eventName = "postrender"
  1154. }
  1155. this.map.on(eventName,callback)
  1156. }
  1157. /**
  1158. * @description 注册地图事件(事件仅执行一次)
  1159. * @param {Strig} eventName 地图操作事件类型,必填
  1160. * "click":单击地图,双击将触发两次;"singleclick":单击地图;"dblclick":双击地图;"movestart":开始移动地图;
  1161. * "moveend":移动地图结束;"postrender":渲染地图后;"pointerdrag":拖动指针时;"mousemove":移动指针时
  1162. * @param {function} callback 操作事件触发时调用的函数,必填
  1163. * @memberof Map
  1164. */
  1165. once(eventName,callback) {
  1166. if(eventName == "mousemove"){
  1167. eventName = "pointermove"
  1168. }
  1169. if(eventName == "load"){
  1170. eventName = "postrender"
  1171. }
  1172. this.map.once(eventName,callback)
  1173. }
  1174. /**
  1175. * @description 取消地图绑定事件
  1176. * @param {Strig} eventName 地图操作事件类型,必填
  1177. * "click":单击地图,双击将触发两次;"singleclick":单击地图;"dblclick":双击地图;"movestart":开始移动地图;
  1178. * "moveend":移动地图结束;"postrender":渲染地图后;"pointerdrag":拖动指针时;"mousemove":移动指针时
  1179. * @param {function} callback 操作事件触发时调用的函数,必填
  1180. * @memberof Map
  1181. */
  1182. off(eventName,callback) {
  1183. if(eventName == "mousemove"){
  1184. eventName = "pointermove"
  1185. }
  1186. if(eventName == "load"){
  1187. eventName = "postrender"
  1188. }
  1189. this.map.un(eventName,callback)
  1190. }
  1191. setMarkerLayerZoomInfo(minZoom,maxZoom){
  1192. this.markerLayer.setMaxZoom(maxZoom);
  1193. this.markerLayer.setMinZoom(minZoom);
  1194. }
  1195. setPolylineLayerZoomInfo(minZoom,maxZoom){
  1196. this.polylineLayer.setMaxZoom(maxZoom);
  1197. this.polylineLayer.setMinZoom(minZoom);
  1198. }
  1199. setPolygonLayerZoomInfo(minZoom,maxZoom){
  1200. this.polygonLayer.setMaxZoom(maxZoom);
  1201. this.polygonLayer.setMinZoom(minZoom);
  1202. }
  1203. }
  1204. export default Map