loading...

Drawing on Map made easy with Huawei Map kit

irene83018774 profile image Irene ・5 min read

Introduction

With the Huawei Maps SDK for Android, you can add maps to your application. You can also use API calls to add markers, polygons, and overlays to a basic map, and to change the user's view of a particular map area. These objects provide additional information for map locations, and allow user interaction with the map. The API allows you to add these graphics to a map:

  • Icons anchored (Markers) to specific positions on the map.
  • Sets of line segments (Polylines).
  • Enclosed segments (Polygons).
  • Bitmap graphics anchored to specific positions on the map (Ground Overlays).
  • Sets of images which are displayed on top of the base map tiles (Tile Overlays). Alt Text

Prerequisite

  • Java JDK 1.8 or higher is recommended.
  • Android Studio is recommended.
  • Huawei android device with HMS core 4.0.0.300 or higher.
  • Before developing an app, you will need to register as a HUAWEI developer. Please refer to Register a HUAWEI ID
  • Integrating app gallery connect SDK. Please refer to AppGallery Connect Service Getting Started.

Integration

  • Enable Map kit in Manage APIS. Please refer to Service Enabling. Alt Text
  • Integrate Map kit dependencies by adding following code in app-level build.gradle.
dependencies {
    implementation 'com.huawei.hms:maps:4.0.1.302'
}
  • Add following permissions in Manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>

//To obtain current device location
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

  • To provide real time permission
private void requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Log.i(TAG, "sdk >= 23 M");
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            String[] strings =
                    {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
            ActivityCompat.requestPermissions(this, strings, 1);
        }
    }
}

Initialize Map

  • Add following code to in your xml file to set the map attributes
<com.huawei.hms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mapview_mapviewdemo"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     map:cameraTargetLat="20.593683"
     map:cameraTargetLng="78.962883"
    map:cameraZoom="4.5"
   />
  • To use map in your app , you need to Implement OnMapReadyCallback.
public class PolylineholderFragment extends Fragment implements OnMapReadyCallback {

@Override
public void onMapReady(HuaweiMap huaweiMap) {

    }
}
  • Load MapView in the onCreate() or onCreateView() method and call getMapAsync() to register the callback.
private MapView mMapView;

@Override
public View onCreateView(
        @NonNull LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.fragment_main, container, false);
    mMapView = root.findViewById(R.id.mapview_mapviewdemo);
    mMapView.getMapAsync(this);
    return root;
}
  • To obtain the HuaweiMap object, Call the onMapReady callback
private HuaweiMap map;

@Override
public void onMapReady(HuaweiMap huaweiMap) {
    Log.d(TAG, "onMapReady: ");
    map = huaweiMap;

}

Polyline

A polyline is an overlay on a map that's created by connecting line segments in an ordered sequence in Maps. You can use a polyline to draw lines on a map.
Alt Text
To create a polyline object :

private LatLng amritsarLatLong = new LatLng(31.633980, 74.872261);
private LatLng delhiLatLong = new LatLng(28.704060, 77.102493);
private LatLng bangaloreLatLong = new LatLng(12.971599, 77.594566);
private LatLng hyderabadLatLong = new LatLng(17.3850, 78.4867);
private LatLng kanyakumariLatLong = new LatLng(8.0883, 77.5385);

@Override
public void onMapReady(HuaweiMap huaweiMap) {
    Log.d(TAG, "onMapReady: ");
    map = huaweiMap;
     // To add polyline
      addPolyline();

}

private void addPolyline() {
    if (null != mPolyline) {
        mPolyline.remove();
        mPolyline = null;
    }
    mPolyline = map.addPolyline(new PolylineOptions()
            .add( amritsarLatLong,delhiLatLong,hyderabadLatLong,bangaloreLatLong,kanyakumariLatLong )
            .color(Color.BLUE)
            .width(3));
}

Clustering Markers

Using Map SDK, you can cluster markers to manage multiple markers at different zoom level. When user zooms in the map, all the markers are displayed, but when user zooms out, all markers are clustered on the map.
Alt Text
Alt Text
The following code demonstrate the implementation of clustered marker

@Override
    public void onMapReady(HuaweiMap huaweiMap) {
        Log.d(TAG, "onMapReady: ");
        map = huaweiMap;

        if (null == map) {
            return;
        }


        map.moveCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(12.9716, 77.5946),8));

        map.addMarker(new MarkerOptions().position(new LatLng(12.9352,77.6245)).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_map)).title("Koramangala").snippet("This is Koramangala").clusterable(true));


        map.addMarker(new MarkerOptions().position(new LatLng(12.9738 , 77.6119)).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_map)).title("M G Road").snippet("This is M G Road").clusterable(true));

        map.addMarker(new MarkerOptions().position(new LatLng(12.9304, 77.6784)).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_map)).title("Bellandur").snippet("This is Bellandur").clusterable(true));

        map.addMarker(new MarkerOptions().position(new LatLng(12.9569, 77.7011)).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_map)).title("Marathahalli").snippet("This is Marathahalli").clusterable(true));

        map.addMarker(new MarkerOptions().position(new LatLng(12.9552,      77.6646)).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_map)).title("HAL").snippet("This is HAL").clusterable(true));

        map.setMarkersClustering(true);

        map.setOnMarkerClickListener(markerClickListener);
    }

    HuaweiMap.OnMarkerClickListener markerClickListener = new HuaweiMap.OnMarkerClickListener() {
    @Override
    public boolean onMarkerClick(Marker marker) {
        Toast.makeText(getContext(), "clicked marker : " + marker.getTitle(), Toast.LENGTH_SHORT).show();
        return false;
    }
};

