@hzab/map-combine 0.4.2-alpha.3 → 0.4.2-alpha.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,7 @@ fix: openlayer getFromLonLat this 指向修复
5
5
  break: PointAggregation datas 改为数组对象
6
6
  fix: cesium flyTo height 计算
7
7
  feat: map.bussinesses onFrame 事件回调
8
+ fix: AmapPoint drawPoint 逻辑修复
8
9
 
9
10
  # @hzab/map-combine@0.4.1
10
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/map-combine",
3
- "version": "0.4.2-alpha.3",
3
+ "version": "0.4.2-alpha.4",
4
4
  "description": "地图组件",
5
5
  "main": "src",
6
6
  "scripts": {
@@ -29,7 +29,7 @@
29
29
  "@amap/amap-jsapi-loader": "^1.0.1",
30
30
  "@hzab/permissions": "0.1.1",
31
31
  "@hzab/webpack-config": "^0.2.1",
32
- "@turf/turf": "6.5",
32
+ "@turf/turf": "6.5.0",
33
33
  "@types/amap-js-api": "^1.4.16",
34
34
  "@types/react": "^17.0.62",
35
35
  "@types/react-dom": "^17.0.20",
@@ -51,8 +51,9 @@
51
51
  "lib": "lib"
52
52
  },
53
53
  "peerDependencies": {
54
- "@turf/turf": "6.5",
54
+ "@turf/turf": "6.5.0",
55
55
  "coordtransform": "^2.1.2",
56
+ "nanoid": "^3.3.7",
56
57
  "lodash": ">=4.17.21",
57
58
  "react-dom": "^17.0.2",
58
59
  "zrender": "^5.4.4"
package/src/amap/AMap.ts CHANGED
@@ -1,306 +1,313 @@
1
- import { MapCombine } from "../basic/MapCombine";
2
- import { PointOption, Point } from "../basic/Point";
3
- import { PointAggregationOption, PointAggregation } from "../basic/PointAggregation";
4
- import { ReactPointOption, ReactPoint, drawReactPoint } from "../basic/ReactPoint";
5
- import { PolylineOption, Polyline } from "../basic/Polyline";
6
- import { PolygonOption, Polygon } from "../basic/Polygon";
7
- import { Tile3DOption, Tile3D } from "../basic/Tile3D";
8
-
9
- import AMapLoader from "./loader";
10
- import { bindEvent } from "./AMapEvent";
11
- import { drawPoint } from "./AMapPoint";
12
- import { drawPolyline } from "./AMapPolyline";
13
- import { drawPolygon } from "./AMapPolygon";
14
-
15
- export interface IAMapOption {
16
- container: HTMLDivElement;
17
- url?: string | string[];
18
- center?: number[];
19
- zoom?: number;
20
- maxZoom?: number;
21
- minZoom?: number;
22
- /** 地图瓦片转换规则 GCJ02 转 WGS84 */
23
- proj?: "GCJ02->WGS84";
24
- /** 高德地图 key */
25
- key: string;
26
- /** 高德地图 securityJsCode */
27
- securityJsCode: string;
28
- /** 加载的插件列表 */
29
- plugins?: [string];
30
- /** loader 配置参数 */
31
- loaderOpt?: Object;
32
- /** 地图初始化 配置参数 */
33
- mapOpt?: Object;
34
- }
35
-
36
- export interface IFlyToViewerOpt {
37
- /**
38
- * 立即缩放到指定位置
39
- */
40
- immediately?: boolean;
41
- /**
42
- * (Array<number> = [0,0,0,0]) 距离边框的内边距,顺序:上、下、左、右
43
- */
44
- avoid?: [number, number, number, number];
45
- /**
46
- * 最大缩放级别
47
- */
48
- maxZoom?: number;
49
- /**
50
- * 动画时间
51
- */
52
- duration?: number;
53
- }
54
-
55
- export class AMap extends MapCombine {
56
- viewer: any;
57
- container: HTMLDivElement = null;
58
- option: any = {};
59
- offset: number[];
60
- fov = 0.9272952180016121;
61
- isFromLonLat = true;
62
- LbsAMap: any;
63
- get cursor(): string {
64
- return this.container.style.cursor;
65
- }
66
- set cursor(val: string) {
67
- this.container.style.cursor = val;
68
- }
69
-
70
- get moveable(): boolean {
71
- return this.viewer?.getStatus()?.dragEnable;
72
- }
73
- set moveable(val: boolean) {
74
- this.viewer?.setStatus({ dragEnable: val });
75
- }
76
-
77
- get center(): number[] {
78
- return this.viewer?.getCenter();
79
- }
80
- set center(val: number[]) {
81
- this.viewer?.setCenter(val);
82
- }
83
- get zoom(): number {
84
- return this.viewer?.getZoom();
85
- }
86
- set zoom(val: number) {
87
- this.viewer?.setZoom(val);
88
- }
89
-
90
- constructor(viewer = undefined) {
91
- super();
92
- viewer && this._initParamsEvent(viewer);
93
- }
94
-
95
- private _initParamsEvent(viewer) {
96
- if (!viewer) {
97
- return;
98
- }
99
- this.viewer = viewer;
100
-
101
- this.container = this.viewer.getContainer();
102
- // this.markers = this.viewer.scene.primitives.add(new Cesium.BillboardCollection());
103
-
104
- bindEvent(this);
105
- }
106
-
107
- init(opt: IAMapOption) {
108
- this.option = opt;
109
- const {
110
- container,
111
- center = [120.2288892, 30.2349677, 0],
112
- zoom = 13,
113
- url,
114
- maxZoom,
115
- minZoom,
116
- proj,
117
- key,
118
- securityJsCode,
119
- plugins,
120
- } = opt || {};
121
-
122
- this.loadPromise = new Promise((resolve, reject) => {
123
- AMapLoader({
124
- ...opt.loaderOpt,
125
- key,
126
- securityJsCode,
127
- plugins,
128
- })
129
- .then((LbsAMap: any) => {
130
- this.LbsAMap = LbsAMap;
131
- let _urls = Array.isArray(url) ? url : [url];
132
- this.viewer = new LbsAMap.Map(container, {
133
- ...opt.mapOpt,
134
- zoom: zoom || 14,
135
- center: center || [120.160217, 30.243861],
136
- doubleClickZoom: false,
137
- zooms: minZoom && maxZoom && [minZoom, maxZoom],
138
- layers: url
139
- ? _urls.map((it: any) => {
140
- let opt = { tileUrl: "", getTileUrl: undefined };
141
- if (typeof it === "string") {
142
- opt.tileUrl = it;
143
- } else {
144
- opt = it;
145
- }
146
- // 使用 getTileUrl 解决接口地址强制改为 https 的问题
147
- opt.getTileUrl = function (x, y, z) {
148
- return opt.tileUrl.replace("{x}", x).replace("{y}", y).replace("{z}", z);
149
- };
150
-
151
- return new LbsAMap.TileLayer(opt);
152
- })
153
- : undefined,
154
- });
155
- this.viewer.on("complete", () => {
156
- resolve(this);
157
- });
158
-
159
- this._initParamsEvent(this.viewer);
160
- return this;
161
- })
162
- .catch(reject);
163
- });
164
- this.loadPromise.then(() => {
165
- this.container.appendChild(this.htmllayer);
166
- });
167
- return this.loadPromise;
168
- }
169
-
170
- createPoint<K>(option?: Partial<PointOption<K>>): Point<K> {
171
- const e = new Point(this, option);
172
- this.loadPromise.then(() => {
173
- drawPoint(this, e);
174
- });
175
- return e;
176
- }
177
-
178
- createPointAggregation(option?: PointAggregationOption): PointAggregation {
179
- const e = new PointAggregation(this, option);
180
- return e;
181
- }
182
-
183
- createReactPoint<K>(option?: Partial<ReactPointOption<K>>): ReactPoint<K> {
184
- const e = new ReactPoint(this, option);
185
- this.loadPromise.then(() => {
186
- drawReactPoint(this, e);
187
- });
188
- return e;
189
- }
190
-
191
- createPolyline<K>(option?: Partial<PolylineOption<K>>): Polyline<K> {
192
- const e = new Polyline(this, option);
193
- this.loadPromise.then(() => {
194
- drawPolyline(this, e);
195
- });
196
- return e;
197
- }
198
- createPolygon<K>(option?: Partial<PolygonOption<K>>): Polygon<K> {
199
- const e = new Polygon(this, option);
200
- this.loadPromise.then(() => {
201
- drawPolygon(this, e);
202
- });
203
- return e;
204
- }
205
- createTile3D(option?: Partial<Tile3DOption>): Tile3D {
206
- throw new Error("Method not implemented.");
207
- }
208
-
209
- /**
210
- * 将高德地图 Canvas 像素坐标转换为经纬度
211
- * @param {Array} p - canvas 点位数组 [x, y]
212
- * @returns {Array} p - 经纬度数组 [lng, lat]
213
- */
214
- canvasTgeography(p: number[]) {
215
- const mapInstance = this.viewer;
216
- if (!mapInstance) {
217
- this.loadPromise.then(() => {
218
- this.canvasTgeography(p);
219
- });
220
- return [];
221
- }
222
- try {
223
- const lngLat = this.viewer.lngLatToContainer(p);
224
- return [lngLat.x, lngLat.y];
225
- } catch (error) {
226
- console.error("canvasPixelToLngLat 转换出错:", error);
227
- return [];
228
- }
229
- }
230
-
231
- /**
232
- * 经纬度转换为高德地图 Canvas 像素坐标
233
- * @param {Array} p - 经纬度数组 [lng, lat]
234
- * @returns {Array} Canvas 像素坐标 [x, y]
235
- */
236
- geographyTcanvas(p: number[]): number[] {
237
- const mapInstance = this.viewer;
238
- if (!mapInstance) {
239
- this.loadPromise.then(() => {
240
- this.geographyTcanvas(p);
241
- });
242
- return [];
243
- }
244
- try {
245
- const containerPixel = this.viewer.lngLatToContainer(p);
246
- return [containerPixel.x, containerPixel.y];
247
- } catch (error) {
248
- console.error("lngLatToCanvasPixel 转换出错:", error);
249
- return [];
250
- }
251
- }
252
- /**
253
- * 所有点位移动至视口,调整位置及层级
254
- * @param points
255
- * @param opt
256
- * @param {Array<number> = [0,0,0,0]} opt.avoid 距离边框的内边距,顺序:上、下、左、右
257
- */
258
- flyToViewer(points: number[][], opt: IFlyToViewerOpt = { avoid: [0, 0, 0, 0], immediately: true }): void {
259
- this.loadPromise.then(() => {
260
- const [zoom, center] = this.viewer.getFitZoomAndCenterByBounds(
261
- this.getBounds(points, { canvas: this.viewer.canvas, ...opt }),
262
- opt?.avoid,
263
- opt.maxZoom,
264
- );
265
-
266
- this.viewer.setZoomAndCenter(zoom, center, opt?.immediately, opt?.duration);
267
- });
268
- }
269
-
270
- /**
271
- * 将点集视野调整至容器内,支持相对边距(百分比)
272
- * @param {number[][]} points - 经纬度数组 [[lng, lat], ...]
273
- * @param {Object} opt
274
- * @param {number[]} opt.avoid - 相对边距 [上, 下, 左, 右],取值范围 0~1,默认 [0,0,0,0]
275
- * @param {boolean} opt.immediately - 是否立即跳转,默认 false(带动画)
276
- */
277
- flyToViewerPercent(points: number[][], opt = { avoid: [0, 0, 0, 0], immediately: false }) {
278
- if (!points?.length) return;
279
-
280
- // 计算原始经纬度范围
281
- let west = Infinity,
282
- east = -Infinity,
283
- south = Infinity,
284
- north = -Infinity;
285
- points.forEach(([lng, lat]) => {
286
- west = Math.min(west, lng);
287
- east = Math.max(east, lng);
288
- south = Math.min(south, lat);
289
- north = Math.max(north, lat);
290
- });
291
-
292
- // 应用相对边距
293
- const [top, bottom, left, right] = opt.avoid;
294
- const lngSpan = east - west;
295
- const latSpan = north - south;
296
-
297
- const bounds = this.LbsAMap.Bounds(
298
- [west - lngSpan * left, south - latSpan * bottom],
299
- [east + lngSpan * right, north + latSpan * top],
300
- );
301
-
302
- this.viewer.setBounds(bounds, opt.immediately);
303
- }
304
-
305
- flyTo() {}
306
- }
1
+ import { MapCombine } from "../basic/MapCombine";
2
+ import { PointOption, Point } from "../basic/Point";
3
+ import { PointAggregationOption, PointAggregation } from "../basic/PointAggregation";
4
+ import { ReactPointOption, ReactPoint, drawReactPoint } from "../basic/ReactPoint";
5
+ import { PolylineOption, Polyline } from "../basic/Polyline";
6
+ import { PolygonOption, Polygon } from "../basic/Polygon";
7
+ import { Tile3DOption, Tile3D } from "../basic/Tile3D";
8
+
9
+ import AMapLoader from "./loader";
10
+ import { bindEvent } from "./AMapEvent";
11
+ import { drawPoint } from "./AMapPoint";
12
+ import { drawPolyline } from "./AMapPolyline";
13
+ import { drawPolygon } from "./AMapPolygon";
14
+
15
+ export interface IAMapOption {
16
+ container: HTMLDivElement;
17
+ url?: string | string[];
18
+ center?: number[];
19
+ zoom?: number;
20
+ maxZoom?: number;
21
+ minZoom?: number;
22
+ /** 地图瓦片转换规则 GCJ02 转 WGS84 */
23
+ proj?: "GCJ02->WGS84";
24
+ /** 高德地图 key */
25
+ key: string;
26
+ /** 高德地图 securityJsCode */
27
+ securityJsCode: string;
28
+ /** 加载的插件列表 */
29
+ plugins?: [string];
30
+ /** loader 配置参数 */
31
+ loaderOpt?: Object;
32
+ /** 地图初始化 配置参数 */
33
+ mapOpt?: Object;
34
+ }
35
+
36
+ export interface IFlyToViewerOpt {
37
+ /**
38
+ * 立即缩放到指定位置
39
+ */
40
+ immediately?: boolean;
41
+ /**
42
+ * (Array<number> = [0,0,0,0]) 距离边框的内边距,顺序:上、下、左、右
43
+ */
44
+ avoid?: [number, number, number, number];
45
+ /**
46
+ * 最大缩放级别
47
+ */
48
+ maxZoom?: number;
49
+ /**
50
+ * 动画时间
51
+ */
52
+ duration?: number;
53
+ }
54
+
55
+ export class AMap extends MapCombine {
56
+ viewer: any;
57
+ container: HTMLDivElement = null;
58
+ option: any = {};
59
+ offset: number[];
60
+ fov = 0.9272952180016121;
61
+ isFromLonLat = true;
62
+ LbsAMap: any;
63
+ get cursor(): string {
64
+ return this.container.style.cursor;
65
+ }
66
+ set cursor(val: string) {
67
+ this.container.style.cursor = val;
68
+ }
69
+
70
+ get moveable(): boolean {
71
+ return this.viewer?.getStatus()?.dragEnable;
72
+ }
73
+ set moveable(val: boolean) {
74
+ this.viewer?.setStatus({ dragEnable: val });
75
+ }
76
+
77
+ _center;
78
+
79
+ get center(): number[] {
80
+ return this.viewer?.getCenter();
81
+ }
82
+ set center(val: number[]) {
83
+ this._center = val;
84
+ this.viewer?.setCenter(val);
85
+ }
86
+ get zoom(): number {
87
+ return this.viewer?.getZoom();
88
+ }
89
+ set zoom(val: number) {
90
+ this.viewer?.setZoom(val);
91
+ }
92
+
93
+ constructor(viewer = undefined) {
94
+ super();
95
+ viewer && this._initParamsEvent(viewer);
96
+ }
97
+
98
+ private _initParamsEvent(viewer) {
99
+ if (!viewer) {
100
+ return;
101
+ }
102
+ this.viewer = viewer;
103
+
104
+ this.container = this.viewer.getContainer();
105
+ // this.markers = this.viewer.scene.primitives.add(new Cesium.BillboardCollection());
106
+
107
+ bindEvent(this);
108
+ }
109
+
110
+ init(opt: IAMapOption) {
111
+ this.option = opt;
112
+ const {
113
+ container,
114
+ center = [120.2288892, 30.2349677, 0],
115
+ zoom = 13,
116
+ url,
117
+ maxZoom,
118
+ minZoom,
119
+ proj,
120
+ key,
121
+ securityJsCode,
122
+ plugins,
123
+ } = opt || {};
124
+
125
+ this.loadPromise = new Promise((resolve, reject) => {
126
+ AMapLoader({
127
+ ...opt.loaderOpt,
128
+ key,
129
+ securityJsCode,
130
+ plugins,
131
+ })
132
+ .then((LbsAMap: any) => {
133
+ this.LbsAMap = LbsAMap;
134
+ let _urls = Array.isArray(url) ? url : [url];
135
+ this.viewer = new LbsAMap.Map(container, {
136
+ ...opt.mapOpt,
137
+ zoom: zoom || 14,
138
+ // _center 解决异步初始化 导致设置 center 无效的问题
139
+ center: this._center || center || [120.160217, 30.243861],
140
+ doubleClickZoom: false,
141
+ zooms: minZoom && maxZoom && [minZoom, maxZoom],
142
+ layers: url
143
+ ? _urls.map((it: any) => {
144
+ let opt = { tileUrl: "", getTileUrl: undefined };
145
+ if (typeof it === "string") {
146
+ opt.tileUrl = it;
147
+ } else {
148
+ opt = it;
149
+ }
150
+ // 使用 getTileUrl 解决接口地址强制改为 https 的问题
151
+ opt.getTileUrl = function (x, y, z) {
152
+ return opt.tileUrl.replace("{x}", x).replace("{y}", y).replace("{z}", z);
153
+ };
154
+
155
+ return new LbsAMap.TileLayer(opt);
156
+ })
157
+ : undefined,
158
+ });
159
+ this.viewer.on("complete", () => {
160
+ resolve(this);
161
+ });
162
+
163
+ this._initParamsEvent(this.viewer);
164
+ return this;
165
+ })
166
+ .catch(reject);
167
+ });
168
+ this.loadPromise.then(() => {
169
+ this.container.appendChild(this.htmllayer);
170
+ });
171
+ return this.loadPromise;
172
+ }
173
+
174
+ createPoint<K>(option?: Partial<PointOption<K>>): Point<K> {
175
+ const e = new Point(this, option);
176
+ this.loadPromise.then(() => {
177
+ drawPoint(this, e);
178
+ });
179
+ return e;
180
+ }
181
+
182
+ createPointAggregation(option?: PointAggregationOption): PointAggregation {
183
+ const e = new PointAggregation(this, option);
184
+ return e;
185
+ }
186
+
187
+ createReactPoint<K>(option?: Partial<ReactPointOption<K>>): ReactPoint<K> {
188
+ const e = new ReactPoint(this, option);
189
+ this.loadPromise.then(() => {
190
+ drawReactPoint(this, e);
191
+ });
192
+ return e;
193
+ }
194
+
195
+ createPolyline<K>(option?: Partial<PolylineOption<K>>): Polyline<K> {
196
+ const e = new Polyline(this, option);
197
+ this.loadPromise.then(() => {
198
+ drawPolyline(this, e);
199
+ });
200
+ return e;
201
+ }
202
+ createPolygon<K>(option?: Partial<PolygonOption<K>>): Polygon<K> {
203
+ const e = new Polygon(this, option);
204
+ this.loadPromise.then(() => {
205
+ drawPolygon(this, e);
206
+ });
207
+ return e;
208
+ }
209
+ createTile3D(option?: Partial<Tile3DOption>): Tile3D {
210
+ throw new Error("Method not implemented.");
211
+ }
212
+
213
+ /**
214
+ * 将高德地图 Canvas 像素坐标转换为经纬度
215
+ * @param {Array} p - canvas 点位数组 [x, y]
216
+ * @returns {Array} p - 经纬度数组 [lng, lat]
217
+ */
218
+ canvasTgeography(p: number[]) {
219
+ const mapInstance = this.viewer;
220
+ if (!mapInstance) {
221
+ this.loadPromise.then(() => {
222
+ this.canvasTgeography(p);
223
+ });
224
+ return [];
225
+ }
226
+ try {
227
+ const lngLat = this.viewer.lngLatToContainer(p);
228
+ return [lngLat.x, lngLat.y];
229
+ } catch (error) {
230
+ console.error("canvasPixelToLngLat 转换出错:", error);
231
+ return [];
232
+ }
233
+ }
234
+
235
+ /**
236
+ * 经纬度转换为高德地图 Canvas 像素坐标
237
+ * @param {Array} p - 经纬度数组 [lng, lat]
238
+ * @returns {Array} Canvas 像素坐标 [x, y]
239
+ */
240
+ geographyTcanvas(p: number[]): number[] {
241
+ const mapInstance = this.viewer;
242
+ if (!mapInstance) {
243
+ this.loadPromise.then(() => {
244
+ this.geographyTcanvas(p);
245
+ });
246
+ return [];
247
+ }
248
+ try {
249
+ const containerPixel = this.viewer.lngLatToContainer(p);
250
+ return [containerPixel.x, containerPixel.y];
251
+ } catch (error) {
252
+ console.error("lngLatToCanvasPixel 转换出错:", error);
253
+ return [];
254
+ }
255
+ }
256
+ /**
257
+ * 所有点位移动至视口,调整位置及层级
258
+ * @param points
259
+ * @param opt
260
+ * @param {Array<number> = [0,0,0,0]} opt.avoid 距离边框的内边距,顺序:上、下、左、右
261
+ */
262
+ flyToViewer(points: number[][], opt: IFlyToViewerOpt = { avoid: [0, 0, 0, 0], immediately: true }): void {
263
+ this.loadPromise.then(() => {
264
+ const [zoom, center] = this.viewer.getFitZoomAndCenterByBounds(
265
+ this.getBounds(points, { canvas: this.viewer.canvas, ...opt }),
266
+ opt?.avoid,
267
+ opt.maxZoom,
268
+ );
269
+
270
+ this.viewer.setZoomAndCenter(zoom, center, opt?.immediately, opt?.duration);
271
+ });
272
+ }
273
+
274
+ /**
275
+ * 将点集视野调整至容器内,支持相对边距(百分比)
276
+ * @param {number[][]} points - 经纬度数组 [[lng, lat], ...]
277
+ * @param {Object} opt
278
+ * @param {number[]} opt.avoid - 相对边距 [上, 下, 左, 右],取值范围 0~1,默认 [0,0,0,0]
279
+ * @param {boolean} opt.immediately - 是否立即跳转,默认 false(带动画)
280
+ */
281
+ flyToViewerPercent(points: number[][], opt = { avoid: [0, 0, 0, 0], immediately: false }) {
282
+ if (!points?.length) return;
283
+
284
+ // 计算原始经纬度范围
285
+ let west = Infinity,
286
+ east = -Infinity,
287
+ south = Infinity,
288
+ north = -Infinity;
289
+ points.forEach(([lng, lat]) => {
290
+ west = Math.min(west, lng);
291
+ east = Math.max(east, lng);
292
+ south = Math.min(south, lat);
293
+ north = Math.max(north, lat);
294
+ });
295
+
296
+ // 应用相对边距
297
+ const [top, bottom, left, right] = opt.avoid;
298
+ const lngSpan = east - west;
299
+ const latSpan = north - south;
300
+
301
+ const bounds = this.LbsAMap.Bounds(
302
+ [west - lngSpan * left, south - latSpan * bottom],
303
+ [east + lngSpan * right, north + latSpan * top],
304
+ );
305
+
306
+ this.viewer.setBounds(bounds, opt.immediately);
307
+ }
308
+
309
+ flyTo(point: number[], opt?: { immediately: false; duration: undefined }) {
310
+ const { immediately, duration } = opt || {};
311
+ this.viewer.setCenter(point, immediately, duration);
312
+ }
313
+ }