@fleet-frontend/mower-maps 0.2.6-beta.1 → 0.2.6-beta.11

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.
Files changed (31) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.esm.js +313 -258
  4. package/dist/index.js +312 -257
  5. package/dist/render/MowerMapRenderer.d.ts.map +1 -1
  6. package/dist/render/MowerPartitionPickerMap.d.ts +1 -1
  7. package/dist/render/MowerPartitionPickerMap.d.ts.map +1 -1
  8. package/dist/render/partitionPicker/constants.d.ts +37 -33
  9. package/dist/render/partitionPicker/constants.d.ts.map +1 -1
  10. package/dist/render/partitionPicker/hooks/useGoogleMapsOverlay.d.ts.map +1 -1
  11. package/dist/render/partitionPicker/hooks/useMapViewport.d.ts +10 -1
  12. package/dist/render/partitionPicker/hooks/useMapViewport.d.ts.map +1 -1
  13. package/dist/render/partitionPicker/layers/MapGridBackground.d.ts.map +1 -1
  14. package/dist/render/partitionPicker/layers/PartitionNameLabels.d.ts +4 -4
  15. package/dist/render/partitionPicker/layers/PartitionNameLabels.d.ts.map +1 -1
  16. package/dist/render/partitionPicker/layers/PartitionPickerGridSvg.d.ts.map +1 -1
  17. package/dist/render/partitionPicker/layers/PartitionPickerSvg.d.ts +2 -2
  18. package/dist/render/partitionPicker/layers/PartitionPickerSvg.d.ts.map +1 -1
  19. package/dist/render/partitionPicker/layers/SelectableBoundaryElement.d.ts +5 -5
  20. package/dist/render/partitionPicker/layers/SelectableBoundaryElement.d.ts.map +1 -1
  21. package/dist/render/partitionPicker/types.d.ts +24 -1
  22. package/dist/render/partitionPicker/types.d.ts.map +1 -1
  23. package/dist/render/partitionPicker/viewportUtils.d.ts +7 -9
  24. package/dist/render/partitionPicker/viewportUtils.d.ts.map +1 -1
  25. package/dist/render/svgElement/ChannelElement/index.d.ts.map +1 -1
  26. package/dist/render/svgElement/PathElement/index.d.ts.map +1 -1
  27. package/dist/render/svgElement/PolygonELement/index.d.ts.map +1 -1
  28. package/dist/render/svgElement/TransformWrapper/DoodleTransformWrapper/DoodleTransformWrapper.d.ts.map +1 -1
  29. package/dist/utils/pathData.d.ts +2 -0
  30. package/dist/utils/pathData.d.ts.map +1 -0
  31. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22976,9 +22976,9 @@ const VertexElement = React.memo(({ r, stroke, fill, ...props }) => {
22976
22976
  });
22977
22977
 
22978
22978
  var _path$1;
22979
- function _extends$8() { return _extends$8 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$8.apply(null, arguments); }
22979
+ function _extends$5() { return _extends$5 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$5.apply(null, arguments); }
22980
22980
  var SvgDelete = function SvgDelete(props) {
22981
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$8({
22981
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$5({
22982
22982
  xmlns: "http://www.w3.org/2000/svg",
22983
22983
  width: 16,
22984
22984
  height: 16,
@@ -23459,6 +23459,73 @@ function computeFitViewBoxToContainer(content, containerWidth, containerHeight)
23459
23459
  height: content.height,
23460
23460
  };
23461
23461
  }
23462
+ /** 地图内容在屏幕坐标系下的包围盒(meet 渲染,未考虑旋转) */
23463
+ function getContentScreenBounds(content, viewBox, containerWidth, containerHeight) {
23464
+ const { x: offsetX, y: offsetY, scale } = getViewBoxMeetOffset(viewBox, containerWidth, containerHeight);
23465
+ return {
23466
+ left: offsetX + (content.x - viewBox.x) * scale,
23467
+ top: offsetY + (content.y - viewBox.y) * scale,
23468
+ right: offsetX + (content.x + content.width - viewBox.x) * scale,
23469
+ bottom: offsetY + (content.y + content.height - viewBox.y) * scale,
23470
+ };
23471
+ }
23472
+ function contentFitsInScreenPadding(content, viewBox, pad, containerWidth, containerHeight) {
23473
+ const bounds = getContentScreenBounds(content, viewBox, containerWidth, containerHeight);
23474
+ return (bounds.left >= pad.left &&
23475
+ bounds.top >= pad.top &&
23476
+ bounds.right <= containerWidth - pad.right &&
23477
+ bounds.bottom <= containerHeight - pad.bottom);
23478
+ }
23479
+ function expandViewBoxFromCenter(viewBox, factor) {
23480
+ const centerX = viewBox.x + viewBox.width / 2;
23481
+ const centerY = viewBox.y + viewBox.height / 2;
23482
+ const width = viewBox.width * factor;
23483
+ const height = viewBox.height * factor;
23484
+ return {
23485
+ x: centerX - width / 2,
23486
+ y: centerY - height / 2,
23487
+ width,
23488
+ height,
23489
+ };
23490
+ }
23491
+ /** 将 viewBox 中心对齐到 padding 内矩形中心(增大 top/left → 内容向对应方向避让) */
23492
+ function applyViewBoxPaddingOffset(viewBox, pad, containerWidth, containerHeight) {
23493
+ const offsetX = ((pad.right - pad.left) / 2) * (viewBox.width / containerWidth);
23494
+ const offsetY = ((pad.bottom - pad.top) / 2) * (viewBox.height / containerHeight);
23495
+ return {
23496
+ ...viewBox,
23497
+ x: viewBox.x + offsetX,
23498
+ y: viewBox.y + offsetY,
23499
+ };
23500
+ }
23501
+ function buildPaddedFitViewBox(baseFit, pad, containerWidth, containerHeight, zoomOutFactor) {
23502
+ const expanded = expandViewBoxFromCenter(baseFit, zoomOutFactor);
23503
+ return applyViewBoxPaddingOffset(expanded, pad, containerWidth, containerHeight);
23504
+ }
23505
+ function findMinimumZoomOutForPadding(content, baseFit, pad, containerWidth, containerHeight) {
23506
+ const fits = (zoomOutFactor) => contentFitsInScreenPadding(content, buildPaddedFitViewBox(baseFit, pad, containerWidth, containerHeight, zoomOutFactor), pad, containerWidth, containerHeight);
23507
+ if (fits(1)) {
23508
+ return 1;
23509
+ }
23510
+ const innerWidth = Math.max(containerWidth - pad.left - pad.right, 1);
23511
+ const innerHeight = Math.max(containerHeight - pad.top - pad.bottom, 1);
23512
+ const legacyScale = Math.min(innerWidth / containerWidth, innerHeight / containerHeight);
23513
+ let hi = legacyScale > 0 && legacyScale < 1 ? 1 / legacyScale : 2;
23514
+ while (!fits(hi) && hi < 1024) {
23515
+ hi *= 2;
23516
+ }
23517
+ let lo = 1;
23518
+ for (let i = 0; i < 32; i++) {
23519
+ const mid = (lo + hi) / 2;
23520
+ if (fits(mid)) {
23521
+ hi = mid;
23522
+ }
23523
+ else {
23524
+ lo = mid;
23525
+ }
23526
+ }
23527
+ return hi;
23528
+ }
23462
23529
  /**
23463
23530
  * 计算默认 fit viewBox
23464
23531
  *
@@ -23470,26 +23537,8 @@ function computeFitViewBox(content, containerWidth, containerHeight, screenPaddi
23470
23537
  if (isZeroScreenPadding(pad)) {
23471
23538
  return baseFit;
23472
23539
  }
23473
- const innerWidth = Math.max(containerWidth - pad.left - pad.right, 1);
23474
- const innerHeight = Math.max(containerHeight - pad.top - pad.bottom, 1);
23475
- const scaleX = innerWidth / containerWidth;
23476
- const scaleY = innerHeight / containerHeight;
23477
- const scale = Math.min(scaleX, scaleY);
23478
- if (!Number.isFinite(scale) || scale <= 0 || scale >= 1) {
23479
- return baseFit;
23480
- }
23481
- const newWidth = baseFit.width / scale;
23482
- const newHeight = baseFit.height / scale;
23483
- const centerX = baseFit.x + baseFit.width / 2;
23484
- const centerY = baseFit.y + baseFit.height / 2;
23485
- const offsetX = ((pad.left - pad.right) / 2) * (newWidth / containerWidth);
23486
- const offsetY = ((pad.top - pad.bottom) / 2) * (newHeight / containerHeight);
23487
- return {
23488
- x: centerX - newWidth / 2 + offsetX,
23489
- y: centerY - newHeight / 2 + offsetY,
23490
- width: newWidth,
23491
- height: newHeight,
23492
- };
23540
+ const zoomOutFactor = findMinimumZoomOutForPadding(content, baseFit, pad, containerWidth, containerHeight);
23541
+ return buildPaddedFitViewBox(baseFit, pad, containerWidth, containerHeight, zoomOutFactor);
23493
23542
  }
23494
23543
  function viewBoxToString(viewBox) {
23495
23544
  return `${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`;
@@ -23568,15 +23617,13 @@ function computePolygonScreenWidthPx(points, viewBox, containerWidth, containerH
23568
23617
  const scale = getViewBoxMeetScale(viewBox, containerWidth, containerHeight);
23569
23618
  return mapWidth * scale;
23570
23619
  }
23571
- function scaleStrokeWidthForViewBox(baseStrokeWidth, viewBox, fitViewBox, options) {
23572
- const { containerWidth, containerHeight, minScreenStrokePx = 2 } = options;
23620
+ function scaleStrokeWidthForViewBox(viewBox, options) {
23621
+ const { containerWidth, containerHeight, targetScreenStrokePx = 2 } = options;
23573
23622
  const meetScale = getViewBoxMeetScale(viewBox, containerWidth, containerHeight);
23574
- const fitMeetScale = getViewBoxMeetScale(fitViewBox, containerWidth, containerHeight);
23575
- if (meetScale <= 0 || fitMeetScale <= 0 || !Number.isFinite(baseStrokeWidth)) {
23576
- return baseStrokeWidth;
23623
+ if (meetScale <= 0 || !Number.isFinite(targetScreenStrokePx)) {
23624
+ return targetScreenStrokePx;
23577
23625
  }
23578
- const targetScreenPx = Math.max(baseStrokeWidth * fitMeetScale, minScreenStrokePx);
23579
- return targetScreenPx / meetScale;
23626
+ return targetScreenStrokePx / meetScale;
23580
23627
  }
23581
23628
  /** 屏幕拖拽像素 → viewBox 坐标增量(与 mapPointToContainerPercent 互逆,供 applyPan 使用) */
23582
23629
  function containerDeltaToViewBoxDelta(deltaXPx, deltaYPx, viewBox, containerWidth, containerHeight, mapRotationDeg = 0) {
@@ -24666,6 +24713,24 @@ const Tooltip = ({ open, x, y, text, style, onClick }) => {
24666
24713
  }, children: text }), document.body);
24667
24714
  };
24668
24715
 
