Jump to content

Module:MapClip

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Wnt (talk | contribs) at 20:32, 10 April 2013 (Muddled, distracted mass of code I'm afraid... hope I can get this one straightened out...). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

 --- 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