Google Maps v2 Projection.toScreenLocation (...) extremely slow

I upgraded Google Maps v1 to v2 in my Android app.

And v2 was enjoyable and so on, but one method seems to be the slowest in my life.

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

toScreenLocation (...) is so slow that the application slows down to an unacceptable slowdown. The method is updated, perhaps 100 times per frame, but it works very well on Google Maps v1.

And when I look at the Android console, I see the following:

 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 ... 

This message exits all the time while the method is being called.

And the difference between v2 and v1 is this:

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

And v1 seems to be a more optimized solution. Is there any way to get this faster? Is this a performance bug?

+7
source share
2 answers

These answers probably come too late, but if someone else is facing the same problems as me, the solution might be to pre-render the image on their own server using Java Graphics2D (which works almost the same way as drawing on canvas ) and download it in the application. You must convert the geo-points to Cartesian coordinates. In the application, you only need to position the image as GroundOverlay using 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 the same as Google Maps V1.

0
source

I arrive at the party very late, 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, he projects LatLng into the coordinates of the pseudo WebMercator (the coordinates of WebMercator are linearly transformed to save some calculations). Then he calculates the necessary matrix for converting the visible region into the coordinates of the screen and applies the found matrix to the points in the coordinate list. About 300 times faster than my tests for a list of 150 coordinates on my Samsung J3 (avoiding redistributing the array for multiple calls).

0
source

Source: https://habr.com/ru/post/976295/


All Articles