-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
try proj4leaflet to support projection in /map
viewer
#560
Changes from 1 commit
83e78d3
5fc9f9c
712c3b9
1acb2aa
3c26453
a0dc0ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,53 +4,20 @@ | |
<meta charset='utf-8' /> | ||
<title>TiTiler Map Viewer</title> | ||
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | ||
<script src='https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js'></script> | ||
<link href='https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css' rel='stylesheet' /> | ||
|
||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"/> | ||
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script> | ||
<script src="https://unpkg.com/proj4@2.3.14/dist/proj4.js"></script> | ||
<script src="https://unpkg.com/proj4leaflet@1.0.2/src/proj4leaflet.js"></script> | ||
<style> | ||
body { margin:0; padding:0; width:100%; height:100%; background-color: #e5e5e5;} | ||
#map { position:absolute; top:0; bottom:0; width:100%; } | ||
.zoom-info { | ||
z-index: 10; | ||
position: absolute; | ||
bottom: 0; | ||
right: 0; | ||
padding: 5px; | ||
width: auto; | ||
height: auto; | ||
font-size: 12px; | ||
color: #000; | ||
} | ||
@media(max-width: 767px) { | ||
.maplibrectrl-attrib { | ||
font-size: 10px; | ||
} | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<div id='map'> | ||
<div class="zoom-info">Zoom: <span id="zoom"></span></div> | ||
</div> | ||
|
||
<script> | ||
|
||
var map = new maplibregl.Map({ | ||
container: 'map', | ||
style: { | ||
version: 8, | ||
sources: {}, | ||
layers: [] | ||
}, | ||
center: [0, 0], | ||
zoom: 1 | ||
}) | ||
<div id='map'></div> | ||
|
||
map.on('zoom', function (e) { | ||
const z = (map.getZoom()).toString().slice(0, 4) | ||
document.getElementById('zoom').textContent = z | ||
}) | ||
<script type="text/javascript"> | ||
|
||
const bboxPolygon = (bounds) => { | ||
return { | ||
|
@@ -69,79 +36,63 @@ | |
} | ||
} | ||
|
||
const addAOI = (bounds) => { | ||
if (map.getLayer('aoi-polygon')) map.removeLayer('aoi-polygon') | ||
if (map.getSource('aoi')) map.removeSource('aoi') | ||
const geojson = { | ||
"type": "FeatureCollection", | ||
"features": [bboxPolygon(bounds)] | ||
// tms comes from morecantile | ||
// https://github.com/developmentseed/morecantile/blob/main/morecantile/models.py | ||
var crs = new L.Proj.CRS( | ||
'{{ tms.crs.srs }}', | ||
'{{ tms.crs.to_proj4() }}', { | ||
origin: [{{ tms.xy_bbox[0] }}, {{ tms.xy_bbox[3] }}], | ||
// bounds: [[{{ tms.xy_bbox[0] }}, {{ tms.xy_bbox[1] }}], [{{ tms.xy_bbox[2] }}, {{ tms.xy_bbox[3] }}]], | ||
resolutions: {{ resolutions|safe }}, | ||
} | ||
); | ||
|
||
map.addSource('aoi', { | ||
'type': 'geojson', | ||
'data': geojson | ||
}) | ||
|
||
map.addLayer({ | ||
id: 'aoi-polygon', | ||
type: 'line', | ||
source: 'aoi', | ||
layout: { | ||
'line-cap': 'round', | ||
'line-join': 'round' | ||
}, | ||
paint: { | ||
'line-color': '#3bb2d0', | ||
'line-width': 1 | ||
} | ||
}) | ||
return | ||
} | ||
var map = L.map('map', { | ||
vincentsarago marked this conversation as resolved.
Show resolved
Hide resolved
|
||
zoom: 0, | ||
center: [0, 0], | ||
vincentsarago marked this conversation as resolved.
Show resolved
Hide resolved
|
||
crs: crs, | ||
continuousWorld: true, | ||
worldCopyJump: false | ||
}); | ||
|
||
map.on('load', () => { | ||
fetch('{{ tilejson_endpoint|safe }}') | ||
.then(res => { | ||
if (res.ok) return res.json() | ||
throw new Error('Network response was not ok.') | ||
}) | ||
.then(data => { | ||
console.log(data) | ||
|
||
fetch('{{ tilejson_endpoint|safe }}') | ||
.then(res => { | ||
if (res.ok) return res.json() | ||
throw new Error('Network response was not ok.') | ||
}) | ||
.then(data => { | ||
console.log(data) | ||
let bounds = [...data.bounds] | ||
// Bounds crossing dateline | ||
if (bounds[0] > bounds[2]) { | ||
bounds[0] = bounds[0] - 360 | ||
} | ||
var left = bounds[0], | ||
bottom = bounds[1], | ||
right = bounds[2], | ||
top = bounds[3]; | ||
|
||
let bounds = [...data.bounds] | ||
// Bounds crossing dateline | ||
if (bounds[0] > bounds[2]) { | ||
bounds[0] = bounds[0] - 360 | ||
var aoi = L.geoJSON( | ||
bboxPolygon(bounds), { | ||
color: '#3bb2d0', fill: false | ||
} | ||
map.fitBounds( | ||
[[bounds[0], bounds[1]], [bounds[2], bounds[3]]] | ||
) | ||
addAOI(bounds) | ||
|
||
map.addSource( | ||
'raster', | ||
{ | ||
type: 'raster', | ||
bounds: data.bounds, | ||
minzoom: data.minzoom, | ||
maxzoom: data.maxzoom, | ||
tiles: data.tiles, | ||
} | ||
) | ||
).addTo(map); | ||
map.fitBounds(aoi.getBounds()); | ||
|
||
map.addLayer( | ||
{ | ||
id: 'raster', | ||
type: 'raster', | ||
source: 'raster', | ||
} | ||
) | ||
|
||
}) | ||
.catch(err => { | ||
console.warn(err) | ||
}) | ||
}) | ||
L.tileLayer( | ||
data.tiles[0], { | ||
minZoom: data.minzoom, | ||
maxZoom: data.maxzoom, | ||
bounds: L.latLngBounds([bottom, left], [top, right]), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think you want to do this - the Focus on getting the |
||
continuousWorld: true, | ||
vincentsarago marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
).addTo(map); | ||
}) | ||
.catch(err => { | ||
console.warn(err) | ||
}) | ||
</script> | ||
</body> | ||
</html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to work but it needs more testing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if
resolutions
is https://github.com/developmentseed/morecantile/blob/main/morecantile/models.py#L370-L379There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is a bit tricky. I'll quote myself from https://gis.stackexchange.com/a/423647/53755 :
So you have to be careful about the CRS's bounds, specially if you plan on using TMS-style tiles with an inverted Y-coordinate (a
{-y}
in the URL template). Specifically, see https://stackoverflow.com/a/62625435/4768502See also https://gis.stackexchange.com/a/310124/53755 - Don't be confused when using Leaflet's functions for projecting/unprojecting coordinates because they don't rely on CRS-relative numbers, but rather screen-relative numbers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for you help @IvanSanchez
going back at this today, and I'm not quite sure I understand all of ☝️ 😭