|
@@ -0,0 +1,391 @@
|
|
|
+import * as ol from 'ol'
|
|
|
+import * as style from 'ol/style'
|
|
|
+import * as layer from 'ol/layer'
|
|
|
+import * as source from 'ol/source'
|
|
|
+import * as geom from 'ol/geom'
|
|
|
+import * as proj from 'ol/proj'
|
|
|
+import * as format from 'ol/format'
|
|
|
+import * as extent from 'ol/extent'
|
|
|
+import store from '@/store/index'
|
|
|
+
|
|
|
+let hasPointClick = false
|
|
|
+let zIndex = 999
|
|
|
+let ctrlHideListGlobal = []
|
|
|
+const activeFeatureMap = new Map()
|
|
|
+const hoverFeatureMap = new Map()
|
|
|
+let moveFlag = false
|
|
|
+
|
|
|
+export const initShape = ({map, layerName, list, clickEl, hoverEl, hoverClick = false, clickHandle = (feature: any) => {}, layerZIndex}) => {
|
|
|
+ const _layers = map.getLayers().getArray().filter(v => v.get('easyMapLayerName') === layerName)
|
|
|
+ let realLayer = _layers.length > 0 ? _layers[0] : null
|
|
|
+ const features = []
|
|
|
+ const featuresMap = new Map()
|
|
|
+ list.forEach((v, i) => {
|
|
|
+ try {
|
|
|
+ const feat = new format.WKT().readFeature(v.easyMapParams.position)
|
|
|
+ feat.set('layerName', layerName)
|
|
|
+ feat.set('easyMap', v)
|
|
|
+ feat.set('_geom', feat.getGeometry())
|
|
|
+ feat.setStyle(v.easyMapParams.normalStyle)
|
|
|
+ feat.set('normalStyle', v.easyMapParams.normalStyle)
|
|
|
+ feat.set('activeStyle', v.easyMapParams.activeStyle ? v.easyMapParams.activeStyle : v.easyMapParams.normalStyle)
|
|
|
+ feat.set('hoverStyle', v.easyMapParams.hoverStyle ? v.easyMapParams.hoverStyle : (v.easyMapParams.activeStyle ? v.easyMapParams.activeStyle : v.easyMapParams.normalStyle))
|
|
|
+ feat.set('backStyle', v.easyMapParams.normalStyle)
|
|
|
+ feat.set('layerZ', realLayer ? realLayer.getZIndex() : layerZIndex ? layerZIndex : zIndex)
|
|
|
+ feat.set('featureZ', i)
|
|
|
+ feat.set('value', v.value)
|
|
|
+ feat.setId(v.easyMapParams.id)
|
|
|
+ v.easyMapParams.featureSetHandle?.(feat)
|
|
|
+ features.push(feat)
|
|
|
+ featuresMap.set(v.easyMapParams.id, feat)
|
|
|
+ } catch (e) {
|
|
|
+ console.log('v:\n%o e:\n%o', v, e)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const vectorSource = new source.Vector({
|
|
|
+ features: features,
|
|
|
+ wrapX: false
|
|
|
+ });
|
|
|
+ let clickDialog = clickEl ? map.getOverlayById(clickEl.id) : null
|
|
|
+ let hoverDialog = hoverEl ? map.getOverlayById(hoverEl.id) : null
|
|
|
+ const clickClose = () => {
|
|
|
+ clickDialog?.setPosition(undefined)
|
|
|
+ }
|
|
|
+ const hoverClose = () => {
|
|
|
+ hoverDialog?.setPosition(undefined)
|
|
|
+ }
|
|
|
+ const setActive = (feature, isClick = false, e = null) => {
|
|
|
+ if (feature) {
|
|
|
+ feature.set('backStyle', feature.getStyle())
|
|
|
+ feature.setStyle(hoverFeatureMap.get(layerName)?.getId() === feature.getId() ? feature.get('hoverStyle') : feature.get('activeStyle'))
|
|
|
+ activeFeatureMap.set(layerName, feature)
|
|
|
+ store.dispatch('easyMap/LOAD_INFO', {
|
|
|
+ type: 'click',
|
|
|
+ data: {
|
|
|
+ layerName: layerName,
|
|
|
+ value: feature.get('easyMap'),
|
|
|
+ feature: feature,
|
|
|
+ isClick,
|
|
|
+ e
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const setHover = (feature) => {
|
|
|
+ if (feature) {
|
|
|
+ if (hoverDialog && !(hoverClick || activeFeatureMap.get(layerName)?.getId() !== hoverFeatureMap.get(layerName)?.getId())) {
|
|
|
+ hoverClose()
|
|
|
+ }
|
|
|
+ feature.set('backStyle', feature.getStyle())
|
|
|
+ feature.setStyle(feature.get('hoverStyle'))
|
|
|
+ hoverFeatureMap.set(layerName, feature)
|
|
|
+ store.dispatch('easyMap/LOAD_INFO', {
|
|
|
+ type: 'hover',
|
|
|
+ data: {
|
|
|
+ layerName: layerName,
|
|
|
+ value: feature.get('easyMap'),
|
|
|
+ feature: feature
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (hoverFeatureMap.get(layerName)) {
|
|
|
+ hoverFeatureMap.set(layerName, vectorSource.getFeatureById(hoverFeatureMap.get(layerName).getId()))
|
|
|
+ setHover(hoverFeatureMap.get(layerName))
|
|
|
+ } else {
|
|
|
+ hoverFeatureMap.set(layerName, null)
|
|
|
+ }
|
|
|
+ if (activeFeatureMap.get(layerName)) {
|
|
|
+ activeFeatureMap.set(layerName, vectorSource.getFeatureById(activeFeatureMap.get(layerName).getId()))
|
|
|
+ setActive(activeFeatureMap.get(layerName))
|
|
|
+ } else {
|
|
|
+ activeFeatureMap.set(layerName, null)
|
|
|
+ }
|
|
|
+ if (realLayer) {
|
|
|
+ realLayer.setSource(vectorSource)
|
|
|
+ } else {
|
|
|
+ realLayer = new layer.VectorImage({
|
|
|
+ source: vectorSource,
|
|
|
+ easyMapLayerName: layerName,
|
|
|
+ layerType: 'easyMap',
|
|
|
+ zIndex: layerZIndex ? layerZIndex : zIndex--
|
|
|
+ })
|
|
|
+ map.addLayer(realLayer)
|
|
|
+ map.on('movestart', e => {
|
|
|
+ moveFlag = true
|
|
|
+ map.un('pointermove', mapPointerMove)
|
|
|
+ map.un('singleclick', mapSingleClick)
|
|
|
+ map.un('contextmenu', mapContextmenu)
|
|
|
+ })
|
|
|
+ map.on('moveend', e => {
|
|
|
+ map.on('singleclick', mapSingleClick)
|
|
|
+ map.on('pointermove', mapPointerMove)
|
|
|
+ map.on('contextmenu', mapContextmenu)
|
|
|
+ moveFlag = false
|
|
|
+ })
|
|
|
+ if (clickEl) {
|
|
|
+ clickDialog = setOverlay(clickEl)
|
|
|
+ map.addOverlay(clickDialog)
|
|
|
+ }
|
|
|
+ const mapSingleClick = e => {
|
|
|
+ let pointFlag = true
|
|
|
+ clickDialog?.setPosition(undefined)
|
|
|
+ // activeFeatureMap.get(layerName)?.setStyle(activeFeatureMap.get(layerName).get('normalStyle'))
|
|
|
+ let activeLayer = {
|
|
|
+ zIndex: 0,
|
|
|
+ layerName: null,
|
|
|
+ }
|
|
|
+ map.forEachFeatureAtPixel(e.pixel, (feature) => {
|
|
|
+ if (feature.get('layerZ') >= activeLayer.zIndex) {
|
|
|
+ activeLayer = {
|
|
|
+ zIndex: feature.get('layerZ'),
|
|
|
+ layerName: feature.get('layerName'),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ map.forEachFeatureAtPixel(e.pixel, (feature) => {
|
|
|
+ if (activeLayer.layerName === layerName && feature.get('layerName') === layerName && !hasPointClick) {
|
|
|
+ if (pointFlag) {
|
|
|
+ hasPointClick = true
|
|
|
+ if (activeFeatureMap.get(layerName)) {
|
|
|
+ activeFeatureMap.get(layerName).set('backStyle', activeFeatureMap.get(layerName).getStyle())
|
|
|
+ activeFeatureMap.get(layerName).setStyle(feature.get('normalStyle'))
|
|
|
+ }
|
|
|
+ pointFlag = false
|
|
|
+ if (!hoverClick) {
|
|
|
+ hoverClose()
|
|
|
+ hoverFeatureMap.delete(layerName)
|
|
|
+ }
|
|
|
+ setActive(feature, true, e)
|
|
|
+ clickHandle(feature)
|
|
|
+ if (clickDialog) {
|
|
|
+ if (feature.getGeometry().getType() !== 'Point') {
|
|
|
+ clickDialog.setPosition(e.coordinate)
|
|
|
+ } else {
|
|
|
+ clickDialog.setPosition(feature.getGeometry().getCoordinates())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ hasPointClick = false
|
|
|
+ }, 100)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ map.on('singleclick', mapSingleClick)
|
|
|
+ if (hoverEl) {
|
|
|
+ hoverDialog = setOverlay(hoverEl)
|
|
|
+ map.addOverlay(hoverDialog)
|
|
|
+ }
|
|
|
+ let pointerMoveTime = null
|
|
|
+ const mapPointerMove = e => {
|
|
|
+ clearTimeout(pointerMoveTime)
|
|
|
+ pointerMoveTime = setTimeout(() => {
|
|
|
+ if (!moveFlag) {
|
|
|
+ let isFeature = false
|
|
|
+ let hoverLayer = {
|
|
|
+ zIndex: 0,
|
|
|
+ layerName: null
|
|
|
+ }
|
|
|
+ map.forEachFeatureAtPixel(e.pixel, (feature) => {
|
|
|
+ if (feature.get('layerZ') > hoverLayer.zIndex) {
|
|
|
+ hoverLayer = {
|
|
|
+ zIndex: feature.get('layerZ'),
|
|
|
+ layerName: feature.get('layerName')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ isFeature = true
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ const reset = () => {
|
|
|
+ hoverDialog?.setPosition(undefined)
|
|
|
+ hoverFeatureMap.get(layerName)?.setStyle(hoverFeatureMap.get(layerName).get('backStyle'))
|
|
|
+ hoverFeatureMap.delete(layerName)
|
|
|
+ }
|
|
|
+ if (layerName !== hoverLayer.layerName) {
|
|
|
+ reset()
|
|
|
+ }
|
|
|
+ if (!isFeature) {
|
|
|
+ reset()
|
|
|
+ }
|
|
|
+ let pointFlag = true
|
|
|
+ map.forEachFeatureAtPixel(e.pixel, (feature) => {
|
|
|
+ if (feature.get('layerName') === layerName) {
|
|
|
+ if (pointFlag) {
|
|
|
+ if (layerName !== hoverLayer.layerName) {
|
|
|
+ hoverDialog?.setPosition(undefined)
|
|
|
+ } else {
|
|
|
+ pointFlag = false
|
|
|
+ if (hoverFeatureMap.get(layerName)?.getId() !== feature.getId()) {
|
|
|
+ if (feature.getId() !== hoverFeatureMap.get(layerName)?.getId()) {
|
|
|
+ reset()
|
|
|
+ }
|
|
|
+ setHover(feature)
|
|
|
+ if (hoverDialog && (hoverClick || activeFeatureMap.get(layerName)?.getId() !== hoverFeatureMap.get(layerName)?.getId())) {
|
|
|
+ if (feature.getGeometry().getType() !== 'Point') {
|
|
|
+ hoverDialog.setPosition(e.coordinate)
|
|
|
+ } else {
|
|
|
+ hoverDialog.setPosition(feature.getGeometry().getCoordinates())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, 10)
|
|
|
+ }
|
|
|
+ map.on('pointermove', mapPointerMove)
|
|
|
+ let ctrlHideList = []
|
|
|
+ const mapContextmenu = e => {
|
|
|
+ let isFeature = false
|
|
|
+ let hoverLayer = {
|
|
|
+ zIndex: 0,
|
|
|
+ layerName: null
|
|
|
+ }
|
|
|
+ map.forEachFeatureAtPixel(e.pixel, (feature) => {
|
|
|
+ if (feature.get('layerZ') > hoverLayer.zIndex) {
|
|
|
+ hoverLayer = {
|
|
|
+ zIndex: feature.get('layerZ'),
|
|
|
+ layerName: feature.get('layerName')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ isFeature = true
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ if (ctrlHideList.length > 0 && !window?.event?.ctrlKey && !window?.event.altKey) {
|
|
|
+ if (ctrlHideListGlobal[ctrlHideListGlobal.length - 1] === ctrlHideList[ctrlHideList.length - 1]) {
|
|
|
+ setTimeout(() => {
|
|
|
+ switchVisible([ctrlHideList.pop()], true)
|
|
|
+ ctrlHideListGlobal.pop()
|
|
|
+ }, 100)
|
|
|
+ }
|
|
|
+ } else if (ctrlHideList.length > 0 && window?.event.altKey) {
|
|
|
+ switchVisible(ctrlHideList, true)
|
|
|
+ ctrlHideList = []
|
|
|
+ ctrlHideListGlobal = []
|
|
|
+ }
|
|
|
+ let pointFlag = true
|
|
|
+ map.forEachFeatureAtPixel(e.pixel, (feature) => {
|
|
|
+ if (feature.get('layerName') === layerName) {
|
|
|
+ if (pointFlag) {
|
|
|
+ if (feature.get('layerName') === hoverLayer.layerName) {
|
|
|
+ pointFlag = false
|
|
|
+ if (window?.event?.ctrlKey) {
|
|
|
+ switchVisible([feature.get('easyMap').easyMapParams.id], false)
|
|
|
+ ctrlHideList.push(feature.get('easyMap').easyMapParams.id)
|
|
|
+ ctrlHideListGlobal.push(feature.get('easyMap').easyMapParams.id)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ hitTolerance: 0,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ map.on('contextmenu', mapContextmenu)
|
|
|
+ }
|
|
|
+ const switchVisible = (arr, show) => {
|
|
|
+ arr.forEach(v => {
|
|
|
+ const feat = featuresMap.get(v)
|
|
|
+ if (show) {
|
|
|
+ feat.setGeometry(feat.get('_geom'))
|
|
|
+ } else {
|
|
|
+ if (feat.getGeometry().getCoordinates().toString() !== [0, 0].toString()) {
|
|
|
+ feat.setGeometry(new geom.Point([0, 0]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const removeRealLayer = () => {
|
|
|
+ map.removeOverlay(clickDialog)
|
|
|
+ map.removeOverlay(hoverDialog)
|
|
|
+ map.removeLayer(realLayer)
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ clickDialog, hoverDialog, clickClose, hoverClose, switchVisible, features, realLayer, removeRealLayer, setActive
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const setOverlay = (el) => {
|
|
|
+ const over = new ol.Overlay({
|
|
|
+ id: el.id,
|
|
|
+ element: el.element,
|
|
|
+ autoPan: false,
|
|
|
+ offset: el.offset,
|
|
|
+ positioning: el.positioning,
|
|
|
+ stopEvent: true,
|
|
|
+ autoPanAnimation: {
|
|
|
+ duration: 250
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return over
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param map 地图实例,传了直接定位到中心点最大可视范围,不传返回中心点和最大分辨率
|
|
|
+ * @param position 坐标数组
|
|
|
+ * @param L 缩放比例系数,数值越小,要素边界越靠近中心
|
|
|
+ */
|
|
|
+export const getShapeView = (map, position, L = 600) => {
|
|
|
+ const center = extent.getCenter(extent.boundingExtent(position))
|
|
|
+ let x = 0
|
|
|
+ let y = 0
|
|
|
+ position.forEach(v => {
|
|
|
+ if (Math.abs(v[0] - center[0]) > x) {
|
|
|
+ x = Math.abs(v[0] - center[0])
|
|
|
+ }
|
|
|
+ if (Math.abs(v[1] - center[1]) > y) {
|
|
|
+ y = Math.abs(v[1] - center[1])
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const resolution = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) / (L / document.body.clientWidth * document.body.clientHeight)
|
|
|
+ if (map) {
|
|
|
+ map.getView().animate({
|
|
|
+ center, resolution
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ center, resolution
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export const formatPosition = {
|
|
|
+ wptTwl: (arr) => { // WKT POINT ARR TO WKT LINESTRING
|
|
|
+ const temp = arr.map(v => new format.WKT().readFeature(v).getGeometry().getCoordinates())
|
|
|
+ return new format.WKT().writeGeometry(new geom.LineString(proj.fromLonLat(temp, 'EPSG:4326')), {
|
|
|
+ dataProjection: 'EPSG:4326'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ cptTwpt: (cpt) => { // coordinates POINT TO WKT POINT
|
|
|
+ return `POINT(${cpt[0]} ${cpt[1]})`
|
|
|
+ },
|
|
|
+ wptTcpt: (wpt) => { // WKT POINT TO coordinates POINT
|
|
|
+ return new format.WKT().readFeature(wpt).getGeometry().getCoordinates()
|
|
|
+ },
|
|
|
+ wpnTcpn: (wpn) => { // WKT POLYGON TO coordinates POLYGON
|
|
|
+ return new format.WKT().readFeature(wpn).getGeometry().getCoordinates()
|
|
|
+ },
|
|
|
+ cpnTwpn: (cpn) => { // coordinates POLYGON TO WKT POLYGON
|
|
|
+ return `POLYGON(${cpn.map(v => '(' + v.map(c => `${c[0]} ${c[1]}`).join(',') + ')')})`
|
|
|
+ },
|
|
|
+ cmpnTwmpn: (cmpt) => { // coordinates MULTIPOLYGON TO WKT MULTIPOLYGON
|
|
|
+ return `MULTIPOLYGON(${cmpt.map(v1 => `(${v1.map(v => '(' + v.map(c => `${c[0]} ${c[1]}`).join(',') + ')')})`)})`
|
|
|
+ },
|
|
|
+ wmpnTcmpn: (wmpn) => { // WKT MULTIPOLYGON TO coordinates MULTIPOLYGON
|
|
|
+ return new format.WKT().readFeature(wmpn).getGeometry().getCoordinates()
|
|
|
+ },
|
|
|
+ wlTcl: (wl) => { // WKT LINESTRING TO coordinates LINESTRING
|
|
|
+ return new format.WKT().readFeature(wl).getGeometry().getCoordinates()
|
|
|
+ }
|
|
|
+}
|