@fleet-frontend/mower-maps 0.2.3 → 0.2.5-beta.1

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
  // 使用自定义密度或设备像素比
@@ -15917,16 +16013,14 @@ const handleMultipleRealTimeData = ({ realTimeData, isMowing, pathData,
15917
16013
  // partitionBoundary,
15918
16014
  currentMowingPartition, }) => {
15919
16015
  // 先将数据进行倒排,这样好插入数据
15920
- if (realTimeData.length > 0) {
15921
- realTimeData.reverse();
15922
- }
16016
+ const newRealTimeData = [...(realTimeData || [])].reverse();
15923
16017
  let newPathData = pathData || {};
15924
16018
  // 这两个数据因为是从另一个推送过来的,可能有一定的滞后性
15925
16019
  // 目前的方式是,如果是location数据,判断是否割草,取决于前一次的process数据的割草状态+本次的location的verchState
15926
16020
  // 关于location的分区,需要通过地图数据,结合射线法,判断当前的点在哪个分区里
15927
16021
  let mowingStatus = isMowing || false;
15928
16022
  let newCurrentMowingPartitionId = currentMowingPartition;
15929
- realTimeData.forEach((item) => {
16023
+ newRealTimeData.forEach((item) => {
15930
16024
  // 这里需要区分,是割草进度还是割草轨迹
15931
16025
  if (item.type === REAL_TIME_DATA_TYPE.LOCATION) {
15932
16026
  // 割草轨迹
@@ -19683,7 +19777,7 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19683
19777
  onTransformChange?.({
19684
19778
  x: deltaX,
19685
19779
  y: deltaY,
19686
- rotate: currentRotationRef.current,
19780
+ rotate: 0,
19687
19781
  });
19688
19782
  startPosRef.current = { x: clientX, y: clientY };
19689
19783
  }, [onTransformChange]);
@@ -19721,35 +19815,11 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19721
19815
  onTransformChange?.({
19722
19816
  x: tempPixelOffsetRef.current.x,
19723
19817
  y: tempPixelOffsetRef.current.y,
19724
- rotate: currentRotationRef.current,
19818
+ rotate: angleDifferenceDegrees,
19725
19819
  });
19726
19820
  // 更新鼠标起始位置为当前位置,为下次计算做准备
19727
19821
  startPosRef.current = { x: mouseCurrentX, y: mouseCurrentY };
19728
19822
  }, [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
19823
  // 添加全局事件监听器
19754
19824
  const addGlobalListeners = useCallback(() => {
19755
19825
  const handleMouseMove = (e) => handleDragMove(e);
@@ -19778,8 +19848,6 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19778
19848
  handleDragMove,
19779
19849
  handleDragEnd,
19780
19850
  addGlobalListeners,
19781
- setTransform,
19782
- resetToDefaultTransform,
19783
19851
  getCurrentDragState,
19784
19852
  };
19785
19853
  };
@@ -28761,82 +28829,6 @@ const WGS84 = 'EPSG:4326';
28761
28829
  const WEB_MERCATOR = 'EPSG:3857';
28762
28830
  proj4.defs(WGS84, '+proj=longlat +datum=WGS84 +no_defs');
28763
28831
  proj4.defs(WEB_MERCATOR, '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
28764
- // 验证GPS坐标是否有效
28765
- const isValidGpsCoordinate = (coordinate) => {
28766
- if (!coordinate || coordinate.length < 2)
28767
- return false;
28768
- const [lng, lat] = coordinate;
28769
- // 检查是否为有效的GPS坐标范围,且不是原点(0,0)
28770
- return (lng >= -180 &&
28771
- lng <= 180 &&
28772
- lat >= -90 &&
28773
- lat <= 90 &&
28774
- !(Math.abs(lng) < 0.001 && Math.abs(lat) < 0.001) // 排除接近(0,0)的坐标
28775
- );
28776
- };
28777
- // 旋转坐标点
28778
- const rotateCoordinate = (point, center, angleRadians) => {
28779
- const [x, y] = point;
28780
- const [cx, cy] = center;
28781
- // 将点移动到原点
28782
- const dx = x - cx;
28783
- const dy = y - cy;
28784
- // 应用旋转矩阵
28785
- const cos = Math.cos(angleRadians);
28786
- const sin = Math.sin(angleRadians);
28787
- const rotatedX = dx * cos - dy * sin;
28788
- const rotatedY = dx * sin + dy * cos;
28789
- // 移回原位置
28790
- return [rotatedX + cx, rotatedY + cy];
28791
- };
28792
- // 获取有效的GPS边界
28793
- const getValidGpsBounds = (mapData, rotation = 0) => {
28794
- let bounds;
28795
- // 首先尝试使用地图数据中的GPS坐标
28796
- if (isValidGpsCoordinate(mapData.sw_gps) && isValidGpsCoordinate(mapData.ne_gps)) {
28797
- bounds = {
28798
- sw: mapData.sw_gps,
28799
- ne: mapData.ne_gps,
28800
- };
28801
- }
28802
- else {
28803
- // 如果GPS坐标无效,尝试从地图几何数据估算
28804
- const { sw, ne } = estimateGpsFromMapBounds(mapData);
28805
- if (sw && ne) {
28806
- console.warn('GPS坐标无效,使用地图几何数据估算边界:', sw, ne);
28807
- bounds = {
28808
- sw: [sw[0], sw[1]],
28809
- ne: [ne[0], ne[1]],
28810
- };
28811
- }
28812
- else {
28813
- // 最后的fallback:使用默认坐标
28814
- console.warn('无法获取有效的GPS边界,使用默认坐标');
28815
- bounds = DEFAULT_COORDINATES;
28816
- }
28817
- }
28818
- // 如果有旋转角度,计算旋转后的边界
28819
- if (rotation !== 0) {
28820
- const angleRadians = (rotation * Math.PI) / 180; // 转换为弧度
28821
- // 计算边界中心点
28822
- const centerLng = (bounds.sw[0] + bounds.ne[0]) / 2;
28823
- const centerLat = (bounds.sw[1] + bounds.ne[1]) / 2;
28824
- const center = [centerLng, centerLat];
28825
- // 旋转四个角点
28826
- const sw = rotateCoordinate(bounds.sw, center, angleRadians);
28827
- const ne = rotateCoordinate(bounds.ne, center, angleRadians);
28828
- const se = rotateCoordinate([bounds.ne[0], bounds.sw[1]], center, angleRadians);
28829
- const nw = rotateCoordinate([bounds.sw[0], bounds.ne[1]], center, angleRadians);
28830
- // 计算旋转后的边界框(包含所有旋转后的点)
28831
- const lngs = [sw[0], ne[0], se[0], nw[0]];
28832
- const lats = [sw[1], ne[1], se[1], nw[1]];
28833
- bounds = {
28834
- sw: [Math.min(...lngs), Math.min(...lats)],
28835
- ne: [Math.max(...lngs), Math.max(...lats)],
28836
- };
28837
- }
28838
- return bounds;
28839
- };
28840
28832
  // 默认配置
28841
28833
  const defaultMapConfig$1 = DEFAULT_STYLES;
28842
28834
  // 地图渲染器组件
@@ -28876,6 +28868,14 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28876
28868
  const mapBounds = useMemo(() => {
28877
28869
  return calculateMapBounds(mapJson);
28878
28870
  }, [mapJson]);
28871
+ const originNorthRotate = useMemo(() => {
28872
+ if (mapJson.map_north_offset)
28873
+ return (mapJson.map_north_offset * 180) / Math.PI;
28874
+ return 0;
28875
+ }, [mapJson]);
28876
+ const actureRotate = useMemo(() => {
28877
+ return originNorthRotate + drag?.rotation;
28878
+ }, [originNorthRotate, drag?.rotation]);
28879
28879
  const svgViewBox = useMemo(() => {
28880
28880
  const padding = 0; // 添加一些边距以避免内容贴边
28881
28881
  const boundWidth = mapBounds.maxX - mapBounds.minX + padding * 2;
@@ -28956,8 +28956,12 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28956
28956
  newSvgElementDatas[key] =
28957
28957
  newSvgElementDatas[key].filter((item) => {
28958
28958
  return (item.status === 1 &&
28959
- (!item.start_timestamp || !item.end_timestamp || (item.start_timestamp && item.start_timestamp <= Date.now() / 1000 &&
28960
- item.end_timestamp && item.end_timestamp >= Date.now() / 1000)));
28959
+ (!item.start_timestamp ||
28960
+ !item.end_timestamp ||
28961
+ (item.start_timestamp &&
28962
+ item.start_timestamp <= Date.now() / 1000 &&
28963
+ item.end_timestamp &&
28964
+ item.end_timestamp >= Date.now() / 1000)));
28961
28965
  }) || [];
28962
28966
  }
28963
28967
  else if (key === DataType.DOODLE) {
@@ -29000,7 +29004,11 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29000
29004
  globalHeight,
29001
29005
  mapConfig: mergedMapConfig,
29002
29006
  mapJson,
29003
- drag: defaultTransform,
29007
+ drag: {
29008
+ x: defaultTransform?.x ?? 0,
29009
+ y: defaultTransform?.y ?? 0,
29010
+ rotate: (defaultTransform?.rotation ?? 0) + originNorthRotate,
29011
+ },
29004
29012
  mapRef,
29005
29013
  overlayScale,
29006
29014
  doodleList,
@@ -29019,6 +29027,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29019
29027
  mergedMapConfig,
29020
29028
  mapJson,
29021
29029
  defaultTransform,
29030
+ originNorthRotate,
29022
29031
  mapRef,
29023
29032
  overlayScale,
29024
29033
  doodleList,
@@ -29103,8 +29112,9 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29103
29112
  handleError('无法计算地图边界');
29104
29113
  return;
29105
29114
  }
29115
+ const rotate = defaultTransform?.rotation + originNorthRotate;
29106
29116
  // 将自定义边界转换为Google Maps LatLngBounds(使用有效的GPS坐标)
29107
- const validBounds = getValidGpsBounds(mapJson, defaultTransform?.rotation);
29117
+ const validBounds = getValidGpsBounds(mapJson, rotate);
29108
29118
  // 地图数据中的坐标格式是 [longitude, latitude]
29109
29119
  const [swLng0, swLat0] = validBounds.sw;
29110
29120
  const [neLng0, neLat0] = validBounds.ne;
@@ -29120,7 +29130,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29120
29130
  new window.google.maps.LatLng(neLat, neLng) // 东北角
29121
29131
  );
29122
29132
  mapRef.fitBounds(googleBounds, padding);
29123
- }, [mapJson, mapRef, defaultTransform]);
29133
+ }, [mapJson, mapRef, defaultTransform, originNorthRotate]);
29124
29134
  const handleDragMove = useCallback((e) => {
29125
29135
  if (!overlay || !bounds)
29126
29136
  return;
@@ -29149,7 +29159,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29149
29159
  setDrag((prev) => ({
29150
29160
  x: prev.x + dx,
29151
29161
  y: prev.y + dy,
29152
- rotation: e.rotate,
29162
+ rotation: prev.rotation + e.rotate,
29153
29163
  }));
29154
29164
  }, [overlay, bounds]);
