Google Maps v2 Projection.toScreenLocation(…) extremely slow

人走茶凉 提交于 2019-12-03 14:02:46

I come very, very late to the party, but I have an answer using 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;
}

Basically, it projects the LatLng into pseudo WebMercator coordinates (WebMercator coordinates linearly transformed to save some calculations). Then it calculates the necessary matrix to transform the visible region to screen coordinates and applies the found matrix to the points in the coordinates list. Roughly 300x faster from my tests for a list of 150 coordinates on my Samsung J3 (avoiding array reallocation for multiple calls).

This answers comes probably too late, but if anybody else runs into the same problems, like me, a solution could be to pre-render an image on an own server with Java's Graphics2D (which works almost the same as drawing to the canvas) and download it within the app. You have to convert the geo points into cartesian coordinates. Within the app, you only have to position the image as GroundOverlay with LatLngBounds: https://developers.google.com/maps/documentation/android/groundoverlay#use_latlngbounds_to_position_an_image

and add it to the map... https://developers.google.com/maps/documentation/android/groundoverlay#change_an_overlay

For me, this approach works pretty fast. At least as fast as the Google Maps V1 approach.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!