ooRexx logo
../code/encodeGString.orx/var/www/html/ooRexx/wip #!/usr/bin/env rexx /* ---------------------------------------------------------------- */ /* Encodes a Google PolyLine string from latitude/longitude pairs. */ /* ---------------------------------------------------------------- */ /* */ /* Originally by Ruurd J. Idenburg */ /* */ /* No copyright, no licence, no guarantees or warrantees, be it */ /* explicit, implicit or whatever. Usage is totally and completely */ /* at the users own risk, the author shall not be liable for any */ /* damages whatsoever, for any reason whatsoever. */ /* */ /* Please keep this comment block intact when modifying this code */ /* and add a note with date and a description. */ /* */ /* ---------------------------------------------------------------- */ /* Parameter(s): */ /* */ /* A series of latitude/longitude pairs separated by at least */ /* 1 space, either via: */ /* stdin - if invoked as a command */ /* or: */ /* an Array if invoked as a function/subroutine. */ /* */ /* Result: */ /* */ /* If invoked as a command encoded string to stdout, */ /* if invoked as a function the encoded string is return value. */ /* */ /* ---------------------------------------------------------------- */ /* 2013/12/13 - Initial version */ /* 2023/06/14 - Changed tmpWords from d2c to d2x as a tab char for */ /* instance is whitespace causing incorrect encoding */ /* ---------------------------------------------------------------- */ --::routine encodeGString parse source os how me if (how="COMMAND") then do item = .input~supplier end else do use strict arg thePath if thePath~class~id<>"Array" then do raise syntax 40.912 array("encodeGString",1,thePath~class~id) end item = thePath~supplier end numeric digits 20 prevLat = 0 prevLon = 0 encodedGString = '' do while item~available parse value(item~item) with lat lon . -- no checking on valid range, maybe later if necessary deltaLat = lat-prevLat deltaLon = lon-prevLon prevLat = lat prevLon = lon encodedGString = encodedGString || encodeDegrees(deltaLat) encodedGString = encodedGString || encodeDegrees(deltaLon) item~next end if how="COMMAND" then say encodedGString else return encodedGString exit encodeDegrees: Procedure parse arg degrees -- take the inital signed value, multiply by 1e5 and round the result tmpString = (degrees*1e5)~format(,0) -- convert to binary, left shift 1 position for sign bit tmpString = (tmpString*2)~d2c(4) -- if original was negative invert what we have if degrees<0 then tmpString = tmpString~bitxor('ffffffff'x) -- break this binary value out in 5 bit chunks from the right -- and place them in reverse order tmpString = tmpString~c2d tmpWords = '' do while tmpString>0 tmpWords = tmpWords (tmpString//32)~d2x(2) tmpString = tmpString%32 end -- OR each chunk with '20'x except the last, to indicate end of number -- convert each chunk to decimal, add 63, concatenate into ascii string encodedDegrees = '' do i=1 to tmpWords~words-1 encodedDegrees = encodedDegrees || (tmpWords~word(i)~x2c~bitor('20'x)~c2d+63)~d2c end encodedDegrees = encodedDegrees || (tmpWords~word(i)~x2c~c2d+63)~d2c return encodedDegrees
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–, except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only. The Idenburg website records no personal information and sets no ‘cookies’. This site is hosted on a VPS(Virtual Private System) rented from Transip.nl, a Dutch company, falling under Dutch (privacy) laws (I think).

This page updated on by Ruurd Idenburg.