24716
+ function getPathData(points) {
24717
+ // 1. 安全守卫:如果没有点,返回空字符串
24718
+ if (!points || points.length === 0)
24719
+ return '';
24720
+ // 2. 如果只有 1 个点,只生成起点 M 即可(或者在最外层判断中直接 return 过滤掉)
24721
+ if (points.length === 1) {
24722
+ return `M ${points[0][0]} ${points[0][1]}`;
24723
+ }
24724
+ // 3. 2个点及以上时,再进行 L 拼接
24725
+ const pathData = points.map((p, index) => {
24726
+ if (index === 0) {
24727
+ return `M ${p[0]} ${p[1]}`;
24728
+ }
24729
+ return ` L ${p[0]} ${p[1]}`;
24730
+ }).join('');
24731
+ return pathData;
24732
+ }
24733
+
24669
24734
  /**
24670
24735
  * 将坐标点数组转换为polygon points字符串
24671
24736
  * @param coordinates 坐标点数组 [[x1, y1], [x2, y2], ...]
@@ -24749,10 +24814,7 @@ const groupCoordinatesByType = (coordinates, autoClose = true) => {
24749
24814
  const createPathData = (points) => {
24750
24815
  if (points.length < 2)
24751
24816
  return '';
24752
- let pathData = `M ${points[0][0]} ${points[0][1]}`;
24753
- for (let i = 1; i < points.length; i++) {
24754
- pathData += ` L ${points[i][0]} ${points[i][1]}`;
24755
- }
24817
+ const pathData = getPathData(points);
24756
24818
  return pathData;
24757
24819
  };
24758
24820
  const PolygonElement = ({ canSelect = false, isHover = false, points, fillColor = 'rgba(0, 0, 0, 0.1)', hoverFillColor = '', fillOpacity = 1, strokeColor = '#000', strokeWidth = 2, strokeOpacity = 1, createMode = false, showPoints = false, onPointClick, completed = false, mousePos = null, editMode = false, onCoordinatesChange, onPathClick, onPolygonClick, onVertexDelete, draggable = true, // 新增参数,如果未指定则根据createMode和editMode自动判断
@@ -25376,17 +25438,17 @@ const PolygonElement = ({ canSelect = false, isHover = false, points, fillColor
25376
25438
  if (isDash && showStraddleBoundaryBorder) {
25377
25439
  return (jsxRuntime.jsx(DashPath, { className: canSelect ? styles$8.polygonPath : '', points: segment.points, stroke: strokeColor, strokeWidth: isHover ? strokeWidth + 1 : strokeWidth, strokeOpacity: strokeOpacity }, index));
25378
25440
  }
25379
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(editMode || createMode) && (jsxRuntime.jsx("path", { d: pathData, fill: "none", stroke: '#fff', strokeWidth: strokeWidth * 2, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke", style: {
25441
+ return (jsxRuntime.jsxs(React.Fragment, { children: [(editMode || createMode) && (jsxRuntime.jsx("path", { d: pathData, fill: "none", stroke: '#fff', strokeWidth: strokeWidth * 2, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke", style: {
25380
25442
  userSelect: 'none',
25381
25443
  WebkitUserSelect: 'none',
25382
25444
  WebkitTouchCallout: 'none',
25383
25445
  touchAction: 'none',
25384
- } }, 'warp' + index)), jsxRuntime.jsx("path", { d: pathData, fill: "none", stroke: strokeColor, strokeWidth: isHover ? strokeWidth + 1 : strokeWidth, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", className: canSelect ? styles$8.polygonPath : '', vectorEffect: "non-scaling-stroke", onClick: onPathClick, style: {
25446
+ } })), jsxRuntime.jsx("path", { d: pathData, fill: "none", stroke: strokeColor, strokeWidth: isHover ? strokeWidth + 1 : strokeWidth, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", className: canSelect ? styles$8.polygonPath : '', vectorEffect: "non-scaling-stroke", onClick: onPathClick, style: {
25385
25447
  userSelect: 'none',
25386
25448
  WebkitUserSelect: 'none',
25387
25449
  WebkitTouchCallout: 'none',
25388
25450
  touchAction: 'none',
25389
- } }, index)] }));
25451
+ } }, index)] }, 'warp' + index));
25390
25452
  }) }), (editMode || (createMode && completed)) &&
25391
25453
  renderCoordinates.length >= 2 &&
25392
25454
  renderCoordinates.map((coord, index) => {
@@ -25694,10 +25756,7 @@ const ChannelElement = ({ data }) => {
25694
25756
  const clipPathUrl = `url(#${channelClipPathId})`;
25695
25757
  const points = data.points;
25696
25758
  const style = data.style;
25697
- let pathData = `M ${points[0][0]} ${points[0][1]}`;
25698
- for (let i = 1; i < points.length; i++) {
25699
- pathData += ` L ${points[i][0]} ${points[i][1]}`;
25700
- }
25759
+ const pathData = getPathData(points);
25701
25760
  const topLineWidth = dp2px(style.lineWidth).toString();
25702
25761
  const bottomLineWidth = dp2px(style.bottomLineWidth).toString();
25703
25762
  const dashLength = dp2px(style.lineWidth);
@@ -26294,15 +26353,15 @@ const useVisionOffTransform = (data, scaleConstraints
26294
26353
  };
26295
26354
  };
26296
26355
 
26297
- var _g$6, _defs$6;
26298
- function _extends$7() { return _extends$7 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$7.apply(null, arguments); }
26356
+ var _g$3, _defs$3;
26357
+ function _extends$4() { return _extends$4 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$4.apply(null, arguments); }
26299
26358
  var SvgTransformDelete = function SvgTransformDelete(props) {
26300
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$7({
26359
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$4({
26301
26360
  xmlns: "http://www.w3.org/2000/svg",
26302
26361
  width: 20,
26303
26362
  height: 20,
26304
26363
  fill: "none"
26305
- }, props), _g$6 || (_g$6 = /*#__PURE__*/React__namespace.createElement("g", {
26364
+ }, props), _g$3 || (_g$3 = /*#__PURE__*/React__namespace.createElement("g", {
26306
26365
  clipPath: "url(#transform-delete_svg__a)"
26307
26366
  }, /*#__PURE__*/React__namespace.createElement("circle", {
26308
26367
  cx: 10,
@@ -26325,7 +26384,7 @@ var SvgTransformDelete = function SvgTransformDelete(props) {
26325
26384
  fill: "#fff",
26326
26385
  rx: 0.8,
26327
26386
  transform: "rotate(45 6.323 5.191)"
26328
- }))), _defs$6 || (_defs$6 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26387
+ }))), _defs$3 || (_defs$3 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26329
26388
  id: "transform-delete_svg__b",
26330
26389
  x1: 17.727,
26331
26390
  x2: -1.215,
@@ -26345,15 +26404,15 @@ var SvgTransformDelete = function SvgTransformDelete(props) {
26345
26404
  })))));
26346
26405
  };
26347
26406
 
26348
- var _g$5, _defs$5;
26349
- function _extends$6() { return _extends$6 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$6.apply(null, arguments); }
26407
+ var _g$2, _defs$2;
26408
+ function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); }
26350
26409
  var SvgTransformRotate = function SvgTransformRotate(props) {
26351
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$6({
26410
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$3({
26352
26411
  xmlns: "http://www.w3.org/2000/svg",
26353
26412
  width: 21,
26354
26413
  height: 20,
26355
26414
  fill: "none"
26356
- }, props), _g$5 || (_g$5 = /*#__PURE__*/React__namespace.createElement("g", {
26415
+ }, props), _g$2 || (_g$2 = /*#__PURE__*/React__namespace.createElement("g", {
26357
26416
  clipPath: "url(#transform-rotate_svg__a)"
26358
26417
  }, /*#__PURE__*/React__namespace.createElement("path", {
26359
26418
  fill: "url(#transform-rotate_svg__b)",
@@ -26361,7 +26420,7 @@ var SvgTransformRotate = function SvgTransformRotate(props) {
26361
26420
  }), /*#__PURE__*/React__namespace.createElement("path", {
26362
26421
  fill: "#fff",
26363
26422
  d: "M11.602 14.719a5.447 5.447 0 0 1-6.608-5.116l-.004-.205a.818.818 0 0 1 1.633-.084l.004.084.01.285a3.81 3.81 0 0 0 2.127 3.137l.26.115a3.8 3.8 0 0 0 2.227.184l.276-.071q.29-.088.561-.219l-1.147-.441a.817.817 0 0 1 .587-1.525l2.54.977a.817.817 0 0 1 .316 1.308l.001.001a5.45 5.45 0 0 1-2.783 1.57M8.623 4.548a5.447 5.447 0 0 1 6.608 5.116l.004.204a.818.818 0 0 1-1.633.084l-.004-.084-.01-.284a3.81 3.81 0 0 0-2.127-3.138l-.26-.115a3.8 3.8 0 0 0-2.227-.184l-.276.072q-.29.087-.561.218l1.147.442a.817.817 0 0 1-.586 1.524l-2.542-.976a.817.817 0 0 1-.315-1.309 5.45 5.45 0 0 1 2.782-1.57"
26364
- }))), _defs$5 || (_defs$5 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26423
+ }))), _defs$2 || (_defs$2 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26365
26424
  id: "transform-rotate_svg__b",
26366
26425
  x1: 17.84,
26367
26426
  x2: -1.103,
@@ -26381,15 +26440,15 @@ var SvgTransformRotate = function SvgTransformRotate(props) {
26381
26440
  })))));
26382
26441
  };
26383
26442
 
26384
- var _g$4, _defs$4;
26385
- function _extends$5() { return _extends$5 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$5.apply(null, arguments); }
26443
+ var _g$1, _defs$1;
26444
+ function _extends$2() { return _extends$2 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$2.apply(null, arguments); }
26386
26445
  var SvgTransformScale = function SvgTransformScale(props) {
26387
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$5({
26446
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$2({
26388
26447
  xmlns: "http://www.w3.org/2000/svg",
26389
26448
  width: 21,
26390
26449
  height: 20,
26391
26450
  fill: "none"
26392
- }, props), _g$4 || (_g$4 = /*#__PURE__*/React__namespace.createElement("g", {
26451
+ }, props), _g$1 || (_g$1 = /*#__PURE__*/React__namespace.createElement("g", {
26393
26452
  clipPath: "url(#transform-scale_svg__a)"
26394
26453
  }, /*#__PURE__*/React__namespace.createElement("path", {
26395
26454
  fill: "url(#transform-scale_svg__b)",
@@ -26397,7 +26456,7 @@ var SvgTransformScale = function SvgTransformScale(props) {
26397
26456
  }), /*#__PURE__*/React__namespace.createElement("path", {
26398
26457
  fill: "#fff",
26399
26458
  d: "M5.078 8.265a.8.8 0 0 0 1.6.001v-.544l5.69 5.69h-.494a.8.8 0 0 0 0 1.6l2.474-.002a.8.8 0 0 0 .311-.062.8.8 0 0 0 .49-.738v-2.474a.8.8 0 1 0-1.6 0v.594L7.81 6.59h.544a.8.8 0 0 0 0-1.6H5.879a.8.8 0 0 0-.8.8z"
26400
- }))), _defs$4 || (_defs$4 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26459
+ }))), _defs$1 || (_defs$1 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26401
26460
  id: "transform-scale_svg__b",
26402
26461
  x1: 17.84,
26403
26462
  x2: -1.103,
@@ -26417,15 +26476,15 @@ var SvgTransformScale = function SvgTransformScale(props) {
26417
26476
  })))));
26418
26477
  };
26419
26478
 
