Projektion und Zoom
Projektion ist das Abbilden der runden Erde auf einen flachen Bildschirm, Zoom gibt an, wie weit herangezoomt ist. Obwohl die Definitionen für beides je nach Anbieter variieren, nutzt MapConductor dieselben Konstanten und dieselben Formeln auf 3 Plattformen und richtet die veröffentlichten Werte an einem Maßstab aus. Die Verwendung der Kamera finden Sie auf der Kamera-Seite, hier werden die darunterliegenden numerischen Werte behandelt.
01 · Konstanten der Erde
Projektion, geodätische Berechnung und Kachelberechnung beziehen sich alle auf die Konstanten von Earth.
02 · Projektion
Der Projektionstyp besitzt nur die beiden Methoden `project` und `unproject`. Es handelt sich um eine symmetrische Operation, bei der Koordinaten in ebene Koordinaten (`Offset`) projiziert und wieder zurückverwandelt werden. Es sind zwei Implementierungen verfügbar.
Web-Mercator in Metern
Projiziert auf eine Ebene von ±20,037,508.34 m, identisch mit EPSG:3857. Wird für Berechnungen von Kachelgrenzen und zur Umrechnung von Bildschirmabständen in Meter verwendet.
256-Pixel-Kachelkoordinaten
Projiziert in ein Koordinatensystem, das auf einer einzigen Kachel bei Zoom 0 (256×256) basiert. Ein Koordinatensystem, das von Renderern zur Generierung von Kachelbildern verwendet wird.
interface ProjectionInterface {
fun project(position: GeoPointInterface): Offset
fun unproject(point: Offset): GeoPointInterface
}
val meters = WebMercator.project(tokyo) // x und y sind in Metern
val tile = WGS84.project(tokyo) // Kachelkoordinaten von 0 bis 256// Unter iOS steckt die Projektion in der Implementierung von Kacheln und räumlichem Index. // Für die Umrechnung Koordinate ⇄ Bildschirm aus der App MapViewHolder verwenden. 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 } sind in Metern
const back = WebMercator.unproject(meters);
const tile = WGS84.project(tokyo); // Kachelkoordinaten von 0 bis 256Wenn eine gegenseitige Umrechnung von Bildschirmpixeln und Koordinaten erforderlich ist, verwenden Sie bitte `toScreenOffset` / `fromScreenOffset` von `MapViewHolder` statt der Projektion. Die tatsächliche Kameraneigung und -drehung werden dabei berücksichtigt.
03 · Umrechnung zwischen Zoom und Höhe
2D-Kachelanbieter verwenden den Zoom-Level, 3D-Anbieter verwenden die Kamerahöhe oder den Betrachtungsabstand für den Maßstab. MapConductor rechnet diese beiden Werte gegeneinander um und zeigt der App immer denselben Zoom-Maßstab an. Die Umrechnung wird für jeden Anbieter in einer Klasse implementiert, die eine gemeinsame abstrakte Klasse erbt.
Die Umrechnung bezieht Breitengrad und Neigung ein. Web Mercator vergrößert die Karte in hohen Breitengraden, sodass selbst bei gleichem Zoom die erforderliche Kamerahöhe am Äquator und in hohen Breitengraden um ein Vielfaches differs.
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;
}Jedes Anbieterpaket enthält einen Konverter (`ZoomAltitudeConverter`). Die App muss ihn nicht direkt aufrufen, aber er kann verwendet werden, wenn Sie eine eigene 3D-Darstellung erstellen.
// 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 · Grenzwerte
Konstanten, die für die Umrechnung verwendet werden. Damit die Formeln in der Nähe der Pole und bei der Draufsicht nicht divergieren, wurde auch eine Untergrenze für `cos` als Konstante festgelegt.
Die Referenzhöhe bei `zoom` 0 ist kein rein theoretischer Wert. Es ist das Ergebnis einer Kalibrierung, bei der der tatsächlich sichtbare Bereich für jede Engine gemessen wurde, wenn der gleiche Zoom angegeben wurde, sodass die Flächen übereinstimmen. Einzige Konstanten sind die Beziehung, dass sich die Höhe pro Zoomstufe halbiert (`ZOOM_FACTOR = 2`), und dieser Referenzwert.