Here is my first working version of an Android application in which the user can see and interact with a Web Map Service (WMS), that shows geological information for Denmark. The WMS is described here:
http://geusjuptest.geus.dk/OneGeologyEurope/
The geological WMS is shown using
Google Maps.
Here is the Activity class that displays the google map as well as the WMS (i.e. the myOverlay object)
package dk.geus;
import java.util.List;
import android.os.Bundle;
import android.preference.PreferenceManager;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
public class Map01 extends MapActivity {
private MapView mapView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
mapView = (MapView)findViewById(R.id.map_view);
MapController mapController = mapView.getController();
mapController.setCenter(new GeoPoint(55700000, 12600000));
mapController.setZoom(10);
mapView.setClickable(true);
mapView.setEnabled(true);
mapView.setBuiltInZoomControls(true);
/* MyLocationOverlay myLocOverlay = new MyLocationOverlay(this, mapView);
myLocOverlay.enableMyLocation();
mapView.getOverlays().add(myLocOverlay);*/
List overlays = mapView.getOverlays();
WMSOverlay myOverlay = new WMSOverlay();
boolean lithologyClicked = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("lithologyClicked", true);
if (lithologyClicked){
overlays.add(myOverlay);
}
mapView.postInvalidate();
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
The WMS overlay extends the com.google.android.maps.Overlay Class. In the draw method the WMS is defined (i.e. the WMSLoader class):
>package dk.geus;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
public class WMSOverlay extends Overlay {
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
WMSLoader wmsclient = new WMSLoader();
GeoPoint[] cornerCoords = MapUtils.getCornerCoordinates(mapView.getProjection(), canvas);
Bitmap image = wmsclient.loadMap(canvas.getWidth(), canvas.getHeight(), cornerCoords[0], cornerCoords[1]);
Paint semitransparent = new Paint();
semitransparent.setAlpha(0x888);
canvas.drawBitmap(image, 0, 0, semitransparent);
}
}
The only missing piece is the WMSLoader class - Here it is:
package dk.geus;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.google.android.maps.GeoPoint;
public class WMSLoader {
public static String TAG = "WMSLoader Exception";
public Bitmap loadMap(int width, int height, GeoPoint ul, GeoPoint lr) {
URL url = null;
try {
// http://geusjuptest.geus.dk/oneGEconnector/?service=WMS&version=1.1.1&styles=default&request=GetMap&layers=OGE_1M_surface_GeologicUnit&width=2000&height=2000&bbox=7,54,15.5,58&format=image/png&srs=epsg:4326
url = new URL(String.format("http://geusjuptest.geus.dk/oneGEconnector/?" +
"LAYERS=OGE_1M_surface_GeologicUnit&TRANSPARENT=true&FORMAT=image/png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=default&EXCEPTIONS=application/vnd.ogc.se_inimage&SRS=EPSG:4326" + "" +
"&BBOX=%f,%f,%f,%f&WIDTH=%d&HEIGHT=%d",
MapUtils.longitude(ul), MapUtils.latitude(lr),
MapUtils.longitude(lr), MapUtils.latitude(ul), width, height));
} catch (MalformedURLException e) {
Log.e(TAG, e.getMessage());
}
InputStream input = null;
try {
input = url.openStream();
} catch (IOException e) {
Log.wtf(TAG, "****************** Error in WMSLoader: " + e.getMessage());
}
return BitmapFactory.decodeStream(input);
}
}
And then finally the little MapUtils helper class:
package dk.geus;
import android.graphics.Canvas;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.Projection;
public class MapUtils {
static float longitude(GeoPoint point){
return (float) (point.getLongitudeE6()/1e6);
}
static float latitude(GeoPoint point){
return (float) (point.getLatitudeE6()/1e6);
}
static GeoPoint[] getCornerCoordinates(Projection projection,Canvas canvas){
GeoPoint[] geoPoint = new GeoPoint[2];
geoPoint[0]= projection.fromPixels(0, 0);
geoPoint[1]= projection.fromPixels(canvas.getWidth() - 1, canvas.getHeight() - 1);
return geoPoint;
}
}
The application works, but has some major limitations. Main problem is that Panning and Zooming is too slow - Next step will be to retrieve the WMS overlay in an AsyncActivity