Skip to content

Commit 1542745

Browse files
committed
openlayer高性能图层代码优化。review by songyumeng.
1 parent e94e88c commit 1542745

File tree

10 files changed

+689
-532
lines changed

10 files changed

+689
-532
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@
7777
- 增加 `ol.style.CloverShape` `ol.style.HitCloverShape` 类,`ol.source.Graphic` 支持三叶草要素风格
7878

7979
- 废弃 `ol.source.TileSuperMapRest` `ol.source.ImageSuperMapRest` 类的 `options._cache` 参数,由 `options.cacheEnabled` 代替
80+
81+
- 废弃 `ol.source.Graphic` 类的 `onClick` 参数
82+
83+
- `ol.source.Graphic` 类新增 `isHighLight` 参数,支持高亮响应事件
84+
8085
### for MapboxGL
8186

8287
- 废弃 `SuperMap.ElasticSearch``options.change` 参数,直接使用 `SuperMap.ElasticSearch.msearch` `SuperMap.ElasticSearch.msearch``callback` 参数

dist/iclient9-openlayers.js

Lines changed: 519 additions & 435 deletions
Large diffs are not rendered by default.

dist/iclient9-openlayers.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/openlayers/07_graphiclayer_clover.html

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,10 @@
133133
}
134134

135135
//设置每个点的经纬度和传入三叶草样式
136-
for (var i = 0; i < count; ++i) {
136+
for (var i = 0; i < count; i++) {
137137
var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
138138
graphics[i] = new ol.Graphic(new ol.geom.Point(coordinates));
139139
graphics[i].setStyle(clovers[Math.floor(Math.random() * randCount)]);
140-
var pointVector = graphics[i];
141-
pointVector.style = {
142-
image: clovers[i % symbolCount]
143-
};
144-
graphics.push(pointVector);
145140
}
146141

147142
map.once('postrender', function () {

src/mapboxgl/core/Base.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
* 定义命名空间
44
*/
55
import mapboxgl from 'mapbox-gl';
6-
import '../core/MapExtend';
6+
import './MapExtend';
77

88
mapboxgl.supermap = mapboxgl.supermap || {};

src/mapboxgl/core/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export {Util} from './Util';
1+
export {Util} from './Util';
2+
export {MapExtend} from './MapExtend';

src/openlayers/core/MapExtend.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import ol from 'openlayers';
2+
3+
/**
4+
* @function MapExtend
5+
* @description 扩展openlayers的一些原始方法
6+
* @private
7+
*/
8+
export var MapExtend = function () {
9+
ol.Map.prototype.forEachFeatureAtPixelDefault = ol.Map.prototype.forEachFeatureAtPixel;
10+
11+
ol.Map.prototype.forEachFeatureAtPixel = function (pixel, callback, opt_options) {
12+
13+
this.forEachFeatureAtPixelDefault(pixel, callback, opt_options);
14+
15+
let layers = this.getLayers().getArray();
16+
let resolution = this.getView().getResolution();
17+
let coordinate = this.getCoordinateFromPixel(pixel);
18+
for (let i = 0; i < layers.length; i++) {
19+
if (layers[i].getSource()._forEachFeatureAtCoordinate) {
20+
layers[i].getSource()._forEachFeatureAtCoordinate(coordinate, resolution, callback, pixel);
21+
}
22+
}
23+
}
24+
}();

src/openlayers/core/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export {StyleUtils} from './StyleUtils';
2-
export {Util} from './Util';
2+
export {Util} from './Util';
3+
export {MapExtend} from './MapExtend';

src/openlayers/overlay/Graphic.js

Lines changed: 122 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import ol from 'openlayers';
2+
import '../core/MapExtend';
23
import {
34
Util
45
} from '../core/Util';
@@ -13,7 +14,12 @@ import {
1314
* @class ol.source.Graphic
1415
* @category Visualization Graphic
1516
* @classdesc 高效率点图层源。
16-
* @param options -{Object} 图形参数
17+
* @param options -{Object} 图形参数。如:<br>
18+
* graphics - {ol.Graphic} 高效率点图层点要素。<br>
19+
* map - [ol.Map]{@linkdoc-openlayers/ol.Map.html} openlayers 面对象。<br>
20+
* isHighLight - {boolean} 事件响应是否支持要素高亮。默认为 true,即默认支持高亮。<br>
21+
* highLightStyle - [ol.style]{@linkdoc-openlayers/ol.style.html} 高亮风格,默认为 defaultHighLightStyle。<br>
22+
* onClick - {function} 点击事件方法。将在下个版本弃用。<br>
1723
* @extends ol.source.ImageCanvas{@linkdoc-openlayers/ol.source.ImageCanvas}
1824
*/
1925
export class Graphic extends ol.source.ImageCanvas {
@@ -31,16 +37,20 @@ export class Graphic extends ol.source.ImageCanvas {
3137
this.graphics_ = options.graphics;
3238
this.map = options.map;
3339
this.highLightStyle = options.highLightStyle;
40+
//是否支持高亮,默认支持
41+
this.isHighLight = typeof options.isHighLight === "undefined" ? true : options.isHighLight;
3442
this.hitGraphicLayer = null;
35-
43+
this._forEachFeatureAtCoordinate = _forEachFeatureAtCoordinate;
3644

3745
var me = this;
46+
47+
//todo 将被弃用
3848
if (options.onClick) {
3949
me.map.on('click', function (e) {
4050
var coordinate = e.coordinate;
4151
var resolution = e.frameState.viewState.resolution;
4252
var pixel = e.pixel;
43-
me.forEachFeatureAtCoordinate(coordinate, resolution, options.onClick,pixel);
53+
me._forEachFeatureAtCoordinate(coordinate, resolution, options.onClick, pixel);
4454
});
4555
}
4656

@@ -118,6 +128,115 @@ export class Graphic extends ol.source.ImageCanvas {
118128
var y = (pixelP[1] - center[1]) * scaleRatio + center[1];
119129
return [x, y];
120130
}
131+
132+
/**
133+
* @private
134+
* @function ol.source.Graphic.prototype._forEachFeatureAtCoordinate
135+
* @description 获取在视图上的要素
136+
* @param coordinate -{string} 坐标
137+
* @param resolution -{number} 分辨率
138+
* @param callback -{function} 回调函数
139+
*/
140+
function _forEachFeatureAtCoordinate(coordinate, resolution, callback, evtPixel) {
141+
let graphics = me.getGraphicsInExtent();
142+
for (let i = graphics.length - 1; i >= 0; i--) {
143+
//已经被高亮的graphics 不被选选中
144+
if (graphics[i].getStyle() instanceof HitCloverShape) {
145+
continue;
146+
}
147+
let center = graphics[i].getGeometry().getCoordinates();
148+
let image = new ol.style.Style({
149+
image: graphics[i].getStyle()
150+
}).getImage();
151+
let extent = [];
152+
extent[0] = center[0] - image.getAnchor()[0] * resolution;
153+
extent[2] = center[0] + image.getAnchor()[0] * resolution;
154+
extent[1] = center[1] - image.getAnchor()[1] * resolution;
155+
extent[3] = center[1] + image.getAnchor()[1] * resolution;
156+
if (ol.extent.containsCoordinate(extent, coordinate)) {
157+
if (me.isHighLight) {
158+
me._highLight(center, image, graphics[i], evtPixel);
159+
}
160+
return callback(graphics[i]);
161+
}
162+
if (me.isHighLight) {
163+
me._highLightClose();
164+
}
165+
}
166+
return undefined;
167+
}
168+
169+
}
170+
171+
/**
172+
* @function ol.source.Graphic.prototype._highLightClose
173+
* @description 关闭高亮要素显示
174+
* @private
175+
*/
176+
_highLightClose() {
177+
this.selected = null;
178+
if (this.hitGraphicLayer) {
179+
this.map.removeLayer(this.hitGraphicLayer);
180+
this.hitGraphicLayer = null;
181+
}
182+
this.changed();
183+
}
184+
185+
/**
186+
* @function ol.source.Graphic.prototype._highLight
187+
* @description 高亮显示选中要素
188+
* @param selectGraphic - {ol.Graphic} 高效率点图层点要素
189+
* @param evtPixel - [ol.Pixel]{@linkdoc-openlayers/ol.html#.Pixel} 当前选中的屏幕像素坐标
190+
* @private
191+
*/
192+
_highLight(center, image, selectGraphic, evtPixel) {
193+
if (selectGraphic.getStyle() instanceof CloverShape) {
194+
if (this.hitGraphicLayer) {
195+
this.map.removeLayer(this.hitGraphicLayer);
196+
this.hitGraphicLayer = null;
197+
}
198+
var pixel = this.map.getPixelFromCoordinate([center[0], center[1]]);
199+
//点击点与中心点的角度
200+
evtPixel = evtPixel || [0, 0];
201+
var angle = (Math.atan2(evtPixel[1] - pixel[1], evtPixel[0] - pixel[0])) / Math.PI * 180;
202+
angle = angle > 0 ? angle : 360 + angle;
203+
//确定扇叶
204+
var index = Math.ceil(angle / (image.getAngle() + image.getSpaceAngle()));
205+
//扇叶的起始角度
206+
var sAngle = (index - 1) * (image.getAngle() + image.getSpaceAngle());
207+
//渲染参数
208+
var opts = {
209+
stroke: new ol.style.Stroke({
210+
color: "#ff0000",
211+
width: 1
212+
}),
213+
fill: new ol.style.Fill({
214+
color: "#0099ff"
215+
}),
216+
radius: image.getRadius(),
217+
angle: image.getAngle(),
218+
eAngle: sAngle + image.getAngle(),
219+
sAngle: sAngle
220+
};
221+
if (this.highLightStyle && this.highLightStyle instanceof HitCloverShape) {
222+
opts.stroke = this.highLightStyle.getStroke();
223+
opts.fill = this.highLightStyle.getFill();
224+
opts.radius = this.highLightStyle.getRadius();
225+
opts.angle = this.highLightStyle.getAngle();
226+
}
227+
var hitGraphic = new ol.Graphic(new ol.geom.Point(center));
228+
hitGraphic.setStyle(new HitCloverShape(opts));
229+
this.hitGraphicLayer = new ol.layer.Image({
230+
source: new ol.source.Graphic({
231+
map: this.map,
232+
graphics: [hitGraphic]
233+
})
234+
});
235+
this.map.addLayer(this.hitGraphicLayer);
236+
} else {
237+
this.selected = selectGraphic;
238+
this.changed();
239+
}
121240
}
122241

123242
/**
@@ -143,86 +262,6 @@ export class Graphic extends ol.source.ImageCanvas {
143262
return graphics;
144263
}
145264

146-
/**
147-
* @private
148-
* @function ol.source.Graphic.prototype.forEachFeatureAtCoordinate
149-
* @description 获取在视图上的要素
150-
* @param coordinate -{string} 坐标
151-
* @param resolution -{number} 分辨率
152-
* @param callback -{function} 回调函数
153-
*/
154-
forEachFeatureAtCoordinate(coordinate, resolution, callback, evtPixel) {
155-
var graphics = this.getGraphicsInExtent();
156-
for (var i = graphics.length - 1; i > 0; i--) {
157-
var center = graphics[i].getGeometry().getCoordinates();
158-
var image = new ol.style.Style({
159-
image: graphics[i].getStyle()
160-
}).getImage();
161-
var extent = [];
162-
extent[0] = center[0] - image.getAnchor()[0] * resolution;
163-
extent[2] = center[0] + image.getAnchor()[0] * resolution;
164-
extent[1] = center[1] - image.getAnchor()[1] * resolution;
165-
extent[3] = center[1] + image.getAnchor()[1] * resolution;
166-
if (ol.extent.containsCoordinate(extent, coordinate)) {
167-
if (graphics[i].getStyle() instanceof CloverShape) {
168-
if (this.hitGraphicLayer) {
169-
this.map.removeLayer(this.hitGraphicLayer);
170-
this.hitGraphicLayer = null;
171-
}
172-
var pixel = this.map.getPixelFromCoordinate([center[0], center[1]]);
173-
//点击点与中心点的角度
174-
evtPixel = evtPixel || [0, 0];
175-
var angle = (Math.atan2(evtPixel[1] - pixel[1], evtPixel[0] - pixel[0])) / Math.PI * 180;
176-
angle = angle > 0 ? angle : 360 + angle;
177-
//确定扇叶
178-
var index = Math.ceil(angle / (image.getAngle() + image.getSpaceAngle()));
179-
//扇叶的起始角度
180-
var sAngle = (index - 1) * (image.getAngle() + image.getSpaceAngle());
181-
//渲染参数
182-
var opts = {
183-
stroke: new ol.style.Stroke({
184-
color: "#ff0000",
185-
width: 1
186-
}),
187-
fill: new ol.style.Fill({
188-
color: "#0099ff"
189-
}),
190-
radius: image.getRadius(),
191-
angle: image.getAngle(),
192-
eAngle: sAngle + image.getAngle(),
193-
sAngle: sAngle
194-
};
195-
if (this.highLightStyle && this.highLightStyle instanceof HitCloverShape) {
196-
opts.stroke = this.highLightStyle.getStroke();
197-
opts.fill = this.highLightStyle.getFill();
198-
opts.radius = this.highLightStyle.getRadius();
199-
opts.angle = this.highLightStyle.getAngle();
200-
}
201-
var hitGraphic = new ol.Graphic(new ol.geom.Point(center));
202-
hitGraphic.setStyle(new HitCloverShape(opts));
203-
this.hitGraphicLayer = new ol.layer.Image({
204-
source: new ol.source.Graphic({
205-
map: this.map,
206-
graphics: [hitGraphic]
207-
})
208-
});
209-
this.map.addLayer(this.hitGraphicLayer);
210-
} else {
211-
this.selected = graphics[i];
212-
this.changed();
213-
}
214-
callback(graphics[i]);
215-
return;
216-
}
217-
this.selected = null;
218-
if (this.hitGraphicLayer) {
219-
this.map.removeLayer(this.hitGraphicLayer);
220-
this.hitGraphicLayer = null;
221-
}
222-
this.changed();
223-
}
224-
callback();
225-
}
226265
}
227266

228267
ol.source.Graphic = Graphic;

test/openlayers/overlay/GraphicSpec.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ describe('openlayers_GraphicLayer', () => {
9696
var a = new Graphic({
9797
graphics: graphics,
9898
map: map
99-
}).forEachFeatureAtCoordinate(coors[1], 1, (result) => {
99+
})._forEachFeatureAtCoordinate(coors[1], 1, (result) => {
100100
console.log(result);
101101
});
102102
expect(a).not.toBeNull();
@@ -228,17 +228,25 @@ describe('openlayers_GraphicLayer', () => {
228228
});
229229
map.addLayer(graphicLayer);
230230
});
231+
231232
setTimeout(() => {
232233
expect(1).not.toBeNull();
233-
graphicLayer.getSource().forEachFeatureAtCoordinate(coors[2], 1, (result) => {
234+
graphicLayer.getSource()._forEachFeatureAtCoordinate(coors[2], 1, (result) => {
234235
console.log(result);
235236
});
236-
graphicLayer.getSource().forEachFeatureAtCoordinate(coors[1], 1, (result) => {
237+
graphicLayer.getSource()._forEachFeatureAtCoordinate(coors[1], 1, (result) => {
237238
console.log(result);
238239
});
239-
graphicLayer.getSource().forEachFeatureAtCoordinate([-126.16, 39.05], 1, (result) => {
240+
graphicLayer.getSource()._forEachFeatureAtCoordinate([-126.16, 39.05], 1, (result) => {
240241
console.log(result);
241242
});
243+
244+
let pixel = map.getPixelFromCoordinate([-36.16, 39.05]);
245+
map.forEachFeatureAtPixel(pixel,
246+
(graphic) => {
247+
expect(graphic).not.toBeNull();
248+
console.log(graphic);
249+
});
242250
map.removeLayer(graphicLayer);
243251
done();
244252
}, 1000)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy