| | |
| | | * Copyright (c) 2023 by shuishen, All Rights Reserved. |
| | | --> |
| | | <template> |
| | | <div class="w100 h100"> |
| | | <div id="OlMapBoxElement" class="w100 h100"> |
| | | <div class="w100 h100"> |
| | | <div id="OlMapBoxElement" class="w100 h100"> |
| | | </div> |
| | | <div id="popup" class="ol-popup" v-show="isShowLivePersonInfoPopover"> |
| | | <a href="#" id="popup-closer" class="ol-popup-closer"></a> |
| | | <div id="popup-content"> |
| | | <p>名称:{{ livePersonData.realName }}</p> |
| | | <p>所属公司:{{ livePersonData.deptName }}</p> |
| | | <p>派遣单位:{{ livePersonData.dispatchCompany }}</p> |
| | | <p>更新时间:{{ livePersonData.recordTime }}</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | import "ol/ol.css" |
| | | import OlView from "ol/View.js" |
| | | import { |
| | | // eslint-disable-next-line no-unused-vars |
| | | defaults as OlControlDefaults, |
| | | defaults, |
| | | // 全屏控件 |
| | | FullScreen, |
| | | // 比例尺控件 |
| | | ScaleLine, |
| | | // 缩放滚动条控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | ZoomSlider, |
| | | // 鼠标位置控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | MousePosition, |
| | | // -地图属性控件 |
| | | Attribution, |
| | | // 鹰眼控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | OverviewMap, |
| | | // 缩放到范围控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | ZoomToExtent, |
| | | Rotate, |
| | | // eslint-disable-next-line no-unused-vars |
| | | defaults as OlControlDefaults, |
| | | defaults, |
| | | // 全屏控件 |
| | | FullScreen, |
| | | // 比例尺控件 |
| | | ScaleLine, |
| | | // 缩放滚动条控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | ZoomSlider, |
| | | // 鼠标位置控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | MousePosition, |
| | | // -地图属性控件 |
| | | Attribution, |
| | | // 鹰眼控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | OverviewMap, |
| | | // 缩放到范围控件 |
| | | // eslint-disable-next-line no-unused-vars |
| | | ZoomToExtent, |
| | | Rotate, |
| | | } from "ol/control.js" |
| | | import OlSourceOSM from "ol/source/OSM.js" |
| | | import OlLayerTile from "ol/layer/Tile.js" |
| | | import Overlay from "ol/Overlay.js" |
| | | |
| | | import { Image as ImageLayer } from 'ol/layer' |
| | | import ImageStatic from 'ol/source/ImageStatic.js' |
| | |
| | | let layersObjcect = {} |
| | | |
| | | let baseMapLayer = { |
| | | yx: [], |
| | | sl: [] |
| | | yx: [], |
| | | sl: [] |
| | | } |
| | | |
| | | let livePersonInfoPopover = null |
| | | |
| | | let options, |
| | | epsgcode, |
| | | isMvt = false |
| | | epsgcode, |
| | | isMvt = false |
| | | |
| | | let isMapResource = true |
| | | export default { |
| | | name: 'OlMapBox', |
| | | name: 'OlMapBox', |
| | | |
| | | props: { |
| | | mapType: { |
| | | type: String, |
| | | default: 'sl' |
| | | }, |
| | | props: { |
| | | mapType: { |
| | | type: String, |
| | | default: 'sl' |
| | | }, |
| | | |
| | | mapContrast: { |
| | | type: String, |
| | | default: 'custom' |
| | | } |
| | | }, |
| | | |
| | | data () { |
| | | return { |
| | | publicPath: process.env.BASE_URL, |
| | | } |
| | | }, |
| | | |
| | | |
| | | mounted () { |
| | | const that = this |
| | | |
| | | this.$nextTick(() => { |
| | | mapView = new OlMap({ |
| | | target: 'OlMapBoxElement', |
| | | layers: [], |
| | | view: new OlView({ |
| | | // 初始化中心点坐标,经纬度一会自己换一下 |
| | | center: [113, 24], |
| | | zoom: 18, |
| | | projection: "EPSG:4326" |
| | | }), |
| | | }) |
| | | |
| | | mapView.on("singleclick", function (event) { |
| | | mapView.forEachFeatureAtPixel( |
| | | event.pixel, |
| | | (feature) => { |
| | | feature.dispatchEvent && feature.dispatchEvent({ type: 'click', event: event }) |
| | | } |
| | | ) |
| | | }) |
| | | |
| | | that.baseInitLayer(that.mapType) |
| | | |
| | | |
| | | this.mapAddClusterLayer( |
| | | 'livePersonLocationLayer', |
| | | '/public/img/map/location', |
| | | [{lng: 113, lat: 24}, {lng: 115, lat:24 }], |
| | | (e) => { }, |
| | | ) |
| | | }) |
| | | }, |
| | | |
| | | methods: { |
| | | /** |
| | | * @description: 底图加载 |
| | | * @param {*} type |
| | | * @return {*} |
| | | */ |
| | | baseInitLayer (type) { |
| | | if (baseMapLayer.yx.length) { |
| | | baseMapLayer.yx.forEach(item => { |
| | | mapView.removeLayer(item) |
| | | }) |
| | | baseMapLayer.yx = [] |
| | | } |
| | | |
| | | if (baseMapLayer.sl.length) { |
| | | baseMapLayer.sl.forEach(item => { |
| | | mapView.removeLayer(item) |
| | | }) |
| | | baseMapLayer.sl = [] |
| | | } |
| | | |
| | | if (type == 'yx') { |
| | | let yxImgW = new OlLayerTile({ |
| | | zIndex: 1, |
| | | title: '影像', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(yxImgW) |
| | | |
| | | baseMapLayer.yx.push(yxImgW) |
| | | |
| | | let yxCvaW = new OlLayerTile({ |
| | | zIndex: 2, |
| | | title: '影像标注', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(yxCvaW) |
| | | |
| | | baseMapLayer.yx.push(yxCvaW) |
| | | } else if (type == 'sl') { |
| | | let slVecW = new OlLayerTile({ |
| | | zIndex: 2, |
| | | title: '矢量', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(slVecW) |
| | | |
| | | baseMapLayer.sl.push(slVecW) |
| | | |
| | | let slCvaW = new OlLayerTile({ |
| | | zIndex: 2, |
| | | title: '矢量标注', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(slCvaW) |
| | | |
| | | baseMapLayer.sl.push(slVecW) |
| | | } |
| | | }, |
| | | |
| | | // javascript 转换 |
| | | lonLat2Mercator (lonlat) { |
| | | var mercator = { |
| | | x: 0, |
| | | y: 0 |
| | | } |
| | | var earthRad = 6378137.0 |
| | | mercator.x = lonlat.lng * Math.PI / 180 * earthRad |
| | | var a = lonlat.lat * Math.PI / 180 |
| | | mercator.y = earthRad / 2 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a))) |
| | | return mercator |
| | | }, |
| | | |
| | | getCurItemFeature (params) { |
| | | const iconFeature = new Feature({ |
| | | geometry: new Point([Number(params.lng), Number(params.lat)]), |
| | | attributes: params.item |
| | | }) |
| | | |
| | | let styleOptions = { |
| | | cursor: 'pointer', |
| | | } |
| | | |
| | | if (params.url) { |
| | | styleOptions.image = new Icon({ |
| | | scale: params.scale || 1, |
| | | imgSize: params.imgSize || [160, 221], |
| | | src: params.url, |
| | | }) |
| | | } |
| | | |
| | | if (params.text) { |
| | | let textElement = document.createElement('span') |
| | | textElement.innerHTML = params.text |
| | | |
| | | let color = '#0000FF' |
| | | |
| | | styleOptions.text = new Text({ |
| | | // 对齐方式 |
| | | textAlign: 'center', |
| | | // 文本基线 |
| | | textBaseline: 'middle', |
| | | text: textElement.innerHTML, |
| | | font: '14px Arial', |
| | | fill: new Fill({ |
| | | color: 'white' |
| | | }), |
| | | // 填充背景 |
| | | backgroundFill: new Fill({ |
| | | color: color |
| | | }), |
| | | padding: [2, 5, 2, 5], |
| | | stroke: new Stroke({ color: '#00000000', width: 1 }) |
| | | }) |
| | | } |
| | | |
| | | iconFeature.setStyle(new Style(styleOptions)) |
| | | |
| | | iconFeature.on('click', (e) => { |
| | | if (params.event) { |
| | | params.event(e.target.values_.attributes.attr) |
| | | mapContrast: { |
| | | type: String, |
| | | default: 'custom' |
| | | } |
| | | }) |
| | | |
| | | return iconFeature |
| | | }, |
| | | |
| | | /** |
| | | * 删除图层 |
| | | * @param {*} layerName 图层名称 |
| | | */ |
| | | mapRemoveLayer (layerNames) { |
| | | layerNames.forEach(item => { |
| | | if (layersObjcect[item] && layersObjcect[item] != null) { |
| | | mapView.removeLayer(layersObjcect[item]) |
| | | delete layersObjcect[item] |
| | | data () { |
| | | return { |
| | | publicPath: process.env.BASE_URL, |
| | | livePersonData: {}, |
| | | isShowLivePersonInfoPopover: false |
| | | } |
| | | |
| | | if (layersObjcect[item + 'ONE'] && layersObjcect[item + 'ONE'] != null) { |
| | | mapView.removeLayer(layersObjcect[item + 'ONE']) |
| | | delete layersObjcect[item + 'ONE'] |
| | | } |
| | | |
| | | if (layersObjcect[item + 'TWO'] && layersObjcect[item + 'TWO'] != null) { |
| | | mapView.removeLayer(layersObjcect[item + 'TWO']) |
| | | delete layersObjcect[item + 'TWO'] |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 添加聚合图层的新模式,水库点分布 |
| | | mapAddClusterLayer (layerName, imgUrl, positionData, incident = (e) => { }, type = '') { |
| | | const that = this |
| | | |
| | | if (!layersObjcect[layerName]) { |
| | | if (type == 'cluster') { |
| | | let source = new VectorSource() |
| | | mounted () { |
| | | const that = this |
| | | |
| | | positionData.forEach(item => { |
| | | source.addFeature(that.getCurItemFeature({ |
| | | item, |
| | | lng: item.lng, |
| | | lat: item.lat, |
| | | url: imgUrl, |
| | | event: incident |
| | | })) |
| | | }) |
| | | |
| | | let layer = new Cluster({ |
| | | source: source, |
| | | distance: 100 |
| | | }) |
| | | |
| | | layersObjcect[layerName] = new VectorLayer({ |
| | | source: layer, |
| | | zIndex: 24, |
| | | style: (feature, resolution) => { |
| | | let size = feature.get('features').length |
| | | |
| | | let radius = 10 |
| | | |
| | | if (size > 900) { |
| | | radius = 19 |
| | | } else if (size > 600) { |
| | | radius = 16 |
| | | } else if (size > 400) { |
| | | radius = 13 |
| | | } |
| | | |
| | | let style = new Style({ |
| | | image: new Circle({ |
| | | radius: radius, |
| | | stroke: new Stroke({ |
| | | color: 'blue', |
| | | width: 1 |
| | | }), |
| | | fill: new Fill({ |
| | | color: 'blue' |
| | | }) |
| | | this.$nextTick(() => { |
| | | mapView = new OlMap({ |
| | | target: 'OlMapBoxElement', |
| | | layers: [], |
| | | view: new OlView({ |
| | | // 初始化中心点坐标,经纬度一会自己换一下 |
| | | center: [113, 24], |
| | | zoom: 18, |
| | | projection: "EPSG:4326" |
| | | }), |
| | | text: new Text({ |
| | | text: size.toString(), |
| | | fill: new Fill({ |
| | | color: 'white' |
| | | }) |
| | | }) |
| | | }) |
| | | }) |
| | | |
| | | return style |
| | | } |
| | | }) |
| | | mapView.on("singleclick", function (event) { |
| | | mapView.forEachFeatureAtPixel( |
| | | event.pixel, |
| | | (feature) => { |
| | | feature.dispatchEvent && feature.dispatchEvent({ type: 'click', event: event }) |
| | | } |
| | | ) |
| | | }) |
| | | |
| | | mapView.addLayer(layersObjcect[layerName]) |
| | | |
| | | return |
| | | } else { |
| | | layersObjcect[layerName] = new VectorLayer({ |
| | | // 图标图层 |
| | | zIndex: 24, |
| | | minZoom: 12, |
| | | source: new VectorSource(), |
| | | }) |
| | | } |
| | | |
| | | mapView.addLayer(layersObjcect[layerName]) |
| | | } |
| | | |
| | | positionData.forEach(item => { |
| | | layersObjcect[layerName].getSource().addFeature(that.getCurItemFeature({ |
| | | item, |
| | | lng: item.lng, |
| | | lat: item.lat, |
| | | url: imgUrl, |
| | | event: incident |
| | | })) |
| | | }) |
| | | that.baseInitLayer(that.mapType) |
| | | }) |
| | | }, |
| | | }, |
| | | |
| | | methods: { |
| | | /** |
| | | * @description: 底图加载 |
| | | * @param {*} type |
| | | * @return {*} |
| | | */ |
| | | baseInitLayer (type) { |
| | | if (baseMapLayer.yx.length) { |
| | | baseMapLayer.yx.forEach(item => { |
| | | mapView.removeLayer(item) |
| | | }) |
| | | baseMapLayer.yx = [] |
| | | } |
| | | |
| | | if (baseMapLayer.sl.length) { |
| | | baseMapLayer.sl.forEach(item => { |
| | | mapView.removeLayer(item) |
| | | }) |
| | | baseMapLayer.sl = [] |
| | | } |
| | | |
| | | if (type == 'yx') { |
| | | let yxImgW = new OlLayerTile({ |
| | | zIndex: 1, |
| | | title: '影像', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(yxImgW) |
| | | |
| | | baseMapLayer.yx.push(yxImgW) |
| | | |
| | | let yxCvaW = new OlLayerTile({ |
| | | zIndex: 2, |
| | | title: '影像标注', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(yxCvaW) |
| | | |
| | | baseMapLayer.yx.push(yxCvaW) |
| | | } else if (type == 'sl') { |
| | | let slVecW = new OlLayerTile({ |
| | | zIndex: 2, |
| | | title: '矢量', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(slVecW) |
| | | |
| | | baseMapLayer.sl.push(slVecW) |
| | | |
| | | let slCvaW = new OlLayerTile({ |
| | | zIndex: 2, |
| | | title: '矢量标注', |
| | | source: new XYZ({ |
| | | url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', |
| | | }) |
| | | }) |
| | | |
| | | mapView.addLayer(slCvaW) |
| | | |
| | | baseMapLayer.sl.push(slVecW) |
| | | } |
| | | }, |
| | | |
| | | // javascript 转换 |
| | | lonLat2Mercator (lonlat) { |
| | | var mercator = { |
| | | x: 0, |
| | | y: 0 |
| | | } |
| | | var earthRad = 6378137.0 |
| | | mercator.x = lonlat.lng * Math.PI / 180 * earthRad |
| | | var a = lonlat.lat * Math.PI / 180 |
| | | mercator.y = earthRad / 2 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a))) |
| | | return mercator |
| | | }, |
| | | |
| | | // 生成图标图层 |
| | | getCurItemFeature (params) { |
| | | const iconFeature = new Feature({ |
| | | geometry: new Point([Number(params.lng), Number(params.lat)]), |
| | | attributes: params.item |
| | | }) |
| | | |
| | | let styleOptions = { |
| | | cursor: 'pointer', |
| | | } |
| | | |
| | | if (params.url) { |
| | | styleOptions.image = new Icon({ |
| | | scale: params.scale || 1, |
| | | imgSize: params.imgSize || [160, 221], |
| | | src: params.url, |
| | | }) |
| | | } |
| | | |
| | | if (params.text) { |
| | | let textElement = document.createElement('span') |
| | | textElement.innerHTML = params.text |
| | | |
| | | let color = '#0000FF' |
| | | |
| | | styleOptions.text = new Text({ |
| | | // 对齐方式 |
| | | textAlign: 'center', |
| | | // 文本基线 |
| | | textBaseline: 'middle', |
| | | text: textElement.innerHTML, |
| | | font: '14px Arial', |
| | | fill: new Fill({ |
| | | color: 'white' |
| | | }), |
| | | // 填充背景 |
| | | backgroundFill: new Fill({ |
| | | color: color |
| | | }), |
| | | padding: [2, 5, 2, 5], |
| | | stroke: new Stroke({ color: '#00000000', width: 1 }) |
| | | }) |
| | | } |
| | | |
| | | iconFeature.setStyle(new Style(styleOptions)) |
| | | |
| | | iconFeature.on('click', (e) => { |
| | | if (params.event) {//icon事件参数 |
| | | params.event(e.target.values_.attributes)//点击事件触发事件并传参 |
| | | } |
| | | }) |
| | | return iconFeature |
| | | }, |
| | | |
| | | /** |
| | | * 删除图层 |
| | | * @param {*} layerName 图层名称 |
| | | */ |
| | | mapRemoveLayer (layerNames) { |
| | | layerNames.forEach(item => { |
| | | if (layersObjcect[item] && layersObjcect[item] != null) { |
| | | mapView.removeLayer(layersObjcect[item]) |
| | | delete layersObjcect[item] |
| | | } |
| | | |
| | | if (layersObjcect[item + 'ONE'] && layersObjcect[item + 'ONE'] != null) { |
| | | mapView.removeLayer(layersObjcect[item + 'ONE']) |
| | | delete layersObjcect[item + 'ONE'] |
| | | } |
| | | |
| | | if (layersObjcect[item + 'TWO'] && layersObjcect[item + 'TWO'] != null) { |
| | | mapView.removeLayer(layersObjcect[item + 'TWO']) |
| | | delete layersObjcect[item + 'TWO'] |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 添加聚合图层的新模式,水库点分布 |
| | | mapAddClusterLayer (layerName, imgUrl, positionData, incident = (e) => { }, type = '') { |
| | | const that = this |
| | | |
| | | if (!layersObjcect[layerName]) { |
| | | if (type == 'cluster') { |
| | | let source = new VectorSource() |
| | | |
| | | positionData.forEach(item => { |
| | | source.addFeature(that.getCurItemFeature({ |
| | | item, |
| | | lng: item.lng, |
| | | lat: item.lat, |
| | | url: imgUrl, |
| | | event: incident |
| | | })) |
| | | }) |
| | | |
| | | let layer = new Cluster({ |
| | | source: source, |
| | | distance: 100 |
| | | }) |
| | | |
| | | layersObjcect[layerName] = new VectorLayer({ |
| | | source: layer, |
| | | zIndex: 24, |
| | | style: (feature, resolution) => { |
| | | let size = feature.get('features').length |
| | | |
| | | let radius = 10 |
| | | |
| | | if (size > 900) { |
| | | radius = 19 |
| | | } else if (size > 600) { |
| | | radius = 16 |
| | | } else if (size > 400) { |
| | | radius = 13 |
| | | } |
| | | |
| | | let style = new Style({ |
| | | image: new Circle({ |
| | | radius: radius, |
| | | stroke: new Stroke({ |
| | | color: 'blue', |
| | | width: 1 |
| | | }), |
| | | fill: new Fill({ |
| | | color: 'blue' |
| | | }) |
| | | }), |
| | | text: new Text({ |
| | | text: size.toString(), |
| | | fill: new Fill({ |
| | | color: 'white' |
| | | }) |
| | | }) |
| | | }) |
| | | |
| | | return style |
| | | } |
| | | }) |
| | | |
| | | mapView.addLayer(layersObjcect[layerName]) |
| | | |
| | | return |
| | | } else { |
| | | layersObjcect[layerName] = new VectorLayer({ |
| | | // 图标图层 |
| | | zIndex: 24, |
| | | minZoom: 12, |
| | | source: new VectorSource(), |
| | | }) |
| | | } |
| | | |
| | | mapView.addLayer(layersObjcect[layerName]) |
| | | } |
| | | |
| | | positionData.forEach(item => { |
| | | layersObjcect[layerName].getSource().addFeature(that.getCurItemFeature({ |
| | | item, |
| | | lng: item.lng, |
| | | lat: item.lat, |
| | | url: imgUrl, |
| | | event: incident |
| | | })) |
| | | mapView.getView().animate({ // 只设置需要的属性即可 |
| | | center: [item.lng, item.lat], // 中心点 |
| | | zoom: 18, // 缩放级别 |
| | | rotation: undefined, // 缩放完成view视图旋转弧度 |
| | | duration: 1000 // 缩放持续时间,默认不需要设置 |
| | | }) |
| | | }) |
| | | |
| | | }, |
| | | |
| | | // 生成地图弹窗 |
| | | generateMapPopup (e) { |
| | | const that = this |
| | | this.livePersonData = e |
| | | this.isShowLivePersonInfoPopover = true |
| | | var container = document.getElementById('popup') |
| | | var closer = document.getElementById('popup-closer') |
| | | |
| | | // 创建popup |
| | | livePersonInfoPopover = new Overlay({ |
| | | element: container, |
| | | autoPan: true, |
| | | positioning: 'bottom-center', |
| | | stopEvent: false, |
| | | autoPanAnimation: { |
| | | duration: 250 |
| | | } |
| | | }) |
| | | mapView.addOverlay(livePersonInfoPopover) |
| | | closer.onclick = function () { |
| | | livePersonInfoPopover.setPosition(undefined) |
| | | closer.blur() |
| | | return false |
| | | } |
| | | livePersonInfoPopover.setPosition([e.lng, e.lat]) |
| | | }, |
| | | |
| | | |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang='scss' scope> |
| | | |
| | | .w100 { |
| | | width: 100%; |
| | | width: 100%; |
| | | } |
| | | |
| | | .h100 { |
| | | height: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .ol-popup { |
| | | position: absolute; |
| | | background-color: white; |
| | | -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); |
| | | filter: drop-shadow(0 1px 4px #FFC125); |
| | | padding: 15px; |
| | | border-radius: 10px; |
| | | border: 1px solid #cccccc; |
| | | bottom: 130px; |
| | | left: -114px; |
| | | min-width: 300px; |
| | | } |
| | | |
| | | .ol-popup:after, |
| | | .ol-popup:before { |
| | | top: 100%; |
| | | border: solid transparent; |
| | | content: " "; |
| | | height: 0; |
| | | width: 0; |
| | | position: absolute; |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .ol-popup:after { |
| | | border-top-color: white; |
| | | border-width: 10px; |
| | | left: 48px; |
| | | margin-left: -10px; |
| | | } |
| | | |
| | | .ol-popup:before { |
| | | border-top-color: #cccccc; |
| | | border-width: 11px; |
| | | left: 48px; |
| | | margin-left: -11px; |
| | | } |
| | | |
| | | .ol-popup-closer { |
| | | text-decoration: none; |
| | | position: absolute; |
| | | top: 2px; |
| | | right: 8px; |
| | | color: red; |
| | | } |
| | | |
| | | .ol-popup-closer:after { |
| | | content: "✖"; |
| | | } |
| | | </style> |