Ok, dengan beberapa masalah awal diselesaikan tugasnya relatif sederhana.
Skala, disajikan sebagai f.ex 1: 50000 berarti bahwa satu unit pada peta sesuai dengan 50.000 unit di dunia nyata.
Untuk peta kertas yang dicetak skala 1: 50000 ini berarti bahwa 1 meter pada peta setara dengan 50.000 meter di dunia nyata, atau untuk membuatnya lebih mudah: 1 cm pada peta setara dengan 50 meter di dunia nyata. Sejauh ini bagus.
Ketika komputer (atau layar ponsel) memasuki acara itu jauh lebih sulit: satuan ukuran pada layar adalah pixel, yang tidak memetakan langsung ke sentimeter. OpenLayers adalah (atau setidaknya di mana) menggunakan "Dots per inch", dan diasumsikan bahwa satu inci sesuai dengan 72 piksel (ini masuk akal pada layar 72 dpi, tetapi salah pada yaitu Retina Menampilkan. Tapi untuk sekarang, mari kita tetap berpegang pada 72 dpi (karena inilah yang dilakukan sebagian besar perpustakaan pemetaan (saya pikir, koreksi disambut)).
OpenLayers memiliki fungsi OpenLayers.Util.getResolutionFromScale (lihat sumber ):
OpenLayers.Util.getResolutionFromScale = function (scale, units) {
var resolution;
if (scale) {
if (units == null) {
units = "degrees";
}
var normScale = OpenLayers.Util.normalizeScale(scale);
resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units]
* OpenLayers.DOTS_PER_INCH);
}
return resolution;
};
Dengan unit = "derajat" (yang EPSG: 4490 adalah, dari apa yang saya kumpulkan) kita mendapatkan inci_per unit = 4374754 (OpenLayers.INCHES_PER_UNIT ["derajat"])
skala 1: 50000 (yang sesuai dengan 1/50000 = 0,00002) (inilah yang menghitung penLayers.Util.normalizeScale) memberikan normScale = 0,00002
- OpenLayers.DOTS_PER_INCH = 72
Kami kemudian dapat menghitung resolusi sebagai
1 / (0.00002 * 4374754 * 72) = 0.00015873908440210453
Mengetahui titik pusat (lon = 100, lat = 30), ukuran piksel viewport (w = 400, h = 600) dan resolusi kita kemudian dapat menggunakan fungsi calculBounds dari OpenLayers.Map (lihat sumber ):
calculateBounds: function(center, resolution) {
var extent = null;
if (center == null) {
center = this.getCachedCenter();
}
if (resolution == null) {
resolution = this.getResolution();
}
if ((center != null) && (resolution != null)) {
var halfWDeg = (this.size.w * resolution) / 2;
var halfHDeg = (this.size.h * resolution) / 2;
extent = new OpenLayers.Bounds(center.lon - halfWDeg,
center.lat - halfHDeg,
center.lon + halfWDeg,
center.lat + halfHDeg);
}
return extent;
},
yang dapat kita kurangi menjadi:
function calculateBounds(center, resolution, size) {
var halfWDeg = (size.w * resolution) / 2;
var halfHDeg = (size.h * resolution) / 2;
return {
"left": center.lon - halfWDeg,
"bottom": center.lat - halfHDeg,
"right": center.lon + halfWDeg,
"top": center.lat + halfHDeg
};
}
Menyebut ini dengan nilai-nilai kami memberi:
calculateBounds({"lon": 100, "lat": 30}, 0.00015873908440210453, {"w": 400, "h":600});
{
left: 99.96825218311957,
bottom: 29.95237827467937,
right: 100.03174781688043,
top: 30.04762172532063
}
Kami kemudian dapat menggabungkan semua ini ke fungsi yang bekerja untuk derajat dengan penyebut skala yang diberikan:
function calculateBounds(center, scaleDenominator, size) {
var resolution = 1 / ((1 / scaleDenominator) * 4374754 * 72)
var halfWDeg = (size.w * resolution) / 2;
var halfHDeg = (size.h * resolution) / 2;
return {
"left": center.lon - halfWDeg,
"bottom": center.lat - halfHDeg,
"right": center.lon + halfWDeg,
"top": center.lat + halfHDeg
};
}