一、首先闡明幾個概念:
1、Scale:比例尺,圖上距離和實地距離之比。
2、Resolution:分辨率,每個象元代表的實地距離(map units per pixels)。
3、Extent:地圖的范圍(地圖四至)。
4、zoomlevel:縮放的級別(0~15)。
注:因為這幾個變量均為對”地圖顯示“的量化描述,因此均有最大和最小值。
5、map,baselayer:map即地圖,其size也是決定顯示的因素。baselayer相當於一個地圖中的底圖,許多尺度變換函數均在baselayer類中實現,所以map中必須添加baselayer。
在Openlayers中如要正確顯示一副地圖,則上面的變量必須要正確設置,但不一定全部設置,全部設置,計算不正確的話可能導致沖突。可選擇設置部分,其余由Openlayers自動計算。
二、scale 和 Resolution 的相互轉化。
按照Openlayers中的概念,分比率是比較好計算的,比如直接取地圖實際寬度(或高度)和地圖div(以像素為單位)大小之比,就得到了該縮放級別下的分辨率。假設:地圖單位是米,在某個縮放級別L下的分辨率為R,如何得到該縮放級別L的比例尺?
Scale是圖上距離和實地距離之比,現在我們有的是地圖的
屏幕距離(以像素為單位),實地距離和分辨率,很顯然,我們只要得到
圖上距離即可。問題轉化為如何由
屏幕距離+分辨率,求圖上距離。解決問題的關鍵是dpi, dots per inches,or pixels per inches。Openlayers假定其接受的地圖圖片均為72dpi,即72的像素點有一英寸的長度,即屏幕上的地圖圖片中,72個像素點就是一英寸的長度。現在問題基本上有頭緒了,就屏幕距離(像素為單位)通過72dpi這個值,轉換為圖上距離。假設屏幕距離為P,分辨率為R,則比例尺S為:
實地距離:
R * P
圖上距離:
(P / 72) / 39.3701 = P / (72*39.3701)
比例尺:
S = P / (72*39.3701) / R*P = 1 / R*72*32.3701
39.3701是inches和米的對應關系。Openlayers專有對象定義了這樣的對應關系,為的就是能對於不同投影,不同單位的地圖得到一個大概的比例尺。
OpenLayers.INCHES_PER_UNIT =
{
'inches': 1.0,
'ft': 12.0,
'mi': 63360.0,
'm': 39.3701,
'km': 39370.1,
'dd': 4374754,
'yd': 36 };
Openlayers中也有這個一個定義:OpenLayers.DOTS_PER_INCH = 72;即前文中提到的dpi。
當然由Scale反算Resolution也很簡單,關鍵是要知道單位,Units。
1、比例尺轉分辨率
//比例尺改變事件監聽
Bus.$on("changeScale", val => {
//默認dpi
const DEFAULT_DPI = 25.4 / 0.28;
//每米多少英寸
const inchesPerMeter = 1000 / 25.4;
var readyToChangeResolution = 0;
//如果是度分秒的話需要轉換為米
if(self.map.getView().getProjection().getUnits() != 'metric'){
readyToChangeResolution = 1/(val*self.map.getView().getProjection().getMetersPerUnit() * inchesPerMeter * DEFAULT_DPI);
}else{
readyToChangeResolution = 1 / (val * inchesPerMeter * DEFAULT_DPI);
}
this.changeScale(readyToChangeResolution);
});
2、分辨率轉比例尺
// 監聽分辨率變化,通過dpi和像素關系(比例尺=dpi/0.0254*分辨率)輸出比例尺
this.map.getView().on('change:resolution', function(){
//默認dpi
const DEFAULT_DPI = 25.4 / 0.28;
//每米多少英寸
const inchesPerMeter = 1000 / 25.4;
var currentScale = 1;
//如果是度分秒的話需要轉換為米
if(self.map.getView().getProjection().getUnits() != 'metric'){
currentScale = self.map.getView().getResolution()*self.map.getView().getProjection().getMetersPerUnit() * inchesPerMeter * DEFAULT_DPI;
}else{
currentScale = self.map.getView().getResolution() * inchesPerMeter * DEFAULT_DPI;
}
const mapScale =
'1 : ' + Math.round(currentScale).toLocaleString();
console.log(mapScale)
});
*注意事項:上述DEFAULT_DPI 來自openlayers(6.x)源碼中的比例尺 早期openlayers版本中的dpi可能有所不同,詳情可查詢所使用openlayers版本的源碼進行確認
轉自:https://blog.csdn.net/weixin_43461143/article/details/100928448
https://www.csdn.net/tags/NtjaUg1sNDg0OTUtYmxvZwO0O0OO0O0O.html