/* Calculate Open Location Code (OLC co-ordinates). Calculations from */ /* https://en.wikipedia.org/wiki/Open_Location_Code */ southMostLat: -80 $ northMostLat: 84 $ EastWestSize: 180 $ NorthSouthSize: 90 $ bandHeightMGRS: 8 $ zoneWidthUTM: 6 $ convertLatLng(latitude, longitude) := block( /* error checking */ if not(numberp(latitude) and numberp(longitude)) then return ("Not a number"), if latitude < southMostLat then return ("Latitude is too small"), if latitude > northMostLat then return ("Latitude is too big"), if longitude < -EastWestSize then return ("East longitude is too small"), if longitude >= EastWestSize then return ("West longitude is too big"), convertLatLngToOLC(latitude, longitude) )$ convertLatLngToOLC(latitude, longitude) := block( [cipherStr: "23456789CFGHJMPQRVWX", OLCstr: "", j, OLCbase: 20, latStr, lngStr, tempA, tempB, plusPos: 9, plusBreak: "+", Yind, Xind, number ], load('StringProc), tempA: (latitude + NorthSouthSize) * OLCbase^3, tempB: (longitude + EastWestSize) * OLCbase^3, obase: OLCbase, latStr: striml("0", string(floor(tempA))), lngStr: striml("0", string(floor(tempB))), obase: 5 + 5, ibase: OLCbase, for j: 1 thru 5 do ( number: eval_string(sconcat("0", substring(latStr, j, j + 1))), OLCstr: sconcat(OLCstr, substring(cipherStr, number + 1, number + 2)), number: eval_string(sconcat("0", substring(lngStr, j, j + 1))), OLCstr: sconcat(OLCstr, substring(cipherStr, number + 1, number + 2)) ), OLCstr: sinsert(plusBreak, OLCstr, plusPos), ibase: 5 + 5, Yind: floor((tempA - floor(tempA)) * 5) * 4, Xind: floor((tempB - floor(tempB)) * 4), OLCstr: sconcat(OLCstr, substring(cipherStr, Yind + Xind + 1, Yind + Xind + 2) ) )$