29155
29165
  useEffect(() => {
@@ -29176,17 +29186,21 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29176
29186
  // mowPartitionDataRef.current = {};
29177
29187
  // // console.error('0.50.5--mowPartitionDataRef.current---->', mowPartitionDataRef.current);
29178
29188
  // }
29179
- isTaskDelayRef.current = vehicleStatusData?.taskDelay !== undefined ? vehicleStatusData?.taskDelay : isTaskDelayRef.current;
29189
+ isTaskDelayRef.current =
29190
+ vehicleStatusData?.taskDelay !== undefined
29191
+ ? vehicleStatusData?.taskDelay
29192
+ : isTaskDelayRef.current;
29180
29193
  // console.error('isTaskDelayRef.current 111---->', isTaskDelayRef.current);
29181
29194
  }
29182
29195
  const positionData = realTimeData?.find((item) => item?.type === RealTimeDataType.LOCATION);
29183
29196
  // 如果当前是taskDelay的状态,或者状态为mowing或者standby,则指定的地块需要高亮,或者全局高亮
29184
- if ((isTaskDelayRef.current || positionData?.vehicleState === RobotStatus.MOWING || positionData?.vehicleState === RobotStatus.STANDBY) &&
29197
+ if ((isTaskDelayRef.current ||
29198
+ positionData?.vehicleState === RobotStatus.MOWING ||
29199
+ positionData?.vehicleState === RobotStatus.STANDBY) &&
29185
29200
  mowPartitionDataRef.current &&
29186
29201
  !mowPartitionDataRef.current?.partitionIds) {
29187
29202
  // 设置全局高亮
29188
- if (mowPartitionDataRef.current &&
29189
- !mowPartitionDataRef.current?.partitionIds) {
29203
+ if (mowPartitionDataRef.current && !mowPartitionDataRef.current?.partitionIds) {
29190
29204
  const allPartitionIds = generateBoundaryData(mapJson)
29191
29205
  ?.filter((item) => !item?.isIsolated)
29192
29206
  .map((item) => item?.id);
@@ -29198,7 +29212,10 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29198
29212
  };
29199
29213
  }
29200
29214
  }
29201
- else if (!isTaskDelayRef.current && positionData?.vehicleState === RobotStatus.WORKING && (currentVehicleStateRef.current === RobotStatus.MOWING || currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29215
+ else if (!isTaskDelayRef.current &&
29216
+ positionData?.vehicleState === RobotStatus.WORKING &&
29217
+ (currentVehicleStateRef.current === RobotStatus.MOWING ||
29218
+ currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29202
29219
  // 非deskDelay的状态下
29203
29220
  // 1. 如果当前是working状态,且上一次是mowing或者standby状态,则取消高亮
29204
29221
  // 兜底收不到割草地块的实时数据,使用状态来兜底
@@ -29207,12 +29224,16 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29207
29224
  mowPartitionDataRef.current = {};
29208
29225
  }
29209
29226
  // 更新当前车辆状态
29210
- currentVehicleStateRef.current = positionData?.vehicleState !== undefined ? positionData?.vehicleState : currentVehicleStateRef.current;
29227
+ currentVehicleStateRef.current =
29228
+ positionData?.vehicleState !== undefined
29229
+ ? positionData?.vehicleState
29230
+ : currentVehicleStateRef.current;
29211
29231
  if (!mapJson || !svgMapRef.current)
29212
29232
  return;
29213
29233
  // 根据后端推送的实时数据,进行不同处理
29214
29234
  if (mowPartitionDataRef.current) {
29215
- const isMowing = mowPartitionDataRef.current?.partitionIds && mowPartitionDataRef.current.partitionIds.length > 0;
29235
+ const isMowing = mowPartitionDataRef.current?.partitionIds &&
29236
+ mowPartitionDataRef.current.partitionIds.length > 0;
29216
29237
  if (!isMowing) {
29217
29238
  setMowingPartitions(undefined);
29218
29239
  }
@@ -29279,7 +29300,6 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29279
29300
  // 基于固定的参考zoom级别计算overlayScale
29280
29301
  const zoomDiff = currentZoom - REFERENCE_ZOOM;
29281
29302
  const scale = Math.pow(2, -zoomDiff); // 负数实现反向缩放
29282
- console.log('scale------->', scale);
29283
29303
  // setOverlayScale(scale < 1 ? 1 : platform === PlatformType.H5 ? 1.5 * scale : scale);
29284
29304
  if (scale < 1) {
29285
29305
  setOverlayScale(1);
@@ -29397,7 +29417,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29397
29417
  // svgEditMapRef?.current?.adjustSvgSize?.(layout);
29398
29418
  setOverlayLayout(layout);
29399
29419
  }
29400
- }, 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 })] })] }) }) }));
29420
+ }, 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 })] })] }) }) }));
29401
29421
  });
