Issue downloading image files from websites with VERY long URLs (1 Viewer)

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
Those of you who’ve read any of my previous threads will know I tend to ask about some fairly obscure topics.
Here’s another example :D…. Apologies for its length

Recently, I’ve been working with adding layers to static Google maps and downloading the image files to my Access apps. For example:



The code used to download the image file is very simple and is based on a Windows API

Code:
Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
            "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal _
            szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long

Public Function DownloadFilefromWeb(url As String, FileName As String) As Boolean
    DownloadFilefromWeb = URLDownloadToFile(0, url, FileName, 0, 0)
End Function

The DownloadFileFromURL function uses Internet Explorer no matter what your default browser is.
The problem is this has a URL character limit of 2083 characters and adding layers to maps can easily exceed this limit

A typical URL (for the Milton Keynes postcode area) is :
Code:
[SIZE="2"]https://maps.googleapis.com/maps/api/staticmap?center=52.0624,-0.666126&zoom=9&size=800x400&maptype=roadmap&path=color:blue|weight:3|fillcolor:0xFFFF0033|52.14162,-0.81819|52.14162,-0.82284|52.1631,-0.76845|52.16524,-0.74465|52.1656,-0.73731|52.18081,-0.69401|52.19602,-0.66556|52.19262,-0.64087|52.22197,-0.59076|52.23503,-0.59166|52.2463,-0.5217|52.27618,-0.53351|52.29479,-0.51758|52.31555,-0.47857|52.28871,-0.41774|52.29586,-0.37891|52.27421,-0.368|52.25632,-0.37461|52.24594,-0.3535|52.24791,-0.35797|52.23217,-0.32469|52.21892,-0.28086|52.20264,-0.2898|52.1792,-0.31879|52.16507,-0.30805|52.13161,-0.33954|52.11926,-0.35565|52.11729,-0.35547|52.09958,-0.3934|52.08669,-0.37372|52.07399,-0.38643|52.06683,-0.36889|52.05806,-0.39985|52.03767,-0.39752|52.02514,-0.36585|52.01476,-0.3841|51.98846,-0.40718|51.98273,-0.40879|51.95536,-0.42364|51.94891,-0.46515|51.9541,-0.48215|51.97343,-0.51687|51.97182,-0.56124|51.96914,-0.57251|51.95196,-0.59184|51.94194,-0.63192|51.96663,-0.66896|51.96556,-0.69329|51.9482,-0.75055|
51.95339,-0.81175|51.92834,-0.77846|51.91116,-0.80334|51.8972,-0.82874|51.9083,-0.89835|51.88307,-0.95758|51.89756,-0.99426|51.90382,-1.00642|51.90848,-1.01859|51.90955,-1.00696|51.92494,-1.04955|51.91975,-1.05617|51.94498,-1.09374|51.95375,-1.10645|51.97808,-1.09625|52.00152,-1.07245|52.00599,-1.08802|52.0323,-1.06458|52.03605,-1.05688|52.05878,-1.03881|52.06737,-1.00446|52.05967,-0.9642|52.08329,-0.92805|52.07041,-0.87777|52.05932,-0.88994|52.06952,-0.87151|52.07345,-0.88064|52.08168,-0.86292|52.09618,-0.87867|52.11765,-0.81819|52.14162,-0.81819&markers=color:blue%7Csize:normal%7Clabel:X%7C52.0624,-0.666126&key=AIzaSyAHXXMSyKgS00M314zzHr0gSg0upA-q1hI[/SIZE]

