Use OSMDROID to display my server generated map tiles - android

I am trying to display map tiles using osmdroid. but it is displaying blank screen.
This is my code:
map.setZ(100);
map.setTileSource(new OnlineTileSourceBase("", 12, 18, 256, ".png",
new String[]{"https://storage.googleapis.com/brainpool/user-files/brainpoollicense/maptiles/PL53LY4K0EDYMX/"}) {
#Override
public String getTileURLString(long pMapTileIndex) {
return getBaseUrl()
+ MapTileIndex.getZoom(pMapTileIndex)
+ "/" + MapTileIndex.getX(pMapTileIndex)
+ "/" + MapTileIndex.getY(pMapTileIndex)
+ mImageFilenameEnding;
}
});
map.setMultiTouchControls(true);
IMapController mapController = map.getController();
GeoPoint startPoint;
startPoint = new GeoPoint(151.2927108765, -32.779342448);
mapController.setZoom(12F);
mapController.setCenter(startPoint);
map.invalidate();
createmarker();
This is output:
Also, note that i am getting this in output always:
W/OsmDroid: Problem downloading MapTile: /12/1674/2 HTTP response: Not Found
My question is when getTileURLString method is called? because it is called for the values which are taking wrong z/x/y which do not exist on the server.

Related

OSM maps look scrambled on android

I am trying to load OpenStreetMaps on an android app but the map does not load correctly. They are displayed unordered.
I am using a self-hosted map server which loads correctly in a browser (Used leaflet for the demo).
The code as follows,
public class MapActivity extends AppCompatActivity {
final private int MIN_ZOOM_LEVEL = 3;
final private int MAX_ZOOM_LEVEL = 18;
final private int TILE_SIZE = 256;
final private String IMAGE_EXTENSION = ".png";
MapView map = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//load/initialize the osmdroid configuration
Context ctx = getApplicationContext();
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
setContentView(R.layout.activity_map);
map = (MapView) findViewById(R.id.map);
map.setTilesScaledToDpi(true);
map.setMultiTouchControls(true);
map.setTileSource(new OnlineTileSourceBase("Tiles", 2, 18, 256, ".png",
new String[] { "http://maps.MY-DOMAIN.com/tile/" }) {
#Override
public String getTileURLString(long pMapTileIndex) {
String url = getBaseUrl()
+ MapTileIndex.getZoom(pMapTileIndex)
+ "/" + MapTileIndex.getX(pMapTileIndex)
+ "/" + MapTileIndex.getY(pMapTileIndex)
+ mImageFilenameEnding;
Log.e("MAP",url);
return url;
}
});
}
}
What I end up getting is,
How can I solve this issue? I have taken a look into the documentation but nothing is mentioned about this.
Either the tile source is z/x/y vs z/y/x OR the y coordinate is inverted the tile source is closer to the TMS specification vs the slippy map format that open street maps uses. In either case, correct the issue, clear the tile cache, then try it again

How to center Google maps driving directions between destination and source

I am using google maps URL commands to draw driving directions from a source to destination using the following commands:
String geoUriString = "http://maps.google.com/maps?" +
"saddr=" + latitude + "," + longitude + "&daddr=" + destLAT+ "," + destLONG;
then
Intent mapCall = new Intent(Intent.ACTION_VIEW, Uri.parse(geoUriString));
startActivity(mapCall);
This opens a list of options, when I choose google maps, it shows me the driving directions from the source to destination.
I have this question:
how can I zoom the map out to fit the drawn path from source to destination? (because now it is zoomed in too much, the full path is not shown at once)
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(18.49866955, 73.8957357166667),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);

How to use MOBAC created OSMDroid SQLite tile source file offline?

