如何为地图的选定部分下载 OSM 瓦片
How to download the OSM tiles for selected part of map
我想使用 Openlayer OSM 层为地图的选定部分离线下载地图,具有单一缩放级别。我有地图的四个角,即地图的显示部分。
但需要获取所有的瓷砖图像或四个角之间的瓷砖。我回顾了一些例子:
https://gis.stackexchange.com/questions/167792/how-to-retrieve-the-tile-url-in-openlayers-3
但我需要在客户单击按钮时下载磁贴。谁能帮帮我。
这里有一个简单的示例,可以将图块保存为数据 URL 供以后使用。如果您需要保存的图块在关闭并重新打开浏览器后仍然可用,请将 sessionStorage 替换为 localStorage。
// load OSM zoom level 8 tiles for Switzerland to data urls
var extent = ol.proj.transformExtent([5.9,45.8,10.55,47.85],'EPSG:4326','EPSG:3857');
var zoom = 8;
var source = new ol.source.OSM();
source.getTileGrid().forEachTileCoord(extent, zoom, function(tileCoord) {
var img = document.createElement("img");
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = source.getTileGrid().getTileSize(zoom);
canvas.height = source.getTileGrid().getTileSize(zoom);
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
sessionStorage.setItem('OSM_' + tileCoord[0] + '_' + tileCoord[1] + '_' + (-tileCoord[2]-1), canvas.toDataURL());
img.remove();
canvas.remove();
};
img.crossOrigin = "Anonymous";
img.src = source.getTileUrlFunction()(tileCoord);
});
// wait a few seconds to ensure data urls are ready, then create a map to use them
setTimeout(function(){
map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
extent: extent,
source: new ol.source.XYZ({
attributions: ol.source.OSM.ATTRIBUTION,
maxZoom: 8,
minZoom: 8,
tileUrlFunction: function(tileCoord) {
return sessionStorage.getItem('OSM_' + tileCoord[0] + '_' + tileCoord[1] + '_' + (-tileCoord[2]-1));
}
}),
})
],
view: new ol.View({
center: ol.extent.getCenter(extent),
zoom: 8
}),
controls: ol.control.defaults({
attributionOptions: { collapsible: false },
})
});
}, 3000);
您可以在 C# 上编写简单的 Web 客户端
例如:
static void Main(string[] args)
{
double[] latitudes= new double[] { 38.822591, 40.979898, 43.068888, 45.089036, 47.040182, 48.922499, 50.736455, 52.48278, 54.162434, 55.776573, 57.326521, 58.813742, 60.239811, 61.606397, 62.915233, 64.168107, 65.366837, 66.51326, 67.60922, 68.656555, 69.657086, 70.612614, 71.524909, 72.395706, 73.2267, 74.019543, 74.775843, 75.497157, 76.184995, 76.840817, 77.466029, 78.061989, 78.630006, 79.171334, 79.687184, 80.178713, 80.647035, 81.093214, 81.518272, 81.923187, 82.308893, 82.676285, 83.026219, 83.359512, 83.676943, 83.979259, 84.267172 };// see netzwolf.info kashebrowser
for (int kk = 0; kk < 45; kk++)
{
string currentToken = "546882";//osm token, you can view it in cookies
String lat1 = "," + latitudes[kk] + ",";
String lat2 = "," + latitudes[kk + 1];
double long1= 18.671225;
double deltaLong1 = 5.0104;// you can get in v
for (i = 32; i < 48; i++)
{
try
{
using (WebClient client = new WebClient())
{
String currentUrl = "https://render.openstreetmap.org/cgi-bin/export?bbox=" + long1.ToString() + lat1+ (long1+ deltaLat1).ToString() + lat2+ "&scale=4000000&format=svg";//format and scale
Console.WriteLine(currentUrl);
Uri url = new Uri(currentUrl);
client.Headers.Add(HttpRequestHeader.Authorization, "render.openstreetmap.org");
client.Headers.Add("method", "GET");
client.Headers.Add("scheme", "https");
client.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
//client.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate, br");
client.Headers.Add(HttpRequestHeader.AcceptLanguage, "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7");
client.Headers.Add(HttpRequestHeader.Cookie, "_osm_totp_token=" + currentToken);
client.Headers.Add("sec-ch-ua", "\"Chromium\";v=\"88\", \"Google Chrome\";v=\"88\", \"; Not A Brand\";v=\"99\"");
client.Headers.Add(HttpRequestHeader.Referer, "https://www.openstreetmap.org/");
client.Headers.Add("sec-fetch-dest", "document");
client.Headers.Add("sec-fetch-mode", "navigate");
client.Headers.Add("sec-fetch-site", "same-site");
client.Headers.Add("sec-fetch-user", "?1");
client.Headers.Add("upgrade-insecure-requests", "1");
client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36");
client.QueryString.Add("format", "svg");
Console.WriteLine(i);
client.DownloadFile(url, i.ToString() + "_" + kk.ToString() + ".svg");
long1+= deltaLong;
}
}
//if server drop, it wait 5 sec get token again and get back one iteration
catch (Exception e)
{
Console.WriteLine(e);
System.Threading.Thread.Sleep(5000);
String currentUrl = "https://www.openstreetmap.org/#map=8/41.8368/104.5450&layers=N";
HttpWebRequest tQ = (HttpWebRequest)HttpWebRequest.Create(currentUrl);
tQ.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9";
tQ.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.41 YaBrowser/21.2.0.1097 Yowser/2.5 Safari/537.36";
tQ.ContentType = "text/html; charset=utf-8";
tQ.Referer = currentUrl;
HttpWebResponse tS = (HttpWebResponse)tQ.GetResponse();
string tC = tS.Headers["Set-Cookie"];
var cc = tC.IndexOf("_osm_totp_token=");
currentToken = tC.Substring(cc + "_osm_totp_token=".Length, 6);
//string num = tC.Trim(, 2);
Console.WriteLine(tC);
i = i - 1;
}
Console.WriteLine("i=" + i.ToString());
}
}
}
我想使用 Openlayer OSM 层为地图的选定部分离线下载地图,具有单一缩放级别。我有地图的四个角,即地图的显示部分。
但需要获取所有的瓷砖图像或四个角之间的瓷砖。我回顾了一些例子:
https://gis.stackexchange.com/questions/167792/how-to-retrieve-the-tile-url-in-openlayers-3
但我需要在客户单击按钮时下载磁贴。谁能帮帮我。
这里有一个简单的示例,可以将图块保存为数据 URL 供以后使用。如果您需要保存的图块在关闭并重新打开浏览器后仍然可用,请将 sessionStorage 替换为 localStorage。
// load OSM zoom level 8 tiles for Switzerland to data urls
var extent = ol.proj.transformExtent([5.9,45.8,10.55,47.85],'EPSG:4326','EPSG:3857');
var zoom = 8;
var source = new ol.source.OSM();
source.getTileGrid().forEachTileCoord(extent, zoom, function(tileCoord) {
var img = document.createElement("img");
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = source.getTileGrid().getTileSize(zoom);
canvas.height = source.getTileGrid().getTileSize(zoom);
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
sessionStorage.setItem('OSM_' + tileCoord[0] + '_' + tileCoord[1] + '_' + (-tileCoord[2]-1), canvas.toDataURL());
img.remove();
canvas.remove();
};
img.crossOrigin = "Anonymous";
img.src = source.getTileUrlFunction()(tileCoord);
});
// wait a few seconds to ensure data urls are ready, then create a map to use them
setTimeout(function(){
map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
extent: extent,
source: new ol.source.XYZ({
attributions: ol.source.OSM.ATTRIBUTION,
maxZoom: 8,
minZoom: 8,
tileUrlFunction: function(tileCoord) {
return sessionStorage.getItem('OSM_' + tileCoord[0] + '_' + tileCoord[1] + '_' + (-tileCoord[2]-1));
}
}),
})
],
view: new ol.View({
center: ol.extent.getCenter(extent),
zoom: 8
}),
controls: ol.control.defaults({
attributionOptions: { collapsible: false },
})
});
}, 3000);
您可以在 C# 上编写简单的 Web 客户端 例如:
static void Main(string[] args)
{
double[] latitudes= new double[] { 38.822591, 40.979898, 43.068888, 45.089036, 47.040182, 48.922499, 50.736455, 52.48278, 54.162434, 55.776573, 57.326521, 58.813742, 60.239811, 61.606397, 62.915233, 64.168107, 65.366837, 66.51326, 67.60922, 68.656555, 69.657086, 70.612614, 71.524909, 72.395706, 73.2267, 74.019543, 74.775843, 75.497157, 76.184995, 76.840817, 77.466029, 78.061989, 78.630006, 79.171334, 79.687184, 80.178713, 80.647035, 81.093214, 81.518272, 81.923187, 82.308893, 82.676285, 83.026219, 83.359512, 83.676943, 83.979259, 84.267172 };// see netzwolf.info kashebrowser
for (int kk = 0; kk < 45; kk++)
{
string currentToken = "546882";//osm token, you can view it in cookies
String lat1 = "," + latitudes[kk] + ",";
String lat2 = "," + latitudes[kk + 1];
double long1= 18.671225;
double deltaLong1 = 5.0104;// you can get in v
for (i = 32; i < 48; i++)
{
try
{
using (WebClient client = new WebClient())
{
String currentUrl = "https://render.openstreetmap.org/cgi-bin/export?bbox=" + long1.ToString() + lat1+ (long1+ deltaLat1).ToString() + lat2+ "&scale=4000000&format=svg";//format and scale
Console.WriteLine(currentUrl);
Uri url = new Uri(currentUrl);
client.Headers.Add(HttpRequestHeader.Authorization, "render.openstreetmap.org");
client.Headers.Add("method", "GET");
client.Headers.Add("scheme", "https");
client.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
//client.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate, br");
client.Headers.Add(HttpRequestHeader.AcceptLanguage, "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7");
client.Headers.Add(HttpRequestHeader.Cookie, "_osm_totp_token=" + currentToken);
client.Headers.Add("sec-ch-ua", "\"Chromium\";v=\"88\", \"Google Chrome\";v=\"88\", \"; Not A Brand\";v=\"99\"");
client.Headers.Add(HttpRequestHeader.Referer, "https://www.openstreetmap.org/");
client.Headers.Add("sec-fetch-dest", "document");
client.Headers.Add("sec-fetch-mode", "navigate");
client.Headers.Add("sec-fetch-site", "same-site");
client.Headers.Add("sec-fetch-user", "?1");
client.Headers.Add("upgrade-insecure-requests", "1");
client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36");
client.QueryString.Add("format", "svg");
Console.WriteLine(i);
client.DownloadFile(url, i.ToString() + "_" + kk.ToString() + ".svg");
long1+= deltaLong;
}
}
//if server drop, it wait 5 sec get token again and get back one iteration
catch (Exception e)
{
Console.WriteLine(e);
System.Threading.Thread.Sleep(5000);
String currentUrl = "https://www.openstreetmap.org/#map=8/41.8368/104.5450&layers=N";
HttpWebRequest tQ = (HttpWebRequest)HttpWebRequest.Create(currentUrl);
tQ.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9";
tQ.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.41 YaBrowser/21.2.0.1097 Yowser/2.5 Safari/537.36";
tQ.ContentType = "text/html; charset=utf-8";
tQ.Referer = currentUrl;
HttpWebResponse tS = (HttpWebResponse)tQ.GetResponse();
string tC = tS.Headers["Set-Cookie"];
var cc = tC.IndexOf("_osm_totp_token=");
currentToken = tC.Substring(cc + "_osm_totp_token=".Length, 6);
//string num = tC.Trim(, 2);
Console.WriteLine(tC);
i = i - 1;
}
Console.WriteLine("i=" + i.ToString());
}
}
}