Skip to content

Commit

Permalink
refactor(Style): to sqaush review
Browse files Browse the repository at this point in the history
  • Loading branch information
ftoromanoff committed Dec 7, 2023
1 parent f19281e commit b9287ba
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 90 deletions.
2 changes: 1 addition & 1 deletion examples/source_file_gpx_3d.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@

var waypointGeometry = new itowns.THREE.BoxGeometry(1, 1, 80);
var waypointMaterial = new itowns.THREE.MeshBasicMaterial({ color: 0xffffff });
// Listen for globe full initialisation event
const style = {
stroke: {
color: 'red',
Expand All @@ -71,6 +70,7 @@
color: 'white',
}
};
// Listen for globe full initialisation event
view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, function () {
console.info('Globe initialized');
itowns.Fetcher.xml('https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/ULTRA2009.gpx')
Expand Down
59 changes: 23 additions & 36 deletions src/Converter/Feature2Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import Extent from 'Core/Geographic/Extent';
import Coordinates from 'Core/Geographic/Coordinates';
import Style, { StyleContext } from 'Core/Style';

const defaultStyle = new Style();
const context = new StyleContext();
let userStyle = new Style();
let style;

/**
* Draw polygon (contour, line edge and fill) based on feature vertices into canvas
Expand All @@ -16,26 +17,15 @@ let userStyle = new Style();
* @param {Object[]} indices - Contains the indices that define the geometry.
* Objects stored in this array have two properties, an `offset` and a `count`.
* The offset is related to the overall number of vertices in the Feature.
* @param {Object} style - object defining the style of the polygon.
* @param {Number} size - The size of the feature.
* @param {Number} extent - The extent.
* @param {Number} invCtxScale - The ration to scale line width and radius circle.
* @param {Boolean} canBeFilled - true if feature.type == FEATURE_TYPES.POLYGON
*/
function drawPolygon(ctx, vertices, indices = [{ offset: 0, count: 1 }], style = {}, size, extent, invCtxScale, canBeFilled) {
function drawPolygon(ctx, vertices, indices = [{ offset: 0, count: 1 }], size, extent, invCtxScale, canBeFilled) {
if (vertices.length === 0) {
return;
}
if (style.length) {
for (const s of style) {
_drawPolygon(ctx, vertices, indices, s, size, extent, invCtxScale, canBeFilled);
}
} else {
_drawPolygon(ctx, vertices, indices, style, size, extent, invCtxScale, canBeFilled);
}
}

function _drawPolygon(ctx, vertices, indices, style, size, extent, invCtxScale, canBeFilled) {
// build contour
const path = new Path2D();

Expand All @@ -49,10 +39,10 @@ function _drawPolygon(ctx, vertices, indices, style, size, extent, invCtxScale,
}
}
}
Style.prototype.applyToCanvasPolygon.call(style, ctx, path, invCtxScale, canBeFilled);
style.applyToCanvasPolygon(ctx, path, invCtxScale, canBeFilled);
}

