Import OpenLayers directly and remove resources/js/ol.mjs

The OpenLayers code is extracted into the
public/js/vendor/openlayers/openlayers.js file.

Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
This commit is contained in:
Maurício Meneghini Fauth 2025-05-22 14:59:08 -03:00
parent 01e4a87bbd
commit a39a8d29ea
No known key found for this signature in database
GPG Key ID: 6A16FD38AFC89CC8
7 changed files with 61 additions and 108 deletions

View File

@ -58,7 +58,7 @@ validateExtension() {
fi
;;
resources/js/*)
if [ "${extension}" != "ts" ] && [ "${extension}" != "mjs" ]; then
if [ "${extension}" != "ts" ]; then
foundFileExt
fi
;;

View File

@ -252,16 +252,12 @@ function makeGeometryInputs (gisData): string {
* @param {function} resolve
*/
function loadJSAndGISEditor (resolve) {
let script;
script = document.createElement('script');
script.src = 'js/table/gis_visualization.js';
document.head.appendChild(script);
let script: HTMLScriptElement;
// OpenLayers.js is BIG and takes time. So asynchronous loading would not work.
// Load the JS and do a callback to load the content for the GIS Editor.
script = document.createElement('script');
script.src = 'js/vendor/openlayers/OpenLayers.js';
script.src = 'js/vendor/openlayers/openlayers.js';
script.addEventListener('load', function () {
resolve();
});
@ -272,6 +268,10 @@ function loadJSAndGISEditor (resolve) {
document.head.appendChild(script);
script = document.createElement('script');
script.src = 'js/table/gis_visualization.js';
document.head.appendChild(script);
gisEditorLoaded = true;
}

View File

@ -4,7 +4,6 @@ interface Window {
mysqlDocTemplate: string;
themeImagePath: string;
firstDayOfCalendar: string;
ol: any;
opera: any;
zxcvbnts: any;
msCrypto: any;

View File

@ -1,36 +0,0 @@
import { Attribution, MousePosition, Zoom } from 'ol/control.js';
import { createStringXY } from 'ol/coordinate.js';
import { isEmpty } from 'ol/extent.js';
import { LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon } from 'ol/geom.js';
import { Tile, Vector as VectorLayer } from 'ol/layer.js';
import { OSM, Vector as VectorSource } from 'ol/source.js';
import { Circle, Fill, Stroke, Style, Text } from 'ol/style.js';
import { Feature, Map, View } from 'ol';
import { get as getProjection } from 'ol/proj.js';
const ol = {
control: {
Attribution, MousePosition, Zoom
},
coordinate: {
createStringXY
},
extent: {
isEmpty
},
geom: {
LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon
},
layer: {
Tile, Vector: VectorLayer
},
source: {
OSM, Vector: VectorSource
},
style: {
Circle, Fill, Stroke, Style, Text
},
Feature, Map, View, getProjection
};
export default ol;

View File

@ -1,6 +1,15 @@
import $ from 'jquery';
import { AJAX } from '../modules/ajax.ts';
import { escapeHtml } from '../modules/functions/escape.ts';
import { Feature, Map, View } from 'ol';
import { Attribution, MousePosition, Zoom } from 'ol/control';
import { createStringXY } from 'ol/coordinate';
import { isEmpty } from 'ol/extent';
import { LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon } from 'ol/geom';
import { Tile, Vector as VectorLayer } from 'ol/layer';
import { get as getProjection } from 'ol/proj';
import { OSM, Vector as VectorSource } from 'ol/source';
import { Circle, Fill, Stroke, Style, Text } from 'ol/style';
/**
* @fileoverview functions used for visualizing GIS data
@ -428,11 +437,11 @@ class OlVisualization extends GisVisualization {
}
drawOpenLayers () {
if (typeof window.ol === 'undefined') {
if (! document.querySelector('script[src*="js/vendor/openlayers/openlayers.js"]')) {
return undefined;
}
const olCss = 'js/vendor/openlayers/theme/ol.css';
const olCss = 'js/vendor/openlayers/openlayers.css';
if (! document.querySelector('link[rel="stylesheet"][href="' + olCss + '"]')) {
const link = document.createElement('link');
link.rel = 'stylesheet';
@ -441,28 +450,28 @@ class OlVisualization extends GisVisualization {
document.head.appendChild(link);
}
const vectorSource = new window.ol.source.Vector({
const vectorSource = new VectorSource({
features: getFeaturesFromOpenLayersData(this.data),
});
const map = new window.ol.Map({
const map = new Map({
target: this.target,
layers: [
new window.ol.layer.Tile({ source: new window.ol.source.OSM() }),
new window.ol.layer.Vector({ source: vectorSource }),
new Tile({ source: new OSM() }),
new VectorLayer({ source: vectorSource }),
],
view: new window.ol.View({ center: [0, 0], zoom: 4 }),
view: new View({ center: [0, 0], zoom: 4 }),
controls: [
new window.ol.control.MousePosition({
coordinateFormat: window.ol.coordinate.createStringXY(4),
new MousePosition({
coordinateFormat: createStringXY(4),
projection: 'EPSG:4326'
}),
new window.ol.control.Zoom,
new window.ol.control.Attribution
new Zoom,
new Attribution
]
});
const extent = vectorSource.getExtent();
if (! window.ol.extent.isEmpty(extent)) {
if (! isEmpty(extent)) {
map.getView().fit(extent, { padding: [20, 20, 20, 20] });
}
@ -502,40 +511,40 @@ function getFeaturesFromOpenLayersData (geometries: any[]): any[] {
let olGeometry: any = null;
const style: any = {};
if (geometry.geometry.type === 'LineString') {
olGeometry = new window.ol.geom.LineString(geometry.geometry.coordinates);
style.stroke = new window.ol.style.Stroke(geometry.style.stroke);
olGeometry = new LineString(geometry.geometry.coordinates);
style.stroke = new Stroke(geometry.style.stroke);
} else if (geometry.geometry.type === 'MultiLineString') {
olGeometry = new window.ol.geom.MultiLineString(geometry.geometry.coordinates);
style.stroke = new window.ol.style.Stroke(geometry.style.stroke);
olGeometry = new MultiLineString(geometry.geometry.coordinates);
style.stroke = new Stroke(geometry.style.stroke);
} else if (geometry.geometry.type === 'MultiPoint') {
olGeometry = new window.ol.geom.MultiPoint(geometry.geometry.coordinates);
style.image = new window.ol.style.Circle({
fill: new window.ol.style.Fill(geometry.style.circle.fill),
stroke: new window.ol.style.Stroke(geometry.style.circle.stroke),
olGeometry = new MultiPoint(geometry.geometry.coordinates);
style.image = new Circle({
fill: new Fill(geometry.style.circle.fill),
stroke: new Stroke(geometry.style.circle.stroke),
radius: geometry.style.circle.radius,
});
} else if (geometry.geometry.type === 'MultiPolygon') {
olGeometry = new window.ol.geom.MultiPolygon(geometry.geometry.coordinates);
style.fill = new window.ol.style.Fill(geometry.style.fill);
style.stroke = new window.ol.style.Stroke(geometry.style.stroke);
olGeometry = new MultiPolygon(geometry.geometry.coordinates);
style.fill = new Fill(geometry.style.fill);
style.stroke = new Stroke(geometry.style.stroke);
} else if (geometry.geometry.type === 'Point') {
olGeometry = new window.ol.geom.Point(geometry.geometry.coordinates);
style.image = new window.ol.style.Circle({
fill: new window.ol.style.Fill(geometry.style.circle.fill),
stroke: new window.ol.style.Stroke(geometry.style.circle.stroke),
olGeometry = new Point(geometry.geometry.coordinates);
style.image = new Circle({
fill: new Fill(geometry.style.circle.fill),
stroke: new Stroke(geometry.style.circle.stroke),
radius: geometry.style.circle.radius,
});
} else if (geometry.geometry.type === 'Polygon') {
olGeometry = new window.ol.geom.Polygon(geometry.geometry.coordinates);
style.fill = new window.ol.style.Fill(geometry.style.fill);
style.stroke = new window.ol.style.Stroke(geometry.style.stroke);
olGeometry = new Polygon(geometry.geometry.coordinates);
style.fill = new Fill(geometry.style.fill);
style.stroke = new Stroke(geometry.style.stroke);
} else {
throw new Error();
}
if (geometry.geometry.srid !== 3857) {
const source = 'EPSG:' + (geometry.geometry.srid !== 0 ? geometry.geometry.srid : 4326);
const sourceProj = window.ol.getProjection(source);
const sourceProj = getProjection(source);
if (sourceProj) {
olGeometry = olGeometry.transform(
@ -546,11 +555,11 @@ function getFeaturesFromOpenLayersData (geometries: any[]): any[] {
}
if (geometry.style.text) {
style.text = new window.ol.style.Text(geometry.style.text);
style.text = new Text(geometry.style.text);
}
const feature = new window.ol.Feature(olGeometry);
feature.setStyle(new window.ol.style.Style(style));
const feature = new Feature(olGeometry);
feature.setStyle(new Style(style));
features.push(feature);
}
@ -572,7 +581,7 @@ class GisVisualizationController {
$(document).on('click', '#useOsmAsBaseLayerSwitch', this.boundOnChoiceChange);
if (typeof window.ol === 'undefined') {
if (! document.querySelector('script[src*="js/vendor/openlayers/openlayers.js"]')) {
$('#useOsmAsBaseLayerSwitch, #useOsmAsBaseLayerSwitchLabel').hide();
$('#useOsmAsBaseLayerSwitch').prop('checked', false);
}

View File

@ -124,7 +124,7 @@ final readonly class GisVisualizationController implements InvocableController
return $response->write((string) $output);
}
$this->response->addScriptFiles(['vendor/openlayers/OpenLayers.js', 'table/gis_visualization.js']);
$this->response->addScriptFiles(['vendor/openlayers/openlayers.js', 'table/gis_visualization.js']);
// If all the rows contain SRID, use OpenStreetMaps on the initial loading.
$useBaseLayer = isset($_POST['redraw']) ? isset($_POST['useBaseLayer']) : $visualization->hasSrid();

View File

@ -1,5 +1,4 @@
const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const CopyPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
@ -93,6 +92,14 @@ module.exports = [
minChunks: 2,
minSize: 1,
},
openLayers: {
priority: 10,
test: /[\\/]node_modules[\\/](ol|rbush)[\\/]/,
name: 'openlayers',
filename: 'vendor/[name]/[name].js',
chunks: 'all',
enforce: true,
},
},
},
},
@ -150,7 +157,7 @@ module.exports = [
{ from: rootPath + '/node_modules/jquery-uitablefilter/jquery.uitablefilter.js', to: publicPath + '/js/vendor/jquery/jquery.uitablefilter.js' },
{ from: rootPath + '/node_modules/tablesorter/dist/js/jquery.tablesorter.js', to: publicPath + '/js/vendor/jquery/jquery.tablesorter.js' },
{ from: rootPath + '/node_modules/jquery-ui-timepicker-addon/dist/jquery-ui-timepicker-addon.js', to: publicPath + '/js/vendor/jquery/jquery-ui-timepicker-addon.js' },
{ from: rootPath + '/node_modules/ol/ol.css', to: publicPath + '/js/vendor/openlayers/theme/ol.css' },
{ from: rootPath + '/node_modules/ol/ol.css', to: publicPath + '/js/vendor/openlayers/openlayers.css' },
{ from: rootPath + '/node_modules/locutus.sprintf/src/php/strings/sprintf.browser.js', to: publicPath + '/js/vendor/sprintf.js' },
{ from: rootPath + '/node_modules/chart.js/dist/chart.umd.js', to: publicPath + '/js/vendor/chart.umd.js' },
{ from: rootPath + '/node_modules/chart.js/dist/chart.umd.js.map', to: publicPath + '/js/vendor/chart.umd.js.map' },
@ -161,32 +168,6 @@ module.exports = [
}),
],
},
{
name: 'OpenLayers',
entry: rootPath + '/resources/js/ol.mjs',
devtool: 'source-map',
mode: 'production',
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000,
},
output: {
path: publicPath + '/js/vendor/openlayers',
filename: 'OpenLayers.js',
library: 'ol',
libraryTarget: 'umd',
libraryExport: 'default',
},
plugins: [
new webpack.BannerPlugin({
banner: 'OpenLayers (https://openlayers.org/)\nCopyright 2005-present, OpenLayers Contributors All rights reserved.\nLicensed under BSD 2-Clause License (https://github.com/openlayers/openlayers/blob/main/LICENSE.md)',
}),
],
optimization: {
minimize: false,
}
},
{
name: 'CSS',
mode: 'none',