29402
29422
  MowerMapRenderer.displayName = 'MowerMapRenderer';
29403
29423
 
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
  // 使用自定义密度或设备像素比
@@ -15937,16 +16033,14 @@ const handleMultipleRealTimeData = ({ realTimeData, isMowing, pathData,
15937
16033
  // partitionBoundary,
15938
16034
  currentMowingPartition, }) => {
15939
16035
  // 先将数据进行倒排,这样好插入数据
15940
- if (realTimeData.length > 0) {
15941
- realTimeData.reverse();
15942
- }
16036
+ const newRealTimeData = [...(realTimeData || [])].reverse();
15943
16037
  let newPathData = pathData || {};
15944
16038
  // 这两个数据因为是从另一个推送过来的,可能有一定的滞后性
15945
16039
  // 目前的方式是,如果是location数据,判断是否割草,取决于前一次的process数据的割草状态+本次的location的verchState
15946
16040
  // 关于location的分区,需要通过地图数据,结合射线法,判断当前的点在哪个分区里
15947
16041
  let mowingStatus = isMowing || false;
15948
16042
  let newCurrentMowingPartitionId = currentMowingPartition;
15949
- realTimeData.forEach((item) => {
16043
+ newRealTimeData.forEach((item) => {
15950
16044
  // 这里需要区分,是割草进度还是割草轨迹
15951
16045
  if (item.type === REAL_TIME_DATA_TYPE.LOCATION) {
15952
16046
  // 割草轨迹
@@ -19703,7 +19797,7 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19703
19797
  onTransformChange?.({
19704
19798
  x: deltaX,
19705
19799
  y: deltaY,
19706
- rotate: currentRotationRef.current,
19800
+ rotate: 0,
19707
19801
  });
19708
19802
  startPosRef.current = { x: clientX, y: clientY };
19709
19803
  }, [onTransformChange]);
@@ -19741,35 +19835,11 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19741
19835
  onTransformChange?.({
19742
19836
  x: tempPixelOffsetRef.current.x,
19743
19837
  y: tempPixelOffsetRef.current.y,
19744
- rotate: currentRotationRef.current,
19838
+ rotate: angleDifferenceDegrees,
19745
19839
  });
19746
19840
  // 更新鼠标起始位置为当前位置,为下次计算做准备
19747
19841
  startPosRef.current = { x: mouseCurrentX, y: mouseCurrentY };
19748
19842
  }, [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
19843
  // 添加全局事件监听器
19774
19844
  const addGlobalListeners = React.useCallback(() => {
19775
19845
  const handleMouseMove = (e) => handleDragMove(e);
@@ -19798,8 +19868,6 @@ const useDrag = ({ dragCallbacks, onBoundaryLabelsCollapse, onTransformChange, }
19798
19868
  handleDragMove,
19799
19869
  handleDragEnd,
19800
19870
  addGlobalListeners,
19801
- setTransform,
19802
- resetToDefaultTransform,
19803
19871
  getCurrentDragState,
19804
19872
  };
19805
19873
  };
@@ -28781,82 +28849,6 @@ const WGS84 = 'EPSG:4326';
28781
28849
  const WEB_MERCATOR = 'EPSG:3857';
28782
28850
  proj4.defs(WGS84, '+proj=longlat +datum=WGS84 +no_defs');
28783
28851
  proj4.defs(WEB_MERCATOR, '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
28784
- // 验证GPS坐标是否有效
28785
- const isValidGpsCoordinate = (coordinate) => {
28786
- if (!coordinate || coordinate.length < 2)
28787
- return false;
28788
- const [lng, lat] = coordinate;
28789
- // 检查是否为有效的GPS坐标范围,且不是原点(0,0)
28790
- return (lng >= -180 &&
28791
- lng <= 180 &&
28792
- lat >= -90 &&
28793
- lat <= 90 &&
28794
- !(Math.abs(lng) < 0.001 && Math.abs(lat) < 0.001) // 排除接近(0,0)的坐标
28795
- );
28796
- };
28797
- // 旋转坐标点
28798
- const rotateCoordinate = (point, center, angleRadians) => {
28799
- const [x, y] = point;
28800
- const [cx, cy] = center;
28801
- // 将点移动到原点
28802
- const dx = x - cx;
28803
- const dy = y - cy;
28804
- // 应用旋转矩阵
28805
- const cos = Math.cos(angleRadians);
28806
- const sin = Math.sin(angleRadians);
28807
- const rotatedX = dx * cos - dy * sin;
28808
- const rotatedY = dx * sin + dy * cos;
28809
- // 移回原位置
28810
- return [rotatedX + cx, rotatedY + cy];
28811
- };
28812
- // 获取有效的GPS边界
28813
- const getValidGpsBounds = (mapData, rotation = 0) => {
28814
- let bounds;
28815
- // 首先尝试使用地图数据中的GPS坐标
28816
- if (isValidGpsCoordinate(mapData.sw_gps) && isValidGpsCoordinate(mapData.ne_gps)) {
28817
- bounds = {
28818
- sw: mapData.sw_gps,
28819
- ne: mapData.ne_gps,
28820
- };
28821
- }
28822
- else {
28823
- // 如果GPS坐标无效,尝试从地图几何数据估算
28824
- const { sw, ne } = estimateGpsFromMapBounds(mapData);
28825
- if (sw && ne) {
28826
- console.warn('GPS坐标无效,使用地图几何数据估算边界:', sw, ne);
28827
- bounds = {
28828
- sw: [sw[0], sw[1]],
28829
- ne: [ne[0], ne[1]],
28830
- };
28831
- }
28832
- else {
28833
- // 最后的fallback:使用默认坐标
28834
- console.warn('无法获取有效的GPS边界,使用默认坐标');
28835
- bounds = DEFAULT_COORDINATES;
28836
- }
28837
- }
28838
- // 如果有旋转角度,计算旋转后的边界
28839
- if (rotation !== 0) {
28840
- const angleRadians = (rotation * Math.PI) / 180; // 转换为弧度
28841
- // 计算边界中心点
28842
- const centerLng = (bounds.sw[0] + bounds.ne[0]) / 2;
28843
- const centerLat = (bounds.sw[1] + bounds.ne[1]) / 2;
28844
- const center = [centerLng, centerLat];
28845
- // 旋转四个角点
28846
- const sw = rotateCoordinate(bounds.sw, center, angleRadians);
28847
- const ne = rotateCoordinate(bounds.ne, center, angleRadians);
28848
- const se = rotateCoordinate([bounds.ne[0], bounds.sw[1]], center, angleRadians);
28849
- const nw = rotateCoordinate([bounds.sw[0], bounds.ne[1]], center, angleRadians);
28850
- // 计算旋转后的边界框(包含所有旋转后的点)
28851
- const lngs = [sw[0], ne[0], se[0], nw[0]];
28852
- const lats = [sw[1], ne[1], se[1], nw[1]];
28853
- bounds = {
28854
- sw: [Math.min(...lngs), Math.min(...lats)],
28855
- ne: [Math.max(...lngs), Math.max(...lats)],
28856
- };
28857
- }
28858
- return bounds;
28859
- };
28860
28852
  // 默认配置
28861
28853
  const defaultMapConfig$1 = DEFAULT_STYLES;
28862
28854
  // 地图渲染器组件
@@ -28896,6 +28888,14 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28896
28888
  const mapBounds = React.useMemo(() => {
28897
28889
  return calculateMapBounds(mapJson);
28898
28890
  }, [mapJson]);
28891
+ const originNorthRotate = React.useMemo(() => {
28892
+ if (mapJson.map_north_offset)
28893
+ return (mapJson.map_north_offset * 180) / Math.PI;
28894
+ return 0;
28895
+ }, [mapJson]);
28896
+ const actureRotate = React.useMemo(() => {
28897
+ return originNorthRotate + drag?.rotation;
28898
+ }, [originNorthRotate, drag?.rotation]);
28899
28899
  const svgViewBox = React.useMemo(() => {
28900
28900
  const padding = 0; // 添加一些边距以避免内容贴边
28901
28901
  const boundWidth = mapBounds.maxX - mapBounds.minX + padding * 2;
@@ -28976,8 +28976,12 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
28976
28976
  newSvgElementDatas[key] =
28977
28977
  newSvgElementDatas[key].filter((item) => {
28978
28978
  return (item.status === 1 &&
28979
- (!item.start_timestamp || !item.end_timestamp || (item.start_timestamp && item.start_timestamp <= Date.now() / 1000 &&
28980
- item.end_timestamp && item.end_timestamp >= Date.now() / 1000)));
28979
+ (!item.start_timestamp ||
28980
+ !item.end_timestamp ||
28981
+ (item.start_timestamp &&
28982
+ item.start_timestamp <= Date.now() / 1000 &&
28983
+ item.end_timestamp &&
28984
+ item.end_timestamp >= Date.now() / 1000)));
28981
28985
  }) || [];
28982
28986
  }
28983
28987
  else if (key === exports.DataType.DOODLE) {
@@ -29020,7 +29024,11 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29020
29024
  globalHeight,
29021
29025
  mapConfig: mergedMapConfig,
29022
29026
  mapJson,
29023
- drag: defaultTransform,
29027
+ drag: {
29028
+ x: defaultTransform?.x ?? 0,
29029
+ y: defaultTransform?.y ?? 0,
29030
+ rotate: (defaultTransform?.rotation ?? 0) + originNorthRotate,
29031
+ },
29024
29032
  mapRef,
29025
29033
  overlayScale,
29026
29034
  doodleList,
@@ -29039,6 +29047,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29039
29047
  mergedMapConfig,
29040
29048
  mapJson,
29041
29049
  defaultTransform,
29050
+ originNorthRotate,
29042
29051
  mapRef,
29043
29052
  overlayScale,
29044
29053
  doodleList,
@@ -29123,8 +29132,9 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29123
29132
  handleError('无法计算地图边界');
29124
29133
  return;
29125
29134
  }
29135
+ const rotate = defaultTransform?.rotation + originNorthRotate;
29126
29136
  // 将自定义边界转换为Google Maps LatLngBounds(使用有效的GPS坐标)
29127
- const validBounds = getValidGpsBounds(mapJson, defaultTransform?.rotation);
29137
+ const validBounds = getValidGpsBounds(mapJson, rotate);
29128
29138
  // 地图数据中的坐标格式是 [longitude, latitude]
29129
29139
  const [swLng0, swLat0] = validBounds.sw;
29130
29140
  const [neLng0, neLat0] = validBounds.ne;
@@ -29140,7 +29150,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29140
29150
  new window.google.maps.LatLng(neLat, neLng) // 东北角
29141
29151
  );
29142
29152
  mapRef.fitBounds(googleBounds, padding);
29143
- }, [mapJson, mapRef, defaultTransform]);
29153
+ }, [mapJson, mapRef, defaultTransform, originNorthRotate]);
29144
29154
  const handleDragMove = React.useCallback((e) => {
29145
29155
  if (!overlay || !bounds)
29146
29156
  return;
@@ -29169,7 +29179,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29169
29179
  setDrag((prev) => ({
29170
29180
  x: prev.x + dx,
29171
29181
  y: prev.y + dy,
29172
- rotation: e.rotate,
29182
+ rotation: prev.rotation + e.rotate,
29173
29183
  }));
29174
29184
  }, [overlay, bounds]);
29175
29185
  React.useEffect(() => {
@@ -29196,17 +29206,21 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29196
29206
  // mowPartitionDataRef.current = {};
29197
29207
  // // console.error('0.50.5--mowPartitionDataRef.current---->', mowPartitionDataRef.current);
29198
29208
  // }
29199
- isTaskDelayRef.current = vehicleStatusData?.taskDelay !== undefined ? vehicleStatusData?.taskDelay : isTaskDelayRef.current;
29209
+ isTaskDelayRef.current =
29210
+ vehicleStatusData?.taskDelay !== undefined
29211
+ ? vehicleStatusData?.taskDelay
29212
+ : isTaskDelayRef.current;
29200
29213
  // console.error('isTaskDelayRef.current 111---->', isTaskDelayRef.current);
29201
29214
  }
29202
29215
  const positionData = realTimeData?.find((item) => item?.type === RealTimeDataType.LOCATION);
29203
29216
  // 如果当前是taskDelay的状态,或者状态为mowing或者standby,则指定的地块需要高亮,或者全局高亮
29204
- if ((isTaskDelayRef.current || positionData?.vehicleState === RobotStatus.MOWING || positionData?.vehicleState === RobotStatus.STANDBY) &&
29217
+ if ((isTaskDelayRef.current ||
29218
+ positionData?.vehicleState === RobotStatus.MOWING ||
29219
+ positionData?.vehicleState === RobotStatus.STANDBY) &&
29205
29220
  mowPartitionDataRef.current &&
29206
29221
  !mowPartitionDataRef.current?.partitionIds) {
29207
29222
  // 设置全局高亮
29208
- if (mowPartitionDataRef.current &&
29209
- !mowPartitionDataRef.current?.partitionIds) {
29223
+ if (mowPartitionDataRef.current && !mowPartitionDataRef.current?.partitionIds) {
29210
29224
  const allPartitionIds = generateBoundaryData(mapJson)
29211
29225
  ?.filter((item) => !item?.isIsolated)
29212
29226
  .map((item) => item?.id);
@@ -29218,7 +29232,10 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29218
29232
  };
29219
29233
  }
29220
29234
  }
29221
- else if (!isTaskDelayRef.current && positionData?.vehicleState === RobotStatus.WORKING && (currentVehicleStateRef.current === RobotStatus.MOWING || currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29235
+ else if (!isTaskDelayRef.current &&
29236
+ positionData?.vehicleState === RobotStatus.WORKING &&
29237
+ (currentVehicleStateRef.current === RobotStatus.MOWING ||
29238
+ currentVehicleStateRef.current === RobotStatus.STANDBY)) {
29222
29239
  // 非deskDelay的状态下
29223
29240
  // 1. 如果当前是working状态,且上一次是mowing或者standby状态,则取消高亮
29224
29241
  // 兜底收不到割草地块的实时数据,使用状态来兜底
@@ -29227,12 +29244,16 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29227
29244
  mowPartitionDataRef.current = {};
29228
29245
  }
29229
29246
  // 更新当前车辆状态
29230
- currentVehicleStateRef.current = positionData?.vehicleState !== undefined ? positionData?.vehicleState : currentVehicleStateRef.current;
29247
+ currentVehicleStateRef.current =
29248
+ positionData?.vehicleState !== undefined
29249
+ ? positionData?.vehicleState
29250
+ : currentVehicleStateRef.current;
29231
29251
  if (!mapJson || !svgMapRef.current)
29232
29252
  return;
29233
29253
  // 根据后端推送的实时数据,进行不同处理
29234
29254
  if (mowPartitionDataRef.current) {
29235
- const isMowing = mowPartitionDataRef.current?.partitionIds && mowPartitionDataRef.current.partitionIds.length > 0;
29255
+ const isMowing = mowPartitionDataRef.current?.partitionIds &&
29256
+ mowPartitionDataRef.current.partitionIds.length > 0;
29236
29257
  if (!isMowing) {
29237
29258
  setMowingPartitions(undefined);
29238
29259
  }
@@ -29299,7 +29320,6 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29299
29320
  // 基于固定的参考zoom级别计算overlayScale
29300
29321
  const zoomDiff = currentZoom - REFERENCE_ZOOM;
29301
29322
  const scale = Math.pow(2, -zoomDiff); // 负数实现反向缩放
29302
- console.log('scale------->', scale);
29303
29323
  // setOverlayScale(scale < 1 ? 1 : platform === PlatformType.H5 ? 1.5 * scale : scale);
29304
29324
  if (scale < 1) {
29305
29325
  setOverlayScale(1);
@@ -29417,7 +29437,7 @@ modelType, showStraddleBoundaryBorder = true, mapRef, mapJson, pathJson, realTim
29417
29437
  // svgEditMapRef?.current?.adjustSvgSize?.(layout);
29418
29438
  setOverlayLayout(layout);
29419
29439
  }
29420
- }, 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 })] })] }) }) }));
29440
+ }, 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 })] })] }) }) }));
29421
29441
  });
