Add basic side menu for layer selection
This _should_ be smart and not load expensive layers until they're rendered.
This commit is contained in:
parent
7e9164c11f
commit
ffaf53fee2
|
@ -8,6 +8,9 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>Sorry, but you'll need JavaScript enabled for any of this to work!</noscript>
|
<noscript>Sorry, but you'll need JavaScript enabled for any of this to work!</noscript>
|
||||||
|
<aside>
|
||||||
|
<h1>Chandler's Maps</h1>
|
||||||
|
</aside>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
<script type="module" src="./main.js"></script>
|
<script type="module" src="./main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
35
layers/index.js
Normal file
35
layers/index.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import TileLayer from 'ol/layer/Tile';
|
||||||
|
import OSM from 'ol/source/OSM';
|
||||||
|
|
||||||
|
import amtrakLayer from './amtrak/layer.js';
|
||||||
|
import arenasLayer from './nhl-arenas/layer.js';
|
||||||
|
|
||||||
|
const layerCategories = [
|
||||||
|
{
|
||||||
|
name: "Base maps",
|
||||||
|
layers: [
|
||||||
|
{
|
||||||
|
name: "OpenStreetMap Carto",
|
||||||
|
enabled: true,
|
||||||
|
layer: new TileLayer({
|
||||||
|
source: new OSM(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Overlays",
|
||||||
|
layers: [
|
||||||
|
{
|
||||||
|
name: "Amtrak Routes",
|
||||||
|
layer: amtrakLayer,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "NHL Arenas",
|
||||||
|
layer: arenasLayer,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default layerCategories;
|
51
main.js
51
main.js
|
@ -1,26 +1,51 @@
|
||||||
import './style.css';
|
import './style.css';
|
||||||
import {Map, View} from 'ol';
|
import {Map, View} from 'ol';
|
||||||
import TileLayer from 'ol/layer/Tile';
|
|
||||||
import OSM from 'ol/source/OSM';
|
|
||||||
import {fromLonLat} from 'ol/proj.js';
|
import {fromLonLat} from 'ol/proj.js';
|
||||||
|
|
||||||
import amtrakLayer from './layers/amtrak/layer.js';
|
import layerCategories from './layers/index.js';
|
||||||
import arenasLayer from './layers/nhl-arenas/layer.js';
|
|
||||||
|
|
||||||
const map = new Map({
|
const map = new Map({
|
||||||
target: 'map',
|
target: 'map',
|
||||||
layers: [
|
layers: [],
|
||||||
new TileLayer({
|
|
||||||
source: new OSM()
|
|
||||||
})
|
|
||||||
],
|
|
||||||
view: new View({
|
view: new View({
|
||||||
center: fromLonLat([-93.24151, 44.80376]),
|
center: fromLonLat([-93.24151, 44.80376]),
|
||||||
zoom: 10,
|
zoom: 10,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
map.getLayers().extend([
|
// Basic reactivity binding: like vue.js, just worse :)
|
||||||
amtrakLayer,
|
//
|
||||||
arenasLayer,
|
// This implements some basic reactivity so that I can add and remove layers.
|
||||||
]);
|
// Nothing too fancy, at this point. Eventually, I'll likely pull in proper Vue,
|
||||||
|
// as I aim for more complex interactions, like layer ordering, color selection,
|
||||||
|
// custom layer imports, and more.
|
||||||
|
for (let category of layerCategories) {
|
||||||
|
const catDiv = document.createElement("div");
|
||||||
|
catDiv.innerHTML = `
|
||||||
|
<h3>${category.name}</h3>
|
||||||
|
<ul></ul>
|
||||||
|
`;
|
||||||
|
for (let layer of category.layers) {
|
||||||
|
const li = document.createElement("li");
|
||||||
|
li.innerHTML = `
|
||||||
|
<input type="checkbox" ${layer.enabled ? "checked" : ""}> ${layer.name}
|
||||||
|
`;
|
||||||
|
li.querySelector("input").addEventListener("change", function(e){
|
||||||
|
if (e.target.checked) {
|
||||||
|
map.getLayers().push(layer.layer);
|
||||||
|
} else {
|
||||||
|
map.getLayers().remove(layer.layer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
catDiv.querySelector("ul").appendChild(li);
|
||||||
|
}
|
||||||
|
document.querySelector("aside").appendChild(catDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let category of layerCategories) {
|
||||||
|
for (let layer of category.layers) {
|
||||||
|
if (layer.enabled) {
|
||||||
|
map.addLayer(layer.layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
21
style.css
21
style.css
|
@ -8,5 +8,24 @@ html, body {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
left: min(max(200px, 20%), 400px);
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
width: min(max(200px, 20%), 400px);
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside ul li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue