android地图圆叠加,动态改变半径?
我的应用程序中有一个 MapView,并在此地图上绘制了一些圆圈叠加层。一切工作正常,但是当我放大地图时,覆盖半径不会改变。我尝试在论坛和谷歌上搜索解决方案,但找不到适合我的解决方案。有人有什么想法吗?
这是我的代码:
HelloGoogleMaps.java(主要活动)
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
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);*/
}
}
预先感谢您的帮助!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我修改了 Bundius 的答案,以便它可以与您可以作为构造函数的一部分输入的仪表一起使用。
I modified Bundius's answer so it works with meters that you can input as part of the constructor.
我知道这个帖子已经有几个月了,但总是有更简单的方法来实现非常相似的结果。
我知道所提出的方法给出了关于圆的大小的更精确的计算,但是,如果您只需要平均某个区域的任何圆,则此代码需要更少的处理,从而使 UI 更加流畅:
解释:
该文档指出,对于每个缩放级别,地图的大小都会加倍(或减半),因此只要半径加倍或减半,其大小在各个绘图中就会保持一致。
可以更改“-10”以改变圆的大小(如果需要,可以在构造函数中完成)
此外,可以根据需要调整 min_r(最小半径)计算,它只是为了防止圆完全消失,因为用户缩小。
希望它对某人有帮助;)
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:
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.
The "-10" can be changed to vary the size of the circle (maybe be done in Constructor if desired)
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 ;)
将 R.drawable.my_location_dot 更改为您用作位置标记的内容,并查看 currentLocation 是否已知
Change the R.drawable.my_location_dot with whatever you use as location marker and see that the currentLocation is known
抱歉,我知道接受的答案已经过时,但存在一个原生且更好的解决方案。
我希望这对某人有帮助 =)
参考:这里< /a>
Sorry, i know the acepted answer is old but exist a native and better solution.
I hope this help someone =)
Reference : Here