Skip to content

GeoRectBounds

GeoRectBounds representa un área geográfica rectangular definida por dos esquinas: suroeste y noreste. Se utiliza para definir regiones de mapa, límites de imágenes de tipo ground image y para cálculos de viewport.

class GeoRectBounds(
southWest: GeoPoint? = null,
northEast: GeoPoint? = null
)
  • southWest: GeoPoint?: esquina suroeste (inferior izquierda) del rectángulo.
  • northEast: GeoPoint?: esquina noreste (superior derecha) del rectángulo.
  • isEmpty: Boolean: devuelve true si los límites no están definidos.
  • center: GeoPoint?: punto central de los límites.
  • toSpan(): GeoPoint?: devuelve el “span” (ancho/alto) como un GeoPointInterface.
fun contains(point: GeoPointInterface): Boolean
// Usage
val bounds = GeoRectBounds(
southWest = GeoPoint.fromLatLong(37.7649, -122.4294),
northEast = GeoPoint.fromLatLong(37.7849, -122.4094)
)
val testPoint = GeoPoint.fromLatLong(37.7749, -122.4194)
val isInside = bounds.contains(testPoint)
println("Point is inside bounds: $isInside")
fun intersects(other: GeoRectBounds): Boolean
// Usage
val bounds1 = GeoRectBounds(/* ... */)
val bounds2 = GeoRectBounds(/* ... */)
val doIntersect = bounds1.intersects(bounds2)
println("Bounds intersect: $doIntersect")
@Composable
fun ViewportBoundsExample() {
var viewportBounds by remember { mutableStateOf<GeoRectBounds?>(null) }
// Calcular el viewport a partir de los marcadores visibles
val markers = remember {
listOf(
GeoPoint.fromLatLong(37.7749, -122.4194),
GeoPoint.fromLatLong(37.7849, -122.4094),
GeoPoint.fromLatLong(37.7649, -122.4294),
GeoPoint.fromLatLong(37.7949, -122.3994)
)
}
LaunchedEffect(markers) {
val bounds = GeoRectBounds()
markers.forEach { marker ->
bounds.extend(marker)
}
viewportBounds = bounds
}
// Sustituye MapView por el proveedor de mapas que prefieras, como GoogleMapView o MapboxMapView
MapView(state = mapViewState) {
// Show all markers
markers.forEach { position ->
Marker(
position = position,
icon = DefaultIcon(fillColor = Color.Blue)
)
}
// Show viewport bounds as a polygon
viewportBounds?.let { bounds ->
if (!bounds.isEmpty) {
val sw = bounds.southWest!!
val ne = bounds.northEast!!
val boundsPolygon = listOf(
sw,
GeoPoint.fromLatLong(sw.latitude, ne.longitude),
ne,
GeoPoint.fromLatLong(ne.latitude, sw.longitude),
sw // Close the polygon
)
Polygon(
points = boundsPolygon,
strokeColor = Color.Red,
strokeWidth = 2.dp,
fillColor = Color.Red.copy(alpha = 0.1f)
)
}
}
}
}
@Composable
fun BoundsBasedLoadingExample() {
var currentBounds by remember { mutableStateOf<GeoRectBounds?>(null) }
var markersInBounds by remember { mutableStateOf<List<GeoPoint>>(emptyList()) }
// Simular todos los marcadores disponibles
val allMarkers = remember {
List(100) { i ->
GeoPoint.fromLatLong(
37.7 + (i % 10) * 0.01,
-122.5 + (i / 10) * 0.01
)
}
}
// Filter markers based on current bounds
LaunchedEffect(currentBounds) {
markersInBounds = currentBounds?.let { bounds ->
if (bounds.isEmpty) {
emptyList()
} else {
allMarkers.filter { marker ->
bounds.contains(marker)
}
}
} ?: emptyList()
}
Column {
Text("Markers in bounds: ${markersInBounds.size}/${allMarkers.size}")
Button(
onClick = {
// Simular el establecimiento de los límites del viewport
currentBounds = GeoRectBounds(
southWest = GeoPoint.fromLatLong(37.7, -122.5),
northEast = GeoPoint.fromLatLong(37.75, -122.45)
)
}
) {
Text("Set Viewport")
}
// Sustituye MapView por el proveedor de mapas que prefieras, como GoogleMapView o MapboxMapView
MapView(state = mapViewState) {
// Show only markers within bounds
markersInBounds.forEach { position ->
Marker(
position = position,
icon = DefaultIcon(
fillColor = Color.Green,
scale = 0.8f
)
)
}
// Show current bounds
currentBounds?.let { bounds ->
if (!bounds.isEmpty) {
val sw = bounds.southWest!!
val ne = bounds.northEast!!
Polygon(
points = listOf(
sw,
GeoPoint.fromLatLong(sw.latitude, ne.longitude),
ne,
GeoPoint.fromLatLong(ne.latitude, sw.longitude),
sw
),
strokeColor = Color.Blue,
strokeWidth = 3.dp,
fillColor = Color.Blue.copy(alpha = 0.1f)
)
}
}
}
}
}
@Composable
fun BoundsEditorExample() {
var bounds by remember {
mutableStateOf(
GeoRectBounds(
southWest = GeoPoint.fromLatLong(37.7649, -122.4294),
northEast = GeoPoint.fromLatLong(37.7849, -122.4094)
)
)
}
val onCornerDrag: (MarkerState) -> Unit = { markerState ->
val newPosition = markerState.position
when (markerState.extra) {
"SW" -> {
bounds = GeoRectBounds(
southWest = newPosition as GeoPoint,
northEast = bounds.northEast
)
}
"NE" -> {
bounds = GeoRectBounds(
southWest = bounds.southWest,
northEast = newPosition as GeoPoint
)
}
}
}
// Sustituye MapView por el proveedor de mapas que prefieras, como GoogleMapView o MapboxMapView
MapView(
state = mapViewState
) {
// Bounds visualization
if (!bounds.isEmpty) {
val sw = bounds.southWest!!
val ne = bounds.northEast!!
// Bounds rectangle
Polygon(
points = listOf(
sw,
GeoPoint.fromLatLong(sw.latitude, ne.longitude),
ne,
GeoPoint.fromLatLong(ne.latitude, sw.longitude),
sw
),
strokeColor = Color.Red,
fillColor = Color.Red.copy(alpha = 0.2f)
)
// Corner markers
Marker(
position = sw,
icon = DefaultIcon(
fillColor = Color.Green,
label = "SW"
),
draggable = true,
extra = "SW",
onDrag = onCornerDrag
)
Marker(
position = ne,
icon = DefaultIcon(
fillColor = Color.Red,
label = "NE"
),
draggable = true,
extra = "NE",
onDrag = onCornerDrag
)
}
}
}