This has almost 1700 characters so is fine
The URL can be shortened (to around 1200 characters by encoding the path (giving the same map):
Code:
https://maps.googleapis.com/maps/api/staticmap?zoom=9&size=800x400&maptype=roadmap&path=color:blue|weight:3|fillcolor:0xFFFF0033|enc:o~f}h?nw~c_?_____?f~___?gbc__?wvi__?ok___?wnc__?ge___?_q`__?w|a__?wkg__?w|a__?_nd__?vq___?g{c__?gtd__?owh__?gpa__?fe___?wca__?otl__?ozd__?~ia__?wub__?_cb__?gbc__?wrf__?vgd__?g|j__?wj`__?wrf__?nhc__?wca__?nob__?vj`__?n}`__?gbc__?ok___?~w___?~bb__?gme__?fpa__?_rg__?~bb__?fw`__?~tc__?ftd__?nva__?wca__?fme__?~fe__?fpa__?~bb__?nk___?ge___?fib__?nlf__?fpa__?wub__?fpa__?~ia__?vj`__?gib__?fw`__?v`e__?~{b__?ok___?fpa__?_ge__?n}`__?nob__?vgd__?vnc__?f~___?nk___?~md__?v|a__?nd`__?f_g__?g~___?fib__?wub__?vye__?fe___?~qg__?vq___?~ia__?fib__?vub__?n}`__?~xf__?g{c__?fff__?fe___?~tc__?nob__?nij__?g~___?f|j__?f{c__?ose__?fib__?f{c__?nva__?nad__?wca__?fnl__?f{c__?~uj__?w|a__?~_f__?od`__?~ia__?_x___?fpa__?ok___?_ja__?w|a__?vkg__?f~___?nd`__?g{c__?nlf__?gw`__?~ia__?_uc__?o}`__?_uc__?_uc__?_x___?~bb__?oad__?wnc__?_x___?_q`__?wnc__?oob__?_q`__?wye__?vj`__?_yf__?wnc__?_`f__?fpa__?owh__?vca__?~ia__?wc
a__?oob__?wq___?fw`__?gw`__?oob__?ova__?~bb__?ohc__?g|j__?_uc__?_____?&border='0'&markers=color:blue%7Csize:normal%7Clabel:X%7C52.0624,-0.666126&key=AIzaSyAHXXMSyKgS00M314zzHr0gSg0upA-q1hI

If you post either of the above into a browser window you will get the map with the blue boundary path shown above.

However, many Google map URLs I’m using still exceed the 2083 limit even when encoded
For example, this boundary path for the Paisley area (PA) is over 3300 characters
Code:
https://maps.googleapis.com/maps/api/staticmap?zoom=7&size=800x400&maptype=roadmap&path=color:blue|weight:3|fillcolor:0xFFFF0033|enc:w~cti?nb}y_?_____?g{c__?nd`__?wnc__?n}`__?ge___?fw`__?nk___?fe___?~{b__?~p`__?_____?vj`__?wub__?vj`__?f~___?fw`__?~w___?fe___?vj`__?~bb__?n~g__?nob__?fcj__?ok___?~qg__?vnc__?f{c__?vub__?vub__?gpa__?~dp__?v|a__?n}`__?gme__?fnl__?wgd__?vq___?_x___?wj`__?o}`__?fe___?wca__?vq___?gw`__?~}p__?_uc__?vca__?n}`__?nob__?~xf__?vwp__?~ia__?ok___?fpa__?nzd__?vdh__?fe___?fqh__?f~___?~w___?fcj__?ok___?vye__?oob__?nob__?_nd__?vln__?wca__?vub__?wub__?ge___?_nd__?fpa__?nk___?vir__?gbc__?wca__?v|a__?gpa__?v`e__?fw`__?fbc__?nxo__?~md__?~_f__?vgd__?vca__?v`e__?fbc__?fff__?oob__?~gl__?nzd__?fib__?nhc__?vzl__?fff__?neg__?_ge__?~ym__?n{k__?voj__?oad__?vub__?vgd__?vnc__?npi__?vq___?ftd__?gtd__?~wx__?nob__?fuk__?oad__?g~___?g}q__?gji__?oeg__?g{c__?od`__?_ja__?o|r__?n}`__?gme__?_ge__?gtd__?fe___?gpa__?~md__?~ia__?vrf__?_q`__?f{c__?olf__?wq___?g{c__?_`f__?gji__?_yf__?_uc__?olf__?vca__?wca__?nhc__?vj`__?~t
c__?w`e__?gpa__?g{c__?ose__?fib__?_uc__?~jh__?g{c__?nd`__?_|b__?w|a__?_rg__?g~___?o}`__?~md__?_q`__?~p`__?_|b__?fxg__?wq___?vj`__?ova__?wca__?w|a__?vub__?ova__?gw`__?_cb__?ozd__?od`__?_am__?gkp__?vgd__?oob__?v|a__?nva__?f}q__?n|r__?vrf__?nmm__?~}p__?ncr__?nwh__?~bb__?fme__?od`__?ok___?~md__?oob__?v|a__?~w___?fbc__?_cb__?vnc__?n}`__?fme__?f~x__?voj__?nbk__?gw`__?~nk__?neg__?~gl__?_x___?vkg__?_|b__?oob__?opi__?opi__?_nd__?~{b__?g{c__?vnc__?_x___?~fe__?ova__?ntl__?~xf__?n~g__?fib__?voj__?_ja__?nob__?ose__?wgd__?ova__?gtd__?wkg__?_ja__?ova__?nhc__?oob__?gw`__?_|b__?gib__?o}`__?_ja__?gxg__?_hl__?_ja__?_kh__?olf__?_rg__?wj`__?_uc__?fbc__?g{c__?o}`__?opi__?gme__?o~g__?gw`__?_}i__?wq___?wgd__?~{b__?opi__?ozd__?fe___?_cb__?gcj__?o{k__?oic`_?_ep__?w|a__?_q`__?nd`__?gtd__?w`e__?gxg__?fgm__?nob__?vnc__?wca__?ge___?ova__?woj__?olf__?ght__?o}`__?~md__?ose__?_q`__?oob__?gzu__?ose__?nbk__?~w___?nd`__?gbc__?nus__?fcj__?nmm__?vgd__?~|i__?wj`__?f{c__?o}`__?fex__?fme__?f|j__?wq___?vxw__?fpa__?~fe__?vub__?vvi__?ok___?nlf__?~bb__
?f~___?vub__?v`e__?nd`__?fcj__?w`e__?wca__?_cb__?_ge__?_x___?fe___?wca__?nob__?o}`__?fbc__?fpa__?vye__?_x___?~bb__?gib__?_|b__?_cb__?g~___?oad__?nad__?_q`__?fe___?wub__?gzu__?gib__?oxo__?vca__?wvi__?_____?ge___?ozd__?neg__?gpa__?wub__?wnc__?~|i__?g{c__?wca__?nva__?vca__?vub__?fme__?nd`__?f{c__?o}`__?od`__?oad__?_`f__?_q`__?vca__?_yf__?_cb__?w|a__?fib__?wq___?voj__?n~g__?vye__?vj`__?vgd__?ftd__?n~g__?g~___?ge___?_nd__?oeg__?w|a__?w|a__?oad__?_sn__?ozd__?wj`__?_uc__?_|b__?o}`__?vca__?gme__?wca__?ova__?gcj__?od`__?oeg__?_uc__?o_o__?wub__?gcj__?vca__?oxo__?wca__?ohc__?fpa__?wdh__?nd`__?g_g__?nhc__?gyn__?_ge__?wcz__?~w___?_wq__?~tc__?wj`__?v`e__?_pr__?fib__?gbc__?wj`__?o~g__?o~g__?o~g__?~w___?_di__?_ge__?ova__?gtd__?o_o__?nk___?_kh__?f|j__?g|j__?nob__?od`__?vzl__?gtd__?fw`__?oz}__?ohc__?oad__?gff__?_ep__?od`__?o`v__?g_g__?w~o__?nse__?~bb__?nfn__?wca__?~ia__?gw`__?vkg__?v`~__?nva__?vln__?o}`__?_x___?fuk__?_nd__?~md__?v`e__?~tc__?_`f__?nfn__?vvi__?vrf__?_____?~fe__?ohc__?vkg__?fme__?vnc__?f~___?v}h__?vca__?~p`__?nd
`__?~qg__?ohc__?nbk__?_ok__?ok___?g`n__?_____?_____?_____?_ge__?~bb__?_n}__?~md__?oad__?vq___?ge___?_____?gqh__?~w___?_cb__?~p`__?wye__?nob__?_____?&border='0'&markers=color:blue%7Csize:normal%7Clabel:X%7C56.0713,-4.91337&key=AIzaSyAHXXMSyKgS00M314zzHr0gSg0upA-q1hI

