所以我花了很多時間試圖弄清楚如何加快速度,但我現在已經沒有想法。我有一門課,mapPopup
,其中MapView
顯示在整個屏幕上。在mapPopup
中有一個GeoPoint
陣列,我想在陣列的第二維中的每個GeoPoint之間畫線。我已經完成了這項任務,已經使用自定義類mapOverlay
,它擴展了Overlay
,但是我遇到的問題是,一旦繪製了所有地圖疊加層,地圖縮放或平移都非常緩慢。一旦所有覆蓋圖都添加到地圖中,通常會超過2000個,但它們都非常小。添加了多個覆蓋圖後,MapView平移和縮放速度很慢
考慮到如果覆蓋圖較少,地圖工作會更快,我將所有線條繪製爲三個獨立的疊加層,而不是每行的獨立疊加層。這實際上導致了對地圖的縮放和縮放,所以我恢復了許多小的覆蓋。
我希望我能用一些方法來提高地圖的描述速度。僞代碼或潛在方法的實際代碼也可以幫助我更好地理解它。我的代碼發佈在下面。請再次注意,我的疊加層和地圖顯示正確;我只想要一種方法可以實現更快的平移和縮放。
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;
}
}
這幫了我不少。我用MotionEvent.ACTION_MOVE替換了MotionEvent.ACTION_DOWN,並使用了mustDraw = true的else塊。像我的應用程序一樣魅力,讓平移更舒適。 – gelupa
同樣的思路也能以某種方式應用於ItemizedOverlay嗎? – topwik
@towpse:從來沒有使用過這個,但是因爲它擴展了'overlay',我看不出爲什麼它不對。 – psycho