12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199 |
- <template>
- <div id="mapbox">
- <!-- 地图 -->
- <div id="mapview" class="map" @click="basemapShow = false">
- </div>
- <!-- 图层 和 消息选择 -->
- <layer-selector
- @getCheckedMap = 'getCheckedMap'
- @getCheckedTag = 'getCheckedTag'
- ></layer-selector>
- <!-- 绘图 控件 -->
- <div
- id='div-draw'
- v-if="isDraw"
- class='float-right'
- >
- <b-form inline>
- <!-- <b-form-group label="绘制类型:" label-for="input-draw-type">
- <b-form-select
- id="input-draw-type"
- class= "mb-2 mr-3 ml-2 mb-sm-0"
- v-model="drawType"
- :options="drawTypeOption"
- required
- ></b-form-select>
- </b-form-group> -->
- <b-button variant="danger" @click="drawEnd" >结束绘制</b-button>
- </b-form>
- </div>
- <!-- popup -->
- <div>
- <!-- PC端popup -->
- <div id="pcPopup" class="ol-popup" v-if="this.$store.state.isMobile === false">
- <PhoneCard
- :title="popupData.info.title"
- :time="popupData.info.time"
- :info="popupData.info.content"
- :url="popupData.info.url"
- :img="popupData.info.img"
- :isMobile = "false"
- >
- </PhoneCard>
- </div>
- <!-- Mobile端popup -->
- <div id="mobilePopup" v-else v-show="isShow">
- <PhoneCard
- :title="popupData.info.title"
- :time="popupData.info.time"
- :info="popupData.info.content"
- :url="popupData.info.url"
- :img="popupData.info.img"
- :isMobile = 'true'
- >
- </PhoneCard>
- </div>
- </div>
- <!-- slogan -->
- <div v-if="this.$store.state.isMobile === true">
- <Slogan v-show="slogan.isShow" :slogan="slogan.content"></Slogan>
- </div>
- </div>
- </template>
- <script>
- import util from '../util'
- // openlayer
- import 'ol/ol.css'
- import {Map, View} from 'ol'
- import * as Extent from 'ol/extent'
- import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer'
- import * as olProj from 'ol/proj'
- import {Point, MultiLineString} from 'ol/geom'
- import {defaults as defaultInteractions} from 'ol/interaction'
- import Feature from 'ol/Feature'
- import * as control from 'ol/control'
- import {Style, Icon, Stroke} from 'ol/style'
- import {Cluster, Vector as VectorSource} from 'ol/source'
- import TileSource from 'ol/source/TileWMS'
- import XYZ from 'ol/source/XYZ'
- import Overlay from 'ol/Overlay'
- // import OSM from 'ol/source/OSM'
- // eventBus公共实例
- import bus from '../../static/js/eventBus'
- // icon
- import culture from '../assets/icon/culture.svg'
- import info from '../assets/icon/info.svg'
- import report from '../assets/icon/report.svg'
- import more from '../assets/icon/more.svg'
- // draw shape
- import DrawShape from '../../static/js/startDrawShape'
- // card
- import phoneCard from './card.vue'
- // slogan
- import slogan from './slogan.vue'
- // 地图对象
- // eslint-disable-next-line
- var map = null
- export default {
- name: 'Map',
- components: {
- PhoneCard: phoneCard,
- Slogan: slogan,
- LayerSelector: () => import('./LayerSelector.vue') // 消息和底图选择
- },
- data () {
- return {
- noticeStyles: { // 通知标注 样式
- Point: new Style({
- image: new Icon({
- crossOrigin: 'anonymous',
- src: info,
- scale: 0.225
- })
- }),
- LineString: new Style({
- stroke: new Stroke({
- color: '#ff8c42',
- width: 6
- })
- })
- },
- reportStyles: { // 报道/新闻 标注 样式
- Point: new Style({
- image: new Icon({
- crossOrigin: 'anonymous',
- src: report,
- scale: 0.25
- })
- }),
- LineString: new Style({
- stroke: new Stroke({
- color: '#2953a5',
- width: 6
- })
- })
- },
- cultureStyles: { // 文化标注 样式
- Point: new Style({
- image: new Icon({
- crossOrigin: 'anonymous',
- src: culture,
- scale: 0.225
- })
- }),
- LineString: new Style({
- stroke: new Stroke({
- color: '#f51a51',
- width: 6
- })
- })
- },
- otherStyles: { // 更多 标注 样式
- Point: new Style({
- image: new Icon({
- crossOrigin: 'anonymous',
- src: more,
- scale: 0.2
- })
- }),
- LineString: new Style({
- stroke: new Stroke({
- color: '#f51a51',
- width: 6
- })
- })
- },
- // popup的overlay对象
- popup: null,
- popupData: { // PC端 地图弹出框信息
- type: '',
- info: ''
- },
- // mobile端popup控制
- isShow: false,
- // 绘制状态
- isDraw: false,
- // 绘制选项
- drawTypeOption: ['线', '点'],
- // 绘制类型
- drawType: '线',
- // 绘制颜色
- drawColor: '#585eaa',
- // 信息显示列表(LayerSelector)
- checkTagList: [],
- checkMapList: [],
- // slogan
- slogan: {
- isShow: true,
- content: ''
- }
- }
- },
- methods: {
- /**
- * @description:构建地图
- * @returns {void}
- */
- initMap: function () {
- // PNG范围
- let leftTop = [11592187.538105225, 3592590.111732335]
- let rightBottom = [11594513.693708975, 3587420.877057335]
- // 经纬度
- // let leftTop = [104.13439162531515, 30.690273107307597]
- // let rightBottom = [104.15523854491164, 30.650437034690334]
- rightBottom = this.getExtentFromPNG(leftTop, rightBottom)
- // leftTop = olProj.fromLonLat(leftTop)
- // rightBottom = olProj.fromLonLat(rightBottom)
- // 根据设备的不同设置地图范围
- const MOBILE = [leftTop[0], rightBottom[1], rightBottom[0], leftTop[1]]
- // const PC = [11591064, 3589994, 11595665, 3592078]
- const PC = [11591064, 3589994, 11596565, 3592078]
- let extent = this.$store.state.isMobile ? MOBILE : PC
- let center = [
- (extent[0] + extent[2]) / 2,
- (extent[1] + extent[3]) / 2
- ]
- // let center = [
- // (leftTop[0] + rightBottom[0]) / 2,
- // (leftTop[1] + rightBottom[1]) / 2
- // ]
- let zoom = this.$store.state.isMobile ? 14.5 : 15.5
- map = new Map({
- target: 'mapview',
- layers: [
- // 天地图 地图
- new TileLayer({
- class: 'basemap',
- title: 'tiandi',
- source: new XYZ({
- url: 'https://t3.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=a7baca459fe5be059d34849072e84fd0'
- }),
- visible: true
- // nameCN: '在线地图'
- }),
- // 天地图 地图标注
- new TileLayer({
- class: 'basemap',
- title: 'tiandi',
- source: new XYZ({
- url: 'https://t3.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=a7baca459fe5be059d34849072e84fd0'
- }),
- visible: true
- // nameCN: '天地图标注'
- }),
- // 文化地图
- new TileLayer({
- class: 'basemap',
- title: 'cdut',
- source: new TileSource({
- // url: 'http://cn-cd-ali-1.natfrp.cloud:10265/geoserver/CDUT/wms',
- // url: 'http://113.125.147.162:8081/geoserver/CDUT/wms',
- // url: 'http://139.155.247.43/geoserver/CDUT/wms',
- url: 'https://geo.itopmap.com/geoserver/CDUT/wms',
- crossOrigin: 'anonymous',
- params: {
- LAYERS: 'cdut_920',
- TILED: true
- },
- servertype: 'geoserver',
- transition: 0
- })
- // nameCN: '文化地图'
- })
- ],
- interactions: defaultInteractions({
- pinchRotate: false // 移动端禁止地图旋转
- }),
- view: new View({
- center: center,
- zoom: zoom,
- extent: extent,
- maxZoom: 18.5
- }),
- controls: control.defaults({
- zoom: false
- })
- // controls: control.defaults().extend([
- // new control.MousePosition()
- // ])
- })
- setTimeout(function () { map.updateSize() })
- },
- /**
- * @description:开启聚合
- */
- addCluster: function (layerName, layerStyle) {
- let layer = map.getLayers().array_
- for (let i = 0; i < layer.length; i++) {
- if (layer[i].className_ === layerName) {
- var targetLayer = layer[i]
- }
- }
- if (targetLayer) {
- let features = targetLayer.getSource().getFeatures()
- let source = new VectorSource({
- features: features
- })
- let clusterSource = new Cluster({
- distance: 20,
- source: source
- })
- targetLayer.setSource(clusterSource)
- let style = (feature) => {
- let features = feature.get('features')
- let size = features.length
- let lastFeature = features[size - 1]
- let lonArr = []
- let latArr = []
- // 存储图标聚合的点的矩形范围
- if (feature.get('features').length > 1) {
- for (let i = 0; i < size; i++) {
- let coordinate = features[i].values_.geometry.flatCoordinates
- lonArr.push(coordinate[0])
- latArr.push(coordinate[1])
- }
- let maxLon = Math.max(...lonArr)
- let minLon = Math.min(...lonArr)
- let maxLat = Math.max(...latArr)
- let minLat = Math.min(...latArr)
- let extent = [minLon, minLat, maxLon, maxLat]
- feature.set('extent', extent)
- }
- feature.set('id', lastFeature.values_.id)
- feature.set('type', lastFeature.values_.type)
- feature.set('number', feature.get('features').length)
- let style = layerStyle
- return style
- }
- targetLayer.setStyle(style)
- }
- },
- /**
- * @description:通过图片范围结合设备尺寸计算extent
- * @param {array} leftTop:左上坐标
- * @param {array} rightBot:右下坐标
- * @returns {array}
- */
- getExtentFromPNG: function (leftTop, rightBot) {
- // 屏幕高度宽度
- let width = window.screen.width
- let height = window.screen.height
- // png坐标(atcmap中获取)
- // let imgLeft = leftTop[0]
- let imgTop = leftTop[1]
- let imgRight = rightBot[0]
- let imgBottom = rightBot[1]
- // png比例*(根据发布的png)
- // let imgWidthratio = 9
- let imgHeightratio = 20
- // 屏幕比例(根据设备获取)
- // let screenWidthratio = 9 // 先假设都为9,其他情况todo
- let screenHeightratio = 9 * height / width // 先假设都小于20,其他情况todo
- // 计算显示范围
- let screenRight = imgRight
- let screenBottom = imgTop - (imgTop - imgBottom) * (screenHeightratio / imgHeightratio)
- // 得到屏幕显示范围
- // let screen_lefttop = [imgLeft, imgTop] // 屏幕显示的左上角
- let screenRightbottom = [screenRight, screenBottom] // 即屏幕显示的右下角
- return screenRightbottom
- },
- /**
- * @description:构建popup覆盖层
- * @returns {void}
- */
- initPopupOverLay: function () {
- var container = document.getElementById('pcPopup')
- this.popup = new Overlay({
- element: container,
- autoPan: true,
- autoPanAnimation: {
- duration: 250
- }
- })
- map.addOverlay(this.popup)
- },
- /**
- * @description:绘制要素
- * @param {String} title:图层名称
- * @param {Object of {GeoJSON,String,String}} msg:要素信息(含有geometry,id,type)
- * @param {String} type:所属类别, 文化类:'culture' / 消息类: 'notice'
- * @param {Boolean} isRefresh:是否刷新图层
- * @param {Boolean} isLoacate:是否缩放到要素
- * @returns {void}
- */
- printFeature: function (title, msg, type, number = null, isRefresh = false, isLocate = false, isRelate = false) {
- // 初始化图层
- var layer = this.getLayerByTitle(title)
- if (layer !== null) {
- // 非首次调用,清除图层中的要素
- if (isRefresh) {
- layer.getSource().clear()
- }
- } else {
- // 首次调用,创建图层
- layer = new VectorLayer({
- title: title,
- class: 'layer',
- className: title,
- // extent: this.extent,
- source: new VectorSource({
- })
- })
- map.addLayer(layer)
- }
- // GeoJSON格式转换为ol.feature格式,样式装载
- var geometry = msg.geometry
- var style
- switch (type) {
- case 'notice':
- style = this.noticeStyles
- break
- case 'report':
- style = this.reportStyles
- break
- case 'culture':
- style = this.cultureStyles
- break
- case 'other':
- style = this.otherStyles
- break
- }
- var feature = this.GeoJSON_to_Feature(geometry, style)
- // 要素属性装载
- feature.set('id', msg.id)
- feature.set('type', type)
- feature.set('number', number)
- // 要素装载入图层
- // 1.起始点
- layer.getSource().addFeature(feature)
- // 2.关联线
- let fe = null
- if (isRelate && msg.relate) {
- fe = this.GeoJSON_to_Feature(msg.relate, style)
- fe.set('id', msg.id)
- fe.set('type', type)
- layer.getSource().addFeature(fe)
- }
- // 缩放至要素
- if (isLocate) {
- let locatedFeature = feature
- let feaType = 'origin'
- if (isRelate && msg.relate) {
- locatedFeature = fe
- feaType = 'relate'
- }
- this.locateAtFeature(locatedFeature, feaType)
- }
- },
- /**
- * @description:根据 GeoJSON 格式数据绘制要素
- * tips:目前支持类型:Point,MultiLineString
- * @param {GeoJSON} geometry:GeoJSON格式数据
- * @param {Array of ol.Style} styles:样式
- * @returns {ol.feature} 返回由GeoJSON转换成的配制好样式的ol.feature
- */
- GeoJSON_to_Feature: function (geometry, styles) {
- if (!geometry.type) {
- console.log('printFromGeoJSON 所输入的GeoJSON不符合规范')
- return
- }
- var feature = null
- // 按geometry.type类型创建要素并赋予样式
- switch (geometry.type) {
- case 'Point':
- feature = new Feature({
- geometry: new Point(olProj.fromLonLat(geometry.coordinates, 'EPSG:3857')),
- shape: geometry.type
- })
- feature.setStyle(styles.Point)
- break
- case 'MultiLineString':
- // let geo = geometry.coordinates.map(x => {
- // return olProj.fromLonLat(x, 'EPSG:3857')
- // })
- // feature = new Feature({
- // geometry: new LineString(geo),
- // shape: geometry.type
- // })
- // feature.setStyle(styles.LineString)
- let coords = []
- // 多线
- geometry.coordinates.forEach(i => {
- // 多点
- let co = i.map(x => {
- x = olProj.fromLonLat(x, 'EPSG:3857')
- return x
- })
- coords.push(co)
- })
- feature = new Feature({
- geometry: new MultiLineString(coords),
- shape: geometry.type
- })
- feature.setStyle(styles.LineString)
- break
- default:
- console.log('printFromGeoJSON不支持该"' + geometry.type + '"类型')
- return
- }
- return feature
- },
- /**
- * @description:ol.feature 转 GeoJSon
- * tips:目前支持类型:Point,LineString;
- * @param {ol.feature} feature
- * @returns {GeoJSON}
- */
- Feature_to_GeoJSon: function (feature) {
- let baseType = feature[0].type
- // 多点取第一个点,多线取多线
- // eslint-disable-next-line no-unneeded-ternary
- let isMulti = feature.length > 1 ? true : false
- // eslint-disable-next-line no-unneeded-ternary
- isMulti = baseType === 'LineString' ? true : false
- if (isMulti) {
- let type = 'MultiLineString'
- let coords = []
- // 多线
- feature.forEach(i => {
- i = i.coordinates
- // 多点
- let co = i.map(x => {
- x = olProj.toLonLat(x)
- return x
- })
- coords.push(co)
- })
- return {
- type: type,
- coordinates: coords
- }
- } else {
- let coord = feature[0].coordinates
- switch (baseType) {
- case 'LineString':
- coord = coord.map(x => {
- x = olProj.toLonLat(x)
- return x
- })
- break
- case 'Point':
- coord = olProj.toLonLat(coord)
- break
- }
- return {
- type: baseType,
- coordinates: coord
- }
- }
- },
- /**
- * @description:缩放至要素
- * @param {ol.Feature} feature:要素
- * @param {int} zoom: 缩放级别
- * @return {void}
- */
- locateAtFeature: function (feature, type, zoom = 17.5) {
- let view = map.getView()
- view.setZoom(zoom)
- if (this.$store.state.isMobile && type !== 'relate') {
- let coord = Extent.getCenter(feature.getGeometry().getExtent())
- coord[1] = coord[1] * 1.00006
- view.setCenter(coord)
- } else {
- view.setCenter(Extent.getCenter(feature.getGeometry().getExtent()))
- }
- if (type === 'relate') {
- view.setZoom(zoom * 0.975)
- }
- },
- /**
- * @description:获取并渲染最近若干天的通知
- * @param {int} day: 天数
- * @returns {void}
- */
- loadRecentNotices: function (day) {
- var that = this
- this.$axios
- .post('/notice/recent', {
- day: day
- })
- .then(res => {
- res.data.forEach(item => {
- that.printFeature('noticeLayer', item, 'notice')
- })
- this.addCluster('noticeLayer', this.noticeStyles.Point)
- })
- },
- /**
- * @description:获取并渲染最近若干天的报道
- * @param {int} day: 天数
- * @returns {void}
- */
- loadRecentReports: function (day) {
- var that = this
- this.$axios
- .post('/report/recent', {
- day: day
- })
- .then(res => {
- res.data.forEach(item => {
- that.printFeature('reportLayer', item, 'report')
- })
- this.addCluster('reportLayer', this.reportStyles.Point)
- })
- },
- /**
- * @description:获取并渲染所有文化设施
- * @returns {void}
- */
- loadCulture: function () {
- var that = this
- this.$axios
- .post('/culture/all')
- .then(res => {
- res.data.forEach(e => {
- that.printFeature('cultureLayer', e, 'culture')
- })
- this.addCluster('cultureLayer', this.cultureStyles.Point)
- })
- },
- /**
- * @description:加载并渲染'更多'
- */
- loadOthers: function () {
- var that = this
- this.$axios
- .post('/others/all')
- .then(res => {
- res.data.forEach(e => {
- that.printFeature('otherLayer', e, 'other')
- })
- this.addCluster('otherLayer', this.otherStyles.Point)
- })
- },
- /**
- * @description: 地图要素点击事件
- * @return {void}
- */
- mapClick: function () {
- var that = this
- // 根据设备类型设置点击事件
- var clickFun = this.$store.state.isMobile ? mobileClickFun : pcClickFun
- map.on('singleclick', clickFun)
- async function mobileClickFun (e) {
- var feature = map.forEachFeatureAtPixel(e.pixel, function (feature) {
- return feature
- })
- if (feature) {
- var id = feature.get('id')
- let type = feature.get('type')
- let number = feature.get('number')
- if (number === 1) {
- let data = null
- switch (type) {
- case 'notice':
- data = await that.loadNoticeByID(id)
- break
- case 'report':
- data = await that.loadReportByID(id)
- break
- case 'culture':
- data = await that.loadCultureByID(id)
- break
- case 'other':
- data = await that.loadOthersByID(id)
- break
- }
- that.printFeature('markLayer', data, type, number, true, true, true)
- that.isShow = true
- bus.$emit('closeList')
- } else {
- // 当点击的图标个数大于1时设置视角范围为多个图标的矩形范围
- let extent = feature.get('extent')
- map.getView().fit(extent, map.getSize())
- }
- } else {
- that.closePopup()
- }
- }
- async function pcClickFun (e) {
- // var coordinate = e.coordinate
- var feature = map.forEachFeatureAtPixel(e.pixel, feature => {
- return feature
- })
- if (feature) {
- let number = feature.get('number')
- if (number === 1) {
- bus.$emit('printMapMark', {
- type: feature.get('type'),
- id: feature.get('id'),
- number: feature.get('number')
- })
- } else {
- // 当点击的图标个数大于1时设置视角范围为多个图标的矩形范围
- let extent = feature.get('extent')
- map.getView().fit(extent, map.getSize())
- }
- } else {
- that.closePopup()
- }
- }
- },
- /**
- * @description: ol封装:通过title属性获取图层
- * @param {title} 图层title值
- * @return {layer / null}
- */
- getLayerByTitle: function (title) {
- var layers = map.getLayers().array_
- for (let i = 0; i < layers.length; i++) {
- if (layers[i].get('title') === title) {
- return layers[i]
- } else {
- continue
- }
- }
- return null
- },
- /**
- * @description:通过id查询载入通知信息
- */
- loadReportByID: async function (id) {
- var that = this
- var res
- await this.$axios
- .post('/report/detail', {
- id: id
- })
- .then(response => {
- that.popupData.info = response.data
- that.popupData.type = '新闻报道'
- res = response.data
- })
- return res
- },
- /**
- * @description:通过id查询载入通知信息
- */
- loadNoticeByID: async function (id) {
- var that = this
- var res
- await this.$axios
- .post('/notice/detail', {
- id: id
- })
- .then(response => {
- that.popupData.info = response.data
- that.popupData.type = '活动通知'
- res = response.data
- })
- return res
- },
- /**
- * @description:通过id 查询载入文化信息
- */
- loadCultureByID: async function (id) {
- var that = this
- var res
- await this.$axios
- .post('/culture/detail', {
- id: id
- })
- .then(response => {
- response.data.content = response.data.content.join('')
- that.popupData.info = response.data
- that.popupData.type = '文化设施'
- res = response.data
- })
- return res
- },
- /**
- * @description:通过id 查询载入'其他'信息
- */
- loadOthersByID: async function (id) {
- var that = this
- var res
- await this.$axios
- .post('/others/detail', {
- id: id
- })
- .then(response => {
- that.popupData.info = response.data
- that.popupData.type = '活动通知'
- res = response.data
- res = response.data
- })
- return res
- },
- /**
- * @description:设置并聚焦到popup的显示位置
- * @param {ol.coordinate}坐标
- * @param {ol.zoom}缩放级别
- */
- setPopupPosition: function (coordinate, zoom = 18) {
- this.popup.setPosition(coordinate)
- this.isShow = true
- var view = map.getView()
- view.setCenter(coordinate)
- // view.setZoom(zoom)
- },
- /**
- * @description:根据pc端与mobile端不同的popup关闭事件
- * @param {DOM} dom:点击按钮dom
- */
- closePopup: function (dom) {
- if (this.$store.state.isMobile) {
- this.isShow = false
- } else {
- this.popup.setPosition(undefined)
- this.isShow = false
- // 消除按钮聚焦
- if (dom) {
- dom.blur()
- }
- }
- return false
- },
- /**
- * @description:绘制要素
- */
- drawBegin: function () {
- // 更改为绘制状态
- this.isDraw = true
- let col = this.drawColor
- switch (this.drawType) {
- case '点':
- DrawShape.drawPoint(col, map)
- break
- case '线':
- DrawShape.drawLine(col, map)
- break
- }
- },
- /**
- * @description:结束绘制要素
- */
- drawEnd: function () {
- this.isDraw = false
- let data = DrawShape.closeDrawShape()
- if (data.length !== 0) {
- data = this.Feature_to_GeoJSon(data)
- } else {
- data = null
- }
- switch (this.drawType) {
- case '点':
- bus.$emit('drawGeometryEnd', data)
- break
- case '线':
- bus.$emit('drawRelateEnd', data)
- break
- }
- },
- // LayerSelector related
- // 底图选择 和 消息选择 的图层切换
- getCheckedMap: function (checkMapList) {
- this.checkMapList = checkMapList
- util.map.setMapVisible(map, checkMapList, 'basemap')
- },
- getCheckedTag: function (checkTagList) {
- this.checkTagList = checkTagList
- util.map.setMapVisible(map, checkTagList, 'layer')
- },
- /**
- * @description: 监听视图变化,调整slogan可见
- */
- sloganListener: function () {
- var that = this
- // 获取放置地图的div
- var mapDiv = document.getElementById('mapview')
- // 当鼠标滚轮事件发生时,执行一些操作
- function onMouseWheel (ev) {
- window.setTimeout(function () {
- let zoom = map.getView().getZoom()
- if (zoom > 15.3) {
- that.slogan.isShow = false
- } else {
- that.slogan.isShow = true
- }
- // FF 和 Chrome
- if (ev.preventDefault) {
- ev.preventDefault()// 阻止默认事件
- }
- return false
- }, 500)
- }
- addEvent(mapDiv, 'mousewheel', onMouseWheel)
- addEvent(mapDiv, 'DOMMouseScroll', onMouseWheel)
- addEvent(mapDiv, 'touchmove', onMouseWheel)
- function addEvent (obj, xEvent, fn) {
- if (obj.attachEvent) {
- obj.attachEvent('on' + xEvent, fn)
- } else {
- obj.addEventListener(xEvent, fn, false)
- }
- }
- },
- /**
- * @description: eventBus的bus.$on 触发事件汇总
- */
- busOnAction: function () {
- var that = this
- // mobile端:绘制报道标识与popup弹窗
- bus.$on('showMsgDetail', async msg => {
- let data
- let id = msg.id
- switch (msg.type) {
- case 'notice':
- await that.loadNoticeByID(id)
- .then(res => {
- data = res
- })
- break
- case 'report':
- await that.loadReportByID(id)
- .then(res => {
- data = res
- })
- break
- case 'culture':
- await that.loadCultureByID(id)
- .then(res => {
- data = res
- })
- break
- case 'other':
- await that.loadOthersByID(id)
- .then(res => {
- data = res
- })
- break
- }
- that.printFeature('markLayer', data, msg.type, null, true, true, true)
- that.isShow = true
- })
- // PC端:根据各个类型的id 绘制地图标识与popup弹窗
- bus.$on('printMapMark', async msg => {
- let data
- let id = msg.id
- let number = msg.number
- switch (msg.type) {
- case 'notice':
- await that.loadNoticeByID(id)
- .then(res => {
- data = res
- })
- break
- case 'report':
- await that.loadReportByID(id)
- .then(res => {
- data = res
- })
- break
- case 'culture':
- await that.loadCultureByID(id)
- .then(res => {
- data = res
- })
- break
- case 'other':
- await that.loadOthersByID(id)
- .then(res => {
- data = res
- })
- break
- }
- that.printFeature('markLayer', data, msg.type, number, true, true, true)
- // 显示popup
- var feature = that.getLayerByTitle('markLayer').getSource().getFeatures()[0]
- var coord = feature.getGeometry().getCoordinates()
- that.setPopupPosition(coord)
- })
- // 刷新地图标识
- bus.$on('refreshMap', () => {
- map.removeLayer(that.getLayerByTitle('noticeLayer'))
- map.removeLayer(that.getLayerByTitle('reportLayer'))
- map.removeLayer(that.getLayerByTitle('cultureLayer'))
- map.removeLayer(that.getLayerByTitle('otherLayer'))
- map.removeLayer(that.getLayerByTitle('markLayer'))
- that.loadOthers()
- that.loadCulture()
- that.loadRecentReports(7)
- that.loadRecentNotices(7)
- that.closePopup()
- })
- // 绘制
- bus.$on('drawBegin', type => {
- that.drawType = type
- that.drawBegin(type)
- })
- // 关闭弹窗
- bus.$on('closePopup', () => {
- that.closePopup()
- })
- }
- },
- mounted () {
- this.initMap()
- this.initPopupOverLay()
- this.busOnAction()
- this.loadRecentReports(365)
- this.loadRecentNotices(365)
- this.loadOthers()
- this.loadCulture()
- this.mapClick()
- this.sloganListener()
- },
- watch: {
- drawType: function () {
- DrawShape.closeDrawShape()
- this.drawBegin()
- },
- isShow: function () {
- if (this.isShow === true) {
- this.slogan.isShow = false
- }
- }
- },
- filters: {
- // 超过100位显示省略号
- ellipsis: function (value) {
- if (!value) return ''
- if (value.length > 70) {
- return value.slice(0, 70) + '...'
- }
- return value
- }
- }
- }
- </script>
- <!-- Add "scoped" attribute to limit CSS to this component only -->
- <style scoped>
- #mapview{
- width: 100%;
- height: 100%;
- position: absolute;
- /* background: rgb(135,191,150); */
- }
- #div-draw {
- position: absolute;
- left: 50%;
- top:2px;
- z-index: 100;
- background: white;
- border-radius: 5px;
- padding: 10px 10px 10px 10px;
- border: 1px solid gray;
- transform: translateX(-50%);
- }
- /*图层切换弹出框样式*/
- #basemap-content {
- position: absolute;
- font-size: 12px;
- z-index: 100;
- background: rgba(255, 255, 255, 0.7);
- opacity: 0.95;
- right: 0px;
- margin-top: 40px;
- height: 50px;
- width:65px;
- align-content: center;
- }
- .basemap-item {
- padding: 5px;
- cursor: pointer;
- }
- .basemap-text,.online-map-text{
- width: 60px;
- height: 12px;
- }
- .basemap-text{
- color: #007bff;
- font-weight: bold;
- font-family: "Source Han Sans CN";
- }
- /*图层与消息按钮样式*/
- .info-select-button {
- width: 22px;
- height: 20px;
- }
- .info-select-button-div {
- width: 22px;
- height: 22px;
- z-index: 999;
- cursor: pointer;
- position: absolute;
- }
- .layer-select-button {
- width: 22px;
- height: 22px;
- }
- .layer-select-button-div {
- width: 22px;
- height: 22px;
- z-index: 999;
- right: 3px;
- cursor: pointer;
- position: absolute;
- }
- </style>
|