@heycar/heycars-map 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { DefineComponent, SetupContext, VNode } from "vue-demi";
3
3
  import type { VNodeChildren } from "vue/types/umd";
4
4
  import type { ComponentOptionsBase } from "vue/types/v3-component-options";
5
5
  import type { ComponentObjectPropsOptions } from "vue/types/v3-component-props";
6
- import type { ObjectEmitsOptions, Slot } from "vue/types/v3-setup-context";
6
+ import type { EmitFn, ObjectEmitsOptions, Slot } from "vue/types/v3-setup-context";
7
7
  export type VNodeChild = VNode | VNodeChildren;
8
8
  export type VueNode = VNode | null | undefined;
9
9
  type LagecyPropNames<N> = N extends `on${string}` ? never : N;
@@ -18,6 +18,7 @@ export type SC<P> = Omit<SetupContext<Extract<EmitByProps<P>, ObjectEmitsOptions
18
18
  default?: Slot;
19
19
  };
20
20
  };
21
+ export type SetupContextEmit<P> = EmitFn<Extract<EmitByProps<P>, ObjectEmitsOptions>>;
21
22
  export type SetupOptions<P> = ComponentOptionsBase<P, Empty, Empty, Empty, Empty, Empty, Empty, Extract<EmitByProps<P>, ObjectEmitsOptions>, Extract<keyof EmitByProps<P>, string>, Empty>;
22
23
  export type Empty = Record<string, never>;
23
24
  export declare function defineFc<P = Empty>(render: (props: P, ctx: SC<P>) => VueNode): DefineComponent<ComponentObjectPropsOptions<P>, Empty, Empty, Empty, Empty, Empty, Empty, Extract<EmitByProps<P, Required<P>>, ObjectEmitsOptions>, Extract<keyof EmitByProps<P, Required<P>>, string>, P, import("vue-demi").ExtractDefaultPropTypes<ComponentObjectPropsOptions<P>>>;
@@ -27,4 +28,5 @@ export declare function defineLagecySetup<P>(setup: (props: P, ctx: SC<P>) => ()
27
28
  };
28
29
  export declare function Noop(): void;
29
30
  export declare const createElement: import("vue-demi").CreateElement;
31
+ export declare const LANGUAGE = "zh-CN";
30
32
  export {};
