Module:MapClip
This module clips out a small region from a set of equirectangular world maps. It can cross boundaries between maps, pasting together pieces of up to four maps per figure. It adds markings for longitude and latitude, feature markings and annotations. You can click on marked features to go to the target articles.
Usage
{{#invoke:MapClip|map|parameters}}
Parameters
Note that all parameters can be provided either as a single number (fractional degrees) or three numbers (fractional degrees, minutes, seconds).
Note that marks for degrees, minutes, seconds are ignored - the numbers are simply assumed to be deg, min, sec in that order, with any other numbers ignored.
Each of these values can be fractional. "W", "S", or "-" causes the latitude/longitude to be counted as negative (the module doesn't actually check to see it is in the right direction).
Giving a south value greater than a north value causes an error; east and west values can be swapped to show the other half of the world.
Mandatory parameters
- regionwestedge,regioneastedge,regionsouthedge,regionnorthedge - required parameters set the edges (in degrees) of the region to be mapped
Optional parameters
- mapfile - specifies a custom set of map files to use. Map files are in [[ ]] listed from left to right. If multiple rows are present they should be separated by "|" (I think this can be passed in with {{!}}).
- grid - this important parameter specifies the color for a grid of latitude and longitude meridians used to annotate the map. Omitting it omits the grid. The spacing of the grid is presently only automatic.
- mapwestedge,mapeastedge',mapsouthedge,mapnorthedge - optional parameters set the edges in degrees of the entire set of map image files. Default to -180,180,-90,90. If mapfile is not specified the default is provided for these and overrides this parameter value (you don't need it).
- mapwidthpx,mapheightpx - tell the program how many pixel an individual map image file has. I've actually had it work with the wrong figure.
- float- right or left to allow the image to "float" in the html sense (like a normal image)
- nowiki - returns the html text (a mass of divs and a file link) for display of the map, rather than the map itself. This is not the same as simply enclosing the #invoke in nowiki tags.
Per-feature parameters
Each of these uses an independent number N. If a feature is present it must have a featureNlat and a featureNlong; the others are optional per feature. Numbers should start from 1 and not skip any for best results.
- featureNlat - the latitude of the feature (can be one or three numbers like the others)
- featureNlong - longitude
- featureNname - the main purpose of the name of the feature presently is to be a Wikilink; apart from linking to an article this shouldn't be provided. There might be a way to distinguish mouseover from the link in the future...
- featureNimage - overrides the default File:Full Star Yellow.svg with a filename you specify. Omit File: from the parameter.
- featureNsize - overrides the default 15px size for the image.
- featureNtext - suppresses placement of any image - instead this arbitrary text is used. This can be a link or not, and is displayed with upper left corner at the latitude and longitude you've provided. The purpose is to allow annotation of general features or groups of features. It can also be used to add a caption to a star on the map, by displacing it a little to the right (larger longitude) or in some other direction.
Example
{{#invoke:MapClip|map|regionwestedge=-82|regioneastedge=-80|regionnorthedge=26|regionsouthedge=24|feature1=Key West|feature1lat=24°33′33″N|feature1long=81°47′03″W|feature2=Old Rhodes Key|feature2lat=25.365957°N|feature2long=80.241866°W|feature3=Old Totten Key|feature3lat=25.3796°N|feature3long=80.2484°W|feature4=Reid Key|feature4lat=25.392779°N|feature4long=80.240149°W|feature5=Duck Key|feature5lat=24°46′32″N|feature5long=80°54′39″W|feature6=Pigeon Key|feature6lat=24.703991°N|feature6long=81.155308°W|feature7=Summerland Key|feature7lat=24.657°N|feature7long=81.441°W|feature8text=[[Lower Keys]]|feature8lat=24.4|feature8long=-81.8|feature9text=[[Middle Keys]]|feature9lat=24.55|feature9long=-81.13|grid=grey}}
produces
Lua error: bad argument #1 to 'find' (string expected, got nil).
--- The purpose of this module is to clip out a segment from a set of files that makes up a map
--- various annotations and scale bars should be added.
--- The spritedraw function is being considered as a possible direct copy (future "require")
--- from Module:Sprite - however, both modules are too inchoate at this time to do that confidently,
--- and some modification may be needed.
local p={}
function spritedraw(left,right,top,bottom,name,imagewidth,spritewidth,scalewidth,float)
if (left==nil or right==nil or top==nil or bottom==nil or name==nil or imagewidth==nil or spritewidth==nil or scalewidth==nil) then return tostring(left) .. tostring(right)..tostring(top)..tostring(bottom)..tostring(name)..tostring(imagewidth)..tostring(spritewidth)..tostring(scalewidth) end
if float then float="float:"..float..";" else float="" end
local scale=scalewidth/spritewidth
top=math.floor(top*scale)
bottom=math.floor(bottom*scale)
left=math.floor(left*scale)
right=math.floor(right*scale)
local scalestring=""
if scalewidth~=spritewidth then scalestring=math.floor(imagewidth*scale)..'px|' end
output='<div style="position:relative;'..float..'width:'..scalewidth..'px;height:'..(bottom-top)..'px;"><div style="position:absolute;'..float..'top:'..(-1*top)..'px;left:'..(-1*left)..'px;clip:rect('..top..'px,'..right..'px,'..bottom..'px,'..left..'px);">[[Image:Flag sprite demo.png|'..scalestring..'link=http://en.wikipedia.org/wiki/'..name..']]</div></div>'
return output
end
function p.map(frame)
--- variables "map" refer to the original image file
--- variables "region" refer to the clipped area to be displayed
local args=frame.args
local parent=frame.getParent(frame)
local pargs=parent.args
--- pixel values (setting regionwidth forces scaling.
--- Regionheight may not be implemented because there's no way to 1-way scale I know of
local mapwidthpx=args.mapwidthpx or pargs.mapwidthpx -- PER IMAGE, all images assumed to be the same
local mapheightpx=args.mapheightpx or pargs.mapheightpx
local regionwidthpx=args.regionwidthpx or pargs.regionwidthpx
local regionheightpx=args.regionheightpx or pargs.regionheightpx
local directions={'north','south','east','west'}
local worldedge={90,-90,-180,180}
for x,d in ipairs(directions) do
local mapedgestring,mapedge={},{}
mapedgestring[d]=args['map'..d..'edge'] or args['map'..d..'edge']
mapedge[d]=tonumber(mw.ustring.find(mapedgestring[d],"^%D*(%d+)")) or worldedge[d] -- assume a world map if not specified
mapedge[d]=mapedge[d]+tonumber(mw.ustring.find(mapedgestring[d],"^%D*%d+%D*(%d)+") or 0)/60
mapedge[d]=mapedge[d]+tonumber(mw.ustring.find(mapedgestring[d],"^%D*%d+%D*%d+%D*(%d+)") or 0)/3600
end
for x,d in ipairs(directions) do
local regionedgestring,mapedge={},{}
regionedgestring[d]=args['map'..d..'edge'] or args['map'..d..'edge']
regionedge[d]=tonumber(mw.ustring.find(regionedgestring[d],"^%D*(%d+)")) or worldedge[d] -- assume a world map if not specified
regionedge[d]=regionedge[d]+tonumber(mw.ustring.find(regionedgestring[d],"^%D*%d+%D*(%d)+") or 0)/60
regionedge[d]=regionedge[d]+tonumber(mw.ustring.find(regionedgestring[d],"^%D*%d+%D*%d+%D*(%d+)") or 0)/3600
end
local mapfile=args.mapfile or pargs.mapfile or "[[WorldMap_180-0-270-90.png]][[WorldMap_270-0-360-90.png]][[WorldMap_0-0-90-90.png]][[WorldMap_90-0-180-90.png]]|[[WorldMap_-180,-90,-90,0.png]][[WorldMap_-90,-90,0,0.png]][[WorldMap_0,-90,90,0.png]][[WorldMap_-270,-90,-180,0.png]]"
local mapfiles={}
local row=0
mapfile=mapfile.."|" -- last row will be processed like the others
while mw.ustring.match(mapfile,"|") do
row=row+1
local rowtext=mw.ustring.match(mapfile,"^([^|]*)|")
mapfiles[row]={}
prowl=mw.ustring.gmatch(rowtext,"%[%[([^%[%]])*%]%]")
repeat
local f=prowl()
if not f then break;end
table.insert(mapfiles[row],f)
until false
mapfile=mw.ustring.gsub(mapfile,"^[^|]*|","")
end
if not mapfiles[1][1] then mapfiles={{'WorldMap_180-0-270-90.png','WorldMap_270-0-360-90.png','WorldMap_0-0-90-90.png','WorldMap_90-0-180-90.png'},{'WorldMap_-180,-90,-90,0.png','WorldMap_-90,-90,0,0.png','WorldMap_0,-90,90,0.png','WorldMap_-270,-90,-180,0.png'}} end -- redundant with later default
local totalmapwidthpx=mapwidthpx*#mapfiles[1]
local totalmapheightpx=mapheightpx*#mapfiles
local mapwidthdeg=mapedge[east]-mapedge[west]
if mapwidthdeg<0 then mapwidthdeg=mapwidthdeg+360 end
local mapheightdeg=mapedge[north]-mapedge[south]
if mapheightdeg<0 then return "[[Module:MapClip]] error: north edge south of south edge" end
local widthratio=totalmapwidthpx/mapwidthdeg
local heightratio=totalmapheightpx/mapheightdeg
local left=regionedge['west']*widthratio
local xfile=math.floor(left/mapwidthpx)
left=left-xfile*mapwidthpx
local right=regionedge['east']*widthratio-xfile*mapwidthpx
if right>mapwidthpx then right=mapwidthpx end
local top=regionedge['north']*heightratio
local yfile=math.floor(top/mapheightpx)
top=top-yfile*mapheightpx
local bottom=regionedge['south']*heightratio
if bottom>mapheightpx then bottom=mapheightpx end
-- still need to implement multi file junctions but this is mad enough to start!
local imagewidth=mapwidthpx
local spritewidth=regionwidthpx
local scalewidth=nil -- not implemented yet
local float=args.float or pargs.float or nil
return spritedraw(left,right,top,bottom,name,imagewidth,spritewidth,scalewidth,float)
end
return p