Aerial Photo Map in OSMDroid - Bing? or What? - android

I have a requirement for building an Android mapping application onto which I will plot archaeological POIs (Points of interest). The requirement is to have aerial photographs much like Google Maps Satellite view. However, the other requirement is offline mapping capability when data connectivity is unavailable, so that rules out using Google Maps.
So I have two questions.
Does OSMDroid have free access to tile sources supporting Arial Photography or Satellite without using Bing?.
I know OSM can support Bing which does have an Ariel Photography map, but I can't get it to work. Are there any bing specific tutorials you can point me to, or a simple example of how to get a bing map to show in OSMDroid as I've been looking for some hours and pulling my hair out.
In eclise I have been able to build a simple app to show the default maps of OSMDroid (Mapink). To try and use Bing I added into my project source three classes. BingMapTileSource.Java, ImageryMetaData.Java and ImageryMetaDataResouce.Java. I got these from the Bing sub folder of the TileProvider directory on the OSMDroid SVN (Link here)
However, when I use this in the onCreate as follows, I get null pointer errors in the BingMapTileSource.java class.
MapView mapView = new MapView(this, 256);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(true);
String m_locale=Locale.getDefault().getISO3Language()+"-"+Locale.getDefault().getISO3Language();
mapView.setTileSource(new BingMapTileSource("Bing",m_locale));
mapView.getController().setZoom(10);
mapView.getController().setCenter(new GeoPoint(39.461078, 2.856445));
setContentView(mapView);
I beleive the cause of this problem is that the following class variables are never initialised before they are first used.
s_roadMetaData = null;
s_aerialMetaData = null;
s_aerialwithLabelsMetaData = null;
The only place I can see them being initialised is in a static method called InitMetaData which never gets called.
public static synchronized void initMetaData(final Context aContext)
Though some clue as to its purpose is provided in its Javadoc which states.
/**
* Initialize BingMap tile source.<br>
* This method should be invoked before class instantiation.<br>
* It get dynamically the REST service url to be used to get tile in each supported map view mode.
* #param a_BingMapKey The user's BingMap key.
* #throws Exception
*/
However, I've no idea how to use this. Any advice or pointers to tutorials, examples, or some code would be greatly appreciated.

updated 22.07.2015
How to add Bing maps to osmdroid
Here are step by step instructions. Perhaps someone this will save a lot of time.
1.Add dependency to gradle
compile 'org.slf4j:slf4j-android:1.6.1-RC1'
compile 'org.osmdroid:osmdroid-android:4.3'
2.add library osmdroid-third-party from here
OR
add three classes in our project (BingMapTileSource.java, ImageryMetaData.java, ImageryMetaDataResource.java). from here
3.Getting a Bing Maps Key. Instructions here
4.Add the Bing Maps Key to the manifest.
<meta-data android:name="BING_KEY" android:value="ApEqyap8rTa4WTNCNv-3pAGQc7XUsHS6595tuDI3MHR59QlahJ5bqYGYhMYJq6Ae" />
5.The last step. Add map code
ResourceProxyImpl mResourceProxy = new ResourceProxyImpl(getContext().getApplicationContext());
MapView mMapView = new MapView(getContext(), 256, mResourceProxy);
mMapView.setBuiltInZoomControls(true);
mMapView.setMultiTouchControls(true);
try{
BingMapTileSource.retrieveBingKey(getContext());
String m_locale = Locale.getDefault().getDisplayName();
BingMapTileSource bing = new BingMapTileSource(m_locale);
bing.setStyle(BingMapTileSource.IMAGERYSET_AERIAL);
mMapView.setTileSource(bing);
}
catch(Exception e){
e.printStackTrace();
}
mapContent.addView(mMapView);

The requirement for offline satellite images means that you will have to license the imagery separately. I don't think any of the providers allow such usage without a specific agreement.

