@sl-utils/map 1.0.2 → 1.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sl-utils/map",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "",
5
5
  "main": "index.cjs",
6
6
  "module": "./src/sl-utils-map.ts",
@@ -10,6 +10,7 @@
10
10
  "build:cjs": "tsc -p tsconfig.cjs.json"
11
11
  },
12
12
  "dependencies": {
13
+ "@amap/amap-jsapi-loader": "^1.0.1",
13
14
  "leaflet": "^1.9.4",
14
15
  "rbush": "^4.0.1"
15
16
  },
@@ -23,7 +24,7 @@
23
24
  "./package.json": "./package.json",
24
25
  ".": {
25
26
  "types": "./src/sl-utils-map.d.ts",
26
- "import": "./src/sl-utils-map.js"
27
+ "import": "./src/sl-utils-map.ts"
27
28
  }
28
29
  },
29
30
  "repository": {
@@ -0,0 +1,2 @@
1
+ export * from "./leaflet-tilelayer-wmts";
2
+ export * from "./slu-leaflet-net-map";
@@ -0,0 +1,98 @@
1
+ export function LeafletTilelayersWMTS(L: any) {
2
+ const LeafletTileLayerWMTS = L.TileLayer.extend({
3
+ defaultWmtsParams: {
4
+ service: 'wmts',
5
+ request: 'gettile',
6
+ version: '1.0.0',
7
+ layer: 'default',
8
+ style: 'default',
9
+ tilematrixset: 'basicsearoad',
10
+ // format: 'image/png'
11
+ // service: "WMTS",
12
+ // request: "GetTile",
13
+ // version: "1.0.0",
14
+ // layer: "",
15
+ // style: "default",
16
+ // tileMatrixSet: "",
17
+ // format: "image/jpeg",
18
+ },
19
+
20
+ initialize: function (url:any, options:any) { // (String, Object)
21
+ this._url = url;
22
+ var lOptions: any = {};
23
+ var cOptions = Object.keys(options);
24
+ cOptions.forEach(element => {
25
+ lOptions[element.toLowerCase()] = options[element];
26
+ });
27
+ var wmtsParams = L.extend({}, this.defaultWmtsParams);
28
+ var tileSize = lOptions.tileSize || this.options.tileSize;
29
+ if (lOptions.detectRetina && L.Browser.retina) {
30
+ wmtsParams.width = wmtsParams.height = tileSize * 2;
31
+ } else {
32
+ wmtsParams.width = wmtsParams.height = tileSize;
33
+ }
34
+ for (var i in lOptions) {
35
+ // all keys that are in defaultWmtsParams options go to WMTS params
36
+ if (wmtsParams.hasOwnProperty(i) && i != "matrixIds") {
37
+ wmtsParams[i] = lOptions[i];
38
+ }
39
+ }
40
+ this.wmtsParams = wmtsParams;
41
+ this.matrixIds = options.matrixIds || this.getDefaultMatrix();
42
+ L.setOptions(this, options);
43
+ },
44
+
45
+ onAdd: function (map:any) {
46
+ this._crs = this.options.crs || map.options.crs;
47
+ L.TileLayer.prototype.onAdd.call(this, map);
48
+ },
49
+
50
+ getTileUrl: function (coords:any) { // (Point, Number) -> String
51
+ var tileSize = this.options.tileSize;
52
+ var nwPoint = coords.multiplyBy(tileSize);
53
+ nwPoint.x += 1;
54
+ nwPoint.y -= 1;
55
+ var sePoint = nwPoint.add(new L.Point(tileSize, tileSize));
56
+ var zoom = this._tileZoom;
57
+ var nw = this._crs.project(this._map.unproject(nwPoint, zoom));
58
+ var se = this._crs.project(this._map.unproject(sePoint, zoom));
59
+ var tilewidth = se.x - nw.x;
60
+ var ident = this.matrixIds[zoom].identifier;
61
+ // var tilematrix = this.wmtsParams.tilematrixset + ":" + ident;
62
+ var tilematrix = ident;
63
+ var X0 = this.matrixIds[zoom].topLeftCorner.lng;
64
+ var Y0 = this.matrixIds[zoom].topLeftCorner.lat;
65
+ var tilecol = Math.floor((nw.x - X0) / tilewidth);
66
+ var tilerow = -Math.floor((nw.y - Y0) / tilewidth);
67
+ var url = L.Util.template(this._url, { s: this._getSubdomain(coords) });
68
+ return url + L.Util.getParamString(this.wmtsParams, url) + "&tilematrix=" + tilematrix + "&tilerow=" + tilerow + "&tilecol=" + tilecol;
69
+ },
70
+
71
+ setParams: function (params:any, noRedraw:any) {
72
+ L.extend(this.wmtsParams, params);
73
+ if (!noRedraw) {
74
+ this.redraw();
75
+ }
76
+ return this;
77
+ },
78
+
79
+ getDefaultMatrix: function () {
80
+ /**
81
+ * the matrix3857 represents the projection
82
+ * for in the IGN WMTS for the google coordinates.
83
+ */
84
+ var matrixIds3857 = new Array(22);
85
+ for (var i = 0; i < 22; i++) {
86
+ matrixIds3857[i] = {
87
+ identifier: "" + i,
88
+ topLeftCorner: new L.LatLng(20037508.3428, -20037508.3428)
89
+ };
90
+ }
91
+ return matrixIds3857;
92
+ }
93
+ });
94
+
95
+ return function (url: string, options: any) {
96
+ return new LeafletTileLayerWMTS(url, options);
97
+ };
98
+ }
@@ -0,0 +1,232 @@
1
+ import * as L from "leaflet";
2
+ import 'proj4leaflet';
3
+ import { u_mapTogps84bd09, u_mapTogps84gcj02 } from "../utils/slu-map";
4
+ 'use strict';
5
+ /**坐标转换关键代码(加载后GridLayer自行转换) */
6
+ (function (window, document) {
7
+ L.GridLayer.include({
8
+ _setZoomTransform: function (level: any, _center: { lng: number, lat: number }, zoom: number) {
9
+ var center = _center;
10
+ if (center != undefined && this.options) {
11
+ if (this.options.corrdType == 'gcj02') {
12
+ center = u_mapTogps84gcj02(_center.lng, _center.lat);
13
+ } else if (this.options.corrdType == 'bd09') {
14
+ center = u_mapTogps84bd09(_center.lng, _center.lat);
15
+ }
16
+ }
17
+ var scale = this._map.getZoomScale(zoom, level.zoom),
18
+ translate = level.origin.multiplyBy(scale)
19
+ .subtract(this._map._getNewPixelOrigin(center, zoom)).round();
20
+
21
+ if (L.Browser.any3d) {
22
+ L.DomUtil.setTransform(level.el, translate, scale);
23
+ } else {
24
+ L.DomUtil.setPosition(level.el, translate);
25
+ }
26
+ },
27
+ _getTiledPixelBounds: function (_center: { lng: number, lat: number }) {
28
+ var center = _center;
29
+ if (center != undefined && this.options) {
30
+ if (this.options.corrdType == 'gcj02') {
31
+ center = u_mapTogps84gcj02(_center.lng, _center.lat);
32
+ } else if (this.options.corrdType == 'bd09') {
33
+ center = u_mapTogps84bd09(_center.lng, _center.lat);
34
+ }
35
+ }
36
+ var map = this._map,
37
+ mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
38
+ scale = map.getZoomScale(mapZoom, this._tileZoom),
39
+ pixelCenter = map.project(center, this._tileZoom).floor(),
40
+ halfSize = map.getSize().divideBy(scale * 2);
41
+ return new L.Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
42
+ }
43
+ })
44
+ }(this, document))
45
+ /**地图的名称
46
+ * tianDiTu 天地图 gaoDe 高德 baiDu 百度 google 谷歌
47
+ * Normal 矢量地图 Satellite 卫星图
48
+ * Map地图 Annotion地名
49
+ */
50
+ export enum SLEMap {
51
+ tianDiTuNormalMap = 'TianDiTu.Normal.Map',
52
+ tianDiTuNormalAnnotion = 'TianDiTu.Normal.Annotion',
53
+ tianDiTuSatelliteMap = 'TianDiTu.Satellite.Map',
54
+ tianDiTuSatelliteAnnotion = 'TianDiTu.Satellite.Annotion',
55
+ tianDiTuTerrainMap = 'TianDiTu.Terrain.Map',
56
+ tianDiTuTerrainAnnotion = 'TianDiTu.Terrain.Annotion',
57
+ /**gaoDe 高德*/
58
+ gaoDeNormalMap = 'GaoDe.Normal.Map',
59
+ gaoDeSatelliteMap = 'GaoDe.Satellite.Map',
60
+ gaoDeSatelliteAnnotion = 'GaoDe.Satellite.Annotion',
61
+ /**百度 */
62
+ baiDuNormalMap = 'Baidu.Normal.Map',
63
+ baiDuSatelliteMap = 'Baidu.Satellite.Map',
64
+ baiDuSatelliteAnnotion = 'Baidu.Satellite.Annotion',
65
+ /**谷歌 */
66
+ googleNormalMap = 'Google.Normal.Map',
67
+ googleSatelliteMap = 'Google.Satellite.Map',
68
+ googleSatelliteAnnotion = 'Google.Satellite.Annotion',
69
+
70
+ geoqNormalMap = 'Geoq.Normal.Map',
71
+ geoqNormalPurplishBlue = 'Geoq.Normal.PurplishBlue',
72
+ geoqNormalGray = 'Geoq.Normal.Gray',
73
+ geoqNormalWarm = 'Geoq.Normal.Warm',
74
+ geoqThemeHydro = 'Geoq.Theme.Hydro',
75
+
76
+ oSMNormalMap = 'OSM.Normal.Map',
77
+ }
78
+ /**网络地图图层配置项 */
79
+ export interface SLPMapLeafletLayer extends L.TileLayerOptions {
80
+ /**个人地图凭证token */
81
+ key?: string;
82
+ /**地图采用的坐标系信息(根据地图名称自动匹配) */
83
+ corrdType?: string;
84
+ }
85
+ /**加载网络地图 并通过坐标转换使瓦片偏移解决地图偏移问题
86
+ * @param name 网络地图名称SLEMap
87
+ * @param options 地图配置
88
+ */
89
+ export class SLULeafletNetMap {
90
+ constructor(name: SLEMap, options?: SLPMapLeafletLayer) {
91
+ this.setMapProvider(name, options);
92
+ }
93
+ private map!: L.Map;
94
+ /**地图图层 */
95
+ private mapLayer!: L.Layer;
96
+ /**将图层添加到map显示在页面 */
97
+ public addTo(map: L.Map) {
98
+ if (!map) return this;
99
+ this.map = map;
100
+ this.mapLayer?.addTo(this.map)
101
+ return this;
102
+ }
103
+ /**从map中移除当前图层 */
104
+ public remove() {
105
+ this.mapLayer?.remove();
106
+ return this;
107
+ }
108
+ /**变更当前图层并添加到map中 */
109
+ public changeMap(name: SLEMap, options?: SLPMapLeafletLayer) {
110
+ this.remove();
111
+ this.setMapProvider(name, options);
112
+ this.addTo(this.map);
113
+ return this;
114
+ }
115
+ /**设置map的地图来源,名称,类型 */
116
+ private setMapProvider(name: SLEMap, options?: SLPMapLeafletLayer) { // (type, Object)
117
+ options = options || {}
118
+ let parts = name.split('.'), mapSource = parts[0], mapName = parts[1], mapType = parts[2];
119
+ let url = MAPINFO[mapSource][mapName][mapType];
120
+ options.subdomains = MAPINFO[mapSource].Subdomains;
121
+ options.key = options.key || MAPINFO[mapSource].key;
122
+ options.corrdType = this.getCorrdType(mapSource);
123
+ if ('tms' in MAPINFO[mapSource]) {
124
+ options.tms = MAPINFO[mapSource]['tms']
125
+ }
126
+ this.mapLayer = new L.TileLayer(url, options);
127
+ }
128
+ /**获取坐标转换类型*/
129
+ private getCorrdType(name: string) {
130
+ var zbName = "wgs84"
131
+ switch (name) {
132
+ case "Geoq":
133
+ case "GaoDe":
134
+ case "Google":
135
+ zbName = "gcj02";
136
+ break;
137
+ case "Baidu":
138
+ zbName = "bd09";
139
+ break;
140
+ case "OSM":
141
+ case "TianDiTu":
142
+ zbName = "wgs84";
143
+ break;
144
+ }
145
+ return zbName;
146
+ }
147
+ }
148
+ /**地图信息 S子域 X经度 Y纬度 Z层级 */
149
+ const MAPINFO: any = {
150
+ TianDiTu: {
151
+ Normal: {
152
+ Map: "//t{s}.tianditu.com/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk={key}",
153
+ Annotion: "//t{s}.tianditu.com/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk={key}",
154
+ AnnotionEn: "//t{s}.tianditu.com/DataServer?T=eva_w&X={x}&Y={y}&L={z}&tk={key}"
155
+ },
156
+ Satellite: {
157
+ Map: "//t{s}.tianditu.com/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk={key}",
158
+ Annotion: "//t{s}.tianditu.com/DataServer?T=cia_w&X={x}&Y={y}&L={z}&tk={key}"
159
+ },
160
+ Terrain: {
161
+ Map: "//t{s}.tianditu.com/DataServer?T=ter_w&X={x}&Y={y}&L={z}&tk={key}",
162
+ Annotion: "//t{s}.tianditu.com/DataServer?T=cta_w&X={x}&Y={y}&L={z}&tk={key}"
163
+ },
164
+ // Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
165
+ Subdomains: ['1'],
166
+ key: "a9e2dd65c94fab979c9d897ff7098a4c"
167
+ },
168
+ GaoDe: {
169
+ Normal: {
170
+ Map: '//webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
171
+ },
172
+ Satellite: {
173
+ Map: '//webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
174
+ Annotion: '//webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}'
175
+ },
176
+ Subdomains: ["1", "2", "3", "4"]
177
+ },
178
+ Google: {
179
+ Normal: {
180
+ Map: "//www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}"
181
+ },
182
+ Satellite: {
183
+ Map: "//www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}",
184
+ Annotion: "//www.google.cn/maps/vt?lyrs=y@189&gl=cn&x={x}&y={y}&z={z}"
185
+ },
186
+ Subdomains: []
187
+ },
188
+ Geoq: {
189
+ Normal: {
190
+ Map: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}",
191
+ PurplishBlue: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
192
+ Gray: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}",
193
+ Warm: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetWarm/MapServer/tile/{z}/{y}/{x}",
194
+ },
195
+ Theme: {
196
+ Hydro: "//thematic.geoq.cn/arcgis/rest/services/ThematicMaps/WorldHydroMap/MapServer/tile/{z}/{y}/{x}"
197
+ },
198
+ Subdomains: []
199
+ },
200
+ OSM: {
201
+ Normal: {
202
+ Map: "//{s}.tile.osm.org/{z}/{x}/{y}.png",
203
+ },
204
+ Subdomains: ['a', 'b', 'c']
205
+ },
206
+ Baidu: {
207
+ Normal: {
208
+ Map: '//online{s}.map.bdimg.com/onlinelabel/qt=tile&x={x}&y={y}&z={z}'
209
+ },
210
+ Satellite: {
211
+ Map: '//online{s}.map.bdimg.com/starpic/?qt=satepc&u=x={x}&y={y}&z={z};v=009;type=sate&fm=46&app=webearth2&v=009&udt=20231212',
212
+ Annotion: '//online{s}.map.bdimg.com/starpic/?qt=satepc&u=x={x}&y={y}&z={z};v=009;type=sate&fm=46&app=webearth2&v=009&udt=20231212'
213
+ },
214
+ Subdomains: '0123456789',
215
+ tms: true
216
+ }
217
+ }
218
+ export const SLCRS = {
219
+ "Baidu": new (L as any).Proj.CRS('EPSG:900913', '+proj=merc +a=6378206 +b=6356584.314245179 +lat_ts=0.0 +lon_0=0.0 +x_0=0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs', {
220
+ resolutions: function () {
221
+ let level = 18
222
+ let res: number[] = [];
223
+ res[0] = Math.pow(2, 18);
224
+ for (var i = 1; i < level; i++) {
225
+ res[i] = Math.pow(2, (18 - i))
226
+ }
227
+ return res;
228
+ }(),
229
+ origin: [0, 0],
230
+ bounds: L.bounds([20037508.342789244, 0], [0, 20037508.342789244])
231
+ })
232
+ }
@@ -1 +1,127 @@
1
- export { MapCanvasDraw } from './map/canvas-draw'
1
+ export { MapCanvasDraw } from './map/canvas-draw'
2
+ import { CRS, Map, latLng } from "leaflet";
3
+ import * as AMapLoader from '@amap/amap-jsapi-loader';
4
+ import { SLCRS, SLEMap, SLULeafletNetMap } from './leaflet';
5
+ declare var AMap: any;
6
+
7
+ export class SLUMap {
8
+ constructor(ele: string)
9
+ constructor(ele: string)
10
+ constructor(ele: string, options: Partial<SLSMapOpt> = {}) {
11
+ this.createMap(ele, options)
12
+ }
13
+
14
+ private map: L.Map | AMAP.Map;
15
+ /**当前正在显示的网络图层 */
16
+ private curs: Partial<{ [key in SLEMap]: SLULeafletNetMap | undefined }> = Object.create(null);
17
+
18
+ /**显示指定的网络图层 */
19
+ public showMap(names: Array<SLEMap> = []): this {
20
+ const { map, curs } = this;
21
+ if (map && map instanceof Map) {
22
+ let mapSource: string = names[0].split('.')[0]
23
+ let center = map.getCenter();
24
+ let zoom = map.getZoom();
25
+ map.options.crs = mapSource === 'Baidu' ? SLCRS.Baidu : CRS.EPSG3857; // 根据图层坐标系设置
26
+ (map as any)._resetView(center, zoom, true);
27
+ names?.forEach(name => {
28
+ if (curs[name]) return;
29
+ let net = new SLULeafletNetMap(name)
30
+ net.addTo(map);
31
+ curs[name] = net;
32
+ });
33
+ for (const key in curs) {
34
+ let name:SLEMap = key as SLEMap;
35
+ let flag = names.includes(name);
36
+ if (flag) continue;
37
+ curs[name].remove();
38
+ Reflect.deleteProperty(curs, key)
39
+ }
40
+ }
41
+ return this
42
+ }
43
+ private async createMap(ele: string, options: Partial<SLSMapOpt>) {
44
+ const { type } = options;
45
+ let map: L.Map | AMAP.Map;
46
+ switch (type) {
47
+ case "A": this.map = await this.initAmap(ele, options); break;
48
+ default: this.map = await this.initLeaflet(ele, options);
49
+ this.showMap([SLEMap.tianDiTuNormalMap, SLEMap.tianDiTuNormalAnnotion]);
50
+ break;
51
+ }
52
+ }
53
+ /**---------------leaflet地图的相关方法------------------- */
54
+ private initLeaflet(ele: string, opt: Partial<SLSMapOpt>) {
55
+ const { zoom = 11, minZoom = 2, maxZoom = 20, center: [lat, lng] = [22.68471, 114.12027], dragging = true, zoomControl = false, attributionControl = false, doubleClickZoom = false, closePopupOnClick = false } = opt;
56
+ let param: L.MapOptions = {
57
+ dragging,
58
+ zoomControl,
59
+ zoom,
60
+ minZoom,
61
+ maxZoom,
62
+ center: latLng(lat, lng),
63
+ attributionControl,
64
+ doubleClickZoom,
65
+ crs: CRS.EPSG3857,
66
+ closePopupOnClick,//点击地图不关闭弹出层
67
+ };
68
+ let map = new Map(ele, param);
69
+ return Promise.resolve(map)
70
+ }
71
+ /**---------------高德地图的相关方法------------------- */
72
+ private async initAmap(ele: string, opt: Partial<SLSMapOpt>) {
73
+ const { zoom = 11, minZoom = 2, maxZoom = 20, center: [lat, lng] = [22.68471, 114.12027], dragging = true, zoomControl = false, attributionControl = false, doubleClickZoom = false, closePopupOnClick = false, showLabel = true } = opt;
74
+ return AMapLoader.load({
75
+ "key": "87e1b1e9aa88724f69208972546fdd57", // 申请好的Web端开发者Key,首次调用 load 时必填
76
+ "version": "1.4.15", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
77
+ "plugins": ["Map3D"] //插件列表
78
+ }).then(() => {
79
+ // initAMapUI();
80
+ let map = new AMap.Map(ele, {
81
+ // mask: mask,
82
+ center: [lng, lat],
83
+ disableSocket: true,
84
+ viewMode: '2D',
85
+ mapStyle: 'amap://styles/dfd45346264e1fa2bb3b796f36cab42a',
86
+ skyColor: "#A3CCFF",
87
+ lang: 'zh_cn', //设置地图语言类型
88
+ labelzIndex: 130,
89
+ pitch: 40,
90
+ zoom: zoom,
91
+ zooms: [minZoom, maxZoom],
92
+ dragEnable: dragging,
93
+ doubleClickZoom: doubleClickZoom,
94
+ keyboardEnable: false,
95
+ isHotspot: false,
96
+ showLabel,
97
+ layers: [],
98
+ });
99
+ return map;
100
+ })
101
+ }
102
+ }
103
+
104
+ interface SLSMapOpt {
105
+ /**地图的类型 @param L leaflet插件 @param A 高德地图 @param B 百度地图 @default L*/
106
+ type: 'L' | 'A' | 'B',
107
+ /**地图中心点 [lat,lng] @default [22.68471,114.12027] */
108
+ center: [number, number],
109
+ /**地图初始层级 @default 11*/
110
+ zoom: number,
111
+ /**最小层级 @default 2*/
112
+ minZoom: number,
113
+ /**最大层级 @default 20*/
114
+ maxZoom: number,
115
+ /**拖拽功能 @default true */
116
+ dragging: boolean,
117
+ /**显示层级控制器 @default false */
118
+ zoomControl: boolean,
119
+ /**显示属性控制器 @default false */
120
+ attributionControl: boolean,
121
+ /**双击放大层级 @default false */
122
+ doubleClickZoom: boolean,
123
+ /**点击关闭弹窗 @default false */
124
+ closePopupOnClick: boolean,
125
+ /**显示标签(省会、地名等) @param AMap @default true */
126
+ showLabel: boolean,
127
+ }