我正在编写一个Android应用程序,其中我必须代表某些块外观。为此,我为每个相关的块立面绘制折线(非常简单的折线,实际上是2个点线......)。
最糟糕的情况是,最多可能有10万条折线。
我的问题是我用大约3000行进行测试并且它已经非常慢了。获取要显示的数据没有问题,绘制线条没有问题,但绘制超过1k行时地图会变得迟钝。
我为每条折线创建一个PolylineOptions,然后绘制它并将其存储在如下变量中:
PolylineOptions options = new PolylineOptions();
options.add(latlon1, latlon2);
options.width(5);
options.color(Color.RED);
Polyline myPolyline = map.addPolyline(options);
myPolyline.setVisible(true);
myPolylines.add(myPolyline);
我尝试不存储它们(虽然这是后续处理所必需的),以防它是一个内存问题,但没有什么区别......而且,当存储它们时,应用程序的其余部分工作流畅(一些额外的按钮/文本字段),它只是变慢的地图(移动/缩放时)。
哦,我正在使用谷歌地图api v2的mapfragment类。
所以,问题是:有没有办法改善地图表现?
提前致谢。
编辑:折线一次全部可见。为了避免画出不必要的线条,我添加了一个"之前的步骤"其中我绘制圆圈,表示具有填充颜色(绿色到红色)的立面数量,并且仅在选择圆圈并且用户要求详细视图时显示线条。
EDIT2:这是我想要完成的事情(它来自地图指南地图,但我试图在Android上复制)
答案 0 :(得分:1)
而不是一次性绘制所有内容,只绘制您可以看到的内容。
所以你会得到可见地图的界限
VisibleRegion vr = map.getProjection().getVisibleRegion();
bounds = vr.latLngBounds;
然后检查你的线是否在可见区域的边界内,然后绘制线
执行此操作将允许您在asynctask中运行代码,您可以使用处理程序回调主线程以在需要时绘制一条线。
您还必须覆盖onCameraChange
以了解VisibleRegion何时更改,即。你模式地图。还有其他一些你需要做的事情,比如跟踪一条线是否被绘制,所以你不要多次绘制同一条线
答案 1 :(得分:1)
如果折线没有变化,我会在背景图块上绘制它们,而不是使用地图折线功能。
有关如何根据LatLng-Coordinates将形状绘制到切片中的示例,请参阅我对this SO question的回答
答案 2 :(得分:0)
我使用asynctask来创建每行50个坐标的polylineoption,并且在publishprogress方法中我将折线添加到地图中。如果确实运行时间过长而且我还没有进度,那么用户可以使用后退按钮取消任务。我最大的测试是来自sqllite数据库的3000坐标。但是,对于每个折线选项有两个坐标,这个代码会因调用publishprogress而陷入困境,因此您必须将两个坐标折线中的几十个堆叠起来,然后将它们添加到publishprogress方法中的地图中。 PublishProgress采用数组,因此传递50个折线选项并不困难。在使用每条折线50个坐标进行调试时,您可以看到在地图上绘制的折线。在实时模式中,折线仅在我便宜的50美元测试手机上出现。
注意:我将所有asynctasks作为单独的.java文件执行,因此我可以在构造函数中传递我需要的任何内容,因此我有相同的cancelMe()代码。我使用的大部分代码都在下面,我省略了数据库的内容,因为它对每个人都不同。
public class TaskParseKmldb extends AsyncTask<KmlSummary, PolylineOptions, Boolean>
implements OnCancelListener {
public interface TaskParseKmldbCallback {
void onTaskParseKmldbComplete(boolean success);
}
public TaskParseKmldb(Activity activity, KmlSummary kmlSummary, GoogleMap mMap,
ProgressDialog pd) {
this.activity = activity;
this.kmlSummary = kmlSummary;
this.mMap = mMap;
this.pd = pd;
// determine if calling activity has implemented the callback interface
callback = (TaskParseKmldbCallback.class.isAssignableFrom(activity
.getClass())) ? (TaskParseKmldbCallback) activity : null;
}
...为onCanceled例程设置进程对话框侦听器。
@Override
protected void onPreExecute() {
pd.setOnCancelListener(this);
pd.setMessage("Loading Recorded Route...");
pd.show();
}
@Override
protected void onCancelled(Boolean result) {
if (pd != null) {
pd.dismiss();
pd = null;
}
if (callback != null) {
callback.onTaskParseKmldbComplete(result);
}
}
@Override
public void onCancel(DialogInterface dialog) {
cancelMe(); // this just gracefully cancels the task.
}
public void cancelMe() {
if (!getStatus().equals(Status.FINISHED)) {
// not canceled
if (!isCancelled()) {
cancel(false);
try {
get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CancellationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
...在doInBackground中的某个地方
if (progress.getPoints().size() > 0) {
publishProgress(progress);
ret = true;
}
protected void onProgressUpdate(PolylineOptions... progress) {
if (isCancelled()) {
return;
}
if (progress[0] != null) {
// add the poly line to the map
// save the polyline returned by the map for later use
polylines.add(mMap.addPolyline(progress[0]));
}
}
...
@Override
protected void onPostExecute(Boolean result) {
if (pd != null) {
pd.dismiss();
pd = null;
}