There are many commercial providers for aerials: Digitalglobe, Geoeye etc. Check from Google Earth, they mention their providers in bottom of the map.
There are also some lower resolution free images like OpenAerialMap, which itself is not working anymore. But it is worth to check their original sources (http://openaerialmap.org/Data_Sources). Also at least some of their remaining archive is available in MapQuest Open Tiles API. Maybe they even allow downloading to offline, check their terms.
Two warnings through - aerial imagery from commercial providers can be quite expensive, especially for offline case. And aerials from any source will take a lot of space, several times more than raster tiles. So just downloading them to the device can be a challenge.

Ok well I figured the problem with getting the Bing maps to work. What was needed was to precede the instantiation of the BingMapTileSouce with the following static method that instantiates the three Meta Data objects discussed earlier.
try
{
BingMapTileSource.initMetaData(this);
}
catch (Exception e)
{
e.printStackTrace();
}

Related

Google Places API (Android) LatLongBounds Not Working

I am working on andorid google places api Autocomplete, everything is working fine but when I set custom LatLongBounds to restrict the search to a specific area for GoogleApiClient object, the results returned are not in that bound. I don't what am I doing wrong. This is what I am doing.
LatLngBounds bounds = new LatLngBounds(new LatLng(24.85764939832254,67.0641630948748), new LatLng(24.866642601677466,67.07407490512522));
LatLng northeast = bounds.northeast;
LatLng southwest = bounds.southwest;
android.util.Log.e("North-East", northeast.toString());
android.util.Log.e("South-West", southwest.toString());
mAdapter = new PlaceAutocompleteAdapter(getActivity(), android.R.layout.simple_list_item_1, GoogleApiClientHelper.get(getActivity()).getGoogleApiClient(), bounds, null);
mAutocompleteView.setAdapter(mAdapter);
I have the same problem. I think Google Place for android is not complete. Api por web works fine, i found a couple web sites where they said you can use this api wor web doing a couple of "fixes" for the code. I think this is not the right way, but if it works, it works.
Google Places API request denied for Android autocomplete, even with the right api key

Baidu maps on Android: access key does not work for location searching

I'm creating an Android app for a chinese client and they need map integration, so Google maps is not an option since all Google services are blocked in China. I'm trying to use Baidu maps, which is called Baidu LBS (location-based services) cloud.
Getting a basic map with no overlays to work was relatively easy. The process is described here (in Chinese, but the code speaks for itself if you don't understand the language). Downloading the latest Baidu Android SDK (v3.2.0 at time of writing) and integrating it into my Eclipse project as a library was no problem, but don't trust the documentation in that link too much even though it is the official one. Their examples often contain code that wouldn't even compile. The name of the .jar file for example was completely different from what you see in their screenshot.
Oh and also their .jar library is obfuscated which is super annoying to work with :-(
I needed to register a Baidu account and go to their control center to generate a key. To create an access key ("ak") for mobile you need to enter the SHA1 fingerprint of the keystore which signs your app, followed by the package name specified in your manifest.
Then I added the generated key to my manifest under the tag
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="xxx...xxx" />
I then copied code from their sample project's CloudSearchActivity because I have specific coordinates that I would like to display. I implemented the CloudListener interface as shown:
#Override
public void onGetSearchResult(final CloudSearchResult result, final int error)
{
Log.w("onGetSearchResult", "status=" + result.status + ". size=" + result.size + ". total=" + result.total + ". error=" + error);
if(null != result && null != result.poiList && 0 < result.poiList.size())
{
mBaiduMap.clear();
final BitmapDescriptor bitmapDescriptor=BitmapDescriptorFactory.fromResource(R.drawable.icon_address_grey);
LatLng latitudeLongitude;
LatLngBounds.Builder builder=new Builder();
for(final CloudPoiInfo info : result.poiList)
{
latitudeLongitude=new LatLng(info.latitude, info.longitude);
final OverlayOptions overlayOptions=new MarkerOptions().icon(bitmapDescriptor).position(latitudeLongitude);
mBaiduMap.addOverlay(overlayOptions);
builder.include(latitudeLongitude);
}
final LatLngBounds bounds=builder.build();
MapStatusUpdate mapStatusUpdate=MapStatusUpdateFactory.newLatLngBounds(bounds);
mBaiduMap.animateMapStatus(mapStatusUpdate);
}
}
And I added code to launch a query (also copied from their sample project):
#Override
public View onCreateView(final LayoutInflater layoutInflater, final ViewGroup viewGroup,
final Bundle savedInstanceState)
{
// initialize needs to be called
SDKInitializer.initialize(getApplication());
CloudManager.getInstance().init(MyFragment.this);
view=(ViewGroup)layoutInflater.inflate(R.layout.fragment_map, viewGroup, false);
mMapView=(MapView)view.findViewById(R.id.baiduMapView);
mBaiduMap=mMapView.getMap();
NearbySearchInfo info=new NearbySearchInfo();
info.ak="xxx...xxx";
info.geoTableId=12345;
info.tags="";
info.radius=30000;
info.location="116.403689,39.914957";
CloudManager.getInstance().nearbySearch(info);
return view;
}
Unfortunately I keep getting a status value of 102 from the server (according to this API page that means STATUS_CODE_SECURITY_CODE_ERROR. Now I don't know what to do.
Things that I don't understand:
Why do I need to repeat my access key ("ak") when building the query? Is it not enough to have it in the manifest once?
What is this "geoTableId" value in the query supposed to be?
Any ideas?
After many hours of research I have made some progress on the open questions.
The reason for the "ak" field in a cloud search query is not duplication, it is in fact a different access key. Somewhere in a hidden place Baidu says that access keys "for mobile" will not work for these cloud searches, you need an ak "for server". So the solution is to go back to the Baidu control center and create another key "for server". This key needs to be used in the query, while the "for mobile" key needs to remain in the manifest.
geoTableId is an identifier of your account, not unsimilar to the access keys. It is a (currently) 5 digit number that you need to obtain in the Baidu control center. The other keys were generated in the tab titled "API控制台" (API control desk), but for the geoTableId you need to switch to the tab called "数据管理" (data management). There I think I needed to press the "创建" (~create) button on top left, then enter a name, select "是" (yes) where they ask if this is for release (not sure about that translation) and then click "保存" (save). After this, your freshly generated number is displayed in the top field in parentheses behind the name you chose just now.
These steps have allowed me to send "successful" queries where the server answers with status 0 (STATUS_CODE_SUCCEED). However, so far all the answers I get are empty, I have yet to find a query which produces a non-empty answer. If anyone manages to do that, please let me know!

osmdroid, Maps API v2, and fragments

Ok. You'd think this would be relatively simple, but nope.
I am using Open street maps on my website, as the data is free to use, edit, and update - my project follows this mantra, and alongside googles API usage restrictions/saving data restrictions, google maps simply was not suitable for me.. at least on the web.
Given this I thought i'd follow suit with my android app, and so I setup osmdroid utilizing open street maps data.
I can have a nice map in my activity.. I also followed a tutorial, and it seemed to work at least such that I can have a map view in a fragment within a tabhost/viewpager. What i really want however (for tablets), is a list of establishments in a fragment on the left, and a map fragment on the right showing where these establishments are.
Simple enough i would have thought, but hours and hours of research suggest this is not possible unless you use some complex code and some deprecated methods..
So.. the fragment (containing a map view) loads and runs perfectly in a tabhost.. i can access methods within the fragment from my activity etc.. yet nothing to just simply have two fragments side by side.
Now.. I know google have just come out with their API v2.. I installed it and had a play.. not really knowing how osmdroid works, I thought i could update so I have MapFragment instead of SherlockFragment (I use ABS).. this then just threw up logcat errors asking for API keys etc.. and given that I dont want to use google map data, I assumed that I had gone wrong.
So.. could anyone advise on how I can get a list fragment, and a map fragment side by side using anything that is available on the market, but preferably utilizing Open source map data such that their are no usage restrictions.
I'm sure an overall overview of "what is available, and how it works" would be very much appreciated by loads of users.. so if anyone could advise it would be amazing !
Before the new Google Maps API came out, I was forced into using OSMDroid for my purposes. However, after having to dig through the source several times to figure out why it was doing what it was (often incorrectly), I was dying for a new library.
Fortunately, the new Google Maps API fits the bill. You can use the Google Maps API v2 in your application and never have to use Google's basemaps, but yes, unfortunately you must get an API key first.
I am assuming you want to use OpenStreetMap as an online map source, so the code below will be tailored towards that.
GoogleMap map = <get-map-instance>;
map.setMapType(GoogleMap.MAP_TYPE_NONE);
TileOverlayOptions options = new TileOverlayOptions();
options.tileProvider(new UrlTileProvider(256, 256) {
#Override
public URL getTileUrl(int x, int y, int z) {
try {
String f = "http://tile.openstreetmap.org/%d/%d/%d.png";
return new URL(String.format(f, z, x, y));
}
catch (MalformedURLException e) {
return null;
}
}
});
map.addTileOverlay(options);
You can find a more formalized version of this code in my Google Maps API v2 add-ons library here.
Also, if you are targeting pre-Fragment Android versions, which I believe you are based on you using ABS, instead of using MapFragment, make sure you use SupportMapFragment.
The Sample Code delivered with Google Maps Android API v2 contains the class com.example.mapdemo.TileOverlayDemoActivity. I little update to this class will show OpenStreetMap tiles within the new v2 framework. Cool! No need to use osmdroid or sherlock-fragments anymore. However... the tiles are not cached :(
Anyway, all additions/updates to the TileOverlayDemoActivity class are shown below:
private static final String OPEN_STREET_MAP_URL_FORMAT =
"http://tile.openstreetmap.org/%d/%d/%d.png";
private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
mMap.setMyLocationEnabled(true);
TileProvider tileProvider = new UrlTileProvider(256, 256) {
#Override
public synchronized URL getTileUrl(int x, int y, int zoom) {
String s = String.format(Locale.US, OPEN_STREET_MAP_URL_FORMAT, zoom, x, y);
URL url = null;
try {
url = new URL(s);
} catch (MalformedURLException e) {
throw new AssertionError(e);
}
return url;
}
};
mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
}

Android Google Maps talking to Google Maps Enterprise Data?

Is it possible to switch the Android Google Maps code to utilize custom data provided by a Google Enterprise?
Details:
Google provides an "enterprise" version of its maps service, where you can host your own data. See here:
http://www.google.com/enterprise/earthmaps/earth_technical.html
But Android's Maps API has no way of using any alternative data sources other than what is freely available on the web.
http://code.google.com/android/add-ons/google-apis/index.html
There are other tools like Open Street Maps or AndNav, but here, I need to use Google.
There is no API for switching the MapView data source, and since it is not open source, there's no obvious way to change it.
You can, however, use WebView to embed a standard Web-based Google Maps that could, presumably, come from your "enterprise" edition.
With the new V2 api on android you can set the tile source by providing a custom TileProvider. I am not familiar with the enterprise offerings, but this should be possible if the tiles are available via a url. The exact implementation will depend on how the tiles are accessed, but here some code to get started:
map.setMapType(GoogleMap.MAP_TYPE_NONE);
TileOverlayOptions options = new TileOverlayOptions();
options.tileProvider(new UrlTileProvider(256, 256) {
#Override
public URL getTileUrl(int x, int y, int z) {
try {
String f = "http://yourURL/%d/%d/%d.png";
return new URL(String.format(f, z, x, y));
}
catch (MalformedURLException e) {
return null;
}
}
});
map.addTileProvider(options);

Flickr API on Android?

I want to use Flickr API for downloading the images on Android Phone, can any one give or tell, me about the working sample of Flickr API on Andorid.
I have add the flickr.jar as the external library, and i have the "Key"and "Secret" but i do not know how to download the images.
All it takes is just 3 steps and you will have it implemented.
Step 1: Find your user id.
The easiest way is to use this service http://idgettr.com/
Step 2: Acquire you flickr api key
Just log-in to you account and click this link http://www.flickr.com/services/api/misc.api_keys.html
Step 3: Get the code from the example project from our blog
http://www.quintostdio.com/blog/archives/1117
Add you user id and api key on the FlickrActivity class (in the package com.quintostdio.test.flickr.ui) and run the example. You can copy paste the classes and add it to your project, with no more changes and it will work.
Hi I have built a Flickr Java library for Android: http://code.google.com/p/flickrj-android/
You'll need to look in their documentation on the Flickr site. Most likely will use the Java library and import it into your Android project.
Probably have to instantiate an object, using the Key and Secret. Once you have a valid authentication object, you'll use a provided method (from the docs) to get a picture.
Have a look here: http://www.flickr.com/services/api/
#Todd DeLand answer is pretty accurate even nowadays.
However, I'll speed you up the search and tell you that the flickrj-android is not anymore up to date, as you can check in the Downloads page https://code.google.com/archive/p/flickrj-android/downloads
The other project that is listed in the Flickr API page ( http://www.flickr.com/services/api/ ), Flickr4Java, it's definitely working nowadays since I just tested it today and so far is doing it's job pretty nicely.
Github repo: https://github.com/boncey/Flickr4Java
Gradle config to add in your project (be careful, since in the README it appears another Gradle configuration, which is for the project that Flickr4Java is based on, and is NOT working):
implementation "com.flickr4java:flickr4java:2.17"
As of today, Flickr4Java was last updated on Nov 11, 2017, which is not bad.
This is an example of how I sent a query to get the pictures around a certain location (latitude,longitude):
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
String apiKey = "MY_API_KEY";
String sharedSecret = "MI_API_SECRET";
REST rest = new REST();
Flickr flickrClient = new Flickr(apiKey, sharedSecret, rest);
SearchParameters searchParameters = new SearchParameters();
searchParameters.setLatitude(exampleLatitude);
searchParameters.setLongitude(exampleLongitude);
searchParameters.setRadius(3); // Km around the given location where to search pictures
PhotoList photos = flickrClient.getPhotosInterface().search(searchParameters,5,1);
} catch (Exception ex) {
Log.d(MapApplication.LOG_TAG, ex.getLocalizedMessage());
}
}
});
thread.start();
I would avoid flickr4java. I assumed it worked at first but after incorporating it in to my project I have found that it crashes the app intermittently. very annoying and has been a big waste of time :(. probably works fine under other java apps but does not seem to play well with android :(

Categories

Resources