@unvt/charites 0.2.0 → 0.4.0
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/.devcontainer/README.md +1 -1
- package/.eslintrc.js +1 -1
- package/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- package/.github/release.yml +14 -0
- package/.github/workflows/build-docs.yml +4 -4
- package/.github/workflows/build.yml +33 -7
- package/LICENSE +1 -1
- package/dist/cli/build.js +4 -4
- package/dist/cli/convert.js +2 -2
- package/dist/cli/init.js +3 -3
- package/dist/cli/serve.js +8 -4
- package/dist/commands/build.js +7 -12
- package/dist/commands/convert.js +2 -12
- package/dist/commands/init.js +1 -1
- package/dist/commands/serve.js +81 -16
- package/dist/lib/build-sprite.js +6 -8
- package/dist/lib/error.js +2 -1
- package/dist/lib/tileinfo-importer/index.js +1 -0
- package/dist/lib/yaml-writer.js +25 -13
- package/dist/types/index.js +6 -2
- package/docs/Pipfile.lock +136 -193
- package/docs/source/conf.py +3 -3
- package/docs/source/index.rst +2 -2
- package/docs/source/install/img/windows-guide-01.png +0 -0
- package/docs/source/install/index.rst +1 -0
- package/docs/source/install/install.rst +1 -0
- package/docs/source/install/install_on_nanban.rst +1 -1
- package/docs/source/install/installation_guide_for_windows.rst +52 -0
- package/docs/source/install/recommended_environment.rst +2 -2
- package/docs/source/usage/commandline_interface.rst +23 -10
- package/docs/source/usage/example2.rst +166 -0
- package/docs/source/usage/examples.rst +2 -2
- package/docs/source/usage/img/example02-001.png +0 -0
- package/docs/source/usage/img/example02-002.png +0 -0
- package/docs/source/usage/img/example02-003.png +0 -0
- package/docs/source/usage/img/example02-004.png +0 -0
- package/docs/source/usage/img/example02-005.png +0 -0
- package/docs/source/usage/img/example02-006.png +0 -0
- package/docs/source/usage/img/example02-007.png +0 -0
- package/docs/source/usage/img/example02-008.png +0 -0
- package/docs/source/usage/img/example02-009.png +0 -0
- package/docs/source/usage/img/example02-010.png +0 -0
- package/docs/source/usage/img/example02-011.png +0 -0
- package/docs/source/usage/img/example02-012.png +0 -0
- package/docs/source/usage/img/example02-013.png +0 -0
- package/docs/source/usage/img/example02-014.png +0 -0
- package/docs/source/usage/img/example02-015.png +0 -0
- package/docs/source/usage/img/example02-016.png +0 -0
- package/docs/source/usage/img/example02-017.png +0 -0
- package/docs/source/usage/img/example02-018.png +0 -0
- package/docs/source/usage/index.rst +1 -0
- package/package.json +34 -28
- package/playwright.config.ts +29 -0
- package/provider/default/app.js +26 -46
- package/provider/default/index.html +4 -3
- package/provider/default/shared.js +76 -0
- package/provider/geolonia/app.js +25 -32
- package/provider/geolonia/index.html +4 -1
- package/provider/mapbox/app.js +33 -53
- package/provider/mapbox/index.html +2 -1
- package/src/cli/init.ts +1 -1
- package/src/cli/serve.ts +10 -3
- package/src/commands/build.ts +2 -6
- package/src/commands/convert.ts +2 -10
- package/src/commands/init.ts +1 -1
- package/src/commands/serve.ts +107 -15
- package/src/lib/build-sprite.ts +2 -6
- package/src/lib/get-sprite-slug.ts +1 -1
- package/src/lib/tileinfo-importer/base-importer.ts +1 -1
- package/src/lib/tileinfo-importer/metadata-importer.ts +1 -1
- package/src/lib/tileinfo-importer/tilejson-importer.ts +1 -1
- package/src/lib/validate-style.ts +1 -1
- package/src/lib/yaml-parser.ts +1 -1
- package/src/lib/yaml-writer.ts +28 -15
- package/test/build.spec.ts +22 -12
- package/test/command.build.spec.ts +39 -31
- package/test/command.serve.spec.ts +103 -0
- package/test/convert.spec.ts +24 -4
- package/test/data/convert.json +7 -0
- package/test/data/style.json +4 -3
- package/test/init.spec.ts +7 -5
- package/test/playwright/provider/default/e2e.spec.ts +13 -0
- package/test/playwright/provider/geolonia/e2e.spec.ts +13 -0
- package/test/playwright/provider/mapbox/e2e.spec.ts +13 -0
- package/test/util/charitesCmd.ts +3 -1
- package/test/util/execPromise.ts +51 -1
- package/test/util/index.ts +3 -0
- package/test/validate-style.spec.ts +1 -1
- package/provider/geolonia/app.css +0 -17
- package/provider/mapbox/app.css +0 -17
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
2
|
+
<html id="charites-geolonia">
|
|
3
3
|
<head>
|
|
4
4
|
<link rel="stylesheet" href="/app.css" />
|
|
5
5
|
<title>Charites Live Preview</title>
|
|
6
|
+
<link href='https://watergis.github.io/maplibre-gl-legend/maplibre-gl-legend.css' rel='stylesheet' />
|
|
6
7
|
</head>
|
|
7
8
|
<body>
|
|
8
9
|
<div class="overlay">
|
|
@@ -14,6 +15,8 @@
|
|
|
14
15
|
</div>
|
|
15
16
|
<div id="map"></div>
|
|
16
17
|
<script type="text/javascript" src="https://cdn.geolonia.com/v1/embed?geolonia-api-key=YOUR-API-KEY"></script>
|
|
18
|
+
<script src="https://watergis.github.io/maplibre-gl-legend/maplibre-gl-legend.js"></script>
|
|
19
|
+
<script type="text/javascript" src="/shared.js"></script>
|
|
17
20
|
<script type="text/javascript" src="/app.js"></script>
|
|
18
21
|
</body>
|
|
19
22
|
</html>
|
package/provider/mapbox/app.js
CHANGED
|
@@ -1,53 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
map.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
map.showTileBoundaries = checked
|
|
35
|
-
}
|
|
36
|
-
setShowTileBoundaries()
|
|
37
|
-
showTileBoundaries.addEventListener('click', setShowTileBoundaries)
|
|
38
|
-
|
|
39
|
-
const showCollisionBoxes = document.getElementById('showCollisionBoxes')
|
|
40
|
-
const setShowCollisionBoxes = function () {
|
|
41
|
-
const checked = showCollisionBoxes.checked
|
|
42
|
-
map.showCollisionBoxes = checked
|
|
43
|
-
}
|
|
44
|
-
setShowCollisionBoxes()
|
|
45
|
-
showCollisionBoxes.addEventListener('click', setShowCollisionBoxes)
|
|
46
|
-
|
|
47
|
-
const showPadding = document.getElementById('showPadding')
|
|
48
|
-
const setShowPadding = function () {
|
|
49
|
-
const checked = showPadding.checked
|
|
50
|
-
map.showPadding = checked
|
|
51
|
-
}
|
|
52
|
-
setShowPadding()
|
|
53
|
-
showPadding.addEventListener('click', setShowPadding)
|
|
1
|
+
;(async () => {
|
|
2
|
+
mapboxgl.accessToken = '___MAPBOX_ACCESS_TOKEN___'
|
|
3
|
+
|
|
4
|
+
const { style, center, zoom } = await window._charites.parseMapStyle()
|
|
5
|
+
const options = {
|
|
6
|
+
container: 'map',
|
|
7
|
+
hash: true,
|
|
8
|
+
style,
|
|
9
|
+
}
|
|
10
|
+
if (center) options.center = center
|
|
11
|
+
if (zoom) options.zoom = zoom
|
|
12
|
+
const map = new mapboxgl.Map(options)
|
|
13
|
+
|
|
14
|
+
window._charites.initializeWebSocket(map)
|
|
15
|
+
|
|
16
|
+
map.addControl(new mapboxgl.NavigationControl(), 'top-right')
|
|
17
|
+
|
|
18
|
+
map.addControl(
|
|
19
|
+
new MapboxLegendControl(
|
|
20
|
+
{},
|
|
21
|
+
{
|
|
22
|
+
showDefault: true,
|
|
23
|
+
showCheckbox: true,
|
|
24
|
+
onlyRendered: true,
|
|
25
|
+
reverseOrder: true,
|
|
26
|
+
accesstoken: mapboxgl.accessToken,
|
|
27
|
+
},
|
|
28
|
+
),
|
|
29
|
+
'bottom-left',
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
window._charites.setupDebugCheckboxes(map)
|
|
33
|
+
})()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
2
|
+
<html id="charites-mapbox">
|
|
3
3
|
<head>
|
|
4
4
|
<link rel="stylesheet" href="/app.css" />
|
|
5
5
|
<link href='https://api.mapbox.com/mapbox-gl-js/v2.5.0/mapbox-gl.css' rel='stylesheet' />
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
<label><input type="checkbox" id="showPadding">show Padding</label>
|
|
18
18
|
</div>
|
|
19
19
|
<div id="map"></div>
|
|
20
|
+
<script type="text/javascript" src="/shared.js"></script>
|
|
20
21
|
<script type="text/javascript" src="/app.js"></script>
|
|
21
22
|
</body>
|
|
22
23
|
</html>
|
package/src/cli/init.ts
CHANGED
|
@@ -6,7 +6,7 @@ const program = new Command()
|
|
|
6
6
|
program
|
|
7
7
|
.name('init')
|
|
8
8
|
.arguments('<file>')
|
|
9
|
-
.description('initialize a style
|
|
9
|
+
.description('initialize a style YAML')
|
|
10
10
|
.option(
|
|
11
11
|
'-t, --tilejson-urls <tilejson_urls>',
|
|
12
12
|
'an URL for TileJSON. It will create empty layers from vector_layers property of TileJSON. Please use comma (,) in case multiple TileJSONs require.',
|
package/src/cli/serve.ts
CHANGED
|
@@ -15,14 +15,21 @@ program
|
|
|
15
15
|
)
|
|
16
16
|
.option(
|
|
17
17
|
'--mapbox-access-token [mapboxAccessToken]',
|
|
18
|
-
'Access Token
|
|
18
|
+
'Your Mapbox Access Token (required if using the `mapbox` provider)',
|
|
19
|
+
)
|
|
20
|
+
.option(
|
|
21
|
+
'-i, --sprite-input [<icon input directory>]',
|
|
22
|
+
'directory path of icon source to build icons. The default <icon source> is `icons/`',
|
|
19
23
|
)
|
|
20
24
|
.option('--port [port]', 'Specify custom port')
|
|
21
|
-
.
|
|
25
|
+
.option('--no-open', "Don't open the preview in the default browser")
|
|
26
|
+
.action(async (source: string, serveOptions: serveOptions) => {
|
|
22
27
|
const options: serveOptions = program.opts()
|
|
23
28
|
options.provider = serveOptions.provider
|
|
24
29
|
options.mapboxAccessToken = serveOptions.mapboxAccessToken
|
|
25
30
|
options.port = serveOptions.port
|
|
31
|
+
options.spriteInput = serveOptions.spriteInput
|
|
32
|
+
options.open = serveOptions.open
|
|
26
33
|
if (!fs.existsSync(defaultSettings.configFile)) {
|
|
27
34
|
fs.writeFileSync(
|
|
28
35
|
defaultSettings.configFile,
|
|
@@ -30,7 +37,7 @@ program
|
|
|
30
37
|
)
|
|
31
38
|
}
|
|
32
39
|
try {
|
|
33
|
-
serve(source, program.opts())
|
|
40
|
+
await serve(source, program.opts())
|
|
34
41
|
} catch (e) {
|
|
35
42
|
error(e)
|
|
36
43
|
}
|
package/src/commands/build.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { buildSprite } from '../lib/build-sprite'
|
|
|
6
6
|
import { getSpriteSlug } from '../lib/get-sprite-slug'
|
|
7
7
|
import { defaultValues } from '../lib/defaultValues'
|
|
8
8
|
import jsonminify from 'jsonminify'
|
|
9
|
-
import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec
|
|
9
|
+
import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec'
|
|
10
10
|
import watch from 'node-watch'
|
|
11
11
|
|
|
12
12
|
export interface buildOptions {
|
|
@@ -94,11 +94,7 @@ export async function build(
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
fs.writeFileSync(destinationPath, style)
|
|
99
|
-
} catch (err) {
|
|
100
|
-
throw `${destinationPath}: Permission denied`
|
|
101
|
-
}
|
|
97
|
+
fs.writeFileSync(destinationPath, style)
|
|
102
98
|
}
|
|
103
99
|
|
|
104
100
|
export function buildWatch(
|
package/src/commands/convert.ts
CHANGED
|
@@ -45,11 +45,7 @@ export function convert(source: string, destination: string) {
|
|
|
45
45
|
const style = JSON.parse(lines.join(''))
|
|
46
46
|
const destinationPath = getDestinationPath(destination)
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
writeYaml(destinationPath, style, false)
|
|
50
|
-
} catch (err) {
|
|
51
|
-
throw `${destinationPath}: Permission denied`
|
|
52
|
-
}
|
|
48
|
+
writeYaml(destinationPath, style, false)
|
|
53
49
|
})
|
|
54
50
|
} else {
|
|
55
51
|
sourcePath = path.resolve(process.cwd(), source)
|
|
@@ -67,10 +63,6 @@ export function convert(source: string, destination: string) {
|
|
|
67
63
|
|
|
68
64
|
const destinationPath = getDestinationPath(destination, sourcePath)
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
writeYaml(destinationPath, style, false)
|
|
72
|
-
} catch (err) {
|
|
73
|
-
throw `${destinationPath}: Permission denied`
|
|
74
|
-
}
|
|
66
|
+
writeYaml(destinationPath, style, false)
|
|
75
67
|
}
|
|
76
68
|
}
|
package/src/commands/init.ts
CHANGED
package/src/commands/serve.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import fs from 'fs'
|
|
3
|
+
import os from 'os'
|
|
3
4
|
import http from 'http'
|
|
4
5
|
import open from 'open'
|
|
5
6
|
import { WebSocketServer } from 'ws'
|
|
@@ -8,14 +9,17 @@ import watch from 'node-watch'
|
|
|
8
9
|
import { parser } from '../lib/yaml-parser'
|
|
9
10
|
import { validateStyle } from '../lib/validate-style'
|
|
10
11
|
import { defaultValues } from '../lib/defaultValues'
|
|
12
|
+
import { buildSprite } from '../lib/build-sprite'
|
|
11
13
|
|
|
12
14
|
export interface serveOptions {
|
|
13
15
|
provider?: string
|
|
14
16
|
mapboxAccessToken?: string
|
|
15
17
|
port?: string
|
|
18
|
+
spriteInput?: string
|
|
19
|
+
open?: boolean
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
export function serve(source: string, options: serveOptions) {
|
|
22
|
+
export async function serve(source: string, options: serveOptions) {
|
|
19
23
|
let port = process.env.PORT || 8080
|
|
20
24
|
if (options.port) {
|
|
21
25
|
port = Number(options.port)
|
|
@@ -36,40 +40,102 @@ export function serve(source: string, options: serveOptions) {
|
|
|
36
40
|
throw `${sourcePath}: No such file or directory`
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
const
|
|
43
|
+
const mapboxAccessToken =
|
|
44
|
+
options.mapboxAccessToken || defaultValues.mapboxAccessToken
|
|
45
|
+
if (provider === 'mapbox' && !mapboxAccessToken) {
|
|
46
|
+
throw `Provider is mapbox, but the Mapbox Access Token is not set. Please provide it using --mapbox-access-token, or set it in \`~/.charites/config.yml\` (see the Global configuration section of the documentation for more information)`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let spriteOut: string | undefined = undefined
|
|
50
|
+
let spriteRefresher: (() => Promise<void>) | undefined = undefined
|
|
51
|
+
if (options.spriteInput) {
|
|
52
|
+
spriteOut = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'charites-'))
|
|
53
|
+
spriteRefresher = async () => {
|
|
54
|
+
if (
|
|
55
|
+
typeof options.spriteInput === 'undefined' ||
|
|
56
|
+
typeof spriteOut === 'undefined'
|
|
57
|
+
) {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
await buildSprite(options.spriteInput, spriteOut, 'sprite')
|
|
61
|
+
}
|
|
62
|
+
await spriteRefresher()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const server = http.createServer(async (req, res) => {
|
|
40
66
|
const url = (req.url || '').replace(/\?.*/, '')
|
|
41
|
-
const
|
|
67
|
+
const defaultProviderDir = path.join(defaultValues.providerDir, 'default')
|
|
68
|
+
const providerDir = path.join(defaultValues.providerDir, provider)
|
|
69
|
+
|
|
70
|
+
if (
|
|
71
|
+
typeof spriteOut !== 'undefined' &&
|
|
72
|
+
url.match(/^\/sprite(@2x)?\.(json|png)/)
|
|
73
|
+
) {
|
|
74
|
+
res.statusCode = 200
|
|
75
|
+
if (url.endsWith('.json')) {
|
|
76
|
+
res.setHeader('Content-Type', 'application/json; charset=UTF-8')
|
|
77
|
+
} else {
|
|
78
|
+
res.setHeader('Content-Type', 'image/png')
|
|
79
|
+
}
|
|
80
|
+
res.setHeader('Cache-Control', 'no-store')
|
|
81
|
+
const filename = path.basename(url)
|
|
82
|
+
const fsStream = fs.createReadStream(path.join(spriteOut, filename))
|
|
83
|
+
fsStream.pipe(res)
|
|
84
|
+
return
|
|
85
|
+
}
|
|
42
86
|
|
|
43
87
|
switch (url) {
|
|
44
88
|
case '/':
|
|
45
89
|
res.statusCode = 200
|
|
46
90
|
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
|
|
47
|
-
const content = fs.readFileSync(
|
|
91
|
+
const content = fs.readFileSync(
|
|
92
|
+
path.join(providerDir, 'index.html'),
|
|
93
|
+
'utf-8',
|
|
94
|
+
)
|
|
48
95
|
res.end(content)
|
|
49
96
|
break
|
|
50
97
|
case '/style.json':
|
|
51
98
|
let style
|
|
52
99
|
try {
|
|
53
100
|
style = parser(sourcePath)
|
|
101
|
+
if (typeof spriteOut !== 'undefined') {
|
|
102
|
+
style.sprite = `http://${
|
|
103
|
+
req.headers.host || `localhost:${port}`
|
|
104
|
+
}/sprite`
|
|
105
|
+
}
|
|
54
106
|
validateStyle(style, provider)
|
|
55
107
|
} catch (error) {
|
|
56
108
|
console.log(error)
|
|
57
109
|
}
|
|
58
110
|
res.statusCode = 200
|
|
59
111
|
res.setHeader('Content-Type', 'application/json; charset=UTF-8')
|
|
112
|
+
res.setHeader('Cache-Control', 'no-store')
|
|
60
113
|
res.end(JSON.stringify(style))
|
|
61
114
|
break
|
|
62
115
|
case '/app.css':
|
|
63
116
|
res.statusCode = 200
|
|
64
117
|
res.setHeader('Content-Type', 'text/css; charset=UTF-8')
|
|
65
|
-
const css = fs.readFileSync(
|
|
118
|
+
const css = fs.readFileSync(
|
|
119
|
+
path.join(defaultProviderDir, 'app.css'),
|
|
120
|
+
'utf-8',
|
|
121
|
+
)
|
|
66
122
|
res.end(css)
|
|
67
123
|
break
|
|
124
|
+
case `/shared.js`:
|
|
125
|
+
res.statusCode = 200
|
|
126
|
+
res.setHeader('Content-Type', 'application/javascript; charset=UTF-8')
|
|
127
|
+
const shared = fs.readFileSync(
|
|
128
|
+
path.join(defaultProviderDir, 'shared.js'),
|
|
129
|
+
'utf-8',
|
|
130
|
+
)
|
|
131
|
+
const js = shared.replace('___PORT___', `${port}`)
|
|
132
|
+
res.end(js)
|
|
133
|
+
break
|
|
68
134
|
case `/app.js`:
|
|
69
135
|
res.statusCode = 200
|
|
70
136
|
res.setHeader('Content-Type', 'application/javascript; charset=UTF-8')
|
|
71
137
|
try {
|
|
72
|
-
const app = fs.readFileSync(path.join(
|
|
138
|
+
const app = fs.readFileSync(path.join(providerDir, 'app.js'), 'utf-8')
|
|
73
139
|
const js = app
|
|
74
140
|
.replace('___PORT___', `${port}`)
|
|
75
141
|
.replace(
|
|
@@ -93,30 +159,56 @@ export function serve(source: string, options: serveOptions) {
|
|
|
93
159
|
console.log(`Provider: ${provider}`)
|
|
94
160
|
console.log(`Loading your style: ${sourcePath}`)
|
|
95
161
|
console.log(`Your map is running on http://localhost:${port}/\n`)
|
|
96
|
-
open
|
|
162
|
+
if (options.open) {
|
|
163
|
+
open(`http://localhost:${port}`)
|
|
164
|
+
}
|
|
97
165
|
})
|
|
98
166
|
|
|
99
167
|
const wss = new WebSocketServer({ server })
|
|
100
168
|
|
|
101
169
|
wss.on('connection', (ws) => {
|
|
102
|
-
watch(
|
|
170
|
+
const watcher = watch(
|
|
103
171
|
path.dirname(sourcePath),
|
|
104
|
-
{ recursive: true, filter: /\.yml$/ },
|
|
172
|
+
{ recursive: true, filter: /\.yml$|\.svg$/i },
|
|
105
173
|
(event, file) => {
|
|
106
174
|
console.log(`${(event || '').toUpperCase()}: ${file}`)
|
|
107
175
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
176
|
+
if (file?.toLowerCase().endsWith('.yml')) {
|
|
177
|
+
ws.send(
|
|
178
|
+
JSON.stringify({
|
|
179
|
+
event: 'styleUpdate',
|
|
180
|
+
}),
|
|
181
|
+
)
|
|
182
|
+
} else if (
|
|
183
|
+
file?.toLowerCase().endsWith('.svg') &&
|
|
184
|
+
typeof spriteRefresher !== 'undefined'
|
|
185
|
+
) {
|
|
186
|
+
spriteRefresher().then(() => {
|
|
187
|
+
ws.send(
|
|
188
|
+
JSON.stringify({
|
|
189
|
+
event: 'spriteUpdate',
|
|
190
|
+
}),
|
|
191
|
+
)
|
|
192
|
+
})
|
|
113
193
|
}
|
|
114
|
-
ws.send(JSON.stringify(style))
|
|
115
194
|
} catch (e) {
|
|
116
195
|
// Nothing to do
|
|
117
196
|
}
|
|
118
197
|
},
|
|
119
198
|
)
|
|
199
|
+
ws.on('close', () => {
|
|
200
|
+
watcher.close()
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
process.on('SIGINT', () => {
|
|
205
|
+
console.log('Cleaning up...')
|
|
206
|
+
server.close()
|
|
207
|
+
if (typeof spriteOut !== 'undefined') {
|
|
208
|
+
fs.rmSync(spriteOut, { recursive: true })
|
|
209
|
+
spriteOut = undefined
|
|
210
|
+
}
|
|
211
|
+
process.exit(0)
|
|
120
212
|
})
|
|
121
213
|
|
|
122
214
|
return server
|
package/src/lib/build-sprite.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { generateSprite } from '@unvt/sprite-one'
|
|
2
|
-
|
|
2
|
+
import path from 'path'
|
|
3
3
|
|
|
4
4
|
export async function buildSprite(
|
|
5
5
|
svgPath: string,
|
|
@@ -8,10 +8,6 @@ export async function buildSprite(
|
|
|
8
8
|
): Promise<void> {
|
|
9
9
|
const pxRatios = [1, 2]
|
|
10
10
|
const outPath = path.join(publicPath, iconSlug)
|
|
11
|
-
|
|
12
|
-
await generateSprite(outPath, [svgPath], pxRatios)
|
|
13
|
-
} catch (error) {
|
|
14
|
-
throw error
|
|
15
|
-
}
|
|
11
|
+
await generateSprite(outPath, [svgPath], pxRatios)
|
|
16
12
|
return
|
|
17
13
|
}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
SourceSpecification,
|
|
5
5
|
LayerSpecification,
|
|
6
6
|
VectorSourceSpecification,
|
|
7
|
-
} from '@maplibre/maplibre-gl-style-spec
|
|
7
|
+
} from '@maplibre/maplibre-gl-style-spec'
|
|
8
8
|
|
|
9
9
|
export type TileInfoJSONResponse = {
|
|
10
10
|
sources: { [key: string]: SourceSpecification | VectorSourceSpecification }
|
|
@@ -3,7 +3,7 @@ import { MetadataJSON, VectorLayer } from '../../types'
|
|
|
3
3
|
import {
|
|
4
4
|
LayerSpecification,
|
|
5
5
|
VectorSourceSpecification,
|
|
6
|
-
} from '@maplibre/maplibre-gl-style-spec
|
|
6
|
+
} from '@maplibre/maplibre-gl-style-spec'
|
|
7
7
|
import { BaseImporter, TileInfoJSONResponse } from './base-importer'
|
|
8
8
|
|
|
9
9
|
export class MetadataJSONImporter extends BaseImporter {
|
|
@@ -3,7 +3,7 @@ import { TileJSON } from '../../types'
|
|
|
3
3
|
import {
|
|
4
4
|
SourceSpecification,
|
|
5
5
|
LayerSpecification,
|
|
6
|
-
} from '@maplibre/maplibre-gl-style-spec
|
|
6
|
+
} from '@maplibre/maplibre-gl-style-spec'
|
|
7
7
|
import { BaseImporter, TileInfoJSONResponse } from './base-importer'
|
|
8
8
|
|
|
9
9
|
export class TileJSONImporter extends BaseImporter {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const maplibreStyleSpec = require('@maplibre/maplibre-gl-style-spec')
|
|
2
2
|
const mapboxStyleSpec = require('@mapbox/mapbox-gl-style-spec')
|
|
3
|
-
import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec
|
|
3
|
+
import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec'
|
|
4
4
|
|
|
5
5
|
export function validateStyle(
|
|
6
6
|
style: StyleSpecification,
|
package/src/lib/yaml-parser.ts
CHANGED
package/src/lib/yaml-writer.ts
CHANGED
|
@@ -4,7 +4,7 @@ import YAML from 'js-yaml'
|
|
|
4
4
|
import {
|
|
5
5
|
StyleSpecification,
|
|
6
6
|
LayerSpecification,
|
|
7
|
-
} from '@maplibre/maplibre-gl-style-spec
|
|
7
|
+
} from '@maplibre/maplibre-gl-style-spec'
|
|
8
8
|
|
|
9
9
|
export const writeYaml = (
|
|
10
10
|
destinationPath: string,
|
|
@@ -30,13 +30,26 @@ const writeCompositedYaml = (
|
|
|
30
30
|
stylePath = destinationPath
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
fs.writeFileSync(stylePath, styleYAML)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class IncFileTag {
|
|
37
|
+
value: string
|
|
38
|
+
constructor(fileName: string) {
|
|
39
|
+
// We use path.posix.join to make sure the path uses / path separators, even when run on Windows.
|
|
40
|
+
this.value = path.posix.join('layers', fileName)
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
43
|
|
|
44
|
+
const INC_PATH_TYPE = new YAML.Type('tag:yaml.org,2002:inc/file', {
|
|
45
|
+
kind: 'scalar',
|
|
46
|
+
resolve: (data) => data,
|
|
47
|
+
construct: (data) => new IncFileTag(data),
|
|
48
|
+
instanceOf: IncFileTag,
|
|
49
|
+
represent: (tag) => (tag as IncFileTag).value,
|
|
50
|
+
})
|
|
51
|
+
const INC_PATH_OUTPUT_SCHEMA = YAML.DEFAULT_SCHEMA.extend([INC_PATH_TYPE])
|
|
52
|
+
|
|
40
53
|
const writeDecompositedYaml = (
|
|
41
54
|
destinationPath: string,
|
|
42
55
|
style: StyleSpecification,
|
|
@@ -47,22 +60,22 @@ const writeDecompositedYaml = (
|
|
|
47
60
|
const layer = style.layers[i]
|
|
48
61
|
const layerYml = YAML.dump(layer)
|
|
49
62
|
const fileName = `${style.layers[i].id}.yml`
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
fs.
|
|
63
|
+
const layersDirName = path.join(path.dirname(destinationPath), 'layers')
|
|
64
|
+
const filePath = path.join(layersDirName, fileName)
|
|
65
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true })
|
|
66
|
+
fs.writeFileSync(filePath, layerYml)
|
|
67
|
+
|
|
68
|
+
// ts-ignore is required here because the !!inc/file object is not compatible with the Layer object type.
|
|
53
69
|
// @ts-ignore
|
|
54
|
-
layers.push(
|
|
70
|
+
layers.push(new IncFileTag(fileName))
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
style.layers = layers
|
|
58
74
|
|
|
59
75
|
fs.writeFileSync(
|
|
60
76
|
destinationPath,
|
|
61
|
-
YAML.dump(style
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return match.replace(/'/g, '')
|
|
65
|
-
},
|
|
66
|
-
),
|
|
77
|
+
YAML.dump(style, {
|
|
78
|
+
schema: INC_PATH_OUTPUT_SCHEMA,
|
|
79
|
+
}),
|
|
67
80
|
)
|
|
68
81
|
}
|
package/test/build.spec.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import chai from 'chai'
|
|
2
|
+
import chaiAsPromised from 'chai-as-promised'
|
|
2
3
|
import path from 'path'
|
|
3
4
|
import fs from 'fs'
|
|
4
5
|
import os from 'os'
|
|
@@ -6,6 +7,10 @@ import os from 'os'
|
|
|
6
7
|
import { build, buildWatch } from '../src/commands/build'
|
|
7
8
|
import { defaultValues } from '../src/lib/defaultValues'
|
|
8
9
|
|
|
10
|
+
chai.use(chaiAsPromised)
|
|
11
|
+
chai.should()
|
|
12
|
+
const assert = chai.assert
|
|
13
|
+
|
|
9
14
|
describe('Test for the `build.ts`.', () => {
|
|
10
15
|
const styleYaml = path.join(__dirname, 'data/style.yml')
|
|
11
16
|
const iconSource = path.join(__dirname, 'data/icons')
|
|
@@ -38,7 +43,12 @@ describe('Test for the `build.ts`.', () => {
|
|
|
38
43
|
|
|
39
44
|
// The file should exists.
|
|
40
45
|
assert.deepEqual(true, !!fs.statSync(styleJson))
|
|
41
|
-
|
|
46
|
+
|
|
47
|
+
const fixtureStyleJson = path.join(__dirname, 'data/style.json')
|
|
48
|
+
assert.equal(
|
|
49
|
+
fs.readFileSync(styleJson, 'utf-8').replace(/\r\n/gm, '\n'),
|
|
50
|
+
fs.readFileSync(fixtureStyleJson, 'utf-8').replace(/\r\n/gm, '\n'),
|
|
51
|
+
)
|
|
42
52
|
})
|
|
43
53
|
|
|
44
54
|
it('Should minify `data/style.yml` to JSON.', async () => {
|
|
@@ -101,18 +111,18 @@ describe('Test for the `build.ts`.', () => {
|
|
|
101
111
|
})
|
|
102
112
|
})
|
|
103
113
|
|
|
104
|
-
it('Should not create sprite when input directory is not exist.',
|
|
114
|
+
it('Should not create sprite when input directory is not exist.', () => {
|
|
105
115
|
const noExistInputDir = path.join(__dirname, 'data/hellooooo')
|
|
106
116
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
const promise = build(styleYaml, styleJson, {
|
|
118
|
+
provider: defaultValues.provider,
|
|
119
|
+
spriteInput: noExistInputDir,
|
|
120
|
+
spriteOutput: tmpdir,
|
|
121
|
+
})
|
|
122
|
+
return assert.isRejected(
|
|
123
|
+
promise,
|
|
124
|
+
/No such directory. Please specify valid icon input directory. For more help run charites build --help/,
|
|
125
|
+
)
|
|
116
126
|
})
|
|
117
127
|
|
|
118
128
|
it('Should watch `*.yml` and convert it to JSON', async () => {
|