I've been pulling my hair out trying to get my own offline Mobile Atlas Creator OSMDroid SQLite map working with OSMDroid 3.0.8 without luck. It's been a long 3 days. I'll try to explain with clips from my application. I've been extending ItemizedIconOverlay and OverlayItem so I hope it doesn't get too confusing.
I created my own OSMDroid SQLite map file with 3 different zoom levels for a small are, like 10 square kms. I copied the resulting "base.sqlite" file into my project /res/raw/ directory. Note that the GeoPoints in my application should be well within the map's tile range. The "base.sqlite" file should get saved to the application specific data directory.
Next I turfed the /osmdroid directory on my phone so I could get the previously cached maps off. I thought I had my own offline maps working until I turned on Airplane mode and noticed the cached maps were still available.
Now all I get is blanks. I have no clue how to get this going. I've see a couple of examples but after a ton of experimentation I haven't been successful in getting any of them working.
private Hashtable<String, NodeOverlayItem> nodes = new Hashtable<String, NodeOverlayItem>();
private MapView mapView;
private Context context;
private LocationManager locManager;
private MapController mapController;
private MapTileProviderArray mapProvider;
private String mapTileArchivePath = "base.sqlite";
private ResourceProxy resourceProxy;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
this.mapView = new MapView(this, 256);
this.mapView.setBuiltInZoomControls(true);
this.mapView.setMultiTouchControls(true);
this.context = this.getApplicationContext();
this.resourceProxy = new DefaultResourceProxyImpl(context);
XYTileSource TILERENDERER = new XYTileSource("test",
ResourceProxy.string.offline_mode,
1, 20, 256, ".png", "http://127.0.0.1");
SimpleRegisterReceiver simpleReceiver = new SimpleRegisterReceiver(this.context);
IArchiveFile[] archives = { ArchiveFileFactory.getArchiveFile(this.getMapsFile()) };
MapTileModuleProviderBase moduleProvider = new MapTileFileArchiveProvider(
simpleReceiver,
TILERENDERER,
archives);
this.mapProvider = new MapTileProviderArray(TILERENDERER, null, new MapTileModuleProviderBase[] { moduleProvider });
this.mapProvider.setUseDataConnection(false);
this.mapView = new MapView(this, 256, this.resourceProxy, this.mapProvider);
this.mapView.setUseDataConnection(false);
mapController = mapView.getController();
mapController.setZoom(18);
mapController.setCenter(new GeoPoint((int)(45.349622 * 1E6), (int)(-75.880700 *1E6)));
this.setContentView(mapView);
} catch(Exception ex) {
Log.e("test", ex.getMessage());
}
}
public File getMapsFile() throws IOException {
Log.d("test", "Trying to load map tiles to: " + this.mapTileArchivePath);
FileOutputStream fos = this.openFileOutput(this.mapTileArchivePath, Context.MODE_PRIVATE);
InputStream in = getResources().openRawResource(R.raw.osmdroid);
byte[] buff = new byte[1024];
int read = 0;
try {
while ((read = in.read(buff)) > 0) {
fos.write(buff, 0, read);
}
} finally {
in.close();
fos.close();
}
return new File(this.getFilesDir(), this.mapTileArchivePath);
}
OK! I know what I doing wrong and I have it all working now! (I'm excited :)
Firstly, I had some trouble with writing my Raw resource map file to the application specific directory (e.g. openFileOutput()) I'm using a Galaxy Nexus which doesn't have an SD slot so I can't dump the map file to SD. Ensure the maps file you intend to use is byte compared with the original copy. Eclipse's DDMS perspective is useful to view a device's file structure.
I also switched to the OSMdroid Zip format. I then made sure the XYTileSource() name matched the directory created in the Zip file by MOBAC, plus ensure the tile size and zoom levels match.
XYTileSource TILERENDERER = new XYTileSource("OSM CloudMade 1", ResourceProxy.string.offline_mode, 16, 18, 256, ".png", "http://127.0.0.1");
MOBAC by default will create 256 pixel tiles. I created an atlas file with 16, 17, and 18 zoom levels. PNG is the default MOBAC tile image format.
Also, if your map file has any issues, ArchiveFileFactory.getArchiveFile() will catch them, even before MapTileFileArchiveProvider.
Here's my usage. Just make every effort to get your IArchive setup correctly and you should be ok:
XYTileSource TILERENDERER = new XYTileSource("OSM CloudMade 1", ResourceProxy.string.offline_mode, 16, 18, 256, ".png", "http://127.0.0.1");
SimpleRegisterReceiver simpleReceiver = new SimpleRegisterReceiver(this.context);
IArchiveFile[] archives = { ArchiveFileFactory.getArchiveFile(this.getMapsSdCard()) };
MapTileModuleProviderBase moduleProvider = new MapTileFileArchiveProvider(
simpleReceiver,
TILERENDERER,
archives);
this.mapProvider = new MapTileProviderArray(TILERENDERER, null, new MapTileModuleProviderBase[] { moduleProvider });
this.mapProvider.setUseDataConnection(false);
this.mapView = new MapView(this, 256, this.resourceProxy, this.mapProvider);
this.mapView.setUseDataConnection(false);
Maybe I'm the only one who had trouble with this, but osmdroid doesn't clearly document how to do this, and when I opened the issue I couldn't get them to comment on my usage. If they had said I was implementing MapTileFileArchiveProvider correctly or included a good offline mapping sample, I would have focused on everything else first.
If you want to use sqlite db you only have to change
ArchiveFileFactory.getArchiveFile(this.getMapsSdCard())
to
MBTilesFileArchive.getDatabaseFileArchive(f)
where f is a File that points to your sqlite database.

Infobox on polygons in Bing Maps Android SDK

I'm using the Bing Maps Android SDK and I'm looking for a way to click on the polygons that I have created and show an infobox. I've been able to accomplish this for a pushpin, but not for a polygon. I have seen this answer, but my app needs will make hundreds of such polygons, and I'm looking for a faster solution using the addHandler method on polygons. I know this is possible for the AJAX v7 flavour of the SDK, which is the underlying base of the Android SDK.
The code I tried for the AJAX version (tested using this emulator.)
map.entities.clear();
latlon = map.getCenter();
var polygon = new Microsoft.Maps.Polygon([new Microsoft.Maps.Location(latlon.latitude, latlon.longitude-0.15), new Microsoft.Maps.Location(latlon.latitude+0.1, latlon.longitude-0.05), new Microsoft.Maps.Location(latlon.latitude+0.1, latlon.longitude+0.05), new Microsoft.Maps.Location(latlon.latitude, latlon.longitude+0.15), new Microsoft.Maps.Location(latlon.latitude-0.1, latlon.longitude+0.05), new Microsoft.Maps.Location(latlon.latitude-0.1, latlon.longitude-0.05), new Microsoft.Maps.Location(latlon.latitude, latlon.longitude-0.15)], null);
Microsoft.Maps.Events.addHandler(polygon, 'click', DisplayInfo);
map.setView( {zoom:10});
map.entities.push(polygon);
function DisplayInfo (e) {
var vertices = e.target.getLocations();
var verticeCenter = new Microsoft.Maps.Location(0,0);
//Calculating location of center
for (i=0; i<vertices.length-1; i++) {
verticeCenter.latitude = verticeCenter.latitude + vertices[i].latitude;
verticeCenter.longitude = verticeCenter.longitude + vertices[i].longitude;
}
verticeCenter.latitude = verticeCenter.latitude / (vertices.length - 1);
verticeCenter.longitude = verticeCenter.longitude / (vertices.length - 1);
defaultInfobox = new Microsoft.Maps.Infobox(verticeCenter, {width: 200, height: 50} );
map.entities.push(defaultInfobox);
}
However, I pushed a similar code to the BingMapsAndroid.js from the assets folder of the SDK, but that doesn't work. The handler is attached, as I checked using the hasHandler method. Touches are recorded and their lat and long values are sent to the log, but the polygon event is not evoked even when the touch lies inside a polygon.
Polygon test function in BingMapsAndroid.js:
this.PolygonTest = function() {
_map.entities.clear();
latlon = new Microsoft.Maps.Location(1,1);
console.log("Polygon test function");
var polygon = new Microsoft.Maps.Polygon([new Microsoft.Maps.Location(latlon.latitude, latlon.longitude-0.15), new Microsoft.Maps.Location(latlon.latitude+0.1, latlon.longitude-0.05), new Microsoft.Maps.Location(latlon.latitude+0.1, latlon.longitude+0.05), new Microsoft.Maps.Location(latlon.latitude, latlon.longitude+0.15), new Microsoft.Maps.Location(latlon.latitude-0.1, latlon.longitude+0.05), new Microsoft.Maps.Location(latlon.latitude-0.1, latlon.longitude-0.05), new Microsoft.Maps.Location(latlon.latitude, latlon.longitude-0.15)], null);
try {
Microsoft.Maps.Events.addHandler(polygon, 'click', function(e) { console.log("Polygon click!"); }); //This is never evoked
Microsoft.Maps.Events.addHandler(_map, 'click', function(e) { var point = new MM.Point(e.getX(), e.getY()); var loc = e.target.tryPixelToLocation(point); console.log("lat: " + loc.latitude + ", lon: " + loc.longitude); });
} catch(e) {
alert("Error");
}
_map.setView( {zoom:10});
_map.entities.push(polygon);
if (Microsoft.Maps.Events.hasHandler(polygon,'click')) {
console.log("Polygon has click handler."); //This works
}
//This function should be added to the click handler for polygon. I'll add it when I know the handler works.
function DisplayInfo (e) {
console.log("Polygon has been clicked.");
var vertices = e.target.getLocations();
var verticeCenter = new Microsoft.Maps.Location(0,0);
for (i=0; i<vertices.length-1; i++) {
verticeCenter.latitude = verticeCenter.latitude + vertices[i].latitude;
verticeCenter.longitude = verticeCenter.longitude + vertices[i].longitude;
}
verticeCenter.latitude = verticeCenter.latitude / (vertices.length - 1);
verticeCenter.longitude = verticeCenter.longitude / (vertices.length - 1);
defaultInfobox = new Microsoft.Maps.Infobox(verticeCenter, { width: 200, height: 50 });
_map.entities.push(defaultInfobox);
}
}
After much testing, I found the issue lies in Android. I tried the code on Bing Maps Interactive SDK for AjaxV7 and these are my results:
Desktop browsers: works (as written in the question)
iPhone 4S: works
Android 2.3.4 with default browser: does not work
Android 2.3.4 with Opera: works
Android ICS with Opera: works
Android ICS with default browser: does not work

Android, Google Maps won't show

I'm making an app that needs to show a location that I define with latitude and longitude. Everything goes fine, it opens Google maps in my app screen but the maps won't show up!
This is the code I use...
public class MapsActivity extends MapActivity {
MapView mapView;
MapController mc;
GeoPoint p;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//vraag custom title bar
requestCustomTitle();
setContentView(R.layout.mapsactivity);
//Titel dynamisch invullen volgens taalvoorkeuren, roept methode setCustomTitle op
setCustomTitle(getResources().getString(R.string.MapsTitel));
showZoom();
locate(getIntent().getStringExtra("kantoorLat"), getIntent().getStringExtra("kantoorLng"));
addMarker();
}
/*
* De methode showZoom zorgt ervoor dat de zoombuttons worden getoond
*/
private void showZoom(){
mapView = (MapView) findViewById(R.id.mapView);
LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);
View zoomView = mapView.getZoomControls();
zoomLayout.addView(zoomView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mapView.displayZoomControls(true);
}
/*
* De methode locate zorgt ervoor dat de juiste locatie wordt getoond
*/
private void locate(String strlat, String strlng){
mc = mapView.getController();
String coordinates[] = {strlat,strlng};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
p = new GeoPoint((int)(lat * 1E6), (int)(lng * 1E6));
mc.animateTo(p);
mc.setZoom(17);
mapView.invalidate();
}
/*
* De methode addMarker zorgt ervoor dat er een indicator staat op de locatie
*/
private void addMarker(){
MapOverlay mapOverlay = new MapOverlay();
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
}
protected boolean isRouteDisplayed(){
return false;
}
class MapOverlay extends com.google.android.maps.Overlay{
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when){
super.draw(canvas, mapView, shadow);
Point screenPts = new Point();
mapView.getProjection().toPixels(p,screenPts);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.accentindicator);
canvas.drawBitmap(bmp, screenPts.x+7, screenPts.y-19, null);
return true;
}
}
MD5 key will not work on different machines.
You need to generate MD5 debug key for the current SDK that you are using.
Generate the debug key for your current machine and try again.
Get a API key here
http://code.google.com/apis/maps/signup.html
Put the following rule in your AndroidManifest
<uses-permission android:name="android.permission.INTERNET" />
Check the following blog entry that lists down the reasons that might cause this issue.
http://blog.doityourselfandroid.com/2011/01/18/using-google-maps-in-your-android-app/
Besides the activity, its also the manifest, the layout or the API key that can be invalid.
In short
The Android SDK needs to be setup to
support Google Maps.
A MapView
component needs to be added to your
layout, containing a valid Google
Maps API key
The Activity that will
be responsible for showing the map
needs to extend from MapActivity
The
application manifest needs to be
setup with the
android.permission.INTERNET
permission
The application manifest
needs to be setup with the
com.google.android.maps library
In your case, it's most likely internet connectivity (permisson in manifest and/or emulator internet access) or an invalid API key. Keep in mind that the API key is linked to the certificate used to sign your APK.
You need to get the key to access Google map in your application and after getting key you have to add library in ue manifest file which will be installed automatic when u got the key.
I think its your emulator version problem.Android sdk 2.2 emulators some times doesnot show the exact location.Try to run emulator 2.1 .
Even using the Google API Introduction I have had problems like this.
I followed this tutorial and it worked for me:
http://www.vogella.com/articles/AndroidGoogleMaps/article.html
Good luck,

Categories

Resources