diff --git a/.husky/pre-commit b/.husky/pre-commit index aadb82a7..fe29fb26 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,10 +1,21 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -npm run switch3 -git add package.json -git add yarn.lock +#替换vue版本 +cat package.json | while read line +do + reg="\"vue\": \"^2.6." + if [[ $line == *$reg* ]] + then + npm run switch3 + git add package.json + git add yarn.lock + fi +done + +#复制文档 npm run cp git add docs/index.md git add docs/CHANGELOG.md + npx lint-staged --allow-empty $1 diff --git a/docs/.vitepress/components/demo-car-track/data.ts b/docs/.vitepress/components/demo-car-track/data.ts new file mode 100644 index 00000000..85e11f35 --- /dev/null +++ b/docs/.vitepress/components/demo-car-track/data.ts @@ -0,0 +1,197 @@ +export const data = { + type: "FeatureCollection", + features: [ + { + type: "Feature", + properties: { + time: 1, + id: "route1", + name: "五棵松" + }, + geometry: { + type: "Point", + coordinates: [116.26802, 39.90623] + } + }, + { + type: "Feature", + properties: { + time: 2, + id: "route1", + name: "万寿路" + }, + geometry: { + type: "Point", + coordinates: [116.28896, 39.90622] + } + }, + { + type: "Feature", + properties: { + time: 3, + id: "route1", + name: "公主坟" + }, + geometry: { + type: "Point", + coordinates: [116.30421, 39.90625] + } + }, + { + type: "Feature", + properties: { + time: 4, + id: "route1", + name: "军事博物馆" + }, + geometry: { + type: "Point", + coordinates: [116.3155, 39.90618] + } + }, + { + type: "Feature", + properties: { + time: 5, + id: "route1", + name: "木樨地" + }, + geometry: { + type: "Point", + coordinates: [116.3313, 39.90611] + } + }, + { + type: "Feature", + properties: { + time: 6, + id: "route1", + name: "南礼士路" + }, + geometry: { + type: "Point", + coordinates: [116.34643, 39.90583] + } + }, + { + type: "Feature", + properties: { + time: 10, + id: "route1", + name: "复兴门" + }, + geometry: { + type: "Point", + coordinates: [116.35033, 39.90582] + } + }, + { + type: "Feature", + properties: { + time: 11, + id: "route1", + name: "西单" + }, + geometry: { + type: "Point", + coordinates: [116.36784, 39.90579] + } + }, + { + type: "Feature", + properties: { + time: 12, + id: "route1", + name: "灵境胡同" + }, + geometry: { + type: "Point", + coordinates: [116.36755, 39.91449] + } + }, + { + type: "Feature", + properties: { + time: 13, + id: "route1", + name: "西四" + }, + geometry: { + type: "Point", + coordinates: [116.36755, 39.91449] + } + }, + { + type: "Feature", + properties: { + time: 14, + id: "route1", + name: "平安里" + }, + geometry: { + type: "Point", + coordinates: [116.36673, 39.93235] + } + }, + { + type: "Feature", + properties: { + time: 15, + id: "route1", + name: "平安里中转" + }, + geometry: { + type: "Point", + coordinates: [116.36651, 39.93924] + } + }, + { + type: "Feature", + properties: { + time: 16, + id: "route1", + name: "新街口" + }, + geometry: { + type: "Point", + coordinates: [116.36172, 39.93923] + } + }, + { + type: "Feature", + properties: { + time: 17, + id: "route1", + name: "西直门" + }, + geometry: { + type: "Point", + coordinates: [116.34936, 39.93913] + } + }, + { + type: "Feature", + properties: { + time: 18, + id: "route1", + name: "动物园" + }, + geometry: { + type: "Point", + coordinates: [116.33292, 39.93697] + } + }, + { + type: "Feature", + properties: { + time: 18, + id: "route1", + name: "白石桥南" + }, + geometry: { + type: "Point", + coordinates: [116.31955, 39.931] + } + } + ] +}; diff --git a/docs/.vitepress/components/demo-car-track/index.vue b/docs/.vitepress/components/demo-car-track/index.vue new file mode 100644 index 00000000..1f44506b --- /dev/null +++ b/docs/.vitepress/components/demo-car-track/index.vue @@ -0,0 +1,43 @@ + + + + + + + diff --git a/docs/.vitepress/components/index.ts b/docs/.vitepress/components/index.ts index 08836d30..9d4ceedb 100644 --- a/docs/.vitepress/components/index.ts +++ b/docs/.vitepress/components/index.ts @@ -4,9 +4,8 @@ const components = import.meta.globEager("./**/*.vue"); export default { install: (app: App) => { - Object.keys(components).forEach((key: string) => { - const component = components[key].default; - app.component(component.name, component); + Object.values(components).forEach(component => { + app.component(component.default.name, component.default); }); } }; diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 277b3449..da371ca4 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -50,6 +50,10 @@ module.exports = { { text: "服务", children: [{ text: "搜索", link: "/service/search" }] + }, + { + text: "扩展", + children: [{ text: "车辆轨迹", link: "/extra/car-track" }] } ] } diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index 8ad09eea..57ed0643 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -7,7 +7,8 @@ export default { enhanceApp({ app }) { app.use(VueTianditu, { v: "4.0", - tk: "7f013d0186775b063d6a046977bbefc6" + tk: "7f013d0186775b063d6a046977bbefc6", + plugins: ["CarTrack"] }); app.use(components); } diff --git a/docs/extra/car-track.md b/docs/extra/car-track.md new file mode 100644 index 00000000..599fab70 --- /dev/null +++ b/docs/extra/car-track.md @@ -0,0 +1,26 @@ +# 搜索 + +## 示例 + + + + +<<< @/.vitepress/components/demo-car-track/index.vue + + +## 属性 + +| 属性 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| interval | number | 1000 | 从当前节点到下一节点的时间间隔 | +| speed | number | 0 | 一个时间间隔移动的距离,单位是米。注:speed 为 0 时,按照 Datas 数组中每个元素的坐标移动 | +| dynamicLine | boolean | false | 为 true 时轨迹线随车移动,而变化。false 时,车辆运动轨迹提前画好且无动态变化 | +| Datas | array | [] | 数据来源。经纬度数组:[[116.26802, 39.90623],[116.28896, 39.90622],...] | +| carstyle | Object | ({ display: true, iconUrl: "car.png", width: 52, height: 26 }) | 车辆样式 | +| polylinestyle | Object | ({ display: true, color: "red", width: 3, opacity: 0.8 }) | 车辆轨迹线样式 | + +## 事件 + +| 事件 | 参数 | 描述 | +| --- | --- | --- | +| passOneNode | (lnglat: VT.LngLat, index: number, length: number) | 车辆移动一次时触发调用的方法。 lnglat:经过的坐标 index:节点序号 length:总节点数量 | diff --git a/packages/components.ts b/packages/components.ts index 3b7aac1f..9f1fb8f2 100644 --- a/packages/components.ts +++ b/packages/components.ts @@ -15,3 +15,4 @@ export * from "./tilelayer/tdt"; export * from "./tilelayer/wms"; export * from "./tilelayer/gridlineLayer"; export * from "./service/search"; +export * from "./extra/cartrack"; diff --git a/packages/extra/cartrack/index.ts b/packages/extra/cartrack/index.ts new file mode 100644 index 00000000..4c285a05 --- /dev/null +++ b/packages/extra/cartrack/index.ts @@ -0,0 +1,52 @@ +import { defineComponent, watch, onBeforeMount, onUnmounted, getCurrentInstance, isVue2 } from "vue-demi"; +import { useMapRoot } from "../../use"; +import { useInit, PROPS, EVENTS } from "./use"; + +export const TdtCarTrack = defineComponent({ + name: "TdtCarTrack", + props: PROPS, + emits: EVENTS, + setup(props, { emit, expose }) { + onBeforeMount(async () => { + onUnmounted(() => tdtComponent?.clear()); + + expose?.({ start, pause, stop, clear }); + if (isVue2) { + const vm = getCurrentInstance()?.proxy as any; + vm.star = start; + vm.paus = pause; + vm.sto = stop; + } + + const tdtMap = await useMapRoot(); + let tdtComponent: T.CarTrack | null = null; + watch( + () => props.Datas, + val => { + tdtComponent?.clear(); + tdtComponent = null; + if (!val.length) return; + tdtComponent = useInit(props, emit, tdtMap); + emit("init", tdtComponent); + }, + { immediate: true } + ); + + function start() { + tdtComponent?.start(); + } + function pause() { + tdtComponent?.pause(); + } + function stop() { + tdtComponent?.stop(); + } + function clear() { + tdtComponent?.clear(); + } + }); + return () => {}; + } +}); + +export type TdtCarTrack = InstanceType; diff --git a/packages/extra/cartrack/use/const.ts b/packages/extra/cartrack/use/const.ts new file mode 100644 index 00000000..814ca6f3 --- /dev/null +++ b/packages/extra/cartrack/use/const.ts @@ -0,0 +1,43 @@ +import { PropType } from "vue-demi"; +import { DefineEmits, DefineProps } from "../../../types"; + +export const NATIVE_PROPS = { + /** 从当前节点到下一节点的时间间隔 */ + interval: { type: Number, default: 1000 }, + /** 一个时间间隔移动的距离,单位是米。注:speed为0时,按照Datas数组中每个元素的坐标移动 */ + speed: { type: Number, default: 0 }, + /** 为true时轨迹线随车移动,而变化。false时,车辆运动轨迹提前画好且无动态变化 */ + dynamicLine: { type: Boolean, default: false }, + /** 数据来源 */ + Datas: { type: Array as PropType, default: () => [] }, + /** 车辆样式 */ + carstyle: { + type: Object as PropType + // default: () => ({ display: true, iconUrl: "car.png", width: 52, height: 26 }) + }, + /** 车辆轨迹线样式 */ + polylinestyle: { + type: Object as PropType + // default: () => ({ display: true, color: "red", width: 3, opacity: 0.8 }) + } +}; + +export const EXTRA_PROPS = {}; + +export const NATIVE_EVENTS = {}; + +export const EXTRA_EVENTS = { + init: (e: T.CarTrack) => e instanceof T.CarTrack, + /** + * 车辆移动一次时触发调用的方法 + * @param lnglat 经过的坐标 + * @param index 节点序号 + * @param length 总节点数量 + */ + passOneNode: (lnglat: VT.LngLat, index: number, length: number) => true +}; + +export const PROPS = { ...NATIVE_PROPS, ...EXTRA_PROPS }; +export const EVENTS = { ...NATIVE_EVENTS, ...EXTRA_EVENTS }; +export type Props = DefineProps; +export type Emit = DefineEmits; diff --git a/packages/extra/cartrack/use/index.ts b/packages/extra/cartrack/use/index.ts new file mode 100644 index 00000000..285c8219 --- /dev/null +++ b/packages/extra/cartrack/use/index.ts @@ -0,0 +1,2 @@ +export * from "./const"; +export * from "./init"; diff --git a/packages/extra/cartrack/use/init.ts b/packages/extra/cartrack/use/init.ts new file mode 100644 index 00000000..b143d4ae --- /dev/null +++ b/packages/extra/cartrack/use/init.ts @@ -0,0 +1,18 @@ +import { toLngLats } from "../../../utils"; +import { Props, Emit } from "."; + +export function useInit(props: Props, emit: Emit, map: T.Map) { + const { interval, speed, dynamicLine, Datas, carstyle, polylinestyle } = props; + const instance = new T.CarTrack(map, { + interval, + speed, + dynamicLine, + Datas: toLngLats(Datas), + carstyle, + polylinestyle, + passOneNode: (lnglat, index, length) => { + emit("passOneNode", [lnglat.lng, lnglat.lat], index, length); + } + }); + return instance; +} diff --git a/packages/mousetool/index.ts b/packages/mousetool/index.ts index 86ee6f42..014c0701 100644 --- a/packages/mousetool/index.ts +++ b/packages/mousetool/index.ts @@ -1,4 +1,4 @@ -import { defineComponent, onBeforeMount, getCurrentInstance, isVue2 } from "vue-demi"; +import { defineComponent, onBeforeMount, onUnmounted, getCurrentInstance, isVue2 } from "vue-demi"; import type { ToolInstances } from "./types"; import { useMapRoot } from "../use"; import { useInit, useWatch, PROPS, EVENTS, useEvent } from "./use"; @@ -9,6 +9,8 @@ export const TdtMousetool = defineComponent({ emits: EVENTS, setup(props, { emit, expose }) { onBeforeMount(async () => { + onUnmounted(() => clearAll()); + expose?.({ open, close, clear, clearAll }); if (isVue2) { const vm = getCurrentInstance()?.proxy as any; diff --git a/packages/tilelayer/wms/use/const.ts b/packages/tilelayer/wms/use/const.ts index a41050f0..9d96c86f 100644 --- a/packages/tilelayer/wms/use/const.ts +++ b/packages/tilelayer/wms/use/const.ts @@ -1,4 +1,3 @@ -import { PropType } from "vue-demi"; import { DefineEmits, DefineProps } from "../../../types"; export const NATIVE_PROPS = { diff --git a/packages/types/helpers/component.d.ts b/packages/types/helpers/component.d.ts index bd1626a4..152e9e2a 100644 --- a/packages/types/helpers/component.d.ts +++ b/packages/types/helpers/component.d.ts @@ -1,4 +1,4 @@ -import { ExtractPropTypes, EmitsOptions, SetupContext, ComponentPublicInstance, VNode } from "vue-demi"; +import { ExtractPropTypes, EmitsOptions, SetupContext, ComponentPublicInstance } from "vue-demi"; export type Data = Record; diff --git a/packages/types/tianditu/extra.d.ts b/packages/types/tianditu/extra.d.ts new file mode 100644 index 00000000..630624a0 --- /dev/null +++ b/packages/types/tianditu/extra.d.ts @@ -0,0 +1,29 @@ +declare namespace T { + /** + * 构建车辆的div元素,和轨迹节点的Svg元素 + */ + class CarTrack { + constructor(map: Map, opts: CarOverlayOptions); + start(): void; + stop(): void; + pause(): void; + clear(): void; + } + + interface CarOverlayOptions { + /** 从当前节点到下一节点的时间间隔。defalut:1000 */ + interval?: number; + /** 一个时间间隔移动的距离,单位是米。 注:speed为0时,按照Datas数组中每个元素的坐标移动。 default:0*/ + speed?: number; + /** 为true时轨迹线随车移动,而变化。 false时,车辆运动轨迹提前画好且无动态变化。 default:false*/ + dynamicLine?: boolean; + /** 数据来源 */ + Datas?: LngLat[]; + /** 车辆样式。default: { display:true, iconUrl:"car.png", width:52, height:26 } */ + carstyle?: { display: boolean; iconUrl: string; width: number; height: number }; + /** 车辆轨迹线样式。default: { display:true, color:"red", width:3, opacity:0.8 } */ + polylinestyle?: { display: boolean; color: string; width: number; opacity: number }; + /** 车辆移动一次时触发调用的方法。 lnglat:经过的坐标 index:节点序号 length:总节点数量 */ + passOneNode?: (lnglat: LngLat, index: number, length: number) => void; + } +} diff --git a/packages/types/tianditu/index.d.ts b/packages/types/tianditu/index.d.ts index 88255ffa..7a00ce65 100644 --- a/packages/types/tianditu/index.d.ts +++ b/packages/types/tianditu/index.d.ts @@ -1,8 +1,10 @@ import "./base"; import "./control"; +import "./extra"; import "./map"; import "./mousetool"; import "./overlay"; +import "./service"; import "./tileLayer"; declare global { diff --git a/packages/types/vue-tianditu/base.d.ts b/packages/types/vue-tianditu/base.d.ts index 486fc14d..5e51a915 100644 --- a/packages/types/vue-tianditu/base.d.ts +++ b/packages/types/vue-tianditu/base.d.ts @@ -42,4 +42,6 @@ declare namespace VT { interface MarkerClustererStyle extends T.MarkerClustererStyle { offset?: Point; } + + type PassOneNode = (lnglat: LngLat, index: number, length: number) => void; } diff --git a/packages/use/apiLoader.ts b/packages/use/apiLoader.ts index 558d8681..52f92103 100644 --- a/packages/use/apiLoader.ts +++ b/packages/use/apiLoader.ts @@ -6,20 +6,20 @@ export const DEFAULT_CONFIG = { export const PLUGINS_URL = { D3: [ - "https://cdn.bootcss.com/d3/3.5.17/d3.js", - "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.js" + "https://cdn.bootcss.com/d3/3.5.17/d3.min.js", + "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.min.js" ], CarTrack: [ - "https://cdn.bootcss.com/d3/3.5.17/d3.js", - "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.js", - "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/CarTrack.js" + "https://cdn.bootcss.com/d3/3.5.17/d3.min.js", + "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.min.js", + "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/CarTrack.min.js" ], - HeatmapOverlay: ["http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/HeatmapOverlay.js"], + HeatmapOverlay: ["http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/HeatmapOverlay.min.js"], BufferTool: [ "https://cdn.bootcss.com/Turf.js/3.0.14/turf.js", - "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/BufferTool.js" + "http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/BufferTool.min.js" ], - ImageOverLayer: ["http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/ImageOverlay.js"] + ImageOverLayer: ["http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/ImageOverlay.min.js"] }; export interface LoadConfig {