29422
29442
  MowerMapRenderer.displayName = 'MowerMapRenderer';
29423
29443
 
@@ -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"}
@@ -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"}
@@ -1 +1 @@
1
- {"version":3,"file":"handleRealTime.d.ts","sourceRoot":"","sources":["../../src/utils/handleRealTime.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIzD,eAAO,MAAM,kBAAkB,GAC7B,mBAAmB,GAAG,EAAE,EACxB,WAAW,MAAM,EACjB,WAAW,MAAM,YAMlB,CAAC;AAGF,eAAO,MAAM,cAAc,GAAI,mBAAmB,GAAG,EAAE,EAAE,WAAW,MAAM,EAAE,WAAW,MAAM,QAU5F,CAAC;AAiDF;;;;;;GAMG;AACH,QAAA,MAAM,0BAA0B,GAAI,+DAOpC,uBAAuB,KAAG;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;CAmEhC,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oCAAoC,GAAI,+DAK3C;IAED,YAAY,EAAE,CAAC,oBAAoB,GAAG,mBAAmB,GAAG,qBAAqB,CAAC,EAAE,CAAC;IACrF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,KAAG;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;CA+BhC,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,oCAAoC,EAAE,CAAC"}
1
+ {"version":3,"file":"handleRealTime.d.ts","sourceRoot":"","sources":["../../src/utils/handleRealTime.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIzD,eAAO,MAAM,kBAAkB,GAC7B,mBAAmB,GAAG,EAAE,EACxB,WAAW,MAAM,EACjB,WAAW,MAAM,YAMlB,CAAC;AAGF,eAAO,MAAM,cAAc,GAAI,mBAAmB,GAAG,EAAE,EAAE,WAAW,MAAM,EAAE,WAAW,MAAM,QAU5F,CAAC;AAiDF;;;;;;GAMG;AACH,QAAA,MAAM,0BAA0B,GAAI,+DAOpC,uBAAuB,KAAG;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;CAiEhC,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,oCAAoC,GAAI,+DAK3C;IAED,YAAY,EAAE,CAAC,oBAAoB,GAAG,mBAAmB,GAAG,qBAAqB,CAAC,EAAE,CAAC;IACrF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,KAAG;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;CA+BhC,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,oCAAoC,EAAE,CAAC"}
@@ -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.3",
3
+ "version": "0.2.5-beta.1",
4
4
  "type": "module",
5
5
  "description": "a mower maps in google maps",
6
6
  "main": "dist/index.js",