I have a fully working map with a few base layers and some buttons, each of which loads and displays different resources. One loads some historical map overlays and uses the L.Control.Opacity plugin https://github.com/dayjournal/Leaflet.Control.Opacity to individually adjust visibility. In the stripped down tester code below I show a single baseLayer and an example overlay OS_1956 in historyMaps, which I hope is sufficient to demonstrate the outline of my scheme.
I'm seeking a generic method to add one or more geoJSON layers into the existing scheme.
One example is to show Roman roads in Britain. The data is available at https://dh.gu.se/dare/ and, as shown, can be very easily added into my map, with opacity control, using the supplied link
roman: new L.tileLayer("https://dh.gu.se/tiles/imperium/{z}/{x}/{y}.png")
However there are two issues. Firstly it covers the entire Roman empire and has far more detail than I want, but more seriously that detail comes married to an underlying map layer which I really don't want.
The project data is available at https://github.com/klokantech/roman-empire. All I want is (some of) the road data at https://github.com/klokantech/roman-empire/blob/master/data/roads_high.geojson.
Clicking on that link displays the roads overlaid on a (different) base layer, while the 'download' button produces a geoJson FeatureCollection which has no reference to that baselayer.
So while it is apparent that L.Control.Opacity can adjust a layer ('roman') made by marrying a geoJSON resource to a tileLayer, I'm afraid the page source code is beyond my grasp and I can't figure out how it is achieved.
Yet klokantech (who know a lot more about maps than me) have somehow done it in their git code such that clicking on a link brings up a working map with overlay but downloading the apparent contents makes no mention of that map.
I'm a bit stumped. I want to reproduce what they've done, using as a base either a tileLayer of my choosing or an entirely transparent tileLayer.
As an alternative, I have turned a sample from the JSON FeatureCollection into a small js object called rroads, which I can easily add to the map on top of my chosen base layer.
var myLayer = L.geoJSON(rroads).addTo(map);
However that neither fits my existing scheme nor has opacity control.
I can achieve opacity control using the technique shown at https://stackoverflow.com/questions/47270647/change-opacity-using-leaflet-without-plugin That adds a geoJSON layer called geojson and works, though not as smoothly as I would like, but the control is outside the map area, and doesn't properly integrate with my existing scheme.
I have attempted to add the same data to historyMaps as histjson: new L.geoJson(rroads, {opacity: 0.01 })
. That integrates a new L.Control.Opacity slider into my scheme but it doesn't do anything (possibly because L.Control.Opacity relies on .setOpacity which is not available to L.geoJson which for some reason only has .setStyle?)
So I'm stuck. All of my attempts have foundered for different reasons and I don't know what to do next. Can anyone advise on the best way to use L.Control.Opacity with geoJSON data please.
<!DOCTYPE html>
<html>
<head>
<title>Roman</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/L.Control.Opacity.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/L.Control.Opacity.css" rel="stylesheet" >
<span id="image-opacity">geojson</span>
<input type="range" id="sldOpacity" min="0" max="1" step="0.1" value="0.01" />
</head>
<body>
<div id="map" style="width: 600px; height: 400px;"></div>
<script>
// from https://github.com/klokantech/roman-empire/blob/master/data/roads_high.geojson edited from 850 features to 2
var rroads = {
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "Name": "Margary 1c", "descriptio": null }, "geometry": { "type": "LineString", "coordinates": [ [ 0.502122913133777, 51.391440023017289, 0.0 ], [ 0.495790717490887, 51.395644730481983, 0.0 ], [ 0.467996181852347, 51.398570131125844, 0.0 ], [ 0.416152252131068, 51.400357741123933, 0.0 ], [ 0.369580604776158, 51.414122946206994, 0.0 ], [ 0.326046318291103, 51.428705828643693, 0.0 ], [ 0.294349044754911, 51.430916683549633, 0.0 ], [ 0.265543899221985, 51.436409391955181, 0.0 ], [ 0.161395541110144, 51.453685025740953, 0.0 ], [ 0.123662308338893, 51.459592810897803, 0.0 ], [ 0.046184044141974, 51.472842635574253, 0.0 ], [ 0.019196574232533, 51.47698452023878, 0.0 ], [ -0.026549796331548, 51.481223032795768, 0.0 ], [ -0.034092702533585, 51.484955510323758, 0.0 ], [ -0.084812782781212, 51.493732620765158, 0.0 ], [ -0.090320915703155, 51.498060695182005, 0.0 ], [ -0.092991357371235, 51.501225076998104, 0.0 ], [ -0.091134672201963, 51.503997443720763, 0.0 ], [ -0.087451419447726, 51.506807540455391, 0.0 ], [ -0.086412464168425, 51.509372384094299, 0.0 ] ] } },
{ "type": "Feature", "properties": { "Name": "Margary 2d", "descriptio": null }, "geometry": { "type": "LineString", "coordinates": [ [ -0.538186341951123, 53.237073005890736, 0.0 ], [ -0.537926882789907, 53.245346023934971, 0.0 ], [ -0.545858081796996, 53.366221001670091, 0.0 ], [ -0.559928349082197, 53.594268830796381, 0.0 ], [ -0.563521370860075, 53.609530235359955, 0.0 ], [ -0.58216819366816, 53.69286831070356, 0.0 ] ] } },
]
};
var map = L.map('map').setView([51.505, -0.09], 6);
const baseMaps = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1
}).addTo(map);
var geojson = L.geoJson(rroads, {
style: {
"opacity": 0.01
},
}).addTo(map);
var historyMaps = {
OS_1956: new L.tileLayer('https://mapseries-tilesets.s3.amazonaws.com/ten_mile/general/{z}/{x}/{y}.png', { opacity: 0.01, maxNativeZoom: 12}),
Roman: new L.tileLayer("https://dh.gu.se/tiles/imperium/{z}/{x}/{y}.png", { opacity: 0.01, maxNativeZoom: 11 }),
histjson: new L.geoJson(rroads, {opacity: 0.01 }),
};
hlay = L.control.opacity(historyMaps, {collapsed: false, label: "History" } );
function history_ctl() {
if (hctl !== 'show') {
show_history()
map.on('baselayerchange', function(e) { ; // say('baselayerchange to ' + e.name);
baseMaps[e.name].bringToBack()
});
}
else
lose_history()
}
function show_history() {
hctl = 'show' ; // say('show_history: hctl ', hctl)
historyMaps.OS_1956.addTo(map);
historyMaps.Roman.addTo(map);
historyMaps.histjson.addTo(map);
hlay.addTo(map); ; // say('map: ', map)
}
function lose_history() {
hctl = 'hide' ; // say('lose_history: hctl ', hctl)
historyMaps.OS_1956.removeFrom(map);
historyMaps.Roman.removeFrom(map);
historyMaps.histjson.removeFrom(map);
hlay.remove();
}
hctl = 'hide'
history_ctl();
L.DomEvent.on(L.DomUtil.get('sldOpacity'), 'change', function () {
L.DomUtil.get('image-opacity').textContent = this.value;
geojson.setStyle({
opacity: this.value
});
});
</script>
</body>
</html>