@fleet-frontend/mower-maps 0.2.2 → 0.2.4

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.
@@ -120,4 +120,5 @@ export declare const SVG_MAP_VIEW_ID = "fleet-maps-svg-map-view";
120
120
  export declare const ALL_DIRECTION_SELECTED = 63;
121
121
  export declare const MIN_DIRECTION_ANGLE = -14;
122
122
  export declare const MAX_DIRECTION_ANGLE = 15;
123
+ export declare const EQUATORIAL_CIRCUMFERENCE = 40075017;
123
124
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/config/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,mBAAmB;;;CAG/B,CAAC;AACF;;GAEG;AACH,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;CAUtB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;CAOpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;CAMhB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;CAUf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;CAYrB,CAAC;AAGX,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,eAAO,MAAM,qBAAqB,sqUAqB3B,CAAC;AAER;;GAEG;AACH,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B;;GAEG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC;;GAEG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC;;GAEG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C;;GAEG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC;;GAEG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD;;GAEG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,UAAU,KAAK,CAAC;AAE7B,eAAO,MAAM,eAAe,4BAA4B,CAAC;AAEzD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,mBAAmB,KAAK,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/config/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,mBAAmB;;;CAG/B,CAAC;AACF;;GAEG;AACH,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;CAUtB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;CAOpB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;CAMhB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;CAUf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;CAYrB,CAAC;AAGX,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,eAAO,MAAM,qBAAqB,sqUAqB3B,CAAC;AAER;;GAEG;AACH,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B;;GAEG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC;;GAEG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC;;GAEG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C;;GAEG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC;;GAEG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC;;GAEG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC;;GAEG;AACH,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD;;GAEG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC;;GAEG;AACH,eAAO,MAAM,UAAU,KAAK,CAAC;AAE7B,eAAO,MAAM,eAAe,4BAA4B,CAAC;AAEzD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAGtC,eAAO,MAAM,wBAAwB,WAAW,CAAC"}
package/dist/index.esm.js CHANGED
@@ -10678,6 +10678,8 @@ const ACTION_BOUNDARY_TASK = 8;
10678
10678
  const ALL_DIRECTION_SELECTED = 63;
10679
10679
  const MIN_DIRECTION_ANGLE = -14;
10680
10680
  const MAX_DIRECTION_ANGLE = 15;
10681
+ // WGS84 赤道周长
10682
+ const EQUATORIAL_CIRCUMFERENCE = 40075017;
10681
10683
 
10682
10684
  /**
10683
10685
  * 数据类型枚举
@@ -15537,7 +15539,7 @@ function calculateBoundaryBoundsCenter(mapData) {
15537
15539
  /**
15538
15540
  * 检查GPS坐标是否有效
15539
15541
  */
15540
- function isValidGpsCoordinate$1(lat, lng) {
15542
+ function isValidGpsCoordinate(lat, lng) {
15541
15543
  // 检查纬度范围 (-90 到 90) 和经度范围 (-180 到 180)
15542
15544
  // 同时排除明显无效的坐标(如0,0或者很接近0的值)
15543
15545
  return (lat >= -90 &&
@@ -15630,7 +15632,7 @@ function calculateMapGpsCenter(mapData) {
15630
15632
  if (mapData.center_gps && mapData.center_gps.length >= 2) {
15631
15633
  const lat = mapData.center_gps[1];
15632
15634
  const lng = mapData.center_gps[0];
15633
- if (isValidGpsCoordinate$1(lat, lng)) {
15635
+ if (isValidGpsCoordinate(lat, lng)) {
15634
15636
  return { lat, lng };
15635
15637
  }
15636
15638
  else {
@@ -15647,7 +15649,7 @@ function calculateMapGpsCenter(mapData) {
15647
15649
  const neLat = mapData.ne_gps[1];
15648
15650
  const neLng = mapData.ne_gps[0];
15649
15651
  // 检查边界坐标的有效性
15650
- if (isValidGpsCoordinate$1(swLat, swLng) && isValidGpsCoordinate$1(neLat, neLng)) {
15652
+ if (isValidGpsCoordinate(swLat, swLng) && isValidGpsCoordinate(neLat, neLng)) {
15651
15653
  return {
15652
15654
  lat: (swLat + neLat) / 2,
15653
15655
  lng: (swLng + neLng) / 2,
@@ -15673,6 +15675,100 @@ function calculateMapGpsCenter(mapData) {
15673
15675
  lng: 116.4074, // 北京经度
15674
15676
  };
15675
15677
  }
15678
+ // 旋转坐标点
15679
+ const rotateCoordinate = (point, center, angleRadians) => {
15680
+ const [x, y] = point;
15681
+ const [cx, cy] = center;
15682
+ // 将点移动到原点
15683
+ const dx = x - cx;
15684
+ const dy = y - cy;
15685
+ // 应用旋转矩阵
15686
+ const cos = Math.cos(angleRadians);
15687
+ const sin = Math.sin(angleRadians);
15688
+ const rotatedX = dx * cos - dy * sin;
15689
+ const rotatedY = dx * sin + dy * cos;
15690
+ // 移回原位置
15691
+ return [rotatedX + cx, rotatedY + cy];
15692
+ };
15693
+ // 获取有效的GPS边界
15694
+ const getValidGpsBounds = (mapData, rotation = 0) => {
15695
+ let bounds;
15696
+ // 优先使用 center_gps 和 map_width/map_height 计算边界
15697
+ if (mapData.center_gps &&
15698
+ mapData.center_gps.length >= 2 &&
15699
+ isValidGpsCoordinate(mapData.center_gps?.[1], mapData.center_gps?.[0]) &&
15700
+ typeof mapData.map_width === 'number' &&
15701
+ typeof mapData.map_height === 'number' &&
15702
+ mapData.map_width > 0 &&
15703
+ mapData.map_height > 0) {
15704
+ const [centerLng, centerLat] = mapData.center_gps;
15705
+ const mapWidthMeters = mapData.map_width;
15706
+ const mapHeightMeters = mapData.map_height;
15707
+ // 精确的坐标转换常数(基于 WGS84 标准 - GPS 国际标准)
15708
+ // WGS84 赤道半径 = 6,378,137 米
15709
+ // 地球赤道周长 = 2 × π × 6,378,137 ≈ 40,075,017 米
15710
+ // 1度纬度 = 40075017 / 360 ≈ 111,319.49 米(在地球上任何地方都基本相同)
15711
+ // 1度经度 = (40075017 / 360) * cos(纬度) 米(随纬度变化)
15712
+ const METERS_PER_DEGREE_LAT = EQUATORIAL_CIRCUMFERENCE / 360;
15713
+ const METERS_PER_DEGREE_LNG = METERS_PER_DEGREE_LAT * Math.cos((centerLat * Math.PI) / 180);
15714
+ // 计算SW(西南角)GPS坐标:从中心点减去半个地图的宽度和高度
15715
+ const swLat = centerLat - mapHeightMeters / 2 / METERS_PER_DEGREE_LAT;
15716
+ const swLng = centerLng - mapWidthMeters / 2 / METERS_PER_DEGREE_LNG;
15717
+ // 计算NE(东北角)GPS坐标:从中心点加上半个地图的宽度和高度
15718
+ const neLat = centerLat + mapHeightMeters / 2 / METERS_PER_DEGREE_LAT;
15719
+ const neLng = centerLng + mapWidthMeters / 2 / METERS_PER_DEGREE_LNG;
15720
+ bounds = {
15721
+ sw: [swLng, swLat],
15722
+ ne: [neLng, neLat],
15723
+ };
15724
+ }
15725
+ else if (isValidGpsCoordinate(mapData.sw_gps?.[1], mapData.sw_gps?.[0]) &&
15726
+ isValidGpsCoordinate(mapData.ne_gps?.[1], mapData.ne_gps?.[0])) {
15727
+ // 降级方案:使用地图数据中的GPS坐标
15728
+ console.warn('center_gps 或 map_width/map_height 不可用,使用 sw_gps 和 ne_gps');
15729
+ bounds = {
15730
+ sw: mapData.sw_gps,
15731
+ ne: mapData.ne_gps,
15732
+ };
15733
+ }
15734
+ else {
15735
+ // 如果GPS坐标无效,尝试从地图几何数据估算
15736
+ const { sw, ne } = estimateGpsFromMapBounds(mapData);
15737
+ if (sw && ne) {
15738
+ console.warn('GPS坐标无效,使用地图几何数据估算边界:', sw, ne);
15739
+ bounds = {
15740
+ sw: [sw[0], sw[1]],
15741
+ ne: [ne[0], ne[1]],
15742
+ };
15743
+ }
15744
+ else {
15745
+ // 最后的fallback:使用默认坐标
15746
+ console.warn('无法获取有效的GPS边界,使用默认坐标');
15747
+ bounds = DEFAULT_COORDINATES;
15748
+ }
15749
+ }
15750
+ // 如果有旋转角度,计算旋转后的边界
15751
+ if (rotation !== 0) {
15752
+ const angleRadians = (rotation * Math.PI) / 180; // 转换为弧度
15753
+ // 计算边界中心点
15754
+ const centerLng = (bounds.sw[0] + bounds.ne[0]) / 2;
15755
+ const centerLat = (bounds.sw[1] + bounds.ne[1]) / 2;
15756
+ const center = [centerLng, centerLat];
15757
+ // 旋转四个角点
15758
+ const sw = rotateCoordinate(bounds.sw, center, angleRadians);
15759
+ const ne = rotateCoordinate(bounds.ne, center, angleRadians);
15760
+ const se = rotateCoordinate([bounds.ne[0], bounds.sw[1]], center, angleRadians);
15761
+ const nw = rotateCoordinate([bounds.sw[0], bounds.ne[1]], center, angleRadians);
15762
+ // 计算旋转后的边界框(包含所有旋转后的点)
15763
+ const lngs = [sw[0], ne[0], se[0], nw[0]];
15764
+ const lats = [sw[1], ne[1], se[1], nw[1]];
15765
+ bounds = {
15766
+ sw: [Math.min(...lngs), Math.min(...lats)],
15767
+ ne: [Math.max(...lngs), Math.max(...lats)],
15768
+ };
15769
+ }
15770
+ return bounds;
15771
+ };
15676
15772
 
15677
15773
  function dp2px(dp, customDensity = null) {
15678
15774
  // 使用自定义密度或设备像素比
@@ -19683,7 +19779,7 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19683
19779
  onTransformChange?.({
19684
19780
  x: deltaX,
19685
19781
  y: deltaY,
19686
- rotate: currentRotationRef.current,
19782
+ rotate: 0,
19687
19783
  });
19688
19784
  startPosRef.current = { x: clientX, y: clientY };
19689
19785
  }, [onTransformChange]);
@@ -19721,35 +19817,11 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19721
19817
  onTransformChange?.({
19722
19818
  x: tempPixelOffsetRef.current.x,
19723
19819
  y: tempPixelOffsetRef.current.y,
19724
- rotate: currentRotationRef.current,
19820
+ rotate: angleDifferenceDegrees,
19725
19821
  });
19726
19822
  // 更新鼠标起始位置为当前位置,为下次计算做准备
19727
19823
  startPosRef.current = { x: mouseCurrentX, y: mouseCurrentY };
19728
19824
  }, [onTransformChange]);
19729
- // 设置transform
19730
- const setTransform = useCallback((transform) => {
19731
- if (typeof transform.x === 'number')
19732
- tempPixelOffsetRef.current.x = transform.x;
19733
- if (typeof transform.y === 'number')
19734
- tempPixelOffsetRef.current.y = transform.y;
19735
- if (typeof transform.rotation === 'number')
19736
- currentRotationRef.current = transform.rotation;
19737
- onTransformChange?.({
19738
- x: tempPixelOffsetRef.current.x,
19739
- y: tempPixelOffsetRef.current.y,
19740
- rotate: currentRotationRef.current,
19741
- });
19742
- }, [onTransformChange]);
19743
- // 重置到默认的transform
19744
- const resetToDefaultTransform = useCallback(() => {
19745
- tempPixelOffsetRef.current = { x: 0, y: 0 };
19746
- currentRotationRef.current = 0;
19747
- initialOffsetRef.current = { x: 0, y: 0 };
19748
- initialRotationRef.current = 0;
19749
- const transformString = `translate(0px, 0px) rotate(0deg)`;
19750
- onTransformChange?.(transformString);
19751
- dragCallbacks?.onDragEnd?.(getCurrentDragState());
19752
- }, [dragCallbacks, getCurrentDragState, onTransformChange]);
19753
19825
  // 添加全局事件监听器
19754
19826
  const addGlobalListeners = useCallback(() => {
19755
19827
  const handleMouseMove = (e) => handleDragMove(e);
@@ -19778,8 +19850,6 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19778
19850
  handleDragMove,
19779
19851
  handleDragEnd,
19780
19852
  addGlobalListeners,
19781
- setTransform,
19782
- resetToDefaultTransform,
19783
19853
  getCurrentDragState,
19784
19854
  };
19785
19855
  };
@@ -23387,23 +23457,26 @@ const useCheckElement = () => {
23387
23457
  return doodleTransformedPoints.some((point) => isPointInPolygon(point, currentBoundaryPoints));
23388
23458
  });
23389
23459
  // 4. 检查当前 obstacle 和 doodle 不能相交,且间隔要大于2m
23390
- // console.log('doodlesInBoundary--->', doodlesInBoundary);
23391
23460
  for (const doodle of doodlesInBoundary) {
23392
- const doodleTransformedPoints = transformSvgElements(doodle).flat();
23393
- // 检查相交
23394
- if (doPolygonsIntersect(currentObstaclePolygon, doodleTransformedPoints)) {
23395
- return {
23396
- result: true,
23397
- code: CheckObstaclePointErrorType.DOODLE_INTERSECT,
23398
- };
23399
- }
23400
- // 检查距离
23401
- const distance = polygonToPolygonDistance(currentObstaclePolygon, doodleTransformedPoints);
23402
- if (distance < minDistance) {
23403
- return {
23404
- result: true,
23405
- code: CheckObstaclePointErrorType.DOODLE_DISTANCE_TOO_CLOSE,
23406
- };
23461
+ // doodle 转换后的数据是二维数组,数组的每一项都是一个polygon,这里之所以不用flat()扁平处理
23462
+ // 因为多个polygon可能会有相交/相切的情况,单纯flat会导致无法处理flat后的不正常的矩形数据
23463
+ const doodleTransformedPoints = transformSvgElements(doodle);
23464
+ for (const points of doodleTransformedPoints) {
23465
+ // 检查相交
23466
+ if (doPolygonsIntersect(currentObstaclePolygon, points)) {
23467
+ return {
23468
+ result: true,
23469
+ code: CheckObstaclePointErrorType.DOODLE_INTERSECT,
23470
+ };
23471
+ }
23472
+ // 检查距离
23473
+ const distance = polygonToPolygonDistance(currentObstaclePolygon, points);
23474
+ if (distance < minDistance) {
23475
+ return {
23476
+ result: true,
23477
+ code: CheckObstaclePointErrorType.DOODLE_DISTANCE_TOO_CLOSE,
23478
+ };
23479
+ }
23407
23480
  }
23408
23481
  }
23409
23482
  return {
@@ -28758,82 +28831,6 @@ const WGS84 = 'EPSG:4326';
28758
28831
  const WEB_MERCATOR = 'EPSG:3857';
28759
28832
  proj4.defs(WGS84, '+proj=longlat +datum=WGS84 +no_defs');
28760
28833
  proj4.defs(WEB_MERCATOR, '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
28761
- // 验证GPS坐标是否有效
28762
- const isValidGpsCoordinate = (coordinate) => {
28763
- if (!coordinate || coordinate.length < 2)
28764
- return false;
28765
- const [lng, lat] = coordinate;
28766
- // 检查是否为有效的GPS坐标范围,且不是原点(0,0)
28767
- return (lng >= -180 &&
28768
- lng <= 180 &&
28769
- lat >= -90 &&
28770
- lat <= 90 &&
28771
- !(Math.abs(lng) < 0.001 && Math.abs(lat) < 0.001) // 排除接近(0,0)的坐标
28772
- );
28773
- };
28774
- // 旋转坐标点
28775
- const rotateCoordinate = (point, center, angleRadians) => {
28776
- const [x, y] = point;
28777
- const [cx, cy] = center;
28778
- // 将点移动到原点
28779
- const dx = x - cx;
28780
- const dy = y - cy;
28781
- // 应用旋转矩阵
28782
- const cos = Math.cos(angleRadians);
28783
- const sin = Math.sin(angleRadians);
28784
- const rotatedX = dx * cos - dy * sin;
28785
- const rotatedY = dx * sin + dy * cos;
28786
- // 移回原位置
28787
- return [rotatedX + cx, rotatedY + cy];
28788
- };
28789
- // 获取有效的GPS边界
28790
- const getValidGpsBounds = (mapData, rotation = 0) => {
28791
- let bounds;
28792
- // 首先尝试使用地图数据中的GPS坐标
28793
- if (isValidGpsCoordinate(mapData.sw_gps) && isValidGpsCoordinate(mapData.ne_gps)) {
28794
- bounds = {
28795
- sw: mapData.sw_gps,
28796
- ne: mapData.ne_gps,
28797
- };
28798
- }
28799
- else {
28800
- // 如果GPS坐标无效,尝试从地图几何数据估算
28801
- const { sw, ne } = estimateGpsFromMapBounds(mapData);
28802
- if (sw && ne) {
28803
- console.warn('GPS坐标无效,使用地图几何数据估算边界:', sw, ne);
28804
- bounds = {
28805
- sw: [sw[0], sw[1]],
28806
- ne: [ne[0], ne[1]],
28807
- };
28808
- }
28809
- else {
28810
- // 最后的fallback:使用默认坐标
28811
- console.warn('无法获取有效的GPS边界,使用默认坐标');
28812
- bounds = DEFAULT_COORDINATES;
28813
- }
28814
- }
28815
- // 如果有旋转角度,计算旋转后的边界
28816
- if (rotation !== 0) {
28817
- const angleRadians = (rotation * Math.PI) / 180; // 转换为弧度
28818
- // 计算边界中心点
28819
- const centerLng = (bounds.sw[0] + bounds.ne[0]) / 2;
28820
- const centerLat = (bounds.sw[1] + bounds.ne[1]) / 2;
28821
- const center = [centerLng, centerLat];
28822
- // 旋转四个角点
28823
- const sw = rotateCoordinate(bounds.sw, center, angleRadians);
28824
- const ne = rotateCoordinate(bounds.ne, center, angleRadians);
28825
- const se = rotateCoordinate([bounds.ne[0], bounds.sw[1]], center, angleRadians);
28826
- const nw = rotateCoordinate([bounds.sw[0], bounds.ne[1]], center, angleRadians);
28827
- // 计算旋转后的边界框(包含所有旋转后的点)
28828
- const lngs = [sw[0], ne[0], se[0], nw[0]];
28829
- const lats = [sw[1], ne[1], se[1], nw[1]];
28830
- bounds = {
28831
- sw: [Math.min(...lngs), Math.min(...lats)],
28832
- ne: [Math.max(...lngs), Math.max(...lats)],
28833
- };
28834
- }
28835
- return bounds;
28836
- };
28837
28834
  // 默认配置
28838
28835
  const defaultMapConfig$1 = DEFAULT_STYLES;
28839
28836
  // 地图渲染器组件
@@ -28873,6 +28870,14 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28873
28870
  const mapBounds = useMemo(() => {
28874
28871
  return calculateMapBounds(mapJson);
28875
28872
  }, [mapJson]);
28873
+ const originNorthRotate = useMemo(() => {
28874
+ if (mapJson.map_north_offset)
28875
+ return (mapJson.map_north_offset * 180) / Math.PI;
28876
+ return 0;
28877
+ }, [mapJson]);
28878
+ const actureRotate = useMemo(() => {
28879
+ return originNorthRotate + drag?.rotation;
28880
+ }, [originNorthRotate, drag?.rotation]);
28876
28881
  const svgViewBox = useMemo(() => {
28877
28882
  const padding = 0; // 添加一些边距以避免内容贴边
28878
28883
  const boundWidth = mapBounds.maxX - mapBounds.minX + padding * 2;
@@ -28953,8 +28958,12 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28953
28958
  newSvgElementDatas[key] =
28954
28959
  newSvgElementDatas[key].filter((item) => {
28955
28960
  return (item.status === 1 &&
28956
- (!item.start_timestamp || !item.end_timestamp || (item.start_timestamp && item.start_timestamp <= Date.now() / 1000 &&
28957
- item.end_timestamp && item.end_timestamp >= Date.now() / 1000)));
28961
+ (!item.start_timestamp ||
28962
+ !item.end_timestamp ||
28963
+ (item.start_timestamp &&
28964
+ item.start_timestamp <= Date.now() / 1000 &&
28965
+ item.end_timestamp &&
28966
+ item.end_timestamp >= Date.now() / 1000)));
28958
28967
  }) || [];
28959
28968
  }
28960
28969
  else if (key === DataType.DOODLE) {
@@ -28997,7 +29006,11 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28997
29006
  globalHeight,
28998
29007
  mapConfig: mergedMapConfig,
28999
29008
  mapJson,
29000
- drag: defaultTransform,
29009
+ drag: {
29010
+ x: defaultTransform?.x ?? 0,
29011
+ y: defaultTransform?.y ?? 0,
29012
+ rotate: (defaultTransform?.rotation ?? 0) + originNorthRotate,
29013
+ },
29001
29014
  mapRef,
29002
29015
  overlayScale,
29003
29016
  doodleList,
@@ -29016,6 +29029,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29016
29029
  mergedMapConfig,
29017
29030
  mapJson,
29018
29031
  defaultTransform,
29032
+ originNorthRotate,
29019
29033
  mapRef,
29020
29034
  overlayScale,
29021
29035
  doodleList,
@@ -29100,8 +29114,9 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29100
29114
  handleError('无法计算地图边界');
29101
29115
  return;
29102
29116
  }
29117
+ const rotate = defaultTransform?.rotation + originNorthRotate;
29103
29118
  // 将自定义边界转换为Google Maps LatLngBounds(使用有效的GPS坐标)
29104
- const validBounds = getValidGpsBounds(mapJson, defaultTransform?.rotation);
29119
+ const validBounds = getValidGpsBounds(mapJson, rotate);
29105
29120
  // 地图数据中的坐标格式是 [longitude, latitude]
29106
29121
  const [swLng0, swLat0] = validBounds.sw;
29107
29122
  const [neLng0, neLat0] = validBounds.ne;
@@ -29117,7 +29132,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29117
29132
  new window.google.maps.LatLng(neLat, neLng) // 东北角
29118
29133
  );
29119
29134
  mapRef.fitBounds(googleBounds, padding);
29120
- }, [mapJson, mapRef, defaultTransform]);
29135
+ }, [mapJson, mapRef, defaultTransform, originNorthRotate]);
29121
29136
  const handleDragMove = useCallback((e) => {
29122
29137
  if (!overlay || !bounds)
29123
29138
  return;
@@ -29146,7 +29161,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29146
29161
  setDrag((prev) => ({
29147
29162
  x: prev.x + dx,
29148
29163
  y: prev.y + dy,
29149
- rotation: e.rotate,
29164
+ rotation: prev.rotation + e.rotate,
29150
29165
  }));
29151
29166
  }, [overlay, bounds]);
29152
29167
  useEffect(() => {
@@ -29173,17 +29188,21 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29173
29188
  // mowPartitionDataRef.current = {};
29174
29189
  // // console.error('0.50.5--mowPartitionDataRef.current---->', mowPartitionDataRef.current);
29175
29190
  // }
29176
- isTaskDelayRef.current = vehicleStatusData?.taskDelay !== undefined ? vehicleStatusData?.taskDelay : isTaskDelayRef.current;
29191
+ isTaskDelayRef.current =
29192
+ vehicleStatusData?.taskDelay !== undefined
29193
+ ? vehicleStatusData?.taskDelay
29194
+ : isTaskDelayRef.current;
29177
29195
  // console.error('isTaskDelayRef.current 111---->', isTaskDelayRef.current);
29178
29196
  }
29179
29197
  const positionData = realTimeData?.find((item) => item?.type === RealTimeDataType.LOCATION);
29180
29198
  // 如果当前是taskDelay的状态,或者状态为mowing或者standby,则指定的地块需要高亮,或者全局高亮
29181
- if ((isTaskDelayRef.current || positionData?.vehicleState === RobotStatus.MOWING || positionData?.vehicleState === RobotStatus.STANDBY) &&
29199
+ if ((isTaskDelayRef.current ||
29200
+ positionData?.vehicleState === RobotStatus.MOWING ||
29201
+ positionData?.vehicleState === RobotStatus.STANDBY) &&
29182
29202
  mowPartitionDataRef.current &&
29183
29203
  !mowPartitionDataRef.current?.partitionIds) {
29184
29204
  // 设置全局高亮
29185
- if (mowPartitionDataRef.current &&
29186
- !mowPartitionDataRef.current?.partitionIds) {
29205
+ if (mowPartitionDataRef.current && !mowPartitionDataRef.current?.partitionIds) {
29187
29206
  const allPartitionIds = generateBoundaryData(mapJson)
29188
29207
  ?.filter((item) => !item?.isIsolated)
29189
29208
  .map((item) => item?.id);
@@ -29195,7 +29214,10 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29195
29214
  };
29196
29215
  }
29197
29216
  }
29198
- else if (!isTaskDelayRef.current && positionData?.vehicleState === RobotStatus.WORKING && (currentVehicleStateRef.current === RobotStatus.MOWING || currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29217
+ else if (!isTaskDelayRef.current &&
29218
+ positionData?.vehicleState === RobotStatus.WORKING &&
29219
+ (currentVehicleStateRef.current === RobotStatus.MOWING ||
29220
+ currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29199
29221
  // 非deskDelay的状态下
29200
29222
  // 1. 如果当前是working状态,且上一次是mowing或者standby状态,则取消高亮
29201
29223
  // 兜底收不到割草地块的实时数据,使用状态来兜底
@@ -29204,12 +29226,16 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29204
29226
  mowPartitionDataRef.current = {};
29205
29227
  }
29206
29228
  // 更新当前车辆状态
29207
- currentVehicleStateRef.current = positionData?.vehicleState !== undefined ? positionData?.vehicleState : currentVehicleStateRef.current;
29229
+ currentVehicleStateRef.current =
29230
+ positionData?.vehicleState !== undefined
29231
+ ? positionData?.vehicleState
29232
+ : currentVehicleStateRef.current;
29208
29233
  if (!mapJson || !svgMapRef.current)
29209
29234
  return;
29210
29235
  // 根据后端推送的实时数据,进行不同处理
29211
29236
  if (mowPartitionDataRef.current) {
29212
- const isMowing = mowPartitionDataRef.current?.partitionIds && mowPartitionDataRef.current.partitionIds.length > 0;
29237
+ const isMowing = mowPartitionDataRef.current?.partitionIds &&
29238
+ mowPartitionDataRef.current.partitionIds.length > 0;
29213
29239
  if (!isMowing) {
29214
29240
  setMowingPartitions(undefined);
29215
29241
  }
@@ -29276,7 +29302,6 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29276
29302
  // 基于固定的参考zoom级别计算overlayScale
29277
29303
  const zoomDiff = currentZoom - REFERENCE_ZOOM;
29278
29304
  const scale = Math.pow(2, -zoomDiff); // 负数实现反向缩放
29279
- console.log('scale------->', scale);
29280
29305
  // setOverlayScale(scale < 1 ? 1 : platform === PlatformType.H5 ? 1.5 * scale : scale);
29281
29306
  if (scale < 1) {
29282
29307
  setOverlayScale(1);
@@ -29394,7 +29419,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29394
29419
  // svgEditMapRef?.current?.adjustSvgSize?.(layout);
29395
29420
  setOverlayLayout(layout);
29396
29421
  }
29397
- }, map: mapRef, mapPaneName: 'overlayMouseTarget', bounds: bounds, rotate: drag?.rotation, children: [jsx(MapDrag, { map: mapRef, dragCallbacks: dragCallbacks, onBoundaryLabelsCollapse: () => { }, onTransformChange: handleDragMove, isDragMap: dragMap, canRotateMap: canRotateMap }), jsx(MowPartitionContextProvider, { value: mowPartitionValue, children: jsx(SvgMapComponent, { editMap: editMap, ref: svgMapRef, pathData: pathJson, mapConfig: mergedMapConfig, mowPartitionData: mowPartitionData }) }), jsx(MowerPosition, { editMap: editMap, mowerPositionData: mowerPositionData, viewBox: svgViewBox || null, modelType: modelType, hasEdger: edger, mapData: mapJson, mapConfig: mergedMapConfig, realTimeData: realTimeData, onMowingPositionChange: onMowingPositionChange }), jsx(CharginPile, { viewBox: svgViewBox || null, rotation: drag?.rotation }), jsx(BoundaryLabels, { editMap: editMap, mapData: mapJson, onlyRead: onlyRead, pathData: pathJson, unitType: unitType, viewBox: svgViewBox || null, rotation: drag?.rotation, mowPartitionData: mowPartitionData, realTimeData: realTimeData }), jsx(Antennas, { editMap: editMap, antennaConfig: antennaConfig || [], layout: overlayLayout || undefined, viewBox: svgViewBox || null, rotation: drag?.rotation, onlyRead: onlyRead }), jsx(SvgEditMap, { editMap: editMap, ref: svgEditMapRef, mapConfig: mergedMapConfig, onEditInfoMapChange: onEditInfoMapChange })] })] }) }) }));
29422
+ }, map: mapRef, mapPaneName: 'overlayMouseTarget', bounds: bounds, rotate: actureRotate, children: [jsx(MapDrag, { map: mapRef, dragCallbacks: dragCallbacks, onBoundaryLabelsCollapse: () => { }, onTransformChange: handleDragMove, isDragMap: dragMap, canRotateMap: canRotateMap }), jsx(MowPartitionContextProvider, { value: mowPartitionValue, children: jsx(SvgMapComponent, { editMap: editMap, ref: svgMapRef, pathData: pathJson, mapConfig: mergedMapConfig, mowPartitionData: mowPartitionData }) }), jsx(MowerPosition, { editMap: editMap, mowerPositionData: mowerPositionData, viewBox: svgViewBox || null, modelType: modelType, hasEdger: edger, mapData: mapJson, mapConfig: mergedMapConfig, realTimeData: realTimeData, onMowingPositionChange: onMowingPositionChange }), jsx(CharginPile, { viewBox: svgViewBox || null, rotation: actureRotate }), jsx(BoundaryLabels, { editMap: editMap, mapData: mapJson, onlyRead: onlyRead, pathData: pathJson, unitType: unitType, viewBox: svgViewBox || null, rotation: actureRotate, mowPartitionData: mowPartitionData, realTimeData: realTimeData }), jsx(Antennas, { editMap: editMap, antennaConfig: antennaConfig || [], layout: overlayLayout || undefined, viewBox: svgViewBox || null, rotation: actureRotate, onlyRead: onlyRead }), jsx(SvgEditMap, { editMap: editMap, ref: svgEditMapRef, mapConfig: mergedMapConfig, onEditInfoMapChange: onEditInfoMapChange })] })] }) }) }));
29398
29423
  });
