谷歌地图 v2 的 Projection.toScreenLocation(...) 非常缓慢

9

我在我的Android应用程序中将Google Maps v1升级到了v2。

v2非常好,但其中一个方法似乎是我生命中最慢的东西。

Projection proj = map.getProjection();
Point point = proj.toScreenLocation(example.m_geopoint);

toScreenLocation(...)非常缓慢,导致应用程序变得无法使用。

每帧可能会更新100次,但在Google Maps v1上表现非常好。

当我在Android控制台中检查时,看到如下提示:

10-06 13:53:04.460: D/dalvikvm(4889): GC_EXPLICIT freed 251K, 14% free 14622K/16839K, paused 3ms+5ms
10-06 13:53:05.859: D/dalvikvm(4889): GC_EXPLICIT freed 252K, 14% free 14622K/16839K, paused 2ms+5ms
10-06 13:53:07.222: D/dalvikvm(4889): GC_EXPLICIT freed 251K, 14% free 14622K/16839K, paused 3ms+6ms
...

当方法被调用时,此消息会一直出现。

v2和v1之间的区别在于:

pointOut = proj.toScreenLocation(geopointIn); // v2
projection.toPixels(geopointIn, pointOut); // v1

而v1似乎是更优化的解决方案。有没有什么方法可以使其更快?这是性能问题吗?


这是相当久以前的事了,但我目前遇到了一些非常类似于此处所描述的性能问题。你最终找到解决方案了吗? - saberrider
2个回答

1

我很晚才参加这个聚会,但我有一个使用android.graphics.Matrix的答案:

float getYMercator(double latitude){
    return (float)Math.log(Math.tan(Math.PI*(0.25+latitude/360.0)));
}
float [] fastToScreenLocation(GoogleMap map, List<LatLng> coordinates,int viewHeight, int viewWidth){
    VisibleRegion visibleRegion = map.getProjection().getVisibleRegion();
    Matrix transformMatrix = new Matrix();
    boolean ok = transformMatrix.setPolyToPoly(
            new float[] {
                    (float)visibleRegion.farLeft.longitude, getYMercator(visibleRegion.farLeft.latitude),
                    (float)visibleRegion.farRight.longitude, getYMercator(visibleRegion.farRight.latitude),
                    (float)visibleRegion.nearRight.longitude, getYMercator(visibleRegion.nearRight.latitude),
                    (float)visibleRegion.nearLeft.longitude, getYMercator(visibleRegion.nearLeft.latitude)
            },0,
            new float[] {
                    0, 0,
                    viewWidth, 0,
                    viewWidth,viewHeight,
                    0, viewHeight
            }, 0,
            4);
    if(!ok) return null;
    float[] points = new float[2*coordinates.size()];
    for(int i=0;i<coordinates.size();++i){
        LatLng location = coordinates.get(i);
        points[2*i]=(float)location.longitude;
        points[2*i+1]=getYMercator(location.latitude);
    }
    transformMatrix.mapPoints(points);
    return points;
}

基本上,它将LatLng投影到伪WebMercator坐标中(WebMercator坐标进行线性变换以保存一些计算)。然后它计算必要的矩阵将可见区域转换为屏幕坐标,并将找到的矩阵应用于坐标列表中的点。在我的三星J3上测试,对于150个坐标的列表,速度大约快了300倍(避免了多次调用的数组重新分配)。

非常感谢!从我的测试来看,对于多个坐标来说确实更快,而对于单个坐标则稍微慢一些。你有相反的操作吗(从屏幕位置到经纬度)? - Tim Autin
还有,你知道如何获取地图的当前倾斜度和旋转角度吗? - Tim Autin

0

这个答案可能有点晚了,但如果其他人遇到了和我一样的问题,解决方案可能是在自己的服务器上使用Java的Graphics2D(几乎与绘制到画布相同)预先渲染图像,并在应用程序中下载它。您必须将地理点转换为笛卡尔坐标。

在应用程序中,您只需将图像定位为GroundOverlay,并使用LatLngBounds添加到地图中:

https://developers.google.com/maps/documentation/android/groundoverlay#use_latlngbounds_to_position_an_image

然后将其添加到地图中...

https://developers.google.com/maps/documentation/android/groundoverlay#change_an_overlay

对我来说,这种方法运行得非常快。至少与Google Maps V1方法一样快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接