@heycar/heycars-map 0.8.3 → 0.8.5

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.
package/dist/index.cjs CHANGED
@@ -9,7 +9,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
9
  const Vue = require("vue");
10
10
  const style = "";
11
11
  const name = "@heycar/heycars-map";
12
- const version = "0.8.3";
12
+ const version = "0.8.5";
13
13
  const type = "module";
14
14
  const scripts = {
15
15
  dev: "vite -c vite.config.dev.ts",
@@ -857,7 +857,6 @@ const useMapOverlay = (props) => {
857
857
  registerOverlay == null ? void 0 : registerOverlay.remove(overlay);
858
858
  });
859
859
  };
860
- const isLatLngLiteral = (obj) => obj != null && typeof obj === "object" && Number.isFinite(obj.lat) && Number.isFinite(obj.lng);
861
860
  var HAS_WEAK_MAP_SUPPORT = typeof WeakMap === "function";
862
861
  var keys = Object.keys;
863
862
  function sameValueZeroEqual(a, b) {
@@ -1098,6 +1097,23 @@ createComparator(function() {
1098
1097
  });
1099
1098
  createComparator(createCircularEqualCreator());
1100
1099
  createComparator(createCircularEqualCreator(sameValueZeroEqual));
1100
+ const isPlace = (place) => {
1101
+ return place.lng !== void 0 && place.lat !== void 0;
1102
+ };
1103
+ const sleep = (milliSeconds) => new Promise((resolve) => setTimeout(resolve, milliSeconds));
1104
+ const assertPoint = (point) => {
1105
+ if (Array.isArray(point) && point.length === 2 && typeof point[0] === "number" && typeof point[1] === "number")
1106
+ return;
1107
+ throw new Error(`Assertion Error: expect type [number, number], actual is ${point}`);
1108
+ };
1109
+ const assertAngle = (angle) => {
1110
+ if (typeof angle === "number" || typeof angle === "undefined")
1111
+ return;
1112
+ throw new Error(`Assertion Error: expect type number | undefined, actual is ${angle}`);
1113
+ };
1114
+ const isLatLngLiteral = (value) => {
1115
+ return value != null && typeof value === "object" && Number.isFinite(value.lat) && Number.isFinite(value.lng);
1116
+ };
1101
1117
  const vec2lnglat = ([lng, lat]) => ({
1102
1118
  lng: Number(lng),
1103
1119
  lat: Number(lat)
@@ -1214,8 +1230,8 @@ const wxGetLocationSuccessResponse2GeolocationPosition = (res) => {
1214
1230
  return { timestamp, coords };
1215
1231
  };
1216
1232
  const deepCompareEqualsForMaps = createComparator((deepEqual) => (a, b) => {
1217
- if (isLatLngLiteral(a) || isLatLngLiteral(b)) {
1218
- return new google.maps.LatLng(a).equals(new google.maps.LatLng(b));
1233
+ if (isLatLngLiteral(a) && isLatLngLiteral(b)) {
1234
+ return isPlaceEqual(a, b);
1219
1235
  }
1220
1236
  return deepEqual(a, b);
1221
1237
  });
@@ -3557,20 +3573,6 @@ const watchVisibilityState = () => {
3557
3573
  document.addEventListener("visibilitychange", handleVisibilityChange);
3558
3574
  return { visibilityStateRef, unwatchVisibilityState };
3559
3575
  };
3560
- const isPlace = (place) => {
3561
- return place.lng !== void 0 && place.lat !== void 0;
3562
- };
3563
- const sleep = (milliSeconds) => new Promise((resolve) => setTimeout(resolve, milliSeconds));
3564
- const assertPoint = (point) => {
3565
- if (Array.isArray(point) && point.length === 2 && typeof point[0] === "number" && typeof point[1] === "number")
3566
- return;
3567
- throw new Error(`Assertion Error: expect type [number, number], actual is ${point}`);
3568
- };
3569
- const assertAngle = (angle) => {
3570
- if (typeof angle === "number" || typeof angle === "undefined")
3571
- return;
3572
- throw new Error(`Assertion Error: expect type number | undefined, actual is ${angle}`);
3573
- };
3574
3576
  const WX_GET_LOCATION_INTERVAL_STILL = 10 * 1e3;
3575
3577
  const WX_GET_LOCATION_INTERVAL_SLOW = 3 * 1e3;
3576
3578
  const WX_GET_LOCATION_INTERVAL_FAST = 1 * 1e3;
@@ -5758,53 +5760,6 @@ const useMapRecomendPlace = (props) => {
5758
5760
  const { supplier } = useMapSupplier();
5759
5761
  return supplier === "gmap" ? useGmapRecomendPlace(props) : useAmapRecomendPlace(props);
5760
5762
  };
5761
- const GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT = 50;
5762
- const DEFAULT_ZOOM$1 = 13;
5763
- const useAmapZoom = (props) => {
5764
- var _a, _b, _c;
5765
- const { onChange, mapRef, defaultValue } = props;
5766
- const zoomRef = Vue.ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
5767
- const setZoom = (v) => {
5768
- var _a2;
5769
- zoomRef.value = v;
5770
- (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v, true);
5771
- };
5772
- const handleZoomEnd = (_, { target }) => {
5773
- const zoom = target.getZoom();
5774
- zoomRef.value = zoom;
5775
- onChange == null ? void 0 : onChange(zoom);
5776
- };
5777
- watchPostEffectForAMapEvent(mapRef, {}, handleZoomEnd, [
5778
- "onZoomEnd"
5779
- ]);
5780
- return { zoomRef, setZoom };
5781
- };
5782
- const useGmapZoom = (props) => {
5783
- var _a, _b, _c;
5784
- const { onChange, mapRef, defaultValue } = props;
5785
- const zoomRef = Vue.ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
5786
- const setZoom = (v) => {
5787
- var _a2;
5788
- zoomRef.value = v;
5789
- (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v);
5790
- };
5791
- const handleZoomChange = debounce(
5792
- (_, { target }) => {
5793
- const zoom = target.getZoom();
5794
- zoomRef.value = zoom;
5795
- onChange == null ? void 0 : onChange(zoom);
5796
- },
5797
- GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT
5798
- );
5799
- watchPostEffectForGMapEvent(mapRef, {}, handleZoomChange, [
5800
- "onZoom_changed"
5801
- ]);
5802
- return { zoomRef, setZoom };
5803
- };
5804
- const useMapZoom = (props) => {
5805
- const { supplier } = useMapSupplier();
5806
- return supplier === "gmap" ? useGmapZoom(props) : useAmapZoom(props);
5807
- };
5808
5763
  const AmapPolygon = defineSetup(function AmapPolygon2(props) {
5809
5764
  const polygonRef = Vue.shallowRef();
5810
5765
  const mapRef = useAmap();
@@ -6067,51 +6022,220 @@ const ConditionalFittablePassengerCircle = defineSetup(function ConditionalFitta
6067
6022
  })]);
6068
6023
  };
6069
6024
  });
6025
+ const GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT = 50;
6026
+ const DEFAULT_ZOOM$1 = 13;
6027
+ const useAmapZoom = (props) => {
6028
+ var _a, _b, _c;
6029
+ const { onChange, mapRef, defaultValue } = props;
6030
+ const zoomRef = Vue.ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
6031
+ const setZoom = (v) => {
6032
+ var _a2;
6033
+ zoomRef.value = v;
6034
+ (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v, true);
6035
+ };
6036
+ const handleZoomEnd = (_, { target }) => {
6037
+ const zoom = target.getZoom();
6038
+ zoomRef.value = zoom;
6039
+ onChange == null ? void 0 : onChange(zoom);
6040
+ };
6041
+ Vue.watch(
6042
+ () => mapRef.value,
6043
+ (map) => {
6044
+ if (!map)
6045
+ return;
6046
+ zoomRef.value = map.getZoom();
6047
+ }
6048
+ );
6049
+ watchPostEffectForAMapEvent(mapRef, {}, handleZoomEnd, [
6050
+ "onZoomEnd"
6051
+ ]);
6052
+ return { zoomRef, setZoom };
6053
+ };
6054
+ const useGmapZoom = (props) => {
6055
+ var _a, _b, _c;
6056
+ const { onChange, mapRef, defaultValue } = props;
6057
+ const zoomRef = Vue.ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
6058
+ const setZoom = (v) => {
6059
+ var _a2;
6060
+ zoomRef.value = v;
6061
+ (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v);
6062
+ };
6063
+ const handleZoomChange = debounce(
6064
+ (_, { target }) => {
6065
+ const zoom = target.getZoom();
6066
+ zoomRef.value = zoom;
6067
+ onChange == null ? void 0 : onChange(zoom);
6068
+ },
6069
+ GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT
6070
+ );
6071
+ Vue.watch(
6072
+ () => mapRef.value,
6073
+ (map) => {
6074
+ if (!map)
6075
+ return;
6076
+ zoomRef.value = map.getZoom();
6077
+ }
6078
+ );
6079
+ watchPostEffectForGMapEvent(mapRef, {}, handleZoomChange, [
6080
+ "onZoom_changed"
6081
+ ]);
6082
+ return { zoomRef, setZoom };
6083
+ };
6084
+ const useMapZoom = (props) => {
6085
+ const { supplier } = useMapSupplier();
6086
+ return supplier === "gmap" ? useGmapZoom(props) : useAmapZoom(props);
6087
+ };
6070
6088
  const reverse = (direction) => direction === "left" ? "right" : "left";