GeoRectBounds maneja rectángulos que cruzan la línea internacional de cambio de fecha (longitud ±180°):

// Bounds crossing the date line
val pacificBounds = GeoRectBounds(
southWest = GeoPoint.fromLatLong(20, 170), // West of date line
northEast = GeoPoint.fromLatLong(40, -170) // East of date line
)
val pointInPacific = GeoPoint.fromLatLong(30, 175)
val containsPoint = pacificBounds.contains(pointInPacific) // true
val emptyBounds = GeoRectBounds()
println(emptyBounds.isEmpty) // true
println(emptyBounds.center) // null
println(emptyBounds.toSpan()) // null
// Extending empty bounds
emptyBounds.extend(GeoPoint.fromLatLong(37.7749, -122.4194))
println(emptyBounds.isEmpty) // false
// For debugging
val bounds = GeoRectBounds(
southWest = GeoPoint.fromLatLong(37.7649, -122.4294),
northEast = GeoPoint.fromLatLong(37.7849, -122.4094)
)
println(bounds.toString())
// Output: ((37.7649, -122.4294), (37.7849, -122.4094))
fun toUrlValue(precision: Int = 6): String
// Usage for API calls
val urlString = bounds.toUrlValue() // "37.764900,-122.429400,37.784900,-122.409400"
val preciseString = bounds.toUrlValue(precision = 8)
fun equalsTo(other: GeoRectBounds): Boolean
// Uso
val bounds1 = GeoRectBounds(/* ... */)
val bounds2 = GeoRectBounds(/* ... */)
val areEqual = bounds1.equalsTo(bounds2)