android地图圈叠加,动态改变半径? [英] android maps circle overlay, dynamically change radius?

查看:68
本文介绍了android地图圈叠加,动态改变半径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一个MapView,并在此地图上绘制了一些圆圈叠加层.一切正常,但是当我在地图上缩放时,覆盖半径不会改变.我曾尝试在论坛和Google上搜索解决方案,但找不到适合我的解决方案.有人有什么想法吗?

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?

这是我的代码:

HelloGoogleMaps.java(主要活动)

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; 
} 
//------------------------------------------------------------------------------------

}

以及Overlay类CustomOverlay.java

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);*/
}
}

预先感谢您的帮助!

推荐答案

我知道此线程已有几个月的历史了,但是总有一些更简单的方法可以实现非常相似的结果. 我知道,提出的方法可以对圆的大小进行更精确的计算,但是,即使您只需要在平均某个区域周围的任何圆,此代码所需的处理也要少得多,从而使UI更加流畅:

I know this thread is a few months old, but there are ALWAYS easier ways to achieve very similar results. I understand that the presented method gives a much more precise calculation regarding the size of the circle, but still, if you only need any circle around averaging some area, this code requires much less processing making the UI more fluid:

public class MapCircleOverlay extends Overlay {

private GeoPoint point;
private Paint paint1, paint2;

public MapCircleOverlay(GeoPoint point) {
    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);  

}

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

    Point pt = mapView.getProjection().toPixels(point, null);
    float radius = (float) Math.pow(2, mapView.getZoomLevel() - 10);

    if(radius < canvas.getHeight()/25){
        radius = canvas.getHeight()/25;
    }

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

}

}

说明: 该文档指出,对于每个zoomLevel,地图的大小都会加倍(或减半),因此,只要半径加倍或减半,其大小将在整个图形中保持一致.

Explanation: the documentation states that for each zoomLevel the map doubles (or halves) the size, so as long as the radius is doubling or halving, its size will be consistent across drawings.

可以更改"-10"以改变圆的大小(如果需要,可以在构造函数中完成)

The "-10" can be changed to vary the size of the circle (maybe be done in Constructor if desired)

还可以根据需要调整min_r(最小半径)计算,这只是为了防止圆随着用户缩小而完全消失.

Also the min_r (minimum radius) calculation can be tweaked as desired, it's only there to prevent the circle to completely disappear as the user zooms out.

希望它能对某人有所帮助;)

hope it helps someone ;)

这篇关于android地图圈叠加,动态改变半径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