Custom, disabled and empty map in android

I want to display only part of the radius of the marker on the map, and the rest of the map should be empty. For example, if the radius of the Marker is 5 km, and I want only the radial part of the map to be visible to the user, and the rest of the map should be empty.

I read about Google Map Overlays, as well as finding various SDKs like MapBox and Skobbler, but none of them provide the functionality I want.

Here is an image that will explain how I want the map to look.

In the image you can see that only some part around the marker is visible, and the rest is empty. I want to achieve this functionality in Android maps.

If anyone has any solutions or ideas, please let me know.

Thanks.

+2
source share
1 answer

You can add View on a map that hides it, and draw a circle on it to display only the places you need.

I based my answers on

MapsActivity:

 public class MapsActivity extends FragmentActivity implements GoogleMap.OnCameraChangeListener { private GoogleMap mMap; private HideOverlayView hideView; private List<Marker> visibleMarkers = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); hideView = (HideOverlayView) findViewById(R.id.hideview); setUpMapIfNeeded(); } @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } @SuppressLint("NewApi") private void setUpMapIfNeeded() { if (mMap == null) { final SupportMapFragment f = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); if (mMap != null) { setUpMap(); } } } private void setUpMap() { mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); mMap.getUiSettings().setAllGesturesEnabled(true); mMap.getUiSettings().setZoomControlsEnabled(true); mMap.getUiSettings().setMyLocationButtonEnabled(true); mMap.setMyLocationEnabled(true); mMap.setOnCameraChangeListener(this); mMap.moveCamera(CameraUpdateFactory.newCameraPosition( CameraPosition.fromLatLngZoom(new LatLng(40.22861, -3.95567), 15))); visibleMarkers.add(mMap.addMarker(new MarkerOptions().position( new LatLng(40.22861, -3.95567)))); visibleMarkers.add(mMap.addMarker(new MarkerOptions().position( new LatLng(40.22977, -3.95338)))); } @Override public void onCameraChange(final CameraPosition cameraPosition) { List<Point> visiblePoints = new ArrayList<>(); Projection projection = mMap.getProjection(); for (Marker visibleMarker : visibleMarkers) { visiblePoints.add(projection.toScreenLocation(visibleMarker.getPosition())); } float radius = 150f; // meters Point centerPoint = projection.toScreenLocation(cameraPosition.target); Point radiusPoint = projection.toScreenLocation( SphericalUtil.computeOffset(cameraPosition.target, radius, 90)); float radiusPx = (float) Math.sqrt(Math.pow(centerPoint.x - radiusPoint.x, 2)); hideView.reDraw(visiblePoints, radiusPx); } } 

HideOverlayView:

 public class HideOverlayView extends LinearLayout { private Bitmap windowFrame; private float radius = 0f; private List<Point> points; public HideOverlayView(Context context) { super(context); } public HideOverlayView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); createWindowFrame(); canvas.drawBitmap(windowFrame, 0, 0, null); } @Override public boolean isEnabled() { return false; } @Override public boolean isClickable() { return false; } public void reDraw(List<Point> points, float radius) { this.points = points; this.radius = radius; invalidate(); } protected void createWindowFrame() { windowFrame = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas osCanvas = new Canvas(windowFrame); RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight()); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLACK); osCanvas.drawRect(outerRectangle, paint); if (radius > 0 && points != null) { for (Point point : points) { paint.setColor(Color.TRANSPARENT); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); paint.setStyle(Paint.Style.FILL); osCanvas.drawCircle(point.x, point.y, radius, paint); } } } @Override public boolean isInEditMode() { return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); windowFrame = null; } } 

activity_maps.xml:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/map" android:name="mypackage.MySupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MapsActivity"/> <mypackage.HideOverlayView android:id="@+id/hideview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" app:radius="150dp"/> </RelativeLayout> 

Result:

enter image description here

Limitations:

  • This solution only updates HideOverlayView on onCameraChange , so when a user enlarges or pans the map, other locations on the map may be displayed.
  • The calculations performed to calculate the radius do not take into account the rotation and inclination of the map
+3
source

All Articles