@hzab/map-combine 0.4.2-alpha.0 → 0.4.2-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +5 -5
  3. package/src/amap/AMap.ts +313 -306
  4. package/src/amap/AMapEvent.ts +110 -54
  5. package/src/amap/AMapPoint.ts +140 -143
  6. package/src/amap/AMapPolygon.ts +214 -195
  7. package/src/amap/AMapPolyline.ts +199 -185
  8. package/src/basic/BasicBusiness.ts +5 -5
  9. package/src/basic/BasicModel.ts +49 -0
  10. package/src/basic/MapCombine.ts +4 -0
  11. package/src/basic/MapElement.ts +2 -1
  12. package/src/basic/MapEvent.ts +5 -0
  13. package/src/basic/Point.ts +1 -0
  14. package/src/basic/PointAggregation.tsx +23 -11
  15. package/src/basic/ReactPopup.tsx +3 -0
  16. package/src/cesium/CesiumEvent.ts +97 -84
  17. package/src/cesium/CesiumMap.ts +355 -347
  18. package/src/cesium/CesiumModel.ts +64 -0
  19. package/src/cesium/CesiumPoint.ts +3 -0
  20. package/src/cesium/CesiumPolygon.ts +2 -0
  21. package/src/cesium/CesiumPolyline.ts +185 -47
  22. package/src/cesium/CesiumTile3D.ts +222 -225
  23. package/src/mine/MineEvent.ts +70 -46
  24. package/src/mine/MineMap.ts +52 -1
  25. package/src/mine/MinePoint.ts +7 -1
  26. package/src/mine/MinePolygon.ts +6 -1
  27. package/src/mine/MinePolyline.ts +6 -1
  28. package/src/openlayer/OpenlayerEvent.ts +109 -87
  29. package/src/openlayer/OpenlayerMap.ts +287 -287
  30. package/src/openlayer/OpenlayerPoint.ts +6 -1
  31. package/src/openlayer/OpenlayerPolygon.ts +34 -24
  32. package/src/openlayer/OpenlayerPolyline.ts +10 -3
  33. package/src/utils/color.ts +49 -0
  34. package/src/utils/index.ts +3 -0
  35. package/src/utils/points-viewer.ts +27 -1
  36. package/src/utils/turfjs-utils.ts +52 -0
  37. package/src/utils/types.d.ts +12 -0
@@ -10,26 +10,10 @@ import iconPoint from "../assets/point.png";
10
10
  import iconAdd from "../assets/add.png";
11
11
  import Point from "ol/geom/Point.js";
12
12
  import { ChainNode, PolygonEditor } from "../utils/PolygonEditor";
13
- const styleNode = new Style({
14
- image: new Icon({
15
- width: 16,
16
- height: 16,
17
- src: iconPoint,
18
- crossOrigin: "anonymous",
19
- }),
20
- });
21
-
22
- const styleVirtual = new Style({
23
- image: new Icon({
24
- width: 16,
25
- height: 16,
26
- src: iconAdd,
27
- crossOrigin: "anonymous",
28
- }),
29
- });
30
13
 
31
14
  export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
32
- const { event, viewer, vectors, getFromLonLat, isFromLonLat } = map;
15
+ const { event, viewer, vectors, isFromLonLat } = map;
16
+ // getFromLonLat 使用 map.getFromLonLat 调用,保证 this 指向正确
33
17
 
34
18
  const source = new VectorSource();
35
19
 
@@ -42,7 +26,12 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
42
26
  let status = 0;
43
27
  let skip = 0;
44
28
 