function drawPoint(ctx, x, y, style = {}, invCtxScale) {
function drawPoint(ctx, x, y, invCtxScale) {
ctx.beginPath();
const opacity = style.point.opacity == undefined ? 1.0 : style.point.opacity;
if (opacity !== ctx.globalAlpha) {
Expand Down Expand Up @@ -81,28 +71,24 @@ function drawFeature(ctx, feature, extent, invCtxScale) {
if (Extent.intersectsExtent(geometry.extent, extent)) {
context.setGeometry(geometry);

userStyle.setContext(context);

if (userStyle) {
if (
feature.type === FEATURE_TYPES.POINT && userStyle.point
) {
// cross multiplication to know in the extent system the real size of
// the point
const px = (Math.round(userStyle.point.radius * invCtxScale) || 3 * invCtxScale) * scaleRadius;
for (const indice of geometry.indices) {
const offset = indice.offset * feature.size;
const count = offset + indice.count * feature.size;
for (let j = offset; j < count; j += feature.size) {
coord.setFromArray(feature.vertices, j);
if (extent.isPointInside(coord, px)) {
drawPoint(ctx, feature.vertices[j], feature.vertices[j + 1], userStyle, invCtxScale);
}
if (
feature.type === FEATURE_TYPES.POINT && style.point
) {
// cross multiplication to know in the extent system the real size of
// the point
const px = (Math.round(style.point.radius * invCtxScale) || 3 * invCtxScale) * scaleRadius;
for (const indice of geometry.indices) {
const offset = indice.offset * feature.size;
const count = offset + indice.count * feature.size;
for (let j = offset; j < count; j += feature.size) {
coord.setFromArray(feature.vertices, j);
if (extent.isPointInside(coord, px)) {
drawPoint(ctx, feature.vertices[j], feature.vertices[j + 1], invCtxScale);
}
}
} else {
drawPolygon(ctx, feature.vertices, geometry.indices, userStyle, feature.size, extent, invCtxScale, (feature.type == FEATURE_TYPES.POLYGON));
}
} else {
drawPolygon(ctx, feature.vertices, geometry.indices, feature.size, extent, invCtxScale, (feature.type == FEATURE_TYPES.POLYGON));
}
}
}
Expand All @@ -121,9 +107,10 @@ const featureExtent = new Extent('EPSG:4326', 0, 0, 0, 0);
export default {
// backgroundColor is a THREE.Color to specify a color to fill the texture
// with, given there is no feature passed in parameter
createTextureFromFeature(collection, extent, sizeTexture, layerStyle = userStyle, backgroundColor) {
createTextureFromFeature(collection, extent, sizeTexture, layerStyle, backgroundColor) {
style = layerStyle || defaultStyle;
style.setContext(context);
let texture;
userStyle = layerStyle;

if (collection) {
// A texture is instancied drawn canvas
Expand Down
86 changes: 42 additions & 44 deletions src/Core/Style.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export function readExpression(property, ctx) {
}
if (typeof property === 'string' || property instanceof String) {
property = property.replace(/\{(.+?)\}/g, (a, b) => (ctx.properties[b] || '')).trim();
// return property.replace(/\{(.+?)\}/g, (a, b) => (ctx.properties[b] || '')).trim();
}
if (property instanceof Function) {
// TOBREAK: Pass the current `context` as a unique parameter.
Expand Down Expand Up @@ -131,18 +130,33 @@ const textAnchorPosition = {
'top-left': [0, 0],
};

function defineStyleProperty(style, category, parameter, value, defaultValue) {
/**
* Defines a property for the given Style for a specific parameter in a given category (one of fill, stroke, point, text, icon or zoom),
* by generating its getter and setter.
* The getter is in charge of returning the right style value from the following ones if they are defined (in that specific order):
* the value set by the user (`userValue`)
* the value read from the data source (`dataValue`)
* the default fallback value (`defaultValue`).
* The setter can be called to change dynamically the value.
* @param {Style} style - The Style instance to set.
* @param {string} category - The category (fill, stroke, point, test, icon or zoom) to set.
* @param {string} parameter - The parameter of the category to set.
* @param {All} userValue - The value given by the user (if any). Can be undefined.
* @param {All} [defaultValue] - The default value to return (if needed).
*/
function defineStyleProperty(style, category, parameter, userValue, defaultValue) {
let property;
Object.defineProperty(
style[category],
parameter,
{
enumerable: true,
get: () => {
if (property) { return property; }
if (value) { return readExpression(value, style.context); }
const dataValue = style.context.fStyle?.[category]?.[parameter];
if (dataValue) { return readExpression(dataValue, style.context); }
// != to check for 'undefined' and 'null' value)
if (property != undefined) { return property; }
if (userValue != undefined) { return readExpression(userValue, style.context); }
const dataValue = style.context.featureStyle?.[category]?.[parameter];
if (dataValue != undefined) { return readExpression(dataValue, style.context); }
if (defaultValue instanceof Function) {
return defaultValue(style.context.properties, style.context);
}
Expand All @@ -160,20 +174,21 @@ function defineStyleProperty(style, category, parameter, value, defaultValue) {
* type of feature and what is needed (fill, stroke or draw a point, etc.) as well as where to get its
* properties and its coordinates (for base_altitude).
*
* @property {number} zoom Current zoom to display the FeatureGeometry.
* @property {Object} collection The FeatureCollection to which the FeatureGeometry is attached.
* @property {Object} properties Properties of the FeatureGeometry.
* @property {string} type Geometry type of the feature. Can be `point`, `line`, or `polygon`.
* @property {Style} style Style of the FeatureGeometry computed from Layer.style and user.style.
* @property {Coordinates} coordinates The coordinates (in world space) of the last vertex (x, y, z) set with
* @property {number} zoom Current zoom to display the FeatureGeometry.
* @property {Object} collection The FeatureCollection to which the FeatureGeometry is attached.
* @property {Object} properties Properties of the FeatureGeometry.
* @property {string} type Geometry type of the feature. Can be `point`, `line`, or `polygon`.
* @property {StyleOptions|Function}featureStyle StyleOptions object (or a function returning one) to get style
* information at feature and FeatureGeometry level from the data parsed.
* @property {Coordinates} coordinates The coordinates (in world space) of the last vertex (x, y, z) set with
* setLocalCoordinatesFromArray().
* private properties:
* @property {Coordinates} worldCoord @private Coordinates object to store coordinates in world space.
* @property {Coordinates} localCoordinates @private Coordinates object to store coordinates in local space.
* @property {boolean} worldCoordsComputed @private Have the world coordinates already been computed
* from the local coordinates?
* @property {Feature} feature @private The itowns feature of interest.
* @property {FeatureGeometry} geometry @private The FeatureGeometry to compute the style.
* @property {Coordinates} worldCoord @private Coordinates object to store coordinates in world space.
* @property {Coordinates} localCoordinates @private Coordinates object to store coordinates in local space.
* @property {boolean} worldCoordsComputed @private Have the world coordinates already been computed
* from the local coordinates?
* @property {Feature} feature @private The itowns feature of interest.
* @property {FeatureGeometry} geometry @private The FeatureGeometry to compute the style.
*/
export class StyleContext {
#worldCoord = new Coordinates('EPSG:4326', 0, 0, 0);
Expand Down Expand Up @@ -211,7 +226,7 @@ export class StyleContext {
get type() {
return this.#feature.type;
}
get fStyle() {
get featureStyle() {
let featureStyle = this.#feature.style;
if (featureStyle instanceof Function) {
featureStyle = featureStyle(this.properties, this);
Expand All @@ -236,10 +251,6 @@ function _addIcon(icon, domElement, opt) {

cIcon.setAttribute('class', 'itowns-icon');

// cIcon.width = icon.width * this.icon.size;
// cIcon.height = icon.height * this.icon.size;
// cIcon.style.color = this.icon.color;
// cIcon.style.opacity = this.icon.opacity;
cIcon.width = icon.width * opt.size;
cIcon.height = icon.height * opt.size;
cIcon.style.color = opt.color;
Expand Down Expand Up @@ -709,25 +720,6 @@ class Style {
return this;
}

copy2(...style) {
style.forEach((source) => {
const descriptors = Object.keys(source).reduce((descriptors, key) => {
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
return descriptors;
}, {});
// Par défaut, Object.assign copie également
// les symboles énumérables
Object.getOwnPropertySymbols(source).forEach((sym) => {
const descriptor = Object.getOwnPropertyDescriptor(source, sym);
if (descriptor.enumerable) {
descriptors[sym] = descriptor;
}
});
Object.defineProperties(this, descriptors);
});
return this;
}

/**
* Clones this style.
*
Expand Down Expand Up @@ -918,6 +910,14 @@ class Style {
}
}
}
// VectorTileSet: by default minZoom = 0 and maxZoom = 24
// https://docs.mapbox.com/style-spec/reference/layers/#maxzoom and #minzoom
// Should be move to layer properties, when (if) one mapBox layer will be considered as several itowns layers.
// issue https://github.com/iTowns/itowns/issues/2153 (last point)
style.zoom = {
min: layer.minzoom || 0,
max: layer.maxzoom || 24,
};
return style;
}

Expand All @@ -933,14 +933,12 @@ class Style {
// draw line or edge of polygon
if (this.stroke) {
// TO DO add possibility of using a pattern (https://github.com/iTowns/itowns/issues/2210)
// Style.prototype._applyStrokeToPolygon.call(this, txtrCtx, invCtxScale, polygon);
this._applyStrokeToPolygon(txtrCtx, invCtxScale, polygon, context);
}

// fill inside of polygon
if (canBeFilled && this.fill) {
// canBeFilled can be move to StyleContext in the later PR
// Style.prototype._applyFillToPolygon.call(this, txtrCtx, invCtxScale, polygon);
this._applyFillToPolygon(txtrCtx, invCtxScale, polygon, context);
}
}
Expand Down
1 change: 0 additions & 1 deletion src/Layer/ColorLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ class ColorLayer extends RasterLayer {
deprecatedColorLayerOptions(config);
super(id, config);
this.isColorLayer = true;
// this.style = config.style;
this.defineLayerProperty('visible', true);
this.defineLayerProperty('opacity', 1.0);
this.defineLayerProperty('sequence', 0);
Expand Down
1 change: 0 additions & 1 deletion src/Layer/LabelLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ class LabelLayer extends GeometryLayer {
delete config.domElement;
super(id, config.object3d || new THREE.Group(), config);

// this.style = config.style || {};
this.isLabelLayer = true;
this.domElement = new DomNode();
this.domElement.show();
Expand Down
4 changes: 1 addition & 3 deletions src/Layer/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import Source from 'Source/Source';
import Cache from 'Core/Scheduler/Cache';
import Style from 'Core/Style';

const userStyle = new Style();

/**
* @property {boolean} isLayer - Used to checkout whether this layer is a Layer.
* Default is true. You should not change this, as it is used internally for
Expand Down Expand Up @@ -109,7 +107,7 @@ class Layer extends THREE.EventDispatcher {
}
config.style = new Style(config.style);
}
this.style = config.style || userStyle;
this.style = config.style || new Style();
Object.assign(this, config);

Object.defineProperty(this, 'id', {
Expand Down
4 changes: 0 additions & 4 deletions src/Source/VectorTilesSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ class VectorTilesSource extends TMSSource {
this.backgroundLayer = layer;
} else if (ffilter(layer)) {
const style = Style.setFromVectorTileLayer(layer, this.sprites, order, this.symbolToCircle);
style.zoom = {
min: layer.minzoom || 0,
max: layer.maxzoom || 24,
};
this.styles[layer.id] = style;

if (!this.layers[layer['source-layer']]) {
Expand Down

0 comments on commit b9287ba

Please sign in to comment.