Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

android maps circle overlay, dynamically change radius?

I have a MapView in my app and am drawing a few circle overlays on this map. Everything is working fine, but when I zoom on the map, the overlay radius does not change. I have tried searching forums and google for a solution but could not find one that worked for me. Does anyone have any ideas?

Here is my code:

HelloGoogleMaps.java (main activity)

package com.adam.maps;

import java.util.Iterator;
import java.util.List;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AbsoluteLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.ZoomButtonsController.OnZoomListener;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class HelloGoogleMaps extends MapActivity {  
//create new LocationManager
//and LocationListener objects
LocationManager lm;
LocationListener locationListener;

OnZoomListener listener;

//create a new MapView
//and MapController object
MapView mapView;
MapController mc;

RelativeLayout parent;

int num = 4;
//LoopRegion region[] = new LoopRegion[num];
//LoopRegion border[] = new LoopRegion[num];
float regionX[] = {(float) 42.91556645193364, (float) 42.9151598328247, 
        (float) 43.00110298764482, (float) 43.00054196511636};
float regionY[] = {(float) -78.87073255078127, (float) -78.8714594294243, 
        (float) -78.78354466454317, (float) -78.78226256863405};
int regionR[] = {100, 70, 150, 75};
GeoPoint regionC[] = new GeoPoint[num];
CustomOverlay overlay[] = new CustomOverlay[num];
CustomOverlay overlayLoc;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Toast.makeText(getBaseContext(), 
            "Welcome to 'sound clusters'" , 
            Toast.LENGTH_LONG).show();

    //---use the LocationManager class to obtain GPS locations---
    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);    

    locationListener = new MyLocationListener();

    lm.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, 
        0, 
        0, 
        locationListener);

    //set our mapViewer object to our "mapview" namespace in the xml layout file
    //this allows us to set the zoom control "ON" in our view
    mapView = (MapView) findViewById(R.id.mapview);
    //this will enable zoom controls, and put it on the screen
    mapView.setBuiltInZoomControls(true);
    //--------------------------------------------------------//
    parent = (RelativeLayout) findViewById(R.id.parent);

    //-------this is part of creating an overlay icon-------------------------------
    /*List<Overlay> mapOverlays = mapView.getOverlays();
    Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
    CustomItemizedOverlay itemizedOverlay =
        new CustomItemizedOverlay(drawable, this);*/
    //------------------------------------------------------------------------------

    // Create new Overlay
    for (int i = 0; i < num; i++){
        regionC[i] = new GeoPoint(
                (int) (regionX[i] * 1E6), 
                (int) (regionY[i] * 1E6));
        int newRadius = (int) feetToPixels(mapView.getZoomLevel(), regionR[i]);
        overlay[i] = new CustomOverlay(regionC[i], newRadius);
        mapView.getOverlays().add(overlay[i]);
    }

    //-------this is part of creating an overlay icon-------------------------------
    /*OverlayItem overlayitem =
         new OverlayItem(point, "Hello", "I'm in Athens, Greece!");
    itemizedOverlay.addOverlay(overlayitem);
    mapOverlays.add(itemizedOverlay);*/
    //------------------------------------------------------------------------------



    mc = mapView.getController();
    mc.setZoom(20);
    mapView.setSatellite(true);
    Toast.makeText(getBaseContext(), 
            "Zoom level: " + mapView.getZoomLevel(), 
            Toast.LENGTH_SHORT).show();


}

//not sure what this does, but Google says you need it----//
@Override
protected boolean isRouteDisplayed() {
    return false;
}
//--------------------------------------------------------//    

private class MyLocationListener implements LocationListener 
{

    //@Override
    public void onLocationChanged(Location loc) {
        if (loc != null) {

            List overlays = mapView.getOverlays();
            // first remove old overlay
            if (overlays.size() > 0) {
                for (Iterator iterator = overlays.iterator(); iterator
                        .hasNext();) {
                    iterator.next();
                    iterator.remove();
                }
            }

            GeoPoint p = new GeoPoint(
                    (int) (loc.getLatitude() * 1E6), 
                    (int) (loc.getLongitude() * 1E6));

            overlayLoc = new CustomOverlay(p, 5);
            mapView.getOverlays().add(overlayLoc);
            for (int i = 0; i < num; i++){
                mapView.getOverlays().add(overlay[i]);
            }
            //mc.animateTo(p);
            //mc.setZoom(16);
            mapView.invalidate();
        }
    }

    //@Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    }

    //@Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    }

    //@Override
    public void onStatusChanged(String provider, int status, 
        Bundle extras) {
        // TODO Auto-generated method stub
    }
}

//custom functions--------------------------------------------------------------------
private static final double equatorFeet = 131479920; 
private double feetToPixels(int zoomLevel, int feet) { 
    double equatorPixels = 256; 
    for (int i = 1; i < zoomLevel; i++) { 
        equatorPixels = equatorPixels * 2; 
    } 
    double pixelPerFoot = equatorPixels / equatorFeet; 
    return feet * pixelPerFoot; 
} 
//------------------------------------------------------------------------------------

}

And the Overlay class CustomOverlay.java

package com.adam.maps;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

public class CustomOverlay extends Overlay {

private GeoPoint geopoint;
private int rad;

public CustomOverlay(GeoPoint point, int radius) {
    geopoint = point;
    rad = radius;
}


@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    // Transform geo-position to Point on canvas
    Projection projection = mapView.getProjection();
    Point point = new Point();
    //store the transformed geopoint into a point with pixel values
    projection.toPixels(geopoint, point);

    /*// text "My Location"
    Paint text = new Paint();
    text.setAntiAlias(true);
    text.setColor(Color.BLUE);
    text.setTextSize(12);
    text.setTypeface(Typeface.MONOSPACE);*/

    // the circle to mark the spot
    Paint circlePaint = new Paint();
    circlePaint.setAntiAlias(true);
    //fill region
    circlePaint.setColor(Color.RED);
    circlePaint.setAlpha(90);
    circlePaint.setStyle(Paint.Style.FILL);
    canvas.drawCircle(point.x, point.y, rad, circlePaint);
    //border region
    circlePaint.setColor(Color.WHITE);
    circlePaint.setAlpha(255);
    circlePaint.setStyle(Paint.Style.STROKE);
    circlePaint.setStrokeWidth(3);
    canvas.drawCircle(point.x, point.y, rad, circlePaint);

    /*canvas.drawText("My Location", point.x + 3 * CIRCLERADIUS, point.y + 3
            * CIRCLERADIUS, text);*/
}
}

Thank you in advance for your help!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;

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

public class MapCircleOverlay extends Overlay {

private GeoPoint point;
private Paint paint1, paint2;
private float radius; //in meters

public MapCircleOverlay(GeoPoint point, float radius) {
    this.point = point;

    paint1 = new Paint();
    paint1.setARGB(128, 0, 0, 255);
    paint1.setStrokeWidth(2);
    paint1.setStrokeCap(Paint.Cap.ROUND);
    paint1.setAntiAlias(true);
    paint1.setDither(false);
    paint1.setStyle(Paint.Style.STROKE);

    paint2 = new Paint();
    paint2.setARGB(64, 0, 0, 255);

    this.radius = radius;
}

@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {

    Point pt = mapView.getProjection().toPixels(point, null);
    float projectedRadius = mapView.getProjection().metersToEquatorPixels(radius);

    canvas.drawCircle(pt.x, pt.y, projectedRadius, paint2);
    canvas.drawCircle(pt.x, pt.y, projectedRadius, paint1);

}

}

I modified Bundius's answer so it works with meters that you can input as part of the constructor.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...