26420
- var _g$3, _defs$3;
26421
- function _extends$4() { return _extends$4 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$4.apply(null, arguments); }
26479
+ var _g, _defs;
26480
+ function _extends$1() { return _extends$1 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$1.apply(null, arguments); }
26422
26481
  var SvgTransformTranslate = function SvgTransformTranslate(props) {
26423
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$4({
26482
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$1({
26424
26483
  xmlns: "http://www.w3.org/2000/svg",
26425
26484
  width: 20,
26426
26485
  height: 20,
26427
26486
  fill: "none"
26428
- }, props), _g$3 || (_g$3 = /*#__PURE__*/React__namespace.createElement("g", {
26487
+ }, props), _g || (_g = /*#__PURE__*/React__namespace.createElement("g", {
26429
26488
  clipPath: "url(#transform-translate_svg__a)"
26430
26489
  }, /*#__PURE__*/React__namespace.createElement("circle", {
26431
26490
  cx: 10,
@@ -26435,7 +26494,7 @@ var SvgTransformTranslate = function SvgTransformTranslate(props) {
26435
26494
  }), /*#__PURE__*/React__namespace.createElement("path", {
26436
26495
  fill: "#fff",
26437
26496
  d: "M16.18 10.758a.8.8 0 0 0-.105-1.218l-1.66-1.66a.801.801 0 0 0-1.132 1.132l.383.381h-2.96V6.418l.385.386a.8.8 0 1 0 1.131-1.13l-1.75-1.75a.8.8 0 0 0-1.222.11L7.594 5.689a.8.8 0 0 0 1.131 1.13l.381-.38v2.954H6.137l.381-.38a.8.8 0 1 0-1.13-1.132l-1.752 1.75a.8.8 0 0 0 .106 1.22l1.66 1.66a.801.801 0 0 0 1.132-1.133l-.386-.385h2.958v2.972l-.38-.38a.8.8 0 0 0-1.132 1.131l1.751 1.75a.8.8 0 0 0 1.223-.11l1.654-1.655a.8.8 0 1 0-1.13-1.131l-.386.386v-2.963h2.978l-.385.384a.8.8 0 1 0 1.131 1.131z"
26438
- }))), _defs$3 || (_defs$3 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26497
+ }))), _defs || (_defs = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("linearGradient", {
26439
26498
  id: "transform-translate_svg__b",
26440
26499
  x1: 17.727,
26441
26500
  x2: -1.215,
@@ -27109,97 +27168,6 @@ const useDoodleTransform = (data, onTransformChange, options) => {
27109
27168
  };
27110
27169
  };
27111
27170
 
27112
- var _g$2, _defs$2;
27113
- function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); }
27114
- var SvgDisabledRotate = function SvgDisabledRotate(props) {
27115
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$3({
27116
- xmlns: "http://www.w3.org/2000/svg",
27117
- width: 16,
27118
- height: 16,
27119
- fill: "none"
27120
- }, props), _g$2 || (_g$2 = /*#__PURE__*/React__namespace.createElement("g", {
27121
- clipPath: "url(#disabled-rotate_svg__a)"
27122
- }, /*#__PURE__*/React__namespace.createElement("path", {
27123
- fill: "#fff",
27124
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27125
- }), /*#__PURE__*/React__namespace.createElement("path", {
27126
- fill: "#211F1F",
27127
- fillOpacity: 0.4,
27128
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27129
- }), /*#__PURE__*/React__namespace.createElement("path", {
27130
- fill: "#fff",
27131
- fillOpacity: 0.7,
27132
- d: "M9.192 11.775a4.36 4.36 0 0 1-5.277-3.93l-.013-.326v-.002a.655.655 0 0 1 1.31 0v.002a3.05 3.05 0 0 0 1.71 2.738l.208.091a3.05 3.05 0 0 0 1.781.147l.22-.057q.234-.07.451-.175l-.919-.354a.653.653 0 1 1 .47-1.22l2.033.782a.654.654 0 0 1 .251 1.047l.002.001a4.36 4.36 0 0 1-2.227 1.256M6.809 3.639a4.36 4.36 0 0 1 5.289 4.256v.002a.654.654 0 1 1-1.309 0v-.002a3.05 3.05 0 0 0-1.71-2.738l-.208-.091a3.05 3.05 0 0 0-1.781-.147l-.22.057a3 3 0 0 0-.451.175l.919.354a.654.654 0 0 1-.47 1.22l-2.033-.782a.654.654 0 0 1-.251-1.046l-.002-.002a4.36 4.36 0 0 1 2.227-1.256"
27133
- }))), _defs$2 || (_defs$2 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("clipPath", {
27134
- id: "disabled-rotate_svg__a"
27135
- }, /*#__PURE__*/React__namespace.createElement("path", {
27136
- fill: "#fff",
27137
- d: "M16 0H0v16h16z"
27138
- })))));
27139
- };
27140
-
27141
- var _g$1, _defs$1;
27142
- function _extends$2() { return _extends$2 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$2.apply(null, arguments); }
27143
- var SvgDisabledScale = function SvgDisabledScale(props) {
27144
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$2({
27145
- xmlns: "http://www.w3.org/2000/svg",
27146
- width: 16,
27147
- height: 16,
27148
- fill: "none"
27149
- }, props), _g$1 || (_g$1 = /*#__PURE__*/React__namespace.createElement("g", {
27150
- clipPath: "url(#disabled-scale_svg__a)"
27151
- }, /*#__PURE__*/React__namespace.createElement("path", {
27152
- fill: "#fff",
27153
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27154
- }), /*#__PURE__*/React__namespace.createElement("path", {
27155
- fill: "#211F1F",
27156
- fillOpacity: 0.4,
27157
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27158
- }), /*#__PURE__*/React__namespace.createElement("path", {
27159
- fill: "#fff",
27160
- fillOpacity: 0.7,
27161
- d: "M3.972 6.612a.64.64 0 0 0 1.28 0v-.437l4.554 4.554H9.41a.64.64 0 0 0 0 1.28h1.979a.64.64 0 0 0 .636-.606l.003-.036.001-1.98a.64.64 0 1 0-1.28.001v.474L6.158 5.27h.435a.64.64 0 0 0 0-1.28h-1.98a.64.64 0 0 0-.64.64z"
27162
- }))), _defs$1 || (_defs$1 = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("clipPath", {
27163
- id: "disabled-scale_svg__a"
27164
- }, /*#__PURE__*/React__namespace.createElement("path", {
27165
- fill: "#fff",
27166
- d: "M0 16h16V0H0z"
27167
- })))));
27168
- };
27169
-
27170
- var _g, _defs;
27171
- function _extends$1() { return _extends$1 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$1.apply(null, arguments); }
27172
- var SvgDisabledTranslate = function SvgDisabledTranslate(props) {
27173
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$1({
27174
- xmlns: "http://www.w3.org/2000/svg",
27175
- width: 16,
27176
- height: 16,
27177
- fill: "none"
27178
- }, props), _g || (_g = /*#__PURE__*/React__namespace.createElement("g", {
27179
- clipPath: "url(#disabled-translate_svg__a)"
27180
- }, /*#__PURE__*/React__namespace.createElement("circle", {
27181
- cx: 8,
27182
- cy: 8,
27183
- r: 8,
27184
- fill: "#fff"
27185
- }), /*#__PURE__*/React__namespace.createElement("circle", {
27186
- cx: 8,
27187
- cy: 8,
27188
- r: 8,
27189
- fill: "#211F1F",
27190
- fillOpacity: 0.4
27191
- }), /*#__PURE__*/React__namespace.createElement("path", {
27192
- fill: "#fff",
27193
- fillOpacity: 0.7,
27194
- d: "M12.944 8.608a.64.64 0 0 0-.079-.97l-1.333-1.334a.64.64 0 0 0-.905.905l.305.305H8.564V5.136l.308.308a.642.642 0 0 0 .906-.906l-1.4-1.399a.64.64 0 0 0-.906 0q-.036.037-.064.08L6.075 4.55a.64.64 0 0 0 .905.905l.305-.304v2.362H4.91l.306-.306a.64.64 0 0 0-.904-.904l-1.4 1.4a.64.64 0 0 0 .077.97l1.334 1.333a.64.64 0 0 0 .906-.905l-.31-.309h2.367v2.38l-.304-.305a.64.64 0 1 0-.905.906l1.4 1.4a.64.64 0 0 0 .97-.08l1.332-1.333a.64.64 0 0 0-.905-.905l-.309.308v-2.37h2.385l-.31.309a.64.64 0 1 0 .905.904z"
27195
- }))), _defs || (_defs = /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("clipPath", {
27196
- id: "disabled-translate_svg__a"
27197
- }, /*#__PURE__*/React__namespace.createElement("path", {
27198
- fill: "#fff",
27199
- d: "M16 0H0v16h16z"
27200
- })))));
27201
- };
27202
-
27203
27171
  var css_248z$6 = ".index-module_doodleHover__jIZHV path {\n fill: #00B3A1;\n}";
27204
27172
  var styles$6 = {"doodleHover":"index-module_doodleHover__jIZHV"};
27205
27173
  styleInject(css_248z$6);
@@ -27398,8 +27366,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
27398
27366
  const infoBoxWidth = 300 * overlayScale; // 信息框宽度
27399
27367
  const infoBoxHeight = 40 * overlayScale; // 信息框高度
27400
27368
  const infoBoxX = centerX - infoBoxWidth / 2; // 居中对齐
27401
- const circleScale = platform === exports.PlatformType.H5 ? 1.5 * overlayScale : 3 * overlayScale;
27402
- const disacledScale = circleScale * 1.2;
27369
+ const circleScale = platform === exports.PlatformType.H5 ? 1.5 * overlayScale : 2 * overlayScale;
27403
27370
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("polygon", { points: selectionBoxPoints.map((point) => `${point.x},${point.y}`).join(' '), fill: "none", stroke: "#B2B4B9", strokeWidth: "2", strokeDasharray: "5,5", vectorEffect: "non-scaling-stroke", ...(platform === exports.PlatformType.H5
27404
27371
  ? {
27405
27372
  onTouchStart: createReactEventHandler((e) => {
@@ -27408,7 +27375,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
27408
27375
  }
27409
27376
  : {
27410
27377
  // onMouseDown: handleMouseDownWithDisabled,
27411
- }) }), jsxRuntime.jsx("g", { transform: `translate(${selectionBoxPoints[3].x}, ${selectionBoxPoints[3].y})`, children: jsxRuntime.jsx("g", { transformOrigin: "center", transform: `translate(-${10 * circleScale}, -${10 * circleScale}) scale(${disacledScale})`, children: jsxRuntime.jsx(SvgDisabledRotate, {}) }) }), jsxRuntime.jsx("g", { transform: `translate(${selectionBoxPoints[1].x}, ${selectionBoxPoints[1].y})`, children: jsxRuntime.jsx("g", { transformOrigin: "center", transform: `translate(-${10 * circleScale}, -${10 * circleScale}) scale(${disacledScale})`, children: jsxRuntime.jsx(SvgDisabledTranslate, {}) }) }), jsxRuntime.jsx("g", { transform: `translate(${selectionBoxPoints[2].x}, ${selectionBoxPoints[2].y})`, children: jsxRuntime.jsx("g", { transformOrigin: "center", transform: `translate(-${10 * circleScale}, -${10 * circleScale}) scale(${disacledScale})`, children: jsxRuntime.jsx(SvgDisabledScale, {}) }) }), platform === exports.PlatformType.H5 && (jsxRuntime.jsx("foreignObject", { x: infoBoxX, y: infoBoxY, width: infoBoxWidth, height: infoBoxHeight, style: { textAlign: 'center' }, onClick: () => {
27378
+ }) }), jsxRuntime.jsx("circle", { cx: selectionBoxPoints[0].x, cy: selectionBoxPoints[0].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), jsxRuntime.jsx("circle", { cx: selectionBoxPoints[3].x, cy: selectionBoxPoints[3].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), jsxRuntime.jsx("circle", { cx: selectionBoxPoints[1].x, cy: selectionBoxPoints[1].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), jsxRuntime.jsx("circle", { cx: selectionBoxPoints[2].x, cy: selectionBoxPoints[2].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), platform === exports.PlatformType.H5 && (jsxRuntime.jsx("foreignObject", { x: infoBoxX, y: infoBoxY, width: infoBoxWidth, height: infoBoxHeight, style: { textAlign: 'center' }, onClick: () => {
27412
27379
  onClickInfo?.();
27413
27380
  }, children: jsxRuntime.jsx("div", { style: {
27414
27381
  padding: `5px ${10 * overlayScale}px`,
@@ -27428,7 +27395,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
27428
27395
  justifyContent: 'center',
27429
27396
  gap: '10px',
27430
27397
  color: '#325069',
27431
- }, children: jsxRuntime.jsxs("div", { children: [locale?.['map.renderer.remainingTime'] || 'Remaining time', ": ", remainingTime] }) }) }) }))] }));
27398
+ }, children: jsxRuntime.jsxs("div", { children: [locale?.['map.renderer.remainTime'] || 'Remaining time', ": ", remainingTime] }) }) }) }))] }));
27432
27399
  };
