/* 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, latNum, lngNum, tempA, tempB, plusPos: 9, plusBreak: "+", Yind, Xind, tmpNum ], load('StringProc), tempA: (latitude + NorthSouthSize) * OLCbase^3, latNum: floor(tempA), Yind: floor((tempA - latNum) * 5) * 4, tempB: (longitude + EastWestSize) * OLCbase^3, lngNum: floor(tempB), Xind: floor((tempB - lngNum) * 4), for j: 1 thru 5 do ( tmpNum: mod(lngNum, OLCbase), lngNum: (lngNum - tmpNum) / OLCbase, OLCstr: sconcat(substring(cipherStr, tmpNum + 1, tmpNum + 2), OLCstr), tmpNum: mod(latNum, OLCbase), latNum: (latNum - tmpNum) / OLCbase, OLCstr: sconcat(substring(cipherStr, tmpNum + 1, tmpNum + 2), OLCstr) ), OLCstr: sinsert(plusBreak, OLCstr, plusPos), OLCstr: sconcat(OLCstr, substring(cipherStr, Yind + Xind + 1, Yind + Xind + 2) ) )$