Using Google Maps and Baidu Maps in same app - android

I'm wondering if there are anyone out that have implemented Google Maps V2 and Baidu Maps in the same version; because GM doesn't work as intended in China?
Or should I split the project into two branches instead? However it would be nice to skip having two branches to maintain.

My solution for this was to implement GM as usual, however if the user has China set (via settings) static maps is to be used, BUT the static map is fetched from Baidu instead of google.
staticUrl = "http://api.map.baidu.com/staticimage?center="
+ location.getLongitude() + "," + location.getLatitude()
+ "&width=" + width + "&height=" + width + "&zoom=15"
+ "&markers=" + location.getLongitude() + "," + location.getLatitude();
Result of https://api.map.baidu.com/staticimage?center=121,31&width=300&height=300&zoom=15:
This method is NOT recommended if trying to implement a real map solution.
Since I have different locations only used by different countries, this solution could be used.
So, that is how I solved it. Hope someone finds this helpful.

Also, I have found that if you use http://ditu.google.cn while in China, it does work.
When using on-line maps in China for your application, whether it's Google Maps or Baidu, there is a transformation of latitude and longitude for legal reasons.
The satellite view in Google Maps uses "Earth" (WGS-84) coordinates. The map view of GMaps in China uses "Mars" coordinates (GCJ-02), and there is code to convert between the two. Baidu maps use the "Bearpaw" coordinates, with a different offset. The Baidu Map API has a demo converting between Google's coordinates and its own systems.
In China, GPS, like everything, has an extra layer of complication :)
If you have built this app, please post the details. Having an English interface to Baidu maps would be great.

You can use both Google Maps and Baidu Maps side by side, but make sure to convert from the WGS-84 coordinates (used by most of the world) to Baidu's coordinates (BD-09, different from China's GCJ-02). Here's some code that does that, based on an example from the Baidu Maps API:
// Google coordinates
var gPoint = new BMap.Point(121.4914, 31.2423); // lon, lat of the Bund Museum in Shanghai - https://www.google.com/maps/#31.2423,121.4914,19z
// gPoint = new BMap.Point(-122.0851053, 37.4219593); // lon, lat of the Googleplex (no Baidu map data but zooms out in Mountain View)
var labelOffset = { offset: new BMap.Size(20, -10) };
// Initialize map
var map = new BMap.Map('allmap');
map.centerAndZoom(gPoint, 15);
map.addControl(new BMap.ScaleControl({anchor: BMAP_ANCHOR_TOP_LEFT})); // add scale
map.addControl(new BMap.NavigationControl());
map.addControl(new BMap.MapTypeControl()); // map type control: street/satellite/2.5D
map.enableScrollWheelZoom(); // mouse wheel scroll is disabled by default
// Add Google marker and label
var markerG = new BMap.Marker(gPoint);
map.addOverlay(markerG);
markerG.setLabel(new BMap.Label('Google coordinates marker appears<br/>at incorrect location on Baidu Map', labelOffset));
// Coordinate conversion ... GCJ-02 coordinates ... Baidu coordinates
BMap.Convertor.translate(gPoint, 2, function (point) {
var marker = new BMap.Marker(point);
map.addOverlay(marker);
marker.setLabel(new BMap.Label('Converted to Baidu coordinates:<br/>' +
point.lng + ', ' +
point.lat +
'<br/>(note the offset of ' + (map.getDistance(gPoint, point)).toFixed(2) + ' meters)',
labelOffset));
map.addOverlay(new BMap.Polyline([gPoint, point])); // draw a line between points
});
<style type="text/css">
body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=gd0GyxGUxSCoAbmdyQBhyhrZ"></script>
<script type="text/javascript" src="http://developer.baidu.com/map/jsdemo/demo/convertor.js"></script>
<div id="allmap"></div>
If the snippet above doesn't work due to the way StackOverflow sandboxes scripts, try the JSbin demo of Google -> Baidu coordinates conversion instead.
If you must perform the conversion offline, check out the evil transform project on GitHub.
It's unclear though what coordinate types browsers localized in Chinese will return via the navigator.geolocation API. I've made a test app for that and posted the question at
Showing navigator.geolocation.getCurrentPosition in Baidu Maps.
Further reading:
What causes the GPS shift in China?
Restrictions on geographic data in China

PROBABLY a bit late to the party, but I accidentally stumbled across something recently which might help you.
I tried baidu maps and it was shockingly difficult to setup and terrible to use so I had a look around and suddenly, google maps worked for me without a vpn!
I realised that the old google china server was still active and if you try:
maps.google.cn
you'll find that creating an iframe using the google.cn address works!

