Matrix Games Forums

Forums  Register  Login  Photo Gallery  Member List  Search  Calendars  FAQ 

My Profile  Inbox  Address Book  My Subscription  My Forums  Log Out

Script for converting LonLat Dec to DegMinSec

 
View related threads: (in this forum | in all forums)

Logged in as: Guest
Users viewing this topic: none
  Printable Version
All Forums >> [New Releases from Matrix Games] >> Command: Modern Air / Naval Operations >> Mods and Scenarios >> Lua Legion >> Script for converting LonLat Dec to DegMinSec Page: [1]
Login
Message << Older Topic   Newer Topic >>
Script for converting LonLat Dec to DegMinSec - 2/2/2019 11:51:43 AM   
KnightHawk75

 

Posts: 113
Joined: 11/15/2018
Status: offline
Ever have the need to convert lat -1.00423423423 lon 4.1211234123 into something more human usable or in relation to wanting to alert a player to a location they could find on the map easier? Maybe you wanted to offset some lat lon's by a small amount (seconds) using games constructs to submit in 'N46.00.00' text format but had only Dec version for the basis to start from and don't like doing the math like me.

I ran across this need few times, wrote the following functions for placement in a global script so can be used throughout other events\scripts\actions etc. Be aware you may have to rename strSplit() and round() if you have exactly named function already in other scripts\fragments.

Attachment contains same as below, just with retained indent and related formatting.

--
-- Split text into a list consisting of the strings in text,
-- separated by strings matching delimiter (which may be a pattern).
-- example: strsplit(",%s*", "Anna, Bob, Charlie,Dolores")
-- note: swiped from web
-- notes: used by convertDECtoDMS
function strsplit(delimiter, text)
local list = {}
local pos = 1
if string.find("", delimiter, 1) then -- this would result in endless loops
error("delimiter matches empty string!");
--return list;
end
while 1 do
local first, last = string.find(text, delimiter, pos)
if first then -- found?
table.insert(list, string.sub(text, pos, first-1))
pos = last+1
else
table.insert(list, string.sub(text, pos))
break
end
end
return list
end

-- Rounding function
-- notes: used by convertDECtoDMS
function round(val, decimal)
local exp = decimal and 10^decimal or 1
return math.ceil(val * exp - 0.5) / exp
end

-- Takes in a decimal lat and lon, spits out full string, and optionally table full of details.
-- feed it lon 4.08765567465032 lat -1.3364146676263 get back text: N 4d 53m 24s | W -1d 20m 11s.
-- Note: Due to rounding this is not super super exact conversion it's dam close for messaging users or
-- general placement purposes, if need more precision change calls to round() to include 2nd decimal place
-- ie round(....,2)
-- Requires: supporting strsplit() and round() functions
-- sLon: decimal # longitude; string should work too but assumes #
-- sLat: decimal # latitude; string should work too but assume #
-- optional: retTable submit an initialized table\array var (t = {}; )and it'll fill it with lon\lat data.
-- optional: dotFlag set to true to get 'N -3.01.22' type output format
-- optional: uniDegree set to true to get 'N3°5'32" type output format
function convertDECtoDMS(sLon,sLat,retTable,dotFlag,uniDegree)
if (sLon == nil) or (sLat == nil) then
print('convertDECtoDMS was called without a longitude or latitude.');
return 'Error! missing lon or lat';
end
dotFlag = dotFlag or false; --Default to not using 'D00.00.00' string notation in the output text.
uniDegree = uniDegree or false; --output '°'
local tmpsplit = strsplit('%.',tostring(sLon));
local degreeLon = tmpsplit[1]; -- store integer portion ie -1.34242324 grab the -1 part.
local msLon = tonumber("0." .. tmpsplit[2]); -- store fractional min and seconds part.
tmpsplit = strsplit('%.',tostring(sLat));
local degreeLat = tmpsplit[1] -- store integer portion ie -1.23234232 grab the -1 part.
local msLat = tonumber("0." .. tmpsplit[2]) -- store fractional min and seconds part.

--N == pos S==neg E == pos W==neg
local signLon = string.match(degreeLon,'-') -- figure out if negative or not if yes we are South; returns nil on no '-'
if signLon ~=nil then signLon = 'S' else signLon = 'N' end
local signLat = string.match(degreeLat,'-') -- figure out if negative or not if yes we are West; return nil on no '-'
if signLat ~=nil then signLat = 'W' else signLat = 'E' end

local mLon = 0; local sLon = 0; --minutes --seconds vars lon
local mLat = 0; local sLat = 0; --minutes --seconds vars lat

mLon = round((msLon * 60));
sLon = round((msLon - (mLon/60)) * 3600);
mLat = round((msLat * 60));
sLat = round((msLat - (mLat/60)) * 3600);
--reverse any negative values in min and seconds
print(degreeLon);
print(degreeLat);
if (tonumber(degreeLon) < 0) then degreeLon = (tonumber(degreeLon) * -1) end
if (tonumber(degreeLat) < 0) then degreeLat = (tonumber(degreeLat) * -1) end
if (mLon < 0) then mLon = (mLon * -1) end
if (sLon < 0) then sLon = (sLon * -1) end
if (mLat < 0) then mLat = (mLat * -1) end
if (sLat < 0) then sLat = (sLat * -1) end

--build our return strings.
local sRetLon = '';
local sRetLat = '';

local tmpformat = "%s %sd %sm %ss"; -- default
if uniDegree == true and not dotflag then
tmpformat = "%s %s\xC2\xB0 %s\' %s\""; --ascii 248 didn't work; utf-8 176 (c2b0) does on english windows7\srv2k8r2.
elseif dotFlag then
tmpformat = "%s%s.%s.%s";
end
sRetLon = string.format(tmpformat,tostring(signLon),tostring(degreeLon),tostring(mLon),tostring(sLon));
sRetLat = string.format(tmpformat,tostring(signLat),tostring(degreeLat),tostring(mLat),tostring(sLat));

--build the table submitted by refference, if submitted an empty{} but valid table then acts as byref out param.
if retTable ~=nil then
retTable['LonDir'] = signLon;
retTable['LonDeg'] = tostring(degreeLon);
retTable['LonMin'] = tostring(mLon);
retTable['LonSec'] = tostring(sLon);
retTable['LatDir'] = signLat;
retTable['LatDeg'] = tostring(degreeLat);
retTable['LatMin'] = tostring(mLat);
retTable['LatSec'] = tostring(sLon);
retTable['FullLonString'] = sRetLon;
retTable['FullLatString'] = sRetLat;
end
return (sRetLon .. ' | ' .. sRetLat)
end

-- Sample Usages
-- Assumes all 3 functions are available as global functions from placement in scenario startup script
-- or entire fragment above with all 3 function are executed in same fragment along with sample.
local latlontable = {};
local retval1 = convertDECtoDMS(4.87655674650319,-1.33641466762635)
local retval2 = convertDECtoDMS(4.87655674650319,-1.33641466762635,latlontable)
local retval3 = convertDECtoDMS(4.87655674650319,-1.33641466762635,latlontable,true)
local retval4 = convertDECtoDMS(4.87655674650319,-1.33641466762635,latlontable,nil,true)
print('return value1: ' .. retval1)
print('return value2: ' .. retval2)
print('return value3: ' .. retval3)
print('return value4: ' .. retval4)
print('latlonTable:');
print(latlontable);
print('---');
-- end code

If anyone notices a much better\simpler\improved way to do this or spots an error please let me know.

Attachment (1)

< Message edited by KnightHawk75 -- 2/2/2019 1:54:20 PM >
Post #: 1
RE: Script for converting LonLat Dec to DegMinSec - 2/2/2019 12:35:59 PM   
Primarchx


Posts: 2905
Joined: 1/20/2013
Status: offline
Nice! There are some definite uses for this!

(in reply to KnightHawk75)
Post #: 2
RE: Script for converting LonLat Dec to DegMinSec - 2/2/2019 1:08:34 PM   
KnightHawk75

 

Posts: 113
Joined: 11/15/2018
Status: offline
Thanks. And wouldn't you know it I spelled DEC in function name as DEG and never noticed till now.. grr oops, just change the G to C folks in attachment...or leave it lol.


Edited post#1 with rename, parameter check enhancements and 1 bugfix (not removing sign when negative for degree for output\display, changed attachment to updated version as well.

< Message edited by KnightHawk75 -- 2/2/2019 1:56:07 PM >

(in reply to Primarchx)
Post #: 3
RE: Script for converting LonLat Dec to DegMinSec - 2/12/2019 8:22:02 PM   
apache85

 

Posts: 1396
Joined: 12/18/2014
From: Melbourne, Australia
Status: offline
This is how I do it in my scenarios:

quote:

function Round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end

function ConvertDecimalPositionToDegrees(latitude,longitude)
local latitidePrefix, longitudePrefix
if latitude > 0 then
latitidePrefix = "N"
else
latitidePrefix = "S"
latitude = latitude*-1
end

local latitudeDegrees = math.floor(latitude)
local latitudeMinutes = math.floor((latitude - latitudeDegrees)*60)
local latitudeSeconds = (((latitude-latitudeDegrees)*60) - latitudeMinutes)*60
latitudeSeconds = Round(latitudeSeconds, 0)

if longitude > 0 then
longitudePrefix = "E"
else
longitudePrefix = "W"
longitude = longitude*-1
end

local longitudeDegrees = math.floor(longitude)
local longitudeMinutes = math.floor((longitude - longitudeDegrees)*60)
local longitudeSeconds = (((longitude-longitudeDegrees)*60) - longitudeMinutes)*60
longitudeSeconds = Round(longitudeSeconds, 0)

local result = (latitidePrefix..latitudeDegrees .. "°" .. latitudeMinutes .. "'" .. latitudeSeconds .. '", '..
longitudePrefix..longitudeDegrees .. "°" .. longitudeMinutes .. "'" .. longitudeSeconds .. '"')
return result
end



< Message edited by apache85 -- 2/12/2019 8:24:57 PM >


_____________________________


(in reply to KnightHawk75)
Post #: 4
RE: Script for converting LonLat Dec to DegMinSec - 2/12/2019 9:06:22 PM   
Primarchx


Posts: 2905
Joined: 1/20/2013
Status: offline
Isn't there a way to get a point's lat/long with a mouse click & hotkey of some sort?

(in reply to apache85)
Post #: 5
RE: Script for converting LonLat Dec to DegMinSec - 2/13/2019 1:18:37 AM   
KnightHawk75

 

Posts: 113
Joined: 11/15/2018
Status: offline

quote:

ORIGINAL: Primarchx

Isn't there a way to get a point's lat/long with a mouse click & hotkey of some sort?


CTRL-X in the editor will give you the DEC lat\lon, but that doesn't really help for what I was trying to accomplish.

Nice apache85 I like it looks a bit simpler. I may merge that with my own just added the table options I like having the elements returned to me in a table for easy manipulation when doing dis-info.

(in reply to Primarchx)
Post #: 6
Page:   [1]
All Forums >> [New Releases from Matrix Games] >> Command: Modern Air / Naval Operations >> Mods and Scenarios >> Lua Legion >> Script for converting LonLat Dec to DegMinSec Page: [1]
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts


Forum Software © ASPPlayground.NET Advanced Edition 2.4.5 ANSI

0.109