Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/trappist the monk/nts
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
require ('strict'); -- alarm when global variables etc are used local nts = require ('Module:Canada NTS'); -- for extents_from_grid(), nts_series_validate, nts_are_validate, nts_sheet_validate local data = mw.loadData ('Module:Canada NTS/data'); -- load the ~/data module --[[--------------------------< W I K I D A T A _ L A T _ L O N G _ G E T >------------------------------------ returns latitude and longitude from wikidata for <qid>; nil else ]] local function wikidata_lat_lon_get (qid) if qid then local value_t = mw.wikibase.getBestStatements (qid, 'P625')[1]; -- attempt to get P625; nil when article does not have P625 if value_t then value_t = value_t.mainsnak.datavalue.value; -- point to the value table return value_t.latitude, -1.0 * value_t.longitude; -- return coordinates from value_t; longitude normalized end end end --[[--------------------------< T A B B I N G >---------------------------------------------------------------- return the number of tabs necessary to more-or-less position comments at column 80 (the right-side margin line in the wiki code editor) ]] local function tabbing (str) return math.ceil ((80 - 4 - str:len()) / 4); -- the -4 because every line begins with a tab character end --[[--------------------------< S O R T >---------------------------------------------------------------------- sort by keys; ascending order numerically by series then by area (alpha sort) then numerically by sheet ]] local function sort (a, b) local a_key_series, a_key_area, a_key_sheet = a:match ('(%d+)(%u)(%d*)'); -- extract series, area, sheet NTS id parts from <a> local b_key_series, b_key_area, b_key_sheet = b:match ('(%d+)(%u)(%d*)'); -- extract series, area, sheet NTS id parts from <b> a_key_series = tonumber (a_key_series); -- convert numerical parts of key from <a> to numbers for comparison a_key_sheet = tonumber (a_key_sheet); -- nil when <a_key_sheet> is empty string a_key_sheet = a_key_sheet and a_key_sheet or 0 -- optional so when omitted set to 0 for comparison b_key_series = tonumber (b_key_series); -- convert numerical parts of key from <a> to numbers for comparison b_key_sheet = tonumber (b_key_sheet); -- nil when <b_key_sheet> is empty string b_key_sheet = b_key_sheet and b_key_sheet or 0 -- optional so when omitted set to 0 for comparison if a_key_series ~= b_key_series then -- do the comparisons; by series first return a_key_series < b_key_series; elseif a_key_area ~= b_key_area then -- then by area return a_key_area < b_key_area; else return a_key_sheet < b_key_sheet; -- and lastly by sheet end end --[[--------------------------< L A T _ B O U N D S _ C H E C K >---------------------------------------------- is <lat> same as or north of <south> and is <lat> same as or south of <north>? returns direction 'north' or 'south' when <lat> out of bounds; nil else ]] local function lat_bounds_check (lat, north, south) if lat < south then return 'south'; -- out of bounds south of <south> elseif lat > north then return 'north'; -- out of bounds north of <north> end end --[[--------------------------< L O N _ B O U N D S _ C H E C K >---------------------------------------------- is <lon> same as or east of <west> and is <lat> same as or west of <east>? returns direction 'east' or 'west' when <lon> out of bounds; nil else ]] local function lon_bounds_check (lon, west, east) if lon < east then return 'east'; -- out of bounds east of <east> elseif lon > west then return 'west'; -- out of bounds west of <west> end end --[[--------------------------< I S _ I N _ B O U N D S >------------------------------------------------------ get map extents using series, area, sheet. check to see that lat/lon fall within the map extents. returns empty string for concatenation when lat/lon fall within map extents; an error message else only one error mesage is returned; if both <lat> and <lon> are out of bounds, this function returns an error message for only one of them because series, area, sheet are taken from Module:Canada NTS/data, they are presumed to be correct ]] local function is_in_bounds (series, area, sheet, lat, lon) local extents_t = nts.extents_from_grid (tonumber(series), area, tonumber(sheet)); -- fetch extents for this nts key local lat_fail, lon_fail; -- flags local north, west, south, east; -- map extents if '' == sheet then -- is this searies, area, sheet an area map? north, west, south, east = extents_t.area_north, extents_t.area_west, extents_t.area_south, extents_t.area_east; lat_fail = lat_bounds_check (lat, north, south); lon_fail = lon_bounds_check (lon, west, east); else -- here when sheet map north, west, south, east = extents_t.north, extents_t.west, extents_t.south, extents_t.east; lat_fail = lat_bounds_check (lat, north, south); lon_fail = lon_bounds_check (lon, west, east); end if lat_fail or lon_fail then -- build error message if 'north' == lat_fail then return string.format ('P625 %s latitude out of bounds: WD lat/lon: <%s>,%s (NW: <%s>,%s / SE: %s,%s)', lat_fail, lat, lon, north, west, south, east); elseif 'south' == lat_fail then return string.format ('P625 %s latitude out of bounds: WD lat/lon: <%s>,%s (NW: %s,%s / SE: <%s>,%s)', lat_fail, lat, lon, north, west, south, east); elseif 'west' == lon_fail then return string.format ('P625 %s longitude out of bounds: WD lat/lon: %s,<%s> (NW: %s,<%s> / SE: %s,%s)', lon_fail, lat, lon, north, west, south, east); elseif 'east' == lon_fail then return string.format ('P625 %s longitude out of bounds: WD lat/lon: %s,<%s> (NW: %s,%s / SE: %s,<%s>)', lon_fail, lat, lon, north, west, south, east); end end return ''; -- in bounds so return empty string message for concatenation end --[[--------------------------< M A I N >---------------------------------------------------------------------- fetch <map_series> entries from Module:Canada NTS/data. For each of those, attempt to get qid that matches the en.wiki article title from wikidata. Replace article title with the qid, sort and make all pretty like for manual replacement in ~/data. to use the results of this function, Module:Canada NTS requires support for qids in lieu of article names which, as of 2022-04-12, does not yet exist This function may be called from an invoke or from the debug console <frame> is a text string when called from debug console: =p.main ('92') {{#invoke:Sandbox/trappist the monk/nts|main|94}} ]] local function main (frame) local map_series; -- number of the series that we are operating on; for invokes, this is only number or start of a range local map_series_end; -- for invokes only; end of a range of map series local invoked; if 'table' == type (frame) then map_series = frame.args[1]; -- for an invoke if frame.args[2] then map_series_end = frame.args[2]; end invoked = true; -- flag used to modify final output rendering else map_series = frame; -- when called from the debug console end local temp_t = {} -- output goes in this sequence table until rendering for k, v in pairs (data) do -- for each entry in the data mofule local series, area, sheet = k:match ('^(%d+)(%u)(%d*)'); -- fetch series, area, sheet from the entry's key if tonumber(series) >= tonumber(map_series) and tonumber(series) <= tonumber(map_series_end or map_series) then -- when this map is one of the map series we're looking for local map_title_parts = mw.text.split (v, '|'); -- extract an article title local qid = mw.wikibase.getEntityIdForTitle (map_title_parts[1]); -- does this article title have a wikidata entry local lat, lon = wikidata_lat_lon_get (qid); -- attempt to get P625 lat/lon from wikidata's entry for the article title local bounds_msg = ''; -- gets an error message if lat/lon from wikidata not within bounds of NTS map if qid and lat then -- when article title has wikidata entry an wikidata has P625 (latitude/longitude) bounds_msg = is_in_bounds (series, area, sheet, lat, lon); -- empty string when in bounds; message else elseif qid then -- lat can be nil when qid points to dab page or article does not have P625 bounds_msg = string.format ('%s missing P625', qid); -- no lat/lon so no P625 end local str; if not qid then -- when article title doesn't have a wikidata entry str = string.format ('\t["%s"] = "%s",', k, v); -- mimic the original elseif not lat then -- has qid but does not have P625 str = string.format ('["%s"] = "%s",', k, v); -- mimic the original + bounds_msg str = string.format ('\t%s%s-- %s', str, string.rep ('\t', tabbing (str)), bounds_msg); elseif map_title_parts[2] then -- for piped article links str = string.format ('["%s"] = "%s|%s",', k, qid, map_title_parts[2]); str = string.format ('\t%s%s-- %s; %s', str, string.rep ('\t', tabbing (str)), map_title_parts[1], bounds_msg); else -- map name same as en.wiki article title str = string.format ('["%s"] = "%s",', k, qid, map_title_parts[1]); str = string.format ('\t%s%s-- %s; %s', str, string.rep ('\t', tabbing (str)), map_title_parts[1], bounds_msg); end if invoked then -- when this function called through an invoke str = str:gsub ('\t', '	') -- replace plain-text tabs with html numeric entities end table.insert (temp_t, str); -- save end end table.sort (temp_t, sort); -- ascending numerical sort by key (NTS id) for i=#temp_t, 1, -1 do -- working backwards through the table if temp_t[i]:match ('%d+%u"%]') then -- if this key is an area key (no sheet) table.insert (temp_t, i, ''); -- insert an empty string to separate area-from-area elseif i > 1 and temp_t[i]:match ('%["(%d+)') ~= temp_t[i-1]:match ('%["(%d+)') then -- because some series list don't begin with area maps (15 for example) table.insert (temp_t, i, ''); -- insert an empty string to separate area-from-area end end if invoked then -- when this function called through an invoke return table.concat ({'<pre>', table.concat (temp_t, '<br />'),'</pre>'}); -- concatenate into a big string using <br /> tags and wrapped in <pre>...</pre> tagsand done else return table.concat (temp_t, '\n'); -- concatenate into a big string using plain-text newlines and done end end --[[--------------------------< N T S _ K E Y _ V A L I D A T E >---------------------------------------------- debug console function to makes sure that all keys in Module:Canada NTS/data have the correct form =p.nts_key_validate() ]] local function nts_key_validate() for k, _ in pairs (data) do local series, area, sheet = k:match ('^(%d+)(%u)(%d*)$'); if not series then return '<span style="color:#d33">invalid key: ' .. k .. '</span>'; end if not nts.nts_series_validate (tonumber(series)) then return '<span style="color:#d33">invalid series: ' .. k .. '</span>'; end if not nts.nts_area_validate (tonumber(series), area) then return '<span style="color:#d33">invalid area: ' .. k .. '</span>'; end if '' ~= sheet and not nts.nts_sheet_validate (tonumber(sheet)) then return '<span style="color:#d33">invalid sheet: ' .. k .. '</span>'; end end return 'keys are valid'; end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return { main = main, nts_key_validate = nts_key_validate, }
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Templates used on this page:
Module:Sandbox/trappist the monk/nts
(
edit
)
Module:Sandbox/trappist the monk/nts/doc
(
edit
)