Webgl immediate implementation for points
Internally uses a replay group to share code. Modifies the dynamic data example to use PointGeometry and Feature in addition to MultiPoint.
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.source.MapQuest');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
var map = new ol.Map({
|
||||
@@ -14,6 +17,7 @@ var map = new ol.Map({
|
||||
source: new ol.source.MapQuest({layer: 'sat'})
|
||||
})
|
||||
],
|
||||
renderer: exampleNS.getRendererFromQueryString(),
|
||||
target: 'map',
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
@@ -28,6 +32,20 @@ var imageStyle = new ol.style.Circle({
|
||||
stroke: new ol.style.Stroke({color: 'red', width: 1})
|
||||
});
|
||||
|
||||
var headInnerImageStyle = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 2,
|
||||
snapToPixel: false,
|
||||
fill: new ol.style.Fill({color: 'blue'})
|
||||
})
|
||||
});
|
||||
|
||||
var headOuterImageStyle = new ol.style.Circle({
|
||||
radius: 5,
|
||||
snapToPixel: false,
|
||||
fill: new ol.style.Fill({color: 'black'})
|
||||
});
|
||||
|
||||
var n = 200;
|
||||
var omegaTheta = 30000; // Rotation period in ms
|
||||
var R = 7e6;
|
||||
@@ -48,6 +66,16 @@ map.on('postcompose', function(event) {
|
||||
vectorContext.setImageStyle(imageStyle);
|
||||
vectorContext.drawMultiPointGeometry(
|
||||
new ol.geom.MultiPoint(coordinates), null);
|
||||
|
||||
var headPoint = new ol.geom.Point(coordinates[coordinates.length - 1]);
|
||||
var headFeature = new ol.Feature(headPoint);
|
||||
vectorContext.drawFeature(headFeature, headInnerImageStyle);
|
||||
|
||||
vectorContext.setImageStyle(headOuterImageStyle);
|
||||
vectorContext.drawMultiPointGeometry(headPoint, null);
|
||||
|
||||
vectorContext.flush();
|
||||
|
||||
map.render();
|
||||
});
|
||||
map.render();
|
||||
|
||||
@@ -6,7 +6,7 @@ goog.provide('ol.render.IVectorContext');
|
||||
|
||||
/**
|
||||
* VectorContext interface. Currently implemented by
|
||||
* {@link ol.render.canvas.Immediate}
|
||||
* {@link ol.render.canvas.Immediate} and {@link ol.render.webgl.Immediate}
|
||||
* @interface
|
||||
*/
|
||||
ol.render.IVectorContext = function() {
|
||||
@@ -15,7 +15,7 @@ ol.render.IVectorContext = function() {
|
||||
|
||||
/**
|
||||
* @param {number} zIndex Z index.
|
||||
* @param {function(ol.render.canvas.Immediate)} callback Callback.
|
||||
* @param {function(ol.render.IVectorContext)} callback Callback.
|
||||
*/
|
||||
ol.render.IVectorContext.prototype.drawAsync = function(zIndex, callback) {
|
||||
};
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
goog.provide('ol.render.webgl.Immediate');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.render.webgl.ReplayGroup');
|
||||
|
||||
|
||||
|
||||
@@ -6,17 +11,102 @@ goog.provide('ol.render.webgl.Immediate');
|
||||
* @constructor
|
||||
* @implements {ol.render.IVectorContext}
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
* @param {ol.Coordinate} center Center.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} rotation Rotation.
|
||||
* @param {ol.Size} size Size.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.Immediate = function(context, pixelRatio) {
|
||||
ol.render.webgl.Immediate = function(context,
|
||||
center, resolution, rotation, size, extent, pixelRatio) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.context_ = context;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.center_ = center;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.extent_ = extent;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.pixelRatio_ = pixelRatio;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.size_ = size;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.rotation_ = rotation;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.resolution_ = resolution;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.style.Image}
|
||||
*/
|
||||
this.imageStyle_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.style.Text}
|
||||
*/
|
||||
this.textStyle_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string,
|
||||
* Array.<function(ol.render.webgl.Immediate)>>}
|
||||
*/
|
||||
this.callbacksByZIndex_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* FIXME: empty description for jsdoc
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.flush = function() {
|
||||
/** @type {Array.<number>} */
|
||||
var zs = goog.array.map(goog.object.getKeys(this.callbacksByZIndex_), Number);
|
||||
goog.array.sort(zs);
|
||||
var i, ii, callbacks, j, jj;
|
||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||
callbacks = this.callbacksByZIndex_[zs[i].toString()];
|
||||
for (j = 0, jj = callbacks.length; j < jj; ++j) {
|
||||
callbacks[j](this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} zIndex Z index.
|
||||
* @param {function(ol.render.webgl.Immediate)} callback Callback.
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawAsync = function(zIndex, callback) {
|
||||
var zIndexKey = zIndex.toString();
|
||||
var callbacks = this.callbacksByZIndex_[zIndexKey];
|
||||
if (goog.isDef(callbacks)) {
|
||||
callbacks.push(callback);
|
||||
} else {
|
||||
this.callbacksByZIndex_[zIndexKey] = [callback];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -32,6 +122,24 @@ ol.render.webgl.Immediate.prototype.drawCircleGeometry =
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawFeature = function(feature, style) {
|
||||
var geometry = feature.getGeometry();
|
||||
if (!goog.isDefAndNotNull(geometry) ||
|
||||
!ol.extent.intersects(this.extent_, geometry.getExtent())) {
|
||||
return;
|
||||
}
|
||||
var zIndex = style.getZIndex();
|
||||
if (!goog.isDef(zIndex)) {
|
||||
zIndex = 0;
|
||||
}
|
||||
this.drawAsync(zIndex, function(render) {
|
||||
render.setFillStrokeStyle(style.getFill(), style.getStroke());
|
||||
render.setImageStyle(style.getImage());
|
||||
render.setTextStyle(style.getText());
|
||||
var renderGeometry =
|
||||
ol.render.webgl.Immediate.GEOMETRY_RENDERERS_[geometry.getType()];
|
||||
goog.asserts.assert(goog.isDef(renderGeometry));
|
||||
renderGeometry.call(render, geometry, null);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -40,6 +148,15 @@ ol.render.webgl.Immediate.prototype.drawFeature = function(feature, style) {
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawGeometryCollectionGeometry =
|
||||
function(geometryCollectionGeometry, data) {
|
||||
var geometries = geometryCollectionGeometry.getGeometriesArray();
|
||||
var renderers = ol.render.webgl.Immediate.GEOMETRY_RENDERERS_;
|
||||
var i, ii;
|
||||
for (i = 0, ii = geometries.length; i < ii; ++i) {
|
||||
var geometry = geometries[i];
|
||||
var geometryRenderer = renderers[geometry.getType()];
|
||||
goog.asserts.assert(goog.isDef(geometryRenderer));
|
||||
geometryRenderer.call(this, geometry, data);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +165,20 @@ ol.render.webgl.Immediate.prototype.drawGeometryCollectionGeometry =
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawPointGeometry =
|
||||
function(pointGeometry, data) {
|
||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||
var replay = replayGroup.getReplay(0, ol.render.ReplayType.IMAGE);
|
||||
replay.setImageStyle(this.imageStyle_);
|
||||
replay.drawPointGeometry(pointGeometry, data);
|
||||
replay.finish(this.context_);
|
||||
// default colors
|
||||
var opacity = 1;
|
||||
var brightness = 0;
|
||||
var contrast = 1;
|
||||
var hue = 0;
|
||||
var saturation = 1;
|
||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||
this.size_, this.extent_, this.pixelRatio_, opacity, brightness,
|
||||
contrast, hue, saturation, {});
|
||||
};
|
||||
|
||||
|
||||
@@ -72,6 +203,20 @@ ol.render.webgl.Immediate.prototype.drawMultiLineStringGeometry =
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawMultiPointGeometry =
|
||||
function(multiPointGeometry, data) {
|
||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||
var replay = replayGroup.getReplay(0, ol.render.ReplayType.IMAGE);
|
||||
replay.setImageStyle(this.imageStyle_);
|
||||
replay.drawMultiPointGeometry(multiPointGeometry, data);
|
||||
replay.finish(this.context_);
|
||||
// default colors
|
||||
var opacity = 1;
|
||||
var brightness = 0;
|
||||
var contrast = 1;
|
||||
var hue = 0;
|
||||
var saturation = 1;
|
||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||
this.size_, this.extent_, this.pixelRatio_, opacity, brightness,
|
||||
contrast, hue, saturation, {});
|
||||
};
|
||||
|
||||
|
||||
@@ -96,6 +241,13 @@ ol.render.webgl.Immediate.prototype.drawPolygonGeometry =
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawText =
|
||||
function(flatCoordinates, offset, end, stride, geometry, data) {
|
||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||
var replay = replayGroup.getReplay(0, ol.render.ReplayType.TEXT);
|
||||
replay.setTextStyle(this.textStyle_);
|
||||
replay.drawText(flatCoordinates, offset, end, stride, geometry, data);
|
||||
replay.finish(this.context_);
|
||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||
this.size_, this.extent_, this.pixelRatio_, {});
|
||||
};
|
||||
|
||||
|
||||
@@ -111,6 +263,7 @@ ol.render.webgl.Immediate.prototype.setFillStrokeStyle =
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.setImageStyle = function(imageStyle) {
|
||||
this.imageStyle_ = imageStyle;
|
||||
};
|
||||
|
||||
|
||||
@@ -118,4 +271,20 @@ ol.render.webgl.Immediate.prototype.setImageStyle = function(imageStyle) {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.setTextStyle = function(textStyle) {
|
||||
this.textStyle_ = textStyle;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @private
|
||||
* @type {Object.<ol.geom.GeometryType,
|
||||
* function(this: ol.render.webgl.Immediate, ol.geom.Geometry,
|
||||
* Object)>}
|
||||
*/
|
||||
ol.render.webgl.Immediate.GEOMETRY_RENDERERS_ = {
|
||||
'Point': ol.render.webgl.Immediate.prototype.drawPointGeometry,
|
||||
'MultiPoint': ol.render.webgl.Immediate.prototype.drawMultiPointGeometry,
|
||||
'GeometryCollection':
|
||||
ol.render.webgl.Immediate.prototype.drawGeometryCollectionGeometry
|
||||
};
|
||||
|
||||
@@ -237,7 +237,16 @@ ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ =
|
||||
function(type, context, frameState) {
|
||||
var layer = this.getLayer();
|
||||
if (layer.hasListener(type)) {
|
||||
var render = new ol.render.webgl.Immediate(context, frameState.pixelRatio);
|
||||
var viewState = frameState.viewState;
|
||||
var resolution = viewState.resolution;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var extent = frameState.extent;
|
||||
var center = viewState.center;
|
||||
var rotation = viewState.rotation;
|
||||
var size = frameState.size;
|
||||
|
||||
var render = new ol.render.webgl.Immediate(
|
||||
context, center, resolution, rotation, size, extent, pixelRatio);
|
||||
var composeEvent = new ol.render.Event(
|
||||
type, layer, render, null, frameState, null, context);
|
||||
layer.dispatchEvent(composeEvent);
|
||||
|
||||
@@ -273,14 +273,19 @@ ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ =
|
||||
var map = this.getMap();
|
||||
if (map.hasListener(type)) {
|
||||
var context = this.context_;
|
||||
var extent = frameState.extent;
|
||||
|
||||
var extent = frameState.extent;
|
||||
var size = frameState.size;
|
||||
var viewState = frameState.viewState;
|
||||
var resolution = viewState.resolution;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
|
||||
var resolution = viewState.resolution;
|
||||
var center = viewState.center;
|
||||
var rotation = viewState.rotation;
|
||||
var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
|
||||
|
||||
var vectorContext = new ol.render.webgl.Immediate(context, pixelRatio);
|
||||
var vectorContext = new ol.render.webgl.Immediate(context,
|
||||
center, resolution, rotation, size, extent, pixelRatio);
|
||||
var replayGroup = new ol.render.webgl.ReplayGroup(tolerance, extent);
|
||||
var composeEvent = new ol.render.Event(type, map, vectorContext,
|
||||
replayGroup, frameState, null, context);
|
||||
@@ -288,9 +293,6 @@ ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ =
|
||||
|
||||
replayGroup.finish(context);
|
||||
if (!replayGroup.isEmpty()) {
|
||||
var center = viewState.center;
|
||||
var rotation = viewState.rotation;
|
||||
var size = frameState.size;
|
||||
// use default color values
|
||||
var opacity = 1;
|
||||
var brightness = 0;
|
||||
|
||||
Reference in New Issue
Block a user