Hi,

I'm facing an issue with Google maps and custom bitmaps as marker icons and
I'm a little confused if I'm doing the thing the wrong way or there's
something wrong happening either with Google maps component or with the
Xamarin - JVM bridge.

1. I'm placing a huge quantity of markers on the map. Let's start with 900.
I'm generating random locations around a point to create these much
different LatLng objects.

Next, I do the following for each LatLng item.

                string title = "Item " + ( itemIndex++ ).ToString(); //
just for readability

                var iconMarkerOption = new MarkerOptions()
                .SetPosition( item )
                .SetSnippet( "Snippet" )
                .Anchor( 0.5f, 0.5f )
                .SetTitle( title );

                map.AddMarker( iconMarkerOption );

Build, Run and... all's well. 900 markers on the screen and not a care in
the world.

2. I don't want to use the default image, to I change the code to use my
own.

                var iconMarkerOption = new MarkerOptions()
                .SetPosition( item )
                .SetSnippet( "Snippet" )
                .Anchor( 0.5f, 0.5f )
                .InvokeIcon( BitmapDescriptorFactory.FromResource(
Resource.Drawable.ic_marker1 ) )
                .SetTitle( title );

Again, build, run and... all's well. 900 markers on the screen with my own
icon.

3. I don't want just a standard image, I want to add some label text to
each icon. So I create the following method.

        private Paint paint = new Paint( PaintFlags.AntiAlias );
        private Rect bounds = new Rect();
        private BitmapDescriptor GetCustomBitmapDescriptor( string text )
        {
            Bitmap baseBitmap = BitmapFactory.DecodeResource( Resources,
Resource.Drawable.ic_marker1 );
            Bitmap bitmap = baseBitmap.Copy( Bitmap.Config.Argb8888, true );

            paint.GetTextBounds( text, 0, text.Length, bounds );

            float x = bitmap.Width / 2.0f;
            float y = ( bitmap.Height - bounds.Height() ) / 2.0f -
bounds.Top;

            Canvas canvas = new Canvas( bitmap );

            canvas.DrawText( text, x, y, paint );

            BitmapDescriptor icon = BitmapDescriptorFactory.FromBitmap(
bitmap );

            return ( icon );
        }

and I change my code

                var iconMarkerOption = new MarkerOptions()
                .SetPosition( item )
                .SetSnippet( "Snippet" )
                .Anchor( 0.5f, 0.5f )
                .InvokeIcon( GetCustomBitmapDescriptor( title ) )
                .SetTitle( title );

Build, run and... out of memory.
07-04 15:32:35.055: E/mono(6005): Unhandled Exception:
07-04 15:32:35.055: E/mono(6005): Java.Lang.OutOfMemoryError: Exception of
type 'Java.Lang.OutOfMemoryError' was thrown.
07-04 15:32:35.055: E/mono(6005): at
Android.Runtime.JNIEnv.CallStaticObjectMethod
(intptr,intptr,Android.Runtime.JValue[]) <0x00080>
07-04 15:32:35.055: E/mono(6005): at
Android.Gms.Maps.Model.BitmapDescriptorFactory.FromBitmap
(Android.Graphics.Bitmap) <0x00103>
07-04 15:32:35.055: E/mono(6005): at
MapsExtensionsTest.MainActivity.GetCustomBitmapDescriptor (string) <0x001b7>
07-04 15:32:35.055: E/mono(6005): at
MapsExtensionsTest.MainActivity.button_Click (object,System.EventArgs)
<0x00187>
07-04 15:32:35.055: E/mono(6005): at
Android.Views.View/IOnClickListenerImplementor.OnClick (Android.Views.View)
<0x0005b>
07-04 15:32:35.055: E/mono(6005): at
Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_
(intptr,intptr,intptr) <0x0005b>
07-04 15:32:35.055: E/mono(6005): at (wrapper dynamic-method)
object.d67d7456-e896-445d-be35-db0b39982fc0 (intptr,intptr,intptr) <0x00043>
07-04 15:32:35.055: E/mono(6005):   --- End of managed exception stack
trace ---
07-04 15:32:35.055: E/mono(6005): java.lang.OutOfMemoryError
07-04 15:32:35.055: E/mono(6005): at
android.graphics.Bitmap.nativeCreateFromParcel(Native Method)

I tried changing the baseBitmap decoding to some place else, so that it's
only called once, as it's kind of lame to do this every single time.

        private Paint paint = new Paint( PaintFlags.AntiAlias );
        private Rect bounds = new Rect();
        Bitmap baseBitmap = null;
        private BitmapDescriptor GetCustomBitmapDescriptor( string text )
        {
            if ( baseBitmap == null )
            {
                baseBitmap = BitmapFactory.DecodeResource( Resources,
Resource.Drawable.ic_marker1 );
            }

            Bitmap bitmap = baseBitmap.Copy( Bitmap.Config.Argb8888, true );

            paint.GetTextBounds( text, 0, text.Length, bounds );

            float x = bitmap.Width / 2.0f;
            float y = ( bitmap.Height - bounds.Height() ) / 2.0f -
bounds.Top;

            Canvas canvas = new Canvas( bitmap );

            canvas.DrawText( text, x, y, paint );

            BitmapDescriptor icon = BitmapDescriptorFactory.FromBitmap(
bitmap );

            return ( icon );
        }

Build, run and... again, out of memory...
07-04 15:36:42.175: E/mono(6409): Java.Lang.OutOfMemoryError: Exception of
type 'Java.Lang.OutOfMemoryError' was thrown.
07-04 15:36:42.175: E/mono(6409): at
Android.Runtime.JNIEnv.CallObjectMethod
(intptr,intptr,Android.Runtime.JValue[]) <0x00080>
07-04 15:36:42.175: E/mono(6409): at Android.Graphics.Bitmap.Copy
(Android.Graphics.Bitmap/Config,bool) <0x00167>
07-04 15:36:42.175: E/mono(6409): at
MapsExtensionsTest.MainActivity.GetCustomBitmapDescriptor (string) <0x00097>
07-04 15:36:42.175: E/mono(6409): at
MapsExtensionsTest.MainActivity.button_Click (object,System.EventArgs)
<0x00187>
07-04 15:36:42.175: E/mono(6409): at
Android.Views.View/IOnClickListenerImplementor.OnClick (Android.Views.View)
<0x0005b>
07-04 15:36:42.175: E/mono(6409): at
Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_
(intptr,intptr,intptr) <0x0005b>
07-04 15:36:42.175: E/mono(6409): at (wrapper dynamic-method)
object.8ea9efe6-5373-404e-9980-0a2a1ca9397f (intptr,intptr,intptr) <0x00043>
07-04 15:36:42.175: E/mono(6409):   --- End of managed exception stack
trace ---
07-04 15:36:42.175: E/mono(6409): java.lang.OutOfMemoryError
07-04 15:36:42.175: E/mono(6409): at
android.graphics.Bitmap.nativeCopy(Native Method)
07-04 15:36:42.175: E/mono(6409): at
android.graphics.Bitmap.copy(Bitmap.java:403)
07-04 15:36:42.175: E/mono(6409): at
mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method)
07-04 15:36:42.175: E/mono(6409): at mono.androi

What can I do to avoid this? If the Google maps can do this when using the
resource id directly, there has to be a way, right?...

Any thoughts on this would be highly appreciated.

Cheers.


-- 
Gonçalo Oliveira
_______________________________________________
Monodroid mailing list
[email protected]

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to