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);
Related
I am using here maps android sdk premium version for map navigation in my android app.
I have successfully implemented here maps navigation. While navigating, if I go out of route then reroute calculation occurs and new route to given destination is shown but if I go through a restricted road, then here maps only says rerouting which is true since from restricted road it cannot calculate the route.
But is there any way I can show nearest exit from the restricted road to get a new route to destination on here maps android? Right now, on the restricted roads, no route is shown.
#Override
public void onRouteUpdated(#NonNull Route route) {
Log.d(TAG, "onRouteUpdated: called.");
//remake new route
map.removeMapObject(mapRoute);
// create a new MapRoute object
mapRoute = new MapRoute(route);
// display new route on the map
map.addMapObject(mapRoute);
}
The above code is not useful while on restricted road. Tried using listener as:
private NavigationManager.RerouteListener rerouteListener = new NavigationManager.RerouteListener() {
#Override
public void onRerouteBegin() {
super.onRerouteBegin();
Toast.makeText(activity, "reRouteListener begin...", Toast.LENGTH_SHORT).show();
}
#Override
public void onRerouteEnd(#NonNull RouteResult routeResult, RoutingError routingError) {
super.onRerouteEnd(routeResult, routingError);
StringBuilder stringBuilder = new StringBuilder();
for (RouteResult.ViolatedOption violatedOption: routeResult.getViolatedOptions()) {
stringBuilder.append(violatedOption.toString());
}
Toast.makeText(activity, "routeresult end: " + stringBuilder, Toast.LENGTH_SHORT).show();
}
};
Sometimes got violated options as START_DIRECTION and sometimes nothing. But still stuck on how to achieve nearest route as such on restricted road.
[update] :
I tried suggestion from #Datasun. But I got invalid routing on initiating new route from restricted road (tried from height restricted road). My problem is while navigating, if user goes to restricted road, the route disappears and it says route recalculating. I want to show user nearest exit from the restricted road or some notification that they are on restricted road. Right now I'm getting violated options of START_DIRECTION but sometimes nothing on the restricted road. What am I missing?
To summarize, within the Navigate SDK the issue is not reproducable any more.
In general the HERE Premium SDK (3.x) is superseded by new 4.x SDK variants and the Premium SDK will be maintained until 31 December 2022 with only critical bug fixes and no feature development / enhancements.
Current users of the HERE Premium SDK (3.x) are encouraged to migrate to Lite, Explore or Navigate HERE SDK (4.x) variants based on licensed use cases before 31 December 2022. Most of the Premium SDK features are already available in the new SDK variants.
I'm to get all nearby "point of interest" for a given latitude/longitude within a given radius without giving any search key.
I started with google place web api. But this api gives desired data when using on web only, not on android. I tried using separate keys on android for same api, even though, the place web api didn't work on android any how. It always said on android, "invalid api key".
Then I moved to google place android api. But this gives data when we use their custom UI, not in any other ways. (But I just want to get location data, not data on google's UI. Since, I want to show POI on camera).
I thought a GEO_DATA_API may help me on android. But somehow it's giving me empty result.
Here is my code for GEO_DATA_API that gave me zero result:
Places.GeoDataApi.getAutocompletePredictions(mGoogleApiClient, query, bounds, null)
.setResultCallback(
new ResultCallback<AutocompletePredictionBuffer>() {
#Override
public void onResult(AutocompletePredictionBuffer buffer) {
if (buffer.getStatus().isSuccess()) {
for (AutocompletePrediction prediction : buffer) {
PlaceResult placeResult = new PlaceResult();
placeResult.setPlaceId(prediction.getPlaceId());
placeResult.setName(prediction.getFullText(null).toString());
}
}
//Prevent memory leak by releasing buffer
buffer.release();
}
}, 60, TimeUnit.SECONDS);
}
I know it is possible to get direction between coordinates using Google's direction web service. But is there any other way to get equally accurate route?
I found few questions on SO those use http://maps.google.com/ to get direction. But then also found few answers on other questions which state that it is no longer supported.
I am confused as this is the first time I am dealing with Google maps for android.
Is there any built in android sdk method to get direction?
you can send an intent to the google maps app and have the app do all the work for you but its not documented and probably never will be.
to do that you can either give it a lattitue/longitude like this
Intent NavIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=" +latitude +","+longitude));
startActivity(NavIntent);
or using the same intent but with an address and see if maps can resolve the address. (I dont have an example with an address).
Other than using google directions API or other 3rd party direction web services there really is no other way to get directions in your app unless you look at Open Street Maps where you calculate the directions yourself using way points but that is quite involved
Firing an intent to the google maps app is what I've choosen to use in my application, the philosophy here is that Android apps should exploit and complement each other functionnlities
Intent i = new Intent(Intent.ACTION_VIEW,Uri.parse(getDirectionUrl(srcLat, srcLng, dstLat, dstLng)));
if (isGoogleMapsInstalled(this)) {
i.setComponent(new ComponentName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity"));
}
startActivity(i);
method to build the directions URL:
public static String getDirectionUrl (double srcLat, double srcLng, double dstLat, double dstLng) {
//return google map url with directions
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.google.com/maps?f=d&saddr=")
.append(srcLat)
.append(",")
.append(srcLng)
.append("&daddr=")
.append(dstLat)
.append(",")
.append(dstLng);
return urlString.toString();
}
Method to test if Maps is installed:
public static boolean isGoogleMapsInstalled(Context c) {
try
{
#SuppressWarnings("unused")
ApplicationInfo info = c.getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0 );
return true;
}
catch(PackageManager.NameNotFoundException e)
{
return false;
}
}
The downside is that Google may change the URL structure.
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));
}
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();
}