ThinkGeo.com    |     Documentation    |     Premium Support

Google Maps with Client ID/Private key

Hi, been using the trial of WPF but am having trouble with Google Maps as an overlay. When I use our enterprise client id and private key I’m not seeing the map tiles - it mostly works when not using the key/clientid.



I looked at the web requests using the simplest code (see below).  It looks like the url parameters are incorrectly formatted before its signature is created.  Here’s what seems to be happening in the request url:



maps.googleapis.com/maps/api/staticmap?center=-40.84706,-45.175781&zoom=3&size=512x512&maptype=roadmap&format=jpg-baseline&sensor=falseclient=gme-cdcltd&&signature=yRDpGRbBNleZvOsJSCXmbJLlac4=



When the url is being constructed, the client parameter is incorrectly placed just after the sensor parameter value:

…sensor=falseclient=gme-cdcltd&&signature=…



trying to use this url will fail:

The Google Maps API server rejected your request. Unable to authenticate the request. Missing the ‘client’ parameter. Learn more: developers.google.com/maps/documentation/business/webservices/auth


Is there anything I can do override the url creation process or another way to fix this?




Private Sub WpfMap_Loaded(ByVal sender As System.ObjectByVal As System.Windows.RoutedEventArgs)
    Map1.MapUnit = GeographyUnit.Meter
    Map1.CurrentExtent = New RectangleShape(-13939426.6371, 6701997.4056, -7812401.86, 2626987.386962)
 
    Dim gmap As New GoogleMapsOverlay()
    gmap.Name = “GMAP”
    gmap.MapType = GoogleMapsMapType.RoadMap
    gmap.TileType = TileType.MultipleTile
    gmap.ClientId = “gme-cdcltd”
    gmap.PrivateKey = “my private key here<my><my>”
 
    AddHandler gmap.SendingWebRequest, AddressOf req
 
    Map1.Overlays.Add(gmap)
    Map1.Refresh()
End Sub
 
 
Private Sub req(sender As Object, e As ThinkGeo.MapSuite.Core.SendingWebRequestEventArgs)
    Debug.Print(e.WebRequest.RequestUri.ToString())
End Sub







Hi
Mark,



Thanks for your post and welcome to Map Suite
Forums!



I notice  the incorrect url is happened as there is
no the "&" between the false and client parameter and a
"&" is more between the client and signature. But I have tried
our both production and development version, seems the url is fine not like yours. Would you
please let us know what's the version you are referring? or it is just a mistake when you copy the url on the post?



There is a workaround to override the
request url by registering the CreatingRequest event:





Private Sub googlelayer_CreatingRequest(sender As Object, e As CreatingRequestGoogleMapsLayerEventArgs)
         e.RequestUri = New Uri(Convert.ToString(e.RequestUri.AbsoluteUri))' modify the url here to make it valid.
End Sub

Actually, we do encounter the invalid url issue for google map when we use the clientId Api. Currently, as our business client Id is not valid anymore, we would very appreciate that you can help us to test what is a valid request url with your ClientId by comparing the request url generating from Map Suite? I guess it might be a bug in GoogleMapLayer with ClientId. Here is a link might be useful: developers.google.com/maps/...vices/auth




Thanks,


Troy





Hi,

  thanks for your response.  I’m using MapSuite WPF Desktop Evaluation (mapSuiteCore version shows 7.0.0.0) 

I had been using googlemaps as an overlay for the base map. I couldn’t  seem to attach to the CreatingRequest event there so I just switched over to adding it to a new LayerOverlay.  This also gave me the same error so I hooked up a handler for the CreatingRequest event and modified the url manually.  Here’s a sample of the original and fixed urls:



Created by MapSuite when Client ID/Key is set: maps.googleapis.com/maps/api/staticmap?center=41.112469,-135.175781&zoom=3&size=512x512&maptype=roadmap&format=jpg-baseline&sensor=falseclient=gme-cdcltd&&signature=M2NuZ5RHtv4eUxCHFEhqhY3wjUo=



Fixed and then Signed URL: maps.googleapis.com/maps/api/staticmap?center=41.112469,-135.175781&zoom=3&size=512x512&maptype=roadmap&format=jpg-baseline&sensor=false&client=gme-cdcltd&signature=ToQJiPjU0J0Y0IzKTy53Xqde0Dc=



When I set the GoogleMapsLayer properties for ClientID and PrivateKey the URL is malformed just after the sensor=false parameter.  To fix the request, I removed everything after sensor=false and added ‘&client=gme-cdcltd’ before signing the url to create a working version. 

Note: “gme-” prefix for the clientID is required and must be a parameter on the URL before it’s signed.



This works for us. As far as I can tell the only problem is when MapSuite creates the request url when a client ID is supplied it’s appending “client=<client id>&” instead of “&client=<client id>” so creating invalid url parameters for a signed url.



I hope this helps you but if there’s anything else you need me to test, let me know.


Sub googlelayer_CreatingRequest(sender As Object, e As CreatingRequestGoogleMapsLayerEventArgs)
        Dim originalURL As String = e.RequestUri.AbsoluteUri
        Dim fixedURL As String
        Dim signedURL As String
        Dim clientPos As Integer
 
        clientPos = originalURL.IndexOf(“client=”)
        fixedURL = originalURL.Substring(0, clientPos) & “&client=gme-cdcltd”
        signedURL = Sign(fixedURL, “my private key here”)
          Debug.Print("Created using Client ID/Key: " & originalURL)
        Debug.Print("Fixed and then Signed URL: " & signedURL)
         e.RequestUri = New Uri(signedURL)



    End Sub




Hi Mark, 
  
 Thanks for the details so much. 
 Now, what we can sure is the issue is happened in version 7.0.0.0 and have been fixed since the 7.0.0.194 I guess. So, I guess if you get the latest version (7.0.0.245 or 7.0.245.0), it should works. Would you please have a try? 
  
 May I know how the detail of method "Sign", I just want to make sure we are using the same logic on the signature. Or just forget it if the version mentioned above works fine. 
  
 Thanks again for your test. 
 Waiting for your further information. 
  
 Regards, 
 Troy

Hi,

  we didn’t know about the daily builds and using them with the evaluation version. I installed those and that has fixed the issue.  Just for reference for anyone else out there wanting to know how to sign their URLs if they have a Google Maps Enterprise API key - we use this code below.  Thanks for your help in understanding what was going on here while we’re doing running the evaluation.  This is looking like a great product with great support.




Public Function Sign(ByVal url As StringByVal keyString As StringAs String
    Dim encoding As ASCIIEncoding = New ASCIIEncoding()
 
    'URL-safe decoding
    Dim privateKeyBytes As Byte() = Convert.FromBase64String(keyString.Replace("-"“+”).Replace("_"“/”))
 
    Dim objURI As Uri = New Uri(url)
    Dim encodedPathAndQueryBytes As Byte()
    encodedPathAndQueryBytes = encoding.GetBytes(objURI.LocalPath & objURI.Query)
    'compute the hash
    Dim algorithm As HMACSHA1 = New HMACSHA1(privateKeyBytes)
    Dim hash As Byte() = algorithm.ComputeHash(encodedPathAndQueryBytes)
 
    'convert the bytes to string and make url-safe by replacing ‘+’ and ‘/’ characters
    Dim signature As String = Convert.ToBase64String(hash).Replace("+"“-”).Replace("/"“_”)
    Return objURI.Scheme & “://” & objURI.Host & objURI.LocalPath & objURI.Query & “&signature=” & signature
End Function


Hi Mark, 



Thanks for the confirmation and praise. Here is a link about daily build and hope it helps: wiki.thinkgeo.com/wiki/Map_S…ilds_Guide

Now, we can confirm that the latest version works fine with the business ClientID and thanks again. 



Any questions, please feel free to let us know. 

Regards, 

Troy