45
- const feature = new Feature();
29
+ const feature = new Feature({
30
+ userData: {
31
+ name: polygon.name,
32
+ target: polygon,
33
+ },
34
+ });
46
35
  const geometry = new OlPolygon([
47
36
  [
48
37
  [0, 0],
@@ -62,6 +51,27 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
62
51
  stroke,
63
52
  fill,
64
53
  });
54
+ const styleNode = new Style({
55
+ image: new Icon({
56
+ width: 16,
57
+ height: 16,
58
+ src: iconPoint,
59
+ crossOrigin: "anonymous",
60
+ }),
61
+ // 保证编辑的点位高于线
62
+ zIndex: style.getZIndex() + 5,
63
+ });
64
+
65
+ const styleVirtual = new Style({
66
+ image: new Icon({
67
+ width: 16,
68
+ height: 16,
69
+ src: iconAdd,
70
+ crossOrigin: "anonymous",
71
+ }),
72
+ // 保证编辑的点位高于线
73
+ zIndex: style.getZIndex() + 5,
74
+ });
65
75
 
66
76
  const _event = {
67
77
  cursor: polygon.cursor,
@@ -95,7 +105,7 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
95
105
  feature.set("event", _event, true);
96
106
  if (polygon.coordinates) {
97
107
  status = 2;
98
- geometry.setCoordinates([polygon.coordinates.map((e) => getFromLonLat(e, isFromLonLat))]);
108
+ geometry.setCoordinates([polygon.coordinates.map((e) => map.getFromLonLat(e, isFromLonLat))]);
99
109
  layer.setZIndex(polygon.coordinates[0][2] ?? 1);
100
110
  source.addFeature(feature);
101
111
  }
@@ -115,7 +125,7 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
115
125
  break;
116
126
  case "coordinates":
117
127
  if (polygon.coordinates) {
118
- geometry.setCoordinates([polygon.coordinates.map((e) => getFromLonLat(e, isFromLonLat))]);
128
+ geometry.setCoordinates([polygon.coordinates.map((e) => map.getFromLonLat(e, isFromLonLat))]);
119
129
  layer.setZIndex(polygon.coordinates[0][2] ?? 1);
120
130
  switch (status) {
121
131
  case 0:
@@ -157,11 +167,11 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
157
167
  switch (status) {
158
168
  case 1:
159
169
  cache.pop();
160
- cache.push(getFromLonLat(event.geography));
170
+ cache.push(map.getFromLonLat(event.geography));
161
171
  geometry.setCoordinates([cache]);
162
172
  break;
163
173
  case 4:
164
- activeNode.update(getFromLonLat(event.geography));
174
+ activeNode.update(map.getFromLonLat(event.geography));
165
175
  geometry.setCoordinates([editor.getCoordinates()]);
166
176
  break;
167
177
  }
@@ -171,7 +181,7 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
171
181
  switch (status) {
172
182
  case 0:
173
183
  status = 1;
174
- cache = [getFromLonLat(event.geography)];
184
+ cache = [map.getFromLonLat(event.geography)];
175
185
  cache.push(cache[0]);
176
186
  geometry.setCoordinates([cache]);
177
187
  source.addFeature(feature);
@@ -25,7 +25,12 @@ export function drawPolyline(map: OpenlayerMap, polyline: Polyline<unknown>) {
25
25
  let status = 0;
26
26
  let skip = 0;
27
27
 
28
- const feature = new Feature();
28
+ const feature = new Feature({
29
+ userData: {
30
+ name: polyline.name,
31
+ target: polyline,
32
+ },
33
+ });
29
34
  const geometry = new LineString([
30
35
  [0, 0],
31
36
  [0, 0],
@@ -48,7 +53,7 @@ export function drawPolyline(map: OpenlayerMap, polyline: Polyline<unknown>) {
48
53
  src: iconPoint,
49
54
  crossOrigin: "anonymous",
50
55
  }),
51
- // 保证线编辑的点位高于线
56
+ // 保证编辑的点位高于线
52
57
  zIndex: style.getZIndex() + 5,
53
58
  });
54
59
 
@@ -59,11 +64,13 @@ export function drawPolyline(map: OpenlayerMap, polyline: Polyline<unknown>) {
59
64
  src: iconAdd,
60
65
  crossOrigin: "anonymous",
61
66
  }),
62
- // 保证线编辑的点位高于线
67
+ // 保证编辑的点位高于线
63
68
  zIndex: style.getZIndex() + 5,
64
69
  });
65
70
 
66
71
  const _event = {
72
+ name: polyline.name,
73
+ target: polyline,
67
74
  cursor: polyline.cursor,
68
75
  silent: polyline.silent,
69
76
  onPointerIn() {
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 解析十六进制颜色字符串,拆分为颜色值和透明度
3
+ * @param {string} hexColor - 十六进制颜色字符串,支持格式:#RGB, #RRGGBB, #RRGGBBAA, #RGBA
4
+ * @param {number} defaultOpacity - 默认透明度(0-1),当颜色没有透明度时使用
5
+ * @returns {Object} { color: string, opacity: number }
6
+ * @throws {Error} 如果颜色格式无效
7
+ */
8
+ export function parseHexColor(hexColor, defaultOpacity = 1) {
9
+ // 移除开头的 # 号(如果有)
10
+ let hex = hexColor.replace(/^#/, "");
11
+
12
+ // 验证是否为有效的十六进制字符串
13
+ if (!/^[0-9a-fA-F]+$/.test(hex)) {
14
+ throw new Error(`无效的颜色格式: "${hexColor}"`);
15
+ }
16
+
17
+ let color = "";
18
+ let opacity = defaultOpacity;
19
+
20
+ switch (hex.length) {
21
+ case 3: // #RGB
22
+ color = `#${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;
23
+ opacity = defaultOpacity;
24
+ break;
25
+
26
+ case 4: // #RGBA
27
+ color = `#${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;
28
+ opacity = parseInt(hex[3] + hex[3], 16) / 255;
29
+ break;
30
+
31
+ case 6: // #RRGGBB
32
+ color = `#${hex}`;
33
+ opacity = defaultOpacity;
34
+ break;
35
+
36
+ case 8: // #RRGGBBAA
37
+ color = `#${hex.slice(0, 6)}`;
38
+ opacity = parseInt(hex.slice(6, 8), 16) / 255;
39
+ break;
40
+
41
+ default:
42
+ throw new Error(`不支持的十六进制颜色长度: "${hexColor}",长度必须为 3、4、6 或 8`);
43
+ }
44
+
45
+ // 确保透明度在 0-1 范围内
46
+ opacity = Math.max(0, Math.min(1, opacity));
47
+
48
+ return { color, opacity };
49
+ }
@@ -12,6 +12,9 @@ export function setValue<T>(obj: any, key: string, val: T, onChange: () => void)
12
12
  }
13
13
  }
14
14
 
15
+ /**
16
+ * 建立两个一维区间之间的线性映射关系,提供正向变换和逆向变换
17
+ */
15
18
  export class OneDimensional {
16
19
  k: number;
17
20
  b: number;
@@ -43,5 +43,31 @@ export const getBounds = function (points, opt) {
43
43
  minLat -= avoid[1] * latPixelRatio;
44
44
  maxLat += avoid[0] * latPixelRatio;
45
45
 
46
- return [minLon, minLat, maxLon, maxLat];
46
+ // 根据 maxZoom 计算最小矩形范围
47
+ const minRange = getMinRangeFromZoom(opt.maxZoom);
48
+ const centerLon = (minLon + maxLon) / 2;
49
+ const centerLat = (minLat + maxLat) / 2;
50
+
51
+ // 确保矩形范围不小于最小值 解决点位距离过近导致异常缩放问题
52
+ let finalWest = Math.min(minLon, centerLon - minRange / 2);
53
+ let finalEast = Math.max(maxLon, centerLon + minRange / 2);
54
+ let finalSouth = Math.min(minLat, centerLat - minRange / 2);
55
+ let finalNorth = Math.max(maxLat, centerLat + minRange / 2);
56
+
57
+ return [finalWest, finalSouth, finalEast, finalNorth];
47
58
  };
59
+
60
+ /**
61
+ * 根据 maxZoom 计算出一个“最小”的经纬度跨度
62
+ * @param zoom
63
+ * @returns
64
+ */
65
+ export function getMinRangeFromZoom(zoom) {
66
+ // 每个瓦片覆盖的经度范围
67
+ const lonPerTile = 360 / Math.pow(2, zoom);
68
+ // 每个瓦片覆盖的纬度范围(近似)
69
+ const latPerTile = 180 / Math.pow(2, zoom);
70
+
71
+ // 返回一个足够小的范围,比如一个瓦片范围的一半
72
+ return Math.max(lonPerTile, latPerTile) / 2;
73
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * 通用函数:提取所有坐标并扁平化为普通数组
3
+ * @param geojsonFeature
4
+ * @param geomType
5
+ * @returns
6
+ */
7
+ export function extractCoordinatesToArr(coords, geomType) {
8
+ if (geomType === "Polygon") {
9
+ // 多边形:三维数组 [环1[点1,点2...], 环2[...]] -> 转为二维数组
10
+ return coords.map(
11
+ (ring) => ring.map((coord) => [coord[0], coord[1]]), // 提取经度、纬度
12
+ );
13
+ } else if (geomType === "MultiPolygon") {
14
+ // 多部件多边形:四维数组 -> 转为三维数组
15
+ return coords.map((polygon) => polygon.map((ring) => ring.map((coord) => [coord[0], coord[1]])));
16
+ } else if (geomType === "Point") {
17
+ // 点:返回一维数组
18
+ return [coords[0], coords[1]];
19
+ } else if (geomType === "LineString") {
20
+ // 线:返回二维数组
21
+ return coords.map((coord) => [coord[0], coord[1]]);
22
+ }
23
+
24
+ return coords;
25
+ }
26
+
27
+ /**
28
+ * 通用函数:提取所有坐标并扁平化为普通数组
29
+ * @param geojsonFeature
30
+ * @returns
31
+ */
32
+ export function extractGeojsonCoordinatesToArr(geojsonFeature) {
33
+ const coords = geojsonFeature.geometry.coordinates;
34
+ const geomType = geojsonFeature.geometry.type;
35
+ if (geomType === "Polygon") {
36
+ // 多边形:三维数组 [环1[点1,点2...], 环2[...]] -> 转为二维数组
37
+ return coords.map(
38
+ (ring) => ring.map((coord) => [coord[0], coord[1]]), // 提取经度、纬度
39
+ );
40
+ } else if (geomType === "MultiPolygon") {
41
+ // 多部件多边形:四维数组 -> 转为三维数组
42
+ return coords.map((polygon) => polygon.map((ring) => ring.map((coord) => [coord[0], coord[1]])));
43
+ } else if (geomType === "Point") {
44
+ // 点:返回一维数组
45
+ return [coords[0], coords[1]];
46
+ } else if (geomType === "LineString") {
47
+ // 线:返回二维数组
48
+ return coords.map((coord) => [coord[0], coord[1]]);
49
+ }
50
+
51
+ return coords;
52
+ }
@@ -0,0 +1,12 @@
1
+ export enum HtmlPosition {
2
+ "auto",
3
+ "bottomright",
4
+ "bottom",
5
+ "bottomleft",
6
+ "right",
7
+ "top",
8
+ "left",
9
+ "topright",
10
+ "topleft" = 9,
11
+ "center",
12
+ }