@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.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { memo, useMemo, useEffect, useState, useRef, useCallback, createContext, useContext, useLayoutEffect, forwardRef, useImperativeHandle, useId } from 'react';
3
+ import React__default, { memo, useMemo, useEffect, useState, useRef, useCallback, createContext, useContext, useLayoutEffect, Fragment as Fragment$1, forwardRef, useImperativeHandle, useId } from 'react';
4
4
  import ReactDOM, { createPortal } from 'react-dom';
5
5
 
6
6
  function globals (defs) {
@@ -22956,9 +22956,9 @@ const VertexElement = React__default.memo(({ r, stroke, fill, ...props }) => {
22956
22956
  });
22957
22957
 
22958
22958
  var _path$1;
22959
- 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); }
22959
+ 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); }
22960
22960
  var SvgDelete = function SvgDelete(props) {
22961
- return /*#__PURE__*/React.createElement("svg", _extends$8({
22961
+ return /*#__PURE__*/React.createElement("svg", _extends$5({
22962
22962
  xmlns: "http://www.w3.org/2000/svg",
22963
22963
  width: 16,
22964
22964
  height: 16,
@@ -23439,6 +23439,73 @@ function computeFitViewBoxToContainer(content, containerWidth, containerHeight)
23439
23439
  height: content.height,
23440
23440
  };
23441
23441
  }
23442
+ /** 地图内容在屏幕坐标系下的包围盒(meet 渲染,未考虑旋转) */
23443
+ function getContentScreenBounds(content, viewBox, containerWidth, containerHeight) {
23444
+ const { x: offsetX, y: offsetY, scale } = getViewBoxMeetOffset(viewBox, containerWidth, containerHeight);
23445
+ return {
23446
+ left: offsetX + (content.x - viewBox.x) * scale,
23447
+ top: offsetY + (content.y - viewBox.y) * scale,
23448
+ right: offsetX + (content.x + content.width - viewBox.x) * scale,
23449
+ bottom: offsetY + (content.y + content.height - viewBox.y) * scale,
23450
+ };
23451
+ }
23452
+ function contentFitsInScreenPadding(content, viewBox, pad, containerWidth, containerHeight) {
23453
+ const bounds = getContentScreenBounds(content, viewBox, containerWidth, containerHeight);
23454
+ return (bounds.left >= pad.left &&
23455
+ bounds.top >= pad.top &&
23456
+ bounds.right <= containerWidth - pad.right &&
23457
+ bounds.bottom <= containerHeight - pad.bottom);
23458
+ }
23459
+ function expandViewBoxFromCenter(viewBox, factor) {
23460
+ const centerX = viewBox.x + viewBox.width / 2;
23461
+ const centerY = viewBox.y + viewBox.height / 2;
23462
+ const width = viewBox.width * factor;
23463
+ const height = viewBox.height * factor;
23464
+ return {
23465
+ x: centerX - width / 2,
23466
+ y: centerY - height / 2,
23467
+ width,
23468
+ height,
23469
+ };
23470
+ }
23471
+ /** 将 viewBox 中心对齐到 padding 内矩形中心(增大 top/left → 内容向对应方向避让) */
23472
+ function applyViewBoxPaddingOffset(viewBox, pad, containerWidth, containerHeight) {
23473
+ const offsetX = ((pad.right - pad.left) / 2) * (viewBox.width / containerWidth);
23474
+ const offsetY = ((pad.bottom - pad.top) / 2) * (viewBox.height / containerHeight);
23475
+ return {
23476
+ ...viewBox,
23477
+ x: viewBox.x + offsetX,
23478
+ y: viewBox.y + offsetY,
23479
+ };
23480
+ }
23481
+ function buildPaddedFitViewBox(baseFit, pad, containerWidth, containerHeight, zoomOutFactor) {
23482
+ const expanded = expandViewBoxFromCenter(baseFit, zoomOutFactor);
23483
+ return applyViewBoxPaddingOffset(expanded, pad, containerWidth, containerHeight);
23484
+ }
23485
+ function findMinimumZoomOutForPadding(content, baseFit, pad, containerWidth, containerHeight) {
23486
+ const fits = (zoomOutFactor) => contentFitsInScreenPadding(content, buildPaddedFitViewBox(baseFit, pad, containerWidth, containerHeight, zoomOutFactor), pad, containerWidth, containerHeight);
23487
+ if (fits(1)) {
23488
+ return 1;
23489
+ }
23490
+ const innerWidth = Math.max(containerWidth - pad.left - pad.right, 1);
23491
+ const innerHeight = Math.max(containerHeight - pad.top - pad.bottom, 1);
23492
+ const legacyScale = Math.min(innerWidth / containerWidth, innerHeight / containerHeight);
23493
+ let hi = legacyScale > 0 && legacyScale < 1 ? 1 / legacyScale : 2;
23494
+ while (!fits(hi) && hi < 1024) {
23495
+ hi *= 2;
23496
+ }
23497
+ let lo = 1;
23498
+ for (let i = 0; i < 32; i++) {
23499
+ const mid = (lo + hi) / 2;
23500
+ if (fits(mid)) {
23501
+ hi = mid;
23502
+ }
23503
+ else {
23504
+ lo = mid;
23505
+ }
23506
+ }
23507
+ return hi;
23508
+ }
23442
23509
  /**
23443
23510
  * 计算默认 fit viewBox
23444
23511
  *
@@ -23450,26 +23517,8 @@ function computeFitViewBox(content, containerWidth, containerHeight, screenPaddi
23450
23517
  if (isZeroScreenPadding(pad)) {
23451
23518
  return baseFit;
23452
23519
  }
23453
- const innerWidth = Math.max(containerWidth - pad.left - pad.right, 1);
23454
- const innerHeight = Math.max(containerHeight - pad.top - pad.bottom, 1);
23455
- const scaleX = innerWidth / containerWidth;
23456
- const scaleY = innerHeight / containerHeight;
23457
- const scale = Math.min(scaleX, scaleY);
23458
- if (!Number.isFinite(scale) || scale <= 0 || scale >= 1) {
23459
- return baseFit;
23460
- }
23461
- const newWidth = baseFit.width / scale;
23462
- const newHeight = baseFit.height / scale;
23463
- const centerX = baseFit.x + baseFit.width / 2;
23464
- const centerY = baseFit.y + baseFit.height / 2;
23465
- const offsetX = ((pad.left - pad.right) / 2) * (newWidth / containerWidth);
23466
- const offsetY = ((pad.top - pad.bottom) / 2) * (newHeight / containerHeight);
23467
- return {
23468
- x: centerX - newWidth / 2 + offsetX,
23469
- y: centerY - newHeight / 2 + offsetY,
23470
- width: newWidth,
23471
- height: newHeight,
23472
- };
23520
+ const zoomOutFactor = findMinimumZoomOutForPadding(content, baseFit, pad, containerWidth, containerHeight);
23521
+ return buildPaddedFitViewBox(baseFit, pad, containerWidth, containerHeight, zoomOutFactor);
23473
23522
  }
23474
23523
  function viewBoxToString(viewBox) {
23475
23524
  return `${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`;
@@ -23548,15 +23597,13 @@ function computePolygonScreenWidthPx(points, viewBox, containerWidth, containerH
23548
23597
  const scale = getViewBoxMeetScale(viewBox, containerWidth, containerHeight);
23549
23598
  return mapWidth * scale;
23550
23599
  }
23551
- function scaleStrokeWidthForViewBox(baseStrokeWidth, viewBox, fitViewBox, options) {
23552
- const { containerWidth, containerHeight, minScreenStrokePx = 2 } = options;
23600
+ function scaleStrokeWidthForViewBox(viewBox, options) {
23601
+ const { containerWidth, containerHeight, targetScreenStrokePx = 2 } = options;
23553
23602
  const meetScale = getViewBoxMeetScale(viewBox, containerWidth, containerHeight);
23554
- const fitMeetScale = getViewBoxMeetScale(fitViewBox, containerWidth, containerHeight);
23555
- if (meetScale <= 0 || fitMeetScale <= 0 || !Number.isFinite(baseStrokeWidth)) {
23556
- return baseStrokeWidth;
23603
+ if (meetScale <= 0 || !Number.isFinite(targetScreenStrokePx)) {
23604
+ return targetScreenStrokePx;
23557
23605
  }
23558
- const targetScreenPx = Math.max(baseStrokeWidth * fitMeetScale, minScreenStrokePx);
23559
- return targetScreenPx / meetScale;
23606
+ return targetScreenStrokePx / meetScale;
23560
23607
  }
23561
23608
  /** 屏幕拖拽像素 → viewBox 坐标增量(与 mapPointToContainerPercent 互逆,供 applyPan 使用) */
23562
23609
  function containerDeltaToViewBoxDelta(deltaXPx, deltaYPx, viewBox, containerWidth, containerHeight, mapRotationDeg = 0) {
@@ -24646,6 +24693,24 @@ const Tooltip = ({ open, x, y, text, style, onClick }) => {
24646
24693
  }, children: text }), document.body);
24647
24694
  };
24648
24695
 
24696
+ function getPathData(points) {
24697
+ // 1. 安全守卫:如果没有点,返回空字符串
24698
+ if (!points || points.length === 0)
24699
+ return '';
24700
+ // 2. 如果只有 1 个点,只生成起点 M 即可(或者在最外层判断中直接 return 过滤掉)
24701
+ if (points.length === 1) {
24702
+ return `M ${points[0][0]} ${points[0][1]}`;
24703
+ }
24704
+ // 3. 2个点及以上时,再进行 L 拼接
24705
+ const pathData = points.map((p, index) => {
24706
+ if (index === 0) {
24707
+ return `M ${p[0]} ${p[1]}`;
24708
+ }
24709
+ return ` L ${p[0]} ${p[1]}`;
24710
+ }).join('');
24711
+ return pathData;
24712
+ }
24713
+
24649
24714
  /**
24650
24715
  * 将坐标点数组转换为polygon points字符串
24651
24716
  * @param coordinates 坐标点数组 [[x1, y1], [x2, y2], ...]
@@ -24729,10 +24794,7 @@ const groupCoordinatesByType = (coordinates, autoClose = true) => {
24729
24794
  const createPathData = (points) => {
24730
24795
  if (points.length < 2)
24731
24796
  return '';
24732
- let pathData = `M ${points[0][0]} ${points[0][1]}`;
24733
- for (let i = 1; i < points.length; i++) {
24734
- pathData += ` L ${points[i][0]} ${points[i][1]}`;
24735
- }
24797
+ const pathData = getPathData(points);
24736
24798
  return pathData;
24737
24799
  };
24738
24800
  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自动判断
@@ -25356,17 +25418,17 @@ const PolygonElement = ({ canSelect = false, isHover = false, points, fillColor
25356
25418
  if (isDash && showStraddleBoundaryBorder) {
25357
25419
  return (jsx(DashPath, { className: canSelect ? styles$8.polygonPath : '', points: segment.points, stroke: strokeColor, strokeWidth: isHover ? strokeWidth + 1 : strokeWidth, strokeOpacity: strokeOpacity }, index));
25358
25420
  }
25359
- return (jsxs(Fragment, { children: [(editMode || createMode) && (jsx("path", { d: pathData, fill: "none", stroke: '#fff', strokeWidth: strokeWidth * 2, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke", style: {
25421
+ return (jsxs(Fragment$1, { children: [(editMode || createMode) && (jsx("path", { d: pathData, fill: "none", stroke: '#fff', strokeWidth: strokeWidth * 2, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke", style: {
25360
25422
  userSelect: 'none',
25361
25423
  WebkitUserSelect: 'none',
25362
25424
  WebkitTouchCallout: 'none',
25363
25425
  touchAction: 'none',
25364
- } }, 'warp' + index)), 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: {
25426
+ } })), 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: {
25365
25427
  userSelect: 'none',
25366
25428
  WebkitUserSelect: 'none',
25367
25429
  WebkitTouchCallout: 'none',
25368
25430
  touchAction: 'none',
25369
- } }, index)] }));
25431
+ } }, index)] }, 'warp' + index));
25370
25432
  }) }), (editMode || (createMode && completed)) &&
25371
25433
  renderCoordinates.length >= 2 &&
25372
25434
  renderCoordinates.map((coord, index) => {
@@ -25674,10 +25736,7 @@ const ChannelElement = ({ data }) => {
25674
25736
  const clipPathUrl = `url(#${channelClipPathId})`;
25675
25737
  const points = data.points;
25676
25738
  const style = data.style;
25677
- let pathData = `M ${points[0][0]} ${points[0][1]}`;
25678
- for (let i = 1; i < points.length; i++) {
25679
- pathData += ` L ${points[i][0]} ${points[i][1]}`;
25680
- }
25739
+ const pathData = getPathData(points);
25681
25740
  const topLineWidth = dp2px(style.lineWidth).toString();
25682
25741
  const bottomLineWidth = dp2px(style.bottomLineWidth).toString();
25683
25742
  const dashLength = dp2px(style.lineWidth);
@@ -26274,15 +26333,15 @@ const useVisionOffTransform = (data, scaleConstraints
26274
26333
  };
26275
26334
  };
26276
26335
 
26277
- var _g$6, _defs$6;
26278
- 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); }
26336
+ var _g$3, _defs$3;
26337
+ 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); }
26279
26338
  var SvgTransformDelete = function SvgTransformDelete(props) {
26280
- return /*#__PURE__*/React.createElement("svg", _extends$7({
26339
+ return /*#__PURE__*/React.createElement("svg", _extends$4({
26281
26340
  xmlns: "http://www.w3.org/2000/svg",
26282
26341
  width: 20,
26283
26342
  height: 20,
26284
26343
  fill: "none"
26285
- }, props), _g$6 || (_g$6 = /*#__PURE__*/React.createElement("g", {
26344
+ }, props), _g$3 || (_g$3 = /*#__PURE__*/React.createElement("g", {
26286
26345
  clipPath: "url(#transform-delete_svg__a)"
26287
26346
  }, /*#__PURE__*/React.createElement("circle", {
26288
26347
  cx: 10,
@@ -26305,7 +26364,7 @@ var SvgTransformDelete = function SvgTransformDelete(props) {
26305
26364
  fill: "#fff",
26306
26365
  rx: 0.8,
26307
26366
  transform: "rotate(45 6.323 5.191)"
26308
- }))), _defs$6 || (_defs$6 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26367
+ }))), _defs$3 || (_defs$3 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26309
26368
  id: "transform-delete_svg__b",
26310
26369
  x1: 17.727,
26311
26370
  x2: -1.215,
@@ -26325,15 +26384,15 @@ var SvgTransformDelete = function SvgTransformDelete(props) {
26325
26384
  })))));
26326
26385
  };
