Skip to content

Commit

Permalink
add vector maps
Browse files Browse the repository at this point in the history
  • Loading branch information
drkane committed Aug 10, 2023
1 parent e72a48a commit bd24695
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 34 deletions.
44 changes: 10 additions & 34 deletions findthatpostcode/static/js/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ if (window.postcodes && postcodes.length > 0) {
var mymap = L.map('postcode-map', {
zoomSnap: 0.1
}).setView(center, 9);
var layer = new L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.png', {
// var layer = new L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.png', {
// attribution: '&copy; <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> <a href="https://www.stamen.com/" target="_blank">&copy; Stamen Design</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/about" target="_blank">OpenStreetMap</a> contributors',
// }).addTo(mymap);
var layer = L.maplibreGL({
style: 'https://tiles.stadiamaps.com/styles/alidade_smooth.json',
attribution: '&copy; <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> <a href="https://www.stamen.com/" target="_blank">&copy; Stamen Design</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/about" target="_blank">OpenStreetMap</a> contributors',
}).addTo(mymap);
L.osGraticule({ showLabels: false, lineColor: '#ddd' }).addTo(mymap);
Expand All @@ -25,8 +29,8 @@ if (document.getElementById('location-map')) {
dragging: false,
scrollWheelZoom: false,
});
new L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}{r}.png', {
attribution: '&copy; <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> <a href="https://www.stamen.com/" target="_blank">&copy; Stamen Design</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/about" target="_blank">OpenStreetMap</a> contributors',
var layer = L.maplibreGL({
style: 'https://tiles.stadiamaps.com/styles/alidade_smooth.json',
}).addTo(location_map);
location_map.fitBounds(UK_BOUNDS);
location_map.setMinZoom(location_map.getZoom());
Expand All @@ -40,12 +44,6 @@ if (window.postcodes) {
radius: 5,
fillOpacity: 0.8
}).addTo(markers);
// marker.bindPopup(
// "<a href=\"/postcodes/{{ postcode.id }}.html\">{{ postcode.id }}</a>",
// {
// autoClose: false
// }
// ).openPopup();
}
}

Expand Down Expand Up @@ -88,38 +86,16 @@ if (geojson) {
});
boundary_json.addTo(mymap);
postcode_show();
mymap.fitBounds(boundary_json.getBounds());
mymap.fitBounds(boundary_json.getBounds(), {
padding: [20, 20]
});

if (location_map) {
boundary_json.eachLayer((layer) => {
L.marker(layer.getBounds().getCenter()).addTo(location_map);
});
}

// if(typeof parent_geojson !== 'undefined'){
// fetch(parent_geojson)
// .then(function (response) {
// if (response.status !== 200) {
// throw new Error("Not 200 response")
// } else {
// return response.json();
// }
// })
// .then(function (geojson) {
// var parent_geojson = L.geoJSON(geojson, {
// style: {
// stroke: true,
// color: '#00449e99',
// weight: 1,
// fill: false,
// },
// });
// parent_geojson.addTo(mymap);
// mymap.fitBounds(parent_geojson.getBounds());
// });