29399
29424
  MowerMapRenderer.displayName = 'MowerMapRenderer';
29400
29425
 
package/dist/index.js CHANGED
@@ -10698,6 +10698,8 @@ const ACTION_BOUNDARY_TASK = 8;
10698
10698
  const ALL_DIRECTION_SELECTED = 63;
10699
10699
  const MIN_DIRECTION_ANGLE = -14;
10700
10700
  const MAX_DIRECTION_ANGLE = 15;
10701
+ // WGS84 赤道周长
10702
+ const EQUATORIAL_CIRCUMFERENCE = 40075017;
10701
10703
 
10702
10704
  /**
10703
10705
  * 数据类型枚举
@@ -15557,7 +15559,7 @@ function calculateBoundaryBoundsCenter(mapData) {
15557
15559
  /**
15558
15560
  * 检查GPS坐标是否有效
15559
15561
  */
15560
- function isValidGpsCoordinate$1(lat, lng) {
15562
+ function isValidGpsCoordinate(lat, lng) {
15561
15563
  // 检查纬度范围 (-90 到 90) 和经度范围 (-180 到 180)
15562
15564
  // 同时排除明显无效的坐标(如0,0或者很接近0的值)
15563
15565
  return (lat >= -90 &&
@@ -15650,7 +15652,7 @@ function calculateMapGpsCenter(mapData) {
15650
15652
  if (mapData.center_gps && mapData.center_gps.length >= 2) {
15651
15653
  const lat = mapData.center_gps[1];
15652
15654
  const lng = mapData.center_gps[0];
15653
- if (isValidGpsCoordinate$1(lat, lng)) {
15655
+ if (isValidGpsCoordinate(lat, lng)) {
15654
15656
  return { lat, lng };
15655
15657
  }
15656
15658
  else {
@@ -15667,7 +15669,7 @@ function calculateMapGpsCenter(mapData) {
15667
15669
  const neLat = mapData.ne_gps[1];
15668
15670
  const neLng = mapData.ne_gps[0];
15669
15671
  // 检查边界坐标的有效性
15670
- if (isValidGpsCoordinate$1(swLat, swLng) && isValidGpsCoordinate$1(neLat, neLng)) {
15672
+ if (isValidGpsCoordinate(swLat, swLng) && isValidGpsCoordinate(neLat, neLng)) {
15671
15673
  return {
15672
15674
  lat: (swLat + neLat) / 2,
15673
15675
  lng: (swLng + neLng) / 2,
@@ -15693,6 +15695,100 @@ function calculateMapGpsCenter(mapData) {
15693
15695
  lng: 116.4074, // 北京经度
15694
15696
  };
15695
15697
  }
15698
+ // 旋转坐标点
15699
+ const rotateCoordinate = (point, center, angleRadians) => {
15700
+ const [x, y] = point;
15701
+ const [cx, cy] = center;
15702
+ // 将点移动到原点
15703
+ const dx = x - cx;
15704
+ const dy = y - cy;
15705
+ // 应用旋转矩阵
15706
+ const cos = Math.cos(angleRadians);
15707
+ const sin = Math.sin(angleRadians);
15708
+ const rotatedX = dx * cos - dy * sin;
15709
+ const rotatedY = dx * sin + dy * cos;
15710
+ // 移回原位置
15711
+ return [rotatedX + cx, rotatedY + cy];
15712
+ };
15713
+ // 获取有效的GPS边界
15714
+ const getValidGpsBounds = (mapData, rotation = 0) => {
15715
+ let bounds;
15716
+ // 优先使用 center_gps 和 map_width/map_height 计算边界
15717
+ if (mapData.center_gps &&
15718
+ mapData.center_gps.length >= 2 &&
15719
+ isValidGpsCoordinate(mapData.center_gps?.[1], mapData.center_gps?.[0]) &&
15720
+ typeof mapData.map_width === 'number' &&
15721
+ typeof mapData.map_height === 'number' &&
15722
+ mapData.map_width > 0 &&
15723
+ mapData.map_height > 0) {
15724
+ const [centerLng, centerLat] = mapData.center_gps;
15725
+ const mapWidthMeters = mapData.map_width;
15726
+ const mapHeightMeters = mapData.map_height;
15727
+ // 精确的坐标转换常数(基于 WGS84 标准 - GPS 国际标准)
15728
+ // WGS84 赤道半径 = 6,378,137 米
15729
+ // 地球赤道周长 = 2 × π × 6,378,137 ≈ 40,075,017 米
15730
+ // 1度纬度 = 40075017 / 360 ≈ 111,319.49 米(在地球上任何地方都基本相同)
15731
+ // 1度经度 = (40075017 / 360) * cos(纬度) 米(随纬度变化)
15732
+ const METERS_PER_DEGREE_LAT = EQUATORIAL_CIRCUMFERENCE / 360;
15733
+ const METERS_PER_DEGREE_LNG = METERS_PER_DEGREE_LAT * Math.cos((centerLat * Math.PI) / 180);
15734
+ // 计算SW(西南角)GPS坐标:从中心点减去半个地图的宽度和高度
15735
+ const swLat = centerLat - mapHeightMeters / 2 / METERS_PER_DEGREE_LAT;
15736
+ const swLng = centerLng - mapWidthMeters / 2 / METERS_PER_DEGREE_LNG;
15737
+ // 计算NE(东北角)GPS坐标:从中心点加上半个地图的宽度和高度
15738
+ const neLat = centerLat + mapHeightMeters / 2 / METERS_PER_DEGREE_LAT;
15739
+ const neLng = centerLng + mapWidthMeters / 2 / METERS_PER_DEGREE_LNG;
15740
+ bounds = {
15741
+ sw: [swLng, swLat],
15742
+ ne: [neLng, neLat],
15743
+ };
15744
+ }
15745
+ else if (isValidGpsCoordinate(mapData.sw_gps?.[1], mapData.sw_gps?.[0]) &&
15746
+ isValidGpsCoordinate(mapData.ne_gps?.[1], mapData.ne_gps?.[0])) {
15747
+ // 降级方案:使用地图数据中的GPS坐标
15748
+ console.warn('center_gps 或 map_width/map_height 不可用,使用 sw_gps 和 ne_gps');
15749
+ bounds = {
15750
+ sw: mapData.sw_gps,
15751
+ ne: mapData.ne_gps,
15752
+ };
15753
+ }
15754
+ else {
15755
+ // 如果GPS坐标无效,尝试从地图几何数据估算
15756
+ const { sw, ne } = estimateGpsFromMapBounds(mapData);
15757
+ if (sw && ne) {
15758
+ console.warn('GPS坐标无效,使用地图几何数据估算边界:', sw, ne);
15759
+ bounds = {
15760
+ sw: [sw[0], sw[1]],
15761
+ ne: [ne[0], ne[1]],
15762
+ };
15763
+ }
15764
+ else {
15765
+ // 最后的fallback:使用默认坐标
15766
+ console.warn('无法获取有效的GPS边界,使用默认坐标');
15767
+ bounds = DEFAULT_COORDINATES;
15768
+ }
15769
+ }
15770
+ // 如果有旋转角度,计算旋转后的边界
15771
+ if (rotation !== 0) {
15772
+ const angleRadians = (rotation * Math.PI) / 180; // 转换为弧度
15773
+ // 计算边界中心点
15774
+ const centerLng = (bounds.sw[0] + bounds.ne[0]) / 2;
15775
+ const centerLat = (bounds.sw[1] + bounds.ne[1]) / 2;
15776
+ const center = [centerLng, centerLat];
15777
+ // 旋转四个角点
15778
+ const sw = rotateCoordinate(bounds.sw, center, angleRadians);
15779
+ const ne = rotateCoordinate(bounds.ne, center, angleRadians);
15780
+ const se = rotateCoordinate([bounds.ne[0], bounds.sw[1]], center, angleRadians);
15781
+ const nw = rotateCoordinate([bounds.sw[0], bounds.ne[1]], center, angleRadians);
15782
+ // 计算旋转后的边界框(包含所有旋转后的点)
15783
+ const lngs = [sw[0], ne[0], se[0], nw[0]];
15784
+ const lats = [sw[1], ne[1], se[1], nw[1]];
15785
+ bounds = {
15786
+ sw: [Math.min(...lngs), Math.min(...lats)],
15787
+ ne: [Math.max(...lngs), Math.max(...lats)],
15788
+ };
15789
+ }
15790
+ return bounds;
15791
+ };
15696
15792
 
15697
15793
  function dp2px(dp, customDensity = null) {
15698
15794
  // 使用自定义密度或设备像素比
@@ -19703,7 +19799,7 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19703
19799
  onTransformChange?.({
19704
19800
  x: deltaX,
19705
19801
  y: deltaY,
19706
- rotate: currentRotationRef.current,
19802
+ rotate: 0,
19707
19803
  });
19708
19804
  startPosRef.current = { x: clientX, y: clientY };
19709
19805
  }, [onTransformChange]);
@@ -19741,35 +19837,11 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19741
19837
  onTransformChange?.({
19742
19838
  x: tempPixelOffsetRef.current.x,
19743
19839
  y: tempPixelOffsetRef.current.y,
19744
- rotate: currentRotationRef.current,
19840
+ rotate: angleDifferenceDegrees,
19745
19841
  });
19746
19842
  // 更新鼠标起始位置为当前位置,为下次计算做准备
19747
19843
  startPosRef.current = { x: mouseCurrentX, y: mouseCurrentY };
19748
19844
  }, [onTransformChange]);
19749
- // 设置transform
19750
- const setTransform = React.useCallback((transform) => {
19751
- if (typeof transform.x === 'number')
19752
- tempPixelOffsetRef.current.x = transform.x;
19753
- if (typeof transform.y === 'number')
19754
- tempPixelOffsetRef.current.y = transform.y;
19755
- if (typeof transform.rotation === 'number')
19756
- currentRotationRef.current = transform.rotation;
19757
- onTransformChange?.({
19758
- x: tempPixelOffsetRef.current.x,
19759
- y: tempPixelOffsetRef.current.y,
19760
- rotate: currentRotationRef.current,
19761
- });
19762
- }, [onTransformChange]);
19763
- // 重置到默认的transform
19764
- const resetToDefaultTransform = React.useCallback(() => {
19765
- tempPixelOffsetRef.current = { x: 0, y: 0 };
19766
- currentRotationRef.current = 0;
19767
- initialOffsetRef.current = { x: 0, y: 0 };
19768
- initialRotationRef.current = 0;
19769
- const transformString = `translate(0px, 0px) rotate(0deg)`;
19770
- onTransformChange?.(transformString);
19771
- dragCallbacks?.onDragEnd?.(getCurrentDragState());
19772
- }, [dragCallbacks, getCurrentDragState, onTransformChange]);
19773
19845
  // 添加全局事件监听器
19774
19846
  const addGlobalListeners = React.useCallback(() => {
19775
19847
  const handleMouseMove = (e) => handleDragMove(e);
@@ -19798,8 +19870,6 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19798
19870
  handleDragMove,
19799
19871
  handleDragEnd,
19800
19872
  addGlobalListeners,
19801
- setTransform,
19802
- resetToDefaultTransform,
19803
19873
  getCurrentDragState,
19804
19874
  };
19805
19875
  };
@@ -23407,23 +23477,26 @@ const useCheckElement = () => {
23407
23477
  return doodleTransformedPoints.some((point) => isPointInPolygon(point, currentBoundaryPoints));
23408
23478
  });
23409
23479
  // 4. 检查当前 obstacle 和 doodle 不能相交,且间隔要大于2m
23410
- // console.log('doodlesInBoundary--->', doodlesInBoundary);
23411
23480
  for (const doodle of doodlesInBoundary) {
23412
- const doodleTransformedPoints = transformSvgElements(doodle).flat();
23413
- // 检查相交
23414
- if (doPolygonsIntersect(currentObstaclePolygon, doodleTransformedPoints)) {
23415
- return {
23416
- result: true,
23417
- code: exports.CheckObstaclePointErrorType.DOODLE_INTERSECT,
23418
- };
23419
- }
23420
- // 检查距离
23421
- const distance = polygonToPolygonDistance(currentObstaclePolygon, doodleTransformedPoints);
23422
- if (distance < minDistance) {
23423
- return {
23424
- result: true,
23425
- code: exports.CheckObstaclePointErrorType.DOODLE_DISTANCE_TOO_CLOSE,
23426
- };
23481
+ // doodle 转换后的数据是二维数组,数组的每一项都是一个polygon,这里之所以不用flat()扁平处理
23482
+ // 因为多个polygon可能会有相交/相切的情况,单纯flat会导致无法处理flat后的不正常的矩形数据
23483
+ const doodleTransformedPoints = transformSvgElements(doodle);
23484
+ for (const points of doodleTransformedPoints) {
23485
+ // 检查相交
23486
+ if (doPolygonsIntersect(currentObstaclePolygon, points)) {
23487
+ return {
23488
+ result: true,
23489
+ code: exports.CheckObstaclePointErrorType.DOODLE_INTERSECT,
23490
+ };
23491
+ }
23492
+ // 检查距离
23493
+ const distance = polygonToPolygonDistance(currentObstaclePolygon, points);
23494
+ if (distance < minDistance) {
23495
+ return {
23496
+ result: true,
23497
+ code: exports.CheckObstaclePointErrorType.DOODLE_DISTANCE_TOO_CLOSE,
23498
+ };
23499
+ }
23427
23500
  }
23428
23501
  }
23429
23502
  return {
@@ -28778,82 +28851,6 @@ const WGS84 = 'EPSG:4326';
28778
28851
  const WEB_MERCATOR = 'EPSG:3857';
28779
28852
  proj4.defs(WGS84, '+proj=longlat +datum=WGS84 +no_defs');
28780
28853
  proj4.defs(WEB_MERCATOR, '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
28781
- // 验证GPS坐标是否有效
28782
- const isValidGpsCoordinate = (coordinate) => {
28783
- if (!coordinate || coordinate.length < 2)
28784
- return false;
28785
- const [lng, lat] = coordinate;
28786
- // 检查是否为有效的GPS坐标范围,且不是原点(0,0)
28787
- return (lng >= -180 &&
28788
- lng <= 180 &&
28789
- lat >= -90 &&
28790
- lat <= 90 &&
28791
- !(Math.abs(lng) < 0.001 && Math.abs(lat) < 0.001) // 排除接近(0,0)的坐标
28792
- );
28793
- };
28794
- // 旋转坐标点
28795
- const rotateCoordinate = (point, center, angleRadians) => {
28796
- const [x, y] = point;
28797
- const [cx, cy] = center;
28798
- // 将点移动到原点
28799
- const dx = x - cx;
28800
- const dy = y - cy;
28801
- // 应用旋转矩阵
28802
- const cos = Math.cos(angleRadians);
28803
- const sin = Math.sin(angleRadians);
28804
- const rotatedX = dx * cos - dy * sin;
28805
- const rotatedY = dx * sin + dy * cos;
28806
- // 移回原位置
28807
- return [rotatedX + cx, rotatedY + cy];
28808
- };
28809
- // 获取有效的GPS边界
28810
- const getValidGpsBounds = (mapData, rotation = 0) => {
28811
- let bounds;
28812
- // 首先尝试使用地图数据中的GPS坐标
28813
- if (isValidGpsCoordinate(mapData.sw_gps) && isValidGpsCoordinate(mapData.ne_gps)) {
28814
- bounds = {
28815
- sw: mapData.sw_gps,
28816
- ne: mapData.ne_gps,
28817
- };
28818
- }
28819
- else {
28820
- // 如果GPS坐标无效,尝试从地图几何数据估算
28821
- const { sw, ne } = estimateGpsFromMapBounds(mapData);
28822
- if (sw && ne) {
28823
- console.warn('GPS坐标无效,使用地图几何数据估算边界:', sw, ne);
28824
- bounds = {
28825
- sw: [sw[0], sw[1]],
28826
- ne: [ne[0], ne[1]],
28827
- };
28828
- }
28829
- else {
28830
- // 最后的fallback:使用默认坐标
28831
- console.warn('无法获取有效的GPS边界,使用默认坐标');
28832
- bounds = DEFAULT_COORDINATES;
28833
- }
28834
- }
28835
- // 如果有旋转角度,计算旋转后的边界
28836
- if (rotation !== 0) {
28837
- const angleRadians = (rotation * Math.PI) / 180; // 转换为弧度
28838
- // 计算边界中心点
28839
- const centerLng = (bounds.sw[0] + bounds.ne[0]) / 2;
28840
- const centerLat = (bounds.sw[1] + bounds.ne[1]) / 2;
28841
- const center = [centerLng, centerLat];
28842
- // 旋转四个角点
28843
- const sw = rotateCoordinate(bounds.sw, center, angleRadians);
28844
- const ne = rotateCoordinate(bounds.ne, center, angleRadians);
28845
- const se = rotateCoordinate([bounds.ne[0], bounds.sw[1]], center, angleRadians);
28846
- const nw = rotateCoordinate([bounds.sw[0], bounds.ne[1]], center, angleRadians);
28847
- // 计算旋转后的边界框(包含所有旋转后的点)
28848
- const lngs = [sw[0], ne[0], se[0], nw[0]];
28849
- const lats = [sw[1], ne[1], se[1], nw[1]];
28850
- bounds = {
28851
- sw: [Math.min(...lngs), Math.min(...lats)],
28852
- ne: [Math.max(...lngs), Math.max(...lats)],
28853
- };
28854
- }
28855
- return bounds;
28856
- };
28857
28854
  // 默认配置
28858
28855
  const defaultMapConfig$1 = DEFAULT_STYLES;
28859
28856
  // 地图渲染器组件
@@ -28893,6 +28890,14 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28893
28890
  const mapBounds = React.useMemo(() => {
28894
28891
  return calculateMapBounds(mapJson);
28895
28892
  }, [mapJson]);
28893
+ const originNorthRotate = React.useMemo(() => {
28894
+ if (mapJson.map_north_offset)
28895
+ return (mapJson.map_north_offset * 180) / Math.PI;
28896
+ return 0;
28897
+ }, [mapJson]);
28898
+ const actureRotate = React.useMemo(() => {
28899
+ return originNorthRotate + drag?.rotation;
28900
+ }, [originNorthRotate, drag?.rotation]);
28896
28901
  const svgViewBox = React.useMemo(() => {
28897
28902
  const padding = 0; // 添加一些边距以避免内容贴边
28898
28903
  const boundWidth = mapBounds.maxX - mapBounds.minX + padding * 2;
@@ -28973,8 +28978,12 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28973
28978
  newSvgElementDatas[key] =
28974
28979
  newSvgElementDatas[key].filter((item) => {
28975
28980
  return (item.status === 1 &&
28976
- (!item.start_timestamp || !item.end_timestamp || (item.start_timestamp && item.start_timestamp <= Date.now() / 1000 &&
28977
- item.end_timestamp && item.end_timestamp >= Date.now() / 1000)));
28981
+ (!item.start_timestamp ||
28982
+ !item.end_timestamp ||
28983
+ (item.start_timestamp &&
28984
+ item.start_timestamp <= Date.now() / 1000 &&
28985
+ item.end_timestamp &&
28986
+ item.end_timestamp >= Date.now() / 1000)));
28978
28987
  }) || [];
28979
28988
  }
28980
28989
  else if (key === exports.DataType.DOODLE) {
@@ -29017,7 +29026,11 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29017
29026
  globalHeight,
29018
29027
  mapConfig: mergedMapConfig,
29019
29028
  mapJson,
29020
- drag: defaultTransform,
29029
+ drag: {
29030
+ x: defaultTransform?.x ?? 0,
29031
+ y: defaultTransform?.y ?? 0,
29032
+ rotate: (defaultTransform?.rotation ?? 0) + originNorthRotate,
29033
+ },
29021
29034
  mapRef,
29022
29035
  overlayScale,
29023
29036
  doodleList,
@@ -29036,6 +29049,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29036
29049
  mergedMapConfig,
29037
29050
  mapJson,
29038
29051
  defaultTransform,
29052
+ originNorthRotate,
29039
29053
  mapRef,
29040
29054
  overlayScale,
29041
29055
  doodleList,
@@ -29120,8 +29134,9 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29120
29134
  handleError('无法计算地图边界');
29121
29135
  return;
29122
29136
  }
29137
+ const rotate = defaultTransform?.rotation + originNorthRotate;
29123
29138
  // 将自定义边界转换为Google Maps LatLngBounds(使用有效的GPS坐标)
29124
- const validBounds = getValidGpsBounds(mapJson, defaultTransform?.rotation);
29139
+ const validBounds = getValidGpsBounds(mapJson, rotate);
29125
29140
  // 地图数据中的坐标格式是 [longitude, latitude]
29126
29141
  const [swLng0, swLat0] = validBounds.sw;
29127
29142
  const [neLng0, neLat0] = validBounds.ne;
@@ -29137,7 +29152,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29137
29152
  new window.google.maps.LatLng(neLat, neLng) // 东北角
29138
29153
  );
29139
29154
  mapRef.fitBounds(googleBounds, padding);
29140
- }, [mapJson, mapRef, defaultTransform]);
29155
+ }, [mapJson, mapRef, defaultTransform, originNorthRotate]);
29141
29156
  const handleDragMove = React.useCallback((e) => {
29142
29157
  if (!overlay || !bounds)
29143
29158
  return;
@@ -29166,7 +29181,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29166
29181
  setDrag((prev) => ({
29167
29182
  x: prev.x + dx,
29168
29183
  y: prev.y + dy,
29169
- rotation: e.rotate,
29184
+ rotation: prev.rotation + e.rotate,
29170
29185
  }));
29171
29186
  }, [overlay, bounds]);
29172
29187
  React.useEffect(() => {
@@ -29193,17 +29208,21 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29193
29208
  // mowPartitionDataRef.current = {};
29194
29209
  // // console.error('0.50.5--mowPartitionDataRef.current---->', mowPartitionDataRef.current);
29195
29210
  // }
29196
- isTaskDelayRef.current = vehicleStatusData?.taskDelay !== undefined ? vehicleStatusData?.taskDelay : isTaskDelayRef.current;
29211
+ isTaskDelayRef.current =
29212
+ vehicleStatusData?.taskDelay !== undefined
29213
+ ? vehicleStatusData?.taskDelay
29214
+ : isTaskDelayRef.current;
29197
29215
  // console.error('isTaskDelayRef.current 111---->', isTaskDelayRef.current);
29198
29216
  }
29199
29217
  const positionData = realTimeData?.find((item) => item?.type === RealTimeDataType.LOCATION);
29200
29218
  // 如果当前是taskDelay的状态,或者状态为mowing或者standby,则指定的地块需要高亮,或者全局高亮
29201
- if ((isTaskDelayRef.current || positionData?.vehicleState === RobotStatus.MOWING || positionData?.vehicleState === RobotStatus.STANDBY) &&
29219
+ if ((isTaskDelayRef.current ||
29220
+ positionData?.vehicleState === RobotStatus.MOWING ||
29221
+ positionData?.vehicleState === RobotStatus.STANDBY) &&
29202
29222
  mowPartitionDataRef.current &&
29203
29223
  !mowPartitionDataRef.current?.partitionIds) {
29204
29224
  // 设置全局高亮
29205
- if (mowPartitionDataRef.current &&
29206
- !mowPartitionDataRef.current?.partitionIds) {
29225
+ if (mowPartitionDataRef.current && !mowPartitionDataRef.current?.partitionIds) {
29207
29226
  const allPartitionIds = generateBoundaryData(mapJson)
29208
29227
  ?.filter((item) => !item?.isIsolated)
29209
29228
  .map((item) => item?.id);
@@ -29215,7 +29234,10 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29215
29234
  };
29216
29235
  }
29217
29236
  }
29218
- else if (!isTaskDelayRef.current && positionData?.vehicleState === RobotStatus.WORKING && (currentVehicleStateRef.current === RobotStatus.MOWING || currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29237
+ else if (!isTaskDelayRef.current &&
29238
+ positionData?.vehicleState === RobotStatus.WORKING &&
29239
+ (currentVehicleStateRef.current === RobotStatus.MOWING ||
29240
+ currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29219
29241
  // 非deskDelay的状态下
29220
29242
  // 1. 如果当前是working状态,且上一次是mowing或者standby状态,则取消高亮
29221
29243
  // 兜底收不到割草地块的实时数据,使用状态来兜底
@@ -29224,12 +29246,16 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29224
29246
  mowPartitionDataRef.current = {};
29225
29247
  }
29226
29248
  // 更新当前车辆状态
29227
- currentVehicleStateRef.current = positionData?.vehicleState !== undefined ? positionData?.vehicleState : currentVehicleStateRef.current;
29249
+ currentVehicleStateRef.current =
29250
+ positionData?.vehicleState !== undefined
29251
+ ? positionData?.vehicleState
29252
+ : currentVehicleStateRef.current;
29228
29253
  if (!mapJson || !svgMapRef.current)
29229
29254
  return;
29230
29255
  // 根据后端推送的实时数据,进行不同处理
29231
29256
  if (mowPartitionDataRef.current) {
29232
- const isMowing = mowPartitionDataRef.current?.partitionIds && mowPartitionDataRef.current.partitionIds.length > 0;
29257
+ const isMowing = mowPartitionDataRef.current?.partitionIds &&
29258
+ mowPartitionDataRef.current.partitionIds.length > 0;
29233
29259
  if (!isMowing) {
29234
29260
  setMowingPartitions(undefined);
29235
29261
  }
@@ -29296,7 +29322,6 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29296
29322
  // 基于固定的参考zoom级别计算overlayScale
29297
29323
  const zoomDiff = currentZoom - REFERENCE_ZOOM;
29298
29324
  const scale = Math.pow(2, -zoomDiff); // 负数实现反向缩放
29299
- console.log('scale------->', scale);
29300
29325
  // setOverlayScale(scale < 1 ? 1 : platform === PlatformType.H5 ? 1.5 * scale : scale);
29301
29326
  if (scale < 1) {
29302
29327
  setOverlayScale(1);
@@ -29414,7 +29439,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29414
29439
  // svgEditMapRef?.current?.adjustSvgSize?.(layout);
29415
29440
  setOverlayLayout(layout);
29416
29441
  }
29417
- }, map: mapRef, mapPaneName: 'overlayMouseTarget', bounds: bounds, rotate: drag?.rotation, children: [jsxRuntime.jsx(MapDrag, { map: mapRef, dragCallbacks: dragCallbacks, onBoundaryLabelsCollapse: () => { }, onTransformChange: handleDragMove, isDragMap: dragMap, canRotateMap: canRotateMap }), jsxRuntime.jsx(MowPartitionContextProvider, { value: mowPartitionValue, children: jsxRuntime.jsx(SvgMapComponent, { editMap: editMap, ref: svgMapRef, pathData: pathJson, mapConfig: mergedMapConfig, mowPartitionData: mowPartitionData }) }), jsxRuntime.jsx(MowerPosition, { editMap: editMap, mowerPositionData: mowerPositionData, viewBox: svgViewBox || null, modelType: modelType, hasEdger: edger, mapData: mapJson, mapConfig: mergedMapConfig, realTimeData: realTimeData, onMowingPositionChange: onMowingPositionChange }), jsxRuntime.jsx(CharginPile, { viewBox: svgViewBox || null, rotation: drag?.rotation }), jsxRuntime.jsx(BoundaryLabels, { editMap: editMap, mapData: mapJson, onlyRead: onlyRead, pathData: pathJson, unitType: unitType, viewBox: svgViewBox || null, rotation: drag?.rotation, mowPartitionData: mowPartitionData, realTimeData: realTimeData }), jsxRuntime.jsx(Antennas, { editMap: editMap, antennaConfig: antennaConfig || [], layout: overlayLayout || undefined, viewBox: svgViewBox || null, rotation: drag?.rotation, onlyRead: onlyRead }), jsxRuntime.jsx(SvgEditMap, { editMap: editMap, ref: svgEditMapRef, mapConfig: mergedMapConfig, onEditInfoMapChange: onEditInfoMapChange })] })] }) }) }));
29442
+ }, map: mapRef, mapPaneName: 'overlayMouseTarget', bounds: bounds, rotate: actureRotate, children: [jsxRuntime.jsx(MapDrag, { map: mapRef, dragCallbacks: dragCallbacks, onBoundaryLabelsCollapse: () => { }, onTransformChange: handleDragMove, isDragMap: dragMap, canRotateMap: canRotateMap }), jsxRuntime.jsx(MowPartitionContextProvider, { value: mowPartitionValue, children: jsxRuntime.jsx(SvgMapComponent, { editMap: editMap, ref: svgMapRef, pathData: pathJson, mapConfig: mergedMapConfig, mowPartitionData: mowPartitionData }) }), jsxRuntime.jsx(MowerPosition, { editMap: editMap, mowerPositionData: mowerPositionData, viewBox: svgViewBox || null, modelType: modelType, hasEdger: edger, mapData: mapJson, mapConfig: mergedMapConfig, realTimeData: realTimeData, onMowingPositionChange: onMowingPositionChange }), jsxRuntime.jsx(CharginPile, { viewBox: svgViewBox || null, rotation: actureRotate }), jsxRuntime.jsx(BoundaryLabels, { editMap: editMap, mapData: mapJson, onlyRead: onlyRead, pathData: pathJson, unitType: unitType, viewBox: svgViewBox || null, rotation: actureRotate, mowPartitionData: mowPartitionData, realTimeData: realTimeData }), jsxRuntime.jsx(Antennas, { editMap: editMap, antennaConfig: antennaConfig || [], layout: overlayLayout || undefined, viewBox: svgViewBox || null, rotation: actureRotate, onlyRead: onlyRead }), jsxRuntime.jsx(SvgEditMap, { editMap: editMap, ref: svgEditMapRef, mapConfig: mergedMapConfig, onEditInfoMapChange: onEditInfoMapChange })] })] }) }) }));
29418
29443
  });