26327
26386
 
26328
- var _g$5, _defs$5;
26329
- 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); }
26387
+ var _g$2, _defs$2;
26388
+ 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); }
26330
26389
  var SvgTransformRotate = function SvgTransformRotate(props) {
26331
- return /*#__PURE__*/React.createElement("svg", _extends$6({
26390
+ return /*#__PURE__*/React.createElement("svg", _extends$3({
26332
26391
  xmlns: "http://www.w3.org/2000/svg",
26333
26392
  width: 21,
26334
26393
  height: 20,
26335
26394
  fill: "none"
26336
- }, props), _g$5 || (_g$5 = /*#__PURE__*/React.createElement("g", {
26395
+ }, props), _g$2 || (_g$2 = /*#__PURE__*/React.createElement("g", {
26337
26396
  clipPath: "url(#transform-rotate_svg__a)"
26338
26397
  }, /*#__PURE__*/React.createElement("path", {
26339
26398
  fill: "url(#transform-rotate_svg__b)",
@@ -26341,7 +26400,7 @@ var SvgTransformRotate = function SvgTransformRotate(props) {
26341
26400
  }), /*#__PURE__*/React.createElement("path", {
26342
26401
  fill: "#fff",
26343
26402
  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"
26344
- }))), _defs$5 || (_defs$5 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26403
+ }))), _defs$2 || (_defs$2 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26345
26404
  id: "transform-rotate_svg__b",
26346
26405
  x1: 17.84,
26347
26406
  x2: -1.103,
@@ -26361,15 +26420,15 @@ var SvgTransformRotate = function SvgTransformRotate(props) {
26361
26420
  })))));
26362
26421
  };
26363
26422
 
26364
- var _g$4, _defs$4;
26365
- 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); }
26423
+ var _g$1, _defs$1;
26424
+ 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); }
26366
26425
  var SvgTransformScale = function SvgTransformScale(props) {
26367
- return /*#__PURE__*/React.createElement("svg", _extends$5({
26426
+ return /*#__PURE__*/React.createElement("svg", _extends$2({
26368
26427
  xmlns: "http://www.w3.org/2000/svg",
26369
26428
  width: 21,
26370
26429
  height: 20,
26371
26430
  fill: "none"
26372
- }, props), _g$4 || (_g$4 = /*#__PURE__*/React.createElement("g", {
26431
+ }, props), _g$1 || (_g$1 = /*#__PURE__*/React.createElement("g", {
26373
26432
  clipPath: "url(#transform-scale_svg__a)"
26374
26433
  }, /*#__PURE__*/React.createElement("path", {
26375
26434
  fill: "url(#transform-scale_svg__b)",
@@ -26377,7 +26436,7 @@ var SvgTransformScale = function SvgTransformScale(props) {
26377
26436
  }), /*#__PURE__*/React.createElement("path", {
26378
26437
  fill: "#fff",
26379
26438
  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"
26380
- }))), _defs$4 || (_defs$4 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26439
+ }))), _defs$1 || (_defs$1 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26381
26440
  id: "transform-scale_svg__b",
26382
26441
  x1: 17.84,
26383
26442
  x2: -1.103,
@@ -26397,15 +26456,15 @@ var SvgTransformScale = function SvgTransformScale(props) {
26397
26456
  })))));
26398
26457
  };
26399
26458
 
