การฉายภาพและการซูม
การฉายภาพ คือการนำโลกทรงกลมมาลงบนหน้าจอแบน และการซูม บ่งบอกถึงระดับการซูมแค่ไหน แม้ว่าคำจำกัดความของทั้งสองอย่างจะแตกต่างกันไปตามผู้ให้บริการ แต่ MapConductor ใช้ค่าคงที่และสูตรเดียวกันบน 3 แพลตฟอร์ม และจัดรูปแบบค่าที่เปิดเผยให้เป็นมาตราส่วนเดียวกัน วิธีการใช้กล้องดูได้ที่หน้ากล้อง ส่วนที่นี่จะพูดถึงค่าตัวเลขที่อยู่ภายใต้นั้น
01 · ค่าคงที่ของโลก
การฉายภาพ การคำนวณทางภูมิศาสตร์ และการคำนวณกระเบื้อง ล้วนอ้างอิงค่าคงที่ของ Earth
02 · การฉายภาพ
ประเภทของการฉายภาพมีเพียง `project` และ `unproject` เท่านั้น เป็นการดำเนินการสมมาตรที่ฉายพิกัดลงในพิกัดระนาบ (`Offset`) และส่งกลับคืน มีการนำไปใช้จริง 2 แบบ
Web Mercator ในหน่วยเมตร
ฉายลงบนระนาบ ±20,037,508.34 m เหมือนกับ EPSG:3857 ใช้สำหรับการคำนวณขอบเขตของไทล์และการแปลงระยะทางบนหน้าจอเป็นเมตร
พิกัดไทล์ 256 พิกเซล
ฉายลงในระบบพิกัดที่ใช้ไทล์เดียวที่ซูม 0 (256×256) เป็นหน่วย เป็นระบบพิกัดที่เรนเดอร์ใช้สร้างภาพไทล์
interface ProjectionInterface {
fun project(position: GeoPointInterface): Offset
fun unproject(point: Offset): GeoPointInterface
}
val meters = WebMercator.project(tokyo) // x, y เป็นเมตร
val tile = WGS84.project(tokyo) // พิกัดไทล์ 0 ถึง 256// บน iOS การฉายอยู่ในอิมพลีเมนต์ฝั่งไทล์และดัชนีเชิงพื้นที่ // การแปลงพิกัด ⇄ หน้าจอจากฝั่งแอป ให้ใช้ MapViewHolder let offset = holder.toScreenOffset(position: tokyo) let point = holder.fromScreenOffsetSync(offset: tapLocation)
import { WebMercator, WGS84, Earth } from '@mapconductor/js-sdk-core';
const meters = WebMercator.project(tokyo); // { x, y } เป็นเมตร
const back = WebMercator.unproject(meters);
const tile = WGS84.project(tokyo); // พิกัดไทล์ 0 ถึง 256เมื่อต้องการแปลงพิกเซลบนหน้าจอและพิกัดร่วมกัน โปรดใช้ `toScreenOffset` / `fromScreenOffset` ของ `MapViewHolder` แทนการฉายภาพ จะสะท้อนความเอียงและการหมุนจริงของกล้องที่แสดงอยู่
03 · การแปลงระหว่างการซูมและระดับความสูง
ผู้ให้บริการระบบกระเบื้อง 2D ใช้ระดับการซูม ส่วนระบบ 3D ใช้ระดับความสูงของกล้องหรือระยะการมองเห็นเพื่อแสดงสเกล MapConductor แปลงทั้งสองนี้ระหว่างกัน และแสดงให้แอปเห็นในสเกลการซูมเดียวกันเสมอ การแปลงถูกนำไปใช้สำหรับแต่ละผู้ให้บริการในรูปแบบคลาสหนึ่งที่สืบทอดจากคลาสนามธรรมทั่วไป
การแปลงรวมถึงละติจูดและความเอียง เนื่องจาก Web Mercator ขยายแผนที่มากขึ้นในละติจูดสูง ดังนั้นแม้ว่าจะซูมเท่ากัน ระดับความสูงของกล้องที่จำเป็นที่เส้นศูนย์สูตรและในละติจูดสูงจะแตกต่างกันหลายเท่า
abstract class AbstractZoomAltitudeConverter(
protected val zoom0Altitude: Double,
) {
abstract fun zoomLevelToAltitude(zoomLevel: Double, latitude: Double, tilt: Double): Double
abstract fun altitudeToZoomLevel(altitude: Double, latitude: Double, tilt: Double): Double
}public protocol ZoomAltitudeConverterProtocol {
var zoom0Altitude: Double { get }
func zoomLevelToAltitude(zoomLevel: Double, latitude: Double, tilt: Double) -> Double
func altitudeToZoomLevel(altitude: Double, latitude: Double, tilt: Double) -> Double
}export abstract class AbstractZoomAltitudeConverter {
constructor(protected readonly zoom0Altitude: number =
AbstractZoomAltitudeConverter.DEFAULT_ZOOM0_ALTITUDE) {}
abstract zoomLevelToAltitude(params: { zoomLevel: number; latitude: number; tilt: number }): number;
abstract altitudeToZoomLevel(params: { altitude: number; latitude: number; tilt: number }): number;
}แต่ละแพ็กเกจของผู้ให้บริการมีตัวแปลง (`ZoomAltitudeConverter`) แอปไม่จำเป็นต้องเรียกโดยตรง แต่สามารถใช้ได้เมื่อสร้างการแสดงผล 3D ของคุณเอง
// The same camera position handed to both states
val shared = MapCameraPosition(
position = GeoPoint.fromLatLong(35.6812, 139.7671),
zoom = 14.0,
)
val maplibre = rememberMapLibreMapViewState(cameraPosition = shared)
val googlemaps = rememberGoogleMapViewState(cameraPosition = shared)
// Move one and the same value goes to the other
Row {
MapLibreMapView(
state = maplibre,
modifier = Modifier.weight(1f),
onCameraMoveEnd = { googlemaps.moveCameraTo(it) },
)
GoogleMapView(
state = googlemaps,
modifier = Modifier.weight(1f),
onCameraMoveEnd = { maplibre.moveCameraTo(it) },
)
}04 · ค่าขีดจำกัด
ค่าคงที่ที่ใช้สำหรับการแปลง เพื่อป้องกันสูตรไม่เป็นอนันต์ใกล้ขั้วหรือมุมมองจากด้านบน จึงกำหนดค่าต่ำสุดของ `cos` ไว้เป็นค่าคงที่
ระดับความสูงอ้างอิงที่ `zoom` 0 ไม่ใช่ค่าที่ตั้งขึ้นจากทฤษฎีเพียงอย่างเดียว เป็นผลจากการสอบเทียบโดยวัดช่วงที่มองเห็นจริงในแต่ละเอ็นจิ้นเมื่อระบุซูมเดียวกัน เพื่อให้พื้นที่ตรงกัน ค่าคงที่เพียงอย่างเดียวคือความสัมพันธ์ที่ว่าระดับความสูงจะลดลงครึ่งหนึ่งต่อขั้นซูม (`ZOOM_FACTOR = 2`) และค่าอ้างอิงนี้