Нарисуйте круг на Android MapView - PullRequest
17 голосов
/ 14 марта 2011

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

Редактировать: обновлено, чтобы отразить ответ робинежности.

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()));

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

Ответы [ 3 ]

8 голосов
/ 21 августа 2012

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

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 раза меньше, чем следовало бы!

7 голосов
/ 04 мая 2012

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

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

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);
    }
}
0 голосов
/ 14 марта 2011
  1. Географическая точка, которую вы пытаетесь показать (0.1275, 51.507222)? Это где-то у побережья Сомали.

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

...