26400
- var _g$3, _defs$3;
26401
- 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); }
26459
+ var _g, _defs;
26460
+ 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); }
26402
26461
  var SvgTransformTranslate = function SvgTransformTranslate(props) {
26403
- return /*#__PURE__*/React.createElement("svg", _extends$4({
26462
+ return /*#__PURE__*/React.createElement("svg", _extends$1({
26404
26463
  xmlns: "http://www.w3.org/2000/svg",
26405
26464
  width: 20,
26406
26465
  height: 20,
26407
26466
  fill: "none"
26408
- }, props), _g$3 || (_g$3 = /*#__PURE__*/React.createElement("g", {
26467
+ }, props), _g || (_g = /*#__PURE__*/React.createElement("g", {
26409
26468
  clipPath: "url(#transform-translate_svg__a)"
26410
26469
  }, /*#__PURE__*/React.createElement("circle", {
26411
26470
  cx: 10,
@@ -26415,7 +26474,7 @@ var SvgTransformTranslate = function SvgTransformTranslate(props) {
26415
26474
  }), /*#__PURE__*/React.createElement("path", {
26416
26475
  fill: "#fff",
26417
26476
  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"
26418
- }))), _defs$3 || (_defs$3 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26477
+ }))), _defs || (_defs = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
26419
26478
  id: "transform-translate_svg__b",
26420
26479
  x1: 17.727,
26421
26480
  x2: -1.215,
@@ -27089,97 +27148,6 @@ const useDoodleTransform = (data, onTransformChange, options) => {
27089
27148
  };
27090
27149
  };
27091
27150
 
27092
- var _g$2, _defs$2;
27093
- 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); }
27094
- var SvgDisabledRotate = function SvgDisabledRotate(props) {
27095
- return /*#__PURE__*/React.createElement("svg", _extends$3({
27096
- xmlns: "http://www.w3.org/2000/svg",
27097
- width: 16,
27098
- height: 16,
27099
- fill: "none"
27100
- }, props), _g$2 || (_g$2 = /*#__PURE__*/React.createElement("g", {
27101
- clipPath: "url(#disabled-rotate_svg__a)"
27102
- }, /*#__PURE__*/React.createElement("path", {
27103
- fill: "#fff",
27104
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27105
- }), /*#__PURE__*/React.createElement("path", {
27106
- fill: "#211F1F",
27107
- fillOpacity: 0.4,
27108
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27109
- }), /*#__PURE__*/React.createElement("path", {
27110
- fill: "#fff",
27111
- fillOpacity: 0.7,
27112
- 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"
27113
- }))), _defs$2 || (_defs$2 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
27114
- id: "disabled-rotate_svg__a"
27115
- }, /*#__PURE__*/React.createElement("path", {
27116
- fill: "#fff",
27117
- d: "M16 0H0v16h16z"
27118
- })))));
27119
- };
27120
-
27121
- var _g$1, _defs$1;
27122
- 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); }
27123
- var SvgDisabledScale = function SvgDisabledScale(props) {
27124
- return /*#__PURE__*/React.createElement("svg", _extends$2({
27125
- xmlns: "http://www.w3.org/2000/svg",
27126
- width: 16,
27127
- height: 16,
27128
- fill: "none"
27129
- }, props), _g$1 || (_g$1 = /*#__PURE__*/React.createElement("g", {
27130
- clipPath: "url(#disabled-scale_svg__a)"
27131
- }, /*#__PURE__*/React.createElement("path", {
27132
- fill: "#fff",
27133
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27134
- }), /*#__PURE__*/React.createElement("path", {
27135
- fill: "#211F1F",
27136
- fillOpacity: 0.4,
27137
- d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0"
27138
- }), /*#__PURE__*/React.createElement("path", {
27139
- fill: "#fff",
27140
- fillOpacity: 0.7,
27141
- 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"
27142
- }))), _defs$1 || (_defs$1 = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
27143
- id: "disabled-scale_svg__a"
27144
- }, /*#__PURE__*/React.createElement("path", {
27145
- fill: "#fff",
27146
- d: "M0 16h16V0H0z"
27147
- })))));
27148
- };
27149
-
27150
- var _g, _defs;
27151
- 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); }
27152
- var SvgDisabledTranslate = function SvgDisabledTranslate(props) {
27153
- return /*#__PURE__*/React.createElement("svg", _extends$1({
27154
- xmlns: "http://www.w3.org/2000/svg",
27155
- width: 16,
27156
- height: 16,
27157
- fill: "none"
27158
- }, props), _g || (_g = /*#__PURE__*/React.createElement("g", {
27159
- clipPath: "url(#disabled-translate_svg__a)"
27160
- }, /*#__PURE__*/React.createElement("circle", {
27161
- cx: 8,
27162
- cy: 8,
27163
- r: 8,
27164
- fill: "#fff"
27165
- }), /*#__PURE__*/React.createElement("circle", {
27166
- cx: 8,
27167
- cy: 8,
27168
- r: 8,
27169
- fill: "#211F1F",
27170
- fillOpacity: 0.4
27171
- }), /*#__PURE__*/React.createElement("path", {
27172
- fill: "#fff",
27173
- fillOpacity: 0.7,
27174
- 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"
27175
- }))), _defs || (_defs = /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
27176
- id: "disabled-translate_svg__a"
27177
- }, /*#__PURE__*/React.createElement("path", {
27178
- fill: "#fff",
27179
- d: "M16 0H0v16h16z"
27180
- })))));
27181
- };
27182
-
27183
27151
  var css_248z$6 = ".index-module_doodleHover__jIZHV path {\n fill: #00B3A1;\n}";
27184
27152
  var styles$6 = {"doodleHover":"index-module_doodleHover__jIZHV"};
27185
27153
  styleInject(css_248z$6);
@@ -27378,8 +27346,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
27378
27346
  const infoBoxWidth = 300 * overlayScale; // 信息框宽度
27379
27347
  const infoBoxHeight = 40 * overlayScale; // 信息框高度
27380
27348
  const infoBoxX = centerX - infoBoxWidth / 2; // 居中对齐
27381
- const circleScale = platform === PlatformType.H5 ? 1.5 * overlayScale : 3 * overlayScale;
27382
- const disacledScale = circleScale * 1.2;
27349
+ const circleScale = platform === PlatformType.H5 ? 1.5 * overlayScale : 2 * overlayScale;
27383
27350
  return (jsxs(Fragment, { children: [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 === PlatformType.H5
27384
27351
  ? {
27385
27352
  onTouchStart: createReactEventHandler((e) => {
@@ -27388,7 +27355,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
27388
27355
  }
27389
27356
  : {
27390
27357
  // onMouseDown: handleMouseDownWithDisabled,
27391
- }) }), jsx("g", { transform: `translate(${selectionBoxPoints[3].x}, ${selectionBoxPoints[3].y})`, children: jsx("g", { transformOrigin: "center", transform: `translate(-${10 * circleScale}, -${10 * circleScale}) scale(${disacledScale})`, children: jsx(SvgDisabledRotate, {}) }) }), jsx("g", { transform: `translate(${selectionBoxPoints[1].x}, ${selectionBoxPoints[1].y})`, children: jsx("g", { transformOrigin: "center", transform: `translate(-${10 * circleScale}, -${10 * circleScale}) scale(${disacledScale})`, children: jsx(SvgDisabledTranslate, {}) }) }), jsx("g", { transform: `translate(${selectionBoxPoints[2].x}, ${selectionBoxPoints[2].y})`, children: jsx("g", { transformOrigin: "center", transform: `translate(-${10 * circleScale}, -${10 * circleScale}) scale(${disacledScale})`, children: jsx(SvgDisabledScale, {}) }) }), platform === PlatformType.H5 && (jsx("foreignObject", { x: infoBoxX, y: infoBoxY, width: infoBoxWidth, height: infoBoxHeight, style: { textAlign: 'center' }, onClick: () => {
27358
+ }) }), jsx("circle", { cx: selectionBoxPoints[0].x, cy: selectionBoxPoints[0].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), jsx("circle", { cx: selectionBoxPoints[3].x, cy: selectionBoxPoints[3].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), jsx("circle", { cx: selectionBoxPoints[1].x, cy: selectionBoxPoints[1].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), jsx("circle", { cx: selectionBoxPoints[2].x, cy: selectionBoxPoints[2].y, r: 10 * circleScale, fill: "#B2B4B9", stroke: "none" }), platform === PlatformType.H5 && (jsx("foreignObject", { x: infoBoxX, y: infoBoxY, width: infoBoxWidth, height: infoBoxHeight, style: { textAlign: 'center' }, onClick: () => {
27392
27359
  onClickInfo?.();
27393
27360
  }, children: jsx("div", { style: {
27394
27361
  padding: `5px ${10 * overlayScale}px`,
@@ -27408,7 +27375,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
27408
27375
  justifyContent: 'center',
27409
27376
  gap: '10px',
27410
27377
  color: '#325069',
27411
- }, children: jsxs("div", { children: [locale?.['map.renderer.remainingTime'] || 'Remaining time', ": ", remainingTime] }) }) }) }))] }));
27378
+ }, children: jsxs("div", { children: [locale?.['map.renderer.remainTime'] || 'Remaining time', ": ", remainingTime] }) }) }) }))] }));
27412
27379
  };
27413
27380
  useEffect(() => {
27414
27381
  const isMove = isDragging || isRotating || isScaling;
@@ -27962,10 +27929,7 @@ const PathElement = forwardRef(({ mapConfig, pathData, mowPartitionData }, ref)
27962
27929
  return;
27963
27930
  }
27964
27931
  // 构建路径数据
27965
- let pathData = `M ${points[0][0]} ${points[0][1]}`;
27966
- for (let i = 1; i < points.length; i++) {
27967
- pathData += ` L ${points[i][0]} ${points[i][1]}`;
27968
- }
27932
+ const pathData = getPathData(points);
27969
27933
  // 根据路径类型设置不同的颜色
27970
27934
  let lineColor;
27971
27935
  if (pathType === PathSegmentType.TRANS) {
@@ -27998,7 +27962,7 @@ const PathElement = forwardRef(({ mapConfig, pathData, mowPartitionData }, ref)
27998
27962
  const result = [];
27999
27963
  partitionTypeGroups.forEach((groupData, groupKey) => {
28000
27964
  const { pathData, style } = groupData;
28001
- if (pathData.length === 0)
27965
+ if (!pathData || pathData.length === 0)
28002
27966
  return;
28003
27967
  // 从groupKey中提取分区ID
28004
27968
  const partitionId = groupKey.split('-')[0];
@@ -28006,8 +27970,8 @@ const PathElement = forwardRef(({ mapConfig, pathData, mowPartitionData }, ref)
28006
27970
  const clipPathId = clipPathData[partitionId]?.id;
28007
27971
  if (!clipPathId)
28008
27972
  return;
28009
- return result.push({
28010
- path: (pathData || []).join(' '),
27973
+ result.push({
27974
+ path: pathData.join(' '),
28011
27975
  style,
28012
27976
  clipPathId: clipPathId,
28013
27977
  });
@@ -28022,7 +27986,7 @@ const PathElement = forwardRef(({ mapConfig, pathData, mowPartitionData }, ref)
28022
27986
  return (jsxs("g", { id: "path", children: [jsx("defs", { children: Object.values(clipPathData).map((item) => {
28023
27987
  return (jsx("clipPath", { id: item.id, clipRule: "evenodd", children: jsx("path", { d: item.path }) }, item.id));
28024
27988
  }) }), Object.values(pathDataObj).map((item) => {
28025
- return (jsx("g", { "clip-path": `url(#${item.clipPathId})`, opacity: "0.5", children: 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 }) }));
27989
+ return (jsx("g", { clipPath: `url(#${item.clipPathId})`, opacity: "0.5", children: 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 }) }));
28026
27990
  })] }));
28027
27991
  });
28028
27992
 
@@ -30221,7 +30185,6 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
30221
30185
  const newSvgElementDatas = { ...svgElementDatas };
30222
30186
  Object.keys(newSvgElementDatas).forEach((key) => {
30223
30187
  if (key === DataType.OBSTACLE) {
30224
- console.error('newSvgElementDatas[key] 000---->', newSvgElementDatas[key]);
30225
30188
  newSvgElementDatas[key] =
30226
30189
  newSvgElementDatas[key].filter((item) => {
30227
30190
  return (item.status === 1 &&
@@ -30843,16 +30806,38 @@ const BoundarySvgRender = React__default.memo(({ mapJson, unStructMapData, id, m
30843
30806
  }) }), jsx(CharginPile, { viewBox: boundaryViewBox || null, rotation: 0 })] }) }) }));
30844
30807
  });
30845
30808
 
30809
+ const ISOLATED_BOUNDARY_SVG_2 = `<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
30810
+ <rect width="20" height="20" rx="10" fill="#8498A9" fill-opacity="0.7"/>
30811
+ <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"/>
30812
+ <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"/>
30813
+ <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"/>
30814
+ </svg>`;
30846
30815
  /** ChannelClipPath 等内容裁剪使用的 SVG 坐标边距(与用户传入的屏幕 padding 无关) */
30847
- const PARTITION_PICKER_CONTENT_CLIP_PADDING = 50;
30848
- /** H5:子区域屏幕宽度超过该值才展示名称标签(px) */
30816
+ const PARTITION_PICKER_CONTENT_CLIP_PADDING = 0;
30817
+ /** 可选中地块 polygon / 标签 data 属性 */
30818
+ const PARTITION_BOUNDARY_ID_ATTR = 'data-partition-boundary-id';
30819
+ /** 孤立子地块命中标记(不可选中) */
30820
+ const PARTITION_ISOLATED_BOUNDARY_ID_ATTR = 'data-partition-isolated-boundary-id';
30821
+ /** H5:子区域屏幕宽度超过该值才展示名称标签(px);与气泡宽度一致 */
30849
30822
  const H5_PARTITION_LABEL_MIN_SCREEN_WIDTH_PX = 72;
30850
30823
  /** H5:名称气泡总宽度(px) */
30851
30824
  const H5_PARTITION_LABEL_WIDTH_PX = 72;
30852
- /** 边界线目标屏幕像素宽度(默认态,全缩放级别保持一致) */
30853
- const PARTITION_BOUNDARY_TARGET_SCREEN_STROKE_PX = 2;
30854
- /** 边界线目标屏幕像素宽度(hover / 选中态) */
30855
- const PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX = 2.5;
30825
+ /** Web:序号徽章与名称标签间距(px) */
30826
+ const WEB_SELECTION_ORDER_GAP_PX = 8;
30827
+ /** H5:序号徽章与名称标签间距(px) */
30828
+ const H5_SELECTION_ORDER_GAP_PX = 4;
30829
+ /** Standalone:充电桩图标最小屏幕尺寸(px),缩小全图 fit 时避免过小;放大时随 viewBox 同比缩放 */
30830
+ const PARTITION_PICKER_CHARGING_PILE_MIN_DISPLAY_PX = 16;
30831
+ /** Web 地块描边屏幕像素宽度:未选中 2px,选中 3px */
30832
+ const WEB_PARTITION_BOUNDARY_STROKE_PX = {
30833
+ default: 2,
30834
+ selected: 3,
30835
+ };
30836
+ /** H5 地块描边屏幕像素宽度:选中与否均为 1px */
30837
+ const H5_PARTITION_BOUNDARY_STROKE_PX = {
30838
+ default: 1,
30839
+ selected: 1,
30840
+ };
30856
30841
  /**
30857
30842
  * Figma bg/mapping 地图网格背景(Standalone SVG 层)
30858
30843
  * @see https://www.figma.com/design/j0DdUYf8VFkXQ8ikkA6ZzP — node 20490:84886
@@ -30860,17 +30845,17 @@ const PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX = 2.5;
30860
30845
  /** 网格区域底色,也用于容器 letterbox 留白 */
30861
30846
  const PARTITION_PICKER_GRID_BASE_COLOR = '#E3E5EB';
30862
30847
  /** 网格单元边长(SVG 地图坐标,与 viewBox 一致;zoom 时间距同比缩放) */
30863
- const PARTITION_PICKER_GRID_TILE_SIZE = 200;
30848
+ const PARTITION_PICKER_GRID_TILE_SIZE = 10;
30864
30849
  /** 网格线宽(地图坐标;随 zoom 同比缩放,不做屏幕像素恒定) */
30865
- const PARTITION_PICKER_GRID_LINE_WIDTH = 4;
30850
+ const PARTITION_PICKER_GRID_LINE_WIDTH = 0.2;
30866
30851
  /** 网格交点圆点半径(地图坐标) */
30867
- const PARTITION_PICKER_GRID_DOT_RADIUS = 8;
30852
+ const PARTITION_PICKER_GRID_DOT_RADIUS = 0.6;
30868
30853
  /** 网格层整体不透明度(Figma 约 80%) */
30869
- const PARTITION_PICKER_GRID_OPACITY = 0.8;
30854
+ const PARTITION_PICKER_GRID_OPACITY = 0.4;
30870
30855
  /** 网格线与交点颜色 */
30871
30856
  const PARTITION_PICKER_GRID_STROKE = '#FFFFFF';
30872
30857
  /** 可见范围内交点超过该数量时跳过圆点,仅保留网格线(缩小视野时减轻 DOM 压力) */
30873
- const PARTITION_PICKER_GRID_MAX_INTERSECTION_DOTS = 400;
30858
+ const PARTITION_PICKER_GRID_MAX_INTERSECTION_DOTS = 2000;
30874
30859
  /**
30875
30860
  * 分区选择地图专用样式
30876
30861
  *
@@ -30895,37 +30880,27 @@ const PARTITION_PICKER_MAP_CONFIG = {
30895
30880
  const PARTITION_PICKER_COLORS_WEB = {
30896
30881
  defaultFill: 'rgba(222, 225, 231, 1)',
30897
30882
  defaultStroke: 'rgba(132, 152, 169, 1)',
30898
- defaultStrokeWidth: 2,
30899
30883
  hoverFill: 'rgba(211, 216, 226, 1)',
30900
30884
  hoverStroke: 'rgba(132, 152, 169, 1)',
30901
- hoverStrokeWidth: 3,
30902
30885
  selectedFill: 'rgba(202, 214, 238, 1)',
30903
30886
  selectedStroke: 'rgba(132, 152, 169, 1)',
30904
- selectedStrokeWidth: 3,
30905
30887
  selectedHoverFill: 'rgba(202, 214, 238, 1)',
30906
30888
  selectedHoverStroke: 'rgba(132, 152, 169, 1)',
30907
- selectedHoverStrokeWidth: 3,
30908
30889
  isolatedFill: 'rgba(225, 227, 233, 1)',
30909
30890
  isolatedStroke: 'rgba(189, 198, 208, 1)',
30910
- isolatedStrokeWidth: 2,
30911
30891
  };
30912
30892
  /** H5 端地块配色 */
30913
30893
  const PARTITION_PICKER_COLORS_H5 = {
30914
30894
  defaultFill: 'rgba(222, 225, 231, 1)',
30915
30895
  defaultStroke: 'rgba(132, 152, 169, 1)',
30916
- defaultStrokeWidth: 1,
30917
30896
  hoverFill: 'rgba(222, 225, 231, 1)',
30918
30897
  hoverStroke: 'rgba(132, 152, 169, 1)',
30919
- hoverStrokeWidth: 1,
30920
30898
  selectedFill: 'rgba(202, 214, 238, 1)',
30921
30899
  selectedStroke: 'rgba(132, 152, 169, 1)',
30922
- selectedStrokeWidth: 1,
30923
30900
  selectedHoverFill: 'rgba(202, 214, 238, 1)',
30924
30901
  selectedHoverStroke: 'rgba(132, 152, 169, 1)',
30925
- selectedHoverStrokeWidth: 1,
30926
30902
  isolatedFill: 'rgba(225, 227, 233, 1)',
30927
30903
  isolatedStroke: 'rgba(189, 198, 208, 1)',
30928
- isolatedStrokeWidth: 1,
30929
30904
  };
