Friday, September 22, 2017

Android Custom Map using Osmdroid method



Android Custom Map Guideline


Map Platform


maxresdefault.jpg






Guide
This documentation outlines the step by step guideline of the Android Map SDK project. The below are the functional requirements.
  • Custom tile server
  • Zoom controls
  • Scale Bar
  • Marker & InfoWindow
  • Polygon
  • Polyline
  • Touch event
  • Scroll Event
  • Long Press Event




STEP 1 : Open Android Studio (my version 2.3) and create a project

Provide a project name with company domain and click Next





Select Empty Activity and click Next


Click Finish


STEP 2 : Initialize the project


Switch Android to Project Files section in Project Explorer menu bar, Paste these jar files download link each in the libs folder directly. Then select them right click and Add as a Library. Once done it should look like this :




You will notice these lines added automatically, if not add them manually in build.gradle



Then add these permissions in your AndroidManifest.xml


<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


STEP 3 : Implementation in activity_main.xml


Add a mapview manually in the text section as follows: (I have used Linear Layout)


<org.osmdroid.views.MapView
  android:id="@+id/mapView"
  android:clickable="true"
  android:enabled="true"
  android:layout_width="match_parent"
  android:layout_height="0dp"
  android:layout_weight="1">
</org.osmdroid.views.MapView>

STEP 4 : Implementation in MainActivity.java


Extend your MainActivity class like this :


public class MainActivity extends Activity implements LocationListener {


Then you will see these methods will be overridden automatically below :


@Override
public void onLocationChanged(Location paramLocation) {
 // TODO Auto-generated method stub


}


@Override
public void onProviderDisabled(String paramString) {
 // TODO Auto-generated method stub


}


@Override
public void onProviderEnabled(String paramString) {
 // TODO Auto-generated method stub


}


@Override
public void onStatusChanged(String paramString, int paramInt,
    Bundle paramBundle) {
 // TODO Auto-generated method stub


}


STEP 4.1 : Adding a custom map server


Declare the mapview inside the onCreate method


osm = (MapView) findViewById(R.id.mapView);


After that create a addMap() method and set the URL


// ADDING MAP-------------------------------
public void addMap() {


 osm.setTileSource(new OnlineTileSourceBase("OSM",
       ResourceProxy.string.base_nl, 0, 25, 150, ".png",
       new String[] {
http://tile.openstreetmap.org/{z}/{x}/{y}.png
" }) {


    @Override
    public String getTileURLString(MapTile arg0) {


       return getBaseUrl() + arg0.getZoomLevel() + "/" + arg0.getX()
             + "/" + arg0.getY() + mImageFilenameEnding;
    }
 });
}


STEP 4.2 : Adding a scale bar


Create addScaleBar() method


// ADDING SCALE BAR ON MAPVIEW-------------------------------
public void addScaleBar() {
 ScaleBarOverlay myScaleBarOverlay = new ScaleBarOverlay(this);
 osm.getOverlays().add(myScaleBarOverlay);
}


STEP 4.3 : Adding zoom controls on mapview


Create addZoomControls() method and set the inbuilt controls visible


// ADDING ZOOM CONTROLS ON MAPVIEW-------------------------------
public void addZoomControls() {
 osm.setBuiltInZoomControls(true);
 osm.setMultiTouchControls(true);
}


STEP 4.4 : Adding Geopoints (Latitude and Longitude)


// DEFINING GEOPOINTS--------------------------
GeoPoint kandy = new GeoPoint(7.2906, 80.6337);
GeoPoint jaffna = new GeoPoint(9.6615, 80.0255);
GeoPoint batticaloa = new GeoPoint(7.7310, 81.6747);
GeoPoint badulla = new GeoPoint(6.9934, 81.0550);
GeoPoint ampara = new GeoPoint(7.2318, 81.6473);


STEP 4.4 : Adding marker


Create addMarker() method as follows :


// ADDING MARKER-------------------------------
public Marker addMarker(GeoPoint p, String title, String subTitle) {
 Marker marker = new Marker(osm);
 marker = new Marker(osm);
 marker.setPosition(p);
 osm.getOverlays().add(marker);
 marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
 marker.setIcon(getResources().getDrawable(R.drawable.black));
 marker.setTitle(title);
 marker.setSnippet(subTitle);
 marker.setInfoWindow(new CustomMarkerInfoWindow(osm));
 marker.setInfoWindowAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_TOP);
 marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {


    @Override
    public boolean onMarkerClick(Marker m, MapView arg1) {
       Log.i("Script", "onMarkerClick()");
       m.showInfoWindow();
       return true;
    }


 });


 return marker;


}

Then inside the onCreate method add one or more markers as follows :


marker = new Marker(osm);
marker = addMarker(batticaloa, "Batticaloa", "I'm here!");


marker2 = new Marker(osm);
marker2 = addMarker(jaffna, "Jaffna", "Welcome\nHello Jaffna");

STEP 4.5 : Marker infoWindow


Create a new class called CustomMarkerInfoWindow.java and add new layout as follows


public class CustomMarkerInfoWindow extends MarkerInfoWindow {


 public CustomMarkerInfoWindow(MapView mapView) {
    super(R.layout.my_bubble, mapView);
 }


 @Override
 public void onOpen(Object item) {
    Marker m = (Marker) item;


    TextView title = (TextView) mView.findViewById(R.id.bubble_title);
    title.setText(m.getTitle());


    TextView snippet = (TextView) mView
          .findViewById(R.id.bubble_description);
    snippet.setText(m.getSnippet());


 }
}


Then create another xml inside res/layout folder with two Textviews as follows :


<LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:paddingLeft="6dp"
 android:orientation="vertical" >
     <TextView android:id="@+id/bubble_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#ff0000"
    android:maxEms="10"
    android:textSize="10dp"
    android:layout_gravity="left"
    android:layout_weight="1"
    android:text="Title" />
    
 <TextView android:id="@+id/bubble_description"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#854442"
    android:textSize="8dp"
    android:maxEms="7"
    android:text="Description" />
</LinearLayout>

STEP 4.6 : Adding Polyline


Create a addPolyline() method as follows :


// ADDING POLYLINE--------------------------------
public Polyline addPolyline(ArrayList<GeoPoint> p) {
 Polyline polyline = new Polyline(this);
 polyline.setPoints(p);
 polyline.setColor(Color.BLUE);
 polyline.setWidth(3);
 osm.getOverlays().add(polyline);
 return polyline;


}


Then define the declared geopoints in an array


// DEFINING POLYLINE POINTS----------------------------
ArrayList<GeoPoint> polylinePoints = new ArrayList<GeoPoint>();
polylinePoints.add(badulla);
polylinePoints.add(kandy);
polylinePoints.add(jaffna);


Later add a polyline object inside onCreate method like this :


polyline = new Polyline(this);
polyline = addPolyline(polylinePoints);


STEP 4.7 : Adding Polygon


Create a addPolygon() method as follows :


// ADDING POLYGON--------------------------------
public Polygon addPolygon(ArrayList<GeoPoint> p) {
 Polygon polygon = new Polygon(this);
 polygon.setFillColor(Color.argb(85, 54, 208, 218));
 polygon.setVisible(true);
 polygon.setStrokeColor(Color.BLUE);
 polygon.setStrokeWidth(3);
 polygon.setPoints(p);
 osm.getOverlays().add(polygon);
 return polygon;


}

Then define the declared geopoints in an array


// DEFINING POLYGON POINTS-----------------------------
ArrayList<GeoPoint> polygonPoints = new ArrayList<GeoPoint>();
polygonPoints.add(badulla);
polygonPoints.add(batticaloa);
polygonPoints.add(ampara);

Later add a polygon object inside onCreate method like this :


polygon = new Polygon(this);
polygon = addPolygon(polygonPoints);

STEP 4.8 : Removing marker, polyline and polygon


// REMOVING MARKER, POLYLINE & POLYGON (UNCOMMENT TO ENABLE)---------


// osm.getOverlays().remove(marker1);
// osm.getOverlays().remove(polyline);
// osm.getOverlays().remove(polygon);


STEP 4.9 : Adding onTouch Event (Single & LongPress)


Create a onTapListener() method as follows and add toast messages on its method accordingly:


// GET LATITUDE & LONGITUDE INFORMATION ON TAP
// EVENT-------------------------------
public void onTapListener() {
 MapEventsReceiver mReceive = new MapEventsReceiver() {


    @Override
    public boolean singleTapConfirmedHelper(GeoPoint p) {


       Toast.makeText(
             getBaseContext(),
             "Latitude  " + p.getLatitude() + "\nLongitude  "
                   + p.getLongitude(), Toast.LENGTH_LONG).show();
       return false;


    }


    @Override
    public boolean longPressHelper(GeoPoint p) {
       Toast.makeText(getBaseContext(), "Long Pressed",
             Toast.LENGTH_SHORT).show();
       return false;
    }
 };


 MapEventsOverlay OverlayEvents = new MapEventsOverlay(getBaseContext(),
       mReceive);
 osm.getOverlays().add(OverlayEvents);


}


STEP 4.10 : Handling other Events (Zoom & Scroll)


Create a otherListeners() method :


// ZOOM & SCROLL EVENTS-------------------------------
public void otherListeners() {


 osm.setMapListener(new DelayedMapListener(new MapListener() {
    public boolean onZoom(final ZoomEvent e) {
       Toast.makeText(getBaseContext(), "Zoomed", Toast.LENGTH_SHORT)
             .show();
       return true;
    }

Here i have implemented a timer which takes back the user after any activity to Jaffna (It actually scrolls to the Jaffna’s marker point)


    // THIS TIMER POINTS INTO JAFFNA AFTER USER'S OTHER
    // ACTIVITY-------------------------------
    public boolean onScroll(final ScrollEvent e) {


       new CountDownTimer(10000, 1000) {


          public void onFinish() {
             GeoPoint jaffna = new GeoPoint(9.6615, 80.0255);
             mc.animateTo(jaffna);
             Toast.makeText(getBaseContext(), "Scrolled to Jaffna",
                   Toast.LENGTH_SHORT).show();
          }


          @Override
          public void onTick(long millisUntilFinished) {
             // TODO Auto-generated method stub


          }


       }.start();


       return true;
    }


 }));
}


THAT'S IT! NOW YOUR MAP SHOULD LOOK LIKE BELOW :)WhatsApp Image 2017-09-19 at 10.32.49 AM.jpeg