Documentación / Core / Proyección y zoom

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.

ELLIPSOID
WGS84
PROJECTIONS
WebMercator · WGS84
ZOOM RANGE
0 – 22
Plataforma

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.

Constante
Valor
Descripción
RADIUS_METERS
6 378 137.0
Semieje mayor (radio ecuatorial) de WGS84.
CIRCUMFERENCE_METERS
2πa
Circunferencia completa del ecuador. Se utiliza para el cálculo de la resolución de mosaicos.
FLATTENING
1 / 298.257223563
Achatamiento. Se utiliza en los cálculos geodésicos del modelo elipsoidal.
SEMI_MINOR_AXIS_METERS
a(1 − f)
Semieje menor (radio polar).
ECCENTRICITY_SQUARED
f(2 − f)
Cuadrado de la primera excentricidad numérica.
WEB_MERCATOR_MAX_EXTENT_METERS
πa ≈ 20 037 508.34
Valor máximo posible para las coordenadas de Web Mercator. Las x e y proyectadas se encuentran dentro de este rango.

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.

WebMercator

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.

WGS84

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.

com.mapconductor.core.projection
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

Cuando 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.

Fig. · Altitud de cámara necesaria con el mismo valor de zoom (relación, ecuador = 1)
0° · Ecuador
×1.00
30° · El Cairo
×0.87
35° · Tokio
×0.82
Incluso con `zoom` 14, lo está viendo desde una posición aproximadamente un 20 % más baja que en el ecuador.
60° · Oslo
×0.50
70° · Tromsø
×0.34
La diferencia con el ecuador es de aproximadamente 3 veces. Si alinea solo la altitud e ignora la latitud, el rango visible se desplaza hasta aquí.
AbstractZoomAltitudeConverter · Kotlin
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
}

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.

Ver la implementación en video · Android + MapLibreKotlin · Jetpack Compose
// 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) },
    )
}
Video de ejemplo · Comparar el mismo valor de zoom entre proveedores
Video aún no grabadoCambiar de proveedor manteniendo el mismo `zoom` y mostrar cuánto se desvía la escala real.

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.

DEFAULT_ZOOM0_ALTITUDE
171,319,879 m
ZOOM_FACTOR
2.0
MIN / MAX_ZOOM_LEVEL
0.0 / 22.0
MIN / MAX_ALTITUDE
100 / 50,000,000 m
MIN_COS_LAT
0.01
MIN_COS_TILT
0.05
WEB_MERCATOR_INITIAL_MPP_256
156,543.033928
TILE SIZE
256 px

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.

Páginas relacionadas