30930
30905
  function getPartitionPickerMapConfig(platform = PlatformType.WEB) {
30931
30906
  return platform === PlatformType.WEB
@@ -30935,6 +30910,11 @@ function getPartitionPickerMapConfig(platform = PlatformType.WEB) {
30935
30910
  function getPartitionPickerColors(platform = PlatformType.WEB) {
30936
30911
  return platform === PlatformType.WEB ? PARTITION_PICKER_COLORS_WEB : PARTITION_PICKER_COLORS_H5;
30937
30912
  }
30913
+ function getPartitionPickerBoundaryStrokePx(platform = PlatformType.WEB) {
30914
+ return platform === PlatformType.WEB
30915
+ ? { ...WEB_PARTITION_BOUNDARY_STROKE_PX }
30916
+ : { ...H5_PARTITION_BOUNDARY_STROKE_PX };
30917
+ }
30938
30918
  /** Web 分区名气泡(Figma「地块名称」/ 选中区域) */
30939
30919
  const PARTITION_PICKER_LABEL_STYLES_WEB = {
30940
30920
  default: {
@@ -30975,6 +30955,7 @@ const PARTITION_PICKER_LABEL_STYLES_H5 = {
30975
30955
  fontWeight: 400,
30976
30956
  padding: '6px',
30977
30957
  width: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
30958
+ maxWidth: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
30978
30959
  borderRadius: 100,
30979
30960
  boxSizing: 'border-box',
30980
30961
  },
@@ -30985,6 +30966,7 @@ const PARTITION_PICKER_LABEL_STYLES_H5 = {
30985
30966
  fontWeight: 400,
30986
30967
  padding: '6px',
30987
30968
  width: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
30969
+ maxWidth: `${H5_PARTITION_LABEL_WIDTH_PX}px`,
30988
30970
  borderRadius: 100,
30989
30971
  boxSizing: 'border-box',
30990
30972
  },
@@ -31022,10 +31004,6 @@ const DEFAULT_PARTITION_PICKER_GRID_STYLE = {
31022
31004
  opacity: PARTITION_PICKER_GRID_OPACITY,
31023
31005
  maxIntersectionDots: PARTITION_PICKER_GRID_MAX_INTERSECTION_DOTS,
31024
31006
  };
31025
- const DEFAULT_PARTITION_PICKER_BOUNDARY_STROKE_PX = {
31026
- default: PARTITION_BOUNDARY_TARGET_SCREEN_STROKE_PX,
31027
- emphasized: PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX,
31028
- };
31029
31007
  /**
31030
31008
  * 将 platform 内置默认值与外部 pickerStyleConfig 深度合并。
31031
31009
  * 调用方只需覆盖变化的字段,无需改组件源码。
@@ -31042,8 +31020,7 @@ function resolvePartitionPickerStyles(platform = PlatformType.WEB, config) {
31042
31020
  }
31043
31021
  : baseLabels,
31044
31022
  grid: merge$1({}, DEFAULT_PARTITION_PICKER_GRID_STYLE, config?.grid),
31045
- boundaryStrokePx: merge$1({}, DEFAULT_PARTITION_PICKER_BOUNDARY_STROKE_PX, config?.boundaryStrokePx),
31046
- labelMinScreenWidthPx: config?.labelMinScreenWidthPx ?? H5_PARTITION_LABEL_MIN_SCREEN_WIDTH_PX,
31023
+ boundaryStrokePx: merge$1({}, getPartitionPickerBoundaryStrokePx(platform), config?.boundaryStrokePx),
31047
31024
  };
31048
31025
  }
31049
31026
 
@@ -31057,7 +31034,7 @@ function resolvePartitionPickerStyles(platform = PlatformType.WEB, config) {
31057
31034
  *
31058
31035
  * 平移可在地块/分区名等任意区域发起;仅当位移小于阈值时才视为点击
31059
31036
  */
31060
- function useMapViewport({ mapJson, containerRef: externalContainerRef, width, height, padding, minZoom = 0.5, maxZoom = 4, enablePanZoom = true, refitOnResize = true, onViewportTap, mapRotationDeg = 0, }) {
31037
+ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, height, padding, minZoom = 0.5, maxZoom = 3, enablePanZoom = true, refitOnResize = true, onViewportTap, mapRotationDeg = 0, }) {
31061
31038
  /** 地图容器 DOM,用于绑定 wheel/pointer/touch 事件 */
31062
31039
  const internalContainerRef = useRef(null);
31063
31040
  const containerRef = externalContainerRef ?? internalContainerRef;
@@ -31263,9 +31240,9 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31263
31240
  /** 位移是否超过 PAN_CLICK_THRESHOLD_PX,超过则视为拖拽 */
31264
31241
  const markPanMoved = (startX, startY, currentX, currentY) => Math.hypot(currentX - startX, currentY - startY) > PAN_CLICK_THRESHOLD_PX;
31265
31242
  /** 触发点击回调(仅当未发生拖拽时) */
31266
- const emitViewportTap = (tapTarget) => {
31243
+ const emitViewportTap = (tapTarget, clientX, clientY) => {
31267
31244
  if (tapTarget) {
31268
- onViewportTapRef.current?.(tapTarget);
31245
+ onViewportTapRef.current?.({ target: tapTarget, clientX, clientY });
31269
31246
  }
31270
31247
  };
31271
31248
  // ── 绑定容器交互事件:滚轮缩放 / 桌面拖拽 / H5 pinch+单指平移 ──
@@ -31291,7 +31268,7 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31291
31268
  if (event) {
31292
31269
  const state = pointerMapRef.current.get(event.pointerId);
31293
31270
  if (state && !state.moved && state.tapTarget) {
31294
- emitViewportTap(state.tapTarget);
31271
+ emitViewportTap(state.tapTarget, event.clientX, event.clientY);
31295
31272
  }
31296
31273
  pointerMapRef.current.delete(event.pointerId);
31297
31274
  try {
@@ -31435,13 +31412,17 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31435
31412
  if (touchState && !touchState.moved) {
31436
31413
  let tapTarget = touchState.tapTarget;
31437
31414
  const touch = event.changedTouches[0];
31415
+ let clientX = touchState.startX;
31416
+ let clientY = touchState.startY;
31438
31417
  if (touch) {
31418
+ clientX = touch.clientX;
31419
+ clientY = touch.clientY;
31439
31420
  const hitTarget = document.elementFromPoint(touch.clientX, touch.clientY);
31440
31421
  if (hitTarget instanceof Element) {
31441
31422
  tapTarget = hitTarget;
31442
31423
  }
31443
31424
  }
31444
- emitViewportTap(tapTarget);
31425
+ emitViewportTap(tapTarget, clientX, clientY);
31445
31426
  }
31446
31427
  if (pinchRef.current) {
31447
31428
  pinchRef.current = null;
@@ -31476,7 +31457,17 @@ function useMapViewport({ mapJson, containerRef: externalContainerRef, width, he
31476
31457
  window.removeEventListener('mouseup', handleWindowPointerUp);
31477
31458
  window.removeEventListener('blur', handleWindowPointerUp);
31478
31459
  };
31479
- }, [applyPan, applyZoom, clearPanState, enablePanZoom, height, maxZoom, minZoom, scheduleViewBox, width]);
31460
+ }, [
31461
+ applyPan,
31462
+ applyZoom,
31463
+ clearPanState,
31464
+ enablePanZoom,
31465
+ height,
31466
+ maxZoom,
31467
+ minZoom,
31468
+ scheduleViewBox,
31469
+ width,
31470
+ ]);
31480
31471
  return {
31481
31472
  /** 绑定到地图外层容器的 ref */
31482
31473
  containerRef,
@@ -31535,10 +31526,12 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31535
31526
  /**
31536
31527
  * OverlayViewF 的 LatLngBounds:
31537
31528
  * GPS 包围盒 + defaultTransform 在 Web Mercator 下的平移偏移。
31529
+ * 仅 Map 模式(enabled)且 Google Maps 已加载时才计算。
31538
31530
  */
31539
31531
  const bounds = useMemo(() => {
31540
- if (!mapJson || typeof window === 'undefined' || !window.google?.maps)
31532
+ if (!enabled || !mapJson || typeof window === 'undefined' || !window.google?.maps) {
31541
31533
  return null;
31534
+ }
31542
31535
  const validBounds = getValidGpsBounds(mapJson, 0);
31543
31536
  const [swLng0, swLat0] = validBounds.sw;
31544
31537
  const [neLng0, neLat0] = validBounds.ne;
@@ -31551,7 +31544,7 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31551
31544
  const [swLng, swLat] = proj4(WEB_MERCATOR, WGS84, [swX, swY]);
31552
31545
  const [neLng, neLat] = proj4(WEB_MERCATOR, WGS84, [neX, neY]);
31553
31546
  return new window.google.maps.LatLngBounds(new window.google.maps.LatLng(swLat, swLng), new window.google.maps.LatLng(neLat, neLng));
31554
- }, [mapJson, transformX, transformY]);
31547
+ }, [enabled, mapJson, transformX, transformY]);
31555
31548
  /** OverlayViewF onDraw:解析 overlay 容器 style,得到像素 layout */
31556
31549
  const handleOverlayDraw = useCallback((style) => {
31557
31550
  const layout = Object.keys(style).reduce((acc, key) => {
@@ -31566,8 +31559,9 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31566
31559
  }, []);
31567
31560
  /** Map 模式 fitToView:调用 google.maps.Map.fitBounds,考虑旋转后的 GPS 包围盒 */
31568
31561
  const fitToView = useCallback((nextPadding) => {
31569
- if (!enabled || !mapRef || !mapJson)
31562
+ if (!enabled || !mapRef || !mapJson || typeof window === 'undefined' || !window.google?.maps) {
31570
31563
  return;
31564
+ }
31571
31565
  const rotate = transformRotation + originNorthRotate;
31572
31566
  const validBounds = getValidGpsBounds(mapJson, rotate);
31573
31567
  const [swLng0, swLat0] = validBounds.sw;
@@ -31616,7 +31610,7 @@ function useGoogleMapsOverlay({ mapJson, mapRef, defaultTransform, originNorthRo
31616
31610
  const listener = mapRef.addListener('zoom_changed', handleZoomChanged);
31617
31611
  updateScale();
31618
31612
  return () => {
31619
- if (listener) {
31613
+ if (listener && window.google?.maps?.event) {
31620
31614
  window.google.maps.event.removeListener(listener);
31621
31615
  }
31622
31616
  handleZoomChanged.cancel();
@@ -31876,19 +31870,15 @@ function usePartitionLabelItems(mapData, viewBox, containerWidth, containerHeigh
31876
31870
  ]);
31877
31871
  }
31878
31872
 
31879
- 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}";
31880
- 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"};
31873
+ 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}";
31874
+ 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"};
31881
31875
  styleInject(css_248z);
31882
31876
 
31883
- const PARTITION_BOUNDARY_ID_ATTR$1 = 'data-partition-boundary-id';
31884
- const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isIsolated = false, selected, hovered, viewBoxWidth, viewBoxHeight, fitViewBox, containerWidth, containerHeight, onHoverChange, onBoundaryClick, }) => {
31877
+ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isIsolated = false, selected, hovered, viewBoxWidth, viewBoxHeight, containerWidth, containerHeight, onHoverChange, onBoundaryClick, onIsolatedTap, }) => {
31885
31878
  const style = data.style || {};
31886
31879
  const boundaryId = Number(data.id);
31887
31880
  const colors = boundaryColors;
31888
- const strokePx = boundaryStrokePx ?? {
31889
- default: PARTITION_BOUNDARY_TARGET_SCREEN_STROKE_PX,
31890
- emphasized: PARTITION_BOUNDARY_EMPHASIZED_TARGET_SCREEN_STROKE_PX,
31891
- };
31881
+ const strokePx = boundaryStrokePx ?? { ...WEB_PARTITION_BOUNDARY_STROKE_PX };
31892
31882
  const pointsString = useMemo(() => data.points.map((point) => `${point[0]},${point[1]}`).join(' '), [data.points]);
31893
31883
  const fillColor = useMemo(() => {
31894
31884
  if (isIsolated)
@@ -31911,31 +31901,16 @@ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isI
31911
31901
  return style.lineColor || colors.defaultStroke;
31912
31902
  }, [colors, hovered, isIsolated, selected, style.lineColor]);
31913
31903
  const strokeWidth = useMemo(() => {
31914
- let baseWidth;
31915
- let emphasized = false;
31916
- if (isIsolated)
31917
- baseWidth = colors.isolatedStrokeWidth;
31918
- else if (selected) {
31919
- emphasized = true;
31920
- baseWidth = hovered ? colors.selectedHoverStrokeWidth : colors.selectedStrokeWidth;
31921
- }
31922
- else if (hovered) {
31923
- emphasized = true;
31924
- baseWidth = colors.hoverStrokeWidth;
31925
- }
31926
- else
31927
- baseWidth = colors.defaultStrokeWidth;
31928
31904
  const viewBox = { width: viewBoxWidth, height: viewBoxHeight };
31929
- return scaleStrokeWidthForViewBox(baseWidth, viewBox, fitViewBox, {
31905
+ const targetScreenStrokePx = !isIsolated && (selected || hovered) ? strokePx.selected : strokePx.default;
31906
+ return scaleStrokeWidthForViewBox(viewBox, {
31930
31907
  containerWidth,
31931
31908
  containerHeight,
31932
- minScreenStrokePx: emphasized ? strokePx.emphasized : strokePx.default,
31909
+ targetScreenStrokePx,
31933
31910
  });
31934
31911
  }, [
31935
- colors,
31936
31912
  containerHeight,
31937
31913
  containerWidth,
31938
- fitViewBox,
31939
31914
  hovered,
31940
31915
  isIsolated,
31941
31916
  selected,
@@ -31944,9 +31919,14 @@ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isI
31944
31919
  viewBoxWidth,
31945
31920
  ]);
31946
31921
  if (isIsolated) {
31947
- return (jsx("polygon", { className: `${styles.boundaryPolygon} ${styles.boundaryPolygonIsolated}`, points: pointsString, fill: fillColor, stroke: strokeColor, strokeWidth: strokeWidth, strokeLinejoin: "round" }));
31922
+ return (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
31923
+ ? (event) => {
31924
+ event.stopPropagation();
31925
+ onIsolatedTap(boundaryId, event.clientX, event.clientY);
31926
+ }
31927
+ : undefined }));
31948
31928
  }
31949
- return (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
31929
+ return (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
31950
31930
  ? (event) => {
31951
31931
  event.stopPropagation();
31952
31932
  onBoundaryClick(boundaryId);
@@ -31955,7 +31935,7 @@ const SelectableBoundaryElement = ({ data, boundaryColors, boundaryStrokePx, isI
31955
31935
  };
31956
31936
  var SelectableBoundaryElement$1 = memo(SelectableBoundaryElement);
31957
31937
 
31958
- const PartitionPickerSvg = ({ svgElementDatas, viewBox, fitViewBox, containerWidth, containerHeight, mapRotation = 0, boundaryColors, boundaryStrokePx, isolatedBoundaryIds, selectedIds, hoveredId, onHoverChange, onBoundaryClick, }) => {
31938
+ const PartitionPickerSvg = ({ svgElementDatas, viewBox, containerWidth, containerHeight, mapRotation = 0, boundaryColors, boundaryStrokePx, isolatedBoundaryIds, selectedIds, hoveredId, onHoverChange, onBoundaryClick, onIsolatedTap, }) => {
31959
31939
  const boundaries = (svgElementDatas[DataType.BOUNDARY] || []);
31960
31940
  const channels = (svgElementDatas[DataType.CHANNEL] || []);
31961
31941
  const selectedIdSet = useMemo(() => new Set(selectedIds), [selectedIds]);
@@ -31967,7 +31947,7 @@ const PartitionPickerSvg = ({ svgElementDatas, viewBox, fitViewBox, containerWid
31967
31947
  }, [mapRotation, viewBox.x, viewBox.y, viewBox.width, viewBox.height]);
31968
31948
  const mapContent = (jsxs(Fragment, { children: [jsx(GElement, { type: "boundary", children: boundaries.map((item) => {
31969
31949
  const boundaryId = Number(item.id);
31970
- return (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));
31950
+ return (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));
31971
31951
  }) }), jsxs(GElement, { type: "channel", children: [jsx(ChannelClipPath, {}), channels.map((item) => (jsx(ChannelElement, { data: item }, item.id)))] })] }));
31972
31952
  return (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 ? (jsx("g", { transform: mapContentTransform, children: mapContent })) : (mapContent) }));
31973
31953
  };
@@ -32002,15 +31982,31 @@ const MapGridBackground = ({ viewBox, gridStyle }) => {
32002
31982
  const patternId = useMemo(() => `partition-picker-grid-lines-${reactId.replace(/:/g, '-')}`, [reactId]);
32003
31983
  const { baseColor, strokeColor, tileSize: tile, lineWidth, dotRadius, opacity, maxIntersectionDots, } = gridStyle;
32004
31984
  const intersections = useMemo(() => getVisibleGridIntersections(viewBox, tile, maxIntersectionDots), [maxIntersectionDots, tile, viewBox.x, viewBox.y, viewBox.width, viewBox.height]);
32005
- return (jsxs("g", { className: "partition-picker-grid-bg", "aria-hidden": true, pointerEvents: "none", children: [jsx("defs", { children: jsxs("pattern", { id: patternId, patternUnits: "userSpaceOnUse", width: tile, height: tile, children: [jsx("line", { x1: 0, y1: 0, x2: tile, y2: 0, stroke: strokeColor, strokeWidth: lineWidth }), jsx("line", { x1: 0, y1: 0, x2: 0, y2: tile, stroke: strokeColor, strokeWidth: lineWidth })] }) }), jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: baseColor }), jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: `url(#${patternId})`, opacity: opacity }), jsx("g", { opacity: opacity, children: intersections.map((point, index) => (jsx("circle", { cx: point.x, cy: point.y, r: dotRadius, fill: strokeColor }, `${point.x}-${point.y}-${index}`))) })] }));
31985
+ /**
31986
+ * SVG stroke 以路径为中心;线在 tile 的 0 边绘制时,四格交点的视觉中心会偏向路径右下。
31987
+ * 线条内缩 lineWidth/2,圆点同步偏移,使圆心与网格线交叉中心对齐。
31988
+ */
31989
+ const lineHalf = lineWidth / 2;
31990
+ return (jsxs("g", { className: "partition-picker-grid-bg", "aria-hidden": true, pointerEvents: "none", children: [jsx("defs", { children: jsxs("pattern", { id: patternId, patternUnits: "userSpaceOnUse", width: tile, height: tile, children: [jsx("line", { x1: 0, y1: lineHalf, x2: tile, y2: lineHalf, stroke: strokeColor, strokeWidth: lineWidth }), jsx("line", { x1: lineHalf, y1: 0, x2: lineHalf, y2: tile, stroke: strokeColor, strokeWidth: lineWidth })] }) }), jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: baseColor }), jsx("rect", { x: viewBox.x, y: viewBox.y, width: viewBox.width, height: viewBox.height, fill: `url(#${patternId})`, opacity: opacity }), jsx("g", { opacity: opacity, children: intersections.map((point, index) => (jsx("circle", { cx: point.x + lineHalf, cy: point.y + lineHalf, r: dotRadius, fill: strokeColor }, `${point.x}-${point.y}-${index}`))) })] }));
32006
31991
  };
32007
31992
  var MapGridBackground$1 = memo(MapGridBackground);
32008
31993
 
32009
31994
  const PartitionPickerGridSvg = ({ viewBox, gridStyle }) => {
32010
- return (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: jsx(MapGridBackground$1, { viewBox: viewBox, gridStyle: gridStyle }) }));
31995
+ return (jsx("svg", { className: styles.gridSvg, "data-viewport-background": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: viewBoxToString(viewBox), width: "100%", height: "100%",
31996
+ // 设置缩放的规则
31997
+ //等比缩放 viewBox 内容,使其完整落在容器内;
31998
+ //水平、垂直都居中;
31999
+ //比例不一致时,上下或左右留空(letterboxing),不裁切、不拉伸变形。
32000
+ preserveAspectRatio: "xMidYMid meet",
32001
+ /**
32002
+ * 控制浏览器如何绘制路径/线条:
32003
+ * geometricPrecision:优先几何精度,线条更平滑、对齐更稳,缩放时不易发虚或抖动。
32004
+ * 网格是大量细线,用这个属性能让缩放/平移时网格更清晰稳定。
32005
+ */
32006
+ shapeRendering: "geometricPrecision", "aria-hidden": true, children: jsx(MapGridBackground$1, { viewBox: viewBox, gridStyle: gridStyle }) }));
32011
32007
  };