6071
6089
  const usePointsLabelDirection = (props) => {
6072
6090
  const { widthLimit, heightLimit } = props;
6073
6091
  const mapRef = useMap();
6074
6092
  const { apiMapLngLatToVw } = useMapLngLatToVw({ mapRef });
6093
+ const { zoomRef } = useMapZoom({ mapRef });
6075
6094
  const diffVw = (from, to) => {
6076
6095
  const [x1, y1] = apiMapLngLatToVw(from);
6077
6096
  const [x2, y2] = apiMapLngLatToVw(to);
6078
6097
  return [x2 - x1, y2 - y1];
6079
6098
  };
6080
- const directionsRef = Vue.ref(Array(props.places.length).fill("right"));
6099
+ const directionsRef = Vue.ref([]);
6100
+ const labeledPlacesRef = Vue.ref([]);
6101
+ const isContainBasePlaceRef = Vue.ref(false);
6081
6102
  watchEffectForDeepOption(
6082
- () => props.places.map(place2point),
6083
- (points) => {
6084
- const sortedPoints = points.map((point, index) => ({ point, index })).sort(
6085
- ({ point: [, lat1] }, { point: [, lat2] }) => lat1 < lat2 ? 1 : lat1 > lat2 ? -1 : 0
6103
+ () => [[...props.places], { ...props.basePlace }, zoomRef.value],
6104
+ ([places, basePlace]) => {
6105
+ const placesExcludeBase = places.filter((place) => !isPlaceEqual(place, basePlace));
6106
+ isContainBasePlaceRef.value = placesExcludeBase.length < places.length;
6107
+ const sortedPlaces = placesExcludeBase.sort(
6108
+ ({ lat: lat1 }, { lat: lat2 }) => lat1 < lat2 ? 1 : lat1 > lat2 ? -1 : 0
6086
6109
  );
6087
- const len = points.length;
6088
- const result = Array(len);
6089
- let prevDirection = "right";
6090
- let isLimited = false;
6091
- for (let idx = 0; idx < len; idx++) {
6092
- const { index } = sortedPoints[idx];
6093
- if (idx === len - 1) {
6094
- result[index] = isLimited ? reverse(prevDirection) : "right";
6095
- continue;
6096
- }
6097
- if (idx === 0) {
6098
- const [dx2, dy2] = diffVw(sortedPoints[idx].point, sortedPoints[idx + 1].point);
6099
- isLimited = dx2 > -widthLimit && dx2 < widthLimit && dy2 > -heightLimit && dy2 < heightLimit;
6100
- const direction2 = !isLimited ? "right" : dx2 > 0 ? "left" : "right";
6101
- result[index] = direction2;
6102
- prevDirection = direction2;
6103
- continue;
6104
- }
6105
- const [dx, dy] = diffVw(sortedPoints[idx].point, sortedPoints[idx + 1].point);
6106
- const direction = isLimited ? reverse(prevDirection) : "right";
6107
- result[index] = direction;
6108
- prevDirection = direction;
6109
- isLimited = dx > -widthLimit && dx < widthLimit && dy > -heightLimit && dy < heightLimit;
6110
- }
6111
- directionsRef.value = result;
6110
+ const noOverlapPlaces = filterNoOverlapPlaces({
6111
+ basePlace,
6112
+ sortedPlaces,
6113
+ widthLimit,
6114
+ heightLimit,
6115
+ distanceFn: diffVw
6116
+ });
6117
+ const directions = createLabelDirections({
6118
+ sortedPoints: sortedPlaces.map(place2point),
6119
+ widthLimit,
6120
+ heightLimit,
6121
+ distanceFn: diffVw
6122
+ });
6123
+ directionsRef.value = directions;
6124
+ labeledPlacesRef.value = noOverlapPlaces;
6112
6125
  }
6113
6126
  );
6114
- return directionsRef;
6127
+ return { directionsRef, labeledPlacesRef, isContainBasePlaceRef };
6128
+ };
6129
+ function createLabelDirections(props) {
6130
+ const { sortedPoints, widthLimit, heightLimit, distanceFn } = props;
6131
+ const len = sortedPoints.length;
6132
+ const result = [];
6133
+ const calcDirection = (isLimited2, isDoubleLimited2, prevDx2, prevDirection2) => {
6134
+ if (isLimited2)
6135
+ return reverse(prevDirection2);
6136
+ if (isDoubleLimited2 && prevDx2 < 0 && prevDirection2 === "left")
6137
+ return "left";
6138
+ return "right";
6139
+ };
6140
+ let prevDirection = "right";
6141
+ let isLimited = false;
6142
+ let isDoubleLimited = false;
6143
+ let prevDx = Infinity;
6144
+ for (let idx = 0; idx < len; idx++) {
6145
+ if (idx === len - 1) {
6146
+ const direction2 = calcDirection(isLimited, isDoubleLimited, prevDx, prevDirection);
6147
+ result.push(direction2);
6148
+ continue;
6149
+ }
6150
+ if (idx === 0) {
6151
+ const [dx2, dy2] = distanceFn(sortedPoints[idx], sortedPoints[idx + 1]);
6152
+ isLimited = dx2 > -widthLimit && dx2 < widthLimit && dy2 > -heightLimit && dy2 < heightLimit;
6153
+ isDoubleLimited = dx2 > -widthLimit * 2 && dx2 < widthLimit * 2 && dy2 > -heightLimit && dy2 < heightLimit;
6154
+ const direction2 = !isLimited ? "right" : dx2 > 0 ? "left" : "right";
6155
+ result.push(direction2);
6156
+ prevDirection = direction2;
6157
+ prevDx = dx2;
6158
+ continue;
6159
+ }
6160
+ const [dx, dy] = distanceFn(sortedPoints[idx], sortedPoints[idx + 1]);
6161
+ const direction = calcDirection(isLimited, isDoubleLimited, prevDx, prevDirection);
6162
+ result.push(direction);
6163
+ prevDirection = direction;
6164
+ prevDx = dx;
6165
+ isLimited = dx > -widthLimit && dx < widthLimit && dy > -heightLimit && dy < heightLimit;
6166
+ isDoubleLimited = dx > -widthLimit * 2 && dx < widthLimit * 2 && dy > -heightLimit && dy < heightLimit;
6167
+ }
6168
+ return result;
6169
+ }
6170
+ function filterNoOverlapPlaces(props) {
6171
+ const { basePlace, sortedPlaces, widthLimit, heightLimit, distanceFn } = props;
6172
+ const measureOverlap = (place1, place2) => {
6173
+ const [dx, dy] = distanceFn(place2point(place1), place2point(place2));
6174
+ const isOverlap = dx > -widthLimit && dx < widthLimit && dy > -heightLimit && dy < heightLimit;
6175
+ spaceLog(
6176
+ "usePointsLabelDirection",
6177
+ "p1, p2, dx, dy, isOverlap = ",
6178
+ place1.displayName,
6179
+ place2.displayName,
6180
+ dx,
6181
+ dy,
6182
+ isOverlap
6183
+ );
6184
+ return isOverlap;
6185
+ };
6186
+ let nextPlaces = sortedPlaces;
6187
+ let overlapPlaces = findRelation(nextPlaces, measureOverlap);
6188
+ while (overlapPlaces.length > 0) {
6189
+ const maxPlace = findMax(overlapPlaces, (place) => {
6190
+ const [dx, dy] = distanceFn(place2point(place), place2point(basePlace));
6191
+ return dx * dx + dy * dy;
6192
+ });
6193
+ nextPlaces = nextPlaces.filter((place) => !isPlaceEqual(maxPlace, place));
6194
+ overlapPlaces = findRelation(nextPlaces, measureOverlap);
6195
+ }
6196
+ return nextPlaces;
6197
+ }
6198
+ const findRelation = (places, measureRelate) => {
6199
+ let isPrevRelated = false;
6200
+ let isNextRelated = false;
6201
+ let isFound = false;
6202
+ const result = [];
6203
+ for (const [idx, place] of places.slice(0, -1).entries()) {
6204
+ isNextRelated = measureRelate(place, places[idx + 1]);
6205
+ if (!isPrevRelated) {
6206
+ isPrevRelated = isNextRelated;
6207
+ continue;
6208
+ }
6209
+ if (!isNextRelated) {
6210
+ if (isFound) {
6211
+ result.push(place);
6212
+ result.push(places[idx + 1]);
6213
+ return result;
6214
+ }
6215
+ isPrevRelated = isNextRelated;
6216
+ continue;
6217
+ }
6218
+ if (!isFound)
6219
+ result.push(places[idx - 1]);
6220
+ if (idx === places.length - 2)
6221
+ result.push(places[idx + 1]);
6222
+ result.push(place);
6223
+ isPrevRelated = isNextRelated;
6224
+ isFound = true;
6225
+ }
6226
+ return result;
6227
+ };
6228
+ const findMax = (list, measure) => {
6229
+ let max = -Infinity;
6230
+ let index = 0;
6231
+ for (const [idx, item] of list.entries()) {
6232
+ const value = measure(item);
6233
+ if (value <= max)
6234
+ continue;
6235
+ max = value;
6236
+ index = idx;
6237
+ }
6238
+ return list[index];
6115
6239
  };
6116
6240
  var AnchorType = /* @__PURE__ */ ((AnchorType2) => {
6117
6241
  AnchorType2["topLeft"] = "top-left";
@@ -6133,25 +6257,23 @@ var labelLayout = "fhyw8b";
6133
6257
  var labelStroke = "fhyw8d fhyw8c";
6134
6258
  var placeCircleLayout = createRuntimeFn({ defaultClassName: "fhyw80", variantClassNames: { textAlign: { left: "fhyw81", right: "fhyw82" } }, defaultVariants: {}, compoundVariants: [] });
6135
6259
  var placeIcon = createRuntimeFn({ defaultClassName: "fhyw88", variantClassNames: { hideIcon: { true: "fhyw89", false: "fhyw8a" } }, defaultVariants: {}, compoundVariants: [] });
6260
+ const DEFAULT_TEXT_ALIGN = "right";
6136
6261
  const APlaceCircle = defineSetup(function APlaceCircle2(props, {
6137
6262
  emit
6138
6263
  }) {
6139
- const textAlignRef = Vue.computed(() => {
6140
- var _a;
6141
- return (_a = props.textAlign) != null ? _a : "right";
6142
- });
6143
6264
  const contentRef = Vue.computed(() => {
6144
6265
  const {
6145
- hideIcon = false
6266
+ hideIcon = false,
6267
+ textAlign = DEFAULT_TEXT_ALIGN
6146
6268
  } = props;
6147
6269
  return `
6148
6270
  <div class="APlaceCircle ${placeCircleLayout({
6149
- textAlign: textAlignRef.value
6271
+ textAlign
6150
6272
  })}">
6151
6273
  <img class="${placeIcon({
6152
6274
  hideIcon
6153
6275
  })} ${amapPlaceIconLayout({
6154
- textAlign: textAlignRef.value
6276
+ textAlign
6155
6277
  })}" src="${imgPlaceCircle}">
6156
6278
  <div class="${labelLayout}">
6157
6279
  <div class="${labelStroke}">${props.label}</div>
@@ -6162,23 +6284,27 @@ const APlaceCircle = defineSetup(function APlaceCircle2(props, {
6162
6284
  });
6163
6285
  const contentWithoutLabelRef = Vue.computed(() => {
6164
6286
  const {
6165
- hideIcon = false
6287
+ hideIcon = false,
6288
+ textAlign = DEFAULT_TEXT_ALIGN
6166
6289
  } = props;
6167
6290
  return `<img class="APlaceCircle ${placeIcon({
6168
6291
  hideIcon
6169
6292
  })} ${amapPlaceIconLayout({
6170
- textAlign: textAlignRef.value
6293
+ textAlign
6171
6294
  })}" src="${imgPlaceCircle}">`;
6172
6295
  });
6173
6296
  const handleClick = () => {
6174
6297
  emit("click", props.position);
6175
6298
  };
6176
6299
  return () => {
6300
+ const {
6301
+ textAlign = DEFAULT_TEXT_ALIGN
6302
+ } = props;
6177
6303
  return Vue.h(AmapMarker, {
6178
6304
  "attrs": {
6179
6305
  "position": props.position,
6180
6306
  "content": props.label ? contentRef.value : contentWithoutLabelRef.value,
6181
- "anchor": textAlignRef.value === "left" ? AnchorType.middleRight : AnchorType.middleLeft,
6307
+ "anchor": textAlign === "left" ? AnchorType.middleRight : AnchorType.middleLeft,
6182
6308
  "zIndex": ZINDEX_PLACE_LAYER
6183
6309
  },
6184
6310
  "on": {
@@ -6190,19 +6316,16 @@ const APlaceCircle = defineSetup(function APlaceCircle2(props, {
6190
6316
  const GPlaceCircle = defineSetup(function GPlaceCircle2(props, {
6191
6317
  emit
6192
6318
  }) {
6193
- const textAlignRef = Vue.computed(() => {
6194
- var _a;
6195
- return (_a = props.textAlign) != null ? _a : "right";
6196
- });
6197
6319
  const contentRef = Vue.computed(() => {
6198
6320
  const {
6199
- hideIcon = false
6321
+ hideIcon = false,
6322
+ textAlign = DEFAULT_TEXT_ALIGN
6200
6323
  } = props;
6201
6324
  return createDom("div", {
6202
6325
  class: `GPlaceCircle ${placeCircleLayout({
6203
- textAlign: textAlignRef.value
6326
+ textAlign
6204
6327
  })} ${gmapPlaceIconLayout({
6205
- textAlign: textAlignRef.value
6328
+ textAlign
6206
6329
  })}`
6207
6330
  }, `
6208
6331
  <img class="${placeIcon({
@@ -6216,13 +6339,14 @@ const GPlaceCircle = defineSetup(function GPlaceCircle2(props, {
6216
6339
  });
6217
6340
  const contentWithoutLabelRef = Vue.computed(() => {
6218
6341
  const {
6219
- hideIcon = false
6342
+ hideIcon = false,
6343
+ textAlign = DEFAULT_TEXT_ALIGN
6220
6344
  } = props;
6221
6345
  return createDom("img", {
6222
6346
  class: `GPlaceCircle ${placeIcon({
6223
6347
  hideIcon
6224
6348
  })} ${gmapPlaceIconLayout({
6225
- textAlign: textAlignRef.value
6349
+ textAlign
6226
6350
  })}`,
6227
6351
  src: imgPlaceCircle
6228
6352
  });
@@ -6257,18 +6381,31 @@ const PlaceCircle = defineSetup(function PlaceCircle2(props, {
6257
6381
  const PickupPoints = defineSetup(function PickupPoints2(props, {
6258
6382
  emit
6259
6383
  }) {
6384
+ const mapRef = useMap();
6260
6385
  const {
6261
- renderLabel
6262
- } = props;
6263
- const directions = usePointsLabelDirection(Vue.reactive({
6386
+ zoomRef
6387
+ } = useMapZoom({
6388
+ mapRef
6389
+ });
6390
+ const {
6391
+ directionsRef,
6392
+ labeledPlacesRef,
6393
+ isContainBasePlaceRef
6394
+ } = usePointsLabelDirection(Vue.reactive({
6395
+ basePlace: Vue.toRef(props, "basePlace"),
6264
6396
  places: Vue.toRef(props, "places"),
6265
6397
  heightLimit: 9,
6266
- widthLimit: 32
6398
+ widthLimit: 34
6267
6399
  }));
6268
6400
  return () => {
6269
- return Vue.h("div", [props.places.map((place, idx) => {
6270
- const direction = directions.value[idx];
6271
- const label2 = renderLabel ? renderLabel(place) : place.displayName;
6401
+ const {
6402
+ basePlace,
6403
+ zoomIconMin,
6404
+ zoomTextMin
6405
+ } = props;
6406
+ return Vue.h("div", [zoomRef.value >= zoomIconMin && labeledPlacesRef.value.map((place, idx) => {
6407
+ const direction = directionsRef.value[idx];
6408
+ const label2 = zoomRef.value < zoomTextMin ? void 0 : place.displayName;
6272
6409
  return Vue.h(PlaceCircle, {
6273
6410
  "attrs": {
6274
6411
  "position": place2point(place),
@@ -6279,12 +6416,17 @@ const PickupPoints = defineSetup(function PickupPoints2(props, {
6279
6416
  "click": () => emit("click", place)
6280
6417
  }
6281
6418
  });
6419
+ }), isContainBasePlaceRef.value && Vue.h(PlaceCircle, {
6420
+ "attrs": {
6421
+ "position": place2point(basePlace)
6422
+ }
6282
6423
  })]);
6283
6424
  };
6284
6425
  });
6285
6426
  const RECOMMEND_PLACE_DRAG_LIMIT = 10;
6286
6427
  const RECOMMEND_PLACE_LARGE_LIMIT = 100;
6287
- const RECOMMEND_PLACE_ZOOM_MIN = 13;
6428
+ const RECOMMEND_PLACE_ICON_ZOOM_MIN = 15.75;
6429
+ const RECOMMEND_PLACE_TEXT_ZOOM_MIN = 16.75;
6288
6430
  const DEFAULT_PLACE_NAME = "当前位置";
6289
6431
  const DEFAULT_ZOOM = 17;
6290
6432
  const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlaceMap2(props, {
@@ -6309,12 +6451,6 @@ const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlac
6309
6451
  const {
6310
6452
  readyPromise
6311
6453
  } = useMapSupplier();
6312
- const {
6313
- zoomRef
6314
- } = useMapZoom({
6315
- mapRef,
6316
- defaultValue: DEFAULT_ZOOM
6317
- });
6318
6454
  const centerPlace = Vue.reactive({
6319
6455
  lng: (_a = geoDefaultPosition == null ? void 0 : geoDefaultPosition[0]) != null ? _a : 0,
6320
6456
  lat: (_b = geoDefaultPosition == null ? void 0 : geoDefaultPosition[1]) != null ? _b : 0,
@@ -6491,13 +6627,12 @@ const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlac
6491
6627
  recomendDescription,
6492
6628
  unavailableTitle
6493
6629
  } = props;
6494
- console.log("centerPlace = ", JSON.stringify(centerPlace));
6495
6630
  const title = geoLoading.value ? geoLoadingTitle2 : !availableRef.value ? unavailableTitle : centerPlace.displayName;
6496
6631
  const description = !availableRef.value ? void 0 : isElectedRef.value ? recomendDescription : void 0;
6497
6632
  return Vue.h(HeycarMap, {
6498
6633
  "attrs": {
6499
6634
  "center": centerPoint.value,
6500
- "zoom": zoomRef.value,
6635
+ "zoom": DEFAULT_ZOOM,
6501
6636
  "touchZoomCenter": true,
6502
6637
  "mapRef": setMap,
6503
6638
  "fallback": slots.fallback,
@@ -6512,10 +6647,12 @@ const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlac
6512
6647
  "position": geoPosition.value,
6513
6648
  "angle": orientation.cssRotationVariableName
6514
6649
  }
6515
- }), zoomRef.value >= RECOMMEND_PLACE_ZOOM_MIN && Vue.h(PickupPoints, {
6650
+ }), Vue.h(PickupPoints, {
6516
6651
  "attrs": {
6652
+ "basePlace": centerPlace,
6517
6653
  "places": placeCandidates.value,
6518
- "renderLabel": (place) => isPlaceEqual(place, centerPlace) ? void 0 : place.displayName
6654
+ "zoomIconMin": RECOMMEND_PLACE_ICON_ZOOM_MIN,
6655
+ "zoomTextMin": RECOMMEND_PLACE_TEXT_ZOOM_MIN
6519
6656
  },
6520
6657
  "on": {
6521
6658
  "click": panToCenterByPlace
@@ -6557,12 +6694,6 @@ const BusinessReselectPlaceMap = defineLagecySetup(function BusinessReselectPlac
6557
6694
  setMap,
6558
6695
  panTo
6559
6696
  } = useHeycarMap();
6560
- const {
6561
- zoomRef
6562
- } = useMapZoom({
6563
- mapRef,
6564
- defaultValue: DEFAULT_ZOOM
6565
- });
6566
6697
  const centerPlace = Vue.reactive({
6567
6698
  lng: defaultPlace.lng,
6568
6699
  lat: defaultPlace.lat,
@@ -6726,7 +6857,7 @@ const BusinessReselectPlaceMap = defineLagecySetup(function BusinessReselectPlac
6726
6857
  return Vue.h(HeycarMap, {
6727
6858
  "attrs": {
6728
6859
  "center": centerPoint.value,
6729
- "zoom": zoomRef.value,
6860
+ "zoom": DEFAULT_ZOOM,
6730
6861
  "touchZoomCenter": true,
6731
6862
  "mapRef": setMap,
6732
6863
  "fallback": slots.fallback,
@@ -6741,10 +6872,12 @@ const BusinessReselectPlaceMap = defineLagecySetup(function BusinessReselectPlac
6741
6872
  "position": geoPosition.value,
6742
6873
  "angle": orientation.cssRotationVariableName
6743
6874
  }
6744
- }), zoomRef.value >= RECOMMEND_PLACE_ZOOM_MIN && Vue.h(PickupPoints, {
6875
+ }), Vue.h(PickupPoints, {
6745
6876
  "attrs": {
6877
+ "basePlace": centerPlace,
6746
6878
  "places": placeCandidates.value,
6747
- "renderLabel": (place) => isPlaceEqual(place, centerPlace) ? void 0 : place.displayName
6879
+ "zoomIconMin": RECOMMEND_PLACE_ICON_ZOOM_MIN,
6880
+ "zoomTextMin": RECOMMEND_PLACE_TEXT_ZOOM_MIN
6748
6881
  },
6749
6882
  "on": {
6750
6883
  "click": panToCenterByPlace
@@ -7916,7 +8049,6 @@ const useBusinessTaxiServiceMap = () => {
7916
8049
  const { mapRef, setMap } = useHeycarMap();
7917
8050
  const { registerFitVeiw, setFitView } = useMapFitView({
7918
8051
  mapRef,
7919
- autoFitTimeout: 5e3,
7920
8052
  padding: [19, 36, 19, 26]
7921
8053
  });
7922
8054
  return { setMap, registerFitVeiw, setFitView };
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ var __publicField = (obj, key, value) => {
7
7
  import Vue, { defineComponent, h, computed, inject, provide, watch, onMounted, onUnmounted, watchPostEffect, shallowRef, ref, watchEffect, reactive, toRefs, toRef } from "vue";
8
8
  const style = "";
9
9
  const name = "@heycar/heycars-map";
10
- const version = "0.8.3";
10
+ const version = "0.8.5";
11
11
  const type = "module";
12
12
  const scripts = {
13
13
  dev: "vite -c vite.config.dev.ts",
@@ -855,7 +855,6 @@ const useMapOverlay = (props) => {
855
855
  registerOverlay == null ? void 0 : registerOverlay.remove(overlay);
856
856
  });
857
857
  };
858
- const isLatLngLiteral = (obj) => obj != null && typeof obj === "object" && Number.isFinite(obj.lat) && Number.isFinite(obj.lng);
859
858
  var HAS_WEAK_MAP_SUPPORT = typeof WeakMap === "function";
860
859
  var keys = Object.keys;
861
860
  function sameValueZeroEqual(a, b) {
@@ -1096,6 +1095,23 @@ createComparator(function() {
1096
1095
  });
1097
1096
  createComparator(createCircularEqualCreator());
1098
1097
  createComparator(createCircularEqualCreator(sameValueZeroEqual));
1098
+ const isPlace = (place) => {
1099
+ return place.lng !== void 0 && place.lat !== void 0;
1100
+ };
1101
+ const sleep = (milliSeconds) => new Promise((resolve) => setTimeout(resolve, milliSeconds));
1102
+ const assertPoint = (point) => {
1103
+ if (Array.isArray(point) && point.length === 2 && typeof point[0] === "number" && typeof point[1] === "number")
1104
+ return;
1105
+ throw new Error(`Assertion Error: expect type [number, number], actual is ${point}`);
1106
+ };
1107
+ const assertAngle = (angle) => {
1108
+ if (typeof angle === "number" || typeof angle === "undefined")
1109
+ return;
1110
+ throw new Error(`Assertion Error: expect type number | undefined, actual is ${angle}`);
1111
+ };
1112
+ const isLatLngLiteral = (value) => {
1113
+ return value != null && typeof value === "object" && Number.isFinite(value.lat) && Number.isFinite(value.lng);
1114
+ };
1099
1115
  const vec2lnglat = ([lng, lat]) => ({
1100
1116
  lng: Number(lng),
1101
1117
  lat: Number(lat)
@@ -1212,8 +1228,8 @@ const wxGetLocationSuccessResponse2GeolocationPosition = (res) => {
1212
1228
  return { timestamp, coords };
1213
1229
  };
1214
1230
  const deepCompareEqualsForMaps = createComparator((deepEqual) => (a, b) => {
1215
- if (isLatLngLiteral(a) || isLatLngLiteral(b)) {
1216
- return new google.maps.LatLng(a).equals(new google.maps.LatLng(b));
1231
+ if (isLatLngLiteral(a) && isLatLngLiteral(b)) {
1232
+ return isPlaceEqual(a, b);
1217
1233
  }
1218
1234
  return deepEqual(a, b);
1219
1235
  });
@@ -3555,20 +3571,6 @@ const watchVisibilityState = () => {
3555
3571
  document.addEventListener("visibilitychange", handleVisibilityChange);
3556
3572
  return { visibilityStateRef, unwatchVisibilityState };
3557
3573
  };
3558
- const isPlace = (place) => {
3559
- return place.lng !== void 0 && place.lat !== void 0;
3560
- };
3561
- const sleep = (milliSeconds) => new Promise((resolve) => setTimeout(resolve, milliSeconds));
3562
- const assertPoint = (point) => {
3563
- if (Array.isArray(point) && point.length === 2 && typeof point[0] === "number" && typeof point[1] === "number")
3564
- return;
3565
- throw new Error(`Assertion Error: expect type [number, number], actual is ${point}`);
3566
- };
3567
- const assertAngle = (angle) => {
3568
- if (typeof angle === "number" || typeof angle === "undefined")
3569
- return;
3570
- throw new Error(`Assertion Error: expect type number | undefined, actual is ${angle}`);
3571
- };
3572
3574
  const WX_GET_LOCATION_INTERVAL_STILL = 10 * 1e3;
3573
3575
  const WX_GET_LOCATION_INTERVAL_SLOW = 3 * 1e3;
3574
3576
  const WX_GET_LOCATION_INTERVAL_FAST = 1 * 1e3;
@@ -5756,53 +5758,6 @@ const useMapRecomendPlace = (props) => {
5756
5758
  const { supplier } = useMapSupplier();
5757
5759
  return supplier === "gmap" ? useGmapRecomendPlace(props) : useAmapRecomendPlace(props);
5758
5760
  };
5759
- const GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT = 50;
5760
- const DEFAULT_ZOOM$1 = 13;
5761
- const useAmapZoom = (props) => {
5762
- var _a, _b, _c;
5763
- const { onChange, mapRef, defaultValue } = props;
5764
- const zoomRef = ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
5765
- const setZoom = (v) => {
5766
- var _a2;
5767
- zoomRef.value = v;
5768
- (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v, true);
5769
- };
5770
- const handleZoomEnd = (_, { target }) => {
5771
- const zoom = target.getZoom();
5772
- zoomRef.value = zoom;
5773
- onChange == null ? void 0 : onChange(zoom);
5774
- };
5775
- watchPostEffectForAMapEvent(mapRef, {}, handleZoomEnd, [
5776
- "onZoomEnd"
5777
- ]);
5778
- return { zoomRef, setZoom };
5779
- };
5780
- const useGmapZoom = (props) => {
5781
- var _a, _b, _c;
5782
- const { onChange, mapRef, defaultValue } = props;
5783
- const zoomRef = ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
5784
- const setZoom = (v) => {
5785
- var _a2;
5786
- zoomRef.value = v;
5787
- (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v);
5788
- };
5789
- const handleZoomChange = debounce(
5790
- (_, { target }) => {
5791
- const zoom = target.getZoom();
5792
- zoomRef.value = zoom;
5793
- onChange == null ? void 0 : onChange(zoom);
5794
- },
5795
- GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT
5796
- );
5797
- watchPostEffectForGMapEvent(mapRef, {}, handleZoomChange, [
5798
- "onZoom_changed"
5799
- ]);
5800
- return { zoomRef, setZoom };
5801
- };
5802
- const useMapZoom = (props) => {
5803
- const { supplier } = useMapSupplier();
5804
- return supplier === "gmap" ? useGmapZoom(props) : useAmapZoom(props);
5805
- };
5806
5761
  const AmapPolygon = defineSetup(function AmapPolygon2(props) {
5807
5762
  const polygonRef = shallowRef();
5808
5763
  const mapRef = useAmap();
@@ -6065,51 +6020,220 @@ const ConditionalFittablePassengerCircle = defineSetup(function ConditionalFitta
6065
6020
  })]);
6066
6021
  };
6067
6022
  });
6023
+ const GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT = 50;
6024
+ const DEFAULT_ZOOM$1 = 13;
6025
+ const useAmapZoom = (props) => {
6026
+ var _a, _b, _c;
6027
+ const { onChange, mapRef, defaultValue } = props;
6028
+ const zoomRef = ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
6029
+ const setZoom = (v) => {
6030
+ var _a2;
6031
+ zoomRef.value = v;
6032
+ (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v, true);
6033
+ };
6034
+ const handleZoomEnd = (_, { target }) => {
6035
+ const zoom = target.getZoom();
6036
+ zoomRef.value = zoom;
6037
+ onChange == null ? void 0 : onChange(zoom);
6038
+ };
6039
+ watch(
6040
+ () => mapRef.value,
6041
+ (map) => {
6042
+ if (!map)
6043
+ return;
6044
+ zoomRef.value = map.getZoom();
6045
+ }
6046
+ );
6047
+ watchPostEffectForAMapEvent(mapRef, {}, handleZoomEnd, [
6048
+ "onZoomEnd"
6049
+ ]);
6050
+ return { zoomRef, setZoom };
6051
+ };
6052
+ const useGmapZoom = (props) => {
6053
+ var _a, _b, _c;
6054
+ const { onChange, mapRef, defaultValue } = props;
6055
+ const zoomRef = ref((_c = (_b = (_a = mapRef.value) == null ? void 0 : _a.getZoom()) != null ? _b : defaultValue) != null ? _c : DEFAULT_ZOOM$1);
6056
+ const setZoom = (v) => {
6057
+ var _a2;
6058
+ zoomRef.value = v;
6059
+ (_a2 = mapRef.value) == null ? void 0 : _a2.setZoom(v);
6060
+ };
6061
+ const handleZoomChange = debounce(
6062
+ (_, { target }) => {
6063
+ const zoom = target.getZoom();
6064
+ zoomRef.value = zoom;
6065
+ onChange == null ? void 0 : onChange(zoom);
6066
+ },
6067
+ GOOGLE_MAP_ZOOM_CHANGE_DEBOUNCE_TIMEOUT
6068
+ );
6069
+ watch(
6070
+ () => mapRef.value,
6071
+ (map) => {
6072
+ if (!map)
6073
+ return;
6074
+ zoomRef.value = map.getZoom();
6075
+ }
6076
+ );
6077
+ watchPostEffectForGMapEvent(mapRef, {}, handleZoomChange, [
6078
+ "onZoom_changed"
6079
+ ]);
6080
+ return { zoomRef, setZoom };
6081
+ };
6082
+ const useMapZoom = (props) => {
6083
+ const { supplier } = useMapSupplier();
6084
+ return supplier === "gmap" ? useGmapZoom(props) : useAmapZoom(props);
6085
+ };
6068
6086
  const reverse = (direction) => direction === "left" ? "right" : "left";
6069
6087
  const usePointsLabelDirection = (props) => {
6070
6088
  const { widthLimit, heightLimit } = props;
6071
6089
  const mapRef = useMap();
6072
6090
  const { apiMapLngLatToVw } = useMapLngLatToVw({ mapRef });
6091
+ const { zoomRef } = useMapZoom({ mapRef });
6073
6092
  const diffVw = (from, to) => {
6074
6093
  const [x1, y1] = apiMapLngLatToVw(from);
6075
6094
  const [x2, y2] = apiMapLngLatToVw(to);
6076
6095
  return [x2 - x1, y2 - y1];
6077
6096
  };
6078
- const directionsRef = ref(Array(props.places.length).fill("right"));
6097
+ const directionsRef = ref([]);
6098
+ const labeledPlacesRef = ref([]);
6099
+ const isContainBasePlaceRef = ref(false);
6079
6100
  watchEffectForDeepOption(
6080
- () => props.places.map(place2point),
6081
- (points) => {
6082
- const sortedPoints = points.map((point, index) => ({ point, index })).sort(
6083
- ({ point: [, lat1] }, { point: [, lat2] }) => lat1 < lat2 ? 1 : lat1 > lat2 ? -1 : 0
6101
+ () => [[...props.places], { ...props.basePlace }, zoomRef.value],
6102
+ ([places, basePlace]) => {
6103
+ const placesExcludeBase = places.filter((place) => !isPlaceEqual(place, basePlace));
6104
+ isContainBasePlaceRef.value = placesExcludeBase.length < places.length;
6105
+ const sortedPlaces = placesExcludeBase.sort(
6106
+ ({ lat: lat1 }, { lat: lat2 }) => lat1 < lat2 ? 1 : lat1 > lat2 ? -1 : 0
6084
6107
  );
6085
- const len = points.length;
6086
- const result = Array(len);
6087
- let prevDirection = "right";
6088
- let isLimited = false;
6089
- for (let idx = 0; idx < len; idx++) {
6090
- const { index } = sortedPoints[idx];
6091
- if (idx === len - 1) {
6092
- result[index] = isLimited ? reverse(prevDirection) : "right";
6093
- continue;
6094
- }
6095
- if (idx === 0) {
6096
- const [dx2, dy2] = diffVw(sortedPoints[idx].point, sortedPoints[idx + 1].point);
6097
- isLimited = dx2 > -widthLimit && dx2 < widthLimit && dy2 > -heightLimit && dy2 < heightLimit;
6098
- const direction2 = !isLimited ? "right" : dx2 > 0 ? "left" : "right";
6099
- result[index] = direction2;
6100
- prevDirection = direction2;
6101
- continue;
6102
- }
6103
- const [dx, dy] = diffVw(sortedPoints[idx].point, sortedPoints[idx + 1].point);
6104
- const direction = isLimited ? reverse(prevDirection) : "right";
6105
- result[index] = direction;
6106
- prevDirection = direction;
6107
- isLimited = dx > -widthLimit && dx < widthLimit && dy > -heightLimit && dy < heightLimit;
6108
- }
6109
- directionsRef.value = result;
6108
+ const noOverlapPlaces = filterNoOverlapPlaces({
6109
+ basePlace,
6110
+ sortedPlaces,
6111
+ widthLimit,
6112
+ heightLimit,
6113
+ distanceFn: diffVw
6114
+ });
6115
+ const directions = createLabelDirections({
6116
+ sortedPoints: sortedPlaces.map(place2point),
6117
+ widthLimit,
6118
+ heightLimit,
6119
+ distanceFn: diffVw
6120
+ });
6121
+ directionsRef.value = directions;
6122
+ labeledPlacesRef.value = noOverlapPlaces;
6110
6123
  }
6111
6124
  );
6112
- return directionsRef;
6125
+ return { directionsRef, labeledPlacesRef, isContainBasePlaceRef };
6126
+ };
6127
+ function createLabelDirections(props) {
6128
+ const { sortedPoints, widthLimit, heightLimit, distanceFn } = props;
6129
+ const len = sortedPoints.length;
6130
+ const result = [];
6131
+ const calcDirection = (isLimited2, isDoubleLimited2, prevDx2, prevDirection2) => {
6132
+ if (isLimited2)
6133
+ return reverse(prevDirection2);
6134
+ if (isDoubleLimited2 && prevDx2 < 0 && prevDirection2 === "left")
6135
+ return "left";
6136
+ return "right";
6137
+ };
6138
+ let prevDirection = "right";
6139
+ let isLimited = false;
6140
+ let isDoubleLimited = false;
6141
+ let prevDx = Infinity;
6142
+ for (let idx = 0; idx < len; idx++) {
6143
+ if (idx === len - 1) {
6144
+ const direction2 = calcDirection(isLimited, isDoubleLimited, prevDx, prevDirection);
6145
+ result.push(direction2);
6146
+ continue;
6147
+ }
6148
+ if (idx === 0) {
6149
+ const [dx2, dy2] = distanceFn(sortedPoints[idx], sortedPoints[idx + 1]);
6150
+ isLimited = dx2 > -widthLimit && dx2 < widthLimit && dy2 > -heightLimit && dy2 < heightLimit;
6151
+ isDoubleLimited = dx2 > -widthLimit * 2 && dx2 < widthLimit * 2 && dy2 > -heightLimit && dy2 < heightLimit;
6152
+ const direction2 = !isLimited ? "right" : dx2 > 0 ? "left" : "right";
6153
+ result.push(direction2);
6154
+ prevDirection = direction2;
6155
+ prevDx = dx2;
6156
+ continue;
6157
+ }
6158
+ const [dx, dy] = distanceFn(sortedPoints[idx], sortedPoints[idx + 1]);
6159
+ const direction = calcDirection(isLimited, isDoubleLimited, prevDx, prevDirection);
6160
+ result.push(direction);
6161
+ prevDirection = direction;
6162
+ prevDx = dx;
6163
+ isLimited = dx > -widthLimit && dx < widthLimit && dy > -heightLimit && dy < heightLimit;
6164
+ isDoubleLimited = dx > -widthLimit * 2 && dx < widthLimit * 2 && dy > -heightLimit && dy < heightLimit;
6165
+ }
6166
+ return result;
6167
+ }
6168
+ function filterNoOverlapPlaces(props) {
6169
+ const { basePlace, sortedPlaces, widthLimit, heightLimit, distanceFn } = props;
6170
+ const measureOverlap = (place1, place2) => {
6171
+ const [dx, dy] = distanceFn(place2point(place1), place2point(place2));
6172
+ const isOverlap = dx > -widthLimit && dx < widthLimit && dy > -heightLimit && dy < heightLimit;
6173
+ spaceLog(
6174
+ "usePointsLabelDirection",
6175
+ "p1, p2, dx, dy, isOverlap = ",
6176
+ place1.displayName,
6177
+ place2.displayName,
6178
+ dx,
6179
+ dy,
6180
+ isOverlap
6181
+ );
6182
+ return isOverlap;
6183
+ };
6184
+ let nextPlaces = sortedPlaces;
6185
+ let overlapPlaces = findRelation(nextPlaces, measureOverlap);
6186
+ while (overlapPlaces.length > 0) {
6187
+ const maxPlace = findMax(overlapPlaces, (place) => {
6188
+ const [dx, dy] = distanceFn(place2point(place), place2point(basePlace));
6189
+ return dx * dx + dy * dy;
6190
+ });
6191
+ nextPlaces = nextPlaces.filter((place) => !isPlaceEqual(maxPlace, place));
6192
+ overlapPlaces = findRelation(nextPlaces, measureOverlap);
6193
+ }
6194
+ return nextPlaces;
6195
+ }
6196
+ const findRelation = (places, measureRelate) => {
6197
+ let isPrevRelated = false;
6198
+ let isNextRelated = false;
6199
+ let isFound = false;
6200
+ const result = [];
6201
+ for (const [idx, place] of places.slice(0, -1).entries()) {
6202
+ isNextRelated = measureRelate(place, places[idx + 1]);
6203
+ if (!isPrevRelated) {
6204
+ isPrevRelated = isNextRelated;
6205
+ continue;
6206
+ }
6207
+ if (!isNextRelated) {
6208
+ if (isFound) {
6209
+ result.push(place);
6210
+ result.push(places[idx + 1]);
6211
+ return result;
6212
+ }
6213
+ isPrevRelated = isNextRelated;
6214
+ continue;
6215
+ }
6216
+ if (!isFound)
6217
+ result.push(places[idx - 1]);
6218
+ if (idx === places.length - 2)
6219
+ result.push(places[idx + 1]);
6220
+ result.push(place);
6221
+ isPrevRelated = isNextRelated;
6222
+ isFound = true;
6223
+ }
6224
+ return result;
6225
+ };
6226
+ const findMax = (list, measure) => {
6227
+ let max = -Infinity;
6228
+ let index = 0;
6229
+ for (const [idx, item] of list.entries()) {
6230
+ const value = measure(item);
6231
+ if (value <= max)
6232
+ continue;
6233
+ max = value;
6234
+ index = idx;
6235
+ }
6236
+ return list[index];
6113
6237
  };
6114
6238
  var AnchorType = /* @__PURE__ */ ((AnchorType2) => {
6115
6239
  AnchorType2["topLeft"] = "top-left";
@@ -6131,25 +6255,23 @@ var labelLayout = "fhyw8b";
6131
6255
  var labelStroke = "fhyw8d fhyw8c";
6132
6256
  var placeCircleLayout = createRuntimeFn({ defaultClassName: "fhyw80", variantClassNames: { textAlign: { left: "fhyw81", right: "fhyw82" } }, defaultVariants: {}, compoundVariants: [] });
6133
6257
  var placeIcon = createRuntimeFn({ defaultClassName: "fhyw88", variantClassNames: { hideIcon: { true: "fhyw89", false: "fhyw8a" } }, defaultVariants: {}, compoundVariants: [] });
6258
+ const DEFAULT_TEXT_ALIGN = "right";
6134
6259
  const APlaceCircle = defineSetup(function APlaceCircle2(props, {
6135
6260
  emit
6136
6261
  }) {
6137
- const textAlignRef = computed(() => {
6138
- var _a;
6139
- return (_a = props.textAlign) != null ? _a : "right";
6140
- });
6141
6262
  const contentRef = computed(() => {
6142
6263
  const {
6143
- hideIcon = false
6264
+ hideIcon = false,
6265
+ textAlign = DEFAULT_TEXT_ALIGN
6144
6266
  } = props;
6145
6267
  return `
6146
6268
  <div class="APlaceCircle ${placeCircleLayout({
6147
- textAlign: textAlignRef.value
6269
+ textAlign
6148
6270
  })}">
6149
6271
  <img class="${placeIcon({
6150
6272
  hideIcon
6151
6273
  })} ${amapPlaceIconLayout({
6152
- textAlign: textAlignRef.value
6274
+ textAlign
6153
6275
  })}" src="${imgPlaceCircle}">
6154
6276
  <div class="${labelLayout}">
6155
6277
  <div class="${labelStroke}">${props.label}</div>
@@ -6160,23 +6282,27 @@ const APlaceCircle = defineSetup(function APlaceCircle2(props, {
6160
6282
  });
6161
6283
  const contentWithoutLabelRef = computed(() => {
6162
6284
  const {
6163
- hideIcon = false
6285
+ hideIcon = false,
6286
+ textAlign = DEFAULT_TEXT_ALIGN
6164
6287
  } = props;
6165
6288
  return `<img class="APlaceCircle ${placeIcon({
6166
6289
  hideIcon
6167
6290
  })} ${amapPlaceIconLayout({
6168
- textAlign: textAlignRef.value
6291
+ textAlign
6169
6292
  })}" src="${imgPlaceCircle}">`;
6170
6293
  });
6171
6294
  const handleClick = () => {
6172
6295
  emit("click", props.position);
6173
6296
  };
6174
6297
  return () => {
6298
+ const {
6299
+ textAlign = DEFAULT_TEXT_ALIGN
6300
+ } = props;
6175
6301
  return h(AmapMarker, {
6176
6302
  "attrs": {
6177
6303
  "position": props.position,
6178
6304
  "content": props.label ? contentRef.value : contentWithoutLabelRef.value,
6179
- "anchor": textAlignRef.value === "left" ? AnchorType.middleRight : AnchorType.middleLeft,
6305
+ "anchor": textAlign === "left" ? AnchorType.middleRight : AnchorType.middleLeft,
6180
6306
  "zIndex": ZINDEX_PLACE_LAYER
6181
6307
  },
6182
6308
  "on": {
@@ -6188,19 +6314,16 @@ const APlaceCircle = defineSetup(function APlaceCircle2(props, {
6188
6314
  const GPlaceCircle = defineSetup(function GPlaceCircle2(props, {
6189
6315
  emit
6190
6316
  }) {
6191
- const textAlignRef = computed(() => {
6192
- var _a;
6193
- return (_a = props.textAlign) != null ? _a : "right";
6194
- });
6195
6317
  const contentRef = computed(() => {
6196
6318
  const {
6197
- hideIcon = false
6319
+ hideIcon = false,
6320
+ textAlign = DEFAULT_TEXT_ALIGN
6198
6321
  } = props;
6199
6322
  return createDom("div", {
6200
6323
  class: `GPlaceCircle ${placeCircleLayout({
6201
- textAlign: textAlignRef.value
6324
+ textAlign
6202
6325
  })} ${gmapPlaceIconLayout({
6203
- textAlign: textAlignRef.value
6326
+ textAlign
6204
6327
  })}`
6205
6328
  }, `
6206
6329
  <img class="${placeIcon({
@@ -6214,13 +6337,14 @@ const GPlaceCircle = defineSetup(function GPlaceCircle2(props, {
6214
6337
  });
6215
6338
  const contentWithoutLabelRef = computed(() => {
6216
6339
  const {
6217
- hideIcon = false
6340
+ hideIcon = false,
6341
+ textAlign = DEFAULT_TEXT_ALIGN
6218
6342
  } = props;
6219
6343
  return createDom("img", {
6220
6344
  class: `GPlaceCircle ${placeIcon({
6221
6345
  hideIcon
6222
6346
  })} ${gmapPlaceIconLayout({
6223
- textAlign: textAlignRef.value
6347
+ textAlign
6224
6348
  })}`,
6225
6349
  src: imgPlaceCircle
6226
6350
  });
@@ -6255,18 +6379,31 @@ const PlaceCircle = defineSetup(function PlaceCircle2(props, {
6255
6379
  const PickupPoints = defineSetup(function PickupPoints2(props, {
6256
6380
  emit
6257
6381
  }) {
6382
+ const mapRef = useMap();
6258
6383
  const {
6259
- renderLabel
6260
- } = props;
6261
- const directions = usePointsLabelDirection(reactive({
6384
+ zoomRef
6385
+ } = useMapZoom({
6386
+ mapRef
6387
+ });
6388
+ const {
6389
+ directionsRef,
6390
+ labeledPlacesRef,
6391
+ isContainBasePlaceRef
6392
+ } = usePointsLabelDirection(reactive({
6393
+ basePlace: toRef(props, "basePlace"),
6262
6394
  places: toRef(props, "places"),
6263
6395
  heightLimit: 9,
6264
- widthLimit: 32
6396
+ widthLimit: 34
6265
6397
  }));
6266
6398
  return () => {
6267
- return h("div", [props.places.map((place, idx) => {
6268
- const direction = directions.value[idx];
6269
- const label2 = renderLabel ? renderLabel(place) : place.displayName;
6399
+ const {
6400
+ basePlace,
6401
+ zoomIconMin,
6402
+ zoomTextMin
6403
+ } = props;
6404
+ return h("div", [zoomRef.value >= zoomIconMin && labeledPlacesRef.value.map((place, idx) => {
6405
+ const direction = directionsRef.value[idx];
6406
+ const label2 = zoomRef.value < zoomTextMin ? void 0 : place.displayName;
6270
6407
  return h(PlaceCircle, {
6271
6408
  "attrs": {
6272
6409
  "position": place2point(place),
@@ -6277,12 +6414,17 @@ const PickupPoints = defineSetup(function PickupPoints2(props, {
6277
6414
  "click": () => emit("click", place)
6278
6415
  }
6279
6416
  });
6417
+ }), isContainBasePlaceRef.value && h(PlaceCircle, {
6418
+ "attrs": {
6419
+ "position": place2point(basePlace)
6420
+ }
6280
6421
  })]);
6281
6422
  };
6282
6423
  });
6283
6424
  const RECOMMEND_PLACE_DRAG_LIMIT = 10;
6284
6425
  const RECOMMEND_PLACE_LARGE_LIMIT = 100;
6285
- const RECOMMEND_PLACE_ZOOM_MIN = 13;
6426
+ const RECOMMEND_PLACE_ICON_ZOOM_MIN = 15.75;
6427
+ const RECOMMEND_PLACE_TEXT_ZOOM_MIN = 16.75;
6286
6428
  const DEFAULT_PLACE_NAME = "当前位置";
6287
6429
  const DEFAULT_ZOOM = 17;
6288
6430
  const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlaceMap2(props, {
@@ -6307,12 +6449,6 @@ const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlac
6307
6449
  const {
6308
6450
  readyPromise
6309
6451
  } = useMapSupplier();
6310
- const {
6311
- zoomRef
6312
- } = useMapZoom({
6313
- mapRef,
6314
- defaultValue: DEFAULT_ZOOM
6315
- });
6316
6452
  const centerPlace = reactive({
6317
6453
  lng: (_a = geoDefaultPosition == null ? void 0 : geoDefaultPosition[0]) != null ? _a : 0,
6318
6454
  lat: (_b = geoDefaultPosition == null ? void 0 : geoDefaultPosition[1]) != null ? _b : 0,
@@ -6489,13 +6625,12 @@ const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlac
6489
6625
  recomendDescription,
6490
6626
  unavailableTitle
6491
6627
  } = props;
6492
- console.log("centerPlace = ", JSON.stringify(centerPlace));
6493
6628
  const title = geoLoading.value ? geoLoadingTitle2 : !availableRef.value ? unavailableTitle : centerPlace.displayName;
6494
6629
  const description = !availableRef.value ? void 0 : isElectedRef.value ? recomendDescription : void 0;
6495
6630
  return h(HeycarMap, {
6496
6631
  "attrs": {
6497
6632
  "center": centerPoint.value,
6498
- "zoom": zoomRef.value,
6633
+ "zoom": DEFAULT_ZOOM,
6499
6634
  "touchZoomCenter": true,
6500
6635
  "mapRef": setMap,
6501
6636
  "fallback": slots.fallback,
@@ -6510,10 +6645,12 @@ const BusinessRecomendPlaceMap = defineLagecySetup(function BusinessRecomendPlac
6510
6645
  "position": geoPosition.value,
6511
6646
  "angle": orientation.cssRotationVariableName
6512
6647
  }
6513
- }), zoomRef.value >= RECOMMEND_PLACE_ZOOM_MIN && h(PickupPoints, {
6648
+ }), h(PickupPoints, {
6514
6649
  "attrs": {
6650
+ "basePlace": centerPlace,
6515
6651
  "places": placeCandidates.value,
6516
- "renderLabel": (place) => isPlaceEqual(place, centerPlace) ? void 0 : place.displayName
6652
+ "zoomIconMin": RECOMMEND_PLACE_ICON_ZOOM_MIN,
6653
+ "zoomTextMin": RECOMMEND_PLACE_TEXT_ZOOM_MIN
6517
6654
  },
6518
6655
  "on": {
6519
6656
  "click": panToCenterByPlace
@@ -6555,12 +6692,6 @@ const BusinessReselectPlaceMap = defineLagecySetup(function BusinessReselectPlac
6555
6692
  setMap,
6556
6693
  panTo
6557
6694
  } = useHeycarMap();
6558
- const {
6559
- zoomRef
6560
- } = useMapZoom({
6561
- mapRef,
6562
- defaultValue: DEFAULT_ZOOM
6563
- });
6564
6695
  const centerPlace = reactive({
6565
6696
  lng: defaultPlace.lng,
6566
6697
  lat: defaultPlace.lat,
@@ -6724,7 +6855,7 @@ const BusinessReselectPlaceMap = defineLagecySetup(function BusinessReselectPlac
6724
6855
  return h(HeycarMap, {
6725
6856
  "attrs": {
6726
6857
  "center": centerPoint.value,
6727
- "zoom": zoomRef.value,
6858
+ "zoom": DEFAULT_ZOOM,
6728
6859
  "touchZoomCenter": true,
6729
6860
  "mapRef": setMap,
6730
6861
  "fallback": slots.fallback,
@@ -6739,10 +6870,12 @@ const BusinessReselectPlaceMap = defineLagecySetup(function BusinessReselectPlac
6739
6870
  "position": geoPosition.value,
6740
6871
  "angle": orientation.cssRotationVariableName
6741
6872
  }
6742
- }), zoomRef.value >= RECOMMEND_PLACE_ZOOM_MIN && h(PickupPoints, {
6873
+ }), h(PickupPoints, {
6743
6874
  "attrs": {
6875
+ "basePlace": centerPlace,
6744
6876
  "places": placeCandidates.value,
6745
- "renderLabel": (place) => isPlaceEqual(place, centerPlace) ? void 0 : place.displayName
6877
+ "zoomIconMin": RECOMMEND_PLACE_ICON_ZOOM_MIN,
6878
+ "zoomTextMin": RECOMMEND_PLACE_TEXT_ZOOM_MIN
6746
6879
  },
6747
6880
  "on": {
6748
6881
  "click": panToCenterByPlace
@@ -7914,7 +8047,6 @@ const useBusinessTaxiServiceMap = () => {
7914
8047
  const { mapRef, setMap } = useHeycarMap();
7915
8048
  const { registerFitVeiw, setFitView } = useMapFitView({
7916
8049
  mapRef,
7917
- autoFitTimeout: 5e3,
7918
8050
  padding: [19, 36, 19, 26]
7919
8051
  });
7920
8052
  return { setMap, registerFitVeiw, setFitView };
@@ -8,7 +8,8 @@ import type { Place, Point } from "../../types/interface";
8
8
  import { AbsoluteAddressBoxProps } from "../AbsoluteAddressBox";
9
9
  export declare const RECOMMEND_PLACE_DRAG_LIMIT = 10;
10
10
  export declare const RECOMMEND_PLACE_LARGE_LIMIT = 100;
11
- export declare const RECOMMEND_PLACE_ZOOM_MIN = 13;
11
+ export declare const RECOMMEND_PLACE_ICON_ZOOM_MIN = 15.75;
12
+ export declare const RECOMMEND_PLACE_TEXT_ZOOM_MIN = 16.75;
12
13
  export declare const DEFAULT_PLACE_NAME = "\u5F53\u524D\u4F4D\u7F6E";
13
14
  export declare const DEFAULT_ZOOM = 17;
14
15
  export interface CenterPlaceSource {
@@ -1,7 +1,9 @@
1
1
  import type { Place } from "../../types/interface";
2
2
  export interface PickupPointsProps {
3
3
  places: Place[];
4
- renderLabel?: (place: Place) => string | undefined;
4
+ basePlace: Place;
5
+ zoomTextMin: number;
6
+ zoomIconMin: number;
5
7
  onClick?: (value: Place) => any;
6
8
  }
7
9
  export declare const PickupPoints: import("vue-demi").DefineComponent<import("vue/types/v3-component-props").ComponentObjectPropsOptions<PickupPointsProps>, import("../../types/helper").Empty, import("../../types/helper").Empty, import("../../types/helper").Empty, import("../../types/helper").Empty, import("../../types/helper").Empty, import("../../types/helper").Empty, import("../../types/helper").EmitByProps<PickupPointsProps, Required<PickupPointsProps>>, "click", PickupPointsProps, {}>;
@@ -1,9 +1,19 @@
1
1
  import type { Place } from "../types/interface";
2
2
  type LabelDirection = "left" | "right";
3
3
  export interface UsePointsLabelDirectionProps {
4
+ basePlace: Place;
4
5
  places: Place[];
5
6
  widthLimit: number;
6
7
  heightLimit: number;
7
8
  }
8
- export declare const usePointsLabelDirection: (props: UsePointsLabelDirectionProps) => import("vue-demi").Ref<LabelDirection[]>;
9
+ export declare const usePointsLabelDirection: (props: UsePointsLabelDirectionProps) => {
10
+ directionsRef: import("vue-demi").Ref<LabelDirection[]>;
11
+ labeledPlacesRef: import("vue-demi").Ref<{
12
+ lng: number;
13
+ lat: number;
14
+ name: string;
15
+ displayName: string;
16
+ }[]>;
17
+ isContainBasePlaceRef: import("vue-demi").Ref<boolean>;
18
+ };
9
19
  export {};
@@ -5,7 +5,6 @@ import type { EmitFn } from "vue/types/v3-setup-context";
5
5
  import type { EmitByProps } from "../types/helper";
6
6
  export declare const deepCompareEqualsForMaps: import("fast-equals").EqualityComparator;
7
7
  export declare function createDeepCompareMemoize<T>(): (value: T) => T;
8
- export declare function useDeepCompareEffectForMaps(callback: () => () => any, dependencies: any[]): void;
9
8
  export declare function watchNoneImmediatePostEffectForDeepOption<T>(getOption: () => T, callback: WatchCallback<T, T>, watchOptions?: WatchOptions<false>): import("vue-demi").WatchStopHandle;
10
9
  export declare function watchPostEffectForDeepOption<T>(getOption: () => T, callback: WatchCallback<T, T | undefined>, watchOptions?: WatchOptions<true>): import("vue-demi").WatchStopHandle;
11
10
  export declare function watchEffectForDeepOption<T>(getOption: () => T, callback: WatchCallback<T, T | undefined>, watchOptions?: WatchOptions<true>): import("vue-demi").WatchStopHandle;
@@ -3,3 +3,4 @@ export declare const isPlace: (place: Partial<Place>) => place is Place;
3
3
  export declare const sleep: (milliSeconds: number) => Promise<unknown>;
4
4
  export declare const assertPoint: (point: unknown) => void;
5
5
  export declare const assertAngle: (angle: unknown) => void;
6
+ export declare const isLatLngLiteral: (value: any) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heycar/heycars-map",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite -c vite.config.dev.ts",