// }

})
.catch((error) => {
postcode_show();
Expand Down
286 changes: 286 additions & 0 deletions findthatpostcode/static/lib/maplibre/leaflet-maplibre-gl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['leaflet', 'maplibre-gl'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS-like
module.exports = factory(require('leaflet'), require('maplibre-gl'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.L, root.maplibregl);
}
}(typeof globalThis !== 'undefined' ? globalThis : this || self, function (L, maplibregl) {
L.MaplibreGL = L.Layer.extend({
options: {
updateInterval: 32,
// How much to extend the overlay view (relative to map size)
// e.g. 0.1 would be 10% of map view in each direction
padding: 0.1,
// whether or not to register the mouse and keyboard
// events on the maplibre overlay
interactive: false,
// set the tilepane as the default pane to draw gl tiles
pane: 'tilePane'
},

initialize: function (options) {
L.setOptions(this, options);

// setup throttling the update event when panning
this._throttledUpdate = L.Util.throttle(this._update, this.options.updateInterval, this);
},

onAdd: function (map) {
if (!this._container) {
this._initContainer();
}

var paneName = this.getPaneName();
map.getPane(paneName).appendChild(this._container);

this._initGL();

this._offset = this._map.containerPointToLayerPoint([0, 0]);

// work around https://github.com/mapbox/mapbox-gl-leaflet/issues/47
if (map.options.zoomAnimation) {
L.DomEvent.on(map._proxy, L.DomUtil.TRANSITION_END, this._transitionEnd, this);
}
},

onRemove: function (map) {
if (this._map._proxy && this._map.options.zoomAnimation) {
L.DomEvent.off(this._map._proxy, L.DomUtil.TRANSITION_END, this._transitionEnd, this);
}
var paneName = this.getPaneName();
map.getPane(paneName).removeChild(this._container);

this._glMap.remove();
this._glMap = null;
},

getEvents: function () {
return {
move: this._throttledUpdate, // sensibly throttle updating while panning
zoomanim: this._animateZoom, // applys the zoom animation to the <canvas>
zoom: this._pinchZoom, // animate every zoom event for smoother pinch-zooming
zoomstart: this._zoomStart, // flag starting a zoom to disable panning
zoomend: this._zoomEnd,
resize: this._resize
};
},

getMaplibreMap: function () {
return this._glMap;
},

getCanvas: function () {
return this._glMap.getCanvas();
},

getSize: function () {
return this._map.getSize().multiplyBy(1 + this.options.padding * 2);
},

getBounds: function () {
var halfSize = this.getSize().multiplyBy(0.5);
var center = this._map.latLngToContainerPoint(this._map.getCenter());
return L.latLngBounds(
this._map.containerPointToLatLng(center.subtract(halfSize)),
this._map.containerPointToLatLng(center.add(halfSize))
);
},

getContainer: function () {
return this._container;
},

// returns the pane name set in options if it is a valid pane, defaults to tilePane
getPaneName: function () {
return this._map.getPane(this.options.pane) ? this.options.pane : 'tilePane';
},

_roundPoint: function(p) {
return {x: Math.round(p.x), y: Math.round(p.y)};
},

_initContainer: function () {
var container = this._container = L.DomUtil.create('div', 'leaflet-gl-layer');

var size = this.getSize();
var offset = this._map.getSize().multiplyBy(this.options.padding);
container.style.width = size.x + 'px';
container.style.height = size.y + 'px';

var topLeft = this._map.containerPointToLayerPoint([0, 0]).subtract(offset);

L.DomUtil.setPosition(container, this._roundPoint(topLeft));
},

_initGL: function () {
var center = this._map.getCenter();

var options = L.extend({}, this.options, {
container: this._container,
center: [center.lng, center.lat],
zoom: this._map.getZoom() - 1,
attributionControl: false
});

this._glMap = new maplibregl.Map(options);

// allow GL base map to pan beyond min/max latitudes
this._glMap.transform.latRange = null;
this._glMap.transform.maxValidLatitude = Infinity;

this._transformGL(this._glMap);

if (this._glMap._canvas.canvas) {
// older versions of mapbox-gl surfaced the canvas differently
this._glMap._actualCanvas = this._glMap._canvas.canvas;
} else {
this._glMap._actualCanvas = this._glMap._canvas;
}

// treat child <canvas> element like L.ImageOverlay
var canvas = this._glMap._actualCanvas;
L.DomUtil.addClass(canvas, 'leaflet-image-layer');
L.DomUtil.addClass(canvas, 'leaflet-zoom-animated');
if (this.options.interactive) {
L.DomUtil.addClass(canvas, 'leaflet-interactive');
}
if (this.options.className) {
L.DomUtil.addClass(canvas, this.options.className);
}
},

_update: function (e) {
// update the offset so we can correct for it later when we zoom
this._offset = this._map.containerPointToLayerPoint([0, 0]);

if (this._zooming) {
return;
}

var size = this.getSize(),
container = this._container,
gl = this._glMap,
offset = this._map.getSize().multiplyBy(this.options.padding),
topLeft = this._map.containerPointToLayerPoint([0, 0]).subtract(offset);

L.DomUtil.setPosition(container, this._roundPoint(topLeft));

this._transformGL(gl);

if (gl.transform.width !== size.x || gl.transform.height !== size.y) {
container.style.width = size.x + 'px';
container.style.height = size.y + 'px';
if (gl._resize !== null && gl._resize !== undefined){
gl._resize();
} else {
gl.resize();
}
} else {
// older versions of mapbox-gl surfaced update publicly
if (gl._update !== null && gl._update !== undefined){
gl._update();
} else {
gl.update();
}
}
},

_transformGL: function (gl) {
var center = this._map.getCenter();

// gl.setView([center.lat, center.lng], this._map.getZoom() - 1, 0);
// calling setView directly causes sync issues because it uses requestAnimFrame

var tr = gl.transform;
tr.center = maplibregl.LngLat.convert([center.lng, center.lat]);
tr.zoom = this._map.getZoom() - 1;
},

// update the map constantly during a pinch zoom
_pinchZoom: function (e) {
this._glMap.jumpTo({
zoom: this._map.getZoom() - 1,
center: this._map.getCenter()
});
},

// borrowed from L.ImageOverlay
// https://github.com/Leaflet/Leaflet/blob/master/src/layer/ImageOverlay.js#L139-L144
_animateZoom: function (e) {
var scale = this._map.getZoomScale(e.zoom);
var padding = this._map.getSize().multiplyBy(this.options.padding * scale);
var viewHalf = this.getSize()._divideBy(2);
// corrections for padding (scaled), adapted from
// https://github.com/Leaflet/Leaflet/blob/master/src/map/Map.js#L1490-L1508
var topLeft = this._map.project(e.center, e.zoom)
._subtract(viewHalf)
._add(this._map._getMapPanePos()
.add(padding))._round();
var offset = this._map.project(this._map.getBounds().getNorthWest(), e.zoom)
._subtract(topLeft);

L.DomUtil.setTransform(
this._glMap._actualCanvas,
offset.subtract(this._offset),
scale
);
},

_zoomStart: function (e) {
this._zooming = true;
},

_zoomEnd: function () {
var scale = this._map.getZoomScale(this._map.getZoom());

L.DomUtil.setTransform(
this._glMap._actualCanvas,
// https://github.com/mapbox/mapbox-gl-leaflet/pull/130
null,
scale
);

this._zooming = false;

this._update();
},

_transitionEnd: function (e) {
L.Util.requestAnimFrame(function () {
var zoom = this._map.getZoom();
var center = this._map.getCenter();
var offset = this._map.latLngToContainerPoint(
this._map.getBounds().getNorthWest()
);

// reset the scale and offset
L.DomUtil.setTransform(this._glMap._actualCanvas, offset, 1);

// enable panning once the gl map is ready again
this._glMap.once('moveend', L.Util.bind(function () {
this._zoomEnd();
}, this));

// update the map position
this._glMap.jumpTo({
center: center,
zoom: zoom - 1
});
}, this);
},

_resize: function (e) {
this._transitionEnd(e);
}
});

L.maplibreGL = function (options) {
return new L.MaplibreGL(options);
};

}));
1 change: 1 addition & 0 deletions findthatpostcode/static/lib/maplibre/maplibre-gl.css

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions findthatpostcode/static/lib/maplibre/maplibre-gl.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions findthatpostcode/templates/_leaflet.html.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<link rel="stylesheet" href="{{ url_for('static', filename='lib/leaflet/leaflet.css' )}}" />
<link rel="stylesheet" href="{{ url_for('static', filename='lib/maplibre/maplibre-gl.css' )}}" />
<script src="{{ url_for('static', filename='lib/leaflet/leaflet.js' )}}"></script>
<script src="{{ url_for('static', filename='lib/maplibre/maplibre-gl.js' )}}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='lib/maplibre/leaflet-maplibre-gl.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/L.OSGraticule.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/leaflet.snogylop.min.js' )}}"></script>

0 comments on commit bd24695

Please sign in to comment.