32012
32008
 
32013
- const PartitionNameLabels = ({ items, selectedIds, labelStyles, labelMinScreenWidthPx = 72, platform = PlatformType.WEB, showSelectionOrder = false, rotation = 0, onHoverChange, onBoundaryClick, }) => {
32009
+ const PartitionNameLabels = ({ items, selectedIds, labelStyles, platform = PlatformType.WEB, showSelectionOrder = false, rotation = 0, onHoverChange, onBoundaryClick, onIsolatedTap, }) => {
32014
32010
  const isWeb = platform === PlatformType.WEB;
32015
32011
  const orderBadgeStyle = useMemo(() => ({
32016
32012
  width: labelStyles.selectionOrderBadge.width,
@@ -32020,18 +32016,18 @@ const PartitionNameLabels = ({ items, selectedIds, labelStyles, labelMinScreenWi
32020
32016
  color: labelStyles.selectionOrderBadge.color,
32021
32017
  fontSize: `${labelStyles.selectionOrderBadge.fontSize}px`,
32022
32018
  fontWeight: labelStyles.selectionOrderBadge.fontWeight,
32019
+ fontFamily: labelStyles.selectionOrderBadge.fontFamily,
32023
32020
  lineHeight: labelStyles.selectionOrderBadge.lineHeight,
32024
32021
  }), [labelStyles]);
32025
32022
  return (jsx("div", { className: styles.labelsLayer, children: items.map((item) => {
32026
32023
  const isIsolated = item.isIsolated === true;
32027
32024
  const selected = !isIsolated && selectedIds.includes(item.id);
32028
32025
  const selectionOrder = selected ? selectedIds.indexOf(item.id) + 1 : null;
32029
- const isLargeEnough = item.screenWidthPx > labelMinScreenWidthPx;
32026
+ const isLargeEnough = item.screenWidthPx > H5_PARTITION_LABEL_MIN_SCREEN_WIDTH_PX;
32030
32027
  // Web 始终展示名称;H5 按屏幕宽度决定
32031
32028
  const showNameLabel = isWeb || isLargeEnough;
32032
32029
  const showOrderBadge = showSelectionOrder && selected && selectionOrder != null;
32033
32030
  const h5OrderOnly = !isWeb && showOrderBadge && !isLargeEnough;
32034
- const h5OrderWithName = !isWeb && showOrderBadge && isLargeEnough;
32035
32031
  if (!showNameLabel && !showOrderBadge && !isIsolated) {
32036
32032
  return null;
32037
32033
  }
@@ -32040,33 +32036,41 @@ const PartitionNameLabels = ({ items, selectedIds, labelStyles, labelMinScreenWi
32040
32036
  styles.label,
32041
32037
  !isWeb && showNameLabel ? styles.labelH5Wrap : '',
32042
32038
  isIsolated ? styles.labelIsolated : '',
32043
- isWeb && showOrderBadge ? styles.labelWithOrder : '',
32044
- h5OrderWithName ? styles.labelWithOrderH5 : '',
32045
32039
  h5OrderOnly ? styles.labelOrderOnly : '',
32046
32040
  isIsolated ? styles.labelIsolatedLayout : '',
32047
32041
  ]
32048
32042
  .filter(Boolean)
32049
32043
  .join(' ');
32050
- const boundaryIdProps = isIsolated ? {} : { [PARTITION_BOUNDARY_ID_ATTR$1]: item.id };
32044
+ const showOrderWithName = showOrderBadge && showNameLabel;
32045
+ const selectionOrderGapPx = isWeb ? WEB_SELECTION_ORDER_GAP_PX : H5_SELECTION_ORDER_GAP_PX;
32046
+ const boundaryIdProps = isIsolated
32047
+ ? { [PARTITION_ISOLATED_BOUNDARY_ID_ATTR]: item.id }
32048
+ : { [PARTITION_BOUNDARY_ID_ATTR]: item.id };
32051
32049
  return (jsxs("div", { className: labelClassName, style: {
32052
32050
  left: `${item.leftPct}%`,
32053
32051
  top: `${item.topPct}%`,
32054
32052
  transform: `translate(-50%, -50%) rotate(${-rotation}deg)`,
32055
- }, ...boundaryIdProps, onMouseEnter: isIsolated ? undefined : () => onHoverChange(item.id), onMouseLeave: isIsolated ? undefined : () => onHoverChange(null), onClick: onBoundaryClick && !isIsolated
32056
- ? (event) => {
32057
- event.stopPropagation();
32058
- onBoundaryClick(item.id);
32059
- }
32060
- : undefined, children: [showOrderBadge && (jsx("div", { className: styles.selectionOrderBadge, style: orderBadgeStyle, children: selectionOrder })), showNameLabel && (jsx("div", { className: `${styles.labelPill} ${!isWeb ? styles.labelPillH5 : ''}`, style: pillStyle, children: jsx("span", { className: `${styles.labelText} ${!isWeb ? styles.labelTextH5 : ''}`, children: item.name }) })), isIsolated && (jsx("div", { className: `${styles.isolatedIconBelow} ${isWeb ? styles.isolatedIconWeb : ''}`, dangerouslySetInnerHTML: { __html: ISOLATED_BOUNDARY_SVG } }))] }, item.id));
32053
+ ...(showOrderWithName ? { gap: selectionOrderGapPx } : undefined),
32054
+ }, ...boundaryIdProps, onMouseEnter: isIsolated ? undefined : () => onHoverChange(item.id), onMouseLeave: isIsolated ? undefined : () => onHoverChange(null), onClick: isIsolated
32055
+ ? onIsolatedTap
32056
+ ? (event) => {
32057
+ event.stopPropagation();
32058
+ onIsolatedTap(item.id, event.clientX, event.clientY);
32059
+ }
32060
+ : undefined
32061
+ : onBoundaryClick
32062
+ ? (event) => {
32063
+ event.stopPropagation();
32064
+ onBoundaryClick(item.id);
32065
+ }
32066
+ : undefined, children: [showOrderBadge && (jsx("div", { className: styles.selectionOrderBadge, style: orderBadgeStyle, children: selectionOrder })), showNameLabel && (jsx("div", { className: `${styles.labelPill} ${!isWeb ? styles.labelPillH5 : ''}`, style: pillStyle, children: jsx("span", { className: `${styles.labelText} ${!isWeb ? styles.labelTextH5 : ''}`, children: item.name }) })), isIsolated && (jsx("div", { className: `${styles.isolatedIconBelow}`, dangerouslySetInnerHTML: { __html: ISOLATED_BOUNDARY_SVG_2 } }))] }, item.id));
32061
32067
  }) }));
32062
32068
  };
32063
32069
 
32064
32070
  const DEFAULT_BACKGROUND = PARTITION_PICKER_GRID_BASE_COLOR;
32065
- /** 地块 polygon / 标签上的 data 属性,供 viewport 点击命中与表格联动 */
32066
- const PARTITION_BOUNDARY_ID_ATTR = 'data-partition-boundary-id';
32067
32071
  /** Map 模式下 OverlayViewF 默认 z-index */
32068
32072
  const DEFAULT_OVERLAY_Z_INDEX = 100;
32069
- const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleConfig, sn = '', platform = 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) => {
32073
+ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleConfig, sn = '', platform = 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) => {
32070
32074
  /**
32071
32075
  * 是否为 Map 模式(传入 mapRef 时为 true):
32072
32076
  * - true:Google Maps 底图 + OverlayViewF,平移/缩放/fit 由底图负责
@@ -32077,8 +32081,34 @@ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleCon
32077
32081
  const channelClipPathId = useMemo(() => createChannelClipPathId({ sn, reactId: reactInstanceId }), [sn, reactInstanceId]);
32078
32082
  /** 外部 pickerStyleConfig 与内置 platform 默认值合并后的最终外观(地块/标签/网格等) */
32079
32083
  const mergedPickerStyles = useMemo(() => resolvePartitionPickerStyles(platform, pickerStyleConfig), [pickerStyleConfig, platform]);
32080
- /** Standalone 容器留白与网格底色;pickerStyleConfig.grid.baseColor 优先于 backgroundColor */
32081
- const resolvedBackgroundColor = pickerStyleConfig?.grid?.baseColor ?? backgroundColor ?? DEFAULT_BACKGROUND;
32084
+ /** Standalone 容器背景与 grid.baseColor 对齐(合并后的最终值) */
32085
+ const resolvedBackgroundColor = useMemo(() => {
32086
+ if (isMapMode)
32087
+ return undefined;
32088
+ if (pickerStyleConfig?.grid?.baseColor != null) {
32089
+ return mergedPickerStyles.grid.baseColor;
32090
+ }
32091
+ return backgroundColor ?? mergedPickerStyles.grid.baseColor;
32092
+ }, [
32093
+ backgroundColor,
32094
+ isMapMode,
32095
+ mergedPickerStyles.grid.baseColor,
32096
+ pickerStyleConfig?.grid?.baseColor,
32097
+ ]);
32098
+ /** Standalone 网格层:backgroundColor 未显式指定 grid.baseColor 时与容器背景同步 */
32099
+ const standaloneGridStyle = useMemo(() => {
32100
+ if (pickerStyleConfig?.grid?.baseColor != null) {
32101
+ return mergedPickerStyles.grid;
32102
+ }
32103
+ if (backgroundColor != null) {
32104
+ return { ...mergedPickerStyles.grid, baseColor: backgroundColor };
32105
+ }
32106
+ return mergedPickerStyles.grid;
32107
+ }, [
32108
+ backgroundColor,
32109
+ mergedPickerStyles.grid,
32110
+ pickerStyleConfig?.grid?.baseColor,
32111
+ ]);
32082
32112
  const mergedMapConfig = useMemo(() => merge$1({}, DEFAULT_STYLES, getPartitionPickerMapConfig(platform), mapConfig), [mapConfig, platform]);
32083
32113
  const svgElementDatas = useMemo(() => UnifiedMapDataProcessor.processMapData(mapJson, mergedMapConfig) || {}, [mapJson, mergedMapConfig]);
32084
32114
  /** 地图 Y 轴相对正北的偏移(度),与 MowerMapRenderer.originNorthRotate 一致 */
@@ -32099,6 +32129,24 @@ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleCon
32099
32129
  }, [mapJson]);
