@hzab/map-combine 0.0.1 → 0.1.2
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 +5 -0
- package/package.json +2 -2
- package/src/basic/BasicBusiness.ts +72 -0
- package/src/basic/BasicElement.ts +35 -0
- package/src/basic/BasicMarker.ts +45 -0
- package/src/basic/MapCombine.ts +11 -1
- package/src/basic/MapElement.ts +15 -17
- package/src/basic/ReactPopup.tsx +24 -1
- package/src/basic/Tile3D.ts +76 -41
- package/src/cesium/CesiumEvent.ts +18 -29
- package/src/cesium/CesiumMap.ts +148 -53
- package/src/cesium/CesiumTile3D.ts +184 -55
- package/src/cesium/cesium-tile-covert/index.js +48 -0
- package/src/cesium/cesium-tile-covert/modules/index.js +12 -0
- package/src/cesium/cesium-tile-covert/modules/projection/BD09Projection.js +377 -0
- package/src/cesium/cesium-tile-covert/modules/provider/AMapImageryProvider.js +27 -0
- package/src/cesium/cesium-tile-covert/modules/provider/BaiduImageryProvider.js +58 -0
- package/src/cesium/cesium-tile-covert/modules/provider/GeoVisImageryProvider.js +25 -0
- package/src/cesium/cesium-tile-covert/modules/provider/GoogleImageryProvider.js +27 -0
- package/src/cesium/cesium-tile-covert/modules/provider/TdtImageryProvider.js +23 -0
- package/src/cesium/cesium-tile-covert/modules/provider/TencentImageryProvider.js +41 -0
- package/src/cesium/cesium-tile-covert/modules/tiling-scheme/BD09TilingScheme.js +100 -0
- package/src/cesium/cesium-tile-covert/modules/tiling-scheme/CustomGeographicTilingScheme.js +60 -0
- package/src/cesium/cesium-tile-covert/modules/tiling-scheme/CustomMercatorTilingScheme.js +70 -0
- package/src/cesium/cesium-tile-covert/modules/tiling-scheme/GCJ02TilingScheme.js +33 -0
- package/src/cesium/cesium-tile-covert/modules/transform/CoordTransform.js +148 -0
- package/src/openlayer/OpenlayerMap.ts +82 -27
- package/src/openlayer/openlayer-tile-gcj02-wgs84.js +144 -0
- package/src/utils/index.ts +15 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author: Caven Chen
|
|
3
|
+
* @Date: 2020-01-15
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { GeographicTilingScheme, Math: CesiumMath, Cartesian2, Rectangle, defined } = Cesium;
|
|
7
|
+
|
|
8
|
+
class CustomGeographicTilingScheme extends GeographicTilingScheme {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
super(options);
|
|
11
|
+
this._origin = options.origin || [-180, 90];
|
|
12
|
+
this._zoomOffset = options.zoomOffset || 0;
|
|
13
|
+
this._tileSize = options.tileSize || 256;
|
|
14
|
+
this._resolutions = options.resolutions || [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get zoomOffset() {
|
|
18
|
+
return this._zoomOffset;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
tileXYToRectangle(x, y, level, result) {
|
|
22
|
+
if (!this._resolutions || !this._resolutions[level + this._zoomOffset]) {
|
|
23
|
+
return Rectangle.MAX_VALUE;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const tileRes = this._resolutions[level + this._zoomOffset] * this._tileSize;
|
|
27
|
+
const west = CesiumMath.toRadians(this._origin[0] + x * tileRes);
|
|
28
|
+
const south = CesiumMath.toRadians(this._origin[1] - (y + 1) * tileRes);
|
|
29
|
+
const east = CesiumMath.toRadians(this._origin[0] + (x + 1) * tileRes);
|
|
30
|
+
const north = CesiumMath.toRadians(this._origin[1] - y * tileRes);
|
|
31
|
+
if (!defined(result)) {
|
|
32
|
+
return new Rectangle(west, south, east, north);
|
|
33
|
+
}
|
|
34
|
+
result.west = west;
|
|
35
|
+
result.south = south;
|
|
36
|
+
result.east = east;
|
|
37
|
+
result.north = north;
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
positionToTileXY(position, level, result) {
|
|
42
|
+
if (!this._resolutions || !this._resolutions[level + this._zoomOffset]) {
|
|
43
|
+
return new Cartesian2();
|
|
44
|
+
}
|
|
45
|
+
const tileRes = this._resolutions[level + this._zoomOffset] * this._tileSize;
|
|
46
|
+
const longitude = CesiumMath.toDegrees(position.longitude);
|
|
47
|
+
const latitude = CesiumMath.toDegrees(position.latitude);
|
|
48
|
+
// Calculate the tile row and column numbers in the current coordinate system
|
|
49
|
+
const xTileCoordinate = Math.floor((longitude - this._origin[0]) / tileRes);
|
|
50
|
+
const yTileCoordinate = Math.floor((this._origin[1] - latitude) / tileRes);
|
|
51
|
+
if (!defined(result)) {
|
|
52
|
+
return new Cartesian2(Math.max(0, xTileCoordinate), Math.max(0, yTileCoordinate));
|
|
53
|
+
}
|
|
54
|
+
result.x = xTileCoordinate;
|
|
55
|
+
result.y = yTileCoordinate;
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default CustomGeographicTilingScheme;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author: Caven Chen
|
|
3
|
+
* @Date: 2020-01-15
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { WebMercatorTilingScheme, Cartesian2, Rectangle, defined } = Cesium;
|
|
7
|
+
|
|
8
|
+
class CustomMercatorTilingScheme extends WebMercatorTilingScheme {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
super(options);
|
|
11
|
+
this._origin = options.origin || [-20037508.3427892, 20037508.3427892];
|
|
12
|
+
this._zoomOffset = options.zoomOffset || 0;
|
|
13
|
+
this._tileSize = options.tileSize || 256;
|
|
14
|
+
this._resolutions = options.resolutions || [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get zoomOffset() {
|
|
18
|
+
return this._zoomOffset;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
tileXYToNativeRectangle(x, y, level, result) {
|
|
22
|
+
if (!this._resolutions || !this._resolutions[level + this._zoomOffset]) {
|
|
23
|
+
return Rectangle.MAX_VALUE;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (x < 0 || y < 0) {
|
|
27
|
+
return Rectangle.MAX_VALUE;
|
|
28
|
+
}
|
|
29
|
+
const tileRes = this._resolutions[level + this._zoomOffset] * this._tileSize;
|
|
30
|
+
let west = this._origin[0] + x * tileRes;
|
|
31
|
+
let south = this._origin[1] - (y + 1) * tileRes;
|
|
32
|
+
let east = this._origin[0] + (x + 1) * tileRes;
|
|
33
|
+
let north = this._origin[1] - y * tileRes;
|
|
34
|
+
|
|
35
|
+
if (!defined(result)) {
|
|
36
|
+
return new Rectangle(west, south, east, north);
|
|
37
|
+
}
|
|
38
|
+
result.west = west;
|
|
39
|
+
result.south = south;
|
|
40
|
+
result.east = east;
|
|
41
|
+
result.north = north;
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
positionToTileXY(position, level, result) {
|
|
46
|
+
const rectangle = this._rectangle;
|
|
47
|
+
if (!Rectangle.contains(rectangle, position)) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
if (!this._resolutions || !this._resolutions[level + this._zoomOffset]) {
|
|
51
|
+
return new Cartesian2();
|
|
52
|
+
}
|
|
53
|
+
const tileRes = this._resolutions[level + this._zoomOffset] * this._tileSize;
|
|
54
|
+
const projection = this._projection;
|
|
55
|
+
const webMercatorPosition = projection.project(position);
|
|
56
|
+
|
|
57
|
+
// Calculate the tile row and column numbers in the current coordinate system
|
|
58
|
+
const xTileCoordinate = Math.floor((webMercatorPosition.x - this._origin[0]) / tileRes);
|
|
59
|
+
|
|
60
|
+
const yTileCoordinate = Math.floor((this._origin[1] - webMercatorPosition.y) / tileRes);
|
|
61
|
+
if (!defined(result)) {
|
|
62
|
+
return new Cartesian2(Math.max(0, xTileCoordinate), Math.max(0, yTileCoordinate));
|
|
63
|
+
}
|
|
64
|
+
result.x = xTileCoordinate;
|
|
65
|
+
result.y = yTileCoordinate;
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default CustomMercatorTilingScheme;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author: Caven Chen
|
|
3
|
+
* @Date: 2020-01-15
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import CoordTransform from "../transform/CoordTransform.js";
|
|
7
|
+
|
|
8
|
+
const { WebMercatorTilingScheme, WebMercatorProjection, Math: CesiumMath, Cartographic, Cartesian2 } = Cesium;
|
|
9
|
+
|
|
10
|
+
class GCJ02TilingScheme extends WebMercatorTilingScheme {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
super(options);
|
|
13
|
+
let projection = new WebMercatorProjection();
|
|
14
|
+
this._projection.project = function (cartographic, result) {
|
|
15
|
+
result = CoordTransform.WGS84ToGCJ02(
|
|
16
|
+
CesiumMath.toDegrees(cartographic.longitude),
|
|
17
|
+
CesiumMath.toDegrees(cartographic.latitude),
|
|
18
|
+
);
|
|
19
|
+
result = projection.project(new Cartographic(CesiumMath.toRadians(result[0]), CesiumMath.toRadians(result[1])));
|
|
20
|
+
return new Cartesian2(result.x, result.y);
|
|
21
|
+
};
|
|
22
|
+
this._projection.unproject = function (cartesian, result) {
|
|
23
|
+
let cartographic = projection.unproject(cartesian);
|
|
24
|
+
result = CoordTransform.GCJ02ToWGS84(
|
|
25
|
+
CesiumMath.toDegrees(cartographic.longitude),
|
|
26
|
+
CesiumMath.toDegrees(cartographic.latitude),
|
|
27
|
+
);
|
|
28
|
+
return new Cartographic(CesiumMath.toRadians(result[0]), CesiumMath.toRadians(result[1]));
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default GCJ02TilingScheme;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author: Caven
|
|
3
|
+
* @Date: 2021-01-31 20:40:25
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
7
|
+
const BD_FACTOR = (3.14159265358979324 * 3000.0) / 180.0;
|
|
8
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
9
|
+
const PI = 3.1415926535897932384626;
|
|
10
|
+
const RADIUS = 6378245.0;
|
|
11
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
12
|
+
const EE = 0.00669342162296594323;
|
|
13
|
+
|
|
14
|
+
class CoordTransform {
|
|
15
|
+
/**
|
|
16
|
+
* BD-09 To GCJ-02
|
|
17
|
+
* @param lng
|
|
18
|
+
* @param lat
|
|
19
|
+
* @returns {number[]}
|
|
20
|
+
*/
|
|
21
|
+
static BD09ToGCJ02(lng, lat) {
|
|
22
|
+
let x = +lng - 0.0065;
|
|
23
|
+
let y = +lat - 0.006;
|
|
24
|
+
let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR);
|
|
25
|
+
let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_FACTOR);
|
|
26
|
+
let gg_lng = z * Math.cos(theta);
|
|
27
|
+
let gg_lat = z * Math.sin(theta);
|
|
28
|
+
return [gg_lng, gg_lat];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* GCJ-02 To BD-09
|
|
33
|
+
* @param lng
|
|
34
|
+
* @param lat
|
|
35
|
+
* @returns {number[]}
|
|
36
|
+
* @constructor
|
|
37
|
+
*/
|
|
38
|
+
static GCJ02ToBD09(lng, lat) {
|
|
39
|
+
lat = +lat;
|
|
40
|
+
lng = +lng;
|
|
41
|
+
let z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * BD_FACTOR);
|
|
42
|
+
let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_FACTOR);
|
|
43
|
+
let bd_lng = z * Math.cos(theta) + 0.0065;
|
|
44
|
+
let bd_lat = z * Math.sin(theta) + 0.006;
|
|
45
|
+
return [bd_lng, bd_lat];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* WGS-84 To GCJ-02
|
|
50
|
+
* @param lng
|
|
51
|
+
* @param lat
|
|
52
|
+
* @returns {number[]}
|
|
53
|
+
*/
|
|
54
|
+
static WGS84ToGCJ02(lng, lat) {
|
|
55
|
+
lat = +lat;
|
|
56
|
+
lng = +lng;
|
|
57
|
+
if (this.out_of_china(lng, lat)) {
|
|
58
|
+
return [lng, lat];
|
|
59
|
+
} else {
|
|
60
|
+
let d = this.delta(lng, lat);
|
|
61
|
+
return [lng + d[0], lat + d[1]];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* GCJ-02 To WGS-84
|
|
67
|
+
* @param lng
|
|
68
|
+
* @param lat
|
|
69
|
+
* @returns {number[]}
|
|
70
|
+
* @constructor
|
|
71
|
+
*/
|
|
72
|
+
static GCJ02ToWGS84(lng, lat) {
|
|
73
|
+
lat = +lat;
|
|
74
|
+
lng = +lng;
|
|
75
|
+
if (this.out_of_china(lng, lat)) {
|
|
76
|
+
return [lng, lat];
|
|
77
|
+
} else {
|
|
78
|
+
let d = this.delta(lng, lat);
|
|
79
|
+
let mgLng = lng + d[0];
|
|
80
|
+
let mgLat = lat + d[1];
|
|
81
|
+
return [lng * 2 - mgLng, lat * 2 - mgLat];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* @param lng
|
|
88
|
+
* @param lat
|
|
89
|
+
* @returns {number[]}
|
|
90
|
+
*/
|
|
91
|
+
static delta(lng, lat) {
|
|
92
|
+
let dLng = this.transformLng(lng - 105, lat - 35);
|
|
93
|
+
let dLat = this.transformLat(lng - 105, lat - 35);
|
|
94
|
+
const radLat = (lat / 180) * PI;
|
|
95
|
+
let magic = Math.sin(radLat);
|
|
96
|
+
magic = 1 - EE * magic * magic;
|
|
97
|
+
const sqrtMagic = Math.sqrt(magic);
|
|
98
|
+
dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI);
|
|
99
|
+
dLat = (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI);
|
|
100
|
+
return [dLng, dLat];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
*
|
|
105
|
+
* @param lng
|
|
106
|
+
* @param lat
|
|
107
|
+
* @returns {number}
|
|
108
|
+
*/
|
|
109
|
+
static transformLng(lng, lat) {
|
|
110
|
+
lat = +lat;
|
|
111
|
+
lng = +lng;
|
|
112
|
+
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
|
|
113
|
+
ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
|
|
114
|
+
ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
|
|
115
|
+
ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
|
|
116
|
+
return ret;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
* @param lng
|
|
122
|
+
* @param lat
|
|
123
|
+
* @returns {number}
|
|
124
|
+
*/
|
|
125
|
+
static transformLat(lng, lat) {
|
|
126
|
+
lat = +lat;
|
|
127
|
+
lng = +lng;
|
|
128
|
+
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
|
|
129
|
+
ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
|
|
130
|
+
ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
|
|
131
|
+
ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
|
|
132
|
+
return ret;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
*
|
|
137
|
+
* @param lng
|
|
138
|
+
* @param lat
|
|
139
|
+
* @returns {boolean}
|
|
140
|
+
*/
|
|
141
|
+
static out_of_china(lng, lat) {
|
|
142
|
+
lat = +lat;
|
|
143
|
+
lng = +lng;
|
|
144
|
+
return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export default CoordTransform;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { MapCombine } from "../basic/MapCombine";
|
|
2
2
|
import { PointOption, Point } from "../basic/Point";
|
|
3
3
|
import Map from "ol/Map.js";
|
|
4
|
+
import View from "ol/View";
|
|
5
|
+
import XYZ from "ol/source/XYZ";
|
|
6
|
+
import Tile from "ol/layer/Tile";
|
|
4
7
|
import DragPan from "ol/interaction/DragPan";
|
|
5
8
|
import { Projection } from "../utils/Projection";
|
|
6
9
|
import VectorSource from "ol/source/Vector";
|
|
@@ -15,19 +18,32 @@ import { drawPoint } from "./OpenlayerPoint";
|
|
|
15
18
|
import { drawPolyline } from "./OpenlayerPolyline";
|
|
16
19
|
import { drawPolygon } from "./OpenlayerPolygon";
|
|
17
20
|
import { Tile3DOption, Tile3D } from "../basic/Tile3D";
|
|
21
|
+
import { gcjMecator } from "./openlayer-tile-gcj02-wgs84";
|
|
22
|
+
|
|
23
|
+
export interface IOpenlayerOption {
|
|
24
|
+
container;
|
|
25
|
+
url: string | string[];
|
|
26
|
+
center?: number[];
|
|
27
|
+
zoom?: number;
|
|
28
|
+
maxZoom?: number;
|
|
29
|
+
minZoom?: number;
|
|
30
|
+
/** 地图瓦片转换规则 GCJ02 转 WGS84 */
|
|
31
|
+
proj?: "GCJ02->WGS84";
|
|
32
|
+
}
|
|
18
33
|
|
|
19
34
|
export class OpenlayerMap extends MapCombine {
|
|
20
35
|
viewer: Map;
|
|
21
36
|
container: HTMLDivElement;
|
|
22
37
|
dragPan: DragPan;
|
|
23
|
-
vectors: VectorSource
|
|
38
|
+
vectors: VectorSource;
|
|
39
|
+
option: IOpenlayerOption;
|
|
24
40
|
offset: number[];
|
|
25
41
|
fov = 0.9272952180016121;
|
|
26
42
|
get cursor(): string {
|
|
27
|
-
return
|
|
43
|
+
return this.container.style.cursor;
|
|
28
44
|
}
|
|
29
45
|
set cursor(val: string) {
|
|
30
|
-
|
|
46
|
+
this.container.style.cursor = val;
|
|
31
47
|
}
|
|
32
48
|
get moveable(): boolean {
|
|
33
49
|
return this.dragPan.getActive();
|
|
@@ -36,8 +52,8 @@ export class OpenlayerMap extends MapCombine {
|
|
|
36
52
|
this.dragPan.setActive(val);
|
|
37
53
|
}
|
|
38
54
|
get center(): number[] {
|
|
39
|
-
const center = this.viewer.getView().getCenter()
|
|
40
|
-
return [Projection.xToLon(center[0]), Projection.yToLat(center[1]), 0]
|
|
55
|
+
const center = this.viewer.getView().getCenter()!;
|
|
56
|
+
return [Projection.xToLon(center[0]), Projection.yToLat(center[1]), 0];
|
|
41
57
|
}
|
|
42
58
|
set center(val: number[]) {
|
|
43
59
|
const { viewer } = this;
|
|
@@ -45,19 +61,59 @@ export class OpenlayerMap extends MapCombine {
|
|
|
45
61
|
view.setCenter([Projection.lonToX(val[0]), Projection.latToY(val[1])]);
|
|
46
62
|
}
|
|
47
63
|
get zoom(): number {
|
|
48
|
-
return this.viewer.getView().getZoom()
|
|
64
|
+
return this.viewer.getView().getZoom();
|
|
49
65
|
}
|
|
50
66
|
set zoom(val: number) {
|
|
51
67
|
this.viewer.getView().setZoom(val);
|
|
52
68
|
}
|
|
53
69
|
|
|
54
|
-
constructor(viewer
|
|
55
|
-
super()
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
constructor(viewer?: Map) {
|
|
71
|
+
super();
|
|
72
|
+
viewer && this._initParamsEvent(viewer);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
init(opt: IOpenlayerOption) {
|
|
76
|
+
this.option = opt;
|
|
77
|
+
const { container, center = [120.2288892, 30.2349677, 0], zoom = 13, url, maxZoom, minZoom, proj } = opt || {};
|
|
78
|
+
|
|
79
|
+
const viewer = new Map({
|
|
80
|
+
target: container,
|
|
81
|
+
controls: [],
|
|
82
|
+
view: new View({
|
|
83
|
+
projection: "EPSG:3857",
|
|
84
|
+
center: fromLonLat(center),
|
|
85
|
+
zoom: zoom,
|
|
86
|
+
maxZoom: maxZoom ?? 18,
|
|
87
|
+
minZoom: minZoom ?? 3,
|
|
88
|
+
}),
|
|
89
|
+
layers: [
|
|
90
|
+
new Tile({
|
|
91
|
+
visible: true,
|
|
92
|
+
source: new XYZ({
|
|
93
|
+
projection: proj === "GCJ02->WGS84" ? gcjMecator : undefined,
|
|
94
|
+
urls: Array.isArray(url) ? url : [url],
|
|
95
|
+
crossOrigin: "anonymous",
|
|
96
|
+
}),
|
|
97
|
+
}),
|
|
98
|
+
],
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
this._initParamsEvent(viewer);
|
|
102
|
+
|
|
103
|
+
return new OpenlayerMap(viewer);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private _initParamsEvent(viewer) {
|
|
107
|
+
if (!viewer) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.viewer = viewer;
|
|
111
|
+
this.container = viewer.getViewport() as HTMLDivElement;
|
|
112
|
+
this.container.appendChild(this.htmllayer);
|
|
113
|
+
this.cursor = "default";
|
|
114
|
+
|
|
59
115
|
const { center } = this;
|
|
60
|
-
this.offset = fromLonLat(center)
|
|
116
|
+
this.offset = fromLonLat(center);
|
|
61
117
|
|
|
62
118
|
this.vectors = new VectorSource();
|
|
63
119
|
this.viewer.addLayer(
|
|
@@ -71,29 +127,29 @@ export class OpenlayerMap extends MapCombine {
|
|
|
71
127
|
.getArray()
|
|
72
128
|
.find((interaction) => {
|
|
73
129
|
if (interaction instanceof DoubleClickZoom) {
|
|
74
|
-
interaction.setActive(false)
|
|
130
|
+
interaction.setActive(false);
|
|
75
131
|
}
|
|
76
132
|
return interaction instanceof DragPan;
|
|
77
133
|
}) as DragPan;
|
|
78
134
|
|
|
79
|
-
bindEvent(this)
|
|
135
|
+
bindEvent(this);
|
|
80
136
|
}
|
|
81
137
|
|
|
82
138
|
createPoint<K>(option?: Partial<PointOption<K>>): Point<K> {
|
|
83
|
-
const e = new Point(this, option)
|
|
84
|
-
drawPoint(this, e)
|
|
85
|
-
return e
|
|
139
|
+
const e = new Point(this, option);
|
|
140
|
+
drawPoint(this, e);
|
|
141
|
+
return e;
|
|
86
142
|
}
|
|
87
143
|
|
|
88
144
|
createPolyline<K>(option?: Partial<PolylineOption<K>>): Polyline<K> {
|
|
89
|
-
const e = new Polyline(this, option)
|
|
90
|
-
drawPolyline(this, e)
|
|
91
|
-
return e
|
|
145
|
+
const e = new Polyline(this, option);
|
|
146
|
+
drawPolyline(this, e);
|
|
147
|
+
return e;
|
|
92
148
|
}
|
|
93
149
|
createPolygon<K>(option?: Partial<PolygonOption<K>>): Polygon<K> {
|
|
94
|
-
const e = new Polygon(this, option)
|
|
95
|
-
drawPolygon(this, e)
|
|
96
|
-
return e
|
|
150
|
+
const e = new Polygon(this, option);
|
|
151
|
+
drawPolygon(this, e);
|
|
152
|
+
return e;
|
|
97
153
|
}
|
|
98
154
|
|
|
99
155
|
// protected _onFrame(): void {
|
|
@@ -116,9 +172,8 @@ export class OpenlayerMap extends MapCombine {
|
|
|
116
172
|
if (pixel) {
|
|
117
173
|
return [pixel[0], pixel[1]];
|
|
118
174
|
} else {
|
|
119
|
-
return [0, 0]
|
|
175
|
+
return [0, 0];
|
|
120
176
|
}
|
|
121
|
-
|
|
122
177
|
}
|
|
123
178
|
spaceTgeography(p: number[]): number[] {
|
|
124
179
|
const { offset } = this;
|
|
@@ -144,6 +199,6 @@ export class OpenlayerMap extends MapCombine {
|
|
|
144
199
|
}
|
|
145
200
|
|
|
146
201
|
_onDestroy() {
|
|
147
|
-
this.viewer.dispose()
|
|
202
|
+
this.viewer.dispose();
|
|
148
203
|
}
|
|
149
|
-
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Projection, addProjection, addCoordinateTransforms } from "ol/proj";
|
|
2
|
+
|
|
3
|
+
let projzh = {};
|
|
4
|
+
projzh.ll2gmerc = function (input, opt_output, opt_dimension) {
|
|
5
|
+
let output = gcj02.fromWGS84(input, opt_output, opt_dimension);
|
|
6
|
+
return projzh.ll2smerc(output, output, opt_dimension);
|
|
7
|
+
};
|
|
8
|
+
projzh.gmerc2ll = function (input, opt_output, opt_dimension) {
|
|
9
|
+
let output = projzh.smerc2ll(input, input, opt_dimension);
|
|
10
|
+
return gcj02.toWGS84(output, opt_output, opt_dimension);
|
|
11
|
+
};
|
|
12
|
+
projzh.smerc2gmerc = function (input, opt_output, opt_dimension) {
|
|
13
|
+
let output = projzh.smerc2ll(input, input, opt_dimension);
|
|
14
|
+
output = gcj02.fromWGS84(output, output, opt_dimension);
|
|
15
|
+
return projzh.ll2smerc(output, output, opt_dimension);
|
|
16
|
+
};
|
|
17
|
+
projzh.gmerc2smerc = function (input, opt_output, opt_dimension) {
|
|
18
|
+
let output = projzh.smerc2ll(input, input, opt_dimension);
|
|
19
|
+
output = gcj02.toWGS84(output, output, opt_dimension);
|
|
20
|
+
return projzh.ll2smerc(output, output, opt_dimension);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function forEachPoint(func) {
|
|
24
|
+
return function (input, opt_output, opt_dimension) {
|
|
25
|
+
const len = input.length;
|
|
26
|
+
const dimension = opt_dimension ? opt_dimension : 2;
|
|
27
|
+
let output;
|
|
28
|
+
if (opt_output) {
|
|
29
|
+
output = opt_output;
|
|
30
|
+
} else {
|
|
31
|
+
if (dimension !== 2) {
|
|
32
|
+
output = input.slice();
|
|
33
|
+
} else {
|
|
34
|
+
output = new Array(len);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (let offset = 0; offset < len; offset += dimension) {
|
|
38
|
+
func(input, output, offset);
|
|
39
|
+
}
|
|
40
|
+
return output;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let RADIUS = 6378137;
|
|
45
|
+
let MAX_LATITUDE = 85.0511287798;
|
|
46
|
+
let RAD_PER_DEG = Math.PI / 180;
|
|
47
|
+
|
|
48
|
+
let sphericalMercator = {};
|
|
49
|
+
sphericalMercator.forward = forEachPoint(function (input, output, offset) {
|
|
50
|
+
let lat = Math.max(Math.min(MAX_LATITUDE, input[offset + 1]), -MAX_LATITUDE);
|
|
51
|
+
let sin = Math.sin(lat * RAD_PER_DEG);
|
|
52
|
+
|
|
53
|
+
output[offset] = RADIUS * input[offset] * RAD_PER_DEG;
|
|
54
|
+
output[offset + 1] = (RADIUS * Math.log((1 + sin) / (1 - sin))) / 2;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
sphericalMercator.inverse = forEachPoint(function (input, output, offset) {
|
|
58
|
+
output[offset] = input[offset] / RADIUS / RAD_PER_DEG;
|
|
59
|
+
output[offset + 1] = (2 * Math.atan(Math.exp(input[offset + 1] / RADIUS)) - Math.PI / 2) / RAD_PER_DEG;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
projzh.ll2smerc = sphericalMercator.forward;
|
|
63
|
+
projzh.smerc2ll = sphericalMercator.inverse;
|
|
64
|
+
|
|
65
|
+
const gcj02 = {};
|
|
66
|
+
const PI = Math.PI;
|
|
67
|
+
const AXIS = 6378245.0;
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
|
|
69
|
+
const OFFSET = 0.00669342162296594323; // (a^2 - b^2) / a^2
|
|
70
|
+
|
|
71
|
+
function delta(wgLon, wgLat) {
|
|
72
|
+
let dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
|
|
73
|
+
let dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
|
|
74
|
+
const radLat = (wgLat / 180.0) * PI;
|
|
75
|
+
let magic = Math.sin(radLat);
|
|
76
|
+
magic = 1 - OFFSET * magic * magic;
|
|
77
|
+
const sqrtMagic = Math.sqrt(magic);
|
|
78
|
+
dLat = (dLat * 180.0) / (((AXIS * (1 - OFFSET)) / (magic * sqrtMagic)) * PI);
|
|
79
|
+
dLon = (dLon * 180.0) / ((AXIS / sqrtMagic) * Math.cos(radLat) * PI);
|
|
80
|
+
return [dLon, dLat];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function outOfChina(lon, lat) {
|
|
84
|
+
if (lon < 72.004 || lon > 137.8347) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
if (lat < 0.8293 || lat > 55.8271) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function transformLat(x, y) {
|
|
94
|
+
let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
|
|
95
|
+
ret += ((20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0) / 3.0;
|
|
96
|
+
ret += ((20.0 * Math.sin(y * PI) + 40.0 * Math.sin((y / 3.0) * PI)) * 2.0) / 3.0;
|
|
97
|
+
ret += ((160.0 * Math.sin((y / 12.0) * PI) + 320 * Math.sin((y * PI) / 30.0)) * 2.0) / 3.0;
|
|
98
|
+
return ret;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function transformLon(x, y) {
|
|
102
|
+
let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
|
|
103
|
+
ret += ((20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0) / 3.0;
|
|
104
|
+
ret += ((20.0 * Math.sin(x * PI) + 40.0 * Math.sin((x / 3.0) * PI)) * 2.0) / 3.0;
|
|
105
|
+
ret += ((150.0 * Math.sin((x / 12.0) * PI) + 300.0 * Math.sin((x / 30.0) * PI)) * 2.0) / 3.0;
|
|
106
|
+
return ret;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
gcj02.toWGS84 = forEachPoint(function (input, output, offset) {
|
|
110
|
+
let lng = input[offset];
|
|
111
|
+
let lat = input[offset + 1];
|
|
112
|
+
if (!outOfChina(lng, lat)) {
|
|
113
|
+
let deltaD = delta(lng, lat);
|
|
114
|
+
lng = lng - deltaD[0];
|
|
115
|
+
lat = lat - deltaD[1];
|
|
116
|
+
}
|
|
117
|
+
output[offset] = lng;
|
|
118
|
+
output[offset + 1] = lat;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
gcj02.fromWGS84 = forEachPoint(function (input, output, offset) {
|
|
122
|
+
let lng = input[offset];
|
|
123
|
+
let lat = input[offset + 1];
|
|
124
|
+
if (!outOfChina(lng, lat)) {
|
|
125
|
+
let deltaD = delta(lng, lat);
|
|
126
|
+
lng = lng + deltaD[0];
|
|
127
|
+
lat = lat + deltaD[1];
|
|
128
|
+
}
|
|
129
|
+
output[offset] = lng;
|
|
130
|
+
output[offset + 1] = lat;
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const gcj02Extent = [-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244];
|
|
134
|
+
const gcjMecator = new Projection({
|
|
135
|
+
code: "GCJ-02",
|
|
136
|
+
extent: gcj02Extent,
|
|
137
|
+
units: "m",
|
|
138
|
+
});
|
|
139
|
+
addProjection(gcjMecator);
|
|
140
|
+
|
|
141
|
+
addCoordinateTransforms("EPSG:4326", gcjMecator, projzh.ll2gmerc, projzh.gmerc2ll);
|
|
142
|
+
addCoordinateTransforms("EPSG:3857", gcjMecator, projzh.smerc2gmerc, projzh.gmerc2smerc);
|
|
143
|
+
|
|
144
|
+
export { gcjMecator };
|
package/src/utils/index.ts
CHANGED
|
@@ -83,7 +83,6 @@ export function getUUID() {
|
|
|
83
83
|
return (Date.now() + Math.random()).toString();
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
86
|
/**
|
|
88
87
|
* 节流执行函数
|
|
89
88
|
* @param func 目标函数
|
|
@@ -128,4 +127,18 @@ export function throttle<T extends (...args: any) => void>(func: T, time = 0, im
|
|
|
128
127
|
}
|
|
129
128
|
} as T;
|
|
130
129
|
}
|
|
131
|
-
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function arrayFillByLen(arr, len, item) {
|
|
133
|
+
let _arr = arr;
|
|
134
|
+
if (!Array.isArray(_arr)) {
|
|
135
|
+
throw new Error("请传入数组");
|
|
136
|
+
}
|
|
137
|
+
if (arr.length >= len) {
|
|
138
|
+
return arr;
|
|
139
|
+
}
|
|
140
|
+
const fillLen = len - arr.length;
|
|
141
|
+
for (let i = 0; i < fillLen; i++) {
|
|
142
|
+
arr.push(item);
|
|
143
|
+
}
|
|
144
|
+
}
|