I am a “beginner” who started Android development about 6 months ago. I am really impassioned on the topic, and I read several books:
Those books enabled me to understand a lot the way Android works. But what lacks to me is now… experience. So I decided to contribute to a project, whose goal is to display a huge subway map—of course, the project’s goals are wider, but talking about it is not relevant to this question.
The map is stored offline, in my application’s package.
Also, using only one big image cannot do the trick: it causes extreme image quality loss.
I split my huge map into 5 different map tiles, which are basically rectangles in landscape format. I put them all (map[1-5].jpg), plus a HTML file (map.html), into the ./assets/ folder. The HTML file’s code is the following:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Huge map</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="user-scalable=yes, height=device-height, target-densityDpi=device-dpi">
<style type="text/css">
html, body, p, img { margin: 0; }
img { border: 0; }
p { height: 100%; min-height: 100%; }
</style>
</head>
<body>
<p><!-- Displaying a 2000×2000px map -->
<img src="file:///android_asset/map1.jpg" alt=""><br> <!-- 2000×408px -->
<img src="file:///android_asset/map2.jpg" alt=""><br> <!-- 2000×408px -->
<img src="file:///android_asset/map3.jpg" alt=""><br> <!-- 2000×408px -->
<img src="file:///android_asset/map4.jpg" alt=""><br> <!-- 2000×408px -->
<img src="file:///android_asset/map5.jpg" alt=""> <!-- 2000×368px -->
</p>
</body>
</html>
Which I then load in my Java code and apply it to my layout (which is but a WebView):
import me.diti.test.R;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class MapActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map); // ./res/layout/map.xml with a <WebView>
WebView mWebView = (WebView) findViewById(R.id.mapWebView); // The WebView’s id is mapWebView
WebSettings webSettings = mWebView.getSettings();
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH); // Attempt at getting better performance…
webSettings.setAppCacheEnabled(false); // Offline map: no need for cache
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
mWebView.setInitialScale(100);
mWebView.setScrollBarStyle(WebView.SCROLLBARS_INSIDE_OVERLAY);
mWebView.loadUrl("file:///android_asset/map.html"); // We load the map (includes 5 big images)
}
/* This is a minimal “working” example, no need for menu inflation and activity handling */
min-height
seems not to work);What is the best way to display a huge, custom map, with good performance and relative easiness to use? Is my solution acceptable? How to fix the flaws? I read a lot of StackOverflow questions concerning all that (custom maps, WebView performance), but none of them helped me.
Looking forward to your help, thank you in advance.
I think splitting the large image into tiles is a good approach, but I think you need to take it further than just 5 images. Try splitting it into 100 200x200 images in a 10x10 grid (or 64 250x250 images in an 8x8 etc). Then use a <table>
to display them in your existing WebView
.
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td><img src="file:///android_asset/map00.00.jpg" border="0"></td>
<td><img src="file:///android_asset/map00.01.jpg" border="0"></td>
...
<td><img src="file:///android_asset/map00.09.jpg" border="0"></td>
</tr>
<tr>
<td><img src="file:///android_asset/map01.00.jpg" border="0"></td>
<td><img src="file:///android_asset/map01.01.jpg" border="0"></td>
...
<td><img src="file:///android_asset/map01.09.jpg" border="0"></td>
</tr>
...
</table>
Using a simple ImageView to display the map is “not possible”, since zooming, panning, etc. are not supported, and coding this myself goes far beyond my capabilities.
You can find third-party code for panning and zooming an ImageView
, such as this one, though that probably will not help you.
What is the best way to display a huge, custom map, with good performance and relative easiness to use?
Use a tile-based map viewer. OSMDroid has some support for this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With