diff --git a/config/jsdoc/api/conf.json b/config/jsdoc/api/conf.json index a4a531ea2f..cc6fe143ea 100644 --- a/config/jsdoc/api/conf.json +++ b/config/jsdoc/api/conf.json @@ -14,6 +14,7 @@ ] }, "plugins": [ + "jsdoc-plugin-intersection", "config/jsdoc/plugins/markdown.cjs", "jsdoc-plugin-typescript", "config/jsdoc/plugins/inline-options.cjs", diff --git a/examples/canvas-gradient-pattern.js b/examples/canvas-gradient-pattern.js index 3b1f1d8c1b..e4031d2ed7 100644 --- a/examples/canvas-gradient-pattern.js +++ b/examples/canvas-gradient-pattern.js @@ -4,7 +4,6 @@ import VectorLayer from '../src/ol/layer/Vector.js'; import VectorSource from '../src/ol/source/Vector.js'; import View from '../src/ol/View.js'; import {DEVICE_PIXEL_RATIO} from '../src/ol/has.js'; -import {Fill, Stroke, Style} from '../src/ol/style.js'; import {fromLonLat} from '../src/ol/proj.js'; // Gradient and pattern are in canvas pixel space, so we adjust for the @@ -29,13 +28,11 @@ const vectorLayer = new VectorLayer({ url: 'data/kml/states.kml', format: new KML({extractStyles: false}), }), - style: new Style({ - fill: new Fill({color: gradient}), - stroke: new Stroke({ - color: '#333', - width: 1, - }), - }), + style: { + 'fill-color': gradient, + 'stroke-width': 1, + 'stroke-color': '#333', + }, }); const map = new Map({ diff --git a/examples/center.js b/examples/center.js index df4d8fab3f..89adf65cad 100644 --- a/examples/center.js +++ b/examples/center.js @@ -1,38 +1,27 @@ import GeoJSON from '../src/ol/format/GeoJSON.js'; import Map from '../src/ol/Map.js'; import View from '../src/ol/View.js'; -import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; -/** @type {VectorSource} */ const source = new VectorSource({ url: 'data/geojson/switzerland.geojson', format: new GeoJSON(), }); -const style = new Style({ - fill: new Fill({ - color: 'rgba(255, 255, 255, 0.6)', - }), - stroke: new Stroke({ - color: '#319FD3', - width: 1, - }), - image: new CircleStyle({ - radius: 5, - fill: new Fill({ - color: 'rgba(255, 255, 255, 0.6)', - }), - stroke: new Stroke({ - color: '#319FD3', - width: 1, - }), - }), -}); + const vectorLayer = new VectorLayer({ source: source, - style: style, + style: { + 'fill-color': 'rgba(255, 255, 255, 0.6)', + 'stroke-width': 1, + 'stroke-color': '#319FD3', + 'circle-radius': 5, + 'circle-fill-color': 'rgba(255, 255, 255, 0.6)', + 'circle-stroke-width': 1, + 'circle-stroke-color': '#319FD3', + }, }); + const view = new View({ center: [0, 0], zoom: 1, diff --git a/examples/custom-interactions.js b/examples/custom-interactions.js index c9621889bd..25c690e4b1 100644 --- a/examples/custom-interactions.js +++ b/examples/custom-interactions.js @@ -1,7 +1,6 @@ import Feature from '../src/ol/Feature.js'; import Map from '../src/ol/Map.js'; import View from '../src/ol/View.js'; -import {Fill, Icon, Stroke, Style} from '../src/ol/style.js'; import {LineString, Point, Polygon} from '../src/ol/geom.js'; import { Pointer as PointerInteraction, @@ -147,22 +146,16 @@ const map = new Map({ source: new VectorSource({ features: [pointFeature, lineFeature, polygonFeature], }), - style: new Style({ - image: new Icon({ - anchor: [0.5, 46], - anchorXUnits: 'fraction', - anchorYUnits: 'pixels', - opacity: 0.95, - src: 'data/icon.png', - }), - stroke: new Stroke({ - width: 3, - color: [255, 0, 0, 1], - }), - fill: new Fill({ - color: [0, 0, 255, 0.6], - }), - }), + style: { + 'icon-src': 'data/icon.png', + 'icon-opacity': 0.95, + 'icon-anchor': [0.5, 46], + 'icon-anchor-x-units': 'fraction', + 'icon-anchor-y-units': 'pixels', + 'stroke-width': 3, + 'stroke-color': [255, 0, 0, 1], + 'fill-color': [0, 0, 255, 0.6], + }, }), ], target: 'map', diff --git a/examples/draw-and-modify-features.js b/examples/draw-and-modify-features.js index 5f7996e112..94514fd356 100644 --- a/examples/draw-and-modify-features.js +++ b/examples/draw-and-modify-features.js @@ -1,6 +1,5 @@ import Map from '../src/ol/Map.js'; import View from '../src/ol/View.js'; -import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js'; import {Draw, Modify, Snap} from '../src/ol/interaction.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; @@ -13,21 +12,13 @@ const raster = new TileLayer({ const source = new VectorSource(); const vector = new VectorLayer({ source: source, - style: new Style({ - fill: new Fill({ - color: 'rgba(255, 255, 255, 0.2)', - }), - stroke: new Stroke({ - color: '#ffcc33', - width: 2, - }), - image: new CircleStyle({ - radius: 7, - fill: new Fill({ - color: '#ffcc33', - }), - }), - }), + style: { + 'fill-color': 'rgba(255, 255, 255, 0.2)', + 'stroke-color': '#ffcc33', + 'stroke-width': 2, + 'circle-radius': 7, + 'circle-fill-color': '#ffcc33', + }, }); // Limit multi-world panning to one world east and west of the real world. diff --git a/examples/geographic.js b/examples/geographic.js index 11c5df9504..84623e4663 100644 --- a/examples/geographic.js +++ b/examples/geographic.js @@ -1,4 +1,3 @@ -import {Circle, Fill, Style} from '../src/ol/style.js'; import {Feature, Map, Overlay, View} from '../src/ol/index.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {Point} from '../src/ol/geom.js'; @@ -25,12 +24,10 @@ const map = new Map({ source: new VectorSource({ features: [new Feature(point)], }), - style: new Style({ - image: new Circle({ - radius: 9, - fill: new Fill({color: 'red'}), - }), - }), + style: { + 'circle-radius': 9, + 'circle-fill-color': 'red', + }, }), ], }); diff --git a/examples/measure.js b/examples/measure.js index e1d52a010b..c0ed9bc696 100644 --- a/examples/measure.js +++ b/examples/measure.js @@ -17,21 +17,13 @@ const source = new VectorSource(); const vector = new VectorLayer({ source: source, - style: new Style({ - fill: new Fill({ - color: 'rgba(255, 255, 255, 0.2)', - }), - stroke: new Stroke({ - color: '#ffcc33', - width: 2, - }), - image: new CircleStyle({ - radius: 7, - fill: new Fill({ - color: '#ffcc33', - }), - }), - }), + style: { + 'fill-color': 'rgba(255, 255, 255, 0.2)', + 'stroke-color': '#ffcc33', + 'stroke-width': 2, + 'circle-radius': 7, + 'circle-fill-color': '#ffcc33', + }, }); /** diff --git a/examples/snap.js b/examples/snap.js index c9f7c53ea5..45f2cf3fb8 100644 --- a/examples/snap.js +++ b/examples/snap.js @@ -1,6 +1,5 @@ import Map from '../src/ol/Map.js'; import View from '../src/ol/View.js'; -import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js'; import {Draw, Modify, Select, Snap} from '../src/ol/interaction.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; @@ -11,21 +10,13 @@ const raster = new TileLayer({ const vector = new VectorLayer({ source: new VectorSource(), - style: new Style({ - fill: new Fill({ - color: 'rgba(255, 255, 255, 0.2)', - }), - stroke: new Stroke({ - color: '#ffcc33', - width: 2, - }), - image: new CircleStyle({ - radius: 7, - fill: new Fill({ - color: '#ffcc33', - }), - }), - }), + style: { + 'fill-color': 'rgba(255, 255, 255, 0.2)', + 'stroke-color': '#ffcc33', + 'stroke-width': 2, + 'circle-radius': 7, + 'circle-fill-color': '#ffcc33', + }, }); const map = new Map({ diff --git a/examples/vector-wfs.js b/examples/vector-wfs.js index 546806bc4a..6329116087 100644 --- a/examples/vector-wfs.js +++ b/examples/vector-wfs.js @@ -3,7 +3,6 @@ import Map from '../src/ol/Map.js'; import VectorSource from '../src/ol/source/Vector.js'; import View from '../src/ol/View.js'; import XYZ from '../src/ol/source/XYZ.js'; -import {Stroke, Style} from '../src/ol/style.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {bbox as bboxStrategy} from '../src/ol/loadingstrategy.js'; @@ -24,12 +23,11 @@ const vectorSource = new VectorSource({ const vector = new VectorLayer({ source: vectorSource, - style: new Style({ - stroke: new Stroke({ - color: 'rgba(0, 0, 255, 1.0)', - width: 2, - }), - }), + style: { + 'stroke-width': 0.75, + 'stroke-color': 'white', + 'fill-color': 'rgba(100,100,100,0.25)', + }, }); const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB'; diff --git a/package-lock.json b/package-lock.json index 88b822994c..63ebf17453 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "handlebars": "4.7.7", "jquery": "3.6.0", "jsdoc": "3.6.11", + "jsdoc-plugin-intersection": "^1.0.4", "jsdoc-plugin-typescript": "^2.1.1", "json-stringify-safe": "^5.0.1", "karma": "^6.3.8", @@ -6306,6 +6307,12 @@ "node": ">=12.0.0" } }, + "node_modules/jsdoc-plugin-intersection": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/jsdoc-plugin-intersection/-/jsdoc-plugin-intersection-1.0.4.tgz", + "integrity": "sha512-5OGv+aWpp0pYRMnhaUeqijesIi/xD2z8IIwIlK+JsQ0sXzMjiWT2YgNSvxcd476pRdh70Xmby/l7GD3NkWcKcQ==", + "dev": true + }, "node_modules/jsdoc-plugin-typescript": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/jsdoc-plugin-typescript/-/jsdoc-plugin-typescript-2.1.1.tgz", @@ -15040,6 +15047,12 @@ } } }, + "jsdoc-plugin-intersection": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/jsdoc-plugin-intersection/-/jsdoc-plugin-intersection-1.0.4.tgz", + "integrity": "sha512-5OGv+aWpp0pYRMnhaUeqijesIi/xD2z8IIwIlK+JsQ0sXzMjiWT2YgNSvxcd476pRdh70Xmby/l7GD3NkWcKcQ==", + "dev": true + }, "jsdoc-plugin-typescript": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/jsdoc-plugin-typescript/-/jsdoc-plugin-typescript-2.1.1.tgz", diff --git a/package.json b/package.json index ade0934051..8c5de6794c 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "handlebars": "4.7.7", "jquery": "3.6.0", "jsdoc": "3.6.11", + "jsdoc-plugin-intersection": "^1.0.4", "jsdoc-plugin-typescript": "^2.1.1", "json-stringify-safe": "^5.0.1", "karma": "^6.3.8", diff --git a/src/ol/layer/BaseVector.js b/src/ol/layer/BaseVector.js index 1b41a7e3a1..c104cdb518 100644 --- a/src/ol/layer/BaseVector.js +++ b/src/ol/layer/BaseVector.js @@ -3,10 +3,11 @@ */ import Layer from './Layer.js'; import RBush from 'rbush'; -import { +import Style, { createDefaultStyle, toFunction as toStyleFunction, } from '../style/Style.js'; +import {toStyle} from '../style/flat.js'; /** * @template {import("../source/Vector.js").default|import("../source/VectorTile.js").default} VectorSourceType @@ -49,7 +50,7 @@ import { * the fill and stroke styles of all of those layers regardless of z-index. To opt out of this * behavior and place declutterd features with their own layer configure the layer with a `className` * other than `ol-layer`. - * @property {import("../style/Style.js").StyleLike|null} [style] Layer style. When set to `null`, only + * @property {import("../style/Style.js").StyleLike|import("../style/flat.js").FlatStyleLike|null} [style] Layer style. When set to `null`, only * features that have their own style will be rendered. See {@link module:ol/style/Style~Style} for the default style * which will be used if this is not set. * @property {import("./Base.js").BackgroundColor} [background] Background color for the layer. If not specified, no background @@ -249,12 +250,51 @@ class BaseVectorLayer extends Layer { * an array of styles. If set to `null`, the layer has no style (a `null` style), * so only features that have their own styles will be rendered in the layer. Call * `setStyle()` without arguments to reset to the default style. See - * {@link module:ol/style/Style~Style} for information on the default style. - * @param {import("../style/Style.js").StyleLike|null} [opt_style] Layer style. + * [the ol/style/Style module]{@link module:ol/style/Style~Style} for information on the default style. + * + * If your layer has a static style, you can use "flat" style object literals instead of + * using the `Style` and symbolizer constructors (`Fill`, `Stroke`, etc.). See the documentation + * for the [flat style types]{@link module:ol/style/flat~FlatStyle} to see what properties are supported. + * + * @param {import("../style/Style.js").StyleLike|import("../style/flat.js").FlatStyleLike|null} [opt_style] Layer style. * @api */ setStyle(opt_style) { - this.style_ = opt_style !== undefined ? opt_style : createDefaultStyle; + /** + * @type {import("../style/Style.js").StyleLike|null} + */ + let style; + + if (opt_style === undefined) { + style = createDefaultStyle; + } else if (opt_style === null) { + style = null; + } else if (typeof opt_style === 'function') { + style = opt_style; + } else if (opt_style instanceof Style) { + style = opt_style; + } else if (Array.isArray(opt_style)) { + const len = opt_style.length; + + /** + * @type {Array