@hzab/map-combine 0.4.2-alpha.0 → 0.4.2-alpha.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.
package/package.json
CHANGED
|
@@ -171,6 +171,7 @@ export class PointAggregation {
|
|
|
171
171
|
|
|
172
172
|
onAfterViewChange(): void {
|
|
173
173
|
const { _map } = this;
|
|
174
|
+
// 限制最大缩放层级
|
|
174
175
|
const zoom = Math.min(Math.round(_map.zoom * 4) / 4, this._option.maxZoomLevel ?? 17);
|
|
175
176
|
if (zoom !== this._current) {
|
|
176
177
|
this._turnoff();
|
|
@@ -1,287 +1,287 @@
|
|
|
1
|
-
import * as ol from "ol/index.js";
|
|
2
|
-
import Map from "ol/Map.js";
|
|
3
|
-
import View from "ol/View";
|
|
4
|
-
import XYZ from "ol/source/XYZ";
|
|
5
|
-
import Tile from "ol/layer/Tile";
|
|
6
|
-
import DragPan from "ol/interaction/DragPan";
|
|
7
|
-
import VectorSource from "ol/source/Vector";
|
|
8
|
-
import VectorLayer from "ol/layer/Vector";
|
|
9
|
-
import { fromLonLat } from "ol/proj";
|
|
10
|
-
import * as olGeom from "ol/geom";
|
|
11
|
-
import * as olSource from "ol/source";
|
|
12
|
-
import * as olStyle from "ol/style";
|
|
13
|
-
import * as olLayer from "ol/layer";
|
|
14
|
-
import * as olExtent from "ol/extent";
|
|
15
|
-
|
|
16
|
-
import { MapCombine } from "../basic/MapCombine";
|
|
17
|
-
import { PointOption, Point } from "../basic/Point";
|
|
18
|
-
import { PointAggregationOption, PointAggregation } from "../basic/PointAggregation";
|
|
19
|
-
import { Projection } from "../utils/Projection";
|
|
20
|
-
import { bindEvent } from "./OpenlayerEvent";
|
|
21
|
-
import { PolylineOption, Polyline } from "../basic/Polyline";
|
|
22
|
-
import DoubleClickZoom from "ol/interaction/DoubleClickZoom";
|
|
23
|
-
import { PolygonOption, Polygon } from "../basic/Polygon";
|
|
24
|
-
|
|
25
|
-
import { drawPoint } from "./OpenlayerPoint";
|
|
26
|
-
import { drawPolyline } from "./OpenlayerPolyline";
|
|
27
|
-
import { drawPolygon } from "./OpenlayerPolygon";
|
|
28
|
-
import { Tile3DOption, Tile3D } from "../basic/Tile3D";
|
|
29
|
-
import { gcjMecator } from "./openlayer-tile-gcj02-wgs84";
|
|
30
|
-
|
|
31
|
-
const MAX_ZOOM = 18;
|
|
32
|
-
|
|
33
|
-
export interface IOpenlayerOption {
|
|
34
|
-
container;
|
|
35
|
-
url: string | string[];
|
|
36
|
-
center?: number[];
|
|
37
|
-
zoom?: number;
|
|
38
|
-
maxZoom?: number;
|
|
39
|
-
minZoom?: number;
|
|
40
|
-
/** 地图瓦片转换规则 GCJ02 转 WGS84 */
|
|
41
|
-
proj?: "GCJ02->WGS84";
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export class OpenlayerMap extends MapCombine {
|
|
45
|
-
viewer: Map;
|
|
46
|
-
container: HTMLDivElement;
|
|
47
|
-
dragPan: DragPan;
|
|
48
|
-
vectors: VectorSource;
|
|
49
|
-
option: IOpenlayerOption;
|
|
50
|
-
offset: number[];
|
|
51
|
-
fov = 0.9272952180016121;
|
|
52
|
-
isFromLonLat = true;
|
|
53
|
-
get cursor(): string {
|
|
54
|
-
return this.container.style.cursor;
|
|
55
|
-
}
|
|
56
|
-
set cursor(val: string) {
|
|
57
|
-
this.container.style.cursor = val;
|
|
58
|
-
}
|
|
59
|
-
get moveable(): boolean {
|
|
60
|
-
return this.dragPan.getActive();
|
|
61
|
-
}
|
|
62
|
-
set moveable(val: boolean) {
|
|
63
|
-
this.dragPan.setActive(val);
|
|
64
|
-
}
|
|
65
|
-
get center(): number[] {
|
|
66
|
-
const center = this.viewer.getView().getCenter()!;
|
|
67
|
-
return [Projection.xToLon(center[0]), Projection.yToLat(center[1]), 0];
|
|
68
|
-
}
|
|
69
|
-
set center(val: number[]) {
|
|
70
|
-
const { viewer } = this;
|
|
71
|
-
const view = viewer.getView();
|
|
72
|
-
view.setCenter([Projection.lonToX(val[0]), Projection.latToY(val[1])]);
|
|
73
|
-
}
|
|
74
|
-
get zoom(): number {
|
|
75
|
-
return this.viewer.getView().getZoom();
|
|
76
|
-
}
|
|
77
|
-
set zoom(val: number) {
|
|
78
|
-
this.viewer.getView().setZoom(val);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
constructor(viewer?: Map) {
|
|
82
|
-
super();
|
|
83
|
-
viewer && this._initParamsEvent(viewer);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
init(opt: IOpenlayerOption) {
|
|
87
|
-
this.option = opt;
|
|
88
|
-
const { container, center = [120.2288892, 30.2349677, 0], zoom = 13, url, maxZoom, minZoom, proj } = opt || {};
|
|
89
|
-
|
|
90
|
-
const viewer = new Map({
|
|
91
|
-
target: container,
|
|
92
|
-
controls: [],
|
|
93
|
-
view: new View({
|
|
94
|
-
projection: "EPSG:3857",
|
|
95
|
-
center: fromLonLat(center),
|
|
96
|
-
zoom: zoom,
|
|
97
|
-
maxZoom: maxZoom ?? 18,
|
|
98
|
-
minZoom: minZoom ?? 3,
|
|
99
|
-
}),
|
|
100
|
-
layers: [
|
|
101
|
-
new Tile({
|
|
102
|
-
visible: true,
|
|
103
|
-
source: new XYZ({
|
|
104
|
-
projection: proj === "GCJ02->WGS84" ? gcjMecator : undefined,
|
|
105
|
-
urls: Array.isArray(url) ? url : [url],
|
|
106
|
-
crossOrigin: "anonymous",
|
|
107
|
-
}),
|
|
108
|
-
}),
|
|
109
|
-
],
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
this._initParamsEvent(viewer);
|
|
113
|
-
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private _initParamsEvent(viewer) {
|
|
118
|
-
if (!viewer) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
this.viewer = viewer;
|
|
122
|
-
this.container = viewer.getViewport() as HTMLDivElement;
|
|
123
|
-
this.container.appendChild(this.htmllayer);
|
|
124
|
-
this.cursor = "default";
|
|
125
|
-
|
|
126
|
-
const { center } = this;
|
|
127
|
-
const proj = this.viewer.getView().getProjection().getCode();
|
|
128
|
-
this.isFromLonLat = proj === "EPSG:3857" || proj === "EPSG:4326";
|
|
129
|
-
this.offset = this.getFromLonLat(center);
|
|
130
|
-
this.vectors = new VectorSource();
|
|
131
|
-
this.viewer.addLayer(
|
|
132
|
-
new VectorLayer({
|
|
133
|
-
source: this.vectors,
|
|
134
|
-
}),
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
this.dragPan = viewer
|
|
138
|
-
.getInteractions()
|
|
139
|
-
.getArray()
|
|
140
|
-
.find((interaction) => {
|
|
141
|
-
if (interaction instanceof DoubleClickZoom) {
|
|
142
|
-
interaction.setActive(false);
|
|
143
|
-
}
|
|
144
|
-
return interaction instanceof DragPan;
|
|
145
|
-
}) as DragPan;
|
|
146
|
-
|
|
147
|
-
bindEvent(this);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
getFromLonLat(lonLat, isFromLonLat = this.isFromLonLat) {
|
|
151
|
-
return isFromLonLat ? fromLonLat(lonLat) : lonLat;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
createPoint<K>(option?: Partial<PointOption<K>>): Point<K> {
|
|
155
|
-
const e = new Point(this, option);
|
|
156
|
-
drawPoint(this, e);
|
|
157
|
-
return e;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
createPointAggregation(option?: PointAggregationOption): PointAggregation {
|
|
161
|
-
const e = new PointAggregation(this, option);
|
|
162
|
-
return e;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
createPolyline<K>(option?: Partial<PolylineOption<K>>): Polyline<K> {
|
|
166
|
-
const e = new Polyline(this, option);
|
|
167
|
-
drawPolyline(this, e);
|
|
168
|
-
return e;
|
|
169
|
-
}
|
|
170
|
-
createPolygon<K>(option?: Partial<PolygonOption<K>>): Polygon<K> {
|
|
171
|
-
const e = new Polygon(this, option);
|
|
172
|
-
drawPolygon(this, e);
|
|
173
|
-
return e;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// protected _onFrame(): void {
|
|
177
|
-
// const { viewer, camera, offset } = this;
|
|
178
|
-
// const box = viewer.getView().calculateExtent(viewer.getSize());
|
|
179
|
-
|
|
180
|
-
// const height = box[3] - box[1];
|
|
181
|
-
|
|
182
|
-
// camera.position.set((box[2] + box[0]) / 2 - offset[0], (box[3] + box[1]) / 2 - offset[1], height);
|
|
183
|
-
|
|
184
|
-
// // this.meterPerPixel = height / this.container.offsetHeight;
|
|
185
|
-
// }
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* 所有点位移动至视口,调整位置及层级
|
|
189
|
-
* @param points
|
|
190
|
-
* @param opt
|
|
191
|
-
* @param {Array<number> = [0,0,0,0]} opt.avoid 距离边框的内边距,顺序:上、下、左、右
|
|
192
|
-
*/
|
|
193
|
-
flyToViewer(points, opt = { avoid: [0, 0, 0, 0], maxZoom: MAX_ZOOM }) {
|
|
194
|
-
if (points?.length === 0) {
|
|
195
|
-
return this.flyTo(points[0], opt);
|
|
196
|
-
}
|
|
197
|
-
const { avoid } = opt || {};
|
|
198
|
-
// 创建 Feature 数组
|
|
199
|
-
const features = points.map((point) => {
|
|
200
|
-
const [lon, lat] = point;
|
|
201
|
-
const coord = this.getFromLonLat([lon, lat]);
|
|
202
|
-
return new ol.Feature({
|
|
203
|
-
geometry: new olGeom.Point(coord),
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// 创建 VectorSource
|
|
208
|
-
const source = new olSource.Vector({
|
|
209
|
-
features: features,
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
// 计算边界范围
|
|
213
|
-
const extent = source.getExtent();
|
|
214
|
-
|
|
215
|
-
// 调整边界范围
|
|
216
|
-
olExtent.buffer(extent, this.viewer.getView().getResolution(), extent);
|
|
217
|
-
|
|
218
|
-
// 设置地图视图
|
|
219
|
-
this.viewer.getView().fit(extent, {
|
|
220
|
-
// avoid {Array<number> = [0,0,0,0]} opt.avoid 距离边框的内边距,顺序:上、下、左、右
|
|
221
|
-
// 上 右 下 左
|
|
222
|
-
padding: [avoid[0], avoid[3], avoid[1], avoid[2]],
|
|
223
|
-
duration: 1000,
|
|
224
|
-
maxZoom: opt?.maxZoom ?? MAX_ZOOM, // 最大缩放级别,
|
|
225
|
-
...opt,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* 移动点位到中心点
|
|
231
|
-
* @param point
|
|
232
|
-
*/
|
|
233
|
-
flyTo(point, opt = {}) {
|
|
234
|
-
// 设置相机视角
|
|
235
|
-
this.viewer.getView().fit(point, {
|
|
236
|
-
duration: 1000,
|
|
237
|
-
...opt,
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
geographyTspace(p: number[]): number[] {
|
|
242
|
-
const { offset } = this;
|
|
243
|
-
return [Projection.lonToX(p[0]) - offset[0], Projection.latToY(p[1]) - offset[1], p[2] ?? 0];
|
|
244
|
-
}
|
|
245
|
-
geographyTcanvas(p: number[]): number[] {
|
|
246
|
-
const pixel = this.viewer.getPixelFromCoordinate(this.getFromLonLat(p));
|
|
247
|
-
if (pixel) {
|
|
248
|
-
return [pixel[0], pixel[1]];
|
|
249
|
-
} else {
|
|
250
|
-
return [0, 0];
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
spaceTgeography(p: number[]): number[] {
|
|
254
|
-
const { offset } = this;
|
|
255
|
-
return [Projection.xToLon(p[0] + offset[0]), Projection.yToLat(p[1] + offset[1]), p[2] ?? 0];
|
|
256
|
-
}
|
|
257
|
-
spaceTcanvas(p: number[]): number[] {
|
|
258
|
-
const { offset } = this;
|
|
259
|
-
const pixel = this.viewer.getPixelFromCoordinate([p[0] + offset[0], p[1] + offset[1]]);
|
|
260
|
-
return [pixel[0], pixel[1]];
|
|
261
|
-
}
|
|
262
|
-
canvasTspace(p: number[]): number[] {
|
|
263
|
-
const coordinates = this.viewer.getCoordinateFromPixel(p);
|
|
264
|
-
// 解决 coordinates 为 null 异常情况
|
|
265
|
-
if (!coordinates) {
|
|
266
|
-
return [];
|
|
267
|
-
}
|
|
268
|
-
return [coordinates[0] - this.offset[0], coordinates[1] - this.offset[1], 0];
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
createTile3D(option?: Partial<Tile3DOption>): Tile3D {
|
|
272
|
-
throw new Error("Method not implemented.");
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
canvasTgeography(p: number[]): number[] {
|
|
276
|
-
const coordinates = this.viewer.getCoordinateFromPixel(p);
|
|
277
|
-
// 解决 coordinates 为 null 异常情况
|
|
278
|
-
if (!coordinates) {
|
|
279
|
-
return [];
|
|
280
|
-
}
|
|
281
|
-
return [Projection.xToLon(coordinates[0]), Projection.yToLat(coordinates[1]), 0];
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
_onDestroy() {
|
|
285
|
-
this.viewer.dispose();
|
|
286
|
-
}
|
|
287
|
-
}
|
|
1
|
+
import * as ol from "ol/index.js";
|
|
2
|
+
import Map from "ol/Map.js";
|
|
3
|
+
import View from "ol/View";
|
|
4
|
+
import XYZ from "ol/source/XYZ";
|
|
5
|
+
import Tile from "ol/layer/Tile";
|
|
6
|
+
import DragPan from "ol/interaction/DragPan";
|
|
7
|
+
import VectorSource from "ol/source/Vector";
|
|
8
|
+
import VectorLayer from "ol/layer/Vector";
|
|
9
|
+
import { fromLonLat } from "ol/proj";
|
|
10
|
+
import * as olGeom from "ol/geom";
|
|
11
|
+
import * as olSource from "ol/source";
|
|
12
|
+
import * as olStyle from "ol/style";
|
|
13
|
+
import * as olLayer from "ol/layer";
|
|
14
|
+
import * as olExtent from "ol/extent";
|
|
15
|
+
|
|
16
|
+
import { MapCombine } from "../basic/MapCombine";
|
|
17
|
+
import { PointOption, Point } from "../basic/Point";
|
|
18
|
+
import { PointAggregationOption, PointAggregation } from "../basic/PointAggregation";
|
|
19
|
+
import { Projection } from "../utils/Projection";
|
|
20
|
+
import { bindEvent } from "./OpenlayerEvent";
|
|
21
|
+
import { PolylineOption, Polyline } from "../basic/Polyline";
|
|
22
|
+
import DoubleClickZoom from "ol/interaction/DoubleClickZoom";
|
|
23
|
+
import { PolygonOption, Polygon } from "../basic/Polygon";
|
|
24
|
+
|
|
25
|
+
import { drawPoint } from "./OpenlayerPoint";
|
|
26
|
+
import { drawPolyline } from "./OpenlayerPolyline";
|
|
27
|
+
import { drawPolygon } from "./OpenlayerPolygon";
|
|
28
|
+
import { Tile3DOption, Tile3D } from "../basic/Tile3D";
|
|
29
|
+
import { gcjMecator } from "./openlayer-tile-gcj02-wgs84";
|
|
30
|
+
|
|
31
|
+
const MAX_ZOOM = 18;
|
|
32
|
+
|
|
33
|
+
export interface IOpenlayerOption {
|
|
34
|
+
container;
|
|
35
|
+
url: string | string[];
|
|
36
|
+
center?: number[];
|
|
37
|
+
zoom?: number;
|
|
38
|
+
maxZoom?: number;
|
|
39
|
+
minZoom?: number;
|
|
40
|
+
/** 地图瓦片转换规则 GCJ02 转 WGS84 */
|
|
41
|
+
proj?: "GCJ02->WGS84";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class OpenlayerMap extends MapCombine {
|
|
45
|
+
viewer: Map;
|
|
46
|
+
container: HTMLDivElement;
|
|
47
|
+
dragPan: DragPan;
|
|
48
|
+
vectors: VectorSource;
|
|
49
|
+
option: IOpenlayerOption;
|
|
50
|
+
offset: number[];
|
|
51
|
+
fov = 0.9272952180016121;
|
|
52
|
+
isFromLonLat = true;
|
|
53
|
+
get cursor(): string {
|
|
54
|
+
return this.container.style.cursor;
|
|
55
|
+
}
|
|
56
|
+
set cursor(val: string) {
|
|
57
|
+
this.container.style.cursor = val;
|
|
58
|
+
}
|
|
59
|
+
get moveable(): boolean {
|
|
60
|
+
return this.dragPan.getActive();
|
|
61
|
+
}
|
|
62
|
+
set moveable(val: boolean) {
|
|
63
|
+
this.dragPan.setActive(val);
|
|
64
|
+
}
|
|
65
|
+
get center(): number[] {
|
|
66
|
+
const center = this.viewer.getView().getCenter()!;
|
|
67
|
+
return [Projection.xToLon(center[0]), Projection.yToLat(center[1]), 0];
|
|
68
|
+
}
|
|
69
|
+
set center(val: number[]) {
|
|
70
|
+
const { viewer } = this;
|
|
71
|
+
const view = viewer.getView();
|
|
72
|
+
view.setCenter([Projection.lonToX(val[0]), Projection.latToY(val[1])]);
|
|
73
|
+
}
|
|
74
|
+
get zoom(): number {
|
|
75
|
+
return this.viewer.getView().getZoom();
|
|
76
|
+
}
|
|
77
|
+
set zoom(val: number) {
|
|
78
|
+
this.viewer.getView().setZoom(val);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
constructor(viewer?: Map) {
|
|
82
|
+
super();
|
|
83
|
+
viewer && this._initParamsEvent(viewer);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
init(opt: IOpenlayerOption) {
|
|
87
|
+
this.option = opt;
|
|
88
|
+
const { container, center = [120.2288892, 30.2349677, 0], zoom = 13, url, maxZoom, minZoom, proj } = opt || {};
|
|
89
|
+
|
|
90
|
+
const viewer = new Map({
|
|
91
|
+
target: container,
|
|
92
|
+
controls: [],
|
|
93
|
+
view: new View({
|
|
94
|
+
projection: "EPSG:3857",
|
|
95
|
+
center: fromLonLat(center),
|
|
96
|
+
zoom: zoom,
|
|
97
|
+
maxZoom: maxZoom ?? 18,
|
|
98
|
+
minZoom: minZoom ?? 3,
|
|
99
|
+
}),
|
|
100
|
+
layers: [
|
|
101
|
+
new Tile({
|
|
102
|
+
visible: true,
|
|
103
|
+
source: new XYZ({
|
|
104
|
+
projection: proj === "GCJ02->WGS84" ? gcjMecator : undefined,
|
|
105
|
+
urls: Array.isArray(url) ? url : [url],
|
|
106
|
+
crossOrigin: "anonymous",
|
|
107
|
+
}),
|
|
108
|
+
}),
|
|
109
|
+
],
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
this._initParamsEvent(viewer);
|
|
113
|
+
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private _initParamsEvent(viewer) {
|
|
118
|
+
if (!viewer) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
this.viewer = viewer;
|
|
122
|
+
this.container = viewer.getViewport() as HTMLDivElement;
|
|
123
|
+
this.container.appendChild(this.htmllayer);
|
|
124
|
+
this.cursor = "default";
|
|
125
|
+
|
|
126
|
+
const { center } = this;
|
|
127
|
+
const proj = this.viewer.getView().getProjection().getCode();
|
|
128
|
+
this.isFromLonLat = proj === "EPSG:3857" || proj === "EPSG:4326";
|
|
129
|
+
this.offset = this.getFromLonLat(center);
|
|
130
|
+
this.vectors = new VectorSource();
|
|
131
|
+
this.viewer.addLayer(
|
|
132
|
+
new VectorLayer({
|
|
133
|
+
source: this.vectors,
|
|
134
|
+
}),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
this.dragPan = viewer
|
|
138
|
+
.getInteractions()
|
|
139
|
+
.getArray()
|
|
140
|
+
.find((interaction) => {
|
|
141
|
+
if (interaction instanceof DoubleClickZoom) {
|
|
142
|
+
interaction.setActive(false);
|
|
143
|
+
}
|
|
144
|
+
return interaction instanceof DragPan;
|
|
145
|
+
}) as DragPan;
|
|
146
|
+
|
|
147
|
+
bindEvent(this);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getFromLonLat(lonLat, isFromLonLat = this.isFromLonLat) {
|
|
151
|
+
return isFromLonLat ? fromLonLat(lonLat) : lonLat;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
createPoint<K>(option?: Partial<PointOption<K>>): Point<K> {
|
|
155
|
+
const e = new Point(this, option);
|
|
156
|
+
drawPoint(this, e);
|
|
157
|
+
return e;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
createPointAggregation(option?: PointAggregationOption): PointAggregation {
|
|
161
|
+
const e = new PointAggregation(this, option);
|
|
162
|
+
return e;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
createPolyline<K>(option?: Partial<PolylineOption<K>>): Polyline<K> {
|
|
166
|
+
const e = new Polyline(this, option);
|
|
167
|
+
drawPolyline(this, e);
|
|
168
|
+
return e;
|
|
169
|
+
}
|
|
170
|
+
createPolygon<K>(option?: Partial<PolygonOption<K>>): Polygon<K> {
|
|
171
|
+
const e = new Polygon(this, option);
|
|
172
|
+
drawPolygon(this, e);
|
|
173
|
+
return e;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// protected _onFrame(): void {
|
|
177
|
+
// const { viewer, camera, offset } = this;
|
|
178
|
+
// const box = viewer.getView().calculateExtent(viewer.getSize());
|
|
179
|
+
|
|
180
|
+
// const height = box[3] - box[1];
|
|
181
|
+
|
|
182
|
+
// camera.position.set((box[2] + box[0]) / 2 - offset[0], (box[3] + box[1]) / 2 - offset[1], height);
|
|
183
|
+
|
|
184
|
+
// // this.meterPerPixel = height / this.container.offsetHeight;
|
|
185
|
+
// }
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 所有点位移动至视口,调整位置及层级
|
|
189
|
+
* @param points
|
|
190
|
+
* @param opt
|
|
191
|
+
* @param {Array<number> = [0,0,0,0]} opt.avoid 距离边框的内边距,顺序:上、下、左、右
|
|
192
|
+
*/
|
|
193
|
+
flyToViewer(points, opt = { avoid: [0, 0, 0, 0], maxZoom: MAX_ZOOM }) {
|
|
194
|
+
if (points?.length === 0) {
|
|
195
|
+
return this.flyTo(points[0], opt);
|
|
196
|
+
}
|
|
197
|
+
const { avoid } = opt || {};
|
|
198
|
+
// 创建 Feature 数组
|
|
199
|
+
const features = points.map((point) => {
|
|
200
|
+
const [lon, lat] = point;
|
|
201
|
+
const coord = this.getFromLonLat([lon, lat]);
|
|
202
|
+
return new ol.Feature({
|
|
203
|
+
geometry: new olGeom.Point(coord),
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// 创建 VectorSource
|
|
208
|
+
const source = new olSource.Vector({
|
|
209
|
+
features: features,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// 计算边界范围
|
|
213
|
+
const extent = source.getExtent();
|
|
214
|
+
|
|
215
|
+
// 调整边界范围
|
|
216
|
+
olExtent.buffer(extent, this.viewer.getView().getResolution(), extent);
|
|
217
|
+
|
|
218
|
+
// 设置地图视图
|
|
219
|
+
this.viewer.getView().fit(extent, {
|
|
220
|
+
// avoid {Array<number> = [0,0,0,0]} opt.avoid 距离边框的内边距,顺序:上、下、左、右
|
|
221
|
+
// 上 右 下 左
|
|
222
|
+
padding: [avoid[0], avoid[3], avoid[1], avoid[2]],
|
|
223
|
+
duration: 1000,
|
|
224
|
+
maxZoom: opt?.maxZoom ?? MAX_ZOOM, // 最大缩放级别,
|
|
225
|
+
...opt,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* 移动点位到中心点
|
|
231
|
+
* @param point
|
|
232
|
+
*/
|
|
233
|
+
flyTo(point, opt = {}) {
|
|
234
|
+
// 设置相机视角
|
|
235
|
+
this.viewer.getView().fit(point, {
|
|
236
|
+
duration: 1000,
|
|
237
|
+
...opt,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
geographyTspace(p: number[]): number[] {
|
|
242
|
+
const { offset } = this;
|
|
243
|
+
return [Projection.lonToX(p[0]) - offset[0], Projection.latToY(p[1]) - offset[1], p[2] ?? 0];
|
|
244
|
+
}
|
|
245
|
+
geographyTcanvas(p: number[]): number[] {
|
|
246
|
+
const pixel = this.viewer.getPixelFromCoordinate(this.getFromLonLat(p));
|
|
247
|
+
if (pixel) {
|
|
248
|
+
return [pixel[0], pixel[1]];
|
|
249
|
+
} else {
|
|
250
|
+
return [0, 0];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
spaceTgeography(p: number[]): number[] {
|
|
254
|
+
const { offset } = this;
|
|
255
|
+
return [Projection.xToLon(p[0] + offset[0]), Projection.yToLat(p[1] + offset[1]), p[2] ?? 0];
|
|
256
|
+
}
|
|
257
|
+
spaceTcanvas(p: number[]): number[] {
|
|
258
|
+
const { offset } = this;
|
|
259
|
+
const pixel = this.viewer.getPixelFromCoordinate([p[0] + offset[0], p[1] + offset[1]]);
|
|
260
|
+
return [pixel[0], pixel[1]];
|
|
261
|
+
}
|
|
262
|
+
canvasTspace(p: number[]): number[] {
|
|
263
|
+
const coordinates = this.viewer.getCoordinateFromPixel(p);
|
|
264
|
+
// 解决 coordinates 为 null 异常情况
|
|
265
|
+
if (!coordinates) {
|
|
266
|
+
return [];
|
|
267
|
+
}
|
|
268
|
+
return [coordinates[0] - this.offset[0], coordinates[1] - this.offset[1], 0];
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
createTile3D(option?: Partial<Tile3DOption>): Tile3D {
|
|
272
|
+
throw new Error("Method not implemented.");
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
canvasTgeography(p: number[]): number[] {
|
|
276
|
+
const coordinates = this.viewer.getCoordinateFromPixel(p);
|
|
277
|
+
// 解决 coordinates 为 null 异常情况
|
|
278
|
+
if (!coordinates) {
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
return [Projection.xToLon(coordinates[0]), Projection.yToLat(coordinates[1]), 0];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
_onDestroy() {
|
|
285
|
+
this.viewer.dispose();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -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,
|
|
15
|
+
const { event, viewer, vectors, isFromLonLat } = map;
|
|
16
|
+
// getFromLonLat 使用 map.getFromLonLat 调用,保证 this 指向正确
|
|
33
17
|
|
|
34
18
|
const source = new VectorSource();
|
|
35
19
|
|
|
@@ -62,6 +46,27 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
|
|
|
62
46
|
stroke,
|
|
63
47
|
fill,
|
|
64
48
|
});
|
|
49
|
+
const styleNode = new Style({
|
|
50
|
+
image: new Icon({
|
|
51
|
+
width: 16,
|
|
52
|
+
height: 16,
|
|
53
|
+
src: iconPoint,
|
|
54
|
+
crossOrigin: "anonymous",
|
|
55
|
+
}),
|
|
56
|
+
// 保证编辑的点位高于线
|
|
57
|
+
zIndex: style.getZIndex() + 5,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const styleVirtual = new Style({
|
|
61
|
+
image: new Icon({
|
|
62
|
+
width: 16,
|
|
63
|
+
height: 16,
|
|
64
|
+
src: iconAdd,
|
|
65
|
+
crossOrigin: "anonymous",
|
|
66
|
+
}),
|
|
67
|
+
// 保证编辑的点位高于线
|
|
68
|
+
zIndex: style.getZIndex() + 5,
|
|
69
|
+
});
|
|
65
70
|
|
|
66
71
|
const _event = {
|
|
67
72
|
cursor: polygon.cursor,
|
|
@@ -95,7 +100,7 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
|
|
|
95
100
|
feature.set("event", _event, true);
|
|
96
101
|
if (polygon.coordinates) {
|
|
97
102
|
status = 2;
|
|
98
|
-
geometry.setCoordinates([polygon.coordinates.map((e) => getFromLonLat(e, isFromLonLat))]);
|
|
103
|
+
geometry.setCoordinates([polygon.coordinates.map((e) => map.getFromLonLat(e, isFromLonLat))]);
|
|
99
104
|
layer.setZIndex(polygon.coordinates[0][2] ?? 1);
|
|
100
105
|
source.addFeature(feature);
|
|
101
106
|
}
|
|
@@ -115,7 +120,7 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
|
|
|
115
120
|
break;
|
|
116
121
|
case "coordinates":
|
|
117
122
|
if (polygon.coordinates) {
|
|
118
|
-
geometry.setCoordinates([polygon.coordinates.map((e) => getFromLonLat(e, isFromLonLat))]);
|
|
123
|
+
geometry.setCoordinates([polygon.coordinates.map((e) => map.getFromLonLat(e, isFromLonLat))]);
|
|
119
124
|
layer.setZIndex(polygon.coordinates[0][2] ?? 1);
|
|
120
125
|
switch (status) {
|
|
121
126
|
case 0:
|
|
@@ -157,11 +162,11 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
|
|
|
157
162
|
switch (status) {
|
|
158
163
|
case 1:
|
|
159
164
|
cache.pop();
|
|
160
|
-
cache.push(getFromLonLat(event.geography));
|
|
165
|
+
cache.push(map.getFromLonLat(event.geography));
|
|
161
166
|
geometry.setCoordinates([cache]);
|
|
162
167
|
break;
|
|
163
168
|
case 4:
|
|
164
|
-
activeNode.update(getFromLonLat(event.geography));
|
|
169
|
+
activeNode.update(map.getFromLonLat(event.geography));
|
|
165
170
|
geometry.setCoordinates([editor.getCoordinates()]);
|
|
166
171
|
break;
|
|
167
172
|
}
|
|
@@ -171,7 +176,7 @@ export function drawPolygon(map: OpenlayerMap, polygon: Polygon<unknown>) {
|
|
|
171
176
|
switch (status) {
|
|
172
177
|
case 0:
|
|
173
178
|
status = 1;
|
|
174
|
-
cache = [getFromLonLat(event.geography)];
|
|
179
|
+
cache = [map.getFromLonLat(event.geography)];
|
|
175
180
|
cache.push(cache[0]);
|
|
176
181
|
geometry.setCoordinates([cache]);
|
|
177
182
|
source.addFeature(feature);
|
|
@@ -48,7 +48,7 @@ export function drawPolyline(map: OpenlayerMap, polyline: Polyline<unknown>) {
|
|
|
48
48
|
src: iconPoint,
|
|
49
49
|
crossOrigin: "anonymous",
|
|
50
50
|
}),
|
|
51
|
-
//
|
|
51
|
+
// 保证编辑的点位高于线
|
|
52
52
|
zIndex: style.getZIndex() + 5,
|
|
53
53
|
});
|
|
54
54
|
|
|
@@ -59,7 +59,7 @@ export function drawPolyline(map: OpenlayerMap, polyline: Polyline<unknown>) {
|
|
|
59
59
|
src: iconAdd,
|
|
60
60
|
crossOrigin: "anonymous",
|
|
61
61
|
}),
|
|
62
|
-
//
|
|
62
|
+
// 保证编辑的点位高于线
|
|
63
63
|
zIndex: style.getZIndex() + 5,
|
|
64
64
|
});
|
|
65
65
|
|