32100
32130
  /** 孤立地块 id 列表(未连接到主地块的子地块) */
32101
32131
  const isolatedBoundaryIds = useIsolatedBoundaryIds(mapJson);
32132
+ const boundaryNameById = useMemo(() => {
32133
+ const names = new Map();
32134
+ for (const boundary of generateBoundaryData(mapJson)) {
32135
+ names.set(boundary.id, boundary.name);
32136
+ }
32137
+ return names;
32138
+ }, [mapJson]);
32139
+ const handleIsolatedTap = useCallback((boundaryId, clientX, clientY) => {
32140
+ if (!onIsolatedBoundaryTap || !isolatedBoundaryIds.has(boundaryId))
32141
+ return;
32142
+ onIsolatedBoundaryTap({
32143
+ boundaryId,
32144
+ boundaryName: boundaryNameById.get(boundaryId),
32145
+ clientX,
32146
+ clientY,
32147
+ });
32148
+ }, [boundaryNameById, isolatedBoundaryIds, onIsolatedBoundaryTap]);
32149
+ const isolatedTapHandler = onIsolatedBoundaryTap ? handleIsolatedTap : undefined;
32102
32150
  /** 选中地块 id 列表(受控/非受控)与切换选中回调 */
32103
32151
  const { selectedIds, toggleBoundary, setSelectedIds } = useBoundarySelection({
32104
32152
  selectedBoundaryIds,
@@ -32124,7 +32172,15 @@ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleCon
32124
32172
  toggleBoundary(id);
32125
32173
  }, [isolatedBoundaryIds, toggleBoundary]);
32126
32174
  /** Standalone 模式:由 viewport 统一处理点击(支持在地块上拖拽平移) */
32127
- const handleViewportTap = useCallback((target) => {
32175
+ const handleViewportTap = useCallback(({ target, clientX, clientY }) => {
32176
+ const isolatedEl = target.closest(`[${PARTITION_ISOLATED_BOUNDARY_ID_ATTR}]`);
32177
+ if (isolatedEl) {
32178
+ const isolatedId = Number(isolatedEl.getAttribute(PARTITION_ISOLATED_BOUNDARY_ID_ATTR));
32179
+ if (Number.isFinite(isolatedId) && isolatedBoundaryIds.has(isolatedId)) {
32180
+ handleIsolatedTap(isolatedId, clientX, clientY);
32181
+ }
32182
+ return;
32183
+ }
32128
32184
  const boundaryEl = target.closest(`[${PARTITION_BOUNDARY_ID_ATTR}]`);
32129
32185
  if (!boundaryEl)
32130
32186
  return;
@@ -32132,7 +32188,7 @@ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleCon
32132
32188
  if (!Number.isFinite(id) || isolatedBoundaryIds.has(id))
32133
32189
  return;
32134
32190
  toggleBoundary(id);
32135
- }, [isolatedBoundaryIds, toggleBoundary]);
32191
+ }, [handleIsolatedTap, isolatedBoundaryIds, toggleBoundary]);
32136
32192
  /**
32137
32193
  * Map 模式 overlay 状态(bounds / viewBox / fitBounds / overlayScale)。
32138
32194
  * 无 mapRef 时 hook 内部 enabled=false,返回值不参与渲染。
@@ -32153,7 +32209,7 @@ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleCon
32153
32209
  }
32154
32210
  }, [isMapMode, isReady, onSizeChange, pxWidth, pxHeight]);
32155
32211
  /** Standalone:平移/缩放 viewBox;Map 模式 enablePanZoom 关闭,仅保留 hook 结构 */
32156
- const { viewBox: standaloneViewBox, gridViewBox, fitViewBox: standaloneFitViewBox, resetView: standaloneResetView, fitToView: standaloneFitToView, } = useMapViewport({
32212
+ const { viewBox: standaloneViewBox, gridViewBox, resetView: standaloneResetView, fitToView: standaloneFitToView, } = useMapViewport({
32157
32213
  mapJson,
32158
32214
  containerRef,
32159
32215
  width: pxWidth,
@@ -32168,7 +32224,6 @@ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleCon
32168
32224
  });
32169
32225
  /** 按模式选取 viewBox / 尺寸 / 旋转 / 就绪状态(Map 与 Standalone 数据源不同) */
32170
32226
  const viewBox = isMapMode ? googleOverlay.svgViewBox : standaloneViewBox;
32171
- const fitViewBox = isMapMode ? googleOverlay.fitViewBox : standaloneFitViewBox;
32172
32227
  const overlayWidth = isMapMode ? googleOverlay.overlayWidth : pxWidth;
32173
32228
  const overlayHeight = isMapMode ? googleOverlay.overlayHeight : pxHeight;
32174
32229
  const actureRotate = isMapMode ? googleOverlay.actureRotate : standaloneActureRotate;
@@ -32242,18 +32297,18 @@ const MowerPartitionPickerMap = forwardRef(({ mapJson, mapConfig, pickerStyleCon
32242
32297
  ...(isMapMode ? {} : layoutStyle),
32243
32298
  }), [isMapMode, layoutStyle, resolvedBackgroundColor, style]);
32244
32299
  /** 地块 + 通道 SVG;Map 模式不在 SVG 内旋转(由 OverlayViewF rotate 处理) */
32245
- const mapSvgLayer = viewBox && isLayersReady ? (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;
32300
+ const mapSvgLayer = viewBox && isLayersReady ? (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;
32246
32301
  /**
32247
32302
  * 分区标签 + 充电桩 HTML 层。
32248
32303
  * Map 模式:平铺于 overlay 根节点;Standalone:包在 mapOverlayLayer 内做 CSS 旋转。
32249
32304
  */
32250
- const overlayLayers = viewBox && isLayersReady ? (isMapMode ? (jsxs(Fragment, { children: [jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, labelMinScreenWidthPx: mergedPickerStyles.labelMinScreenWidthPx, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange, onBoundaryClick: handleBoundaryClick }), jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate })] })) : (jsxs("div", { className: styles.mapOverlayLayer, style: mapOverlayLayerStyle, children: [jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, labelMinScreenWidthPx: mergedPickerStyles.labelMinScreenWidthPx, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange }), jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate, viewRotationMode: "overlay-parent", containerWidth: overlayWidth, containerHeight: overlayHeight })] }))) : null;
32305
+ const overlayLayers = viewBox && isLayersReady ? (isMapMode ? (jsxs(Fragment, { children: [jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange, onBoundaryClick: handleBoundaryClick, onIsolatedTap: isolatedTapHandler }), jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate })] })) : (jsxs("div", { className: styles.mapOverlayLayer, style: mapOverlayLayerStyle, children: [jsx(PartitionNameLabels, { items: labelItems, selectedIds: selectedIds, labelStyles: mergedPickerStyles.labels, platform: platform, showSelectionOrder: showSelectionOrder, rotation: actureRotate, onHoverChange: handleHoverChange, onIsolatedTap: isolatedTapHandler }), jsx(CharginPile, { viewBox: viewBox, rotation: actureRotate, viewRotationMode: "overlay-parent", containerWidth: overlayWidth, containerHeight: overlayHeight, sizeInSvgUnits: true, minDisplaySizePx: PARTITION_PICKER_CHARGING_PILE_MIN_DISPLAY_PX })] }))) : null;
32251
32306
  /** Map 模式:渲染 OverlayViewF,底图为 Google Maps */
32252
32307
  if (isMapMode && mapRef) {
32253
32308
  return (jsx(CommonContextProvider, { value: commonValue, children: jsx(SvgEditContextProvider, { value: svgEditValue, children: jsx(OverlayViewF, { map: mapRef, mapPaneName: "overlayMouseTarget", bounds: googleOverlay.bounds ?? undefined, rotate: actureRotate, zIndex: zIndex, onDraw: googleOverlay.handleOverlayDraw, children: jsxs("div", { className: `${styles.googleOverlayRoot} ${className || ''}`, style: containerStyle, onMouseLeave: () => setHoveredId(null), children: [mapSvgLayer, overlayLayers] }) }) }) }));
32254
32309
  }
32255
32310
  /** Standalone 模式:固定容器 + 网格底图 + 双层 SVG / HTML overlay */
32256
- return (jsx(CommonContextProvider, { value: commonValue, children: jsx(SvgEditContextProvider, { value: svgEditValue, children: jsx("div", { ref: containerRef, className: `${styles.container} ${className || ''}`, "data-viewport-background": "true", style: containerStyle, onMouseLeave: () => setHoveredId(null), children: isLayersReady && (jsxs(Fragment, { children: [jsxs("div", { className: styles.mapSvgStack, children: [jsx(PartitionPickerGridSvg, { viewBox: gridViewBox, gridStyle: mergedPickerStyles.grid }), mapSvgLayer] }), overlayLayers] })) }) }) }));
32311
+ return (jsx(CommonContextProvider, { value: commonValue, children: jsx(SvgEditContextProvider, { value: svgEditValue, children: jsx("div", { ref: containerRef, className: `${styles.container} ${className || ''}`, "data-viewport-background": "true", style: containerStyle, onMouseLeave: () => setHoveredId(null), children: isLayersReady && (jsxs(Fragment, { children: [jsxs("div", { className: styles.mapSvgStack, children: [jsx(PartitionPickerGridSvg, { viewBox: gridViewBox, gridStyle: standaloneGridStyle }), mapSvgLayer] }), overlayLayers] })) }) }) }));
32257
32312
  });
32258
32313
  MowerPartitionPickerMap.displayName = 'MowerPartitionPickerMap';
32259
32314