-
Notifications
You must be signed in to change notification settings - Fork 335
Home
The TileView widget is a subclass of ViewGroup that provides a mechanism to asynchronously display tile-based images, with additional functionality for 2D dragging, flinging, pinch or double-tap to zoom, adding overlaying Views (markers), built-in Hot Spot support, dynamic path drawing, multiple levels of detail, and support for any relative positioning or coordinate system.
Following the steps to follow to create a new project.
In Eclipse : Menu File/New/Android Application Project
Then fill the name and the package of the application. Exemple :
Press Next button for the next screens, till the end (Finish Button).
To add the library [Jake Wharton's DiskLruCache] (https://github.com/JakeWharton/DiskLruCache) to the project do the following steps:
- Download the jar Here
- Then add the downloaded file to the folder "libs" of your project
- Download the current project and put the src files in your src folder
- Then in Eclipse, refresh your project
You'll have the following:
Image Magick is a tool that will allow us to generate all the needed pictures (all the tiles).
- Go to the [Image Magick web site] (http://www.imagemagick.org/) and install it.
For this exemple we will use a big world map.
- Go to [here] (http://panda-blog.org.uk/world-map/)
- Download the big map :-D
Then split it using Image Magick: you can use the following script (under Windows) to generate the nedded pictures.
Note: _J:\installed\ImageMagick-6.8.6-Q16_ is the folder where I have installed Image Magic, the best: add it to your PATH:
@echo off set filename=big-world-map.gif set /a tilesize=256 set /a downsamplesize=1000 set tilesfolder=tiles set downsamplesfolder=downsamples mkdir %tilesfolder% %downsamplesfolder% echo Generate the smaller map images (divide by 2 each time) echo Generate 1/2 J:\installed\ImageMagick-6.8.6-Q16\convert %filename% -resize 50%% map500.jpg echo Generate 1/4 J:\installed\ImageMagick-6.8.6-Q16\convert %filename% -resize 25%% map250.jpg echo Generate 1/8 J:\installed\ImageMagick-6.8.6-Q16\convert %filename% -resize 12.5%% map125.jpg echo Generate the smaller map images (divide by 2 each time) J:\installed\ImageMagick-6.8.6-Q16\convert %filename% -resize %downsamplesize%x%downsamplesize% ./%downsamplesfolder%/map.png echo Generate the downsample map J:\installed\ImageMagick-6.8.6-Q16\convert %filename% -crop %tilesize%x%tilesize% -set filename:tile "%%[fx:page.x/%tilesize%]_%%[fx:page.y/%tilesize%]" +repage +adjoin "./%tilesfolder%/1000_%%[filename:tile].png" echo Generate the tile for the half size map J:\installed\ImageMagick-6.8.6-Q16\convert map500.jpg -crop %tilesize%x%tilesize% -set filename:tile "%%[fx:page.x/%tilesize%]_%%[fx:page.y/%tilesize%]" +repage +adjoin "./%tilesfolder%/500_%%[filename:tile].png" echo Generate the tile for the 1/4 size map J:\installed\ImageMagick-6.8.6-Q16\convert map250.jpg -crop %tilesize%x%tilesize% -set filename:tile "%%[fx:page.x/%tilesize%]_%%[fx:page.y/%tilesize%]" +repage +adjoin "./%tilesfolder%/250_%%[filename:tile].png" echo Generate the tile for the 1/8 size map J:\installed\ImageMagick-6.8.6-Q16\convert map125.jpg -crop %tilesize%x%tilesize% -set filename:tile "%%[fx:page.x/%tilesize%]_%%[fx:page.y/%tilesize%]" +repage +adjoin "./%tilesfolder%/125_%%[filename:tile].png" echo DONE pause
Then put the generated files (folders downsamples AND tiles) in the assets folder. Under Eclipse, refresh your project, you'll now have the following.
The minimum implementation requires that setSize be called, and at least one detail level (tile set) is registered.
Edit the MainActivity.java class file
Replace the current code:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
By:
TileView tileView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create our TileView tileView = new TileView(this); // Set the minimum parameters tileView.setSize(6252,4087); tileView.addDetailLevel(1f, "tiles/1000_%col%_%row%.png", "downsamples/map.png"); // Add the view to display it setContentView(tileView); }
As we have generated 4 zoom level of tiles we can use them:
Replace the previous code:
// Set the minimum parameters tileView.setSize(6252,4087); tileView.addDetailLevel(1f, "tiles/1000_%col%_%row%.png", "downsamples/map.png");
By:
tileView.setSize(6252,4087); tileView.addDetailLevel(1f, "tiles/1000_%col%_%row%.png", "downsamples/map.png"); tileView.addDetailLevel(0.5f, "tiles/500_%col%_%row%.png", "downsamples/map.png"); tileView.addDetailLevel(0.25f, "tiles/250_%col%_%row%.png", "downsamples/map.png"); tileView.addDetailLevel(0.125f, "tiles/125_%col%_%row%.png", "downsamples/map.png");
Now we can center our map by default, and set the default zoom by adding the following code at the end of the method onCreate:
// use pixel coordinates to roughly center it // they are calculated against the "full" size of the mapView // i.e., the largest zoom level as it would be rendered at a scale of 1.0f tileView.moveToAndCenter( 6252, 4087 ); tileView.slideToAndCenter( 6252, 4087 ); // Set the default zoom (zoom out by 4 => 1/4 = 0.25) tileView.setScale( 0.25 );
To add some markers on our map:
- Add the following image
to the res\drawable-hdpi folder
- Then add the following code:
ImageView markerA = new ImageView(this); markerA.setImageResource(R.drawable.maps_marker_blue); markerA.setTag("Nice"); ImageView markerB = new ImageView(this); markerB.setImageResource(R.drawable.maps_marker_blue); markerB.setTag("Paris"); tileView.addMarker(markerA, 3245, 2056, -0.5f, -1.0f); tileView.addMarker(markerB, 3162, 1942, -0.5f, -1.0f);
You can also set some listeners on the click over the markers using:
tileView.addMarkerEventListener(new MarkerEventListener(){ @Override public void onMarkerTap( View view, int x, int y ){ Log.d("Marker Event", "marker tag = " + view.getTag() ); } });
If you want to use Geographic coordinate system, you can define the relative bounds of your map. You must set the top left and bottom right bounds using this code:
tileView.defineRelativeBounds( 42.379676, -71.094919, 42.346550, -71.040280);
After this line, all the coordinates will use the Geographic coordinate system and no more the pixel based coordonate.
You can activate the cache is you are using remote pictures with the following code:
tileView.setCacheEnabled( true );