If pasted into Chrome or Firefox it works. With IE it doesn’t

So I’m looking for the best solution. Possible methods (with comments) include:

1 Use another browser instead of IE
Chrome & Firefox both allow URLs of at least 64000 characters – more than enough. BUT DownloadFileFromURL won’t work with either

2 Shorten path by using fewer decimal places in lat/long data Boundary precision reduced but should be OK BUT encoded path is no shorter than before

3 Shorten path by using fewer points in lat/long data e.g. use alternate points only
Boundary precision reduced but should be OK
Need to find simple way of selecting alternate points using code. I have over 18000 such boundary paths to fix

4 Find another function that works in Chrome/Firefox
Excellent idea but what?

5 Use a dynamic map in a web browser control
Dynamic maps can be problematic in web browser controls
Also depends on IE so doesn’t help

6 Shorten the url using bit.ly or similar
Doesn’t work if the path is over 2000 characters or thereabouts.
The paths can’t be read correctly - defeats the whole point really!
The Google equivalent goo.gl is a bit better in this respect but is about to be scrapped! Replacement is called Firebase. Its more powerful but not quite the same idea.

If you got to the end, thank you for reading it
Any suggestions for solving any of the above would be VERY welcome particularly points 3 or 4
So indeed would be any other good ideas
 

Attachments

  • MapCircle.jpg
    MapCircle.jpg
    32.8 KB · Views: 362
  • MapBoundaryPath.jpg
    MapBoundaryPath.jpg
    43.9 KB · Views: 387
  • MapPaths.jpg
    MapPaths.jpg
    43.4 KB · Views: 729
Last edited:

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
Thanks for your reply. Not sure how to adapt but I'll have a proper look tomorrow

Despite the length of my post I forgot to say that I also have this code

Code:
Public Function LoadPictureFromURL(ByVal url As String) As Picture
    Dim IPic(15) As Byte 'holds the IPicture interface
    CLSIDFromString StrPtr("{7BF80980-BF32-101A-8BBB-00AA00300CAB}"), IPic(0)
    OleLoadPicturePath StrPtr(url), 0&, 0&, 0&, IPic(0), LoadPictureFromURL
    
End Function

Its intended for use with MSForms Image control but I can't get it to work unless I hard code the path. This works:
strURL = "http://www.blogcdn.com/www.engadget.com/media/2012/03/nokia-n9-inception.jpg"
Set Image0.Picture = LoadPictureFromURL(strURL)

BUT using one of the strURL values in my previous post fails. The function doesn't seem to accept long strings!
 
Last edited:

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
Many thanks for spending time researching this.
There are 2 examples at that link:

The first is a variation on the code that I use to download JSON files.
The second one is effectively identical to what I posted in post 1

I've double checked & despite what the SO link says, both use IE no matter which browser is set as the default.
So the 2083 character limit remains for URLs (where on earth did that number come from?)

There is also a 8192 character limit for google static map paths anyway.

I looked at the link CJ London provided but couldn't see how to use it

So after further thought, I've gone with option 3 from my first post:
Shorten path by using fewer points in lat/long data
I've written a function that selects every 2nd or 3rd or 4th pair (etc) of coordinates depending on the path length, then encodes the path so that the resulting URL is less than the 2083 limit
In the most extreme case (postcode district ZE2 in the Shetland Isles), the path was so long that I had to select the first, last & every 20th point in between



Even in this case, although boundary precision is reduced slightly its not enough to be a concern

I've just finished coding all 18000+ points - surprisingly fast once I'd worked out the process

I'm now going to mark this as solved
Thanks to you both for the suggestions
 

Attachments

  • PostcodeDistrictMap.PNG
    PostcodeDistrictMap.PNG
    69.4 KB · Views: 666
Last edited:

CJ_London

Super Moderator
Staff member
Local time
Today, 12:52
Joined
Feb 19, 2013
Messages
16,555
Since Edge has replaced IE which is now deprecated, I wonder if MS will be upgrading the api to use Edge?
 

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
I've been wondering that for a long time.
I suspect it won't due to the additional security features in Edge

Also Edge also has issues with very long URLs
The screenshots below show the results of pasting the long URL of around 3300 characters from the end of my first post into Edge & Chrome

 

Attachments

  • Capture.jpg
    Capture.jpg
    27.3 KB · Views: 593

Minty

AWF VIP
Local time
Today, 12:52
Joined
Jul 26, 2013
Messages
10,355
I think the edge version has some merits...

A lot less cluttered ;)
 

Orthodox Dave

Home Developer
Local time
Today, 12:52
Joined
Apr 13, 2017
Messages
218
So the 2083 character limit remains for URLs (where on earth did that number comer from?)
Something to do with it being a prime number?
 

MrHans

Registered User
Local time
Today, 13:52
Joined
Jul 27, 2015
Messages
147
Hi Colin,


I remembered this discussion from the past.
I am now encountering the same problem actually, while generating a Google Static Map that displays a route using the Path parameter. When the route exceeds about 100 KM, the URL exceeds the 2K characters and it fails.


Do you have some tips to get the most out of it?
Like the encoding that you applied, what kind of encoding is that?


Thanks a lot!
 

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
Hi Hans
You do have a good memory as I haven't looked at this thread in a very long time

I achieved a very good solution by a combination of methods. But it was very complicated to work out

Google maps allows up to 8192 characters in URLs but even that wasn't nowhere near enough for some of my complex boundary lines. The longest of these for a group of Scottish islands had so many points that it was around 90,000 characters originally - see map in post #5

AFAIK it still isn't possible to use any browser other than IE for this purpose so you are actually stuck with the 2083 character limit for the URL. Therefore you need to shorten the URL in order to trace your path.

To do so, I used fewer points (sampling every 2nd, 3rd, 10th ...20th point as appropriate from the full dataset) then used an encoded polyline algorithm to shorten those geocordinates still further - see code in post #1 for an example of this in practice
The Google Static Maps API Developers Guide contains much of the information needed and is very good :
https://developers.google.com/maps/documentation/maps-static/dev-guide
The encoded polyline section is towards the end and has a link to the algorithm
https://developers.google.com/maps/documentation/utilities/polylinealgorithm

One of the the main tasks was to create a VBA procedure to process that algorithm. There were no examples online when I did so so I created my own. It took a long time to test but works perfectly.
When creating dynamic boundary circles of differing radii to display places near to a specified location, I also had to find and/or create functions to determine trigonometric functions like arctan2. Some of those were things I hadn't used since I was at school a very long time ago.

However, its well over a year since I wrote the code & would need to study it again to remember exactly what I did at the time

The end results form a small part of my UK Postal Address Finder app which I have for sale via my website.
There is a free evaluation version if you want to see how I make use of the code I developed.
See http://www.mendipdatasystems.co.uk/uk-postal-address-finder/4594138311 for several screenshots and a download link if you wish to have a look at it. Click any screenshot for a larger popup version

If you want further details, please email me using the link below.
 

MrHans

Registered User
Local time
Today, 13:52
Joined
Jul 27, 2015
Messages
147
Thanks a lot for your feedback Colin.

I think I'll need a similar combination of workarounds. Possibly first reduce the accuracy of the coordinates to max 4 decimals, then remove some of points as you described and finally apply the Encoding routine.

I read the page you linked to, but it looks very complicated indeed. I'll search around a bit more to see if I can find some more examples of it.

Thx again!
 

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
It was complicated but it is solvable.
From memory, I don't think you should reduce the coordinate accuracy as that will make the encoded version less accurate BUT won't make that code any shorter
Creating the VBA procedure to make the encoded version took time and lots of testing but wasn't that difficult.
Basically just convert the 'recipe' to VBA
As I said I couldn't find any examples of it online. The nearest I found was this site http://jomacinc.com/map-radius/.
You'll see that I asked if the author would do a VBA conversion but no luck! Nevertheless it was a massive help for me at the time

Please do have a look at my UKPAF app or at the very least look at the screenshots
Obviously you are very welcome to purchase the source code version of my app and make use of/adapt my code ;) :cool:
 
Last edited:

MrHans

Registered User
Local time
Today, 13:52
Joined
Jul 27, 2015
Messages
147
Ok, it's good to know that reducing the accuracy of the coordinates won't make any difference using this encoding scheme.

The recipe looks a bit over my head to be honest, I'm not experienced working with binary data at all. For now it doesn't make much sense to me.

I checked your application and it looks very nice indeed. Like all the other applications I've seen from you. And I understand you need to make a living as well.

The function itself would be nice addition to our repository though. Maybe I'll open another thread to develop something together.
 

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
I'm happy to pass on the encode polyline procedure.
This shows how I adapted the Google algorithm for VBA.
I've disabled all the items that can be bypassed

Code:
Function EncPolyline(sngValue) As String

'used to calculate the EncodedPolylineAlgorithmFormat values for Google maps
'full steps below

    Dim lngE5 As Long, strBin As String
    Dim strTemp1, strTemp2, strTemp3 As String
    Dim strDec As String, strOut As String
    
    '==========================================
    'The steps for encoding such a signed value are specified below.

    'Take the initial signed value:
    '-179.9832104
    
    If IsNull(sngValue) Then Exit Function
    
    '1. Take the decimal value and multiply it by 1e5, rounding the result:
    '-17998321
    lngE5 = Fix(sngValue * 100000)
    'Debug.Print lngE5
    
    '2. Convert the decimal value to binary.
    'Note that a negative value must be calculated using its two's complement
    'by inverting the binary value and adding one to the result:
    '00000001 00010010 10100001 11110001
    '11111110 11101101 01011110 00001110
    '11111110 11101101 01011110 00001111
    strBin = DecToBin(lngE5)
    
    'Debug.Print strBin
    
    '3. Left-shift the binary value one bit:
    '11111101 11011010 10111100 00011110
    strBin = Mid(strBin, 2) & "0"
    
    '4. If the original decimal value is negative, invert this encoding:
    'i.e. make all 0 into 1 and vice versa
    '00000010 00100101 01000011 11100001
    If sngValue < 0 Then
        strBin = Replace(strBin, "1", "2")
        strBin = Replace(strBin, "0", "1")
        strBin = Replace(strBin, "2", "0")
    End If
    
    'Debug.Print strBin
    
    '5. Break the binary value out into 5-bit chunks (starting from the right hand side):
    '00001 00010 01010 10000 11111 00001
    'This can be bypassed
    'strTemp1 = Mid(strBin, 3, 5) & " " & Mid(strBin, 8, 5) & _
        " " & Mid(strBin, 13, 5) & " " & Mid(strBin, 18, 5) & _
        " " & Mid(strBin, 23, 5) & " " & Mid(strBin, 28, 5)
    
    '6. Place the 5-bit chunks into reverse order:
    '00001 11111 10000 01010 00010 00001
    'This can be bypassed
    'strTemp2 = Mid(strBin, 28, 5) & " " & Mid(strBin, 23, 5) & _
        " " & Mid(strBin, 18, 5) & " " & Mid(strBin, 13, 5) & _
        " " & Mid(strBin, 8, 5) & " " & Mid(strBin, 3, 5)
        
    '7. OR each value with 0x20 if another bit chunk follows:
    '100001 111111 110000 101010 100010 000001
    'This can be bypassed
    'strTemp3 = "1" & Mid(strBin, 28, 5) & " 1" & Mid(strBin, 23, 5) & _
        " 1" & Mid(strBin, 18, 5) & " 1" & Mid(strBin, 13, 5) & _
        " 1" & Mid(strBin, 8, 5) & " 0" & Mid(strBin, 3, 5)
    
    '8. Convert each value to decimal:
    '33 63 48 42 34 1
    'This can be bypassed
    'strDec = Bin2Dec("1" & Mid(strBin, 28, 5)) & " " & Bin2Dec("1" & Mid(strBin, 23, 5)) & _
        " " & Bin2Dec("1" & Mid(strBin, 18, 5)) & " " & Bin2Dec("1" & Mid(strBin, 13, 5)) & _
        " " & Bin2Dec("1" & Mid(strBin, 8, 5)) & " " & Bin2Dec("0" & Mid(strBin, 3, 5))
    
    '9. Add 63 to each value:
    '96 126 111 105 97 64
    'This can be bypassed
    'strDec = (63 + Bin2Dec("1" & Mid(strBin, 28, 5))) & " " & (63 + Bin2Dec("1" & Mid(strBin, 23, 5))) & _
        " " & (63 + Bin2Dec("1" & Mid(strBin, 18, 5))) & " " & (63 + Bin2Dec("1" & Mid(strBin, 13, 5))) & _
        " " & (63 + Bin2Dec("1" & Mid(strBin, 8, 5))) & " " & (63 + Bin2Dec("0" & Mid(strBin, 3, 5)))
    
    '10. Convert each value to its ASCII equivalent:
    '`~oia@
    strOut = Chr(63 + Bin2Dec("1" & Mid(strBin, 28, 5))) & Chr(63 + Bin2Dec("1" & Mid(strBin, 23, 5))) & _
        Chr(63 + Bin2Dec("1" & Mid(strBin, 18, 5))) & Chr(63 + Bin2Dec("1" & Mid(strBin, 13, 5))) & _
        Chr(63 + Bin2Dec("1" & Mid(strBin, 8, 5))) & Chr(63 + Bin2Dec("0" & Mid(strBin, 3, 5)))
    
    'Debug.Print sngValue, strOut
    
    EncPolyline = strOut
End Function

This allow you to test the code for a single coordinate value:
Code:
Sub TESTEncode()

    Dim sngValue As Single
    sngValue = 51.3447
    EncPolyline (sngValue)
    
End Sub

These functions are used to convert decimal to binary & vide versa

Code:
Public Function DecToBin(ByVal lngDec As Long) As String

'==============================
'Sample results:

'Debug.Print DecToBin(32768)
'00000000000000001000000000000000
'Debug.Print DecToBin(32769)
'00000000000000001000000000000001
'Debug.Print DecToBin(2 ^ 31 - 1)
'01111111111111111111111111111111
'Debug.Print DecToBin(2147483647)
'01111111111111111111111111111111
'Debug.Print DecToBin(-2 ^ 31)
'10000000000000000000000000000000
'Debug.Print DecToBin(-2147483648#)
'10000000000000000000000000000000
'Debug.Print DecToBin(2 ^ 31)
' Overflow error

'Function based on example in MSKB Art 109260, How to Convert a Decimal Number to a Binary Number in a String modified somewhat. As noted in article, "This program accepts a nine-digit positive decimal number and returns a 32- character string that represents the number in binary notation. Negative numbers are converted into the 32-digit, twos-complement binary format used by long integers in Basic.... In that format, the left-most binary digit (the thirty-second digit in a long integer) will always be 1 for a negative number and 0 for a positive number."

'If you don't want the leading zeroes then you'd need to modify function.

Const MAXLEN = 30
Dim strBin As String
Dim N As Long

If lngDec < 0 Then
strBin = "1"
Else
strBin = "0"
End If

For N = MAXLEN To 0 Step -1
If lngDec And (2 ^ N) Then
strBin = strBin & "1"
Else
strBin = strBin & "0"
End If
Next

DecToBin = strBin

End Function

'Binary To Decimal
' =================
Function Bin2Dec(BinaryString As String) As Variant
    Dim X As Integer
    For X = 0 To Len(BinaryString) - 1
        Bin2Dec = CDec(Bin2Dec) + Val(Mid(BinaryString, _
                  Len(BinaryString) - X, 1)) * 2 ^ X
    Next
End Function

There's obviously a lot more to it but it may get you started
I have other code I developed for drawing a circle on a map

Hope that helps
 

MrHans

Registered User
Local time
Today, 13:52
Joined
Jul 27, 2015
Messages
147
Ah wow, yes, that should help a lot!

Thank you for sharing Colin.
 

isladogs

MVP / VIP
Local time
Today, 12:52
Joined
Jan 14, 2017
Messages
18,186
You're welcome - you should be able to follow what each step of the code does - I left the commented code/values in deliberately
Let me know if it doesn't compile. If so there may be other code involved or global variables to define.
Good luck
 

Users who are viewing this thread

Top Bottom