Saltar al contenido

Dibuja círculos de tamaño constante en la pantalla en Google Maps API v2

Basta ya de buscar por todo internet ya que estás al espacio indicado, poseemos la solución que deseas sin liarte.

Solución:

Probablemente no le importe realmente el tamaño de píxel exacto, solo que se ve igual para todos los niveles de zoom y rotaciones del dispositivo.

Aquí hay una manera bastante simple de hacer esto. Dibuje (y vuelva a dibujar si se cambia el zoom) un círculo cuyo radio sea un porcentaje de la diagonal de la pantalla visible.

La API de Google Maps v2 tiene un getProjection() función que devolverá las coordenadas de latitud/longitud de las 4 esquinas de la pantalla visible. Luego, usando el súper conveniente Location clase, puede calcular la distancia de la diagonal de lo que se ve en la pantalla y usar un porcentaje de esa diagonal como el radio de su círculo. Su círculo tendrá el mismo tamaño sin importar la escala de zoom o la forma en que se gire el dispositivo.

Aquí está el código en Java:

public Circle drawMapCircle(GoogleMap googleMap,LatLng latLng,Circle currentCircle) 

    // get 2 of the visible diagonal corners of the map (could also use farRight and nearLeft)
    LatLng topLeft = googleMap.getProjection().getVisibleRegion().farLeft;
    LatLng bottomRight = googleMap.getProjection().getVisibleRegion().nearRight;

    // use the Location class to calculate the distance between the 2 diagonal map points
    float results[] = new float[4]; // probably only need 3
    Location.distanceBetween(topLeft.latitude,topLeft.longitude,bottomRight.latitude,bottomRight.longitude,results);
    float diagonal = results[0];

    // use 5% of the diagonal for the radius (gives a 10% circle diameter)
    float radius = diagonal / 20;

    Circle circle = null;
    if (currentCircle != null) 
        // change the radius if the circle already exists (result of a zoom change)
        circle = currentCircle;

        circle.setRadius(radius);
     else 
        // draw a new circle
        circle = googleMap.addCircle(new CircleOptions()
                .center(latLng)
                .radius(radius)
                .strokeColor(Color.BLACK)
                .strokeWidth(2)
                .fillColor(Color.LTGRAY));
    

    return circle;

Utilice un icono personalizado para Marker en lugar de. puedes crear Bitmap y Canvasrecurra a este último y utilícelo como Marker icono:

new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(bitmap))...

EDITAR:

Mi respuesta anterior ya no es válida. Como mencionó Jean-Philippe Jodoin, simplemente puede hacerlo con marcadores y establecer su ancla en 0.5/0.5. Es una solución mucho más limpia.

Pegue el fragmento de código sugerido aquí como referencia:

marker = mMap.addMarker(new MarkerOptions().position(latlng).anchor(0.5f, 0.5f));

Respuesta antigua:

Me encontré con el mismo problema y no pude encontrar una solución, así que lo hice yo mismo, lo publicaré con la esperanza de que sea útil para otras personas.

El enfoque de “marcador” no me funcionó porque quería que los círculos estuvieran centrados en una latitud/longitud específica, y no se puede hacer eso con un marcador: si configura un ícono de círculo para su marcador, el borde del círculo tocará la latitud /lng, pero el círculo no estará centrado en la lat/lng.

Creé una función para calcular cuál debería ser el tamaño del círculo en metros dada la latitud y el nivel de zoom de la cámara, luego agregué un detector de cámara en el mapa para actualizar el tamaño del círculo cada vez que la cámara cambia el nivel de zoom. El resultado es un círculo que no cambia de tamaño (al menos a simple vista).

Aquí está mi código:

public static double calculateCircleRadiusMeterForMapCircle(final int _targetRadiusDip, final double _circleCenterLatitude,
    final float _currentMapZoom) 
    //That base value seems to work for computing the meter length of a DIP
    final double arbitraryValueForDip = 156000D;
    final double oneDipDistance = Math.abs(Math.cos(Math.toRadians(_circleCenterLatitude))) * arbitraryValueForDip / Math.pow(2, _currentMapZoom);
    return oneDipDistance * (double) _targetRadiusDip;


public void addCircleWithConstantSize()
    final GoogleMap googleMap = ...//Retrieve your GoogleMap object here

    //Creating a circle for the example
    final CircleOptions co = new CircleOptions();
    co.center(new LatLng(0,0));
    co.fillColor(Color.BLUE);
    final Circle circle = googleMap.addCircle(co);

    //Setting a listener on the map camera to monitor when the camera changes
    googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() 
        @Override
        public void onCameraMove() 
            //Use the function to calculate the radius
            final double radius = calculateCircleRadiusMeterForMapCircle(12, co.getCenter().latitude, googleMap.getCameraPosition().zoom);
            //Apply the radius to the circle
            circle.setRadius(radius);
        
    );

Reseñas y calificaciones

Te invitamos a añadir valor a nuestra información dando tu veteranía en las interpretaciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *