所以我花了很多时间试图弄清楚如何加快速度,但我现在没有主意了。我有一个类 mapPopup
,其中一个 MapView
显示在整个屏幕上。 mapPopup
中有一个由 GeoPoint
组成的数组,我想在数组的二维中的每个 GeoPoint 之间画线。我已经使用扩展 Overlay
的自定义类 mapOverlay
完成了这项任务,但我遇到的问题是,一旦绘制了所有 map 叠加层, map 缩放或平移非常慢。一旦将所有叠加层添加到 map 中,通常会有 2000 多个叠加层,但它们都非常小。
考虑到如果叠加层越少 map 会工作得更快,我将所有线绘制到三个单独的叠加层而不是每条线单独的叠加层。这实际上导致 map 的平移和缩放变慢,所以我又回到了许多小的叠加层。
如果能提供一些信息丰富且易于理解的方法说明,我将不胜感激,我可以使用这些方法来加快 map 绘制速度。潜在方法的伪代码或真实代码也可以帮助我更好地理解它。我的代码贴在下面。再次请注意,我的覆盖图和 map 显示正确;我只想要一种允许更快平移和缩放的方法。
mapOverlay 类
public class mapOverlay extends Overlay {
private Projection projection;
private GeoPoint gp1;
private GeoPoint gp2;
private int color;
public mapOverlay(int color, MapView map, GeoPoint geo1, GeoPoint geo2) {
// super();
this.projection = map.getProjection();
this.gp1 = geo1;
this.gp2 = geo2;
this.color = color;
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, false);
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
mPaint.setColor(this.color);
Point p1 = new Point();
Point p2 = new Point();
Path path1 = new Path();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path1.moveTo(p1.x, p1.y);
path1.lineTo(p2.x, p2.y);
canvas.drawPath(path1, mPaint);
}
}
mapPopup 类
public class mapPopup extends MapActivity {
public String[] trailNames;
public String tableName = "";
public int numTrails = 0;
public static GeoPoint[][] geoPoints;
public int[] colors = new int[] { Color.WHITE, Color.BLUE, Color.CYAN,
Color.RED, Color.YELLOW, Color.MAGENTA, Color.GRAY, Color.LTGRAY };
public int[] newColors;
// public Bitmap b;
public GeoPoint firstP;
public void loadMapData(Bitmap b, MapView map, int[] colors,
GeoPoint[][] GPAA, int ZoomLevel) {
// GPAA holds an array of an array of GeoPoint
Log.i("DEBUG", "starting loadMapDataTask");
map.setSatellite(true);
MapController mc = map.getController();
mapOverlay[][] mapOverlay = new mapOverlay[GPAA.length][];
Log.i("DEBUG", "length of GPAA is: " + GPAA.length);
// i cycles through the first dimension of GPAA
for (int i = 0; i < GPAA.length; i++) {
GeoPoint[] geoPoints = GPAA[i];
int length = geoPoints.length - 1;
mapOverlay[i] = new mapOverlay[length]; //
int pointCount = 0;
// z cycles through the second dimension of GPAA
for (int z = 0; z < length; z++) {
mapOverlay[i][z] = new mapOverlay(colors[i], map,
geoPoints[pointCount], geoPoints[pointCount + 1]);
pointCount++;
}
}
// Actually adds overlays to map
List<Overlay> mapOverlays = map.getOverlays();
for (int i = 0; i < mapOverlay.length; i++) {
int length = mapOverlay[i].length;
Log.i("DEBUG", "Adding map overlays for trail: " + i);
Log.i("DEBUG", "Length of mapOverlay[i] is: " + length);
for (int z = 0; z < length; z++) {
mapOverlays.add(mapOverlay[i][z]);
}
}
mc.animateTo(GPAA[0][0]);
mc.setZoom(ZoomLevel);
Rect r = new Rect();
map.getDrawingRect(r);
map.invalidate(r);
}
public static class runBGLoad extends
AsyncTask<bgLoadParam, Integer, GeoPoint[][]> {
public GeoPoint[][] geoPoints;
protected GeoPoint[] getGPa(Context context, String name, int ID) {
File file = context.getFileStreamPath(name);
if (file.exists() == false) {
Log.i("DEBUG", "Creating file");
InputStream is;
FileOutputStream fos;
try {
Log.i("DEBUG", "id is " + ID);
is = context.getResources().openRawResource(ID);
byte[] buffer = new byte[is.available()];
is.read(buffer);
fos = context.openFileOutput(name, Context.MODE_PRIVATE);
fos.write(buffer);
fos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.i("DEBUG", "File already exists");
}
// Log.i("DEBUG", "starting to get geopoints");
List<Location> gpsPoints = XMLParser.getPoints(file);
int i = 0;
int index = 0;
GeoPoint[] geoPoints = new GeoPoint[gpsPoints.size()];
// makes list of gpsPoints into GeoPoint[]
ListIterator<Location> it = gpsPoints.listIterator();
while (it.hasNext()) {
index = it.nextIndex();
Location loc = gpsPoints.get(index);
geoPoints[i] = new GeoPoint((int) (loc.getLatitude() * 1E6),
(int) (loc.getLongitude() * 1E6));
it.next();
i++;
}
return geoPoints;
}
@Override
protected GeoPoint[][] doInBackground(bgLoadParam... params) {
Context context = params[0].getContext();
int tNLength = params[0].getTNames().length;
geoPoints = new GeoPoint[tNLength][];
for (int i = 0; i < params[0].getTNames().length; i++) {
String modName = params[0].getTNames()[i].toLowerCase()
.replace(' ', '_');
int identifier = context.getResources().getIdentifier(modName,
"raw", context.getPackageName());
geoPoints[i] = getGPa(params[0].getContext(), modName
+ "_mapfile", identifier);
}
Log.i("DEBUG", "TEST");
mapPopup.geoPoints = geoPoints;
Log.i("DEBUG", "TEST2");
return geoPoints;
}
@Override
protected void onPostExecute(GeoPoint[][] result) {
Log.i("DEBUG", "The points are loaded.");
mapPopup.geoPoints = result;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
String[] extras = intent.getStringArrayExtra("strings");
tableName = extras[1];
numTrails = Integer.parseInt(extras[2]);
trailNames = intent.getStringArrayExtra("trailNamesA");
super.onCreate(savedInstanceState);
setContentView(R.layout.map_popup_layout);
newColors = new int[numTrails];
for (int i = 0; i < numTrails; i++) {
newColors[i] = colors[i];
}
ViewGroup layout = (ViewGroup) findViewById(R.id.map_popup);
TextView[] tVs = new TextView[numTrails];
for (int i = 0; i < numTrails; i++) {
LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tVs[i] = new TextView(getApplicationContext());
tVs[i].setText(trailNames[i]);
tVs[i].setId(i + 700);
tVs[i].setTextColor(colors[i]);
tVs[i].setBackgroundColor(Color.BLACK);
if (i > 0) {
params.addRule(RelativeLayout.BELOW, (699 + i));
}
layout.addView(tVs[i], params);
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
MapView map = (MapView) findViewById(R.id.popupMV);
Bitmap b = Bitmap.createBitmap(map.getWidth(), map.getHeight(),
Bitmap.Config.RGB_565);
try {
trailsActivity.mapPreLoad.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
loadMapData(b, map, newColors, geoPoints, 17);
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
最佳答案
我目前面临同样的问题,我刚刚找到了一个解决方法:防止在缩放或平移时绘制叠加层。这并不完美,我仍在寻找更好的解决方案,但至少 map 可以使用,而无需为每次平移或缩放等待 5 秒。
这是我在 Overlay
扩展中使用的代码。它不是 Java 而是 C#(使用 Monodroid)——但它应该很容易理解。
public override bool OnTouchEvent (MotionEvent e, Android.GoogleMaps.MapView mapView)
{
if (e.Action == MotionEventActions.Down)
_mustDraw = false;
else if (e.Action == MotionEventActions.Up)
_mustDraw = true;
return base.OnTouchEvent (e, mapView);
}
public override void Draw (Android.Graphics.Canvas canvas, Android.GoogleMaps.MapView mapView, bool shadow)
{
if (shadow || !_mustDraw)
return;
// ...
}
该解决方案适用于每个基于 map 触摸的 Action ,现在执行速度很快,我只是在使用内置缩放控件放大或缩小时缺少相同行为的实现,但我首先需要解决一些问题我在做这部分之前的错误,我稍后会回来讨论这部分。
关于android - 添加许多 Overlay 后 MapView 平移和缩放速度很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10944749/