Подтвердить что ты не робот

Нарисовать круг на Android MapView

Исправлено это мое решение:

Изменить: обновлено, чтобы отразить ответ robguinness.

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;

public class CircleOverlay extends Overlay {

Context context;
double mLat;
double mLon;
float mRadius;

public CircleOverlay(Context _context, double _lat, double _lon, float radius ) {
    context = _context;
    mLat = _lat;
    mLon = _lon;
    mRadius = radius;
}

public CircleOverlay(Context _context, double _lat, double _lon, float radius ) {
    context = _context;
    mLat = _lat;
    mLon = _lon;
    mRadius = radius;
}

public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    super.draw(canvas, mapView, shadow); 

    if(shadow) return; // Ignore the shadow layer

    Projection projection = mapView.getProjection();

    Point pt = new Point();

    GeoPoint geo = new GeoPoint((int) (mLat *1e6), (int)(mLon * 1e6));

    projection.toPixels(geo ,pt);
    float circleRadius = projection.metersToEquatorPixels(mRadius) * (1/ FloatMath.cos((float) Math.toRadians(mLat)));

    Paint innerCirclePaint;

    innerCirclePaint = new Paint();
    innerCirclePaint.setColor(Color.BLUE);
    innerCirclePaint.setAlpha(25);
    innerCirclePaint.setAntiAlias(true);

    innerCirclePaint.setStyle(Paint.Style.FILL);

    canvas.drawCircle((float)pt.x, (float)pt.y, circleRadius, innerCirclePaint);
}

}

Чтобы "нарисовать" его нужно добавить в наложения карт

mMapView.getOverlays().add(new CircleOverlay(context, loc.getLatitude(),loc.getLongitude()));

Надеюсь, что это поможет.

4b9b3361

Ответ 1

В принятом ответе есть ошибка. Я попытался исправить это, но мое редактирование было отклонено по какой-то странной причине. В любом случае, это исправленный ответ:

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;

public class CircleOverlay extends Overlay {

    Context context;
    double mLat;
    double mLon;
    float mRadius;

    public CircleOverlay(Context _context, double _lat, double _lon, float radius ) {
        context = _context;
        mLat = _lat;
        mLon = _lon;
        mRadius = radius;
    }

    public CircleOverlay(Context _context, double _lat, double _lon, float radius ) {
        context = _context;
        mLat = _lat;
        mLon = _lon;
        mRadius = radius;
    }

    public void draw(Canvas canvas, MapView mapView, boolean shadow) {
        super.draw(canvas, mapView, shadow); 

        if(shadow) return; // Ignore the shadow layer

        Projection projection = mapView.getProjection();

        Point pt = new Point();

        GeoPoint geo = new GeoPoint((int) (mLat *1e6), (int)(mLon * 1e6));

        projection.toPixels(geo ,pt);
        float circleRadius = projection.metersToEquatorPixels(mRadius) * (1/ FloatMath.cos((float) Math.toRadians(mLat)));

        Paint innerCirclePaint;

        innerCirclePaint = new Paint();
        innerCirclePaint.setColor(Color.BLUE);
        innerCirclePaint.setAlpha(25);
        innerCirclePaint.setAntiAlias(true);

        innerCirclePaint.setStyle(Paint.Style.FILL);

        canvas.drawCircle((float)pt.x, (float)pt.y, circleRadius, innerCirclePaint);
    }
}

Проблема в ответе Скотта заключается в том, что circleRadius был рассчитан с использованием метода, который преобразуется из метров в пиксели для точек на экваторе. Если, однако, ваша желаемая точка не находится на экваторе, радиус будет слишком мал, потому что преобразование не учитывает тот факт, что меридианы собираются вместе на полюсах. Это можно исправить, однако, путем умножения на (1/ FloatMath.cos((float) Math.toRadians(mLat))), что является единственным изменением, которое я сделал для исходного ответа Скотта.

Я надеюсь, что это поможет кому-то, потому что я обнаружил проблему с трудом. Я живу в Финляндии, где, используя оригинальный метод, круги были нарисованы в 2 раза меньше, чем они должны были быть!

Ответ 2

Я взял вышеприведенный образец и расширил его, чтобы учесть круги, которые нужно масштабировать с помощью уровня масштабирования карты (т.е. кругов относительно расстояния до земли).

Некоторые люди могут найти это полезным.

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;

public class CircleOverlay extends Overlay {

    Context context;
    double mLat;
    double mLon;
    float mRadius;

     public CircleOverlay(Context _context, double _lat, double _lon, float radius ) {
            context = _context;
            mLat = _lat;
            mLon = _lon;
            mRadius = radius;
     }

     public void draw(Canvas canvas, MapView mapView, boolean shadow) {
         super.draw(canvas, mapView, shadow); 

         if(shadow) return; // Ignore the shadow layer

         Projection projection = mapView.getProjection();

         Point pt = new Point();

         GeoPoint geo = new GeoPoint((int) (mLat *1e6), (int)(mLon * 1e6));

         projection.toPixels(geo ,pt);
         float circleRadius = projection.metersToEquatorPixels(mRadius) * (1/ FloatMath.cos((float) Math.toRadians(mLat)));

         Paint innerCirclePaint;

         innerCirclePaint = new Paint();
         innerCirclePaint.setColor(Color.BLUE);
         innerCirclePaint.setAlpha(25);
         innerCirclePaint.setAntiAlias(true);

         innerCirclePaint.setStyle(Paint.Style.FILL);

         canvas.drawCircle((float)pt.x, (float)pt.y, circleRadius, innerCirclePaint);
    }
}

Ответ 3

  • Является ли точка геометрии, которую вы пытаетесь показать (0.1275, 51.507222)? Это где-то недалеко от побережья Сомали.

  • super.draw(..) должен быть первым выражением в вашем методе draw().