Google maps destination SwiftUI - google-maps

I am working on a project where users can add the addresses of their clients. I managed to make these addresses to be interactive so that when you tap on them a sheet shows the option to open either GoogleMaps or Apple Maps. However I am not sure how to set the specific address I tap to be the destination when the map opens. This is what I have:
.actionSheet(isPresented: $showingSheet){
let latitude = 51.49
let longitude = -30
let appleURL = "http://maps.apple.com/?daddr=\(latitude),\(longitude)"
let googleURL = "comgooglemaps://?daddr=\(latitude),\(longitude)&directionsmode=driving"
//let wazeURL = "waze://?ll=\(latitude),\(longitude)&navigate=false"
let googleItem = ("Google Map", URL(string:googleURL)!)
//let wazeItem = ("Waze", URL(string:wazeURL)!)
var installedNavigationApps = [("Apple Maps", URL(string:appleURL)!)]
if UIApplication.shared.canOpenURL(googleItem.1) {
installedNavigationApps.append(googleItem)
}
// if UIApplication.shared.canOpenURL(wazeItem.1) {
// installedNavigationApps.append(wazeItem)
// }
var buttons: [ActionSheet.Button] = []
for app in installedNavigationApps {
let button: ActionSheet.Button = .default(Text(app.0)) {
UIApplication.shared.open(app.1, options: [:], completionHandler: nil)
}
buttons.append(button)
}
let cancel: ActionSheet.Button = .cancel()
buttons.append(cancel)
return ActionSheet(title: Text("Navigate"), message: Text("Select an app..."), buttons: buttons)
Any suggestions?

Both Apple Maps and Google Maps have a similar URL scheme for opening their map for driving directions.
Apple Maps reference: https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
Google Maps URL scheme for iOS: https://developers.google.com/maps/documentation/urls/ios-urlscheme#directions
In both cases, the daddr value you're passing can be sent a full address, which the Maps product will then geocode and pinpoint.
You're currently sending a stringified version of your lat/lng coordinates in that string, which each maps product can use to derive a location. But there neither scheme seems to support an option of "here are the coordinates I want to use, and this is the address I want to show" – it's one or the other.
So if you take the address you have and enter it as a single string (don't forget to URL encode it – you may find it easiest to assemble your URL using the URLComponents and URLQueryItem helper objects) you ought to be able to use that encoded string as a new daddr value.

Related

How to extract route GPX from a Google Maps route?

My objective is to extract a route which some user would have created on Google Maps into a GPX file containing latitude longitudes for further use in other apps.
The route will be shared via a link like this - https://goo.gl/maps/HcikiDXFwN2coeFN8
Interestingly, this app is already doing what I want to do - https://mapstogpx.com/ and https://www.gpsvisualizer.com/convert_input?convert_format=gpx. I just want to know how they are doing it so that I can emulate it for my own needs.
Since both the tools I've mentioned also require providing a Google Maps API key with the directions API enabled, my initial guess is that these tools first parse the webpage for the waypoints and then use those waypoints in a Directions API call to get all the route trackpoints.
Thanks
The solution lies in the "data" param in the expanded url for the google maps route link.
Lets take this URL for example - https://goo.gl/maps/zrcP5gL1cd2AHGoq8
This expands to https://www.google.com/maps/dir/Eiffel+Tower,+Paris,+France/Palais+Garnier,+Pl.+de+l'Op%C3%A9ra,+75009+Paris,+France/#48.8606129,2.2961092,14z/am=t/data=!4m29!4m28!1m20!1m1!1s0x47e6701f7e8337b5:0xa2cb58dd28914524!2m2!1d2.2930458!2d48.8560934!3m4!1m2!1d2.3122286!2d48.8490916!3s0x47e6702fa62d0bc5:0xd2d94ed604f2e5a0!3m4!1m2!1d2.3035972!2d48.8729816!3s0x47e66fc1755cf609:0x3c5040f902b41a5f!3m4!1m2!1d2.3235117!2d48.8581242!3s0x47e66e2ac3bca3ed:0x1c289763e3096e61!1m5!1m1!1s0x47e66e30d4668339:0xa9abf21c286d0767!2m2!1d2.3316014!2d48.8719697!3e0
On closer examination, you will see that the data param has lat-lng coordinates embedded in it. For example this
!1d2.2930458!2d48.8560934 or !1d2.3122286!2d48.8490916. These are longitude latitude pairs representing various waypoints on the route. The longitude always starts with !1d and ends with !2d and the latitude starts with !2d and ends with !3.
Here is a small kotlin method to extract all the coordinates :
//https://stackoverflow.com/a/62191093/3090120
fun String?.indexesOf(pat: String, ignoreCase: Boolean = true): List<Int> =
pat.toRegex(if (ignoreCase) setOf(RegexOption.IGNORE_CASE) else emptySet())
.findAll(this ?: "")
.map { it.range.first }
.toList()
fun extractCoordinates(expandedUrl: String): List<LatLng> {
val latLngList = arrayListOf<LatLng>()
val indexes = expandedUrl.indexesOf("!1d")
indexes.forEach {
val coordinatesStr = expandedUrl.substring(it + 3).substringBefore("!3").split("!2d")
latLngList.add(LatLng(coordinatesStr[1].toDouble(), coordinatesStr[0].toDouble()))
}
return latLngList
}
The result with this string would be
[lat/lng: (48.8560934,2.2930458), lat/lng: (48.8490916,2.3122286), lat/lng: (48.8729816,2.3035972), lat/lng: (48.8581242,2.3235117), lat/lng: (48.8719697,2.3316014)]
Once we have all the lat-lng pairs we can simply fire off a Google Maps Directions API call and recreate the route in the link and export it as a GPX file.

Getting a Direct Image From Address With Google Street View Image API

I am using the static image API (where you pass a URL to Google and it returns an image). My issue is the images google is returning are sometimes not straight-on/clear view of the address. I am looking to get the same image as what the Google Maps search feature comes up with as a thumbnail.
I have read the Google Documentation for this API. An example URL is: https://maps.googleapis.com/maps/api/streetview?parameters&size=640x640&fov=50&location=4113+Hartford+Dr+Garland+TX
If I put this same address (4113 Hartford Dr, Garland, TX) directly into Google Maps, I get a much cleaner image.
I have experimented with changing the FOV value. My only other idea is to use heading, but I am unsure about this.
The end implementation is in Excel using VBA.
Let me know if you need any additional information.
You are going to have to compute the heading. I don't have the raw math for that, but here is an example using the JS API, if that's an option.
function getStreetView(lat, lng) {
let panorama = new google.maps.StreetViewPanorama(
document.getElementById('panorama'), {
position: {lat: lat, lng: lng}
})
let service = new google.maps.StreetViewService
service.getPanoramaByLocation(panorama.getPosition(), 50, function(panoData) {
if (panoData) {
let panoCenter = panoData.location.latLng
let heading = google.maps.geometry.spherical.computeHeading(panoCenter, {lat: lat, lng: lng})
let pov = panorama.getPov()
pov.heading = heading
panorama.setPov(pov)
} else {
alert('no streetview found')
}
})
map.setStreetView(panorama) // set dude on map
}

Google maps creation of geofencing for iOS

Does google maps provide the ability to create geofence in iOS?
Similar to this for Android:
http://developer.android.com/training/location/geofencing.html
Thank you.
Just in case someone else end up here :
https://www.raywenderlich.com/136165/core-location-geofencing-tutorial
Geofencing notifies your app when its device enters or leaves geographical regions you set up. It lets you make cools that can trigger a notification whenever you leave home, or greet users with the latest and greatest deals whenever favorite shops are nearby. In this geofencing tutorial, you’ll learn how to use region monitoring in iOS with Swift – using the Region Monitoring API in Core Location.[...]
In swift 5 You can create the geofencing by using the Google Map Object. In the view did load or anywhere in the code where you want to initialize the path just instantiate the GMSMutablePath object
var path : GMSMutablePath!
//In viewdidload
path = GMSMutablePath()
let lat = Double(i.latitude ?? "0") ?? 0.0
let lng = Double(i.longitude ?? "0") ?? 0.0
print(lat,lng)
path.add(CLLocationCoordinate2D(latitude: lat, longitude: lng))
let polyline = GMSPolyline(path: path)
polyline.strokeColor = AppColor.authFontColor
polyline.strokeWidth = 3.0
polyline.map = googleMapView

Cannot find POI via google-places-api that can be found on google-maps and google-plus

I am trying to find a specific listing via the google-maps-places API, but I don't get any results. This is strange to me, as there is a Google+ page and also a google-maps entry.
Let's take a look at the links:
Google+:
https://plus.google.com/115673722468988785755/about
Maps:
https://www.google.de/maps/place/AMWAY+Beratung+%26+Vertrieb+Haegebarth/#53.171976,9.465828,17z/data=!3m1!4b1!4m2!3m1!1s0x47b106116fc69d69:0xe17811ab2780c71d
If I use the very same coordinates from the maps entry in my nearby search and use the name from the entry as the keyword (or location for what it's worth) the results is empty.
Places-API (with exact same coordinates):
https://maps.googleapis.com/maps/api/place/nearbysearch/json?sensor=false&radius=2000&name=amway&location=53.171976,9.465828&language=de-DE&key=YOURKEY
I can of course imagine that the db for the Google+ POIs is a different one. But then again I don't see how the maps api does not find what I can find on the maps web app.
Thanks a lot for any help!
Try something like this:
map.places.nearbySearch({
location: latLng,
rankBy: google.maps.places.RankBy.DISTANCE,
types: ['shop'], // optional
name: "AMWAY Beratung & Vertrieb Haegebarth" // optional
},function(results, status){
if (status == google.maps.places.PlacesServiceStatus.OK) {
// The thing you need should be result[0]
// console.log(results[0]);
if (results[0].name == "AMWAY Beratung & Vertrieb Haegebarth") { // optionally check the type
// You have your place :)
}
}
}
What a workaround! Rumours are that the Google Maps JS API v3.20 or later will allow us to trigger click events on POIs, thereby getting Place objects directly.

Flickr API returning unavailable image Windows Phone

Hi I'm new to Windows Phone and the flickr API's.
I've been trying to get some images and display them on the panorama view with this code:
var baseUrl = string.Format(flickString, flickrAPIKey);
string flickrResult = await client.GetStringAsync(baseUrl);
FlickrData flickrApiData = JsonConvert.DeserializeObject<FlickrData>(flickrResult);
if(flickrApiData.stat == "ok")
{
foreach (Photo data in flickrApiData.photos.photo)
{
// To retrieve one photo
// http://farm{farmid}.staticflickr.com/{server-id}/{id}_{secret}{size}.jpeg
//string photoUrl = "http://farm{0}.staticflickr.com/{1}/{2}_{3}_o.jpeg";
//string photoUrl = "http://farm{0}.staticflickr.com/{1}/{2}_{3}_b.jpeg";
string photoUrl = "http://farm{0}.staticflickr.com/{0}/{0}_{0}_n.jpeg";
string baseFlickrUrl = string.Format(photoUrl,
data.farm,
data.server,
data.id,
data.secret);
flickr1Image.Source = new BitmapImage(new Uri(baseFlickrUrl));
break;
}
}
I've tried trying different farms & servers etc but every time it still returns "This image is unavailable at this time". I dont know what I'm doing wrong here, appreciate some help.
Thanks
After Running your link, it turns out that the image extension should use jpg instead of jpeg
But I would strongly recommend you to use the extra field to get the respective url directly by using the extra attribute in the API
extras (Optional)
A comma-delimited list of extra information to fetch for each returned record.
you can use either of those: url_sq, url_t, url_s, url_q, url_m, url_n, url_z, url_c, url_l, url_o