UNPKG

vue-cesium

Version:
606 lines (599 loc) 21.6 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); require('../../../composables/index.js'); var cesiumHelpers = require('../../../utils/cesium-helpers.js'); var emits$1 = require('../../../utils/emits.js'); var index$5 = require('../../primitive-collections/index.js'); var lodashEs = require('lodash-es'); var useLog = require('../../../composables/private/use-log.js'); var index$2 = require('../../primitives/index.js'); var index$3 = require('../../geometry-instance/index.js'); var index$4 = require('../../geometries/index.js'); var index$6 = require('../html/index.js'); var circle = require('@turf/circle'); var index = require('../../../composables/use-common/index.js'); var index$1 = require('../../../composables/use-locale/index.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var circle__default = /*#__PURE__*/_interopDefaultLegacy(circle); "use strict"; const defaultPointProps = { color: "#409eff", pixelSize: 8, outlineColor: "rgba(0,0,0,0.6)", outlineWidth: 1, disableDepthTestDistance: Number.POSITIVE_INFINITY }; const defaultLinePrimitiveProps = { enableMouseEvent: false, asynchronous: false, allowPicking: true }; const defaultLineGeometryProps = { width: 2, show: true }; const defaultLabelProps = { pixelOffset: [20, 0], showBackground: true, backgroundColor: "rgba(0,0,0,1)", enableMouseEvent: false }; const typhoonOverlayProps = { typhoonRoutes: { type: Array }, clampToGround: { type: Boolean, default: false }, radius7Color: { type: String, default: "rgba(68, 255, 230, 0.3)" }, radius10Color: { type: String, default: "rgba(32, 237, 39, 0.3)" }, radius12Color: { type: String, default: "rgba(255, 247, 16, 0.3)" }, pointProps: { type: [Object, Function], default: () => defaultPointProps }, linePrimitiveProps: { type: [Object, Function], default: () => defaultLinePrimitiveProps }, lineGeometryProps: { type: [Object, Function], default: () => defaultLineGeometryProps }, labelProps: { type: [Object, Function], default: () => defaultLabelProps }, circleOverlayPosition: { type: [String, Function], default: "-175px" }, setsArray: { type: Array, default: () => ["\u4E2D\u592E\u53F0", "\u65E5\u672C", "\u7F8E\u56FD", "\u97E9\u56FD", "\u4E2D\u56FD\u9999\u6E2F"] } }; const emits = { ...emits$1.commonEmits, mouseover: (e) => true, mouseout: (e) => true, click: (e) => true, clickout: (e) => true, forecastRouteAdded: (e) => true }; var OverlayTyphoon = vue.defineComponent({ name: "VcOverlayTyphoon", props: typhoonOverlayProps, emits, setup(props, ctx) { const instance = vue.getCurrentInstance(); instance.cesiumClass = "VcOverlayTyphoon"; instance.cesiumEvents = []; const commonState = index["default"](props, ctx, instance); if (commonState === void 0) { return; } const { $services } = commonState; const logger = useLog["default"](instance); const { t } = index$1.useLocale(); const primitiveCollectionRef = vue.ref(null); const typhoonDatasources = vue.reactive([]); instance.createCesiumObject = async () => { return primitiveCollectionRef; }; const addTyphoonPath = (index, datasource) => { datasource.playIndex = index; const point = datasource.typhoonRoute.points[index]; point.type = "live"; point.index = index; point.tfbh = datasource.name; const position = [point.lng, point.lat]; datasource.positions.push(position); const pointProps = typeof props.pointProps === "function" ? lodashEs.merge(lodashEs.cloneDeep(defaultPointProps), props.pointProps(point)) : props.pointProps; datasource.points.push({ id: point.id || Cesium.createGuid(), position, onMouseover(evt) { ctx.emit("mouseover", evt); }, onMouseout(evt) { ctx.emit("mouseout", evt); }, onClick(evt) { showForecast(point, datasource, index, true); datasource.playIndex = point.index; ctx.emit("click", evt); }, onClickout(evt) { ctx.emit("clickout", evt); }, ...pointProps, ...point }); const lastPoint = datasource.points[index]; lastPoint && datasource.colors.push(lastPoint.color); if (index === datasource.typhoonRoute.points.length - 1) { showForecast(point, datasource, index); } }; const playTyphoonRoute = (tfbh) => { const typhoonDatasourceIndex = typhoonDatasources.findIndex((datasource) => datasource.name === tfbh); if (typhoonDatasourceIndex >= 0) { let index = 0; const datasource = typhoonDatasources[typhoonDatasourceIndex]; datasource.points.length = 0; datasource.positions.length = 0; const typhoonData = datasource.typhoonRoute; addTyphoonPath(index, datasource); cancelAnimationFrame(datasource.playInterval); const animation = () => { index++; if (index >= typhoonData.points.length) { cancelAnimationFrame(datasource.playInterval); } else { addTyphoonPath(index, datasource); } datasource.playInterval = requestAnimationFrame(animation); }; datasource.playInterval = requestAnimationFrame(animation); } else { logger.warn(t(`vc.typhoon.warn`) || "\u64AD\u653E\u53F0\u98CE\u5931\u8D25\uFF0C\u539F\u56E0\uFF1A\u672A\u627E\u5230\u5BF9\u5E94\u7F16\u53F7\u7684\u53F0\u98CE\u6570\u636E\u3002"); } }; const showForecast = (livePoint, datasource, index, fromClick = false) => { datasource.children.length = 0; let forecast = fromClick ? livePoint.forecast || [] : []; if (!fromClick) { for (let i = 0; i < props.setsArray.length; i++) { const f = (livePoint2, index2) => { const forecastRaw = (livePoint2 == null ? void 0 : livePoint2.forecast) || []; forecast.push(...forecastRaw); if (fromClick) { return; } forecast = lodashEs.uniqWith(forecast, (a, b) => a.sets === b.sets); const sets = props.setsArray[i]; const setsIndex = forecast.findIndex((v) => v.sets === sets); if (setsIndex > -1) { if (!forecast[setsIndex].unshifted) { forecast[setsIndex].points.unshift({ lat: livePoint2.lat, lng: livePoint2.lng }); forecast[setsIndex].unshifted = true; } } else if (index2 > 0) { const preLivePoint = datasource.typhoonRoute.points[index2 - 1]; f(preLivePoint, index2 - 1); } }; f(livePoint, index); } } if (!forecast || forecast.length <= 0) { return; } for (let i = 0; i < forecast.length; i++) { const typhoonRouteBySet = forecast[i]; const points = []; const positions = []; const datasourceBySet = { name: datasource.name + "_" + typhoonRouteBySet.sets, typhoonRoute: typhoonRouteBySet, show: true, positions, points, type: "forc" }; datasource.children.push(datasourceBySet); typhoonRouteBySet.points.forEach((point, index2) => { const position = [point.lng, point.lat]; datasourceBySet.positions.push(position); if (index2 === 0 && fromClick) { datasourceBySet.positions.unshift([livePoint.lng, livePoint.lat]); } point.sets = typhoonRouteBySet.sets; point.type = "forc"; point.index = index2; const pointProps = typeof props.pointProps === "function" ? props.pointProps(point) : props.pointProps; index2 !== 0 && datasourceBySet.points.push({ id: point.id || Cesium.createGuid(), position, onMouseover(evt) { ctx.emit("mouseover", evt); }, onMouseout(evt) { ctx.emit("mouseout", evt); }, onClick(evt) { ctx.emit("click", evt); }, ...pointProps, ...point }); }); } ctx.emit("forecastRouteAdded", { livePoint, datasource, addedByClick: fromClick }); }; const addTyphoonRoute = (typhoonRoute) => { const points = []; const positions = []; const typhoonDatasource = { name: typhoonRoute.tfbh, typhoonRoute, show: true, positions, points, children: [], colors: [], type: "live" }; typhoonDatasources.push(typhoonDatasource); playTyphoonRoute(typhoonRoute.tfbh); return typhoonDatasource; }; const flyToTyphoonRoute = (typhoon, options) => { const names = []; if (typeof typhoon === "string") { names.push(typhoon); } else { names.push(...typhoon); } let boundingSphereUnion = null; names.forEach((name) => { var _a; const positions = []; const typhoonDatasource = typhoonDatasources.find((v) => v.name === name); if (typhoonDatasource && typhoonDatasource.typhoonRoute.points) { typhoonDatasource.typhoonRoute.points.forEach((point) => { positions.push([point.lng, point.lat]); }); } if ((_a = typhoonDatasource == null ? void 0 : typhoonDatasource.children) == null ? void 0 : _a.length) { typhoonDatasource.children.forEach((v) => { v.typhoonRoute.points.forEach((point) => { positions.push([point.lng, point.lat]); }); }); } const cartesian3Array = cesiumHelpers.makeCartesian3Array(positions); const boundingSphere = Cesium.BoundingSphere.fromPoints(cartesian3Array); if (null === boundingSphereUnion) { boundingSphereUnion = boundingSphere; } else { boundingSphereUnion = Cesium.BoundingSphere.union(boundingSphereUnion, boundingSphere); } }); $services.viewer.camera.flyToBoundingSphere(new Cesium.BoundingSphere(boundingSphereUnion.center, boundingSphereUnion.radius), { ...options }); }; const removeTyphoonData = (datasource) => { const index = typhoonDatasources.indexOf(datasource); if (index >= 0) { clearInterval(datasource.playInterval); typhoonDatasources.splice(index, 1); } }; const removeAllTyphoonData = () => { typhoonDatasources.forEach((datasource) => { clearInterval(datasource.playInterval); }); typhoonDatasources.length = 0; }; const getTyphoonCirclePostions = (center, radiusData) => { let positions = []; if (typeof radiusData === "number") { positions = circle__default["default"](center, radiusData * 1e3, { units: "meters" }).geometry.coordinates; } else if (radiusData["ne"]) { const _angInterval = 6; const _pointNums = 360 / (_angInterval * 4); const quadrant = { // 逆时针算角度 "0": "ne", "1": "nw", "2": "sw", "3": "se" }; for (let i = 0; i < 4; i++) { let _r = parseFloat(radiusData[quadrant[i]]) * 1e3; if (!_r) _r = 0; for (let j = i * _pointNums; j <= (i + 1) * _pointNums; j++) { const _ang = _angInterval * j; const x = center[0] + _r * Math.cos(_ang * Math.PI / 180) / 111e3; const y = center[1] + _r * Math.sin(_ang * Math.PI / 180) / 111e3; positions.push([x, y]); } } } return positions; }; const getChildren = (datasources, centerPointCircle) => { const children = []; datasources.forEach((typhoonDatasource) => { if (typhoonDatasource.positions.length > 1) { const linePrimitiveProps = typeof props.linePrimitiveProps === "function" ? lodashEs.merge(lodashEs.cloneDeep(defaultLinePrimitiveProps), props.linePrimitiveProps(typhoonDatasource)) : props.linePrimitiveProps; const lineGeometryProps = typeof props.lineGeometryProps === "function" ? lodashEs.merge(lodashEs.cloneDeep(defaultLineGeometryProps), props.lineGeometryProps(typhoonDatasource)) : props.lineGeometryProps; children.push( vue.h( index$2.VcPrimitive, { show: typhoonDatasource.show, appearance: { type: typhoonDatasource.type === "live" ? "PolylineColorAppearance" : "PolylineMaterialAppearance", options: { material: typhoonDatasource.type === "live" ? void 0 : { fabric: { type: "PolylineDash", uniforms: { color: "#000000" } } }, translucent: true } }, onMouseover: (evt) => { ctx.emit("mouseover", evt); }, onMouseout: (evt) => { ctx.emit("mouseout", evt); }, onClick: (evt) => { ctx.emit("click", evt); }, onClickout: (evt) => { ctx.emit("clickout", evt); }, ...linePrimitiveProps }, () => vue.h( index$3.VcGeometryInstance, { id: typhoonDatasource.name || Cesium.createGuid() }, () => vue.h(index$4.VcGeometryPolyline, { positions: cesiumHelpers.makeCartesian3Array(typhoonDatasource.positions), colors: typhoonDatasource.colors, ...lineGeometryProps }) ) ) ); } typhoonDatasource.points.length && children.push( vue.h(index$5.VcCollectionPoint, { show: typhoonDatasource.show, points: typhoonDatasource.points, onReady: (e) => { const { cesiumObject: pointPrimitiveCollection } = e; const originalUpdate = pointPrimitiveCollection.update; pointPrimitiveCollection.update = function(frameState) { const originalLength = frameState.commandList.length; originalUpdate.call(this, frameState); const endLength = frameState.commandList.length; for (let i = originalLength; i < endLength; ++i) { frameState.commandList[i].pass = Cesium["Pass"].TRANSLUCENT; frameState.commandList[i].renderState = Cesium["RenderState"].fromCache({ depthTest: { enabled: false }, depthMask: false }); } }; } }) ); if (typhoonDatasource.type === "live") { const labelProps = typeof props.labelProps === "function" ? lodashEs.merge(lodashEs.cloneDeep(defaultLabelProps), props.labelProps(typhoonDatasource)) : props.labelProps; children.push( vue.h(index$5.VcCollectionLabel, { show: typhoonDatasource.show, enableMouseEvent: false, labels: [ { text: typhoonDatasource.typhoonRoute.name, position: typhoonDatasource.positions[0], ...labelProps } ] }) ); const point = typhoonDatasource.points[typhoonDatasource.playIndex]; centerPointCircle.length = // 旋转图形 centerPointCircle.push( vue.h( index$6["default"], { show: typhoonDatasource.show, position: point.position, autoHidden: true }, () => vue.h("div", { class: "vc-typhoon-circle", style: { backgroundPosition: typeof props.circleOverlayPosition == "function" ? props.circleOverlayPosition(point) : props.circleOverlayPosition } }) ) ); if ((point == null ? void 0 : point.radius7) > 0) { children.push( vue.h(index$5.VcPolygon, { show: typhoonDatasource.show, positions: getTyphoonCirclePostions(point.position, point.radius7_quad), clampToGround: props.clampToGround, asynchronous: false, allowPicking: false, enableMouseEvent: false, classificationType: 2, appearance: { type: "MaterialAppearance", options: { material: { fabric: { type: "Color", uniforms: { color: props.radius7Color } } } } }, onReady: onVcPolygonReady }) ); } if ((point == null ? void 0 : point.radius10) > 0) { children.push( vue.h(index$5.VcPolygon, { show: typhoonDatasource.show, positions: getTyphoonCirclePostions(point.position, point.radius10_quad), clampToGround: props.clampToGround, asynchronous: false, allowPicking: false, enableMouseEvent: false, classificationType: 2, appearance: { type: "MaterialAppearance", options: { material: { fabric: { type: "Color", uniforms: { color: props.radius10Color } } } } }, onReady: onVcPolygonReady }) ); } if ((point == null ? void 0 : point.radius12) > 0) { children.push( vue.h(index$5.VcPolygon, { show: typhoonDatasource.show, positions: getTyphoonCirclePostions(point.position, point.radius12_quad), clampToGround: props.clampToGround, asynchronous: false, allowPicking: false, enableMouseEvent: false, classificationType: 2, appearance: { type: "MaterialAppearance", options: { material: { fabric: { type: "Color", uniforms: { color: props.radius12Color } } } } }, onReady: onVcPolygonReady }) ); } } if (typhoonDatasource.children) { children.push(...getChildren(typhoonDatasource.children, centerPointCircle)); } }); return children; }; const onVcPolygonReady = (e) => { const primitive = e.cesiumObject; const originalPrimitiveUpdate = primitive.update; primitive.update = function(frameState) { const originalLength = frameState.commandList.length; originalPrimitiveUpdate.call(this, frameState); const endLength = frameState.commandList.length; for (let i = originalLength; i < endLength; ++i) { if (frameState.commandList[i].pass !== Cesium["Pass"].TRANSLUCENT) { continue; } frameState.commandList[i].pass = Cesium["Pass"].OPAQUE; frameState.commandList[i].renderState = Cesium["RenderState"].fromCache({ depthTest: { enabled: false }, depthMask: false, blending: Cesium.BlendingState.ALPHA_BLEND }); } }; }; Object.assign(instance.proxy, { addTyphoonRoute, playTyphoonRoute, flyToTyphoonRoute, showForecast, removeTyphoonData, removeAllTyphoonData, getTyphoonDatasources: () => typhoonDatasources }); props.typhoonRoutes.forEach((typhoonData) => { addTyphoonRoute(typhoonData); }); return () => { const centerPointCircle = []; const children = getChildren(typhoonDatasources, centerPointCircle); return [ vue.h( index$5.VcCollectionPrimitive, { ref: primitiveCollectionRef, show: true // onReady: e => { // ctx.emit('ready', e) // } }, () => children ), ...centerPointCircle ]; }; } }); exports["default"] = OverlayTyphoon; exports.typhoonOverlayProps = typhoonOverlayProps; //# sourceMappingURL=index.js.map