Find Duplicate LatLong.fh_lua--[[
@Title: Find Duplicate LatLong
@Type: Standard
@Author: Mike Tate
@Version: 1.0
@Keywords:
@LastUpdated: 10 Mar 2026
@Licence: This plugin is copyright (c) 2026 Mike Tate and contributors, and is licensed under the MIT License which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: List Place records with duplicate LatLong values.
]]
function Main()
local arrPlac = {} -- Result Set arrays
local arrRcId = {}
local arrLtLg = {}
local arrDpId = {}
local dicRecd = {} -- List Record Id versus LatLong
local dicLatLong = {} -- List LatLong versus Record Id
local dicDpId = {} -- List Duplicate Id versus LatLong
local ptrPlac = fhNewItemPtr()
ptrPlac:MoveToFirstRecord("_PLAC")
while ptrPlac:IsNotNull() do -- Search all Place records
local ptrLatLong = fhGetItemPtr(ptrPlac,"~.LATLONG")
local strLatLong = fhGetValueAsText(ptrLatLong)
if #strLatLong > 0 then
if dicLatLong[strLatLong] then -- Found duplicate LatLong
dicRecd[dicLatLong[strLatLong]] = strLatLong
dicRecd[fhGetRecordId(ptrPlac)] = strLatLong
if not dicDpId[strLatLong] then
dicDpId[strLatLong] = true
table.insert(dicDpId,strLatLong)
end
else
dicLatLong[strLatLong] = fhGetRecordId(ptrPlac)
end
end
ptrPlac:MoveNext()
end
table.sort(dicDpId)
for intDpId, strLatLong in ipairs(dicDpId) do -- Ensure Duplicate Id are in same order as LatLong
dicDpId[strLatLong] = intDpId
end
for intRcId, strLatLong in pairs(dicRecd) do -- Populate the Result Set arrays
ptrPlac:MoveToRecordById("_PLAC",intRcId)
table.insert( arrPlac, ptrPlac:Clone() )
table.insert( arrRcId, intRcId )
table.insert( arrLtLg, strLatLong )
table.insert( arrDpId, dicDpId[strLatLong] )
end
if #arrPlac > 0 then -- Display the Result Set
fhMessageBox("\n "..#arrPlac.." duplicate LatLong found. \n")
fhOutputResultSetTitles("Find Duplicate LatLong")
fhOutputResultSetColumn("Place", "item" , arrPlac, #arrPlac, 200, "align_left" )
fhOutputResultSetColumn("RecId", "integer", arrRcId, #arrPlac, 30, "align_mid" , 2 )
fhOutputResultSetColumn("LatLong","text" , arrLtLg, #arrPlac, 100, "align_left" )
fhOutputResultSetColumn("DupId", "integer", arrDpId, #arrPlac, 30, "align_right", 1 )
else
fhMessageBox("\n No duplicate LatLong found. \n")
end
end
fhInitialise(6,0,0,"save_recommended")
Main()
--[[
@Title: Find Duplicate LatLong
@Type: Standard
@Author: Mike Tate
@Version: 1.0
@Keywords:
@LastUpdated: 10 Mar 2026
@Licence: This plugin is copyright (c) 2026 Mike Tate and contributors, and is licensed under the MIT License which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: List Place records with duplicate LatLong values.
]]
function Main()
local arrPlac = {} -- Result Set arrays
local arrRcId = {}
local arrLtLg = {}
local arrDpId = {}
local dicRecd = {} -- List Record Id versus LatLong
local dicLatLong = {} -- List LatLong versus Record Id
local dicDpId = {} -- List Duplicate Id versus LatLong
local ptrPlac = fhNewItemPtr()
ptrPlac:MoveToFirstRecord("_PLAC")
while ptrPlac:IsNotNull() do -- Search all Place records
local ptrLatLong = fhGetItemPtr(ptrPlac,"~.LATLONG")
local strLatLong = fhGetValueAsText(ptrLatLong)
if #strLatLong > 0 then
if dicLatLong[strLatLong] then -- Found duplicate LatLong
dicRecd[dicLatLong[strLatLong]] = strLatLong
dicRecd[fhGetRecordId(ptrPlac)] = strLatLong
if not dicDpId[strLatLong] then
dicDpId[strLatLong] = true
table.insert(dicDpId,strLatLong)
end
else
dicLatLong[strLatLong] = fhGetRecordId(ptrPlac)
end
end
ptrPlac:MoveNext()
end
table.sort(dicDpId)
for intDpId, strLatLong in ipairs(dicDpId) do -- Ensure Duplicate Id are in same order as LatLong
dicDpId[strLatLong] = intDpId
end
for intRcId, strLatLong in pairs(dicRecd) do -- Populate the Result Set arrays
ptrPlac:MoveToRecordById("_PLAC",intRcId)
table.insert( arrPlac, ptrPlac:Clone() )
table.insert( arrRcId, intRcId )
table.insert( arrLtLg, strLatLong )
table.insert( arrDpId, dicDpId[strLatLong] )
end
if #arrPlac > 0 then -- Display the Result Set
fhMessageBox("\n "..#arrPlac.." duplicate LatLong found. \n")
fhOutputResultSetTitles("Find Duplicate LatLong")
fhOutputResultSetColumn("Place", "item" , arrPlac, #arrPlac, 200, "align_left" )
fhOutputResultSetColumn("RecId", "integer", arrRcId, #arrPlac, 30, "align_mid" , 2 )
fhOutputResultSetColumn("LatLong","text" , arrLtLg, #arrPlac, 100, "align_left" )
fhOutputResultSetColumn("DupId", "integer", arrDpId, #arrPlac, 30, "align_right", 1 )
else
fhMessageBox("\n No duplicate LatLong found. \n")
end
end
fhInitialise(6,0,0,"save_recommended")
Main()
Source:Find-Duplicate-LatLong-1.fh_lua