Try to use this way with Google coordinate
http://api.map.baidu.com/marker?location=39.916979519873,116.41004950566&output=html

If your server can access GM without issues (eg. your hosting is not in China mainland or it is but has uncensored connection), why don't you have server do loading data from GM and route it to user instead? We did that for few projects in the past, worked like a charm.
p.s. you could make php pull static map from GM for requested long/lat, store it into temp file on server, then pass back url to the temp file. From user's perspective they would be looking at (static) GM.
p.p.s. If you need user to be able to use GM's UI (do pan/zoom) then you'd need a bit more complex php that would alter all JS loaded from GM so all data would still be requested to your server which would then get maps - so basically to avoid any requests from client machine to be sent to GM server, but all to be sent to yours instead.

Related

How to use a google distant matrix api key and an google maps api key in one app?

im programming an app for android that helps me to find the optimal parking space in my hometown.
For that I'm using Google maps API in for android. I managed to get it to work to display the car parks in the city.
Now I want to use google distant matrix API to calculate the traveltime by car between my position and the different car parks and additionally the traveltime by foot from the car parks to a user specific location in the town.
Since I have to use
String url = "https://maps.googleapis.com/maps/api/distancematrix/json?"
+ "origins=" + start.latitude + "," + start.longitude
+ "&destinations=" +waypoints+"&sensor=false&mode=driving&key=GOOGLE_key";
I need to add an API key for GOOGLE_key.
I already have an API key for the distant matrix but I'm hesitating to use that in the code, since on the tutorials they advise against that.
Now to my questions:
How and where can I store that key?
I want to use something like ... + "&sensor=false&mode=driving&key=" + GOOGLE_key; without using the API key in the code.
Additional Info:
In my AndroidManifest.xml is:
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key"
and in google_maps_api.xml:
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</string>
Thank you for all your help.
Create a variable like GOOGLE_key, then attach google_maps_key string to this via getResources().getSring(). Now, you can use "&sensor=false&mode=driving&key=" + GOOGLE_key;

Create a link that opens the appropriate map app on any device, with directions to destination

I rather thought this would not be so hard to find out but appearantly it is not easy to find an awesome cross device article, like you'd expect.
I want to create a link which opens either the mobile device's browser and surf to google maps OR open a maps app (Apple Maps or Google Maps) and directly starting a route, i.e.: start at the current location, end at a given point (lat/long).
I can test on two devices (beside browserstack), an Android and an iPhone.
The following link works only on the Android:
Take me there!
Clicking this link in iPhone's Chrome, this weirdly opens Google Maps in desktop version with ads on the mobile app...
This one only works on iOS, opening Apple Maps asking me to enter a start location (i can pick "Current Location") and start the route = desired behavior. Clicking this link completely fails on Android:
Take me there!
Notice the maps:// protocol.
Is there an elegant cross device way of creating such a link? One link that works on all main mobiles?
Thanks
UPDATE: Solution found (kinda)
Here is what I've come up with. It's not quite what I imagined, though it's working.
var ua = navigator.userAgent.toLowerCase(),
plat = navigator.platform,
protocol = '',
a,
href;
$.browser.device = ua.match(/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera/i) ? ua.match(/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera/i)[0] : false;
if ($.browser.device) {
switch($.browser.device) {
case 'iphone':
case 'ipad':
case 'ipod':
function iOSversion() {
if (/iP(hone|od|ad)/.test(navigator.platform)) {
// supports iOS 2.0 and later: <http://bit. ly/TJjs1V>
var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
}
}
var ver = iOSversion() || [0];
if (ver[0] >= 6) {
protocol = 'maps://';
}
else {
protocol = 'http://maps.google.com/maps';
}
break;
case 'android':
default:
protocol = 'http://maps.google.com/maps';
break;
}
a.attr('href', protocol + href)
the maps:// protocol is the url scheme for the apple maps app, which will only start working on ios 6 or higher. There are ways to test if gmaps is installed and then chose what to do with the url, but that was kind of too much for what I intended. So i just ended up creating a maps:// OR maps.google.com/ link, using the above parameters.
** UPDATE **
sadly, $.browser.device don't work since jquery 1.9
(source - http://api.jquery.com/jquery.browser )
I haven't worked much with phones, so I dont't know if this would work. But just from a html/javascript point of view, you could just open a different url depending on what the user's device is?
<a style="cursor: pointer;" onclick="myNavFunc()">Take me there!</a>
function myNavFunc(){
// If it's an iPhone..
if( (navigator.platform.indexOf("iPhone") != -1)
|| (navigator.platform.indexOf("iPod") != -1)
|| (navigator.platform.indexOf("iPad") != -1))
window.open("maps://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=[YOUR_LAT],[YOUR_LNG]");
else
window.open("https://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=[YOUR_LAT],[YOUR_LNG]");
}
Interestingly, http://maps.apple.com links will open directly in Apple Maps on an iOS device, or redirect to Google Maps otherwise (which is then intercepted on an Android device), so you can craft a careful URL that will do the right thing in both cases using an "Apple Maps" URL like:
http://maps.apple.com/?daddr=1600+Amphitheatre+Pkwy,+Mountain+View+CA
Alternatively, you can use a Google Maps url directly (without the /maps URL component) to open directly in Google Maps on an Android device, or open in Google Maps' Mobile Web on an iOS device:
http://maps.google.com/?daddr=1+Infinite+Loop,+Cupertino+CA
just bumped in this question and found here all the answers
I took some of the codes above and made simple js function that works on
android and iphone (it supports almost every android and iphones).
function navigate(lat, lng) {
// If it's an iPhone..
if ((navigator.platform.indexOf("iPhone") !== -1) || (navigator.platform.indexOf("iPod") !== -1)) {
function iOSversion() {
if (/iP(hone|od|ad)/.test(navigator.platform)) {
// supports iOS 2.0 and later
var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
}
}
var ver = iOSversion() || [0];
var protocol = 'http://';
if (ver[0] >= 6) {
protocol = 'maps://';
}
window.location = protocol + 'maps.apple.com/maps?daddr=' + lat + ',' + lng + '&ll=';
}
else {
window.open('http://maps.google.com?daddr=' + lat + ',' + lng + '&ll=');
}
}
The html:
<a onclick="navigate(31.046051,34.85161199999993)" >Israel</a>
This works for me on all devices [ iOS, Android and Window Mobile 8.1 ].
Does not look like the best way by any means... but cannot be more simpler :)
<a href="bingmaps:?cp=18.551464~73.951399">
<a href="http://maps.apple.com/maps?q=18.551464, 73.951399">
Open Maps
</a>
</a>
http://jsbin.com/dibeq
if (navigator.geolocation) { //Checks if browser supports geolocation
navigator.geolocation.getCurrentPosition(function (position) {
var latitude = position.coords.latitude; //users current
var longitude = position.coords.longitude; //location
var coords = new google.maps.LatLng(latitude, longitude); //Creates variable for map coordinates
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var mapOptions = //Sets map options
{
zoom: 15, //Sets zoom level (0-21)
center: coords, //zoom in on users location
mapTypeControl: true, //allows you to select map type eg. map or satellite
navigationControlOptions:
{
style: google.maps.NavigationControlStyle.SMALL //sets map controls size eg. zoom
},
mapTypeId: google.maps.MapTypeId.ROADMAP //sets type of map Options:ROADMAP, SATELLITE, HYBRID, TERRIAN
};
map = new google.maps.Map( /*creates Map variable*/ document.getElementById("map"), mapOptions /*Creates a new map using the passed optional parameters in the mapOptions parameter.*/);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('panel'));
var request = {
origin: coords,
destination: 'BT42 1FL',
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
});
}
Well no, from an iOS developer prospective, there are two links that I know of that will open the Maps app on the iPhone
On iOS 5 and lower: http://maps.apple.com?q=xxxx
On iOS 6 and up: http://maps.google.com?q=xxxx
And that's only on Safari. Chrome will direct you to Google Maps webpage.
Other than that you'll need to use a URL scheme that basically beats the purpose because no android will know that protocol.
You might want to know, Why Safari opens the Maps app and Chrome directs me to a webpage?
Well, because safari is the build in browser made by apple and can detect the URL above. Chrome is "just another app" and must comply to the iOS Ecosystem. Therefor the only way for it to communicate with other apps is by using URL schemes.
Simple URL :
https://www.google.com/maps/dir/?api=1&destination=[LAT],[LNG]
This url is specific for routing.
Reference
I found that this works across the board:
<a href="https://www.google.com/maps/place/1+Fake+Street,+City+Province/State>Get Directions</a>
For desktops/laptops the user has to click Directions when that map loads, but from my testing all mobile devices will load that link in the Google Maps app without difficulty.
Based on the documentation the origin parameter is optional and it defaults to the user's location.
... Defaults to most relevant starting location, such as user location, if available. If none, the resulting map may provide a blank form to allow a user to enter the origin....
ex: https://www.google.com/maps/dir/?api=1&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling
For me this works on Desktop, IOS and Android.
The URL syntax is the same regardless of the platform in use
String url = "https://www.google.com/maps/search/?api=1&query=" + latitude + ","+
longitude;
In Android or iOS the URL launches Google Maps in the Maps app, If the Google Maps app is not installed, the URL launches Google Maps in a browser and performs the requested action.
On any other device, the URL launches Google Maps in a browser and performs the requested action.
here's the link for official documentation
https://developers.google.com/maps/documentation/urls/guide

Android Google api v2 navigation route map without using parsing

I want to create a route map navigation in Android google map v2 along with all those details which google provides( like at this crossing you have to turn left). I know this can be done using a parsing techniques i have done that but what im looking for is, is there any new method predefined within android v2 google map which will give all these details and will show the route map within two points.
Again Im mentioning it not using the JSON parsing technique. anything newly implemented for v2
Any sample projects or examples is very much helpful.
thanks
Without using json parsing technique to draw routes can be done by one method linking to google navigation by doing stuff like this.
String address = marker.getTitle();
Intent intent;
if (address == null) {
LatLng pt = marker.getPosition();
String lat = Double.toString(pt.latitude); //this i mentioned with current location
String lng = Double.toString(pt.longitude);
intent = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("google.navigation:q=" + lat + "," + lng));
However for Google map direction, json parsing is best.
No, there is only the Google Directions API available for a route response, which includes JSON parsing.

Showing a marker at a geo:-url in Android Maps

Is it possible not only to have Google Maps on Android show a given coordinate in the Maps Application but have also a marker (or pin) set at the location?
I read the documentation at https://developer.android.com/guide/appendix/g-app-intents.html but it only lets me set the zoom level.
Right now I use the following code to show a place in Google Maps on Android:
Double lat = 53.3;
Double lng = 13.4;
final String uriString = "geo:" + lat + ',' + lng + "?z=15";
Intent showOnMapIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uriString));
startActivity(showOnMapIntent);
Is it possible to have a marker there or do I need to use a MapActivity?
Where can I find the complete documentation on the url parameters that the Maps application understands?
Can I use a different url prefix? For example "https://maps.google.de/maps?"?
Maps has an intent-filter matching this scheme/host/pathPrefix.
Where can I find documentation on which parameters Google Maps for Android actually supports with this url?
Dirk, have you tried geo:0,0?q=lat,lng?
it is displaying a marker on my nexus 5.
It works with the follwoing url:
final String uriString = "http://maps.google.com/maps?q=" + lat + ',' + lng + "("+ label +")&z=15";
The reverse geo coded address is shown.
I found documentation to the supported parameters here. This is not the documentation for Androids Google Maps but what I tried works.
Note: it should be noted that the original question was in regards to the the geo: URI to launch the Google Maps app (see Android Developer Reference Intents List, whereas this answer might launch a web view with the Google Maps website depending on what App the user chooses for this Intent.
try this:
http://maps.google.com/?saddr=34.052222,-118.243611
and to get the complete route between two points:
http://maps.google.com/?saddr=34.052222,-118.243611&daddr=37.322778,-122.031944

Does createRoute method support lat/Lng in Mapquest?

This is a question about Mapquest Android Maps API.
Does anyone know that the createRoute method is supporting lat/Lng or not in mapquest?
public void createRoute(java.lang.String from, java.lang.String to)
The document I found here:
I have read the "Location Format Documentation" : link
It seems that createRoute method supports lat/Lng.
I tried to input lat/Lng a whole day but it returns me an error message only:
Unable to create route.
Error: -1"
Message:[null]
Are you still seeing this error message? The MapQuest Android Maps API does support lat/lng input for routing. Here is a sample request that uses lat/lng inputs:
private void displayRoute() {
RouteManager routeManager= new
RouteManager( this );
routeManager.setMapView( map );
routeManager.createRoute( "{latLng:{lat:37.765007,lng:-122.239937}}" , "Fremont, CA" );
}
Also, The MapQuest Developer Network has an Android Maps API forum. It is also a good resource to check!
You can write like this
RouteManager routeManager = new RouteManager(this);
routeManager.setMapView(map);
routeManager.createRoute("37.002004,35.322998", "36.802687,34.632812");
or like this
RouteManager routeManager = new RouteManager(this);
routeManager.setMapView(map);
routeManager.createRoute("Any City Name", "Any City Name");
MapQuest is supporting this types

Categories

Resources