trazar studio pro para hacer google earth dibujar crear como circunferencia circulo android google-maps

android - studio - hacer buffer en google earth



¿Cómo puedo dibujar un círculo objetivo estático en Google Maps? (1)

He estado buscando dibujar un círculo para un radio estático en la parte superior de Google Maps y todas las respuestas que encontré describen dibujar marcadores y círculos que están vinculados a una coordenada de latitud larga.

Lo que requiero es esto:

Este círculo y el marcador flotan sobre el fragmento de Google Maps , es decir: cuando desplazas y haces zoom, permanece estático . Y aquí está la parte complicada: quiero poder obtener el área cubierta en el mapa para su procesamiento (por ejemplo: el lat, largo del marcador central y el radio del círculo dependiendo del nivel de zoom en el mapa).

¿Cómo puedo conseguir esto? Gracias por adelantado.


Puede crear una View personalizada para dibujar el círculo. He basado mi ejemplo en Dibujar círculo transparente lleno afuera

Aquí puede encontrar un tutorial sobre cómo crear vistas personalizadas.

En mi ejemplo, estoy creando una RadarOverlayView personalizada con un parámetro de radius que utilizo para calcular el área.

Mi código de vista personalizada:

public class RadarOverlayView extends LinearLayout { private Bitmap windowFrame; private float radius = 0f; private int centerX = 0; private int centerY = 0; public RadarOverlayView(Context context) { super(context); } public RadarOverlayView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.RadarOverlayView, 0, 0); try { radius = a.getDimension(R.styleable.RadarOverlayView_radius, 0f); } finally { a.recycle(); } } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (windowFrame == null) { createWindowFrame(); } canvas.drawBitmap(windowFrame, 0, 0, null); } @Override public boolean isEnabled() { return false; } @Override public boolean isClickable() { return false; } protected void createWindowFrame() { windowFrame = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas osCanvas = new Canvas(windowFrame); centerX = getWidth() / 2; centerY = getHeight() / 2; if (radius > 0) { Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); // Draw the circunference paint.setStyle(Paint.Style.STROKE); paint.setColor(Color.RED); paint.setAlpha(200); paint.setStrokeWidth(5); osCanvas.drawCircle(centerX, centerY, radius, paint); // Draw the circle paint.setStyle(Paint.Style.FILL); paint.setColor(Color.RED); paint.setAlpha(100); osCanvas.drawCircle(centerX, centerY, radius, paint); // Draw the center icon paint.setAlpha(255); Bitmap centerBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); osCanvas.drawBitmap(centerBitmap, centerX - centerBitmap.getWidth() / 2, centerY - centerBitmap.getHeight() / 2, paint); } } @Override public boolean isInEditMode() { return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); windowFrame = null; } public float getRadius() { return radius; } public int getCenterX() { return centerX; } public int getCenterY() { return centerY; } }

Mi attrs.xml:

<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RadarOverlayView"> <attr name="radius" format="dimension" /> </declare-styleable> </resources>

Mi diseño activity_maps.xml:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/map" android:name="myPackage.MySupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MapsActivity"/> <myPackage.RadarOverlayView android:id="@+id/radar" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" app:radius="150dp" /> </RelativeLayout>

Mi actividad:

public class MapsActivity extends FragmentActivity implements GoogleMap.OnCameraChangeListener { private GoogleMap mMap; private RadarOverlayView radarView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); radarView = (RadarOverlayView) findViewById(R.id.radar); setUpMapIfNeeded(); } @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } private void setUpMapIfNeeded() { if (mMap == null) { mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); if (mMap != null) { setUpMap(); } } } private void setUpMap() { mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); mMap.getUiSettings().setAllGesturesEnabled(true); mMap.getUiSettings().setZoomControlsEnabled(true); mMap.setOnCameraChangeListener(this); } @Override public void onCameraChange(final CameraPosition cameraPosition) { // Compute the area of the circle each time the camera changes LatLng center = mMap.getProjection().fromScreenLocation( new Point(radarView.getCenterX(), radarView.getCenterY())); LatLng right = mMap.getProjection().fromScreenLocation( new Point(radarView.getCenterX() + Math.round(radarView.getRadius()), radarView.getCenterY())); Location locationCenter = new Location("center"); locationCenter.setLatitude(center.latitude); locationCenter.setLongitude(center.longitude); Location locationRight = new Location("right"); locationRight.setLatitude(right.latitude); locationRight.setLongitude(right.longitude); double geoRadius = locationCenter.distanceTo(locationRight); double geoArea = Math.PI * Math.pow(geoRadius, 2); // Uncomment to inspect the difference between // RadarOverlayView circle and geographic circle: // mMap.clear(); // Circle circle = mMap.addCircle(new CircleOptions() // .center(cameraPosition.target) // .radius(geoRadius) // .strokeColor(Color.GREEN) // .fillColor(Color.BLUE)); Toast.makeText(this, "Area: " + geoArea, Toast.LENGTH_SHORT).show(); } }

El resultado se ve así y muestra una Toast con el área cubierta por el círculo cada vez que cambia la cámara:

Limitaciones

El ejemplo dibuja un círculo perfecto en una View , pero no se garantiza que este círculo sea geográficamente preciso según el nivel de zoom.

Puede ver que, en niveles de zoom altos, hay una gran diferencia entre el círculo dibujado por la vista personalizada y un círculo geográficamente preciso (basado en el objetivo y el radio de la cámara) si descomenta el código mMap.addCircle en el método onCameraChange :

Esta diferencia que es causada por la proyección del mapa (WGS84), es enorme con altos niveles de zoom y disminuye a niveles de zoom más bajos: