waibu-maps 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/bajo/.alias +1 -0
- package/bajo/config.json +10 -0
- package/bajoI18N/resource/en-US.json +17 -0
- package/bajoI18N/resource/id.json +19 -0
- package/package.json +34 -0
- package/waibuBootstrap/theme/component/factory/control-attribution.js +29 -0
- package/waibuBootstrap/theme/component/factory/control-buttons-item.js +14 -0
- package/waibuBootstrap/theme/component/factory/control-buttons.js +67 -0
- package/waibuBootstrap/theme/component/factory/control-center-position.js +28 -0
- package/waibuBootstrap/theme/component/factory/control-draw.js +43 -0
- package/waibuBootstrap/theme/component/factory/control-fullscreen.js +26 -0
- package/waibuBootstrap/theme/component/factory/control-geolocate.js +27 -0
- package/waibuBootstrap/theme/component/factory/control-group-button.js +15 -0
- package/waibuBootstrap/theme/component/factory/control-group-menu.js +45 -0
- package/waibuBootstrap/theme/component/factory/control-group.js +94 -0
- package/waibuBootstrap/theme/component/factory/control-image.js +43 -0
- package/waibuBootstrap/theme/component/factory/control-loader.js +27 -0
- package/waibuBootstrap/theme/component/factory/control-logo.js +50 -0
- package/waibuBootstrap/theme/component/factory/control-mouse-pos.js +78 -0
- package/waibuBootstrap/theme/component/factory/control-navigation.js +29 -0
- package/waibuBootstrap/theme/component/factory/control-ruler.js +47 -0
- package/waibuBootstrap/theme/component/factory/control-scale.js +27 -0
- package/waibuBootstrap/theme/component/factory/control-search.js +159 -0
- package/waibuBootstrap/theme/component/factory/control-zbp.js +70 -0
- package/waibuBootstrap/theme/component/factory/control.js +42 -0
- package/waibuBootstrap/theme/component/factory/layer-geojson.js +103 -0
- package/waibuBootstrap/theme/component/factory/layer-html-cluster.js +124 -0
- package/waibuBootstrap/theme/component/factory/map/options.js +44 -0
- package/waibuBootstrap/theme/component/factory/map.js +139 -0
- package/waibuBootstrap/theme/component/factory/script.js +20 -0
- package/waibuBootstrap/theme/component/factory/template.js +10 -0
- package/waibuBootstrap/theme/component/wmaps-base.js +40 -0
- package/waibuMpa/partial/menu.html +10 -0
- package/waibuMpa/route/default-style.js +13 -0
- package/waibuMpa/route/wmaps.js +13 -0
- package/waibuMpa/template/default-style.json +20 -0
- package/waibuMpa/template/wmaps.js +320 -0
- package/waibuStatic/asset/css/control-buttons.css +3 -0
- package/waibuStatic/asset/css/control-center-position.css +17 -0
- package/waibuStatic/asset/css/control-loader.css +7 -0
- package/waibuStatic/asset/css/control-mouse-position.css +21 -0
- package/waibuStatic/asset/css/control-ruler.css +12 -0
- package/waibuStatic/asset/css/control-search.css +25 -0
- package/waibuStatic/asset/css/wmaps.css +150 -0
- package/waibuStatic/asset/font/noto_sans_regular.pbf +0 -0
- package/waibuStatic/asset/image/center.svg +25 -0
- package/waibuStatic/asset/image/ruler.svg +4 -0
- package/waibuStatic/asset/js/control-buttons.js +98 -0
- package/waibuStatic/asset/js/control-center-position.js +19 -0
- package/waibuStatic/asset/js/control-mouse-position.js +47 -0
- package/waibuStatic/asset/js/control-ruler.js +204 -0
- package/waibuStatic/asset/js/donut-chart.js +58 -0
- package/waibuStatic/asset/js/lib/worker-timers.js +243 -0
- package/waibuStatic/virtual.json +7 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import control from './control.js'
|
|
2
|
+
|
|
3
|
+
const prefix = 'cmp'
|
|
4
|
+
|
|
5
|
+
async function controlMousePos () {
|
|
6
|
+
const WmapsControl = await control.call(this)
|
|
7
|
+
|
|
8
|
+
return class WmapsControlMousePos extends WmapsControl {
|
|
9
|
+
constructor (options) {
|
|
10
|
+
super(options)
|
|
11
|
+
this.params.noTag = true
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async build () {
|
|
15
|
+
const { generateId } = this.plugin.app.bajo
|
|
16
|
+
const { jsonStringify, minify } = this.plugin.app.waibuMpa
|
|
17
|
+
const { has, omit } = this.plugin.app.bajo.lib._
|
|
18
|
+
const options = omit(this.params.attr, ['octag', 'class', 'style', 'content'])
|
|
19
|
+
options.class = prefix + ' maplibregl-ctrl-group widget'
|
|
20
|
+
const id = generateId('alpha')
|
|
21
|
+
const tpl = await minify(await this.component.buildSentence(`
|
|
22
|
+
<c:grid-row>
|
|
23
|
+
<c:grid-col col="6">{%= lng %}</c:grid-col>
|
|
24
|
+
<c:grid-col col="6">{%= lat %}</c:grid-col>
|
|
25
|
+
</c:grid-row>
|
|
26
|
+
<c:grid-row style="font-size:smaller">
|
|
27
|
+
<c:grid-col col="6" t:content="Longitude" />
|
|
28
|
+
<c:grid-col col="6" t:content="Latitude" />
|
|
29
|
+
</c:grid-row>
|
|
30
|
+
`))
|
|
31
|
+
this.block.dataInit.push(`
|
|
32
|
+
this.$watch('$store.map.center', val => {
|
|
33
|
+
if (!this.${prefix}TrackCenter) return
|
|
34
|
+
this.${prefix}Pos = [...val]
|
|
35
|
+
})
|
|
36
|
+
this.$watch('${prefix}Pos', this.${prefix}Update.bind(this))
|
|
37
|
+
`)
|
|
38
|
+
this.block.reactive.push(`
|
|
39
|
+
${prefix}Tpl: _.template('${tpl}')
|
|
40
|
+
`, `
|
|
41
|
+
${prefix}Pos: [0, 0]
|
|
42
|
+
`, `
|
|
43
|
+
${prefix}TrackCenter: ${has(this.params.attr, 'trackCenter') ? 'true' : 'false'}
|
|
44
|
+
`, `
|
|
45
|
+
${prefix}Update () {
|
|
46
|
+
const el = document.querySelector('#${id}')
|
|
47
|
+
if (!el) return
|
|
48
|
+
const [lng, lat] = this.${prefix}Pos
|
|
49
|
+
el.innerHTML = this.${prefix}Tpl({
|
|
50
|
+
lng: wmpa.format(lng, 'float', { longitude: true }),
|
|
51
|
+
lat: wmpa.format(lat, 'float', { latitude: true })
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
`, `
|
|
55
|
+
async ${prefix}Builder () {
|
|
56
|
+
const body = '<c:div id="${id}" margin="x-2 top-1" text="align:center nowrap"/>'
|
|
57
|
+
return await wmpa.createComponent(body)
|
|
58
|
+
}
|
|
59
|
+
`)
|
|
60
|
+
this.block.run.push(`
|
|
61
|
+
map.on('mousemove', evt => {
|
|
62
|
+
if (this.${prefix}TrackCenter) return
|
|
63
|
+
const coord = evt.lngLat.wrap()
|
|
64
|
+
this.${prefix}Pos = [coord.lng, coord.lat]
|
|
65
|
+
})
|
|
66
|
+
if (this.${prefix}TrackCenter) this.${prefix}Pos = [...this.$store.map.center]
|
|
67
|
+
`)
|
|
68
|
+
|
|
69
|
+
this.block.control.push(`
|
|
70
|
+
await wmaps.createControl(_.merge(${jsonStringify(options, true)}, { builder: this.${prefix}Builder, firstCall: this.${prefix}Update }))
|
|
71
|
+
`)
|
|
72
|
+
|
|
73
|
+
this.params.html = this.writeBlock()
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export default controlMousePos
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import control from './control.js'
|
|
2
|
+
|
|
3
|
+
async function controlNavigation () {
|
|
4
|
+
const WmapsControl = await control.call(this)
|
|
5
|
+
|
|
6
|
+
return class WmapsControlNavigation extends WmapsControl {
|
|
7
|
+
constructor (options) {
|
|
8
|
+
super(options)
|
|
9
|
+
this.params.noTag = true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async build () {
|
|
13
|
+
const { jsonStringify } = this.plugin.app.waibuMpa
|
|
14
|
+
const opts = { showCompass: false }
|
|
15
|
+
if (this.params.attr.compass) opts.showCompass = true
|
|
16
|
+
if (this.params.attr.noZoom) opts.showZoom = false
|
|
17
|
+
if (this.params.attr.visualizePitch) opts.visualizePitch = true
|
|
18
|
+
opts.classSelector = 'maplibregl-ctrl-zoom-in'
|
|
19
|
+
opts.classGroup = true
|
|
20
|
+
opts.position = this.ctrlPos.includes(this.params.attr.position) ? this.params.attr.position : 'bottom-right'
|
|
21
|
+
this.block.control.push(`
|
|
22
|
+
await wmaps.createControlNative('NavigationControl', ${jsonStringify(opts, true)})
|
|
23
|
+
`)
|
|
24
|
+
this.params.html = this.writeBlock()
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default controlNavigation
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import control from './control.js'
|
|
2
|
+
const storeKey = 'mapControl.ruler'
|
|
3
|
+
|
|
4
|
+
async function controlRuler () {
|
|
5
|
+
const WmapsControl = await control.call(this)
|
|
6
|
+
|
|
7
|
+
return class WmapsControlRuler extends WmapsControl {
|
|
8
|
+
static scripts = [
|
|
9
|
+
...super.scripts,
|
|
10
|
+
'bajoSpatial.virtual:/geolib/lib/index.js',
|
|
11
|
+
'waibuMaps.asset:/js/control-ruler.js'
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
static css = [
|
|
15
|
+
...super.css,
|
|
16
|
+
'waibuMaps.asset:/css/control-ruler.css'
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
constructor (options) {
|
|
20
|
+
super(options)
|
|
21
|
+
this.params.noTag = true
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async build () {
|
|
25
|
+
const { routePath } = this.plugin.app.waibu
|
|
26
|
+
const { jsonStringify } = this.plugin.app.waibuMpa
|
|
27
|
+
const pos = this.ctrlPos.includes(this.params.attr.position) ? this.params.attr.position : 'bottom-right'
|
|
28
|
+
const opts = {
|
|
29
|
+
imageUrl: routePath('waibuMaps.asset:/image/ruler.svg')
|
|
30
|
+
}
|
|
31
|
+
this.block.control.push(`
|
|
32
|
+
const rulerCtrl = new ControlRuler(${jsonStringify(opts, true)})
|
|
33
|
+
map.addControl(rulerCtrl${pos ? `, '${pos}'` : ''})
|
|
34
|
+
if (this.$store.mapControl) {
|
|
35
|
+
el = document.querySelector('#' + map._container.id + ' .maplibregl-ctrl-ruler')
|
|
36
|
+
el.setAttribute('x-data', '')
|
|
37
|
+
el.setAttribute('x-show', '$store.${storeKey}')
|
|
38
|
+
// TODO: disable measuring first
|
|
39
|
+
// el.setAttribute('x-init', "$watch('$store.${storeKey}', val => console.log(rulerCtrl))")
|
|
40
|
+
}
|
|
41
|
+
`)
|
|
42
|
+
this.params.html = this.writeBlock()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default controlRuler
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import control from './control.js'
|
|
2
|
+
|
|
3
|
+
async function controlScale () {
|
|
4
|
+
const WmapsControl = await control.call(this)
|
|
5
|
+
|
|
6
|
+
return class WmapsControlScale extends WmapsControl {
|
|
7
|
+
constructor (options) {
|
|
8
|
+
super(options)
|
|
9
|
+
this.params.noTag = true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async build () {
|
|
13
|
+
const { jsonStringify } = this.plugin.app.waibuMpa
|
|
14
|
+
const { isString } = this.plugin.app.bajo.lib._
|
|
15
|
+
const opts = {}
|
|
16
|
+
if (['imperial', 'metric', 'nautical'].includes(this.params.attr.unit)) opts.unit = this.params.attr.unit
|
|
17
|
+
if (isString(this.params.attr.maxWidth) && Number(this.params.attr.maxWidth)) opts.maxWidth = Number(this.params.attr.maxWidth)
|
|
18
|
+
opts.position = this.ctrlPos.includes(this.params.attr.position) ? this.params.attr.position : 'bottom-left'
|
|
19
|
+
this.block.control.push(`
|
|
20
|
+
await wmaps.createControlNative('ScaleControl', ${jsonStringify(opts, true)})
|
|
21
|
+
`)
|
|
22
|
+
this.params.html = this.writeBlock()
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default controlScale
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import control from './control.js'
|
|
2
|
+
const prefix = 'csrc'
|
|
3
|
+
|
|
4
|
+
async function controlSearch () {
|
|
5
|
+
const WmapsControl = await control.call(this)
|
|
6
|
+
|
|
7
|
+
return class WmapsControlSearch extends WmapsControl {
|
|
8
|
+
constructor (options) {
|
|
9
|
+
super(options)
|
|
10
|
+
this.params.noTag = true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async build () {
|
|
14
|
+
const { generateId } = this.plugin.app.bajo
|
|
15
|
+
const { isString } = this.plugin.app.bajo.lib._
|
|
16
|
+
const { jsonStringify } = this.plugin.app.waibuMpa
|
|
17
|
+
const id = isString(this.params.attr.id) ? this.params.attr.id : generateId('alpha')
|
|
18
|
+
const opts = {}
|
|
19
|
+
opts.position = this.ctrlPos.includes(this.params.attr.position) ? this.params.attr.position : 'top-left'
|
|
20
|
+
opts.class = prefix + ' maplibregl-ctrl-group'
|
|
21
|
+
this.block.control.push(`
|
|
22
|
+
await wmaps.createControl(_.merge(${jsonStringify(opts, true)}, { builder: this.${prefix}Builder }))
|
|
23
|
+
`)
|
|
24
|
+
this.block.dataInit.push(`
|
|
25
|
+
this.$watch('$store.mapSearch.value', async val => {
|
|
26
|
+
if (_.isEmpty(val)) return wbs.notify('You need to enter a search phrase first', { type: 'danger' })
|
|
27
|
+
const html = await ${this.params.attr.method}(val, this.$store.mapSearch.feed)
|
|
28
|
+
this.$store.mapSearch.recent = html ?? ''
|
|
29
|
+
this.$store.mapSearch.busy = false
|
|
30
|
+
})
|
|
31
|
+
this.$watch('$store.mapSearch.recent', async val => {
|
|
32
|
+
val = val ?? ''
|
|
33
|
+
if (val === 'flying' && this.$store.mapSearch.feed === 'latLng:latLng') {
|
|
34
|
+
wbs.closeModal('${id}')
|
|
35
|
+
this.$store.mapSearch.recent = ''
|
|
36
|
+
}
|
|
37
|
+
wmpa.replaceWithComponentHtml(val, '#${id} .result div', 'div')
|
|
38
|
+
})
|
|
39
|
+
this.$watch('$store.mapSearch.feed', async val => {
|
|
40
|
+
this.$store.mapSearch.recent = ''
|
|
41
|
+
})
|
|
42
|
+
this.$watch('$store.mapSearch.busy', async val => {
|
|
43
|
+
const el = document.querySelector('#${id} .input-group .dropdown-toggle')
|
|
44
|
+
el.disabled = !!val
|
|
45
|
+
})
|
|
46
|
+
`)
|
|
47
|
+
this.block.mapLoad.push(`
|
|
48
|
+
await this.${prefix}Populate()
|
|
49
|
+
`)
|
|
50
|
+
this.block.reactive.push(`
|
|
51
|
+
async ${prefix}Builder (params) {
|
|
52
|
+
const body = [
|
|
53
|
+
'<c:button dim="height:100" flex="align-items:center justify-content:center" open="${id}">',
|
|
54
|
+
'<c:icon name="search" />',
|
|
55
|
+
'</c:button>'
|
|
56
|
+
]
|
|
57
|
+
return [await wmpa.createComponent(body)]
|
|
58
|
+
},
|
|
59
|
+
async ${prefix}Populate () {
|
|
60
|
+
const feeds = await ${this.params.attr.feed}() ?? []
|
|
61
|
+
feeds.unshift({ code: 'latLng', name: 'Goto Latitude/Longitude', feed: { id: 'latLng', label: 'Latitude/Longitude' } })
|
|
62
|
+
this.$store.mapSearch.feeds = feeds
|
|
63
|
+
const body = feeds.map(feed => '<c:dropdown-item :class="$store.mapSearch.feed === $el.getAttribute(\\'data-code-feedid\\') ? \\'active\\' : \\'\\'" data-code-feedid="' + feed.code + ':' + feed.feed.id + '" content="' + feed.feed.label + '" @click="$store.mapSearch.feed = \\'' + feed.code + ':' + feed.feed.id + '\\'"/>')
|
|
64
|
+
await wmpa.addComponent(body, '#${id} .input-group .dropdown-menu', 'div')
|
|
65
|
+
if (!this.$store.mapSearch.feed) this.$store.mapSearch.feed = feeds[0].code + ':' + feeds[0].feed.id
|
|
66
|
+
const html = this.$store.mapSearch.recent ?? ''
|
|
67
|
+
wmpa.replaceWithComponentHtml(html, '#${id} .result div', 'div')
|
|
68
|
+
}
|
|
69
|
+
`)
|
|
70
|
+
const ui = await this.component.buildSentence(`
|
|
71
|
+
<div class="childmap maplibregl-ctrl-search">
|
|
72
|
+
<c:modal id="${id}" size="lg" no-header no-center x-data="{
|
|
73
|
+
get feedCode () {
|
|
74
|
+
const [code, feedId] = (this.$store.mapSearch.feed ?? '').split(':')
|
|
75
|
+
return code
|
|
76
|
+
},
|
|
77
|
+
get feedName () {
|
|
78
|
+
const [code, feedId] = (this.$store.mapSearch.feed ?? '').split(':')
|
|
79
|
+
const item = _.find(this.$store.mapSearch.feeds, f => f.code === code && f.feed.id === feedId)
|
|
80
|
+
return item ? item.feed.label : feedId
|
|
81
|
+
},
|
|
82
|
+
search () {
|
|
83
|
+
this.$store.mapSearch.value = this.$refs.input.value
|
|
84
|
+
},
|
|
85
|
+
clearHistory () {
|
|
86
|
+
wmpa.replaceWithComponentHtml('', '#${id} .result div', 'div')
|
|
87
|
+
},
|
|
88
|
+
abort () {
|
|
89
|
+
const endpoint = this.$store.mapSearch.busy
|
|
90
|
+
const status = _.get(wmpa, 'fetchingApi.' + endpoint + '.status')
|
|
91
|
+
const controller = _.get(wmpa, 'fetchingApi.' + endpoint + '.abortCtrl')
|
|
92
|
+
if (!endpoint || status !== 'fetching') return
|
|
93
|
+
controller.abort()
|
|
94
|
+
},
|
|
95
|
+
resetValue () {
|
|
96
|
+
const el = document.querySelector('#${id} input[type=search]')
|
|
97
|
+
el.value = ''
|
|
98
|
+
},
|
|
99
|
+
select (id) {
|
|
100
|
+
this.$store.mapSearch.select = id
|
|
101
|
+
const instance = wbs.getInstance('Modal', '${id}')
|
|
102
|
+
instance.hide()
|
|
103
|
+
}
|
|
104
|
+
}" x-init="$watch('$store.mapSearch.feed', resetValue)">
|
|
105
|
+
<c:form-input x-ref="input" type="search" dim="width:max" @keyup.enter="search()" :disabled="$store.mapSearch.busy">
|
|
106
|
+
<c:form-input-addon prepend>
|
|
107
|
+
<c:dropdown>
|
|
108
|
+
</c:dropdown>
|
|
109
|
+
</c:form-input-addon>
|
|
110
|
+
<c:form-input-addon prepend>
|
|
111
|
+
<c:span x-show="feedCode === 'latLng'"><c:icon name="arrowEnd"/></c:span>
|
|
112
|
+
<c:span x-show="feedCode !== 'latLng' && !$store.mapSearch.busy"><c:icon name="search"/></c:span>
|
|
113
|
+
<c:spinner size="sm" x-show="feedCode !== 'latLng' && $store.mapSearch.busy" text="color:primary" />
|
|
114
|
+
</c:form-input-addon>
|
|
115
|
+
<c:form-input-addon append>
|
|
116
|
+
<c:btn @click="abort" x-show="$store.mapSearch.busy" t:content="Abort" />
|
|
117
|
+
</c:form-input-addon>
|
|
118
|
+
</c:form-input>
|
|
119
|
+
<c:div margin="top-2" flex="justify-content:between">
|
|
120
|
+
<div>
|
|
121
|
+
<template x-if="feedCode !== 'latLng'"><span><c:t>Search in:</c:t> <strong><span x-html="feedName" /></strong></span></template>
|
|
122
|
+
<template x-if="feedCode === 'latLng'"><span><c:t>Goto:</c:t> <strong><span><c:t>Latitude/Longitude</c:t></span></strong></span></template>
|
|
123
|
+
</div>
|
|
124
|
+
<c:btn x-show="feedCode !== 'latLng'" size="sm" color="link" t:content="Clear History" @click="clearHistory()" />
|
|
125
|
+
</c:div>
|
|
126
|
+
<c:div margin="top-3" class="result"><div></div></c:div>
|
|
127
|
+
</c:modal>
|
|
128
|
+
</div>
|
|
129
|
+
`)
|
|
130
|
+
this.block.dataInit.push(`
|
|
131
|
+
this.$watch('$store.mapSearch.select', async val => {
|
|
132
|
+
if (_.isEmpty(val)) return
|
|
133
|
+
const [source, feedId] = (this.$store.mapSearch.feed ?? '').split(':')
|
|
134
|
+
const feed = _.find(this.$store.mapSearch.feeds, item => {
|
|
135
|
+
return item.code === source && item.feed.id === feedId
|
|
136
|
+
})
|
|
137
|
+
this.$store.mapSearch.select = null
|
|
138
|
+
const scope = wmpa.alpineScope()
|
|
139
|
+
const fn = scope[feed.feed.prefix + 'FindTarget']
|
|
140
|
+
if (fn) await fn.call(scope, val, feedId)
|
|
141
|
+
})
|
|
142
|
+
`)
|
|
143
|
+
this.block.initializing.push(`
|
|
144
|
+
Alpine.store('mapSearch', {
|
|
145
|
+
feed: Alpine.$persist('latLng:latLng').as('mapSearchFeed'),
|
|
146
|
+
recent: Alpine.$persist('').as('mapSearchRecent'),
|
|
147
|
+
feeds: [],
|
|
148
|
+
select: null,
|
|
149
|
+
value: null,
|
|
150
|
+
busy: false
|
|
151
|
+
})
|
|
152
|
+
`)
|
|
153
|
+
|
|
154
|
+
this.params.html = [this.writeBlock(), ui].join('\n')
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export default controlSearch
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import control from './control.js'
|
|
2
|
+
|
|
3
|
+
const prefix = 'czbp'
|
|
4
|
+
|
|
5
|
+
async function controlZbp () {
|
|
6
|
+
const WmapsControl = await control.call(this)
|
|
7
|
+
|
|
8
|
+
return class WmapsControlZbp extends WmapsControl {
|
|
9
|
+
constructor (options) {
|
|
10
|
+
super(options)
|
|
11
|
+
this.params.noTag = true
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async build () {
|
|
15
|
+
const { generateId } = this.plugin.app.bajo
|
|
16
|
+
const { jsonStringify, minify } = this.plugin.app.waibuMpa
|
|
17
|
+
const { omit } = this.plugin.app.bajo.lib._
|
|
18
|
+
const options = omit(this.params.attr, ['octag', 'class', 'style', 'content'])
|
|
19
|
+
options.class = prefix + ' maplibregl-ctrl-group widget'
|
|
20
|
+
const id = generateId('alpha')
|
|
21
|
+
const tpl = await minify(await this.component.buildSentence(`
|
|
22
|
+
<c:grid-row font="size:5">
|
|
23
|
+
<c:grid-col col="4">{%= zoom %}</c:grid-col>
|
|
24
|
+
<c:grid-col col="4">{%= bearing %}</c:grid-col>
|
|
25
|
+
<c:grid-col col="4">{%= pitch %}</c:grid-col>
|
|
26
|
+
</c:grid-row>
|
|
27
|
+
<c:grid-row style="font-size:smaller">
|
|
28
|
+
<c:grid-col col="4" t:content="Zoom" />
|
|
29
|
+
<c:grid-col style="cursor:pointer" @click="reset" col="4" t:content="Bearing" />
|
|
30
|
+
<c:grid-col style="cursor:pointer" @click="reset" col="4" t:content="Pitch" />
|
|
31
|
+
</c:grid-row>
|
|
32
|
+
`))
|
|
33
|
+
this.block.dataInit.push(`
|
|
34
|
+
this.$watch('$store.map.zoom, $store.map.bearing, $store.map.pitch', this.${prefix}Update.bind(this))
|
|
35
|
+
`)
|
|
36
|
+
this.block.reactive.push(`
|
|
37
|
+
${prefix}Tpl: _.template('${tpl}')
|
|
38
|
+
`, `
|
|
39
|
+
${prefix}Update () {
|
|
40
|
+
const el = document.querySelector('#${id}')
|
|
41
|
+
if (!el) return
|
|
42
|
+
el.innerHTML = this.${prefix}Tpl({
|
|
43
|
+
zoom: wmpa.format(this.$store.map.zoom, 'integer'),
|
|
44
|
+
bearing: wmpa.format(this.$store.map.bearing, 'integer'),
|
|
45
|
+
pitch: wmpa.format(this.$store.map.pitch, 'integer')
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
`, `
|
|
49
|
+
async ${prefix}Builder () {
|
|
50
|
+
const body = ['<c:div id="${id}" margin="x-2 top-1" text="align:center" ',
|
|
51
|
+
'x-data="{',
|
|
52
|
+
' reset () {',
|
|
53
|
+
' wmpa.alpineScopeMethod(\\'getMap.flyTo\\')({ bearing: 0, pitch: 0 }) ',
|
|
54
|
+
' }',
|
|
55
|
+
'}" />'
|
|
56
|
+
]
|
|
57
|
+
return await wmpa.createComponent(body)
|
|
58
|
+
}
|
|
59
|
+
`)
|
|
60
|
+
|
|
61
|
+
this.block.control.push(`
|
|
62
|
+
await wmaps.createControl(_.merge(${jsonStringify(options, true)}, { builder: this.${prefix}Builder, firstCall: this.${prefix}Update }))
|
|
63
|
+
`)
|
|
64
|
+
|
|
65
|
+
this.params.html = this.writeBlock()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default controlZbp
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import wmapsBase from '../wmaps-base.js'
|
|
2
|
+
|
|
3
|
+
async function control () {
|
|
4
|
+
const WmapsBase = await wmapsBase.call(this)
|
|
5
|
+
|
|
6
|
+
return class WmapsControl extends WmapsBase {
|
|
7
|
+
constructor (options) {
|
|
8
|
+
super(options)
|
|
9
|
+
this.ctrlPos = ['top-left', 'top-right', 'bottom-left', 'bottom-right']
|
|
10
|
+
this.params.noTag = true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async build () {
|
|
14
|
+
const { $ } = this.component
|
|
15
|
+
const html = []
|
|
16
|
+
$(`<div>${this.params.html}</div>`).find('.childmap').each(function () {
|
|
17
|
+
html.push($(this).prop('outerHTML'))
|
|
18
|
+
})
|
|
19
|
+
this.readBlock()
|
|
20
|
+
// persisting
|
|
21
|
+
if (this.params.attr.persist) {
|
|
22
|
+
this.block.initializing.push(`
|
|
23
|
+
Alpine.store('mapControl', {
|
|
24
|
+
attrib: Alpine.$persist(true).as('mapControlAttrib'),
|
|
25
|
+
centerPos: Alpine.$persist(true).as('mapControlCenterPos'),
|
|
26
|
+
fullscreen: Alpine.$persist(true).as('mapControlFullscreen'),
|
|
27
|
+
mousePos: Alpine.$persist(true).as('mapControlMousePos'),
|
|
28
|
+
nav: Alpine.$persist(true).as('mapControlNav'),
|
|
29
|
+
scale: Alpine.$persist(true).as('mapControlScale'),
|
|
30
|
+
geolocate: Alpine.$persist(true).as('mapControlGeolocate'),
|
|
31
|
+
ruler: Alpine.$persist(true).as('mapControlRuler'),
|
|
32
|
+
search: Alpine.$persist(true).as('mapControlSearch')
|
|
33
|
+
})
|
|
34
|
+
`)
|
|
35
|
+
}
|
|
36
|
+
this.params.html = this.writeBlock()
|
|
37
|
+
if (html.length > 0) this.params.html += '\n' + html.join('\n')
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default control
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import wmapsBase from '../wmaps-base.js'
|
|
2
|
+
|
|
3
|
+
export function buildLayers (params) {
|
|
4
|
+
const { isString, map } = this.plugin.app.bajo.lib._
|
|
5
|
+
const { routePath } = this.plugin.app.waibu
|
|
6
|
+
const { attrToArray, jsonStringify } = this.plugin.app.waibuMpa
|
|
7
|
+
|
|
8
|
+
if (!isString(params.attr.layer)) return ''
|
|
9
|
+
const items = map(attrToArray(params.attr.layer), item => routePath(item))
|
|
10
|
+
return `
|
|
11
|
+
for (const l of ${jsonStringify(items, true)}) {
|
|
12
|
+
const layer = await this.loadResource(l)
|
|
13
|
+
layer.source = '${params.attr.name}'
|
|
14
|
+
map.addLayer(layer)
|
|
15
|
+
}
|
|
16
|
+
`
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function buildImage (params) {
|
|
20
|
+
const { isString, map } = this.plugin.app.bajo.lib._
|
|
21
|
+
const { routePath } = this.plugin.app.waibu
|
|
22
|
+
const { attrToArray, jsonStringify } = this.plugin.app.waibuMpa
|
|
23
|
+
|
|
24
|
+
if (!isString(params.attr.image)) return ''
|
|
25
|
+
const items = map(attrToArray(params.attr.image), item => routePath(item))
|
|
26
|
+
return `
|
|
27
|
+
for (const l of ${jsonStringify(items, true)}) {
|
|
28
|
+
let [item, name] = l.split(';')
|
|
29
|
+
if (!name) name = _.last(l.split('?')[0].split('#')[0].split('/')).split('.')[0]
|
|
30
|
+
if (map.listImages().includes(name)) continue
|
|
31
|
+
const resp = await map.loadImage(l)
|
|
32
|
+
map.addImage(name, resp.data)
|
|
33
|
+
}
|
|
34
|
+
`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function buildSrcImages (params) {
|
|
38
|
+
const { isString } = this.plugin.app.bajo.lib._
|
|
39
|
+
const { routePath, fetch } = this.plugin.app.waibu
|
|
40
|
+
|
|
41
|
+
if (!isString(params.attr.srcImages)) return
|
|
42
|
+
params.attr.srcImages = routePath(params.attr.srcImages)
|
|
43
|
+
const items = await fetch(params.attr.srcImages)
|
|
44
|
+
const lines = []
|
|
45
|
+
for (const key in items) {
|
|
46
|
+
lines.push(`${items[key]};${key}`)
|
|
47
|
+
}
|
|
48
|
+
params.attr.image = lines.join(' ')
|
|
49
|
+
return buildImage.call(this, params)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function buildSource (params, extra = []) {
|
|
53
|
+
const { routePath } = this.plugin.app.waibu
|
|
54
|
+
params.attr.src = routePath(params.attr.src)
|
|
55
|
+
return `
|
|
56
|
+
const rsc = await this.loadResource('${params.attr.src}')
|
|
57
|
+
let data = {}
|
|
58
|
+
if (rsc.type === 'geojson' && rsc.data) data = rsc
|
|
59
|
+
else {
|
|
60
|
+
data.type = 'geojson'
|
|
61
|
+
data.data = rsc
|
|
62
|
+
}
|
|
63
|
+
${params.attr.lineGradient ? 'data.lineMetrics = true' : ''}
|
|
64
|
+
${extra.join('\n')}
|
|
65
|
+
map.addSource('${params.attr.name}', data)
|
|
66
|
+
`
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function layerGeojson () {
|
|
70
|
+
const WmapsBase = await wmapsBase.call(this)
|
|
71
|
+
|
|
72
|
+
return class WmapsLayerGeojson extends WmapsBase {
|
|
73
|
+
constructor (options) {
|
|
74
|
+
super(options)
|
|
75
|
+
this.params.noTag = true
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async build () {
|
|
79
|
+
const { generateId } = this.plugin.app.bajo
|
|
80
|
+
const { isString } = this.plugin.app.bajo.lib._
|
|
81
|
+
const { groupAttrs } = this.plugin.app.waibuMpa
|
|
82
|
+
this.params.noTag = true
|
|
83
|
+
if (!this.params.attr.src) return
|
|
84
|
+
this.params.attr.name = this.params.attr.name ?? generateId('alpha')
|
|
85
|
+
const group = groupAttrs(this.params.attr, ['cluster'])
|
|
86
|
+
const cluster = []
|
|
87
|
+
if (group.cluster) {
|
|
88
|
+
cluster.push('data.cluster = true')
|
|
89
|
+
if (isString(group.cluster.radius)) cluster.push('data.clusterRadius = ' + Number(group.cluster.radius))
|
|
90
|
+
if (isString(group.cluster.maxZoom)) cluster.push('data.clusterMaxZoom = ' + Number(group.cluster.maxZoom))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.block.mapLoad.push(`
|
|
94
|
+
${this.params.attr.srcImages ? (await buildSrcImages.call(this, this.params)) : buildImage.call(this, this.params)}
|
|
95
|
+
${buildSource.call(this, this.params, cluster)}
|
|
96
|
+
${buildLayers.call(this, this.params)}
|
|
97
|
+
`)
|
|
98
|
+
this.params.html = this.writeBlock()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default layerGeojson
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import wmapsBase from '../wmaps-base.js'
|
|
2
|
+
|
|
3
|
+
import { buildSource } from './layer-geojson.js'
|
|
4
|
+
|
|
5
|
+
function createLayerLabel (params) {
|
|
6
|
+
return `{
|
|
7
|
+
id: '${params.attr.name}_label',
|
|
8
|
+
type: 'symbol',
|
|
9
|
+
source: '${params.attr.name}',
|
|
10
|
+
filter: ['!=', '${params.attr.clusterKey}', true],
|
|
11
|
+
layout: {
|
|
12
|
+
'text-field': [
|
|
13
|
+
'number-format',
|
|
14
|
+
['get', '${params.attr.valueKey}'],
|
|
15
|
+
{'min-fraction-digits': 1, 'max-fraction-digits': 1}
|
|
16
|
+
],
|
|
17
|
+
'text-font': ['Open Sans Bold'],
|
|
18
|
+
'text-size': 10
|
|
19
|
+
},
|
|
20
|
+
paint: {
|
|
21
|
+
'text-color': [
|
|
22
|
+
'case',
|
|
23
|
+
['<', ['get', '${params.attr.valueKey}'], 3],
|
|
24
|
+
'black',
|
|
25
|
+
'white'
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function createLayerCircle (params, filters) {
|
|
32
|
+
const circle = [`{
|
|
33
|
+
id: '${params.attr.name}_circle',
|
|
34
|
+
type: 'circle',
|
|
35
|
+
source: '${params.attr.name}',
|
|
36
|
+
filter: ['!=', '${params.attr.clusterKey}', true],
|
|
37
|
+
paint: {
|
|
38
|
+
'circle-color': [
|
|
39
|
+
'case',
|
|
40
|
+
`]
|
|
41
|
+
let i = 0
|
|
42
|
+
const keys = Object.keys(filters)
|
|
43
|
+
for (const key of keys) {
|
|
44
|
+
circle.push(`this.filter.${key},`, `this.colors[${i}],`)
|
|
45
|
+
i++
|
|
46
|
+
if (i >= keys.length - 1) break
|
|
47
|
+
}
|
|
48
|
+
circle.push(`this.colors[${i}]`, '],\'circle-opacity\': 0.6, \'circle-radius\': 12 }}')
|
|
49
|
+
return circle.join('\n')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function layerHtmlCluster () {
|
|
53
|
+
const WmapsBase = await wmapsBase.call(this)
|
|
54
|
+
|
|
55
|
+
return class WmapsLayerHtmlCluster extends WmapsBase {
|
|
56
|
+
static scripts = [
|
|
57
|
+
...super.scripts,
|
|
58
|
+
'waibuMaps.asset:/js/donut-chart.js'
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
constructor (options) {
|
|
62
|
+
super(options)
|
|
63
|
+
this.params.noTag = true
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async build () {
|
|
67
|
+
const { generateId } = this.plugin.app.bajo
|
|
68
|
+
const { attrToArray, jsonStringify } = this.plugin.app.waibuMpa
|
|
69
|
+
const { fetch, routePath } = this.plugin.app.waibu
|
|
70
|
+
const { isString } = this.plugin.app.bajo.lib._
|
|
71
|
+
if (!this.params.attr.src) return
|
|
72
|
+
this.params.attr.name = this.params.attr.name ?? generateId('alpha')
|
|
73
|
+
this.params.attr.valueKey = this.params.attr.valueKey ?? ''
|
|
74
|
+
this.params.attr.clusterKey = this.params.attr.clusterKey ?? 'cluster'
|
|
75
|
+
this.params.attr.clusterIdKey = this.params.attr.clusterIdKey ?? 'clusterId'
|
|
76
|
+
const colors = attrToArray(this.params.attr.color ?? '#fed976 #feb24c #fd8d3c #fc4e2a #e31a1c')
|
|
77
|
+
this.params.attr.filter = routePath(this.params.attr.filter)
|
|
78
|
+
const filters = await fetch(this.params.attr.filter)
|
|
79
|
+
const extra = [
|
|
80
|
+
'data.cluster = true',
|
|
81
|
+
`data.clusterRadius = ${isString(this.params.attr.clusterRadius) ? Number(this.params.attr.clusterRadius) : 80}`,
|
|
82
|
+
'data.clusterProperties = {'
|
|
83
|
+
]
|
|
84
|
+
for (const key in filters) {
|
|
85
|
+
extra.push(`${key}: ['+', ['case', this.filter.${key}, 1, 0]],`)
|
|
86
|
+
}
|
|
87
|
+
extra.push('}')
|
|
88
|
+
this.block.mapLoad.push(`
|
|
89
|
+
${buildSource.call(this, this.params, extra)}
|
|
90
|
+
map.addLayer(
|
|
91
|
+
${createLayerCircle.call(this, this.params, filters)}
|
|
92
|
+
)
|
|
93
|
+
map.addLayer(
|
|
94
|
+
${createLayerLabel.call(this, this.params)}
|
|
95
|
+
)
|
|
96
|
+
map.on('data', e => {
|
|
97
|
+
if (e.sourceId !== '${this.params.attr.name}' || !e.isSourceLoaded) return
|
|
98
|
+
map.on('move', () => { this.updateMarkers() })
|
|
99
|
+
map.on('moveend', () => { this.updateMarkers() })
|
|
100
|
+
updateMarkers()
|
|
101
|
+
})
|
|
102
|
+
`)
|
|
103
|
+
this.block.reactive.push(
|
|
104
|
+
`colors: ${jsonStringify(colors, true)}`,
|
|
105
|
+
`filter: ${jsonStringify(filters, true)}`,
|
|
106
|
+
`updateMarkers () {
|
|
107
|
+
const filter = Alpine.raw(this.filter)
|
|
108
|
+
const colors = Alpine.raw(this.colors)
|
|
109
|
+
wmaps.updateClusterMarkers({
|
|
110
|
+
sourceId: '${this.params.attr.name}',
|
|
111
|
+
clusterKey: '${this.params.attr.clusterKey}',
|
|
112
|
+
clusterIdKey: '${this.params.attr.clusterIdKey}',
|
|
113
|
+
handler: function (props) {
|
|
114
|
+
return donutChart.create(props, Object.keys(filter), colors)
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
}`
|
|
118
|
+
)
|
|
119
|
+
this.params.html = this.writeBlock()
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default layerHtmlCluster
|