Ground Overlay

A ground overlay is a fixed image on the map.
Image can be fetched from

  • File : BitmapDescriptorFactory.fromFile(fileName);
  • Resource : BitmapDescriptorFactory.fromResource(R.drawable.flag)
  • Asset : BitmapDescriptorFactory.fromAsset("images/flag.jpg")
  • Path : BitmapDescriptorFactory.fromPath(path);
  • Bitmap : BitmapDescriptorFactory.fromBitmap(bitmap); Alt Text The following code demonstrate the implementation of ground overlay. Here we will fetch the image from resource
private GroundOverlay mGroundOverlay;

@Override
public void onMapReady(HuaweiMap huaweiMap) {
    Log.d(TAG, "onMapReady: ");
    map = huaweiMap;

    if (map == null) {
        return;
    }
    if (null != mGroundOverlay) {
        mGroundOverlay.remove();
    }

    addGroundOverlay() ;
}

private void addGroundOverlay() {
    BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.karnataka_flag);

    GroundOverlayOptions options =
            new GroundOverlayOptions().position(new LatLng(12.9716, 77.5946), 60, 30).image(descriptor);
    mGroundOverlay = map.addGroundOverlay(options);

    CameraPosition position =
            CameraPosition.builder().target(new LatLng(12.9716, 77.5946)).zoom(18).bearing(0f).tilt(0f).build();
    CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(position);

    map.moveCamera(cameraUpdate);
    map.setOnGroundOverlayClickListener(ongroundOverlayclickListner);
}

HuaweiMap.OnGroundOverlayClickListener ongroundOverlayclickListner = new HuaweiMap.OnGroundOverlayClickListener() {
    @Override
    public void onGroundOverlayClick(GroundOverlay groundOverlay) {
        Toast.makeText(getContext(), "Flag is clicked.", Toast.LENGTH_LONG).show();
    }
};

Adding a Circle

To add a circle on map, we need to create circle object

private Circle mCircle;

@Override
public void onMapReady(HuaweiMap huaweiMap) {
    Log.d(TAG, "onMapReady: ");
    map = huaweiMap;

    if (null == map) {
        return;
    }
    if (null != mCircle) {
        mCircle.remove();
    }
    mCircle = map.addCircle(new CircleOptions()
            .center(new LatLng(12.9552, 77.6646))
            .radius(6200)
            .fillColor(Color.parseColor("#05ff0000")));
    mCircle.setStrokeColor(Color.RED);

    }

Marker Drag event

To drag a marker, user needs to long click on the marker and drag it to specified position on the screen and drop it.
Alt Text
We need to use HuaweiMap.OnMarkerDragListener to listen to drag movement with drag attribute being set to true.

private Marker mMarker;

@Override
public void onMapReady(HuaweiMap huaweiMap) {
    Log.d(TAG, "onMapReady: ");
    map = huaweiMap;

            mMarker = map.addMarker(new MarkerOptions()
            .position(new LatLng(13.0055, 77.5692)).title("Malleshwaram")
            .icon(BitmapDescriptorFactory.fromResource(R.drawable.streetview)));
    /**
     * Set Marker to be draggable
   */
    mMarker.setDraggable(true);
    map.setOnMarkerDragListener(onMarkerDragListner);
}


   HuaweiMap.OnMarkerDragListener onMarkerDragListner = new HuaweiMap.OnMarkerDragListener() {
        @Override
        public void onMarkerDragStart(Marker marker) {
            Log.d(TAG, "onMarkerDragStart");
            LatLng latLng = marker.getPosition();
            double latitude =  latLng.latitude;
            double longitude  = latLng.longitude;
            Log.d(TAG, "Lat Long coordiantes are " + latitude + ", " + longitude);
        }

        @Override
        public void onMarkerDrag(Marker marker) {
            Log.d(TAG, "onMarkerDrag");
            LatLng latLng = marker.getPosition();
            double latitude =  latLng.latitude;
            double longitude  = latLng.longitude;
           Log.d(TAG, "Lat Long coordianted are " + latitude + ", " + longitude);
        }

        @Override
        public void onMarkerDragEnd(Marker marker) {
            Log.d(TAG, "onMarkerDragEnd");
            LatLng latLng = marker.getPosition();
            double latitude =  latLng.latitude;
            double longitude  = latLng.longitude;
            Log.d(TAG, "Lat Long coordiantes are " + latitude + ", " + longitude);
        }
    };

Summary

In the article we learnt how to draw polyline, ground overlay, marker clusters and dragging the image.

Posted on by:

Discussion

markdown guide