Module:Infobox dim/sandbox
Appearance
From Wikipedia, the free encyclopedia
This is the module sandbox page for Module:Infobox dim (diff).
See also the companion subpage for test cases (run).
See also the companion subpage for test cases (run).
This module is rated as ready for general use. It has reached a mature state, is considered relatively stable and bug-free, and may be used wherever appropriate. It can be mentioned on help pages and other Wikipedia resources as an option for new users. To minimise server load and avoid disruptive output, improvements should be developed through sandbox testing rather than repeated trial-and-error editing.
Warning This Lua module is used on approximately 362,000 pages .
To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them.
To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them.
Code to convert information about physical size of objects into parameters for geohack or mapframes.
The following parameters describe the physical object size:
- length_km
- length_mi
- width_km
- width_mi
- area_km2
- area_mi2
- area_ha
- area_acre
When producing scale or zoom, module can use size of object on screen specified via |viewport_cm= or |viewport_px=. Defaults to 10cm, to match geohack.
In addition, the module can accept and convert between geohack parameters:
- dim
- scale
- type (e.g., "mountain" or "city")
- population (for type="city" only)
Usage
[edit ]{{#invoke:Infobox dim|dim}}
Generates dim string (e.g, "24km") suitable for geohack link
{{#invoke:Infobox dim|scale}}
Generates scale (e.g, 100000) suitable for geohack link
{{#invoke:Infobox dim|zoom}}
Generates Open Street Map zoom level (e.g, 12) suitable for use in mapframes
The above documentation is transcluded from Module:Infobox dim/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (edit | run) pages.
Add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module's sandbox (edit | diff) and testcases (edit | run) pages.
Add categories to the /doc subpage. Subpages of this module.
require('strict') localgetArgs=require('Module:Arguments').getArgs localp={} locallog2=0.693147181 localppm=1000/0.3-- pixels per meter, from 0.3 mm / pixel from https://wiki.openstreetmap.org/wiki/Zoom_levels -- To convert to OSM zoom level, we need to know meters per pixel at zoom level 9 -- On the equator, it's 305.748 meters/pixel according to https://wiki.openstreetmap.org/wiki/Zoom_levels -- This quantity depends on the latitude (which we usually don't have easy access to) -- Instead, we'll be correct at 38 degrees N, given en-WP bias towards NA and Europe -- 38N was chosen because: -- * It's the furthest north where scale=100000 maps to zoom=12 -- * One hemisphere (20000km) maps to zoom=1 localmppl9Equator=305.748 -- Convert from Geohack's scale to OSM style zoom levels as used by <maplink> localfunctiongeohackScaleToMapZoom(scale,latitude) scale=tonumber(scale) ifnotscaleorscale<=0thenreturnend latitude=latitudeor38 localmppl9=mppl9Equator*math.cos(math.rad(latitude)) returnmath.log(mppl9*ppm/scale)/log2+9 end -- compute the viewport size (on screen) in meters, assuming ppm pixels per meter on screen localfunctioncomputeViewport(args) localviewport_cm=tonumber(args.viewport_cm) localviewport_px=tonumber(args.viewport_px) returnviewport_cmandviewport_cm/100orviewport_pxandviewport_px/ppm ortonumber(args.default_viewport)or0.1 end -- convert from geohack dim (knowing the viewpoint size on screen) to geohack scale localfunctiongeohackDimToScale(dim,args) dim=tonumber(dim) args=argsor{} ifnotdimordim<=0thenreturnend localunits=args.units ifunitsandstring.lower(units)=='km'then dim=dim*1000 end returndim/computeViewport(args) end -- inverse of above function, returning dim in km localfunctiongeohackScaleToDim(scale,args) scale=tonumber(scale) args=argsor{} ifnotscaleorscale<=0thenreturnend returnscale*computeViewport(args)*1e-3 end localoddShape=2.09--- length/sqrt(area) of Boston (to choose an example) -- Convert from Geohack's types to Geohack dim localfunctiongeohackTypeToDim(args) localt=args.type ifnottthenreturnend localtypeDim=mw.loadData('Module:Infobox_dim/sandbox/data') localdim=typeDim[t] localpopulation=tonumber(args.population) ift=='city'andpopulationandpopulation>0then -- assume city is a circle with density of 1000/square kilometer -- compute diameter, in meters. Then multiply by oddShape to account for weird shapes dim=35.68e-3*math.sqrt(population)*oddShape -- don't zoom in too far ifdim<5then dim=5 end end returndim end -- Convert from dimension of object to Geohack dim localfunctioncomputeDim(length,width,area) iflengthandwidththen returnmath.max(length,width) end iflengththenreturnlengthend ifwidththenreturnwidthend ifareathenreturnoddShape*math.sqrt(area)end end -- compute geohack dim from unit arguments (e.g., length_mi) localfunctionconvertDim(args) locallength=args.length_miand1.60934*args.length_miorargs.length_km localwidth=args.width_miand1.60934*args.width_miorargs.width_km localarea=args.area_acreand0.00404686*args.area_acreor args.area_haand0.01*args.area_haor args.area_mi2and2.58999*args.area_mi2orargs.area_km2 localdim=computeDim(length,width,area) returndim end localfunctioncomputeScale(args) ifargs.scalethenreturnargs.scaleend localdim,units,scale ifargs.dimthen dim,units=mw.ustring.match(args.dim,"^([-%d%.]+)%s*(%D*)") args.units=units args.default_viewport=0.1-- default geohack viewpoirt scale=geohackDimToScale(dim,args) end ifnotscalethen dim=convertDim(args)orgeohackTypeToDim(args) args.units='km' args.default_viewport=0.2--- when object dimensions or type is specified, assume 20cm viewport scale=dimandgeohackDimToScale(dim,args) end ifnotscalethenreturnend scale=math.floor(scale+0.5) -- keep scale within sane bounds (OSM zoom levels 1-17) ifscale<1600then scale=1600 end ifscale>200e6then scale=200e6 end returnscale end -- Argument checking localpositiveNumericArgs={viewport_cm=true,viewport_px=true,length_mi=true,length_km=true, width_mi=true,width_km=true,area_mi2=true,area_km2=true, area_acre=true,area_ha=true,scale=true,population=true} localfunctioncleanArgs(args) localclean={} iftype(args)=='table'then fork,vinpairs(args)do ifpositiveNumericArgs[k]then v=vandmw.ustring.gsub(v,",","")-- clean out any commas v=tonumber(v)-- ensure argument is numeric ifvandv<=0then-- if non-positive, ignore value v=nil end end clean[k]=v end end returnclean end -- Module entry points functionp._dim(args) args=cleanArgs(args) ifargs.dimthenreturnargs.dimend -- compute scale for geohack localscale=args.scale localdim ifnotscalethen args.default_viewport=0.2-- when specifying a object dimension or type, assume output spans 20cm dim=convertDim(args)orgeohackTypeToDim(args) args.units='km' scale=dimandgeohackDimToScale(dim,args) end -- reset back to 10cm viewport for correct geohack dim output args.viewport_cm=10 dim=scaleandgeohackScaleToDim(scale,args) returndimandtostring(math.floor(dim+0.5))..'km' end functionp._scale(args) args=cleanArgs(args) returncomputeScale(args) end functionp._zoom(args) args=cleanArgs(args) args.viewport_px=args.viewport_pxor200--- viewport for Kartographer is 200px high localscale=computeScale(args) ifscalethen locallatitude=tonumber(args.latitude) latitude=latitudeand(latitude>70and70orlatitude<-70and-70orlatitude) localzoom=geohackScaleToMapZoom(scale,latitude) returnzoomandmath.floor(zoom) end end -- Template entry points functionp.dim(frame) returnp._dim(getArgs(frame))or'' end functionp.scale(frame) returnp._scale(getArgs(frame))or'' end functionp.zoom(frame) returnp._zoom(getArgs(frame))or'' end returnp