diff --git a/lib/mapp.mjs b/lib/mapp.mjs
index 1e9b6a60d..668bc930f 100644
--- a/lib/mapp.mjs
+++ b/lib/mapp.mjs
@@ -28,7 +28,43 @@ import plugins from './plugins/_plugins.mjs'
hooks.parse();
+const _ol = {
+ current: 9.1,
+ load: async() => await new Promise(resolve => {
+
+ const script = document.createElement('script')
+
+ script.type = 'application/javascript'
+
+ script.src = 'https://cdn.jsdelivr.net/npm/ol@v9.1.0/dist/ol.js'
+
+ script.onload = resolve
+
+ document.head.append(script)
+
+ console.warn('Openlayers library loaded from script tag.')
+ })
+}
+
+if (window.ol === undefined) {
+
+ console.warn(`Openlayers has not been loaded.`)
+
+} else {
+
+ let olVersion = parseFloat(ol?.util.VERSION)
+
+ console.log(`OpenLayers version ${olVersion}`)
+
+ if (olVersion < _ol.current) {
+
+ console.warn(`The current support OL version ${ol?.util.VERSION} supersedes the loaded version.`)
+ }
+}
+
self.mapp = {
+ ol: _ol,
+
version: '4.8.3',
hash: '4ada79d6afdd939dc1ed61a225b2603e950fa09f',
diff --git a/lib/utils/_utils.mjs b/lib/utils/_utils.mjs
index f9b9e4583..3a42eab51 100644
--- a/lib/utils/_utils.mjs
+++ b/lib/utils/_utils.mjs
@@ -35,20 +35,6 @@ Import ol script through scrit tag in promise.
@function olScript
@memberof module:/utils
*/
-const olScript = async() => await new Promise(async resolve => {
-
- const script = document.createElement('script')
-
- script.type = 'application/javascript'
-
- script.src = 'https://cdn.jsdelivr.net/npm/ol@v9.0.0/dist/ol.js'
-
- script.onload = resolve
-
- document.head.append(script)
-
- console.warn('Openlayers library loaded from script tag.')
-})
import convert from './convert.mjs'
@@ -98,7 +84,7 @@ export default {
hexa,
loadPlugins,
merge,
- olScript,
+ olScript: ()=>mapp.ol.load(),
paramString,
polygonIntersectFeatures,
promiseAll,
diff --git a/public/tests/lib/layer/featureStyle.test.mjs b/public/tests/lib/layer/featureStyle.test.mjs
new file mode 100644
index 000000000..66c524e10
--- /dev/null
+++ b/public/tests/lib/layer/featureStyle.test.mjs
@@ -0,0 +1,166 @@
+import { describe, it, assertEqual, assertTrue } from 'https://esm.sh/codi-test-framework@0.0.26';
+
+export async function featureStyleTest() {
+ await describe('mapp.layer.featureStyle', () => {
+ it('should return cached styles if available', () => {
+ const layer = {
+ style: {
+ cache: true,
+ },
+ };
+ const feature = {
+ get: (key) => {
+ if (key === 'Styles') {
+ return { fillColor: 'red' };
+ }
+ },
+ };
+
+ const styleFunction = mapp.layer.mapp.layer.featureStyle(layer);
+ const styles = styleFunction(feature);
+
+ console.log(styles);
+
+ assertEqual(styles.fillColor, 'red', 'Should return cached styles');
+ });
+
+ it('should apply theme style to the feature', () => {
+ const layer = {
+ style: {
+ theme: {
+ type: 'customTheme',
+ },
+ },
+ filter: {
+ current: {},
+ },
+ };
+ const feature = {
+ get: () => {},
+ getProperties: () => ({}),
+ };
+
+ mapp.layer.themes.customTheme = (theme, feat) => {
+ feat.style.fillColor = 'blue';
+ };
+
+ const styleFunction = mapp.layer.featureStyle(layer);
+ styleFunction(feature);
+
+ assertEqual(feature.style.fillColor, 'blue', 'Should apply custom theme style');
+ });
+
+ it('should apply cluster style to the feature', () => {
+ const layer = {
+ style: {
+ cluster: {
+ clusterScale: 2,
+ },
+ default: {},
+ },
+ max_size: 100,
+ mapview: {
+ Map: {
+ getView: () => ({
+ getZoom: () => 10,
+ }),
+ },
+ },
+ };
+ const feature = {
+ get: () => {},
+ getProperties: () => ({
+ count: 50,
+ }),
+ };
+
+ const styleFunction = mapp.layer.featureStyle(layer);
+ styleFunction(feature);
+
+ assertTrue(feature.style.clusterScale > 1, 'Should apply cluster scaling');
+ });
+
+ it('should apply highlight style to the feature', () => {
+ const layer = {
+ style: {
+ default: {},
+ highlight: {
+ fillColor: 'yellow',
+ },
+ },
+ highlight: 'feature1',
+ };
+ const feature = {
+ get: (key) => {
+ if (key === 'id') {
+ return 'feature1';
+ }
+ },
+ };
+
+ const styleFunction = mapp.layer.featureStyle(layer);
+ styleFunction(feature);
+
+ assertEqual(feature.style.fillColor, 'yellow', 'Should apply highlight style');
+ });
+
+ it('should apply label style to the feature', () => {
+ const layer = {
+ style: {
+ default: {},
+ label: {
+ display: true,
+ field: 'name',
+ },
+ },
+ mapview: {
+ Map: {
+ getView: () => ({
+ getZoom: () => 10,
+ }),
+ },
+ },
+ };
+ const feature = {
+ get: () => {},
+ getProperties: () => ({
+ name: 'Feature 1',
+ }),
+ style: {},
+ };
+
+ const styleFunction = mapp.layer.featureStyle(layer);
+ styleFunction(feature);
+
+ assertEqual(feature.style.label.text, 'Feature 1', 'Should apply label style');
+ });
+
+ it('should apply selected style to the feature', () => {
+ const layer = {
+ key: 'layer1',
+ style: {
+ default: {},
+ selected: {
+ fillColor: 'green',
+ },
+ },
+ mapview: {
+ locations: {
+ 'layer1!feature1': true,
+ },
+ },
+ };
+ const feature = {
+ get: () => {},
+ getProperties: () => ({
+ id: 'feature1',
+ }),
+ };
+
+ const styleFunction = mapp.layer.featureStyle(layer);
+ styleFunction(feature);
+
+ assertEqual(feature.style.fillColor, 'green', 'Should apply selected style');
+ });
+ });
+}
\ No newline at end of file
diff --git a/public/views/_default.html b/public/views/_default.html
index 1fe8c3b7f..2b524d5fe 100644
--- a/public/views/_default.html
+++ b/public/views/_default.html
@@ -9,7 +9,7 @@
-
+
diff --git a/public/views/_test.html b/public/views/_test.html
index 06c6c6e34..f4d236427 100644
--- a/public/views/_test.html
+++ b/public/views/_test.html
@@ -9,7 +9,7 @@
-
+