Proyección y zoom
La proyección es proyectar la Tierra redonda en una pantalla plana y el zoom indica qué tan cerca se está. Aunque las definiciones de ambas varían según el proveedor, MapConductor comparte las mismas constantes y las mismas fórmulas en 3 plataformas y alinea los valores publicados en una sola escala. El uso de la cámara se encuentra en la página de la cámara; aquí se tratan los valores numéricos subyacentes.
01 · Constantes de la Tierra
La proyección, el cálculo geográfico y el cálculo de mosaicos hacen referencia a las constantes de Earth.
02 · Proyección
El tipo de proyección solo tiene dos métodos: `project` y `unproject`. Es una operación simétrica que proyecta coordenadas en coordenadas planas (`Offset`) y las devuelve. Hay dos implementaciones disponibles.
Web Mercator en metros
Se proyecta en un plano de ±20,037,508.34 m, igual que EPSG:3857. Se usa para el cálculo de los límites de los mosaicos y para convertir distancias en pantalla a metros.
Coordenadas de mosaico de 256 píxeles
Se proyecta en un sistema de coordenadas basado en un solo mosaico en el nivel de zoom 0 (256×256). Es el sistema de coordenadas que usan los procesadores para generar imágenes de mosaicos.
interface ProjectionInterface {
fun project(position: GeoPointInterface): Offset
fun unproject(point: Offset): GeoPointInterface
}
val meters = WebMercator.project(tokyo) // x e y están en metros
val tile = WGS84.project(tokyo) // Coordenadas de mosaico de 0 a 256// En iOS la proyección vive dentro de la implementación de mosaicos e índice espacial. // Para convertir coordenada ⇄ pantalla desde la app, usa 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 } están en metros
const back = WebMercator.unproject(meters);
const tile = WGS84.project(tokyo); // Coordenadas de mosaico de 0 a 256Cuando sea necesaria la conversión mutua entre píxeles de pantalla y coordenadas, utilice `toScreenOffset` / `fromScreenOffset` de `MapViewHolder` en lugar de la proyección. Se reflejará la inclinación y rotación reales de la cámara que se muestra.
03 · Conversión entre zoom y altitud
Los proveedores de mosaicos 2D usan el nivel de zoom, mientras que los sistemas 3D usan la altitud de la cámara o la distancia de visualización para la escala. MapConductor convierte ambos entre sí y siempre muestra a la app la misma escala de zoom. La conversión se implementa por proveedor en una clase que hereda de una clase abstracta común.
La conversión incluye latitud e inclinación. Web Mercator amplifica el mapa en latitudes altas, por lo que, incluso con el mismo zoom, la altitud de cámara necesaria en el ecuador y en latitudes altas difiere varias veces.
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;
}El paquete de cada proveedor tiene un convertidor (`ZoomAltitudeConverter`). La app no necesita llamarlo directamente, pero puede usarse al crear una representación 3D personalizada.
// 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 · Valores límite
Constantes utilizadas para la conversión. Para evitar que las fórmulas diverjan cerca de los polos y en la vista cenital, se ha establecido un límite inferior para `cos` como constante.
La altitud de referencia para `zoom` 0 no es un valor puramente teórico. Es el resultado de calibrar midiendo el rango realmente visible en cada motor cuando se especifica el mismo zoom, de modo que las áreas coincidan. Las únicas constantes son la relación de que la altura se reduce a la mitad por cada paso de zoom (`ZOOM_FACTOR = 2`) y este valor de referencia.