29419
29444
  MowerMapRenderer.displayName = 'MowerMapRenderer';
29420
29445
 
@@ -1 +1 @@
1
- {"version":3,"file":"MowerMapRenderer.d.ts","sourceRoot":"","sources":["../../src/render/MowerMapRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAuBf,OAAO,EAGL,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AA0B3B,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,MAAM,EAAE,GAAG,CAAC;KACb;CACF;AA8FD,eAAO,MAAM,gBAAgB,mGAgvB5B,CAAC;AAIF,eAAe,gBAAgB,CAAC;AAChC,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"MowerMapRenderer.d.ts","sourceRoot":"","sources":["../../src/render/MowerMapRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAyBf,OAAO,EAGL,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AA0B3B,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,MAAM,EAAE,GAAG,CAAC;KACb;CACF;AAMD,eAAO,MAAM,gBAAgB,mGAoxB5B,CAAC;AAIF,eAAe,gBAAgB,CAAC;AAChC,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,CAAC"}
@@ -16,12 +16,6 @@ export declare const useDrag: ({ dragCallbacks, onBoundaryLabelsCollapse, onTran
16
16
  handleDragMove: (e: MouseEvent | TouchEvent) => void;
17
17
  handleDragEnd: (e: MouseEvent | TouchEvent) => void;
18
18
  addGlobalListeners: () => () => void;
19
- setTransform: (transform: {
20
- x?: number;
21
- y?: number;
22
- rotation?: number;
23
- }) => void;
24
- resetToDefaultTransform: () => void;
25
19
  getCurrentDragState: () => DragState;
26
20
  };
27
21
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useDrag.d.ts","sourceRoot":"","sources":["../../../src/render/drag/useDrag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEhE,UAAU,YAAY;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;IACtC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACnF;AAED,eAAO,MAAM,OAAO,GAAI,iEAIrB,YAAY;;;yBA4BN,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,QAChC,MAAM,GAAG,QAAQ,aACZ,cAAc;wBA4BvB,UAAU,GAAG,UAAU;uBAsBvB,UAAU,GAAG,UAAU;;8BAiGf;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;;+BAhKf,SAAS;CA8NtD,CAAC"}
1
+ {"version":3,"file":"useDrag.d.ts","sourceRoot":"","sources":["../../../src/render/drag/useDrag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEhE,UAAU,YAAY;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;IACtC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACnF;AAED,eAAO,MAAM,OAAO,GAAI,iEAIrB,YAAY;;;yBA4BN,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,QAChC,MAAM,GAAG,QAAQ,aACZ,cAAc;wBA4BvB,UAAU,GAAG,UAAU;uBAsBvB,UAAU,GAAG,UAAU;;+BA/De,SAAS;CA+LtD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCheckElement.d.ts","sourceRoot":"","sources":["../../../../src/render/svgEditMap/hooks/useCheckElement.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAGnF,eAAO,MAAM,eAAe;uBAIU;QAClC,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,oBAAoB,CAAC;KAC7B;8CA+He;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,gBACtB,MAAM,EAAE,EAAE,KACvB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,2BAA2B,CAAA;KAAE;CAyH7D,CAAC"}
1
+ {"version":3,"file":"useCheckElement.d.ts","sourceRoot":"","sources":["../../../../src/render/svgEditMap/hooks/useCheckElement.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAGnF,eAAO,MAAM,eAAe;uBAIU;QAClC,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,oBAAoB,CAAC;KAC7B;8CA+He;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,gBACtB,MAAM,EAAE,EAAE,KACvB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,2BAA2B,CAAA;KAAE;CA2H7D,CAAC"}
@@ -35,6 +35,7 @@ export interface MapData {
35
35
  antena_deleted: number;
36
36
  map_circle_center: number[];
37
37
  map_circle_radius: number;
38
+ map_north_offset?: number;
38
39
  map_width: number;
39
40
  map_height: number;
40
41
  center_gps: number[];
@@ -1 +1 @@
1
- {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/types/map.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC,QAAQ,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAGD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAC/C,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb"}
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/types/map.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC,QAAQ,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAGD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAC/C,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb"}
@@ -46,4 +46,8 @@ export declare function calculateMapGpsCenter(mapData: MapData): {
46
46
  lat: number;
47
47
  lng: number;
48
48
  };
49
+ export declare const getValidGpsBounds: (mapData: any, rotation?: number) => {
50
+ sw: number[];
51
+ ne: number[];
52
+ };
49
53
  //# sourceMappingURL=mapBounds.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mapBounds.d.ts","sourceRoot":"","sources":["../../src/utils/mapBounds.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAmB,OAAO,EAAE,MAAM,UAAU,CAAC;AAEpD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,oBAAoB,UAAO,GAAG,SAAS,CA2D3F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAgDnE;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAShF;AACD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAOzE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK,CAKxD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAKlF;AAiBD;;;;GAIG;AAEH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG;IAC1D,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrB,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtB,GAAG,IAAI,CA4EP;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAoDpF"}
1
+ {"version":3,"file":"mapBounds.d.ts","sourceRoot":"","sources":["../../src/utils/mapBounds.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAmB,OAAO,EAAE,MAAM,UAAU,CAAC;AAEpD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,oBAAoB,UAAO,GAAG,SAAS,CA2D3F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAgDnE;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAShF;AACD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAOzE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK,CAKxD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAKlF;AAiBD;;;;GAIG;AAEH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG;IAC1D,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrB,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtB,GAAG,IAAI,CA4EP;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAoDpF;AAsBD,eAAO,MAAM,iBAAiB,GAC5B,SAAS,GAAG,EACZ,WAAU,MAAU,KACnB;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,CAAA;CA0F9B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleet-frontend/mower-maps",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "description": "a mower maps in google maps",
6
6
  "main": "dist/index.js",