vue-cesium
Version:
Vue 3.x components for CesiumJS.
606 lines (599 loc) • 21.6 kB
JavaScript
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);
;
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
;