From 1697f8cc5e2a09e4d2ce19f34223e8dcc4d4cced Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Sun, 10 Nov 2024 23:38:38 +0800 Subject: [PATCH] style: add comments for folding --- src/BaseRenderer.mjs | 18 +++--- src/BasicDrawComponent.mjs | 16 +++++- src/BasicLeafletRenderer.mjs | 96 +++++++++++--------------------- src/BasicMaplibreRenderer.mjs | 56 ++++++++++--------- src/BasicOpenlayersRenderer.mjs | 99 ++++++++++++++++++--------------- 5 files changed, 140 insertions(+), 145 deletions(-) diff --git a/src/BaseRenderer.mjs b/src/BaseRenderer.mjs index 6926d91..55e5b4f 100644 --- a/src/BaseRenderer.mjs +++ b/src/BaseRenderer.mjs @@ -39,7 +39,7 @@ export class MapOption { * Class: base class for Map Renderer */ export default class { - // properties {{{ + /** fields */ width = '300px' height = '300px' center = [121, 24] @@ -87,7 +87,6 @@ export default class { ] } - // }}} validateOption (option, value) { const isValid = this.constructor.validOptions.find( opt => opt.valueOf() === option, @@ -97,7 +96,7 @@ export default class { return isValid(value) } - // Valid Options {{{ + /** options * static validOptions = Object.freeze([ new MapOption({ name: 'id', @@ -202,8 +201,8 @@ export default class { isValid: () => true, }), ]) - // }}} + /** step: options */ setOptionAliases (config) { if (config.XYZ) { const xyzArray = @@ -266,6 +265,7 @@ export default class { }) } + /** step: HTMLElement */ createView ({ target, width, height }) { target.style.width = width target.style.height = height @@ -274,6 +274,7 @@ export default class { } } + /** step: draw */ setDraw = ({ target, terraDrawAdapter }) => { const idPrefix = target?.id ? target.id + '-' : '' const options = { @@ -296,6 +297,7 @@ export default class { return this.terraDraw } + /** options: not-implemented */ getTerraDrawAdapter () { return { state: 'skip' } } @@ -336,13 +338,7 @@ export default class { this.updateCamera({ center: this.center, zoom: this.zoom }) } - showLayerSwitcher (data) { - const wmtsRecords = data.filter(record => record.type === 'wmts') - const tileRecords = data.filter(record => record.type === 'tile') - - return wmtsRecords.length > 0 || tileRecords.length > 1 - } - + /** utils: eval */ propsForEval () { let currentPrototype = this let props = [] diff --git a/src/BasicDrawComponent.mjs b/src/BasicDrawComponent.mjs index efbbc00..083996e 100644 --- a/src/BasicDrawComponent.mjs +++ b/src/BasicDrawComponent.mjs @@ -1,3 +1,4 @@ +/** Import */ import { TerraDraw, TerraDrawSelectMode, @@ -9,7 +10,13 @@ import { TerraDrawRenderMode, } from 'terra-draw' -// ref: https://github.com/JamesLMilner/terra-draw/blob/main/guides/4.MODES.md#selection-mode +/** + * BasicDrawComponent. + * ref: https://github.com/JamesLMilner/terra-draw/blob/main/guides/4.MODES.md#selection-mode + * @param {TerraDrawBaseAdapter} adapter + * @param {Object} options + * @return TerraDratxw + */ export const BasicDrawComponent = (adapter, options = {}) => new TerraDraw({ adapter, @@ -53,6 +60,13 @@ export const BasicDrawComponent = (adapter, options = {}) => ...options, }) +/** + * addSimpleSelector. + * + * @param {HTMLElement} target + * @param {TerraDraw} draw + * @param {Object} options + */ export const addSimpleSelector = (target, draw, options = {}) => { const selector = document.createElement('select') target.appendChild(selector) diff --git a/src/BasicLeafletRenderer.mjs b/src/BasicLeafletRenderer.mjs index e777c6b..d413b6e 100644 --- a/src/BasicLeafletRenderer.mjs +++ b/src/BasicLeafletRenderer.mjs @@ -1,18 +1,16 @@ import defaultExport, { loadCSS } from './BaseRenderer' -import { - renderWith, - renderByYamlWith, - renderByScriptTargetWith, -} from './mapclay.mjs' import * as L from 'leaflet/dist/leaflet-src.esm' import { TerraDrawLeafletAdapter } from 'terra-draw' loadCSS('https://unpkg.com/leaflet@1.9.4/dist/leaflet.css') +/** class: Leaflet */ const Renderer = class extends defaultExport { + /** fields */ id = 'leaflet' version = '1.9.4' L = L + /** options: center, zoom */ addMap ({ target, center, zoom }) { const [x, y] = center this.map = L.map(target).setView([y, x], zoom) @@ -26,6 +24,7 @@ const Renderer = class extends defaultExport { return this.map } + /** options: draw */ getTerraDrawAdapter ({ draw, L, map }) { if (!draw) return { state: 'skip' } @@ -33,6 +32,7 @@ const Renderer = class extends defaultExport { return this.getTerraDrawAdapter } + /** options: control */ setControl ({ map, control }) { if (!control || Object.values(control).filter(v => v).length === 0) { return { state: 'skip' } } @@ -71,7 +71,7 @@ const Renderer = class extends defaultExport { return new L.GridLayer.GridDebug() } - // Configure extra stuff + /** options: debug, eval */ setExtra (config) { const { map, debug } = config if (!debug && !config.eval) return { state: 'skip' } @@ -87,32 +87,7 @@ const Renderer = class extends defaultExport { } } - addMarker (config) { - const options = config.element - ? { - html: config.element.innerHTML, - iconSize: config.size, - iconAnchor: config.anchor, - } - : { - html: this.svgPin.html, - iconSize: this.svgPin.size, - iconAnchor: this.svgPin.anchor, - } - const markerIcon = L.divIcon({ - ...options, - className: 'marker', - }) - const xy = Array.from(config.xy).reverse() - const marker = L.marker(xy, { icon: markerIcon }) - .addTo(this.map) - const element = marker.getElement() - element.classList.add('marker') - - element.remove = () => this.map.removeLayer(marker) - return element - } - + /** options: data */ addTileData ({ map, data }) { const tileData = data.filter(d => d.type === 'tile') @@ -136,39 +111,34 @@ const Renderer = class extends defaultExport { } } - addGPXFile ({ map, data }) { - const gpxUrl = data.find(record => record.type === 'gpx') - if (!gpxUrl) return { state: 'skip' } - - const script = document.createElement('script') - script.src = - 'https://cdnjs.cloudflare.com/ajax/libs/leaflet-gpx/1.7.0/gpx.min.js' - document.body.append(script) + /** actions: marker */ + addMarker (config) { + const options = config.element + ? { + html: config.element.innerHTML, + iconSize: config.size, + iconAnchor: config.anchor, + } + : { + html: this.svgPin.html, + iconSize: this.svgPin.size, + iconAnchor: this.svgPin.anchor, + } + const markerIcon = L.divIcon({ + ...options, + className: 'marker', + }) + const xy = Array.from(config.xy).reverse() + const marker = L.marker(xy, { icon: markerIcon }) + .addTo(this.map) + const element = marker.getElement() + element.classList.add('marker') - const options = { - gpx_options: { - joinTrackSegments: false, - }, - polyline_options: { - color: 'red', - weight: 3, - lineCap: 'round', - }, - marker_options: { - startIconUrl: null, - endIconUrl: null, - shadowUrl: '', - wptIconUrls: { - '': null, - }, - }, - async: true, - } - script.onload = () => { - new L.GPX(gpxUrl, options).addTo(map) - } + element.remove = () => this.map.removeLayer(marker) + return element } + /** actions: camera */ async updateCamera ({ center, zoom, bounds, animation, padding, duration }) { const latLon = center ? L.latLng(center[1], center[0]) : this.map.getCenter() const options = { @@ -196,6 +166,7 @@ const Renderer = class extends defaultExport { }) } + /** utils: projection */ project ([lng, lat]) { return this.map.latLngToContainerPoint([lat, lng]) } @@ -206,4 +177,5 @@ const Renderer = class extends defaultExport { } } +/** export */ export default Renderer diff --git a/src/BasicMaplibreRenderer.mjs b/src/BasicMaplibreRenderer.mjs index d7a2fce..696683e 100644 --- a/src/BasicMaplibreRenderer.mjs +++ b/src/BasicMaplibreRenderer.mjs @@ -1,16 +1,13 @@ import defaultExport, { MapOption, loadCSS } from './BaseRenderer' -import { - renderWith, - renderByYamlWith, - renderByScriptTargetWith, -} from './mapclay.mjs' /* eslint-disable-next-line no-unused-vars */ import maplibregl from 'maplibre-gl' import { addProtocols } from 'maplibre-gl-vector-text-protocol' import { TerraDrawMapLibreGLAdapter } from 'terra-draw' loadCSS('https://unpkg.com/maplibre-gl@4.5.2/dist/maplibre-gl.css') +/** class: Openlayers */ const Renderer = class extends defaultExport { + /** fields */ id = 'maplibre' pitch = 0 bearing = 0 @@ -19,7 +16,7 @@ const Renderer = class extends defaultExport { /* eslint-disable-next-line no-undef */ maplibregl = maplibregl - // Options {{{ + /** options */ static validOptions = this.validOptions.concat([ new MapOption({ name: 'pitch', @@ -50,8 +47,8 @@ const Renderer = class extends defaultExport { isValid: value => URL.parse(value), }), ]) - // }}} + /** options: center, zoom, pitch, bearing */ async addMap ({ maplibregl, target, @@ -84,6 +81,7 @@ const Renderer = class extends defaultExport { }) } + /** options: draw */ getTerraDrawAdapter ({ maplibregl, map, draw }) { if (!draw) return { state: 'skip' } @@ -91,7 +89,7 @@ const Renderer = class extends defaultExport { return this.terraDrawAdapter } - // Configure controls + /** options: control */ setControl ({ maplibregl, map, control }) { if (!control || Object.values(control).filter(v => v).length === 0) { return { state: 'skip' } } @@ -106,7 +104,7 @@ const Renderer = class extends defaultExport { } } - // Configure extra stuff + /** options: debug, eval */ setExtra (config) { const { map, debug } = config if (!debug && !config.eval) return { state: 'skip' } @@ -119,23 +117,7 @@ const Renderer = class extends defaultExport { } } - addMarker (config) { - const options = config.element - ? { - element: config.element, - anchor: config.type === 'pin' ? 'bottom' : 'center', - } - : {} - const marker = new this.maplibregl.Marker(options) - .setLngLat(config.xy) - .addTo(this.map) - const element = marker.getElement() - element.classList.add('marker') - element.remove = () => marker.remove() - - return element - } - + /** options: data */ addTileData ({ map, data }) { const tileData = data.filter(d => d.type === 'tile') if (tileData.length === 0) return { state: 'skip' } @@ -153,6 +135,7 @@ const Renderer = class extends defaultExport { map.setStyle(style) } + /** options: data.gpx */ async addGPXFile ({ maplibregl, map, data }) { const gpxUrl = data.find(record => record.type === 'gpx') if (!gpxUrl) return { state: 'skip' } @@ -190,6 +173,25 @@ const Renderer = class extends defaultExport { } } + /** actions: marker */ + addMarker (config) { + const options = config.element + ? { + element: config.element, + anchor: config.type === 'pin' ? 'bottom' : 'center', + } + : {} + const marker = new this.maplibregl.Marker(options) + .setLngLat(config.xy) + .addTo(this.map) + const element = marker.getElement() + element.classList.add('marker') + element.remove = () => marker.remove() + + return element + } + + /** actions: camera */ async updateCamera ({ bounds, center, zoom, animation, ...others }, useAnimation) { if (bounds) { this.map.fitBounds(bounds, { linear: true, ...others }) @@ -211,6 +213,7 @@ const Renderer = class extends defaultExport { }) } + /** utils: projection */ project ([lng, lat]) { return this.map.project([lng, lat]) } @@ -221,4 +224,5 @@ const Renderer = class extends defaultExport { } } +/** export */ export default Renderer diff --git a/src/BasicOpenlayersRenderer.mjs b/src/BasicOpenlayersRenderer.mjs index 9f39d80..88cc80e 100644 --- a/src/BasicOpenlayersRenderer.mjs +++ b/src/BasicOpenlayersRenderer.mjs @@ -1,9 +1,4 @@ import defaultExport, { MapOption, loadCSS } from './BaseRenderer' -import { - renderWith, - renderByYamlWith, - renderByScriptTargetWith, -} from './mapclay' import { TerraDrawOpenLayersAdapter } from 'terra-draw' import * as ol from 'ol' @@ -18,7 +13,9 @@ import proj4 from 'proj4' import * as olProj4 from 'ol/proj/proj4' loadCSS('https://cdn.jsdelivr.net/npm/ol@10.1.0/ol.css') +/** class: Openlayers */ const Renderer = class extends defaultExport { + /** fields */ id = 'openlayers' crs = 'EPSG:4326' control = { @@ -54,6 +51,30 @@ const Renderer = class extends defaultExport { }), ]) + /** step: cursor */ + setCursor ({ map }) { + map.getViewport().style.cursor = 'grab' + map.on('pointerdrag', _ => { + map.getViewport().style.cursor = 'grabbing' + }) + map.on('pointerup', () => { + map.getViewport().style.cursor = 'grab' + }) + } + + /** step: options */ + setOptionsAliases (config) { + super.handleAliases(config) + if (config.STYLE) { + config.data.push({ + type: 'style', + url: config.STYLE, + }) + delete config.STYLE + } + } + + /** options: crs */ async setCoordinateSystem ({ proj4, ol, crs }) { // Set projection proj4.defs( @@ -74,6 +95,7 @@ const Renderer = class extends defaultExport { return ol.proj.getUserProjection() } + /** options: center, zoom */ async addMap ({ ol, target, center, zoom }) { // Set basemap and camera this.map = new ol.Map({ @@ -88,6 +110,7 @@ const Renderer = class extends defaultExport { return this.map } + /** options: draw */ getTerraDrawAdapter ({ map, ol, draw }) { if (!draw) return { state: 'skip' } @@ -109,27 +132,7 @@ const Renderer = class extends defaultExport { return this.terraDrawAdapter } - setCursor ({ map }) { - map.getViewport().style.cursor = 'grab' - map.on('pointerdrag', _ => { - map.getViewport().style.cursor = 'grabbing' - }) - map.on('pointerup', () => { - map.getViewport().style.cursor = 'grab' - }) - } - - setOptionsAliases (config) { - super.handleAliases(config) - if (config.STYLE) { - config.data.push({ - type: 'style', - url: config.STYLE, - }) - delete config.STYLE - } - } - + /** options: control */ setControl ({ map, control, ol }) { if (!control || Object.values(control).filter(v => v).length === 0) { return { state: 'skip' } } @@ -146,6 +149,7 @@ const Renderer = class extends defaultExport { } } + /** options: debug, eval */ setExtra (config) { const { map, debug, ol } = config if (!debug && !config.eval) return { state: 'skip' } @@ -165,25 +169,7 @@ const Renderer = class extends defaultExport { } } - // Apply vector layer for markers onto map - addMarker (config) { - const element = config.element ?? document.createElement('div') - if (element.children.length === 0) element.innerHTML = this.svgPin.html - config.type = 'pin' - - const position = this.ol.proj.fromLonLat(config.xy, this.crs) - const overlay = new ol.Overlay({ - element, - position, - positioning: config.type !== 'pin' ? 'center-center' : 'bottom-center', - }) - this.map.addOverlay(overlay) - - element.classList.add('marker') - element.remove = () => this.map.removeOverlay(overlay) - return element - } - + /** options: data */ async addTileData ({ map, data, ol }) { const tileData = data.filter(record => record.type === 'tile') @@ -217,6 +203,7 @@ const Renderer = class extends defaultExport { }) } + /** options: data.gpx */ addGPXFile ({ map, ol, data }) { const gpxUrl = data.find(record => record.type === 'gpx') if (!gpxUrl) return { state: 'skip' } @@ -245,6 +232,26 @@ const Renderer = class extends defaultExport { // } } + /** actions: marker */ + addMarker (config) { + const element = config.element ?? document.createElement('div') + if (element.children.length === 0) element.innerHTML = this.svgPin.html + config.type = 'pin' + + const position = this.ol.proj.fromLonLat(config.xy, this.crs) + const overlay = new ol.Overlay({ + element, + position, + positioning: config.type !== 'pin' ? 'center-center' : 'bottom-center', + }) + this.map.addOverlay(overlay) + + element.classList.add('marker') + element.remove = () => this.map.removeOverlay(overlay) + return element + } + + /** actions: camera */ async updateCamera ({ center, animation, zoom, bounds, duration, padding }) { const map = this.map const view = map.getView() @@ -266,6 +273,7 @@ const Renderer = class extends defaultExport { }) } + /** utils: projection */ project = ([x, y]) => this.map.getPixelFromCoordinate( this.ol.proj.fromLonLat( @@ -281,4 +289,5 @@ const Renderer = class extends defaultExport { ) } +/** export */ export default Renderer