I’ve mentioned in my earlier post that it would be nice to find a way to convert the entire track into encoded polyline. The conversion should be done from the GPX format which I mainly use. After some Internet search nothing useful came up. At least nothing automated and ready to use. I even sent an e-mail to the creator of the wonderful site GPSVisualizer, but nothing came back. So, to solve this, I decided to write the code myself.
In order not to start completely from scratch I shamelessly borrowed the Python code from gpxplot project in Google code repository. The project itself seem a bit stale with little activity. However, the provided python code can be used as a great starting point. It has all the GPX reading functionality. All I have to do is to add one more parameter to convert the tracks to the encoded polylines and then post the results, of course. I hope this won’t violate the GNU licensing.
So, the final python code is here. I ran into a couple of problems with the algorithm during the development. However, thanks to a very good source I could solve them. My Python skills need some improvement also. I still think in C/C++ and thus miss out on many Python specific optimizations that can make the code much more elegant. One major issue was with the example provided by Google. The example doesn’t show what to do if the point value is small and doesn’t need to be encoded using all 6 characters. They do show this in the table, but somehow I couldn’t find the explanation how it was achieved.
Testing:
I took a track from my recent trip to Yosemite NP. The file contains one track. The first map is generated using GPSVisualizer. It is just an image.
The second is a static Google map. Note: Google static map is not perfect and at some number of points it will choke. It is a good idea to reduce the number of points to be plotted. It is not possible to see everything anyway. The image below was drawn with 1000 points.
Notes:
- The code is written for Python 3.2. I haven’t tried to run it on Python 2.7.
- It would be nice to make a GUI for it. Using an interpreter or an IDE is a bit tedious. Perhaps I’ll make it time permitting.
- The next step would be to add filtering to the data. This is what I wanted to do for a very long time. Basically GPS signal is sometimes noisy and this noise is transferred to the recorded track. However, the device manufacturers don’t want to add this feature for some reason.
So, the final python code is here.
hy,
your python script is really awsome! is there a way to get the levels from the generated encoded polyline too?
kind regards, bernard
Hi, Bernard.
Sorry, can you elaborate? What kind of levels?
wow that was quick, thanks for your response.
for displaying the encoded polyline on a map i need the levels.
google docs: http://code.google.com/intl/en/apis/maps/documentation/utilities/polylinealgorithm.html
the final code should look like this:
var ePolyline = new GPolyline.fromEncoded({
color: “#ff0000”,
weight: 4,
opacity: 0.8,
points: encodedPoints,
levels: encodedLevels, //the needed level part
zoomFactor: 2,
numLevels: 1
});
map.addOverlay(ePolyline);
greetings,
bernard
Ok, I see.
I’ll have to implement it. Since I was just using polyline in the static Google maps I didn’t need this feature. Please stay tuned. I’ll take me a couple of days. 🙂
That would be a handy tool, if you implement this – i’ll stay tuned for the new feature!
many thanks and
greetings from austria,
bernard
Hi, Bernard.
Do you by any chance have an algorithm description how to calculate the levels? I couldn’t really find a good source on the web other than this – http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/algorithm.html.
Hy!
I have a Javascript Encoder Class for you, if it helps: http://dl.dropbox.com/u/18677288/PolylineEncoder.js
also a good solutions for preventing double slash and linebreak issues are in the class.
hope it helps you.
Greets,
Bernhard
Bernard:
Can you tell me a general algorithm on how you would you your Javascript file? Mainly the sequence of the calls.
Thank you.
hy, sorry for the late response. there is a documentation about encoding polylines on http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoderClass.html
greetings, bernhard
ps: it’s for a local mountain rescue to ensure the track quality guidelines for hikers…
Your Java Script has this code:
segmentLength = Math.pow(points[current[1]].lat()-points[current[0]].lat(),2) + …
The current[] came from stack.pop(), which supposed to just return one top element from stack.
I’m not very proficient with Java script, but it appears that pop() actually returns 2 elements from stack. Am I reading this correctly?
I hope you are not waiting for the feature to come soon. It may take me some time to implement it.
No worrys, your python script would be perfect for a batch convert in a project (if i will get the job).
Thanks in advance for your help!
Kind regards,
Bernhard
What sort of project? Just curious.
I will need you help with testing, however.
Pingback: GPX to Google Polyline. Part 2 | Ilya’s Life Weblog
Hi, I went ahead and checked u’r code, and u should’ve seen my face as i scrolled down though it. 🙂 .. it looks awesome, however i’m kinda clueless with it. So can you help me little with it. I am trying to encode a set of like 60 lat lang values separated by pipe “|”.
i’ll give you an example :- “13.3555072649,77.6859783926|13.3555019186,77.68597096|13.3554965724,77.6859635275|13.3554912261,77.6859560949|13.3554858799,77.6859486623|13.3554805337,77.6859412297|13.3554751874,77.6859337972|13.3554698412,77.6859263646|13.3554644949,77.685918932|13.3554591487,77.6859114994|13.3554538025,77.6859040668|13.3554484562,77.6858966343|13.35544311,77.6858892017|13.3554377637,77.6858817691|13.3554324175,77.6858743365|13.3554270713,77.685866904|13.355421725,77.6858594714|13.3554163788,77.6858520388|13.3554110325,77.6858446062|13.3554056863,77.6858371736|13.3554003401,77.6858297411|13.3553949938,77.6858223085|13.3553896476,77.6858148759|13.3553843013,77.6858074433|13.3553789551,77.6858000108|13.3553736089,77.6857925782|13.3553682626,77.6857851456|13.3553629164,77.685777713|13.3553575701,77.6857702804|13.3553522239,77.6857628479|13.3553468777,77.6857554153|13.3553415314,77.6857479827|13.3553361852,77.6857405501|13.3553308389,77.6857331176|13.3553254927,77.685725685|13.3553201465,77.6857182524|13.3553148002,77.6857108198|13.355309454,77.6857033872|13.3553041077,77.6856959547|13.3552987615,77.6856885221|13.3552934153,77.6856810895|13.355288069,77.6856736569|13.3552827228,77.6856662244|13.3552773765,77.6856587918|13.3552720303,77.6856513592|13.3552666841,77.6856439266|13.3552613378,77.685636494|13.3552559916,77.6856290615|13.3552506453,77.6856216289|13.3552452991,77.6856141963|13.3552399529,77.6856067637|13.3552346066,77.6855993312|13.3552292604,77.6855918986|13.3552239141,77.685584466|13.3552185679,77.6855770334|13.3552132217,77.6855696008|13.3552078754,77.6855621683|13.3552025292,77.6855547357|13.3551971829,77.6855473031|13.3551918367,77.6855398705”
I have no plans to show this in data in the UI so i don’t have any level value to be encoded.
So my question is can we encode this with the help of your code? or is there any further modification we need to do?
thanks for your time.
Hello.
Sorry, my code doesn’t do that. The input format must be in GPX form (a type of XML designed to encode GPS routes).
However, doesn’t Google maps just accept the format you have?
Thanks for responding so fast. It does with the existing format, but I am facing challenge due to so many restrictions google has put in place. 1. it can only accept 2500 request per day. – strange enough in each execution my code hardly sends 5 request(the url query i mean), 2. it can only contain 512 location/request & 3. the total URL size must not exceed 2048 characters. – now without encoding i can hardly fit 60 coordinates in a single request. so I was wondering if we could encode it and that way push more data in each request thus reduce the total no of request. however I still feel the request limit system is kinda flawed as there’s no way it can exceed such a huge limit, but I guess i’ll have to adjust instead hoping google will adjust for me. 😀