GroundImage — Colocar una imagen en el mapa
Defina un rango con dos puntos (suroeste y noreste) y coloque ahí una sola imagen. Planos de planta de instalaciones, mapas antiguos, fotografías aéreas, mapas de coropletas personalizados, etc.: las imágenes que no están en mosaico se pueden superponer directamente en el mapa. El rango y la transparencia se pueden modificar más tarde; la imagen permanece pegada al suelo siguiendo las operaciones de la cámara y se muestra accordingly.
01 · Estado de GroundImage
GroundImageState representa una sola imagen. Tiene un rango, una imagen, una opacidad y un controlador de toque. Puede pasar la imagen de la forma natural para cada plataforma (Android usa Drawable, iOS usa UIImage, Web usa una URL).
val groundImageState =
GroundImageState(
id = "groundImage",
bounds =
GeoRectBounds(
southWest = southWestPosition,
northEast = northEastPosition,
),
image = drawable, // Pasa el Drawable tal cual
opacity = 0.5f,
onClick = this::onGroundImageClick,
)
GroundImage(groundImageState)let groundImageState = GroundImageState(
bounds: GeoRectBounds(southWest: southWest, northEast: northEast),
image: resources.image, // Pasa el UIImage tal cual
opacity: 0.5,
id: "groundImage"
)
content.groundImages = [GroundImage(state: groundImageState)]const image = createGroundImageState({
id: 'ground-image',
bounds: createGeoRectBounds({ southWest, northEast }),
imageUrl: GROUND_IMAGE_URL, // Pásalo como URL
opacity,
onClick: () => showToast('Ground image clicked.'),
});
<GroundImage state={image} />02 · Rango y opacidad
El rango es un rectángulo. Si la relación de aspecto de la imagen y la del rango son diferentes, la imagen se estirará para ajustarse al rango, así que especifique un rango que coincida con la relación de aspecto del dibujo que desea colocar. El rango, la opacidad y la imagen se pueden cambiar más tarde y los cambios se reflejarán en el renderizado en ese momento.
Recrear el rango arrastrando
Si reemplaza bounds mientras arrastra dos marcadores, la imagen seguirá. Sin embargo, la capacidad de seguimiento de actualizaciones continuas varía según el proveedor.
Superponer con el mapa base
Si reduce la opacidad, se verán las carreteras y los nombres de lugares del mapa inferior. Dependiendo del motor, puede haber limitaciones en el momento y la forma en que se aplican los cambios.

// Arrastra los marcadores de las esquinas para rehacer los límites
override fun onMarkerDrag(dragged: MarkerState) {
when (dragged.id) {
"south_west" -> southWestPosition = GeoPoint.from(dragged.position)
"north_east" -> northEastPosition = GeoPoint.from(dragged.position)
}
bounds = GeoRectBounds(southWest = southWestPosition, northEast = northEastPosition)
}
// La opacidad es una simple asignación
groundImageState.opacity = sliderOpacityfunc setOpacity(_ value: Double) {
opacity = value
groundImageState.opacity = value
}
// Rehaz los límites conforme se arrastra el marcador
groundImageState.bounds = GeoRectBounds(southWest: sw, northEast: ne)// Mientras arrastras, escribe directo en el objeto de estado en vez de esperar un re-render
const applyGeometry = (sw: GeoPoint, ne: GeoPoint) => {
image.bounds = createGeoRectBounds({ southWest: sw, northEast: ne });
polylineState.points = framePoints(sw, ne);
};
image.opacity = opacity;03 · Verse igual en todos los proveedores
GroundImage es la función con la mayor diferencia de implementación entre los controladores de los SDK de mapas. El mecanismo de superposición de imágenes varía mucho según el motor y algunos no tienen una funcionalidad equivalente. MapConductor absorbe esta diferencia en la medida de lo posible, pero algunos proveedores pueden tener restricciones en los cambios dinámicos.
Mismo rango, mismo estiramiento
La imagen se ubica de acuerdo con el rango especificado. Sin importar las diferencias en el sistema de coordenadas de superposición de imágenes del motor, se muestra en la misma posición y con el mismo tamaño.
Dibujar primero con funciones nativas
Cada controlador dibuja de manera óptima utilizando, siempre que sea posible, las funciones de superposición de imágenes específicas de ese SDK de mapas (por ejemplo, MediaLayer + ImageElement para ArcGIS, material de imagen de Rectangle para Cesium, etc.). Solo para motores que inevitablemente no tienen una función equivalente, se recortan las imágenes y se suministran como mosaicos, superponiéndolas como una capa ráster. El código de la aplicación no cambia en ninguna de las dos rutas.
Limitaciones según el proveedor
La recreación del rango (actualización continua mientras se arrastra) o el cambio de opacidad pueden ser limitados debido a restricciones del motor. La colocación estática es la misma en todos los proveedores, pero para usos que cambian dinámicamente, se recomienda verificarlo en el proveedor objetivo.
La detección de toques también es común
Dado que la detección de toques se realiza con una lógica común, se llamará a onClick independientemente de si el motor es compatible con toques en superposiciones de imágenes.
04 · Toque
onClick recibe el estado de la imagen y las coordenadas tocadas. En el ejemplo, se reemplaza la imagen misma al tocar para cambiar la visualización.
// Cambia la imagen al tocar
override fun onGroundImageClick(clicked: GroundImageEvent) {
val isBase = clicked.state.image == imageResources.image
image = if (isBase) imageResources.clickedImage else imageResources.image
}private func onGroundImageClick(_ event: GroundImageEvent) {
let isBase = groundImageState.image === resources.image
groundImageState.image = isBase ? resources.clickedImage : resources.image
}createGroundImageState({
bounds,
imageUrl,
onClick: event => showToast(event.clicked),
});El estado de la imagen tocada. Se puede hacer referencia a la imagen actual y extra.
Las coordenadas geográficas tocadas. Puede saber qué parte dentro del rango se presionó.
Las partes transparentes de la imagen también se incluyen en el área táctil. Si no quiere que las partes transparentes reaccionen, ajuste el área al cuerpo real de la imagen o use un polígono además.