27433
27400
  React.useEffect(() => {
27434
27401
  const isMove = isDragging || isRotating || isScaling;
@@ -27982,10 +27949,7 @@ const PathElement = React.forwardRef(({ mapConfig, pathData, mowPartitionData },
27982
27949
  return;
27983
27950
  }
27984
27951
  // 构建路径数据
27985
- let pathData = `M ${points[0][0]} ${points[0][1]}`;
27986
- for (let i = 1; i < points.length; i++) {
27987
- pathData += ` L ${points[i][0]} ${points[i][1]}`;
27988
- }
27952
+ const pathData = getPathData(points);
27989
27953
  // 根据路径类型设置不同的颜色
27990
27954
  let lineColor;
27991
27955
  if (pathType === PathSegmentType.TRANS) {
@@ -28018,7 +27982,7 @@ const PathElement = React.forwardRef(({ mapConfig, pathData, mowPartitionData },
28018
27982
  const result = [];
28019
27983
  partitionTypeGroups.forEach((groupData, groupKey) => {
28020
27984
  const { pathData, style } = groupData;
28021
- if (pathData.length === 0)
27985
+ if (!pathData || pathData.length === 0)
28022
27986
  return;
28023
27987
  // 从groupKey中提取分区ID
28024
27988
  const partitionId = groupKey.split('-')[0];
@@ -28026,8 +27990,8 @@ const PathElement = React.forwardRef(({ mapConfig, pathData, mowPartitionData },
28026
27990
  const clipPathId = clipPathData[partitionId]?.id;
28027
27991
  if (!clipPathId)
28028
27992
  return;
28029
- return result.push({
28030
- path: (pathData || []).join(' '),
27993
+ result.push({
27994
+ path: pathData.join(' '),
28031
27995
  style,
28032
27996
  clipPathId: clipPathId,
28033
27997
  });
@@ -28042,7 +28006,7 @@ const PathElement = React.forwardRef(({ mapConfig, pathData, mowPartitionData },
28042
28006
  return (jsxRuntime.jsxs("g", { id: "path", children: [jsxRuntime.jsx("defs", { children: Object.values(clipPathData).map((item) => {
28043
28007
  return (jsxRuntime.jsx("clipPath", { id: item.id, clipRule: "evenodd", children: jsxRuntime.jsx("path", { d: item.path }) }, item.id));
28044
28008
  }) }), Object.values(pathDataObj).map((item) => {
28045
- return (jsxRuntime.jsx("g", { "clip-path": `url(#${item.clipPathId})`, opacity: "0.5", children: jsxRuntime.jsx("path", { className: "vector-path", d: item.path, fill: "none", "mix-blend-mode": "normal", "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": item.style.lineWidth, stroke: item.style.lineColor }) }));
28009
+ return (jsxRuntime.jsx("g", { clipPath: `url(#${item.clipPathId})`, opacity: "0.5", children: jsxRuntime.jsx("path", { className: "vector-path", d: item.path, fill: "none", "mix-blend-mode": "normal", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: item.style.lineWidth, stroke: item.style.lineColor }) }));
28046
28010
  })] }));
28047
28011
  });
28048
28012
 
@@ -30241,7 +30205,6 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
30241
30205
  const newSvgElementDatas = { ...svgElementDatas };
30242
30206
  Object.keys(newSvgElementDatas).forEach((key) => {
30243
30207
  if (key === exports.DataType.OBSTACLE) {
30244
- console.error('newSvgElementDatas[key] 000---->', newSvgElementDatas[key]);
30245
30208
  newSvgElementDatas[key] =
30246
30209
  newSvgElementDatas[key].filter((item) => {
30247
30210
  return (item.status === 1 &&
@@ -30863,16 +30826,38 @@ const BoundarySvgRender = React.memo(({ mapJson, unStructMapData, id, maxWidth =
30863
30826
  }) }), jsxRuntime.jsx(CharginPile, { viewBox: boundaryViewBox || null, rotation: 0 })] }) }) }));
30864
30827
  });
30865
30828
 
30829
+ const ISOLATED_BOUNDARY_SVG_2 = `<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
30830
+ <rect width="20" height="20" rx="10" fill="#8498A9" fill-opacity="0.7"/>
30831
+ <path d="M11.7178 12.4307C12.2201 11.9284 12.9629 11.8149 13.5752 12.0879L12.9756 12.6865C12.7427 12.6649 12.5034 12.7432 12.3223 12.917C12.3176 12.9214 12.3122 12.9251 12.3076 12.9297L11.7344 13.5029C11.4091 13.8284 11.409 14.3563 11.7344 14.6816L12.0879 15.0342C12.4133 15.3595 12.9412 15.3596 13.2666 15.0342L13.5527 14.7461L13.8408 14.46C14.011 14.2896 14.091 14.0629 14.083 13.8398L14.7002 13.2236C14.9614 13.8318 14.8443 14.5639 14.3477 15.0605L13.8613 15.5459C13.2105 16.1963 12.1556 16.1964 11.5049 15.5459L11.2314 15.2725C10.5816 14.6218 10.5815 13.5677 11.2314 12.917L11.7178 12.4307Z" fill="white"/>
30832
+ <path d="M12.1738 4.00488C11.6587 4.98031 10.6742 7.45647 10.8555 9.55762C11.3152 9.02665 12.5281 7.88542 13.7002 7.56934C13.2369 8.10318 12.5313 9.25837 12.1445 10.7949C11.6656 10.9223 11.2115 11.1723 10.835 11.5488L10.3496 12.0352C9.77429 12.6108 9.49095 13.367 9.49707 14.1211H4.72656C5.04472 13.1579 5.14564 10.847 3.00586 9.30957C4.04607 9.35761 5.61481 9.31003 6.83691 10.4141C6.66589 9.30985 6.83631 8.53141 4.90137 5.78711C5.69833 5.98284 7.68952 6.32958 8.74414 7.96875C9.20789 6.88364 10.4356 4.93597 12.1738 4.00488Z" fill="white"/>
30833
+ <path d="M14.8838 9.2666C15.5345 8.61618 16.5894 8.6153 17.2402 9.26562L17.5137 9.53906C18.164 10.19 18.1633 11.2458 17.5127 11.8965L17.0264 12.3828C16.5297 12.879 15.7985 12.9947 15.1904 12.7334L15.8115 12.1104C16.0351 12.1187 16.2619 12.0398 16.4326 11.8691L17.0068 11.2949C17.332 10.9697 17.3327 10.4417 17.0078 10.1162L16.6543 9.7627C16.3491 9.45791 15.8654 9.43902 15.5381 9.70605C15.5158 9.72417 15.4944 9.74388 15.4736 9.76465L14.9004 10.3379C14.7179 10.5204 14.6369 10.7665 14.6592 11.0049L14.0547 11.6084C13.7823 10.9964 13.8955 10.255 14.3975 9.75293L14.8838 9.2666Z" fill="white"/>
30834
+ </svg>`;
30866
30835
  /** ChannelClipPath 等内容裁剪使用的 SVG 坐标边距(与用户传入的屏幕 padding 无关) */
30867
- const PARTITION_PICKER_CONTENT_CLIP_PADDING = 50;
30868
- /** H5:子区域屏幕宽度超过该值才展示名称标签(px) */
30836
+ const PARTITION_PICKER_CONTENT_CLIP_PADDING = 0;
30837
+ /** 可选中地块 polygon / 标签 data 属性 */
30838
+ const PARTITION_BOUNDARY_ID_ATTR = 'data-partition-boundary-id';
30839
+ /** 孤立子地块命中标记(不可选中) */
30840
+ const PARTITION_ISOLATED_BOUNDARY_ID_ATTR = 'data-partition-isolated-boundary-id';
30841
+ /** H5:子区域屏幕宽度超过该值才展示名称标签(px);与气泡宽度一致 */
30869
30842
  const H5_PARTITION_LABEL_MIN_SCREEN_WIDTH_PX = 72;
30870
30843
  /** H5:名称气泡总宽度(px) */
30871
30844
  const H5_PARTITION_LABEL_WIDTH_PX = 72;
30872
- /** 边界线目标屏幕像素宽度(默认态,全缩放级别保持一致) */
30873
- const PARTITION_BOUNDARY_TARGET_SCREEN_STROKE_PX = 2;
30874
- /** 边界线目标屏幕像素宽度(hover / 选中态) */
30875
- const PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX = 2.5;
30845
+ /** Web:序号徽章与名称标签间距(px) */
30846
+ const WEB_SELECTION_ORDER_GAP_PX = 8;
30847
+ /** H5:序号徽章与名称标签间距(px) */
30848
+ const H5_SELECTION_ORDER_GAP_PX = 4;
30849
+ /** Standalone:充电桩图标最小屏幕尺寸(px),缩小全图 fit 时避免过小;放大时随 viewBox 同比缩放 */
30850
+ const PARTITION_PICKER_CHARGING_PILE_MIN_DISPLAY_PX = 16;
30851
+ /** Web 地块描边屏幕像素宽度:未选中 2px,选中 3px */
30852
+ const WEB_PARTITION_BOUNDARY_STROKE_PX = {
30853
+ default: 2,
30854
+ selected: 3,
30855
+ };
30856
+ /** H5 地块描边屏幕像素宽度:选中与否均为 1px */
30857
+ const H5_PARTITION_BOUNDARY_STROKE_PX = {
30858
+ default: 1,
30859
+ selected: 1,
30860
+ };
30876
30861
  /**
30877
30862
  * Figma bg/mapping 地图网格背景(Standalone SVG 层)
30878
30863
  * @see https://www.figma.com/design/j0DdUYf8VFkXQ8ikkA6ZzP — node 20490:84886
@@ -30880,17 +30865,17 @@ const PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX = 2.5;
30880
30865
  /** 网格区域底色,也用于容器 letterbox 留白 */
30881
30866
  const PARTITION_PICKER_GRID_BASE_COLOR = '#E3E5EB';
30882
30867
  /** 网格单元边长(SVG 地图坐标,与 viewBox 一致;zoom 时间距同比缩放) */
30883
- const PARTITION_PICKER_GRID_TILE_SIZE = 200;
30868
+ const PARTITION_PICKER_GRID_TILE_SIZE = 10;
30884
30869
  /** 网格线宽(地图坐标;随 zoom 同比缩放,不做屏幕像素恒定) */
30885
- const PARTITION_PICKER_GRID_LINE_WIDTH = 4;
30870
+ const PARTITION_PICKER_GRID_LINE_WIDTH = 0.2;
30886
30871
  /** 网格交点圆点半径(地图坐标) */
30887
- const PARTITION_PICKER_GRID_DOT_RADIUS = 8;
30872
+ const PARTITION_PICKER_GRID_DOT_RADIUS = 0.6;
30888
30873
  /** 网格层整体不透明度(Figma 约 80%) */
30889
- const PARTITION_PICKER_GRID_OPACITY = 0.8;
30874
+ const PARTITION_PICKER_GRID_OPACITY = 0.4;
30890
30875
  /** 网格线与交点颜色 */
30891
30876
  const PARTITION_PICKER_GRID_STROKE = '#FFFFFF';
30892
30877
  /** 可见范围内交点超过该数量时跳过圆点,仅保留网格线(缩小视野时减轻 DOM 压力) */
30893
- const PARTITION_PICKER_GRID_MAX_INTERSECTION_DOTS = 400;
30878
+ const PARTITION_PICKER_GRID_MAX_INTERSECTION_DOTS = 2000;
30894
30879
  /**
30895
30880
  * 分区选择地图专用样式
30896
30881
  *
@@ -30915,37 +30900,27 @@ const PARTITION_PICKER_MAP_CONFIG = {
30915
30900
  const PARTITION_PICKER_COLORS_WEB = {
30916
30901
  defaultFill: 'rgba(222, 225, 231, 1)',
30917
30902
  defaultStroke: 'rgba(132, 152, 169, 1)',
30918
- defaultStrokeWidth: 2,
30919
30903
  hoverFill: 'rgba(211, 216, 226, 1)',
30920
30904
  hoverStroke: 'rgba(132, 152, 169, 1)',
30921
- hoverStrokeWidth: 3,
30922
30905
  selectedFill: 'rgba(202, 214, 238, 1)',
30923
30906
  selectedStroke: 'rgba(132, 152, 169, 1)',
30924
- selectedStrokeWidth: 3,
30925
30907
  selectedHoverFill: 'rgba(202, 214, 238, 1)',
30926
30908
  selectedHoverStroke: 'rgba(132, 152, 169, 1)',
30927
- selectedHoverStrokeWidth: 3,
30928
30909
  isolatedFill: 'rgba(225, 227, 233, 1)',
30929
30910
  isolatedStroke: 'rgba(189, 198, 208, 1)',
30930
- isolatedStrokeWidth: 2,
30931
30911
  };
30932
30912
  /** H5 端地块配色 */
30933
30913
  const PARTITION_PICKER_COLORS_H5 = {
30934
30914
  defaultFill: 'rgba(222, 225, 231, 1)',
30935
30915
  defaultStroke: 'rgba(132, 152, 169, 1)',
30936
- defaultStrokeWidth: 1,
30937
30916
  hoverFill: 'rgba(222, 225, 231, 1)',
30938
30917
  hoverStroke: 'rgba(132, 152, 169, 1)',
30939
- hoverStrokeWidth: 1,
30940
30918
  selectedFill: 'rgba(202, 214, 238, 1)',
30941
30919
  selectedStroke: 'rgba(132, 152, 169, 1)',
30942
- selectedStrokeWidth: 1,
30943
30920
  selectedHoverFill: 'rgba(202, 214, 238, 1)',
30944
30921
  selectedHoverStroke: 'rgba(132, 152, 169, 1)',
30945
- selectedHoverStrokeWidth: 1,
30946
30922
  isolatedFill: 'rgba(225, 227, 233, 1)',
30947
30923
  isolatedStroke: 'rgba(189, 198, 208, 1)',
30948
- isolatedStrokeWidth: 1,
30949
30924
  };
30950
30925
  function getPartitionPickerMapConfig(platform = exports.PlatformType.WEB) {
30951
30926
  return platform === exports.PlatformType.WEB
@@ -30955,6 +30930,11 @@ function getPartitionPickerMapConfig(platform = exports.PlatformType.WEB) {
30955
30930
  function getPartitionPickerColors(platform = exports.PlatformType.WEB) {
30956
30931
  return platform === exports.PlatformType.WEB ? PARTITION_PICKER_COLORS_WEB : PARTITION_PICKER_COLORS_H5;
30957
30932
  }
30933
+ function getPartitionPickerBoundaryStrokePx(platform = exports.PlatformType.WEB) {
30934
+ return platform === exports.PlatformType.WEB
30935
+ ? { ...WEB_PARTITION_BOUNDARY_STROKE_PX }
30936
+ : { ...H5_PARTITION_BOUNDARY_STROKE_PX };
30937
+ }
30958
30938
  /** Web 分区名气泡(Figma「地块名称」/ 选中区域) */
30959
30939
  const PARTITION_PICKER_LABEL_STYLES_WEB = {
30960
30940
  default: {
@@ -30995,6 +30975,7 @@ const PARTITION_PICKER_LABEL_STYLES_H5 = {
30995
30975
  fontWeight: 400,
30996
30976
  padding: '6px',
30997
30977
  width: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
30978
+ maxWidth: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
30998
30979
  borderRadius: 100,
30999
30980
  boxSizing: 'border-box',
31000
30981
  },
@@ -31005,6 +30986,7 @@ const PARTITION_PICKER_LABEL_STYLES_H5 = {
31005
30986
  fontWeight: 400,
31006
30987
  padding: '6px',
31007
30988
  width: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
30989
+ maxWidth: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
31008
30990
  borderRadius: 100,
31009
30991
  boxSizing: 'border-box',
31010
30992
  },
@@ -31042,10 +31024,6 @@ const DEFAULT_PARTITION_PICKER_GRID_STYLE = {
31042
31024
  opacity: PARTITION_PICKER_GRID_OPACITY,
31043
31025
  maxIntersectionDots: PARTITION_PICKER_GRID_MAX_INTERSECTION_DOTS,
31044
31026
  };
31045
- const DEFAULT_PARTITION_PICKER_BOUNDARY_STROKE_PX = {
31046
- default: PARTITION_BOUNDARY_TARGET_SCREEN_STROKE_PX,
31047
- emphasized: PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX,
31048
- };
31049
31027
  /**
31050
31028
  * 将 platform 内置默认值与外部 pickerStyleConfig 深度合并。
31051
31029
  * 调用方只需覆盖变化的字段,无需改组件源码。
@@ -31062,8 +31040,7 @@ function resolvePartitionPickerStyles(platform = exports.PlatformType.WEB, confi
31062
31040
  }
31063
31041
  : baseLabels,
31064
31042
  grid: merge$1({}, DEFAULT_PARTITION_PICKER_GRID_STYLE, config?.grid),
31065
- boundaryStrokePx: merge$1({}, DEFAULT_PARTITION_PICKER_BOUNDARY_STROKE_PX, config?.boundaryStrokePx),
31066
- labelMinScreenWidthPx: config?.labelMinScreenWidthPx ?? H5_PARTITION_LABEL_MIN_SCREEN_WIDTH_PX,
31043
+ boundaryStrokePx: merge$1({}, getPartitionPickerBoundaryStrokePx(platform), config?.boundaryStrokePx),
31067
31044
  };
31068
31045
  }
31069
31046
 
@@ -31077,7 +31054,7 @@ function resolvePartitionPickerStyles(platform = exports.PlatformType.WEB, confi
31077
31054
  *
31078
31055
  * 平移可在地块/分区名等任意区域发起;仅当位移小于阈值时才视为点击
31079
31056
  */
31080
- function useMapViewport({ mapJson, containerRef: externalContainerRef, width, height, padding, minZoom = 0.5, maxZoom = 4, enablePanZoom = true, refitOnResize = true, onViewportTap, mapRotationDeg = 0, }) {
31057
+ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, height, padding, minZoom = 0.5, maxZoom = 3, enablePanZoom = true, refitOnResize = true, onViewportTap, mapRotationDeg = 0, }) {
31081
31058
  /** 地图容器 DOM,用于绑定 wheel/pointer/touch 事件 */
31082
31059
  const internalContainerRef = React.useRef(null);
31083
31060
  const containerRef = externalContainerRef ?? internalContainerRef;
@@ -31283,9 +31260,9 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31283
31260
  /** 位移是否超过 PAN_CLICK_THRESHOLD_PX,超过则视为拖拽 */
31284
31261
  const markPanMoved = (startX, startY, currentX, currentY) => Math.hypot(currentX - startX, currentY - startY) > PAN_CLICK_THRESHOLD_PX;
31285
31262
  /** 触发点击回调(仅当未发生拖拽时) */
31286
- const emitViewportTap = (tapTarget) => {
31263
+ const emitViewportTap = (tapTarget, clientX, clientY) => {
31287
31264
  if (tapTarget) {
31288
- onViewportTapRef.current?.(tapTarget);
31265
+ onViewportTapRef.current?.({ target: tapTarget, clientX, clientY });
31289
31266
  }
31290
31267
  };
31291
31268
  // ── 绑定容器交互事件:滚轮缩放 / 桌面拖拽 / H5 pinch+单指平移 ──
@@ -31311,7 +31288,7 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31311
31288
  if (event) {
31312
31289
  const state = pointerMapRef.current.get(event.pointerId);
31313
31290
  if (state && !state.moved && state.tapTarget) {
31314
- emitViewportTap(state.tapTarget);
31291
+ emitViewportTap(state.tapTarget, event.clientX, event.clientY);
31315
31292
  }
31316
31293
  pointerMapRef.current.delete(event.pointerId);
31317
31294
  try {
@@ -31455,13 +31432,17 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31455
31432
  if (touchState && !touchState.moved) {
31456
31433
  let tapTarget = touchState.tapTarget;
31457
31434
  const touch = event.changedTouches[0];
31435
+ let clientX = touchState.startX;
31436
+ let clientY = touchState.startY;
31458
31437
  if (touch) {
31438
+ clientX = touch.clientX;
31439
+ clientY = touch.clientY;
31459
31440
  const hitTarget = document.elementFromPoint(touch.clientX, touch.clientY);
31460
31441
  if (hitTarget instanceof Element) {
31461
31442
  tapTarget = hitTarget;
31462
31443
  }
31463
31444
  }
31464
- emitViewportTap(tapTarget);
31445
+ emitViewportTap(tapTarget, clientX, clientY);
31465
31446
  }
31466
31447
  if (pinchRef.current) {
31467
31448
  pinchRef.current = null;
@@ -31496,7 +31477,17 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31496
31477
  window.removeEventListener('mouseup', handleWindowPointerUp);
31497
31478
  window.removeEventListener('blur', handleWindowPointerUp);
31498
31479
  };
31499
- }, [applyPan, applyZoom, clearPanState, enablePanZoom, height, maxZoom, minZoom, scheduleViewBox, width]);
31480
+ }, [
31481
+ applyPan,
31482
+ applyZoom,
31483
+ clearPanState,
31484
+ enablePanZoom,
31485
+ height,
31486
+ maxZoom,
31487
+ minZoom,
31488
+ scheduleViewBox,
31489
+ width,
31490
+ ]);
31500
31491
  return {
31501
31492
  /** 绑定到地图外层容器的 ref */
31502
31493
  containerRef,
@@ -31555,10 +31546,12 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31555
31546
  /**
31556
31547
  * OverlayViewF 的 LatLngBounds:
31557
31548
  * GPS 包围盒 + defaultTransform 在 Web Mercator 下的平移偏移。
31549
+ * 仅 Map 模式(enabled)且 Google Maps 已加载时才计算。
31558
31550
  */
31559
31551
  const bounds = React.useMemo(() => {
31560
- if (!mapJson || typeof window === 'undefined' || !window.google?.maps)
31552
+ if (!enabled || !mapJson || typeof window === 'undefined' || !window.google?.maps) {
31561
31553
  return null;
31554
+ }
31562
31555
  const validBounds = getValidGpsBounds(mapJson, 0);
31563
31556
  const [swLng0, swLat0] = validBounds.sw;
31564
31557
  const [neLng0, neLat0] = validBounds.ne;
@@ -31571,7 +31564,7 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31571
31564
  const [swLng, swLat] = proj4(WEB_MERCATOR, WGS84, [swX, swY]);
31572
31565
  const [neLng, neLat] = proj4(WEB_MERCATOR, WGS84, [neX, neY]);
31573
31566
  return new window.google.maps.LatLngBounds(new window.google.maps.LatLng(swLat, swLng), new window.google.maps.LatLng(neLat, neLng));
31574
- }, [mapJson, transformX, transformY]);
31567
+ }, [enabled, mapJson, transformX, transformY]);
31575
31568
  /** OverlayViewF onDraw:解析 overlay 容器 style,得到像素 layout */
31576
31569
  const handleOverlayDraw = React.useCallback((style) => {
31577
31570
  const layout = Object.keys(style).reduce((acc, key) => {
@@ -31586,8 +31579,9 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31586
31579
  }, []);
31587
31580
  /** Map 模式 fitToView:调用 google.maps.Map.fitBounds,考虑旋转后的 GPS 包围盒 */
31588
31581
  const fitToView = React.useCallback((nextPadding) => {
31589
- if (!enabled || !mapRef || !mapJson)
31582
+ if (!enabled || !mapRef || !mapJson || typeof window === 'undefined' || !window.google?.maps) {
31590
31583
  return;
31584
+ }
31591
31585
  const rotate = transformRotation + originNorthRotate;
31592
31586
  const validBounds = getValidGpsBounds(mapJson, rotate);
31593
31587
  const [swLng0, swLat0] = validBounds.sw;
@@ -31636,7 +31630,7 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31636
31630
  const listener = mapRef.addListener('zoom_changed', handleZoomChanged);
31637
31631
  updateScale();
31638
31632
  return () => {
31639
- if (listener) {
31633
+ if (listener && window.google?.maps?.event) {
31640
31634
  window.google.maps.event.removeListener(listener);
31641
31635
  }
31642
31636
  handleZoomChanged.cancel();
@@ -31896,19 +31890,15 @@ function usePartitionLabelItems(mapData, viewBox, containerWidth, containerHeigh
31896
31890
  ]);
31897
31891
  }
31898
31892
 
31899
- var css_248z = "@charset \"UTF-8\";\n/* 地图容器:裁剪溢出,禁用浏览器默认 touch 手势以便自定义 pinch */\n.index-module_container__nNYv7 {\n position: relative;\n overflow: hidden;\n touch-action: none;\n user-select: none;\n cursor: grab;\n /* H5 点击时不出现矩形 tap 高亮 */\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n}\n\n/* 网格 + 地块双层 SVG 叠放,共用 viewBox 保证平移/缩放同步 */\n.index-module_mapSvgStack__nz2s2 {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 1;\n}\n\n.index-module_gridSvg__MoJD6 {\n position: absolute;\n inset: 0;\n display: block;\n pointer-events: none;\n}\n\n/* 地图 SVG:地块/通道,可绕 viewBox 中心旋转 */\n.index-module_mapSvg__vN0LV {\n position: absolute;\n inset: 0;\n display: block;\n pointer-events: none;\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n}\n\n/* 可点击地块:点击选中由 viewport 统一处理,此处保留 hover */\n.index-module_boundaryPolygon__uHe-E {\n cursor: grab;\n pointer-events: auto;\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n outline: none;\n -webkit-touch-callout: none;\n}\n\n.index-module_container__nNYv7:active {\n cursor: grabbing;\n}\n\n.index-module_boundaryPolygon__uHe-E:active {\n cursor: grabbing;\n}\n\n/* Map 模式:OverlayViewF 内根节点,铺满 overlay 像素区域 */\n.index-module_googleOverlayRoot__TQ3II {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: visible;\n}\n\n/* HTML overlay 层:CSS rotate 与 MowerMapRenderer OverlayViewF 一致,子元素自行反向补偿 */\n.index-module_mapOverlayLayer__7jTDy {\n position: absolute;\n inset: 0;\n transform-origin: 50% 50%;\n pointer-events: none;\n z-index: 2;\n}\n\n/* 分区名气泡层,绝对定位覆盖在 SVG 之上 */\n.index-module_labelsLayer__Rcikw {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.index-module_label__xo3Kc {\n position: absolute;\n display: flex;\n flex-direction: column;\n align-items: center;\n pointer-events: auto;\n cursor: grab;\n white-space: nowrap;\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n outline: none;\n -webkit-touch-callout: none;\n}\n\n.index-module_label__xo3Kc:active {\n cursor: grabbing;\n}\n\n.index-module_labelWithOrder__uiHNo {\n gap: 8px;\n}\n\n.index-module_labelWithOrderH5__fg3nU {\n gap: 4px;\n}\n\n.index-module_labelOrderOnly__TDLBU {\n gap: 0;\n}\n\n/* H5 名称标签:总宽 72px,文案最大 60px 可换行 */\n.index-module_labelH5Wrap__Es5cA {\n white-space: normal;\n}\n\n.index-module_labelPill__7jnOo {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n}\n\n.index-module_labelPillH5__iPeHi {\n width: 72px;\n max-width: 72px;\n box-sizing: border-box;\n}\n\n.index-module_labelText__ialST {\n word-break: break-word;\n text-align: center;\n}\n\n.index-module_labelTextH5__jz8SO {\n max-width: 60px;\n white-space: normal;\n overflow-wrap: anywhere;\n line-height: 1.33;\n}\n\n/* 选中序号徽章:尺寸与颜色由 constants 按 platform 注入 */\n.index-module_selectionOrderBadge__uj7LX {\n flex-shrink: 0;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.index-module_boundaryPolygonIsolated__syN4V {\n cursor: not-allowed;\n}\n\n.index-module_boundaryPolygonIsolated__syN4V:active {\n cursor: grabbing;\n}\n\n.index-module_labelIsolated__K3WAB {\n cursor: not-allowed;\n pointer-events: auto;\n}\n\n.index-module_labelIsolated__K3WAB:active {\n cursor: grabbing;\n}\n\n.index-module_labelIsolatedLayout__k-rwI {\n gap: 4px;\n}\n\n.index-module_isolatedIconBelow__PuVIF {\n position: static;\n transform: none;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n pointer-events: none;\n}\n\n.index-module_isolatedIconBelow__PuVIF.index-module_isolatedIconWeb__iPkYp {\n width: 20px;\n height: 20px;\n}\n\n.index-module_isolatedIcon__Vbxl0 {\n position: absolute;\n width: 24px;\n height: 24px;\n left: 50%;\n bottom: calc(100% + 4px);\n transform: translateX(-50%);\n}\n\n.index-module_isolatedIconWeb__iPkYp {\n width: 20px;\n height: 20px;\n bottom: calc(100% + 2px);\n}";
31900
- var styles = {"container":"index-module_container__nNYv7","mapSvgStack":"index-module_mapSvgStack__nz2s2","gridSvg":"index-module_gridSvg__MoJD6","mapSvg":"index-module_mapSvg__vN0LV","boundaryPolygon":"index-module_boundaryPolygon__uHe-E","googleOverlayRoot":"index-module_googleOverlayRoot__TQ3II","mapOverlayLayer":"index-module_mapOverlayLayer__7jTDy","labelsLayer":"index-module_labelsLayer__Rcikw","label":"index-module_label__xo3Kc","labelWithOrder":"index-module_labelWithOrder__uiHNo","labelWithOrderH5":"index-module_labelWithOrderH5__fg3nU","labelOrderOnly":"index-module_labelOrderOnly__TDLBU","labelH5Wrap":"index-module_labelH5Wrap__Es5cA","labelPill":"index-module_labelPill__7jnOo","labelPillH5":"index-module_labelPillH5__iPeHi","labelText":"index-module_labelText__ialST","labelTextH5":"index-module_labelTextH5__jz8SO","selectionOrderBadge":"index-module_selectionOrderBadge__uj7LX","boundaryPolygonIsolated":"index-module_boundaryPolygonIsolated__syN4V","labelIsolated":"index-module_labelIsolated__K3WAB","labelIsolatedLayout":"index-module_labelIsolatedLayout__k-rwI","isolatedIconBelow":"index-module_isolatedIconBelow__PuVIF","isolatedIconWeb":"index-module_isolatedIconWeb__iPkYp"};
31893
+ var css_248z = "@charset \"UTF-8\";\n/* 地图容器:裁剪溢出,禁用浏览器默认 touch 手势以便自定义 pinch */\n.index-module_container__nNYv7 {\n position: relative;\n overflow: hidden;\n touch-action: none;\n user-select: none;\n cursor: grab;\n /* H5 点击时不出现矩形 tap 高亮 */\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n}\n\n/* 网格 + 地块双层 SVG 叠放,共用 viewBox 保证平移/缩放同步 */\n.index-module_mapSvgStack__nz2s2 {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 1;\n}\n\n.index-module_gridSvg__MoJD6 {\n position: absolute;\n inset: 0;\n display: block;\n pointer-events: none;\n}\n\n/* 地图 SVG:地块/通道,可绕 viewBox 中心旋转 */\n.index-module_mapSvg__vN0LV {\n position: absolute;\n inset: 0;\n display: block;\n pointer-events: none;\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n}\n\n/* 可点击地块:悬停显示 pointer,与地图容器 grab 区分 */\n.index-module_boundaryPolygon__uHe-E {\n cursor: pointer;\n pointer-events: auto;\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n outline: none;\n -webkit-touch-callout: none;\n}\n\n.index-module_container__nNYv7:active {\n cursor: grabbing;\n}\n\n/* Map 模式:OverlayViewF 内根节点,铺满 overlay 像素区域 */\n.index-module_googleOverlayRoot__TQ3II {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: visible;\n}\n\n/* HTML overlay 层:CSS rotate 与 MowerMapRenderer OverlayViewF 一致,子元素自行反向补偿 */\n.index-module_mapOverlayLayer__7jTDy {\n position: absolute;\n inset: 0;\n transform-origin: 50% 50%;\n pointer-events: none;\n z-index: 2;\n}\n\n/* 分区名气泡层,绝对定位覆盖在 SVG 之上 */\n.index-module_labelsLayer__Rcikw {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.index-module_label__xo3Kc {\n position: absolute;\n display: flex;\n flex-direction: column;\n align-items: center;\n pointer-events: auto;\n cursor: pointer;\n white-space: nowrap;\n -webkit-tap-highlight-color: transparent;\n tap-highlight-color: transparent;\n outline: none;\n -webkit-touch-callout: none;\n}\n\n.index-module_labelOrderOnly__TDLBU {\n gap: 0;\n}\n\n/* H5 名称标签:气泡宽度 / 文案最大宽度由 constants.ts 内联样式控制 */\n.index-module_labelH5Wrap__Es5cA {\n white-space: normal;\n}\n\n.index-module_labelPill__7jnOo {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n}\n\n.index-module_labelPillH5__iPeHi {\n box-sizing: border-box;\n}\n\n.index-module_labelText__ialST {\n word-break: break-word;\n text-align: center;\n}\n\n.index-module_labelTextH5__jz8SO {\n max-width: 100%;\n white-space: normal;\n overflow-wrap: anywhere;\n line-height: 1.33;\n}\n\n/* 选中序号徽章:尺寸与颜色由 constants 按 platform 注入 */\n.index-module_selectionOrderBadge__uj7LX {\n flex-shrink: 0;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.index-module_boundaryPolygonIsolated__syN4V {\n cursor: not-allowed;\n}\n\n.index-module_boundaryPolygonIsolated__syN4V:active {\n cursor: grabbing;\n}\n\n.index-module_labelIsolated__K3WAB {\n cursor: not-allowed;\n pointer-events: auto;\n}\n\n.index-module_labelIsolated__K3WAB:active {\n cursor: grabbing;\n}\n\n.index-module_labelIsolatedLayout__k-rwI {\n gap: 4px;\n}\n\n.index-module_isolatedIconBelow__PuVIF {\n position: static;\n transform: none;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n pointer-events: none;\n}";
31894
+ var styles = {"container":"index-module_container__nNYv7","mapSvgStack":"index-module_mapSvgStack__nz2s2","gridSvg":"index-module_gridSvg__MoJD6","mapSvg":"index-module_mapSvg__vN0LV","boundaryPolygon":"index-module_boundaryPolygon__uHe-E","googleOverlayRoot":"index-module_googleOverlayRoot__TQ3II","mapOverlayLayer":"index-module_mapOverlayLayer__7jTDy","labelsLayer":"index-module_labelsLayer__Rcikw","label":"index-module_label__xo3Kc","labelOrderOnly":"index-module_labelOrderOnly__TDLBU","labelH5Wrap":"index-module_labelH5Wrap__Es5cA","labelPill":"index-module_labelPill__7jnOo","labelPillH5":"index-module_labelPillH5__iPeHi","labelText":"index-module_labelText__ialST","labelTextH5":"index-module_labelTextH5__jz8SO","selectionOrderBadge":"index-module_selectionOrderBadge__uj7LX","boundaryPolygonIsolated":"index-module_boundaryPolygonIsolated__syN4V","labelIsolated":"index-module_labelIsolated__K3WAB","labelIsolatedLayout":"index-module_labelIsolatedLayout__k-rwI","isolatedIconBelow":"index-module_isolatedIconBelow__PuVIF"};
31901
31895
  styleInject(css_248z);
31902
31896
 
31903
- const PARTITION_BOUNDARY_ID_ATTR$1 = 'data-partition-boundary-id';
31904
- const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isIsolated = false, selected, hovered, viewBoxWidth, viewBoxHeight, fitViewBox, containerWidth, containerHeight, onHoverChange, onBoundaryClick, }) => {
31897
+ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isIsolated = false, selected, hovered, viewBoxWidth, viewBoxHeight, containerWidth, containerHeight, onHoverChange, onBoundaryClick, onIsolatedTap, }) => {
31905
31898
  const style = data.style || {};
31906
31899
  const boundaryId = Number(data.id);
31907
31900
  const colors = boundaryColors;
31908
- const strokePx = boundaryStrokePx ?? {
31909
- default: PARTITION_BOUNDARY_TARGET_SCREEN_STROKE_PX,
31910
- emphasized: PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX,
31911
- };
31901
+ const strokePx = boundaryStrokePx ?? { ...WEB_PARTITION_BOUNDARY_STROKE_PX };
31912
31902
  const pointsString = React.useMemo(() => data.points.map((point) => `${point[0]},${point[1]}`).join(' '), [data.points]);
31913
31903
  const fillColor = React.useMemo(() => {
31914
31904
  if (isIsolated)
@@ -31931,31 +31921,16 @@ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isI
31931
31921
  return style.lineColor || colors.defaultStroke;
31932
31922
  }, [colors, hovered, isIsolated, selected, style.lineColor]);
31933
31923
  const strokeWidth = React.useMemo(() => {
31934
- let baseWidth;
31935
- let emphasized = false;
31936
- if (isIsolated)
31937
- baseWidth = colors.isolatedStrokeWidth;
31938
- else if (selected) {
31939
- emphasized = true;
31940
- baseWidth = hovered ? colors.selectedHoverStrokeWidth : colors.selectedStrokeWidth;
31941
- }
31942
- else if (hovered) {
31943
- emphasized = true;
31944
- baseWidth = colors.hoverStrokeWidth;
31945
- }
31946
- else
31947
- baseWidth = colors.defaultStrokeWidth;
31948
31924
  const viewBox = { width: viewBoxWidth, height: viewBoxHeight };
31949
- return scaleStrokeWidthForViewBox(baseWidth, viewBox, fitViewBox, {
31925
+ const targetScreenStrokePx = !isIsolated && (selected || hovered) ? strokePx.selected : strokePx.default;
31926
+ return scaleStrokeWidthForViewBox(viewBox, {
31950
31927
  containerWidth,
31951
31928
  containerHeight,
31952
- minScreenStrokePx: emphasized ? strokePx.emphasized : strokePx.default,
31929
+ targetScreenStrokePx,
31953
31930
  });
31954
31931
  }, [
31955
- colors,
31956
31932
  containerHeight,
31957
31933
  containerWidth,
31958
- fitViewBox,
31959
31934
  hovered,
31960
31935
  isIsolated,
31961
31936
  selected,
@@ -31964,9 +31939,14 @@ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isI
31964
31939
  viewBoxWidth,
31965
31940
  ]);
31966
31941
  if (isIsolated) {
31967
- return (jsxRuntime.jsx("polygon", { className: `${styles.boundaryPolygon} ${styles.boundaryPolygonIsolated}`, points: pointsString, fill: fillColor, stroke: strokeColor, strokeWidth: strokeWidth, strokeLinejoin: "round" }));
31942
+ return (jsxRuntime.jsx("polygon", { className: `${styles.boundaryPolygon} ${styles.boundaryPolygonIsolated}`, points: pointsString, fill: fillColor, stroke: strokeColor, strokeWidth: strokeWidth, strokeLinejoin: "round", [PARTITION_ISOLATED_BOUNDARY_ID_ATTR]: boundaryId, onClick: onIsolatedTap
31943
+ ? (event) => {
31944
+ event.stopPropagation();
31945
+ onIsolatedTap(boundaryId, event.clientX, event.clientY);
31946
+ }
31947
+ : undefined }));
31968
31948
  }
31969
- return (jsxRuntime.jsx("polygon", { className: styles.boundaryPolygon, points: pointsString, fill: fillColor, stroke: strokeColor, strokeWidth: strokeWidth, strokeLinejoin: "round", [PARTITION_BOUNDARY_ID_ATTR$1]: boundaryId, onMouseEnter: () => onHoverChange(boundaryId), onMouseLeave: () => onHoverChange(null), onClick: onBoundaryClick
31949
+ return (jsxRuntime.jsx("polygon", { className: styles.boundaryPolygon, points: pointsString, fill: fillColor, stroke: strokeColor, strokeWidth: strokeWidth, strokeLinejoin: "round", [PARTITION_BOUNDARY_ID_ATTR]: boundaryId, onMouseEnter: () => onHoverChange(boundaryId), onMouseLeave: () => onHoverChange(null), onClick: onBoundaryClick
31970
31950
  ? (event) => {
31971
31951
  event.stopPropagation();
31972
31952
  onBoundaryClick(boundaryId);
@@ -31975,7 +31955,7 @@ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isI
31975
31955
  };
31976
31956
  var SelectableBoundaryElement$1 = React.memo(SelectableBoundaryElement);
31977
31957
 
31978
- const PartitionPickerSvg = ({ svgElementDatas, viewBox, fitViewBox, containerWidth, containerHeight, mapRotation = 0, boundaryColors, boundaryStrokePx, isolatedBoundaryIds, selectedIds, hoveredId, onHoverChange, onBoundaryClick, }) => {
31958
+ const PartitionPickerSvg = ({ svgElementDatas, viewBox, containerWidth, containerHeight, mapRotation = 0, boundaryColors, boundaryStrokePx, isolatedBoundaryIds, selectedIds, hoveredId, onHoverChange, onBoundaryClick, onIsolatedTap, }) => {
31979
31959
  const boundaries = (svgElementDatas[exports.DataType.BOUNDARY] || []);
31980
31960
  const channels = (svgElementDatas[exports.DataType.CHANNEL] || []);
31981
31961
  const selectedIdSet = React.useMemo(() => new Set(selectedIds), [selectedIds]);
@@ -31987,7 +31967,7 @@ const PartitionPickerSvg = ({ svgElementDatas, viewBox, fitViewBox, containerWid
31987
31967
  }, [mapRotation, viewBox.x, viewBox.y, viewBox.width, viewBox.height]);
31988
31968
  const mapContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(GElement, { type: "boundary", children: boundaries.map((item) => {
31989
31969
  const boundaryId = Number(item.id);
31990
- return (jsxRuntime.jsx(SelectableBoundaryElement$1, { data: item, boundaryColors: boundaryColors, boundaryStrokePx: boundaryStrokePx, isIsolated: isolatedBoundaryIds.has(boundaryId), selected: selectedIdSet.has(boundaryId), hovered: hoveredId === boundaryId, viewBoxWidth: viewBox.width, viewBoxHeight: viewBox.height, fitViewBox: fitViewBox, containerWidth: containerWidth, containerHeight: containerHeight, onHoverChange: onHoverChange, onBoundaryClick: onBoundaryClick }, item.id));
31970
+ return (jsxRuntime.jsx(SelectableBoundaryElement$1, { data: item, boundaryColors: boundaryColors, boundaryStrokePx: boundaryStrokePx, isIsolated: isolatedBoundaryIds.has(boundaryId), selected: selectedIdSet.has(boundaryId), hovered: hoveredId === boundaryId, viewBoxWidth: viewBox.width, viewBoxHeight: viewBox.height, containerWidth: containerWidth, containerHeight: containerHeight, onHoverChange: onHoverChange, onBoundaryClick: onBoundaryClick, onIsolatedTap: onIsolatedTap }, item.id));
31991
31971
  }) }), jsxRuntime.jsxs(GElement, { type: "channel", children: [jsxRuntime.jsx(ChannelClipPath, {}), channels.map((item) => (jsxRuntime.jsx(ChannelElement, { data: item }, item.id)))] })] }));
31992
31972
  return (jsxRuntime.jsx("svg", { className: styles.mapSvg, xmlns: "http://www.w3.org/2000/svg", viewBox: viewBoxToString(viewBox), width: "100%", height: "100%", preserveAspectRatio: "xMidYMid meet", shapeRendering: "geometricPrecision", children: mapContentTransform ? (jsxRuntime.jsx("g", { transform: mapContentTransform, children: mapContent })) : (mapContent) }));
31993
31973
  };
@@ -32022,15 +32002,31 @@ const MapGridBackground = ({ viewBox, gridStyle }) => {
32022
32002
  const patternId = React.useMemo(() => `partition-picker-grid-lines-${reactId.replace(/:/g, '-')}`, [reactId]);
32023
32003
  const { baseColor, strokeColor, tileSize: tile, lineWidth, dotRadius, opacity, maxIntersectionDots, } = gridStyle;
32024
32004
  const intersections = React.useMemo(() => getVisibleGridIntersections(viewBox, tile, maxIntersectionDots), [maxIntersectionDots, tile, viewBox.x, viewBox.y, viewBox.width, viewBox.height]);
32025
- return (jsxRuntime.jsxs("g", { className: "partition-picker-grid-bg", "aria-hidden": true, pointerEvents: "none", children: [jsxRuntime.jsx("defs", { children: jsxRuntime.jsxs("pattern", { id: patternId, patternUnits: "userSpaceOnUse", width: tile, height: tile, children: [jsxRuntime.jsx("line", { x1: 0, y1: 0, x2: tile, y2: 0, stroke: strokeColor, strokeWidth: lineWidth }), jsxRuntime.jsx("line", { x1: 0, y1: 0, x2: 0, y2: tile, stroke: strokeColor, strokeWidth: lineWidth })] }) }), jsxRuntime.jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: baseColor }), jsxRuntime.jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: `url(#${patternId})`, opacity: opacity }), jsxRuntime.jsx("g", { opacity: opacity, children: intersections.map((point, index) => (jsxRuntime.jsx("circle", { cx: point.x, cy: point.y, r: dotRadius, fill: strokeColor }, `${point.x}-${point.y}-${index}`))) })] }));
32005
+ /**
32006
+ * SVG stroke 以路径为中心;线在 tile 的 0 边绘制时,四格交点的视觉中心会偏向路径右下。
32007
+ * 线条内缩 lineWidth/2,圆点同步偏移,使圆心与网格线交叉中心对齐。
32008
+ */
32009
+ const lineHalf = lineWidth / 2;
32010
+ return (jsxRuntime.jsxs("g", { className: "partition-picker-grid-bg", "aria-hidden": true, pointerEvents: "none", children: [jsxRuntime.jsx("defs", { children: jsxRuntime.jsxs("pattern", { id: patternId, patternUnits: "userSpaceOnUse", width: tile, height: tile, children: [jsxRuntime.jsx("line", { x1: 0, y1: lineHalf, x2: tile, y2: lineHalf, stroke: strokeColor, strokeWidth: lineWidth }), jsxRuntime.jsx("line", { x1: lineHalf, y1: 0, x2: lineHalf, y2: tile, stroke: strokeColor, strokeWidth: lineWidth })] }) }), jsxRuntime.jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: baseColor }), jsxRuntime.jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: `url(#${patternId})`, opacity: opacity }), jsxRuntime.jsx("g", { opacity: opacity, children: intersections.map((point, index) => (jsxRuntime.jsx("circle", { cx: point.x + lineHalf, cy: point.y + lineHalf, r: dotRadius, fill: strokeColor }, `${point.x}-${point.y}-${index}`))) })] }));
32026
32011
  };
32027
32012
  var MapGridBackground$1 = React.memo(MapGridBackground);
32028
32013
 
32029
32014
  const PartitionPickerGridSvg = ({ viewBox, gridStyle }) => {
32030
- return (jsxRuntime.jsx("svg", { className: styles.gridSvg, "data-viewport-background": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: viewBoxToString(viewBox), width: "100%", height: "100%", preserveAspectRatio: "xMidYMid meet", shapeRendering: "geometricPrecision", "aria-hidden": true, children: jsxRuntime.jsx(MapGridBackground$1, { viewBox: viewBox, gridStyle: gridStyle }) }));
32015
+ return (jsxRuntime.jsx("svg", { className: styles.gridSvg, "data-viewport-background": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: viewBoxToString(viewBox), width: "100%", height: "100%",
32016
+ // 设置缩放的规则
32017
+ //等比缩放 viewBox 内容,使其完整落在容器内;
32018
+ //水平、垂直都居中;
32019
+ //比例不一致时,上下或左右留空(letterboxing),不裁切、不拉伸变形。
32020
+ preserveAspectRatio: "xMidYMid meet",
32021
+ /**
32022
+ * 控制浏览器如何绘制路径/线条:
32023
+ * geometricPrecision:优先几何精度,线条更平滑、对齐更稳,缩放时不易发虚或抖动。
32024
+ * 网格是大量细线,用这个属性能让缩放/平移时网格更清晰稳定。
32025
+ */
32026
+ shapeRendering: "geometricPrecision", "aria-hidden": true, children: jsxRuntime.jsx(MapGridBackground$1, { viewBox: viewBox, gridStyle: gridStyle }) }));
32031
32027
  };
32032
32028
 
32033
- const PartitionNameLabels = ({ items, selectedIds, labelStyles, labelMinScreenWidthPx = 72, platform = exports.PlatformType.WEB, showSelectionOrder = false, rotation = 0, onHoverChange, onBoundaryClick, }) => {
32029
+ const PartitionNameLabels = ({ items, selectedIds, labelStyles, platform = exports.PlatformType.WEB, showSelectionOrder = false, rotation = 0, onHoverChange, onBoundaryClick, onIsolatedTap, }) => {
32034
32030
  const isWeb = platform === exports.PlatformType.WEB;
32035
32031
  const orderBadgeStyle = React.useMemo(() => ({
32036
32032
  width: labelStyles.selectionOrderBadge.width,
@@ -32040,18 +32036,18 @@ const PartitionNameLabels = ({ items, selectedIds, labelStyles, labelMinScreenWi
32040
32036
  color: labelStyles.selectionOrderBadge.color,
32041
32037
  fontSize: `${labelStyles.selectionOrderBadge.fontSize}px`,
32042
32038
  fontWeight: labelStyles.selectionOrderBadge.fontWeight,
32039
+ fontFamily: labelStyles.selectionOrderBadge.fontFamily,
32043
32040
  lineHeight: labelStyles.selectionOrderBadge.lineHeight,
32044
32041
  }), [labelStyles]);
32045
32042
  return (jsxRuntime.jsx("div", { className: styles.labelsLayer, children: items.map((item) => {
32046
32043
  const isIsolated = item.isIsolated === true;
32047
32044
  const selected = !isIsolated && selectedIds.includes(item.id);
32048
32045
  const selectionOrder = selected ? selectedIds.indexOf(item.id) + 1 : null;
32049
- const isLargeEnough = item.screenWidthPx > labelMinScreenWidthPx;
32046
+ const isLargeEnough = item.screenWidthPx > H5_PARTITION_LABEL_MIN_SCREEN_WIDTH_PX;
32050
32047
  // Web 始终展示名称;H5 按屏幕宽度决定
32051
32048
  const showNameLabel = isWeb || isLargeEnough;
32052
32049
  const showOrderBadge = showSelectionOrder && selected && selectionOrder != null;
32053
32050
  const h5OrderOnly = !isWeb && showOrderBadge && !isLargeEnough;
32054
- const h5OrderWithName = !isWeb && showOrderBadge && isLargeEnough;
32055
32051
  if (!showNameLabel && !showOrderBadge && !isIsolated) {
32056
32052
  return null;
32057
32053
  }
@@ -32060,33 +32056,41 @@ const PartitionNameLabels = ({ items, selectedIds, labelStyles, labelMinScreenWi
32060
32056
  styles.label,
32061
32057
  !isWeb && showNameLabel ? styles.labelH5Wrap : '',
32062
32058
  isIsolated ? styles.labelIsolated : '',
32063
- isWeb && showOrderBadge ? styles.labelWithOrder : '',
32064
- h5OrderWithName ? styles.labelWithOrderH5 : '',
32065
32059
  h5OrderOnly ? styles.labelOrderOnly : '',
32066
32060
  isIsolated ? styles.labelIsolatedLayout : '',
32067
32061
  ]
32068
32062
  .filter(Boolean)
32069
32063
  .join(' ');
32070
- const boundaryIdProps = isIsolated ? {} : { [PARTITION_BOUNDARY_ID_ATTR$1]: item.id };
32064
+ const showOrderWithName = showOrderBadge && showNameLabel;
32065
+ const selectionOrderGapPx = isWeb ? WEB_SELECTION_ORDER_GAP_PX : H5_SELECTION_ORDER_GAP_PX;
32066
+ const boundaryIdProps = isIsolated
32067
+ ? { [PARTITION_ISOLATED_BOUNDARY_ID_ATTR]: item.id }
32068
+ : { [PARTITION_BOUNDARY_ID_ATTR]: item.id };
32071
32069
  return (jsxRuntime.jsxs("div", { className: labelClassName, style: {
32072
32070
  left: `${item.leftPct}%`,
32073
32071
  top: `${item.topPct}%`,
32074
32072
  transform: `translate(-50%, -50%) rotate(${-rotation}deg)`,
32075
- }, ...boundaryIdProps, onMouseEnter: isIsolated ? undefined : () => onHoverChange(item.id), onMouseLeave: isIsolated ? undefined : () => onHoverChange(null), onClick: onBoundaryClick && !isIsolated
32076
- ? (event) => {
32077
- event.stopPropagation();
32078
- onBoundaryClick(item.id);
32079
- }
32080
- : undefined, children: [showOrderBadge && (jsxRuntime.jsx("div", { className: styles.selectionOrderBadge, style: orderBadgeStyle, children: selectionOrder })), showNameLabel && (jsxRuntime.jsx("div", { className: `${styles.labelPill} ${!isWeb ? styles.labelPillH5 : ''}`, style: pillStyle, children: jsxRuntime.jsx("span", { className: `${styles.labelText} ${!isWeb ? styles.labelTextH5 : ''}`, children: item.name }) })), isIsolated && (jsxRuntime.jsx("div", { className: `${styles.isolatedIconBelow} ${isWeb ? styles.isolatedIconWeb : ''}`, dangerouslySetInnerHTML: { __html: ISOLATED_BOUNDARY_SVG } }))] }, item.id));
32073
+ ...(showOrderWithName ? { gap: selectionOrderGapPx } : undefined),
32074
+ }, ...boundaryIdProps, onMouseEnter: isIsolated ? undefined : () => onHoverChange(item.id), onMouseLeave: isIsolated ? undefined : () => onHoverChange(null), onClick: isIsolated
32075
+ ? onIsolatedTap
32076
+ ? (event) => {
32077
+ event.stopPropagation();
32078
+ onIsolatedTap(item.id, event.clientX, event.clientY);
32079
+ }
32080
+ : undefined
32081
+ : onBoundaryClick
32082
+ ? (event) => {
32083
+ event.stopPropagation();
32084
+ onBoundaryClick(item.id);
32085
+ }
32086
+ : undefined, children: [showOrderBadge && (jsxRuntime.jsx("div", { className: styles.selectionOrderBadge, style: orderBadgeStyle, children: selectionOrder })), showNameLabel && (jsxRuntime.jsx("div", { className: `${styles.labelPill} ${!isWeb ? styles.labelPillH5 : ''}`, style: pillStyle, children: jsxRuntime.jsx("span", { className: `${styles.labelText} ${!isWeb ? styles.labelTextH5 : ''}`, children: item.name }) })), isIsolated && (jsxRuntime.jsx("div", { className: `${styles.isolatedIconBelow}`, dangerouslySetInnerHTML: { __html: ISOLATED_BOUNDARY_SVG_2 } }))] }, item.id));
32081
32087
  }) }));
32082
32088
  };
32083
32089
 
32084
32090
  const DEFAULT_BACKGROUND = PARTITION_PICKER_GRID_BASE_COLOR;
32085
- /** 地块 polygon / 标签上的 data 属性,供 viewport 点击命中与表格联动 */
32086
- const PARTITION_BOUNDARY_ID_ATTR = 'data-partition-boundary-id';
32087
32091
  /** Map 模式下 OverlayViewF 默认 z-index */
32088
32092
  const DEFAULT_OVERLAY_Z_INDEX = 100;
32089
- const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerStyleConfig, sn = '', platform = exports.PlatformType.WEB, width, height, padding = 50, backgroundColor = DEFAULT_BACKGROUND, defaultTransform, mapRef, minZoom = 0.5, maxZoom = 4, enablePanZoom = true, refitOnResize = true, onSizeChange, selectedBoundaryIds, defaultSelectedBoundaryIds, onSelectionChange, hoveredBoundaryId, defaultHoveredBoundaryId, onBoundaryHoverChange, showSelectionOrder = false, zIndex = DEFAULT_OVERLAY_Z_INDEX, className, style, }, ref) => {
32093
+ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerStyleConfig, sn = '', platform = exports.PlatformType.WEB, width, height, padding = 0, backgroundColor = DEFAULT_BACKGROUND, defaultTransform, mapRef, minZoom = 0.5, maxZoom = 3, enablePanZoom = true, refitOnResize = true, onSizeChange, selectedBoundaryIds, defaultSelectedBoundaryIds, onSelectionChange, hoveredBoundaryId, defaultHoveredBoundaryId, onBoundaryHoverChange, showSelectionOrder = false, onIsolatedBoundaryTap, zIndex = DEFAULT_OVERLAY_Z_INDEX, className, style, }, ref) => {
32090
32094
  /**
32091
32095
  * 是否为 Map 模式(传入 mapRef 时为 true):
32092
32096
  * - true:Google Maps 底图 + OverlayViewF,平移/缩放/fit 由底图负责
@@ -32097,8 +32101,34 @@ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerSt
32097
32101
  const channelClipPathId = React.useMemo(() => createChannelClipPathId({ sn, reactId: reactInstanceId }), [sn, reactInstanceId]);
32098
32102
  /** 外部 pickerStyleConfig 与内置 platform 默认值合并后的最终外观(地块/标签/网格等) */
32099
32103
  const mergedPickerStyles = React.useMemo(() => resolvePartitionPickerStyles(platform, pickerStyleConfig), [pickerStyleConfig, platform]);
32100
- /** Standalone 容器留白与网格底色;pickerStyleConfig.grid.baseColor 优先于 backgroundColor */
32101
- const resolvedBackgroundColor = pickerStyleConfig?.grid?.baseColor ?? backgroundColor ?? DEFAULT_BACKGROUND;
32104
+ /** Standalone 容器背景与 grid.baseColor 对齐(合并后的最终值) */
32105
+ const resolvedBackgroundColor = React.useMemo(() => {
32106
+ if (isMapMode)
32107
+ return undefined;
32108
+ if (pickerStyleConfig?.grid?.baseColor != null) {
32109
+ return mergedPickerStyles.grid.baseColor;
32110
+ }
32111
+ return backgroundColor ?? mergedPickerStyles.grid.baseColor;
32112
+ }, [
32113
+ backgroundColor,
32114
+ isMapMode,
32115
+ mergedPickerStyles.grid.baseColor,
32116
+ pickerStyleConfig?.grid?.baseColor,
32117
+ ]);
32118
+ /** Standalone 网格层:backgroundColor 未显式指定 grid.baseColor 时与容器背景同步 */
32119
+ const standaloneGridStyle = React.useMemo(() => {
32120
+ if (pickerStyleConfig?.grid?.baseColor != null) {
32121
+ return mergedPickerStyles.grid;
32122
+ }
32123
+ if (backgroundColor != null) {
32124
+ return { ...mergedPickerStyles.grid, baseColor: backgroundColor };
32125
+ }
32126
+ return mergedPickerStyles.grid;
32127
+ }, [
32128
+ backgroundColor,
32129
+ mergedPickerStyles.grid,
32130
+ pickerStyleConfig?.grid?.baseColor,
32131
+ ]);
32102
32132
  const mergedMapConfig = React.useMemo(() => merge$1({}, DEFAULT_STYLES, getPartitionPickerMapConfig(platform), mapConfig), [mapConfig, platform]);
32103
32133
  const svgElementDatas = React.useMemo(() => UnifiedMapDataProcessor.processMapData(mapJson, mergedMapConfig) || {}, [mapJson, mergedMapConfig]);
32104
32134
  /** 地图 Y 轴相对正北的偏移(度),与 MowerMapRenderer.originNorthRotate 一致 */
@@ -32119,6 +32149,24 @@ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerSt
32119
32149
  }, [mapJson]);
32120
32150
  /** 孤立地块 id 列表(未连接到主地块的子地块) */
32121
32151
  const isolatedBoundaryIds = useIsolatedBoundaryIds(mapJson);
32152
+ const boundaryNameById = React.useMemo(() => {
32153
+ const names = new Map();
32154
+ for (const boundary of generateBoundaryData(mapJson)) {
32155
+ names.set(boundary.id, boundary.name);
32156
+ }
32157
+ return names;
32158
+ }, [mapJson]);
32159
+ const handleIsolatedTap = React.useCallback((boundaryId, clientX, clientY) => {
32160
+ if (!onIsolatedBoundaryTap || !isolatedBoundaryIds.has(boundaryId))
32161
+ return;
32162
+ onIsolatedBoundaryTap({
32163
+ boundaryId,
32164
+ boundaryName: boundaryNameById.get(boundaryId),
32165
+ clientX,
32166
+ clientY,
32167
+ });
32168
+ }, [boundaryNameById, isolatedBoundaryIds, onIsolatedBoundaryTap]);
32169
+ const isolatedTapHandler = onIsolatedBoundaryTap ? handleIsolatedTap : undefined;
32122
32170
  /** 选中地块 id 列表(受控/非受控)与切换选中回调 */
32123
32171
  const { selectedIds, toggleBoundary, setSelectedIds } = useBoundarySelection({
32124
32172
  selectedBoundaryIds,
@@ -32144,7 +32192,15 @@ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerSt
32144
32192
  toggleBoundary(id);
32145
32193
  }, [isolatedBoundaryIds, toggleBoundary]);
32146
32194
  /** Standalone 模式:由 viewport 统一处理点击(支持在地块上拖拽平移) */
32147
- const handleViewportTap = React.useCallback((target) => {
32195
+ const handleViewportTap = React.useCallback(({ target, clientX, clientY }) => {
32196
+ const isolatedEl = target.closest(`[${PARTITION_ISOLATED_BOUNDARY_ID_ATTR}]`);
32197
+ if (isolatedEl) {
32198
+ const isolatedId = Number(isolatedEl.getAttribute(PARTITION_ISOLATED_BOUNDARY_ID_ATTR));
32199
+ if (Number.isFinite(isolatedId) && isolatedBoundaryIds.has(isolatedId)) {
32200
+ handleIsolatedTap(isolatedId, clientX, clientY);
32201
+ }
32202
+ return;
32203
+ }
32148
32204
  const boundaryEl = target.closest(`[${PARTITION_BOUNDARY_ID_ATTR}]`);
32149
32205
  if (!boundaryEl)
32150
32206
  return;
@@ -32152,7 +32208,7 @@ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerSt
32152
32208
  if (!Number.isFinite(id) || isolatedBoundaryIds.has(id))
32153
32209
  return;
32154
32210
  toggleBoundary(id);
32155
- }, [isolatedBoundaryIds, toggleBoundary]);
32211
+ }, [handleIsolatedTap, isolatedBoundaryIds, toggleBoundary]);
32156
32212
  /**
32157
32213
  * Map 模式 overlay 状态(bounds / viewBox / fitBounds / overlayScale)。
32158
32214
  * 无 mapRef 时 hook 内部 enabled=false,返回值不参与渲染。
@@ -32173,7 +32229,7 @@ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerSt
32173
32229
  }
32174
32230
  }, [isMapMode, isReady, onSizeChange, pxWidth, pxHeight]);
32175
32231
  /** Standalone:平移/缩放 viewBox;Map 模式 enablePanZoom 关闭,仅保留 hook 结构 */
32176
- const { viewBox: standaloneViewBox, gridViewBox, fitViewBox: standaloneFitViewBox, resetView: standaloneResetView, fitToView: standaloneFitToView, } = useMapViewport({
32232
+ const { viewBox: standaloneViewBox, gridViewBox, resetView: standaloneResetView, fitToView: standaloneFitToView, } = useMapViewport({
32177
32233
  mapJson,
32178
32234
  containerRef,
32179
32235
  width: pxWidth,
@@ -32188,7 +32244,6 @@ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerSt
32188
32244
  });
32189
32245
  /** 按模式选取 viewBox / 尺寸 / 旋转 / 就绪状态(Map 与 Standalone 数据源不同) */
32190
32246
  const viewBox = isMapMode ? googleOverlay.svgViewBox : standaloneViewBox;
32191
- const fitViewBox = isMapMode ? googleOverlay.fitViewBox : standaloneFitViewBox;
32192
32247
  const overlayWidth = isMapMode ? googleOverlay.overlayWidth : pxWidth;
32193
32248
  const overlayHeight = isMapMode ? googleOverlay.overlayHeight : pxHeight;
32194
32249
  const actureRotate = isMapMode ? googleOverlay.actureRotate : standaloneActureRotate;
@@ -32262,18 +32317,18 @@ const MowerPartitionPickerMap = React.forwardRef(({ mapJson, mapConfig, pickerSt
32262
32317
  ...(isMapMode ? {} : layoutStyle),
32263
32318
  }), [isMapMode, layoutStyle, resolvedBackgroundColor, style]);
32264
32319
  /** 地块 + 通道 SVG;Map 模式不在 SVG 内旋转(由 OverlayViewF rotate 处理) */
32265
- const mapSvgLayer = viewBox && isLayersReady ? (jsxRuntime.jsx(PartitionPickerSvg, { svgElementDatas: svgElementDatas, viewBox: viewBox, fitViewBox: fitViewBox ?? viewBox, containerWidth: overlayWidth, containerHeight: overlayHeight, mapRotation: isMapMode ? 0 : actureRotate, boundaryColors: mergedPickerStyles.boundary, boundaryStrokePx: mergedPickerStyles.boundaryStrokePx, isolatedBoundaryIds: isolatedBoundaryIds, selectedIds: selectedIds, hoveredId: hoveredId, onHoverChange: handleHoverChange, onBoundaryClick: isMapMode ? handleBoundaryClick : undefined })) : null;
32320
+ const mapSvgLayer = viewBox && isLayersReady ? (jsxRuntime.jsx(PartitionPickerSvg, { svgElementDatas: svgElementDatas, viewBox: viewBox, containerWidth: overlayWidth, containerHeight: overlayHeight, mapRotation: isMapMode ? 0 : actureRotate, boundaryColors: mergedPickerStyles.boundary, boundaryStrokePx: mergedPickerStyles.boundaryStrokePx, isolatedBoundaryIds: isolatedBoundaryIds, selectedIds: selectedIds, hoveredId: hoveredId, onHoverChange: handleHoverChange, onBoundaryClick: isMapMode ? handleBoundaryClick : undefined, onIsolatedTap: isMapMode ? isolatedTapHandler : undefined })) : null;
32266
32321
  /**
32267
32322
  * 分区标签 + 充电桩 HTML 层。
32268
32323
  * Map 模式:平铺于 overlay 根节点;Standalone:包在 mapOverlayLayer 内做 CSS 旋转。
32269
32324
  */
32270
- const overlayLayers = viewBox && isLayersReady ? (isMapMode ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, labelMinScreenWidthPx: mergedPickerStyles.labelMinScreenWidthPx, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange, onBoundaryClick: handleBoundaryClick }), jsxRuntime.jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate })] })) : (jsxRuntime.jsxs("div", { className: styles.mapOverlayLayer, style: mapOverlayLayerStyle, children: [jsxRuntime.jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, labelMinScreenWidthPx: mergedPickerStyles.labelMinScreenWidthPx, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange }), jsxRuntime.jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate, viewRotationMode: "overlay-parent", containerWidth: overlayWidth, containerHeight: overlayHeight })] }))) : null;
32325
+ const overlayLayers = viewBox && isLayersReady ? (isMapMode ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange, onBoundaryClick: handleBoundaryClick, onIsolatedTap: isolatedTapHandler }), jsxRuntime.jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate })] })) : (jsxRuntime.jsxs("div", { className: styles.mapOverlayLayer, style: mapOverlayLayerStyle, children: [jsxRuntime.jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange, onIsolatedTap: isolatedTapHandler }), jsxRuntime.jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate, viewRotationMode: "overlay-parent", containerWidth: overlayWidth, containerHeight: overlayHeight, sizeInSvgUnits: true, minDisplaySizePx: PARTITION_PICKER_CHARGING_PILE_MIN_DISPLAY_PX })] }))) : null;
32271
32326
  /** Map 模式:渲染 OverlayViewF,底图为 Google Maps */
