Skip to content

Commit

Permalink
regularshape example with style expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
MoonE committed Sep 17, 2023
1 parent 70e6da2 commit f96b1a4
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 110 deletions.
200 changes: 96 additions & 104 deletions examples/regularshape.js
Expand Up @@ -4,121 +4,116 @@ import Point from '../src/ol/geom/Point.js';
import VectorLayer from '../src/ol/layer/Vector.js';
import VectorSource from '../src/ol/source/Vector.js';
import View from '../src/ol/View.js';
import {Fill, RegularShape, Stroke, Style} from '../src/ol/style.js';

const stroke = new Stroke({color: 'black', width: 2});
const fill = new Fill({color: 'red'});

const styles = {
'square': new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
points: 4,
radius: 10,
angle: Math.PI / 4,
}),
}),
'rectangle': new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
radius: 10 / Math.SQRT2,
radius2: 10,
points: 4,
angle: 0,
scale: [1, 0.5],
}),
}),
'triangle': new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
points: 3,
radius: 10,
rotation: Math.PI / 4,
angle: 0,
}),
}),
'star': new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
points: 5,
radius: 10,
radius2: 4,
angle: 0,
}),
}),
'cross': new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
points: 4,
radius: 10,
radius2: 0,
angle: 0,
}),
}),
'x': new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
points: 4,
radius: 10,
radius2: 0,
angle: Math.PI / 4,
}),
}),
'square': {
'shape-fill-color': ['var', 'color'],
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-points': 4,
'shape-radius': 10,
'shape-angle': Math.PI / 4,
},
'rectangle': {
'shape-fill-color': 'red',
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-radius': 10 / Math.SQRT2,
'shape-radius2': 10,
'shape-points': 4,
'shape-angle': 0,
'shape-scale': [1, 0.5],
},
'triangle': {
'shape-fill-color': 'red',
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-points': 3,
'shape-radius': 10,
'shape-rotation': Math.PI / 4,
'shape-angle': 0,
},
'star': {
'shape-fill-color': 'red',
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-points': 5,
'shape-radius': 10,
'shape-radius2': 4,
'shape-rotation': 4,
'shape-angle': 0,
},
'cross': {
'shape-fill-color': 'red',
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-points': 4,
'shape-radius': 10,
'shape-radius2': 0,
'shape-rotation': 0,
'shape-angle': 0,
},
'x': {
'shape-fill-color': 'red',
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-points': 4,
'shape-radius': 10,
'shape-radius2': 0,
'shape-rotation': 0,
'shape-angle': Math.PI / 4,
},
'stacked': [
new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
points: 4,
radius: 5,
angle: Math.PI / 4,
displacement: [0, 10],
}),
}),
new Style({
image: new RegularShape({
fill: fill,
stroke: stroke,
points: 4,
radius: 10,
angle: Math.PI / 4,
}),
}),
{
'shape-fill-color': 'red',
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-points': 4,
'shape-radius': 5,
'shape-angle': Math.PI / 4,
'shape-displacement': [0, 10],
},
{
'shape-fill-color': 'red',
'shape-stroke-width': 2,
'shape-stroke-color': 'black',
'shape-points': 4,
'shape-radius': 10,
'shape-angle': Math.PI / 4,
},
],
};

const styleKeys = [
'x',
'cross',
'star',
'triangle',
'square',
'rectangle',
'stacked',
];
const count = 250;
const styleKeys = Object.keys(styles);
const count = 5000;
const features = new Array(count);
const e = 4500000;
for (let i = 0; i < count; ++i) {
const coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
const styleIndex = Math.floor(Math.random() * (i % styleKeys.length));
features[i] = new Feature(new Point(coordinates));
features[i].setStyle(
styles[styleKeys[Math.floor(Math.random() * styleKeys.length)]]
);
features[i].set('shape', styleKeys[styleIndex], true);
}

const source = new VectorSource({
features: features,
});
const styleVariables = {
color: 'red',
};

const vectorLayer = new VectorLayer({
source: source,
source: new VectorSource({
features: features,
}),
variables: styleVariables,
style: styleKeys.map((key, index) => {
const rule = {
filter: ['==', ['get', 'shape'], key],
style: styles[key],
};
if (index > 0) {
rule.else = true;
}
return rule;
}),
});

