Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixed marker size at the android Google map

Is there any possibility to make marker static? I don't need to increese/reduce marker size while zoom is changing. I know about groundoverlay - it's not an option here.

The result should be like this:

enter image description here

like image 221
inaps Avatar asked Mar 28 '26 23:03

inaps


2 Answers

Ben P is right in his comment: "markers do not change size based on zoom". But this marker behavior can be achieved by deleting and re-creating the marker with custom icon size in (for example) onCameraIdle() for each zoom level. With:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final int DIAMETER_IN_METERS = 300;

    private final LatLng MARKER_LOCATION = new LatLng(37.762555, -122.244221);

    private GoogleMap mGoogleMap;
    private MapFragment mMapFragment;

    private Marker mMarker = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map_fragment);
        mMapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;

        mGoogleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
            @Override
            public void onCameraIdle() {

                if (mMarker != null) {
                    mMarker.remove();
                }
                mMarker = createResizedMarker(MARKER_LOCATION);
            }
        });
        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(MARKER_LOCATION, 16));
    }

    private Marker createResizedMarker(LatLng marker_location) {
        // get vector drawable
        final Drawable iconDrawable = getResources().getDrawable(R.drawable.ic_letter_m);
        // calc map resolution (meters per pixel) for current zoom level for details see e.g. https://msdn.microsoft.com/en-us/library/aa940990.aspx
        final double meters_per_pixel = (Math.cos(mGoogleMap.getCameraPosition().target.latitude * Math.PI / 180) * 2 * Math.PI * 6378137) / (256 * Math.pow(2, mGoogleMap.getCameraPosition().zoom));
        // calc marker icon diameter in pixels
        final int diameter = (int)(DIAMETER_IN_METERS / meters_per_pixel);
        // create marker icon bitmap for current scale
        final Bitmap bitmap = Bitmap.createBitmap(diameter, diameter, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        iconDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        iconDrawable.draw(canvas);

        Marker marker = mGoogleMap.addMarker(new MarkerOptions()
                .position(MARKER_LOCATION)
                .anchor(0.5f, 0.5f)
                .icon(BitmapDescriptorFactory.fromBitmap(bitmap)));

        return marker;
    }
}

and R.drawable.ic_letter_m - xml vector drawable (for perfect scaling) like:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="512dp"
        android:height="512dp"
        android:viewportWidth="512"
        android:viewportHeight="512">

    <path
        android:name="canvas_background"
        android:pathData="M -1 -1 H 581 V 401 H -1 V -1 Z" />
    <path
        android:name="SVGCleanerId_0"
        android:fillColor="#54BBFF"
        android:pathData="M256,0l-61.811005,256l61.811005,256c141.384979,0 256,-114.61499
256,-256s-114.61499,-256 -256,-256z" />
    <path
        android:name="SVGCleanerId_1"
        android:fillColor="#8DD2FF"
        android:pathData="M0,256c0,141.384979 114.614998,256 256,256l0,-512c-141.385002,0 -256,114.614998
-256,256z" />
    <path
        android:name="svg_1"
        android:fillColor="#C6E8FF"
        android:pathData="M256,30.905001l0,450.188993c124.31601,0 225.095001,-100.777985
225.095001,-225.095001s-100.778992,-225.093992 -225.095001,-225.093992z" />
    <path
        android:name="svg_2"
        android:fillColor="#FFFFFF"
        android:pathData="M450.188995,256c0,-124.315994 -86.94101,-225.094999
-194.188995,-225.094999c-124.315994,0 -225.094999,100.779005
-225.094999,225.094999s100.779005,225.095001 225.094999,225.095001c107.247986,0
194.188995,-100.778992 194.188995,-225.095001z" />
    <path
        android:name="svg_3"
        android:fillColor="#54BBFF"
        android:pathData="M306.993988,395.589996c-11.378998,0 -20.604004,-9.223999
-20.604004,-20.604004l0,-137.592987l-11.453003,26.722992c-3.246002,7.576019
-10.694977,12.488007 -18.937988,12.488007c-8.240997,0 -15.69101,-4.912018
-18.938004,-12.488007l-11.453003,-26.722992l0,137.593018c0,11.378998
-9.223999,20.603973 -20.604004,20.603973c-11.378998,0 -20.603989,-9.223999
-20.603989,-20.603973l0,-237.972015c0,-9.782997 6.878998,-18.215996
16.460999,-20.182999c9.584,-1.968002 19.227005,3.075005
23.080002,12.065994l32.059006,74.798004l32.056,-74.796997c3.852997,-8.990997
13.502014,-14.032997 23.079987,-12.066002c9.583008,1.968002 16.460999,10.401001
16.460999,20.183006l0,237.971985c0.001007,11.377991 -9.223999,20.602997
-20.602997,20.602997z" />
    <path
        android:name="SVGCleanerId_0_1_"
        android:fillColor="#F655A0"
        android:pathData="M256,0l-61.811005,256l61.811005,256c141.384979,0 256,-114.61499
256,-256s-114.61499,-256 -256,-256z" />
    <path
        android:name="SVGCleanerId_1_1_"
        android:fillColor="#F655A0"
        android:pathData="M0,256c0,141.384979 114.614998,256 256,256l0,-512c-141.385002,0 -256,114.614998
-256,256z" />
    <path
        android:name="svg_8"
        android:fillColor="#FFFFFF"
        android:pathData="M335.771271,393.589996c-17.577087,0 -31.826935,-9.223999
-31.826935,-20.604004l0,-137.592987l-17.691406,26.722992c-5.014069,7.576019
-16.520477,12.488007 -29.253418,12.488007c-12.729828,0 -24.237839,-4.912018
-29.253448,-12.488007l-17.691406,-26.722992l0,137.593018c0,11.378998
-14.248276,20.603973 -31.82692,20.603973c-17.577087,0 -31.826889,-9.223999
-31.826889,-20.603973l0,-237.972015c0,-9.782997 10.625946,-18.215996
25.427231,-20.182999c14.804367,-1.968002 29.699875,3.075005
35.651581,12.065994l49.521408,74.798004l49.516754,-74.796997c5.951721,-8.990997
20.856506,-14.032997 35.651581,-12.066002c14.802826,1.968002 25.427216,10.401001
25.427216,20.183006l0,237.971985c0.001556,11.377991 -14.24826,20.602997
-31.825348,20.602997z" />
</vector>

you got something like:

Marker resize

But indeed, Ground Overlay do all that job from the box. It's really better to use Ground Overlays for task like that (at least for better performance and smooth zooming). And if you need, e.g. in case you need to draw car movement, you can recreate Ground Overlays (with different bitmaps or bitmaps size like markers above) in any time. You can also rotate Ground Overlays like markers with .setBearing().

like image 181
Andrii Omelchenko Avatar answered Apr 02 '26 23:04

Andrii Omelchenko


I had the same problem, using the following code for the solution. You may use the following code for a fixed-size marker. As of my study for this, we have only Bitmap option.

int height = 100;
int width = 100;
BitmapDrawable bitmapdraw=(BitmapDrawable)getResources().getDrawable(R.mipmap.marker);
Bitmap b=bitmapdraw.getBitmap();
Bitmap smallMarker = Bitmap.createScaledBitmap(b, width, height, false);

To add market use the following code:

gMap.addMarker(new MarkerOptions()
                        .position(POSITION)
                        .title("Title")
                        .icon(BitmapDescriptorFactory.fromBitmap(smallMarker))
                );
like image 44
aanshu Avatar answered Apr 02 '26 23:04

aanshu