32272
32327
  if (isMapMode && mapRef) {
32273
32328
  return (jsxRuntime.jsx(CommonContextProvider, { value: commonValue, children: jsxRuntime.jsx(SvgEditContextProvider, { value: svgEditValue, children: jsxRuntime.jsx(OverlayViewF, { map: mapRef, mapPaneName: "overlayMouseTarget", bounds: googleOverlay.bounds ?? undefined, rotate: actureRotate, zIndex: zIndex, onDraw: googleOverlay.handleOverlayDraw, children: jsxRuntime.jsxs("div", { className: `${styles.googleOverlayRoot} ${className || ''}`, style: containerStyle, onMouseLeave: () => setHoveredId(null), children: [mapSvgLayer, overlayLayers] }) }) }) }));
32274
32329
  }
32275
32330
  /** Standalone 模式:固定容器 + 网格底图 + 双层 SVG / HTML overlay */
32276
- return (jsxRuntime.jsx(CommonContextProvider, { value: commonValue, children: jsxRuntime.jsx(SvgEditContextProvider, { value: svgEditValue, children: jsxRuntime.jsx("div", { ref: containerRef, className: `${styles.container} ${className || ''}`, "data-viewport-background": "true", style: containerStyle, onMouseLeave: () => setHoveredId(null), children: isLayersReady && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: styles.mapSvgStack, children: [jsxRuntime.jsx(PartitionPickerGridSvg, { viewBox: gridViewBox, gridStyle: mergedPickerStyles.grid }), mapSvgLayer] }), overlayLayers] })) }) }) }));
32331
+ return (jsxRuntime.jsx(CommonContextProvider, { value: commonValue, children: jsxRuntime.jsx(SvgEditContextProvider, { value: svgEditValue, children: jsxRuntime.jsx("div", { ref: containerRef, className: `${styles.container} ${className || ''}`, "data-viewport-background": "true", style: containerStyle, onMouseLeave: () => setHoveredId(null), children: isLayersReady && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: styles.mapSvgStack, children: [jsxRuntime.jsx(PartitionPickerGridSvg, { viewBox: gridViewBox, gridStyle: standaloneGridStyle }), mapSvgLayer] }), overlayLayers] })) }) }) }));
32277
32332
  });
32278
32333
  MowerPartitionPickerMap.displayName = 'MowerPartitionPickerMap';
32279
32334