const map = new Map({
Expand All @@ -134,9 +129,6 @@ const colors = ['blue', 'green', 'yellow', 'aqua', 'red'];
let currentColor = 0;

document.getElementById('color-changer').addEventListener('click', function () {
styles.square
.getImage()
.setFill(new Fill({color: colors[currentColor % colors.length]}));
styleVariables.color = colors[currentColor++ % colors.length];
vectorLayer.changed();
currentColor++;
});
16 changes: 12 additions & 4 deletions src/ol/layer/BaseVector.js
Expand Up @@ -64,6 +64,7 @@ import {
* batches will be recreated when no animation is active.
* @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will
* be recreated during interactions. See also `updateWhileAnimating`.
* @property {Object} [variables] Style variables.
* @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.
*/

Expand Down Expand Up @@ -130,6 +131,12 @@ class BaseVectorLayer extends Layer {
*/
this.styleFunction_ = undefined;

/**
* @type {Object}
* @private
*/
this.variables_ = options.variables || {};

this.setStyle(options.style);

/**
Expand Down Expand Up @@ -269,7 +276,7 @@ class BaseVectorLayer extends Layer {
* @api
*/
setStyle(style) {
this.style_ = toStyleLike(style);
this.style_ = toStyleLike(style, this.variables_);
this.styleFunction_ =
style === null ? undefined : toStyleFunction(this.style_);
this.changed();
Expand All @@ -281,9 +288,10 @@ class BaseVectorLayer extends Layer {
* styles, and arrays of rules are converted into style functions.
*
* @param {import("../style/Style.js").StyleLike|import("../style/flat.js").FlatStyleLike|null} [style] Layer style.
* @param {Object} [variables] Style variables.
* @return {import("../style/Style.js").StyleLike|null} The style.
*/
function toStyleLike(style) {
function toStyleLike(style, variables) {
if (style === undefined) {
return createDefaultStyle;
}
Expand Down Expand Up @@ -333,12 +341,12 @@ function toStyleLike(style) {
}
rules[i] = candidate;
}
return rulesToStyleFunction(rules);
return rulesToStyleFunction(rules, variables);
}

const flatStyles =
/** @type {Array<import("../style/flat.js").FlatStyle>} */ (style);
return flatStylesToStyleFunction(flatStyles);
return flatStylesToStyleFunction(flatStyles, variables);
}

export default BaseVectorLayer;
8 changes: 6 additions & 2 deletions src/ol/render/canvas/style.js
Expand Up @@ -66,12 +66,14 @@ function always(context) {
* and pass a more complete evaluation context (variables, zoom, time, etc.).
*
* @param {Array<import('../../style/flat.js').Rule>} rules The rules.
* @param {Object} variables Style variables
* @return {import('../../style/Style.js').StyleFunction} A style function.
*/
export function rulesToStyleFunction(rules) {
export function rulesToStyleFunction(rules, variables) {
const parsingContext = newParsingContext();
const evaluator = buildRuleSet(rules, parsingContext);
const evaluationContext = newEvaluationContext();
evaluationContext.variables = variables;
return function (feature, resolution) {
evaluationContext.properties = feature.getPropertiesInternal();
evaluationContext.resolution = resolution;
Expand All @@ -85,9 +87,10 @@ export function rulesToStyleFunction(rules) {
* and pass a more complete evaluation context (variables, zoom, time, etc.).
*
* @param {Array<import('../../style/flat.js').FlatStyle>} flatStyles The flat styles.
* @param {Object} variables Style variables
* @return {import('../../style/Style.js').StyleFunction} A style function.
*/
export function flatStylesToStyleFunction(flatStyles) {
export function flatStylesToStyleFunction(flatStyles, variables) {
const parsingContext = newParsingContext();
const length = flatStyles.length;

Expand All @@ -99,6 +102,7 @@ export function flatStylesToStyleFunction(flatStyles) {
evaluators[i] = buildStyle(flatStyles[i], parsingContext);
}
const evaluationContext = newEvaluationContext();
evaluationContext.variables = variables;

/**
* @type {Array<Style>}
Expand Down

0 comments on commit f96b1a4

Please sign in to comment.