jekyll-maplibre 1.0.pre.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rubocop.yml +112 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +280 -0
- data/Rakefile +6 -0
- data/jekyll-maplibre.gemspec +27 -0
- data/lib/jekyll-maplibre/maplibre.html.erb +151 -0
- data/lib/jekyll-maplibre/maplibre_tag.rb +221 -0
- data/lib/jekyll-maplibre/options_parser.rb +49 -0
- data/lib/jekyll-maplibre/version.rb +5 -0
- data/lib/jekyll-maplibre.rb +11 -0
- data/script/bootstrap +3 -0
- data/script/cibuild +4 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ab808189fd4b1d54aab12429599ebf2cef5ef6579e315fb5eeb8e409324d0e7
|
4
|
+
data.tar.gz: 64ee05a010230a5712494c45016fc400f871ad3211d64e576e0df66da780ca55
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b6c0ca7186c6e4fa6c8765faddf510bd38f44677e254431e8e1fe4a7214e8d8e0d9aa2cc5a445edbe8af934109fcd1167448d9aca8c547b994a16288bf3601e2
|
7
|
+
data.tar.gz: 746f400184fd527e050f6bc35c299ff992079b4c1ce10ba6c2a7a49f1ba17931acdbd782724c75ced778fe5113afd2ebc2e2c5620d5852d597ae5177e11e5183
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
---
|
2
|
+
AllCops:
|
3
|
+
TargetRubyVersion: 3.1
|
4
|
+
Include:
|
5
|
+
- lib/**/*.rb
|
6
|
+
# - spec/**/*.rb
|
7
|
+
NewCops: enable
|
8
|
+
SuggestExtensions: false
|
9
|
+
Layout/EndAlignment:
|
10
|
+
Severity: error
|
11
|
+
Lint/UnreachableCode:
|
12
|
+
Severity: error
|
13
|
+
Lint/UselessAccessModifier:
|
14
|
+
Enabled: false
|
15
|
+
Metrics/AbcSize:
|
16
|
+
Max: 20
|
17
|
+
Metrics/BlockLength:
|
18
|
+
Exclude:
|
19
|
+
- spec/**/*.rb
|
20
|
+
Metrics/ClassLength:
|
21
|
+
Max: 300
|
22
|
+
Exclude:
|
23
|
+
- !ruby/regexp /spec\/.*.rb$/
|
24
|
+
Metrics/CyclomaticComplexity:
|
25
|
+
Max: 8
|
26
|
+
Layout/LineLength:
|
27
|
+
Exclude:
|
28
|
+
- Rakefile
|
29
|
+
- Gemfile
|
30
|
+
- jekyll-maps.gemspec
|
31
|
+
Max: 90
|
32
|
+
Severity: warning
|
33
|
+
Metrics/MethodLength:
|
34
|
+
Max: 20
|
35
|
+
CountComments: false
|
36
|
+
Severity: error
|
37
|
+
Metrics/ModuleLength:
|
38
|
+
Max: 240
|
39
|
+
Metrics/ParameterLists:
|
40
|
+
Max: 4
|
41
|
+
Metrics/PerceivedComplexity:
|
42
|
+
Max: 8
|
43
|
+
Style/Alias:
|
44
|
+
Enabled: false
|
45
|
+
Style/AndOr:
|
46
|
+
Severity: error
|
47
|
+
Style/Attr:
|
48
|
+
Enabled: false
|
49
|
+
Style/ClassAndModuleChildren:
|
50
|
+
Enabled: false
|
51
|
+
Style/Documentation:
|
52
|
+
Enabled: false
|
53
|
+
Style/DoubleNegation:
|
54
|
+
Enabled: false
|
55
|
+
Layout/EmptyLinesAroundAccessModifier:
|
56
|
+
Enabled: false
|
57
|
+
Layout/EmptyLinesAroundModuleBody:
|
58
|
+
Enabled: false
|
59
|
+
Layout/ExtraSpacing:
|
60
|
+
AllowForAlignment: true
|
61
|
+
Naming/FileName:
|
62
|
+
Enabled: false
|
63
|
+
Layout/FirstParameterIndentation:
|
64
|
+
EnforcedStyle: consistent
|
65
|
+
Style/GuardClause:
|
66
|
+
Enabled: false
|
67
|
+
Style/HashSyntax:
|
68
|
+
EnforcedStyle: hash_rockets
|
69
|
+
Severity: error
|
70
|
+
Style/IfUnlessModifier:
|
71
|
+
Enabled: false
|
72
|
+
Layout/IndentationWidth:
|
73
|
+
Severity: error
|
74
|
+
Style/ModuleFunction:
|
75
|
+
Enabled: false
|
76
|
+
Layout/MultilineMethodCallIndentation:
|
77
|
+
EnforcedStyle: indented
|
78
|
+
Layout/MultilineOperationIndentation:
|
79
|
+
EnforcedStyle: indented
|
80
|
+
Style/MultilineTernaryOperator:
|
81
|
+
Severity: error
|
82
|
+
Style/PercentLiteralDelimiters:
|
83
|
+
PreferredDelimiters:
|
84
|
+
"%q": "{}"
|
85
|
+
"%Q": "{}"
|
86
|
+
"%r": "!!"
|
87
|
+
"%s": "()"
|
88
|
+
"%w": "()"
|
89
|
+
"%W": "()"
|
90
|
+
"%x": "()"
|
91
|
+
Style/RedundantReturn:
|
92
|
+
Enabled: false
|
93
|
+
Style/RedundantSelf:
|
94
|
+
Enabled: false
|
95
|
+
Style/RegexpLiteral:
|
96
|
+
EnforcedStyle: percent_r
|
97
|
+
Style/RescueModifier:
|
98
|
+
Enabled: false
|
99
|
+
Style/SignalException:
|
100
|
+
EnforcedStyle: only_raise
|
101
|
+
Style/SingleLineMethods:
|
102
|
+
Enabled: false
|
103
|
+
Layout/SpaceAroundOperators:
|
104
|
+
Enabled: false
|
105
|
+
Style/StringLiterals:
|
106
|
+
EnforcedStyle: double_quotes
|
107
|
+
Style/StringLiteralsInInterpolation:
|
108
|
+
EnforcedStyle: double_quotes
|
109
|
+
Style/RedundantCapitalW:
|
110
|
+
Enabled: false
|
111
|
+
Style/SymbolArray:
|
112
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
## 1.0.0-alpha.1
|
2
|
+
|
3
|
+
* fork jekyll-maps to create jekyll-maplibre
|
4
|
+
* remove all code related to Google Maps and use MapLibre GL JS (<https://maplibre.org/maplibre-gl-js/docs/>) instead
|
5
|
+
* flexible configuration of sources, layers, styles through page metadata and site config
|
6
|
+
* update README.md
|
7
|
+
* prepare minimal example
|
8
|
+
* prepare a folder with useful assets
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
Copyright (c) 2016 Anatoliy Yastreb
|
3
|
+
Copyright (c) 2023 Robert Riemann (<robert@riemann.cc>)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
# Jekyll MapLibre
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/jekyll-maplibre.svg)](https://badge.fury.io/rb/jekyll-maplibre)
|
4
|
+
|
5
|
+
Jekyll MapLibre is a Jekyll plugin that allows to easily display maps with [MapLibre GL JS](https://maplibre.org/). It is a fork of [Jekyll Maps](https://github.com/ayastreb/jekyll-maps) that uses Google Maps.
|
6
|
+
|
7
|
+
MapLibre GL JS is open source software and allows for self-hosted maps. Self-hosting become much easier with [PMTiles](https://docs.protomaps.com/pmtiles/), which is a single-file archive format for pyramids of tiled data that can be hosted on Github, Gitlab, Netlify, etc. and enables low-cost, zero-maintenance map applications.
|
8
|
+
|
9
|
+
Check out a Jekyll MapLibre [demo at blog.riemann.cc](https://blog.riemann.cc/projects/jekyll-maplibre)!
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
1. Add the following to your site's `Gemfile`:
|
14
|
+
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'jekyll-maplibre'
|
18
|
+
```
|
19
|
+
|
20
|
+
2. Add the following to your site's `_config.yml`:
|
21
|
+
|
22
|
+
|
23
|
+
```yml
|
24
|
+
plugins:
|
25
|
+
- jekyll-maplibre
|
26
|
+
```
|
27
|
+
|
28
|
+
3. Also prepare configuration specific for `jekyll-maplibre` in your site's `_config.yml`:
|
29
|
+
|
30
|
+
```
|
31
|
+
maplibre:
|
32
|
+
width: 600
|
33
|
+
height: 400
|
34
|
+
zoom: 10
|
35
|
+
pmtiles: true
|
36
|
+
style: false
|
37
|
+
# if style is not set to an URL (Mapbox, MapTiler, OpenMapTiles), the following values are used
|
38
|
+
sprite: /assets/maps/osm-liberty-sprites/osm-liberty
|
39
|
+
glyphs: /assets/maps/fonts/{fontstack}/{range}.pbf
|
40
|
+
layers: /assets/maps/OSM-Liberty-layers.json
|
41
|
+
sources:
|
42
|
+
openmaptiles:
|
43
|
+
type: vector
|
44
|
+
url: pmtiles:///assets/maps/maptiler-osm-2020-02-10-v3.11-belgium_brussels.pmtiles
|
45
|
+
attribution: © <a href='https://openstreetmap.org'>OpenStreetMap contributors</a>
|
46
|
+
natural_earth_shaded_relief:
|
47
|
+
attribution: Made with <a href='https://www.naturalearthdata.com/'>Natural Earth</a> data
|
48
|
+
maxzoom: 6
|
49
|
+
type: raster
|
50
|
+
url: pmtiles:///assets/maps/natural_earth_2_shaded_relief.raster.pmtiles
|
51
|
+
# uncomment tileSize and tiles for cloud CDN tiles
|
52
|
+
# tileSize: 256
|
53
|
+
# tiles:
|
54
|
+
# - "https://klokantech.github.io/naturalearthtiles/tiles/natural_earth_2_shaded_relief.raster/{z}/{x}/{y}.png"
|
55
|
+
```
|
56
|
+
|
57
|
+
4. Prepare assets to display maps with MapLibre GL JS:
|
58
|
+
|
59
|
+
The required assets depend on your specific map configuration. With cloud hosting (untested), it may be sufficient to only configure the `style` property above.
|
60
|
+
|
61
|
+
For self-hosted maps, you need to host and configure the following resources:
|
62
|
+
|
63
|
+
- **The source.** PMTiles covering the map area you need. Use `pmtiles convert input.mbtiles output.pmtiles` to convert your mbtiles from e.g. <https://data.maptiler.com/downloads/planet/>. More on `pmtiles` and extraction of custom areas at <https://docs.protomaps.com/guide/getting-started>.
|
64
|
+
- **The glyphs.** Font files in pbf format when using vector sources. Check out <https://github.com/openmaptiles/fonts/releases>.
|
65
|
+
- **The sprite.** Icons used when using vector sources.
|
66
|
+
- **The layers.** A map requires at least one layer. Layers describe how to render source data and rely on glyphs and sprite. The layer definition for vector data depends on the schema used to encode the data in the vector source.
|
67
|
+
- **The Mapbox Style file.** It links all assets together.
|
68
|
+
|
69
|
+
For an easy start `jekyll-maplibre` suggests to use PMTiles raster files and vector files following the *OpenMapTiles Vector Tile Schema*, so that the layers from [OSM-Liberty](https://maputnik.github.io/osm-liberty/) can be used. Find a demo of OSM Liberty [here](https://maputnik.github.io/editor/?style=https://maputnik.github.io/osm-liberty/style.json).
|
70
|
+
|
71
|
+
Example assets folder:
|
72
|
+
|
73
|
+
```
|
74
|
+
assets
|
75
|
+
└── maps
|
76
|
+
├── fonts
|
77
|
+
│ ├── Roboto Condensed Italic
|
78
|
+
│ │ ├── 0-255.pbf
|
79
|
+
│ │ ├── […]
|
80
|
+
│ │ └── 9984-10239.pbf
|
81
|
+
│ ├── Roboto Medium
|
82
|
+
│ │ ├── 0-255.pbf
|
83
|
+
│ │ ├── […]
|
84
|
+
│ │ └── 9984-10239.pbf
|
85
|
+
│ └── Roboto Regular
|
86
|
+
│ ├── 0-255.pbf
|
87
|
+
│ ├── […]
|
88
|
+
│ └── 9984-10239.pbf
|
89
|
+
├── maplibre-gl.css
|
90
|
+
├── maplibre-gl.js
|
91
|
+
├── maptiler-osm-2020-02-10-v3.11-belgium_brussels.pmtiles
|
92
|
+
├── natural_earth_2_shaded_relief.raster.pmtiles
|
93
|
+
├── natural_earth.vector.pmtiles
|
94
|
+
├── OSM-Liberty-layers.json
|
95
|
+
├── osm-liberty-sprites
|
96
|
+
│ ├── osm-liberty@2x.json
|
97
|
+
│ ├── osm-liberty@2x.png
|
98
|
+
│ ├── osm-liberty.json
|
99
|
+
│ └── osm-liberty.png
|
100
|
+
└── pmtiles.js
|
101
|
+
|
102
|
+
```
|
103
|
+
|
104
|
+
Example assets sources:
|
105
|
+
|
106
|
+
- [pmtiles.js](https://unpkg.com/pmtiles@2.11.0/dist/index.js)
|
107
|
+
- [osm-liberty-sprites](https://github.com/maputnik/osm-liberty/tree/gh-pages/sprites)
|
108
|
+
- [fonts](https://github.com/maputnik/osm-liberty/tree/gh-pages/sprites) (the v2.0 zip)
|
109
|
+
- [maplibre-gl.js](https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.js)
|
110
|
+
- [maplibre-gl.css](https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.css)
|
111
|
+
- [OSM-Liberty-layers.json extracted from OSM Liberty style.json](https://github.com/maputnik/osm-liberty/blob/f2c798e80dc11d47613e3b093881b4d37a5fde8e/style.json)
|
112
|
+
|
113
|
+
5. Load MapLibre GL JS CSS in `<head>`
|
114
|
+
|
115
|
+
The file `maplibre-gl.css` should be linked in your `<head>` or included in another css file.
|
116
|
+
|
117
|
+
Many Jeyll templates provide for a file `_includes/my-head.html` or `_includes/custom-head.html` (check the docs). If so, add a line such as `<link href="/assets/maps/maplibre-gl.css" rel="stylesheet">`.
|
118
|
+
|
119
|
+
## Usage
|
120
|
+
|
121
|
+
### MapLibre Tag
|
122
|
+
|
123
|
+
```
|
124
|
+
{% maplibre %}
|
125
|
+
```
|
126
|
+
|
127
|
+
The following optional attributes are supported:
|
128
|
+
|
129
|
+
- id
|
130
|
+
- width
|
131
|
+
- height
|
132
|
+
- class
|
133
|
+
- style
|
134
|
+
- zoom
|
135
|
+
- center
|
136
|
+
- description
|
137
|
+
- latitude
|
138
|
+
- longitude
|
139
|
+
|
140
|
+
The flag `no_cluster` can be used to disable clustering of points.
|
141
|
+
|
142
|
+
Example with all attributes and flags:
|
143
|
+
|
144
|
+
```
|
145
|
+
{% maplibre id="custom-id" width="100%" height="200" class="custom-class" style="clear: both;" zoom="10" center="4.300,50.800" description="<a href='#'>Popup Link</a>" longitude="4.300" latitude="50.800" no_cluster %}
|
146
|
+
```
|
147
|
+
|
148
|
+
### Data Source
|
149
|
+
|
150
|
+
Jekyll MapLibre offers several ways to add markers to the map. While in principle MapLibre GL JS allows to add all kinds of data other than markers to the map, more configuration must be added to the style definition.
|
151
|
+
|
152
|
+
#### Location data in the tag attributes
|
153
|
+
|
154
|
+
Example:
|
155
|
+
|
156
|
+
```
|
157
|
+
{% maplibre longitude="4.300" latitude="50.800" %}
|
158
|
+
```
|
159
|
+
|
160
|
+
#### Location data in the YAML frontmatter
|
161
|
+
|
162
|
+
```yml
|
163
|
+
location:
|
164
|
+
latitude: 50.800
|
165
|
+
longitude: 4.300
|
166
|
+
```
|
167
|
+
|
168
|
+
#### GeoJSON data in the YAML frontmatter
|
169
|
+
|
170
|
+
The `geojson` attribute in the YAML frontmatter supports (a) individual GeoJSON features or (b) collections of features.
|
171
|
+
|
172
|
+
Individual feature:
|
173
|
+
|
174
|
+
```
|
175
|
+
geojson:
|
176
|
+
type: Feature
|
177
|
+
properties:
|
178
|
+
description: |
|
179
|
+
<strong>A Little Night Music</strong><p>The Arlington Players' production of Stephen Sondheim's <em>A Little Night Music</em> comes to the Kogod Cradle at The Mead Center for American Theater (1101 6th Street SW) this weekend and next. 8:00 p.m.</p>
|
180
|
+
geometry:
|
181
|
+
type: Point
|
182
|
+
coordinates: [4.300, 50.800]
|
183
|
+
```
|
184
|
+
|
185
|
+
Collection of features:
|
186
|
+
|
187
|
+
```
|
188
|
+
geojson:
|
189
|
+
type: FeatureCollection
|
190
|
+
features:
|
191
|
+
-
|
192
|
+
type: Feature
|
193
|
+
properties:
|
194
|
+
description: "<strong>A Little Night Music</strong><p>The Arlington Players' production of Stephen Sondheim's <em>A Little Night Music</em> comes to the Kogod Cradle at The Mead Center for American Theater (1101 6th Street SW) this weekend and next. 8:00 p.m.</p>\n"
|
195
|
+
geometry:
|
196
|
+
type: Point
|
197
|
+
coordinates: [4.376, - 50.83012]
|
198
|
+
-
|
199
|
+
type: Feature
|
200
|
+
...
|
201
|
+
```
|
202
|
+
|
203
|
+
#### GeoJSON data in a JSON file
|
204
|
+
|
205
|
+
The `geojson` attribute in the YAML frontmatter can also contain a URL with `.json` extension.
|
206
|
+
|
207
|
+
Example:
|
208
|
+
|
209
|
+
```
|
210
|
+
geojson: /post-locations.json`
|
211
|
+
```
|
212
|
+
|
213
|
+
The linked file can be a static file on the same host or another server. If the data source points to a generated file capturing the `location` attribute of posts, Jekyll MapLibre can display maps with post markers.
|
214
|
+
|
215
|
+
Example for `/post-locations.json`:
|
216
|
+
|
217
|
+
```
|
218
|
+
{% assign posts = site.posts | where_exp:"location", "location != nil" %}
|
219
|
+
{
|
220
|
+
"type": "FeatureCollection",
|
221
|
+
"features": [
|
222
|
+
{% for post in posts limit:20 %}
|
223
|
+
{
|
224
|
+
"type": "Feature",
|
225
|
+
"properties": {
|
226
|
+
"description": "<b><a href='{{post.url}}'>{{post.title}}</a></b><br/>{{post.description}}<br/>"
|
227
|
+
},
|
228
|
+
"geometry": {
|
229
|
+
"type": "Point",
|
230
|
+
"coordinates": {{post.location | jsonify }}
|
231
|
+
}
|
232
|
+
}{% unless forloop.last %},{% endif %}
|
233
|
+
{% endfor %}
|
234
|
+
]
|
235
|
+
}
|
236
|
+
```
|
237
|
+
|
238
|
+
With `where` and `where_exp` (see [documentation](https://jekyllrb.com/docs/liquid/filters/)), Jekyll permits to implement various filters.
|
239
|
+
|
240
|
+
### Marker Cluster
|
241
|
+
|
242
|
+
Clusters are enabled by default. Use the flag `no_cluster` in the tag to disable clusters.
|
243
|
+
|
244
|
+
## Examples
|
245
|
+
|
246
|
+
Want to see Jekyll MapLibre in action? Check out [Demo Page](https://ayastreb.me/jekyll-maps/#examples)!
|
247
|
+
|
248
|
+
## Contributing
|
249
|
+
|
250
|
+
1. Fork it (https://github.com/rriemann/jekyll-maplibre/fork)
|
251
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
252
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
253
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
254
|
+
5. Create a new Pull Request
|
255
|
+
|
256
|
+
## TODOs
|
257
|
+
|
258
|
+
The following issues and limitation require contribution:
|
259
|
+
|
260
|
+
- implement random SVG markers, see: <https://github.com/maplibre/maplibre-gl-js/discussions/3243>, <https://github.com/rbrundritt/maplibre-gl-svg/>
|
261
|
+
- implement more than one map tag per page
|
262
|
+
- add more examples on how to generate geojson data from Jekyll collections/data.
|
263
|
+
- Jekyll-Maps has spec tests (still in this repo) – make them work again with Jekyll MapLibre
|
264
|
+
- add flag to switch popups to open by default (without click to open)
|
265
|
+
|
266
|
+
## Similar Software
|
267
|
+
|
268
|
+
- <https://github.com/ayastreb/jekyll-maps/>
|
269
|
+
- <https://github.com/matthewowen/jekyll-mapping>
|
270
|
+
- <https://wiki.openstreetmap.org/wiki/UMap>
|
271
|
+
|
272
|
+
## Contributors
|
273
|
+
|
274
|
+
- Anatoliy Yastreb (as the author of the forked Jekyll Maps gem)
|
275
|
+
- Robert Riemann
|
276
|
+
|
277
|
+
## License
|
278
|
+
|
279
|
+
[MIT](https://github.com/rriemann/jekyll-maplibre/blob/master/LICENSE). Feel free to use, copy or
|
280
|
+
distribute it.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require "jekyll-maplibre/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jekyll-maplibre"
|
8
|
+
spec.summary = "Maplibre GL JS for Jekyll"
|
9
|
+
spec.description = "MapLibre GL JS support for Jekyll websites to easily display vector maps with geojson data"
|
10
|
+
spec.version = Jekyll::MapLibre::VERSION
|
11
|
+
spec.authors = ["Anatoliy Yastreb, Robert Riemann"]
|
12
|
+
spec.email = ["robert@riemann.cc"]
|
13
|
+
|
14
|
+
spec.homepage = "https://blog.riemann.cc/projects/jekyll-maplibre"
|
15
|
+
spec.licenses = ["MIT"]
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|spec|features)/!) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.required_ruby_version = '>= 3.1.0'
|
20
|
+
|
21
|
+
spec.add_dependency "jekyll", ">= 3.0", "< 5.0"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler"
|
24
|
+
spec.add_development_dependency "rake", "~> 13.1"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.5"
|
26
|
+
spec.add_development_dependency "rubocop", "1.50.2"
|
27
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
<script src="/assets/maps/maplibre-gl.js"></script>
|
2
|
+
<% if context.registers[:site].config.dig("maplibre","pmtiles") %>
|
3
|
+
<script src="/assets/maps/pmtiles.js"></script>
|
4
|
+
<script type="text/javascript">
|
5
|
+
// add the PMTiles plugin to the maplibregl global.
|
6
|
+
let protocol = new pmtiles.Protocol();
|
7
|
+
maplibregl.addProtocol("pmtiles",protocol.tile);
|
8
|
+
</script>
|
9
|
+
<% end %>
|
10
|
+
<div <%= attributes(context) %>></div>
|
11
|
+
|
12
|
+
<script type="text/javascript">
|
13
|
+
(async () => {
|
14
|
+
const map = new maplibregl.Map({
|
15
|
+
container: '<%= @options[:attributes][:id] %>',
|
16
|
+
zoom: <%= zoom %>,
|
17
|
+
center: <%= center(context).to_json %>,
|
18
|
+
style: <%= style(context) %>,
|
19
|
+
});
|
20
|
+
// map.showTileBoundaries = true;
|
21
|
+
|
22
|
+
// Add zoom and rotation controls to the map.
|
23
|
+
map.addControl(new maplibregl.NavigationControl());
|
24
|
+
|
25
|
+
<% if geojson(context) %>
|
26
|
+
map.on('load', () => {
|
27
|
+
// Add a new source from our GeoJSON data and
|
28
|
+
// set the 'cluster' option to true. GL-JS will
|
29
|
+
// add the point_count property to your source data.
|
30
|
+
map.addSource('jekyll-data', {
|
31
|
+
type: 'geojson',
|
32
|
+
data: <%= geojson(context).to_json %>,
|
33
|
+
cluster: <%= (!@options[:flags][:no_cluster]).to_s %>,
|
34
|
+
clusterMaxZoom: 14, // Max zoom to cluster points on
|
35
|
+
clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
|
36
|
+
});
|
37
|
+
|
38
|
+
map.addLayer({
|
39
|
+
id: 'clusters',
|
40
|
+
type: 'circle',
|
41
|
+
source: 'jekyll-data',
|
42
|
+
filter: ['has', 'point_count'],
|
43
|
+
paint: {
|
44
|
+
// Use step expressions (https://maplibre.org/maplibre-style-spec/#expressions-step)
|
45
|
+
// with three steps to implement three types of circles:
|
46
|
+
// * Blue, 20px circles when point count is less than 100
|
47
|
+
// * Yellow, 30px circles when point count is between 100 and 750
|
48
|
+
// * Pink, 40px circles when point count is greater than or equal to 750
|
49
|
+
'circle-color': [
|
50
|
+
'step',
|
51
|
+
['get', 'point_count'],
|
52
|
+
'#51bbd6',
|
53
|
+
100,
|
54
|
+
'#f1f075',
|
55
|
+
750,
|
56
|
+
'#f28cb1'
|
57
|
+
],
|
58
|
+
'circle-radius': [
|
59
|
+
'step',
|
60
|
+
['get', 'point_count'],
|
61
|
+
20,
|
62
|
+
100,
|
63
|
+
30,
|
64
|
+
750,
|
65
|
+
40
|
66
|
+
]
|
67
|
+
}
|
68
|
+
});
|
69
|
+
|
70
|
+
map.addLayer({
|
71
|
+
id: 'cluster-count',
|
72
|
+
type: 'symbol',
|
73
|
+
source: 'jekyll-data',
|
74
|
+
filter: ['has', 'point_count'],
|
75
|
+
layout: {
|
76
|
+
'text-field': '{point_count_abbreviated}',
|
77
|
+
'text-font': ['Roboto Regular'],
|
78
|
+
'text-size': 12
|
79
|
+
}
|
80
|
+
});
|
81
|
+
|
82
|
+
map.addLayer({
|
83
|
+
id: 'unclustered-point',
|
84
|
+
type: 'symbol',
|
85
|
+
source: 'jekyll-data',
|
86
|
+
filter: ['!', ['has', 'point_count']],
|
87
|
+
layout: {
|
88
|
+
"icon-image": "marker",
|
89
|
+
"icon-size": 2,
|
90
|
+
"icon-anchor": "bottom",
|
91
|
+
}
|
92
|
+
});
|
93
|
+
|
94
|
+
// inspect a cluster on click
|
95
|
+
map.on('click', 'clusters', (e) => {
|
96
|
+
const features = map.queryRenderedFeatures(e.point, {
|
97
|
+
layers: ['clusters']
|
98
|
+
});
|
99
|
+
const clusterId = features[0].properties.cluster_id;
|
100
|
+
map.getSource('jekyll-data').getClusterExpansionZoom(
|
101
|
+
clusterId,
|
102
|
+
(err, zoom) => {
|
103
|
+
if (err) return;
|
104
|
+
|
105
|
+
map.easeTo({
|
106
|
+
center: features[0].geometry.coordinates,
|
107
|
+
zoom
|
108
|
+
});
|
109
|
+
}
|
110
|
+
);
|
111
|
+
});
|
112
|
+
|
113
|
+
// When a click event occurs on a feature in
|
114
|
+
// the unclustered-point layer, open a popup at
|
115
|
+
// the location of the feature, with
|
116
|
+
// description HTML from its properties.
|
117
|
+
map.on('click', 'unclustered-point', (e) => {
|
118
|
+
if(!e.features[0].properties.description) return;
|
119
|
+
const coordinates = e.features[0].geometry.coordinates.slice();
|
120
|
+
|
121
|
+
// Ensure that if the map is zoomed out such that
|
122
|
+
// multiple copies of the feature are visible, the
|
123
|
+
// popup appears over the copy being pointed to.
|
124
|
+
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
|
125
|
+
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
|
126
|
+
}
|
127
|
+
|
128
|
+
new maplibregl.Popup({offset: [0, -35]})
|
129
|
+
.setLngLat(coordinates)
|
130
|
+
.setHTML(e.features[0].properties.description)
|
131
|
+
.addTo(map);
|
132
|
+
});
|
133
|
+
|
134
|
+
map.on('mouseenter', 'unclustered-point', () => {
|
135
|
+
if(!e.features[0].properties.description) return;
|
136
|
+
map.getCanvas().style.cursor = 'pointer';
|
137
|
+
});
|
138
|
+
map.on('mouseleave', 'unclustered-point', () => {
|
139
|
+
map.getCanvas().style.cursor = '';
|
140
|
+
});
|
141
|
+
|
142
|
+
map.on('mouseenter', 'clusters', () => {
|
143
|
+
map.getCanvas().style.cursor = 'pointer';
|
144
|
+
});
|
145
|
+
map.on('mouseleave', 'clusters', () => {
|
146
|
+
map.getCanvas().style.cursor = '';
|
147
|
+
});
|
148
|
+
});
|
149
|
+
<% end %>
|
150
|
+
})();
|
151
|
+
</script>
|
@@ -0,0 +1,221 @@
|
|
1
|
+
##
|
2
|
+
# copyright: 2020 Anatoliy Yastreb <anatoliy.yastreb@gmail.com>,
|
3
|
+
# 2023 Robert Riemann <robert@riemann.cc>
|
4
|
+
# license: MIT
|
5
|
+
#
|
6
|
+
# original code from jekyll-maps, https://github.com/ayastreb/jekyll-maps/
|
7
|
+
|
8
|
+
require 'json'
|
9
|
+
require 'erb'
|
10
|
+
|
11
|
+
# taken from Active Support Gem (MIT license)
|
12
|
+
class Hash
|
13
|
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 82
|
14
|
+
def deep_transform_keys(&block)
|
15
|
+
result = {}
|
16
|
+
each do |key, value|
|
17
|
+
result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
|
18
|
+
end
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 128
|
23
|
+
def deep_symbolize_keys
|
24
|
+
deep_transform_keys{ |key| key.to_sym rescue key }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Jekyll
|
29
|
+
module MapLibre
|
30
|
+
|
31
|
+
# @author Robert Riemann <robert@riemann.cc>
|
32
|
+
class MapLibreTag < Liquid::Tag
|
33
|
+
DEFAULT_MAP_WIDTH = 600
|
34
|
+
DEFAULT_MAP_HEIGHT = 400
|
35
|
+
DEFAULT_ZOOM = 10
|
36
|
+
|
37
|
+
def initialize(tag_name, args, tokens)
|
38
|
+
@options = OptionsParser.parse(args)
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [String] HTML code with JS to render map with MapLibre GL
|
43
|
+
def render(context)
|
44
|
+
zoom = @options[:attributes][:zoom] || context.registers[:site].config.dig('maplibre', 'zoom') || DEFAULT_ZOOM
|
45
|
+
|
46
|
+
@options[:attributes][:id] ||= "maplibre-#{SecureRandom.uuid}"
|
47
|
+
|
48
|
+
template = ERB.new File.read(File.expand_path("maplibre.html.erb", __dir__))
|
49
|
+
template.result(binding)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
# @return [String] absolute URL for sprite property pursuant to Mapbox Style Spec
|
54
|
+
def sprite_url(context)
|
55
|
+
# note: unlike glyphs, sprites must be an absolute path with protocol
|
56
|
+
# see: https://github.com/mapbox/mapbox-gl-js/pull/9225
|
57
|
+
sprite_config = context.registers[:site].config["maplibre"]["sprite"]
|
58
|
+
if sprite_config.start_with?('/') then
|
59
|
+
"#{context.registers[:site].config["url"]}#{sprite_config}"
|
60
|
+
else
|
61
|
+
sprite_config
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
# Generates from page metadata and site config
|
67
|
+
# the style object pursuant to the Mapbox Style Spec
|
68
|
+
#
|
69
|
+
# @note The output can include some JS code to load layers asynchronously
|
70
|
+
# and is as such not always valid JSON.
|
71
|
+
# @return [String] style persuant to Mapbox Style Spec
|
72
|
+
def style(context)
|
73
|
+
page_config = context.registers[:page].to_hash
|
74
|
+
site_config = context.registers[:site].config
|
75
|
+
|
76
|
+
if page_config.dig('maplibre', 'style') then
|
77
|
+
page_config.dig('maplibre', 'style').to_json
|
78
|
+
elsif site_config.dig('maplibre', 'style') then
|
79
|
+
site_config.dig('maplibre', 'style').to_json
|
80
|
+
else
|
81
|
+
{
|
82
|
+
version: 8,
|
83
|
+
name: "OSM Liberty",
|
84
|
+
metadata: {
|
85
|
+
"maputnik:license": "https://github.com/maputnik/osm-liberty/blob/gh-pages/LICENSE.md",
|
86
|
+
"maputnik:renderer": "mbgljs",
|
87
|
+
"openmaptiles:version": "3.x"
|
88
|
+
},
|
89
|
+
sources: sources(context),
|
90
|
+
sprite: sprite_url(context),
|
91
|
+
glyphs: context.registers[:site].config["maplibre"]["glyphs"],
|
92
|
+
layers: "__LAYERS__",
|
93
|
+
id: "osm-liberty"
|
94
|
+
}.to_json.sub(%r{"__LAYERS__"}, layers(context)) # assumes that #to_json uses double quotes
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
# Generates from page metadata and site config the sources
|
100
|
+
# for the style object pursuant to the Mapbox Style Spec
|
101
|
+
#
|
102
|
+
# @return [Hash] Mapbox Style sources
|
103
|
+
def sources(context)
|
104
|
+
page_config = context.registers[:page].to_hash
|
105
|
+
site_config = context.registers[:site].config
|
106
|
+
|
107
|
+
if page_config.dig('maplibre', 'sources') then
|
108
|
+
page_config.dig('maplibre', 'sources')
|
109
|
+
elsif site_config.dig('maplibre', 'sources') then
|
110
|
+
site_config.dig('maplibre', 'sources')
|
111
|
+
else
|
112
|
+
raise "No MapLibre source found in site config and page meta data."
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
# Generates from page metadata and site config the layers
|
118
|
+
# for the style object pursuant to the Mapbox Style Spec
|
119
|
+
#
|
120
|
+
# @note The string is either some JS code to load a JSON file asynchronously or directly a JSON Hash.
|
121
|
+
# @return [String] Mapbox Style layers
|
122
|
+
def layers(context)
|
123
|
+
page_config = context.registers[:page].to_hash
|
124
|
+
site_config = context.registers[:site].config
|
125
|
+
|
126
|
+
unless page_config.dig('maplibre', 'layers') or site_config.dig('maplibre', 'layers') then
|
127
|
+
raise "No MapLibre layers found in site config and page meta data."
|
128
|
+
end
|
129
|
+
|
130
|
+
obj = page_config.dig('maplibre', 'layers') || site_config.dig('maplibre', 'layers')
|
131
|
+
if obj&.end_with? '.json' then
|
132
|
+
"await (await fetch('#{obj}')).json()"
|
133
|
+
else
|
134
|
+
obj.to_json
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
# LngLat array from tag options or geojson to center the map
|
140
|
+
#
|
141
|
+
# @return [Array,nil] LngLat array or nil
|
142
|
+
def center(context)
|
143
|
+
@options[:attributes][:center]&.map{|v| v.to_f} || geojson(context).dig(:features, 0, :geometry, :coordinates)
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
# Generates map div attributes
|
148
|
+
#
|
149
|
+
# @return [String]
|
150
|
+
def attributes(context)
|
151
|
+
attr = []
|
152
|
+
attr << "id='#{@options[:attributes][:id]}'"
|
153
|
+
attr << %(class='#{Array(@options[:attributes][:class]).join(" ")}') if @options[:attributes][:class]
|
154
|
+
attr << %(style='#{(Array(@options[:attributes][:style]) + dimensions(context)).join(";")}')
|
155
|
+
attr.join(" ")
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
# Generates map div css with dimensions
|
160
|
+
#
|
161
|
+
# @return [String]
|
162
|
+
def dimensions(context)
|
163
|
+
width = @options[:attributes][:width] || context.registers[:site].config.dig('maplibre', 'width') || DEFAULT_MAP_WIDTH
|
164
|
+
height = @options[:attributes][:height] || context.registers[:site].config.dig('maplibre', 'height') || DEFAULT_MAP_HEIGHT
|
165
|
+
width_unit = width.to_s.include?("%") ? "" : "px"
|
166
|
+
height_unit = height.to_s.include?("%") ? "" : "px"
|
167
|
+
["width:#{width}#{width_unit}", "height:#{height}#{height_unit}"]
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
# Generates GeoJSON Hash from tag attributes or page metadata
|
172
|
+
#
|
173
|
+
# @return [Hash] GeoJSON Hash
|
174
|
+
def geojson(context)
|
175
|
+
@geojson ||= if @options[:attributes][:latitude] and @options[:attributes][:longitude] then
|
176
|
+
{
|
177
|
+
type: "FeatureCollection",
|
178
|
+
features: [{
|
179
|
+
type: "Feature",
|
180
|
+
# properties: {}.select {|key, value| !value.nil? },
|
181
|
+
geometry: {
|
182
|
+
type: "Point",
|
183
|
+
coordinates: [ # first long, that lat
|
184
|
+
@options[:attributes]["longitude"].to_f,
|
185
|
+
@options[:attributes]["latitude"].to_f,
|
186
|
+
]
|
187
|
+
}
|
188
|
+
}],
|
189
|
+
}
|
190
|
+
elsif (context.registers[:page]["geojson"]&.is_a?(String) and context.registers[:page]["geojson"]&.end_with?(".json")) or
|
191
|
+
context.registers[:page]["geojson"]["type"] == "FeatureCollection" then
|
192
|
+
context.registers[:page]["geojson"].deep_symbolize_keys
|
193
|
+
elsif context.registers[:page]["geojson"]["type"] == "Feature" then
|
194
|
+
{
|
195
|
+
type: "FeatureCollection",
|
196
|
+
features: [context.registers[:page]["geojson"].deep_symbolize_keys]
|
197
|
+
}
|
198
|
+
elsif context.registers[:page]["location"]["latitude"] and context.registers[:page]["location"]["longitude"] then
|
199
|
+
{
|
200
|
+
type: "FeatureCollection",
|
201
|
+
features: [{
|
202
|
+
type: "Feature",
|
203
|
+
# properties: {}.select {|key, value| !value.nil? },
|
204
|
+
geometry: {
|
205
|
+
type: "Point",
|
206
|
+
coordinates: [ # first long, that lat
|
207
|
+
context.registers[:page]["location"]["longitude"].to_f,
|
208
|
+
context.registers[:page]["location"]["latitude"].to_f,
|
209
|
+
]
|
210
|
+
}
|
211
|
+
}]
|
212
|
+
}
|
213
|
+
else
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
Liquid::Template.register_tag("maplibre", Jekyll::MapLibre::MapLibreTag)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
##
|
2
|
+
# copyright: 2020 Anatoliy Yastreb <anatoliy.yastreb@gmail.com>
|
3
|
+
# license: MIT
|
4
|
+
#
|
5
|
+
# original code from jekyll-maps, https://github.com/ayastreb/jekyll-maps/
|
6
|
+
|
7
|
+
module Jekyll
|
8
|
+
module MapLibre
|
9
|
+
class OptionsParser
|
10
|
+
OPTIONS_SYNTAX = %r!([^\s]+)\s*=\s*['"]+([^'"]+)['"]+!
|
11
|
+
ALLOWED_FLAGS = %w(
|
12
|
+
no_cluster
|
13
|
+
).freeze
|
14
|
+
ALLOWED_ATTRIBUTES = %w(
|
15
|
+
id
|
16
|
+
width
|
17
|
+
height
|
18
|
+
class
|
19
|
+
style
|
20
|
+
zoom
|
21
|
+
center
|
22
|
+
description
|
23
|
+
latitude
|
24
|
+
longitude
|
25
|
+
).freeze
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def parse(raw_options)
|
29
|
+
options = {
|
30
|
+
:attributes => {},
|
31
|
+
:flags => {}
|
32
|
+
}
|
33
|
+
raw_options.scan(OPTIONS_SYNTAX).each do |key, value|
|
34
|
+
value = value.split(",") if value.include?(",")
|
35
|
+
if ALLOWED_ATTRIBUTES.include?(key)
|
36
|
+
options[:attributes][key.to_sym] = value
|
37
|
+
else
|
38
|
+
raise "found not allowed MapLibre tag attribute #{key}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
ALLOWED_FLAGS.each do |key|
|
42
|
+
options[:flags][key.to_sym] = true if raw_options.include?(key)
|
43
|
+
end
|
44
|
+
options
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/script/bootstrap
ADDED
data/script/cibuild
ADDED
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-maplibre
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.pre.alpha.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anatoliy Yastreb, Robert Riemann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-12-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jekyll
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '13.1'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '13.1'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.5'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.5'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rubocop
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.50.2
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.50.2
|
89
|
+
description: MapLibre GL JS support for Jekyll websites to easily display vector maps
|
90
|
+
with geojson data
|
91
|
+
email:
|
92
|
+
- robert@riemann.cc
|
93
|
+
executables: []
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
97
|
+
- ".gitignore"
|
98
|
+
- ".rubocop.yml"
|
99
|
+
- CHANGELOG.md
|
100
|
+
- Gemfile
|
101
|
+
- LICENSE
|
102
|
+
- README.md
|
103
|
+
- Rakefile
|
104
|
+
- jekyll-maplibre.gemspec
|
105
|
+
- lib/jekyll-maplibre.rb
|
106
|
+
- lib/jekyll-maplibre/maplibre.html.erb
|
107
|
+
- lib/jekyll-maplibre/maplibre_tag.rb
|
108
|
+
- lib/jekyll-maplibre/options_parser.rb
|
109
|
+
- lib/jekyll-maplibre/version.rb
|
110
|
+
- script/bootstrap
|
111
|
+
- script/cibuild
|
112
|
+
homepage: https://blog.riemann.cc/projects/jekyll-maplibre
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata: {}
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 3.1.0
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.3.1
|
130
|
+
requirements: []
|
131
|
+
rubygems_version: 3.3.7
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: Maplibre GL JS for Jekyll
|
135
|
+
test_files: []
|