@@ -16,6 +16,6 @@ type PickSettableOptions<T, S, K extends keyof T = keyof T> = K extends `set${in
16
16
  export declare function watchPostEffectForMapProperty<T, P>(targetRef: ShallowRef<T | undefined> | Ref<T | undefined>, props: P, nameOptions: PickSettableOptions<T, keyof P>[], watchOptions?: WatchOptions<true>): void;
17
17
  export declare function watchNoneImmediatePostEffectForMapProperty<T, P>(targetRef: ShallowRef<T | undefined> | Ref<T | undefined>, props: P, nameOptions: PickSettableOptions<T, keyof P>[], watchOptions?: WatchOptions<false>): void;
18
18
  type NamesRestrict<N, S extends string> = N extends `on${string}` ? Lowercase<N> extends `on${S}` ? N : never : never;
19
- export declare function watchPostEffectForAMapEvent<T extends AMap.Event, P, E extends string = AMap.EventType>(targetRef: ShallowRef<T | undefined> | Ref<T | undefined>, props: P, emit: EmitFn<EmitByProps<P>>, propertyNames: NamesRestrict<keyof P, E>[]): void;
20
- export declare function watchPostEffectForGMapEvent<T extends google.maps.MVCObject, P>(targetRef: ShallowRef<T | undefined> | Ref<T | undefined>, props: P, emit: EmitFn<EmitByProps<P>>, propertyNames: NamesRestrict<keyof P, string>[]): void;
19
+ export declare function watchPostEffectForAMapEvent<T extends AMap.Event, P, E extends string = AMap.EventType>(targetRef: ShallowRef<T | undefined> | Ref<T | undefined> | undefined, props: P, emit: EmitFn<EmitByProps<P>>, propertyNames: NamesRestrict<keyof P, E>[]): void;
20
+ export declare function watchPostEffectForGMapEvent<T extends google.maps.MVCObject, P>(targetRef: ShallowRef<T | undefined> | Ref<T | undefined> | undefined, props: P, emit: EmitFn<EmitByProps<P>>, propertyNames: NamesRestrict<keyof P, string>[]): void;
21
21
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heycar/heycars-map",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite -c vite.config.dev.ts",
@@ -1,4 +1,5 @@
1
1
  import { AddressBox } from "../../business-components/AddressBox";
2
+ import { useMapCenter } from "../../hooks/useMapCenter";
2
3
  import { defineSetup } from "../../types/helper";
3
4
  import { HeycarMap, MapProvider } from "../MapProvider/MapProvider";
4
5
  import * as css from "./Demo.css";
@@ -24,8 +25,22 @@ export const HeycarDemo = defineSetup(function HeycarDemo() {
24
25
  center={[0, 0]}
25
26
  zoom={3}
26
27
  >
28
+ <Hello />
27
29
  <AddressBox position={[0, 0]} title={"Martyrs Lawn"} description={"您将在此处上车"} />
28
30
  </HeycarMap>
29
31
  </MapProvider>
30
32
  );
31
33
  });
34
+
35
+ export const Hello = defineSetup(function Hello() {
36
+ const { center, setCenter } = useMapCenter();
37
+ (window as any).setCenter = setCenter;
38
+ return () => {
39
+ console.log("center = ", { ...center });
40
+ return (
41
+ <div>
42
+ {center.name} | {center.lng} | {center.lat}{" "}
43
+ </div>
44
+ );
45
+ };
46
+ });
@@ -6,7 +6,7 @@ import {
6
6
  } from "../../utils/compare";
7
7
  import { provideGmap } from "./useGmap";
8
8
  export interface GampProps extends google.maps.MapOptions {
9
- onCenter_changed?: () => void;
9
+ onCenter_changed?: (e: { target: google.maps.Map }) => void;
10
10
  }
11
11
 
12
12
  export const Gmap = defineSetup(function Gmap(props: GampProps, { slots, emit }) {
@@ -17,6 +17,7 @@ export const Gmap = defineSetup(function Gmap(props: GampProps, { slots, emit })
17
17
  const defaultOptions = options.value;
18
18
  const elementRef = shallowRef();
19
19
  const mapRef = shallowRef<google.maps.Map>();
20
+ const handleCenter_changed: typeof emit = (name) => emit(name, { target: mapRef.value! });
20
21
  provideGmap(mapRef);
21
22
  watchPostEffect(() => {
22
23
  // todo 这里是否会因为 mapRef 的赋值导致不停运行?
@@ -29,6 +30,6 @@ export const Gmap = defineSetup(function Gmap(props: GampProps, { slots, emit })
29
30
  mapRef.value?.setOptions({ ...options });
30
31
  }
31
32
  );
32
- watchPostEffectForGMapEvent(mapRef, props, emit, ["onCenter_changed"]);
33
+ watchPostEffectForGMapEvent(mapRef, props, handleCenter_changed, ["onCenter_changed"]);
33
34
  return () => h("div", { ref: elementRef }, slots.default?.());
34
35
  });
@@ -1,8 +1,10 @@
1
+ import { debounce } from "lodash-es";
2
+ import { ON_CHANGE_CENTER_INTERVAL } from "../../hooks/useMapCenter";
1
3
  import { defineLagecySetup, defineSetup } from "../../types/helper";
2
4
  import { vec2lnglat } from "../../utils/transform";
3
5
  import { Amap, AmapProps } from "../Amap";
4
6
  import { AmapLoader } from "../AmapLoader";
5
- import { Gmap } from "../Gmap";
7
+ import { GampProps, Gmap } from "../Gmap";
6
8
  import { GmapLoader, GmapLoaderProps } from "../GmapLoader";
7
9
  import { MapSupplierPayolad, provideMapSupplier, useMapSupplier } from "./useMapSupplier";
8
10
 
@@ -15,10 +17,21 @@ export const MapProvider = defineLagecySetup(function MapProvider(
15
17
  return () => <div>{slots.default?.()}</div>;
16
18
  }).props(["amapKey", "amapSecret", "amapServiceHost", "gmapId", "gmapKey", "supplier"]);
17
19
 
18
- export type HeycarMapProps = Pick<GmapLoaderProps, "fallback" | "loading"> &
19
- Pick<AmapProps, "center" | "zoom">;
20
- export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, { slots }) {
20
+ export interface HeycarMapProps
21
+ extends Pick<GmapLoaderProps, "fallback" | "loading">,
22
+ Pick<AmapProps, "center" | "zoom"> {
23
+ onChangeCenter?: (value: [number, number]) => any;
24
+ }
25
+ export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, { slots, emit }) {
21
26
  const payload = useMapSupplier();
27
+ const gmapDebouncedEmit = debounce<Required<GampProps>["onCenter_changed"]>(({ target }) => {
28
+ const { lng, lat } = target.getCenter() as google.maps.LatLng;
29
+ emit("changeCenter", [lng(), lat()]);
30
+ }, ON_CHANGE_CENTER_INTERVAL);
31
+ const amapDebounceEmit = debounce<Required<AmapProps>["onMapMove"]>(({ target }) => {
32
+ const { lng, lat } = target.getCenter();
33
+ emit("changeCenter", [lng, lat]);
34
+ }, ON_CHANGE_CENTER_INTERVAL);
22
35
  return () => {
23
36
  const { gmapKey, amapKey, amapSecret, amapServiceHost, supplier, gmapId } = payload;
24
37
  const { fallback, loading, center, zoom } = props;
@@ -33,7 +46,12 @@ export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, {
33
46
  loading={loading}
34
47
  fallback={fallback}
35
48
  >
36
- <Gmap mapId={gmapId} center={center ? vec2lnglat(center) : undefined} zoom={zoom}>
49
+ <Gmap
50
+ mapId={gmapId}
51
+ center={center ? vec2lnglat(center) : undefined}
52
+ zoom={zoom}
53
+ onCenter_changed={gmapDebouncedEmit}
54
+ >
37
55
  {children}
38
56
  </Gmap>
39
57
  </GmapLoader>
@@ -54,7 +72,7 @@ export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, {
54
72
  loading={loading}
55
73
  fallback={fallback}
56
74
  >
57
- <Amap center={center} zoom={zoom}>
75
+ <Amap center={center} zoom={zoom} onMapMove={amapDebounceEmit}>
58
76
  {children}
59
77
  </Amap>
60
78
  </AmapLoader>
@@ -0,0 +1,70 @@
1
+ import { debounce } from "lodash-es";
2
+ import { reactive } from "vue-demi";
3
+ import type { AmapProps } from "../components/Amap";
4
+ import { useAmap } from "../components/Amap/useAmap";
5
+ import type { GampProps } from "../components/Gmap";
6
+ import { useGmap } from "../components/Gmap/useGmap";
7
+ import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
8
+ import { LANGUAGE, SetupContextEmit } from "../types/helper";
9
+ import { watchPostEffectForAMapEvent, watchPostEffectForGMapEvent } from "../utils/compare";
10
+ import { vec2lnglat } from "../utils/transform";
11
+
12
+ export const ON_CHANGE_CENTER_INTERVAL = 200;
13
+ export interface UseMapCenterData {
14
+ lng: number;
15
+ lat: number;
16
+ name: string;
17
+ }
18
+ export const useAmapCenter = () => {
19
+ const amapRef = useAmap();
20
+ const centerData = reactive<UseMapCenterData>({ lng: 0, lat: 0, name: "" });
21
+ const setCenter = (value: [number, number]) => amapRef?.value?.setCenter(value);
22
+ const debouncedEmit = debounce<SetupContextEmit<AmapProps>>((_, { target }) => {
23
+ const center = target.getCenter();
24
+ centerData.lng = center.lng;
25
+ centerData.lat = center.lat;
26
+ const geocoder = new AMap.Geocoder({ lang: LANGUAGE });
27
+ geocoder.getAddress(center, (status, result) => {
28
+ switch (status) {
29
+ case "complete":
30
+ centerData.name = (result as AMap.ReGeocoderResult).regeocode.formattedAddress;
31
+ return;
32
+ case "no_data":
33
+ return;
34
+ case "error":
35
+ throw result;
36
+ }
37
+ });
38
+ }, ON_CHANGE_CENTER_INTERVAL);
39
+ watchPostEffectForAMapEvent(amapRef!, {} as AmapProps, debouncedEmit, ["onMapMove"]);
40
+ return { center: centerData, setCenter };
41
+ };
42
+
43
+ export const useGmapCenter = () => {
44
+ const gmapRef = useGmap();
45
+ const centerData = reactive<UseMapCenterData>({ lng: 0, lat: 0, name: "" });
46
+ const setCenter = (value: [number, number]) => gmapRef?.value?.setCenter(vec2lnglat(value));
47
+ const debouncedEmit = debounce<SetupContextEmit<GampProps>>(async (_, { target }) => {
48
+ const center = target.getCenter();
49
+ const lng = center?.lng();
50
+ const lat = center?.lat();
51
+ if (lng) centerData.lng = lng;
52
+ if (lat) centerData.lat = lat;
53
+ const geocoder = new google.maps.Geocoder();
54
+ const { results } = await geocoder.geocode({ language: LANGUAGE, location: center });
55
+ centerData.name = results[0].formatted_address;
56
+ }, ON_CHANGE_CENTER_INTERVAL);
57
+ watchPostEffectForGMapEvent(gmapRef!, {} as GampProps, debouncedEmit, ["onCenter_changed"]);
58
+ return { center: centerData, setCenter };
59
+ };
60
+
61
+ export const useMapCenter = () => {
62
+ const payload = useMapSupplier();
63
+ // todo: 这里违反 react hook 规则,但 react 版本应该可以同时调用 useAmap 和 useGmap
64
+ switch (payload.supplier) {
65
+ case "gmap":
66
+ return useGmapCenter();
67
+ default:
68
+ return useAmapCenter();
69
+ }
70
+ };
@@ -71,6 +71,7 @@ declare global {
71
71
  addressComponent: AddressComponent;
72
72
  // 道路信息列表
73
73
  roads: Road[];
74
+ formattedAddress: string;
74
75
  // 道路交叉口列表
75
76
  roadinters: Roadinter[];
76
77
  // poi信息列表
@@ -5,7 +5,7 @@ import { DefineComponent, defineComponent, h, SetupContext, VNode } from "vue-de
5
5
  import type { VNodeChildren } from "vue/types/umd";
6
6
  import type { ComponentOptionsBase } from "vue/types/v3-component-options";
7
7
  import type { ComponentObjectPropsOptions } from "vue/types/v3-component-props";
8
- import type { ObjectEmitsOptions, Slot } from "vue/types/v3-setup-context";
8
+ import type { EmitFn, ObjectEmitsOptions, Slot } from "vue/types/v3-setup-context";
9
9
  export type VNodeChild = VNode | VNodeChildren;
10
10
  export type VueNode = VNode | null | undefined;
11
11
 
@@ -27,7 +27,7 @@ export type SC<P> = Omit<SetupContext<Extract<EmitByProps<P>, ObjectEmitsOptions
27
27
  : never]: P[K];
28
28
  } & { default?: Slot };
29
29
  };
30
-
30
+ export type SetupContextEmit<P> = EmitFn<Extract<EmitByProps<P>, ObjectEmitsOptions>>;
31
31
  export type SetupOptions<P> = ComponentOptionsBase<
32
32
  P,
33
33
  Empty,
@@ -137,3 +137,6 @@ export function defineLagecySetup<P>(setup: (props: P, ctx: SC<P>) => () => VueN
137
137
  export function Noop() {}
138
138
 
139
139
  export const createElement = h;
140
+
141
+ // todo 从 provider 那边去设置
142
+ export const LANGUAGE = "zh-CN";
@@ -128,13 +128,13 @@ export function watchPostEffectForAMapEvent<
128
128
  P,
129
129
  E extends string = AMap.EventType
130
130
  >(
131
- targetRef: ShallowRef<T | undefined> | Ref<T | undefined>,
131
+ targetRef: ShallowRef<T | undefined> | Ref<T | undefined> | undefined,
132
132
  props: P,
133
133
  emit: EmitFn<EmitByProps<P>>,
134
134
  propertyNames: NamesRestrict<keyof P, E>[]
135
135
  ) {
136
136
  watchPostEffect((onCleanup) => {
137
- const target = targetRef.value;
137
+ const target = targetRef?.value;
138
138
  if (!target) return;
139
139
  const cleanList: (() => void)[] = [];
140
140
  for (const name of propertyNames) {
@@ -151,13 +151,13 @@ export function watchPostEffectForAMapEvent<
151
151
  }
152
152
 
153
153
  export function watchPostEffectForGMapEvent<T extends google.maps.MVCObject, P>(
154
- targetRef: ShallowRef<T | undefined> | Ref<T | undefined>,
154
+ targetRef: ShallowRef<T | undefined> | Ref<T | undefined> | undefined,
155
155
  props: P,
156
156
  emit: EmitFn<EmitByProps<P>>,
157
157
  propertyNames: NamesRestrict<keyof P, string>[]
158
158
  ) {
159
159
  watchPostEffect((onCleanup) => {
160
- const target = targetRef.value;
160
+ const target = targetRef?.value;
161
161
  if (!target) return;
162
162
  const cleanList: (() => void)[] = [];
163
163
  for (const name of propertyNames) {