Circle
Los círculos son superposiciones circulares que se pueden dibujar en el mapa con propiedades de radio, trazo y relleno personalizables. Son útiles para representar áreas, rangos o zonas.
Funciones Composable
Section titled “Funciones Composable”Cuando tienes pocos círculo, especificar opciones directamente es más fácil.
Especificar id puede reducir Recomposiciones innecesarias.
@Composablefun MapViewScope.Circle( center: GeoPointInterface, radiusMeters: Double, geodesic: Boolean = false, strokeColor: Color = Color.Red, strokeWidth: Dp = 2.dp, fillColor: Color = Color.White.copy(alpha = 0.5f), extra: Serializable? = null, id: String? = null)Cuando tienes muchos círculo o necesitas mover círculo, se recomienda usar este enfoque.
Especificar id puede reducir Recomposiciones innecesarias.
CircleState( center: GeoPointInterface, radiusMeters: Double, geodesic: Boolean = false, strokeColor: Color = Color.Red, strokeWidth: Dp = 2.dp, fillColor: Color = Color.White.copy(alpha = 0.5f), extra: Serializable? = null, id: String? = null)
@Composablefun MapViewScope.Circle(state: CircleState)Parámetros
Section titled “Parámetros”center: Punto geográfico central del círculo (GeoPointInterface)radiusMeters: Radio en metros (Double)geodesic: Si se debe dibujar el círculo usando bordes geodésicos que sigan la curvatura de la Tierra (predeterminado:false)strokeColor: Color del borde del círculo (predeterminado:Color.Red)strokeWidth: Ancho de la línea del borde (predeterminado:2.dp)fillColor: Color de relleno del interior del círculo (predeterminado: blanco semi-transparente)extra: Datos adicionales adjuntos al círculo (Serializable?)id: Identificador único para el círculo (String?)
Ejemplos de Uso
Section titled “Ejemplos de Uso”Círculo Básico
Section titled “Círculo Básico”// Reemplace MapView con su proveedor de mapas elegido, como GoogleMapView, MapboxMapViewMapView(state = mapViewState) { Circle( center = GeoPoint.fromLatLong(37.7749, -122.4194), radiusMeters = 1000.0, // 1km radius strokeColor = Color.Blue, fillColor = Color.Blue.copy(alpha = 0.3f), id = "downtown-area" )}Círculo Interactivo con Marcadores
Section titled “Círculo Interactivo con Marcadores”Según el patrón de la aplicación de ejemplo, aquí se muestra cómo crear un círculo interactivo con marcadores arrastrables:
@Composablefun InteractiveCircleExample() { var centerPosition by remember { mutableStateOf(GeoPoint.fromLatLong(37.7749, -122.4194)) } var radiusMeters by remember { mutableStateOf(1000.0) }
// Calculate edge marker position val edgePosition = remember(centerPosition, radiusMeters) { // Calculate a point that's 'radiusMeters' meters away from center // Esto está simplificado - el cálculo real consideraría la curvatura de la Tierra val latOffset = radiusMeters / 111000.0 // Rough meters per degree latitude GeoPoint.fromLatLong( centerPosition.latitude + latOffset, centerPosition.longitude ) }
val circleState = CircleState( center = centerPosition, radiusMeters = radiusMeters, strokeColor = Color.Blue, fillColor = Color.Blue.copy(alpha = 0.3f), clickable = true, onClick = { circleEvent -> println("Circle clicked at: ${circleEvent.clicked}") } )
val centerMarker = MarkerState( position = centerPosition, icon = DefaultIcon( fillColor = Color.Blue, label = "C" ), draggable = false )
val edgeMarker = MarkerState( position = edgePosition, icon = DefaultIcon( fillColor = Color.Green, label = "E" ), draggable = true, onDrag = { markerState -> // Calculate new radius based on edge marker position val distance = calculateDistance(centerPosition, markerState.position) radiusMeters = distance } )
// Reemplace MapView con su proveedor de mapas elegido, como GoogleMapView, MapboxMapView MapView( state = mapViewState ) { Circle(circleState) Marker(centerMarker) Marker(edgeMarker) }}Actualizaciones Dinámicas de Círculo
Section titled “Actualizaciones Dinámicas de Círculo”@Composablefun DynamicCircleExample() { var circleRadius by remember { mutableStateOf(500.0) } var circleColor by remember { mutableStateOf(Color.Blue) }
Column { // Controls Slider( value = circleRadius.toFloat(), onValueChange = { circleRadius = it.toDouble() }, valueRange = 100f..2000f, modifier = Modifier.padding(16.dp) )
Row { Button(onClick = { circleColor = Color.Red }) { Text("Red") } Button(onClick = { circleColor = Color.Blue }) { Text("Blue") } Button(onClick = { circleColor = Color.Green }) { Text("Green") } }
// Map with dynamic circle // Reemplace MapView con su proveedor de mapas elegido, como GoogleMapView, MapboxMapView MapView(state = mapViewState) { Circle( center = GeoPoint.fromLatLong(37.7749, -122.4194), radiusMeters = circleRadius, strokeColor = circleColor, fillColor = circleColor.copy(alpha = 0.3f) )
// Center marker Marker( position = GeoPoint.fromLatLong(37.7749, -122.4194), icon = DefaultIcon( fillColor = circleColor, label = "${circleRadius.toInt()}m" ) ) } }}Manejo de Eventos
Section titled “Manejo de Eventos”Las interacciones de círculo se manejan con su componente de proveedor de mapas:
// Reemplace MapView con su proveedor de mapas elegido, como GoogleMapView, MapboxMapViewMapView( state = mapViewState) { Circle( center = GeoPoint.fromLatLong(37.7749, -122.4194), radiusMeters = 1000.0, clickable = true, extra = "Clickable circle", onClick = { circleEvent -> val circle = circleEvent.state val clickPoint = circleEvent.clicked
println("Circle clicked:") println(" Center: ${circle.center}") println(" Radius: ${circle.radiusMeters}m") println(" Click point: ${clickPoint}") println(" Extra data: ${circle.extra}") } )}Opciones de Estilo
Section titled “Opciones de Estilo”Estilos de Trazo
Section titled “Estilos de Trazo”// Thin borderCircle( center = center, radiusMeters = 500.0, strokeColor = Color.Black, strokeWidth = 1.dp)
// Thick borderCircle( center = center, radiusMeters = 500.0, strokeColor = Color.Black, strokeWidth = 5.dp)
// No borderCircle( center = center, radiusMeters = 500.0, strokeColor = Color.Transparent, strokeWidth = 0.dp)Estilos de Relleno
Section titled “Estilos de Relleno”// Solid fillCircle( center = center, radiusMeters = 500.0, fillColor = Color.Red)
// Semi-transparent fillCircle( center = center, radiusMeters = 500.0, fillColor = Color.Red.copy(alpha = 0.5f))
// No fillCircle( center = center, radiusMeters = 500.0, fillColor = Color.Transparent)Identificación de Círculo
Section titled “Identificación de Círculo”Uso de la Propiedad ID
Section titled “Uso de la Propiedad ID”La propiedad id proporciona un identificador único para círculos, permitiendo un seguimiento y gestión eficientes:
@Composablefun CircleIdentificationExample() { val mapViewState = rememberGoogleMapViewState()
// Use ID in event handling val onCircleClick: OnCircleEventHandler = { circleEvent -> when (circleEvent.state.id) { "zone-a" -> handleZoneA() "zone-b" -> handleZoneB() else -> handleUnknownZone() } }
// Create circles with unique IDs val circles = listOf( CircleState( center = GeoPoint.fromLatLong(37.7749, -122.4194), radiusMeters = 1000.0, strokeColor = Color.Red, fillColor = Color.Red.copy(alpha = 0.3f), id = "zone-a", onClick = onCircleClick ), CircleState( center = GeoPoint.fromLatLong(37.7849, -122.4094), radiusMeters = 1500.0, strokeColor = Color.Blue, fillColor = Color.Blue.copy(alpha = 0.3f), id = "zone-b", onClick = onCircleClick ) )
MapView( state = mapViewState ) { circles.forEach { circle -> Circle(circle) } }}
private fun handleZoneA() { println("Zone A clicked")}
private fun handleZoneB() { println("Zone B clicked")}
private fun handleUnknownZone() { println("Unknown zone clicked")}Beneficios del Uso de IDs
Section titled “Beneficios del Uso de IDs”- Identificación Única: Distinguir entre círculos incluso cuando tienen propiedades similares
- Manejo de Eventos: Simplifica el manejo de eventos de clic y la lógica específica de área
- Gestión del Estado: Permite actualizaciones eficientes y gestión de selección
- Rendimiento: Facilita la renderización y actualizaciones optimizadas
Manejo de Eventos Detallado
Section titled “Manejo de Eventos Detallado”Ejemplo detallado de manejo de eventos de clic de círculo:
@Composablefun CircleClickEventExample() { val mapViewState = rememberGoogleMapViewState()
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapView MapView( state = mapViewState ) { Circle( center = GeoPoint.fromLatLong(37.7749, -122.4194), radiusMeters = 1000.0, clickable = true, extra = "Clickable circle", onClick = { circleEvent -> val circle = circleEvent.state val clickPoint = circleEvent.clicked
println("Circle clicked:") println(" Center: ${circle.center}") println(" Radius: ${circle.radiusMeters}m") println(" Click point: ${clickPoint}") println(" Extra data: ${circle.extra}") } ) }}Mejores Prácticas
Section titled “Mejores Prácticas”- Use Radio Apropiado: Considere el nivel de zoom del mapa al establecer el radio del círculo
- Proporcione IDs Únicos: Siempre establezca valores
idúnicos al trabajar con múltiples círculos - Contraste de Color: Asegure que los colores de trazo y relleno proporcionen buena visibilidad en el mapa
- Rendimiento: Evite crear demasiados círculos grandes ya que pueden impactar el rendimiento de renderización
- Retroalimentación Interactiva: Proporcione retroalimentación visual cuando los círculos sean clickeables
- Estilo Consistente: Mantenga un estilo de círculo consistente en su aplicación
- Datos Adicionales: Utilice el parámetro
extrapara almacenar metadatos para manejo de eventos - Gestión de Z-Index: Considere el orden de dibujo cuando los círculos se superponen