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 interaction from 'ol/interaction' import * as extent from "ol/extent"; import * as format from "ol/format"; import { Coordinate } from 'ol/coordinate' import * as turf from '@turf/turf' const trackLineStyle = (feature: any, resolution: any, map: any, color: any, pMap: { get: (arg0: string) => any }, callback: (arg0: style.Style[], arg1: any[]) => void) => { const _style = [] _style.push(new style.Style({ stroke: new style.Stroke({ color: color, width: 2 }) })) const geometry = feature.getGeometry(); const length = geometry.getLength();//获取线段长度 const radio = (200 * resolution) / length; const dradio = 1;//投影坐标系,如3857等,在EPSG:4326下可以设置dradio=10000 const radius = 10 const longRadius = radius * Math.SQRT2; const judgeIs = (p1: any[], p2: any[], p3: any[]) => { const E = 0.00000001 const k1 = (ps: any[], pe: number[]) => { return (pe[1] - ps[1]) / (pe[0] - ps[0]) } const k2 = (ps: any[], pe: number[]) => { return (pe[0] - ps[0]) / (pe[1] - ps[0]) } const a = (ps: any[], pe: any[]) => { return Math.abs(k1(p1, ps) - k1(p1, pe)) <= E && Math.abs(k1(p1, ps) - k1(p1, pe)) >= -E } const d = (ps: any[], pe: any[]) => { return Math.abs(k2(p1, ps) - k2(p1, pe)) <= E && Math.abs(k2(p1, ps) - k2(p1, pe)) >= -E } const s = (p: any[]) => { return p3[0] === p[0] && p3[1] === p[1] } return s(p1) || s(p2) || a(p2, p3) || d(p2, p3) } for (let i = 0; i <= 1; i += radio) { const arrowLocation = geometry.getCoordinateAt(i); if (extent.containsCoordinate(map.getView().calculateExtent(map.getSize()), arrowLocation)) { geometry.forEachSegment((start: any[], end: any[]) => { if (!judgeIs(start, end, arrowLocation)) { return } let rotation = 0; const dx = end[0] - start[0]; const dy = end[1] - start[1]; rotation = Math.atan2(dy, dx); const pushStyle = (position: Coordinate) => { _style.push(new style.Style({ geometry: new geom.Point(position), image: new style.RegularShape({ stroke: new style.Stroke({ color, width: 2, lineDash: [ longRadius - (4 * (radius / 10)), longRadius + (5.5 * (radius / 10)), longRadius, 0 ] }), radius: radius / Math.SQRT2, rotation: -rotation, angle: Math.PI / (180 / 90), points: 4 }) })); } if (map.getView().getZoom() < map.getView().getMaxZoom()) { const dx1 = end[0] - arrowLocation[0]; const dy1 = end[1] - arrowLocation[1]; const dx2 = arrowLocation[0] - start[0]; const dy2 = arrowLocation[1] - start[1]; if (dx1 != dx2 && dy1 != dy2) { if (Math.abs(dradio * dx1 * dy2 - dradio * dx2 * dy1) < 0.001) { pushStyle(arrowLocation) } } } else { if (Math.sqrt(Math.pow(start[0] - end[0], 2) + Math.pow(start[1] - end[1], 2)) > resolution * 100) { pushStyle([(start[0] + end[0]) / 2, (start[1] + end[1]) / 2]) } } }); } } const pList = [] let lC = 0 // pList.push(pMap.get(geometry.getFirstCoordinate().join('-'))) if (map.getView().getZoom() < map.getView().getMaxZoom()) { geometry.forEachSegment((start: number | Coordinate, end: number | any[]) => { // @ts-ignore const l = new geom.LineString([start, end]) lC += l.getLength() if (extent.containsCoordinate(map.getView().calculateExtent(map.getSize()), start) && lC > 200 * resolution) { // @ts-ignore const current = pMap.get(`${start[0]}-${start[1]}`) // @ts-ignore const next = pMap.get(`${end[0]}-${end[1]}`) pList.push({current, next}) lC = 0 } }); } else { geometry.forEachSegment((start: number | Coordinate, end: number | any[]) => { // @ts-ignore const l = new geom.LineString([start, end]) if (extent.containsCoordinate(map.getView().calculateExtent(map.getSize()), start)) { // @ts-ignore const current = pMap.get(`${start[0]}-${start[1]}`) // @ts-ignore const next = pMap.get(`${end[0]}-${end[1]}`) pList.push({current, next}) } }); } pList.push({ current: pMap.get(geometry.getLastCoordinate().join('-')), next: null }) callback(_style, pList) return _style } const trackPointStyle = (color: any, current: any, next: any) => { const _style = [] let _text = String(current.speed) + '节' if (next) { const dis = turf.distance(turf.point(current.position), turf.point(next.position), {units: 'meters'}) _text += dis > 1000 ? `\n${(dis / 1000).toFixed(1)}千米` : `\n${dis.toFixed(0)}米` _text += `\n${(dis / 0.51444444).toFixed(0)}秒` } _style.push(new style.Style({ image: new style.Circle({ radius: 10, fill: new style.Fill({ color: color, }), }), text: new style.Text({ text: _text, font: "12px Microsoft YaHei", // 设置字体大小 fill: new style.Fill({ // 设置字体颜色 color: "#000", }), }) }),) return _style } export default { trackLineStyle, trackPointStyle }