モジュール:地図/点

モジュールの解説[作成]
local function create(projection,itemlist)
	local size=projection.getSize()
	local reader=require("Module:地図/行政区域")(projection)
	local sc
	do
		local dp=projection.getDp()
		for _,ds in ipairs({1000000,500000,200000,100000,50000,20000,10000,5000,2000,1000,500,200,100}) do
			local m=math.floor(ds/dp)
			if m<size[1]/2 then
				sc={ds,m}
				break
			end
		end
	end
	local marks={}
	table.insert(marks,{
		type="path",
		interactive=false,
		properties={
			enter={
				path={
					value=reader.getCoast()
				},
				fill={
					value="white"
				}
			}
		}
	})
	for i=1,3 do
		local path=reader.getInnerPath(i)
		if #path>0 then
			table.insert(marks,{
				type="path",
				interactive=false,
				properties={
					enter={
						path={
							value=path
						},
						stroke={
							value="gray"
						},
						strokeWidth={
							value=i==1 and 1.5 or 0.25
						},
						strokeDash={
							value=i<=2 and {10,2,2,2} or {2,2}
						}
					}
				}
			})
		end
	end
	table.insert(marks,{
		type="rect",
		interactive=false,
		properties={
			enter={
				fill={
					value="white"
				},
				fillOpacity={
					value=0.75
				},
				x={
					value=size[1]-sc[2]-12
				},
				y={
					value=size[2]-28
				},
				width={
					value=sc[2]+8
				},
				height={
					value=24
				}
			}
		}
	})
	table.insert(marks,{
		type="rect",
		interactive=false,
		properties={
			enter={
				fill={
					value="black"
				},
				x={
					value=size[1]-sc[2]-8
				},
				y={
					value=size[2]-12
				},
				width={
					value=sc[2]
				},
				height={
					value=4
				}
			}
		}
	})
	table.insert(marks,{
		type="text",
		interactive=false,
		properties={
			enter={
				fill={
					value="black"
				},
				align={
					value="center"
				},
				baseline={
					value="middle"
				},
				font={
					value="TakaoExGothic"
				},
				fontSize={
					value=12
				},
				text={
					value=sc[1]<1000 and (sc[1].."m") or ((sc[1]/1000).."km")
				},
				x={
					value=size[1]-sc[2]/2-8
				},
				y={
					value=size[2]-18
				},
			}
		}
	})
	table.insert(marks,{
		type="symbol",
		interactive=false,
		from={
			data="point"
		},
		properties={
			enter={
				x={
					field="x"
				},
				y={
					field="y"
				},
				stroke={
					value="black"
				},
				strokeWidth={
					value=0.75
				}
			},
			update={
				size={
					{
						test="datum==active",
						value=64
					},
					{
						value=16
					}
				},
				fill={
					{
						test="datum==active",
						value="crimson"
					},
					{
						value="deeppink"
					}
				}
			}
		}
	})
	table.insert(marks,{
		type="rect",
		interactive=false,
		from={
			data="point",
			transform={
				{
					type="filter",
					test="datum==active"
				}
			}
		},
		properties={
			update={
				fill={
					value="white"
				},
				fillOpacity={
					value=0.75
				},
				xc={
					field="x"
				},
				y={
					field="y",
					offset=-38
				},
				width={
					field="length",
					mult=24
				},
				height={
					value=24
				}
			}
		}
	})
	table.insert(marks,{
		type="text",
		interactive=false,
		from={
			data="point",
			transform={
				{
					type="filter",
					test="datum==active"
				}
			}
		},
		properties={
			enter={
				fill={
					{
						test="datum.linkexist",
						value="#0645ad"
					},
					{
						value="#ba0000"
					}
				},
				align={
					value="center"
				},
				baseline={
					value="middle"
				},
				fontSize={
					value=20
				}
			},
			update={
				x={
					field="x"
				},
				y={
					field="y",
					offset=-24
				},
				text={
					field="text"
				}
			}
		}
	})
	table.insert(marks,{
		type="path",
		from={
			data="point"
		},
		properties={
			enter={
				fill={
					value="transparent"
				},
				path={
					field="layout_path"
				}
			}
		}
	})
	local pointlist={}
	for line in string.gmatch(mw.text.trim(itemlist),"[^\n]+") do
		local ss=mw.text.split(mw.text.trim(line),",")
		local q=mw.text.split(mw.text.trim(ss[2]),"/")
		local t=mw.text.split(mw.text.trim(ss[1]),"%$")
		local p=projection.convert({tonumber(q[1]),tonumber(q[2])})
		table.insert(pointlist,{text=t[1],link=t[#t],linkexist=mw.title.new(t[#t],0).exists,x=tonumber(string.format("%.1f",p[1])),y=tonumber(string.format("%.1f",p[2]))})
	end
	return {
		width=size[1],
		height=size[2],
		background="lavender",
		signals={
			{
				name="active",
				init=nil,
				streams={
					{
						type="path:mouseover,path:touchstart",
						expr="datum"
					},
					{
						type="path:mouseout,touchend",
						expr="null"
					}
				}
			},
			{
				name="link",
				init={},
				streams={
					{
						type="path:click",
						expr="open('https://ja.wikipedia.org/wiki/'+active.link)"
					}
				}
			}
		},
		data={
			{
				name="point",
				values=pointlist,
				transform={
					{
						type="formula",
						field="sy",
						expr="datum.y+8"
					},
					{
						type="voronoi",
						x="x",
						y="sy",
						clipExtent={{0,0},size}
					},
					{
						type="formula",
						field="length",
						expr="length(datum.text)"
					}
				}
			}
		},
		marks={
			{
				type="group",
				properties={
					enter={
						clip={
							value=true
						},
						x={
							value=0
						},
						y={
							value=0
						},
						width={
							value=size[1]
						},
						height={
							value=size[2]
						}
					}
				},
				marks=marks
			}
		}
	}
end
return {
	_=function(frame)
		local args=frame:getParent().args
		local width=tonumber(args[3])
		local createProjection=require("Module:地図/正射図法")
		local projection
		if args[2]=="北海道" then
			projection=createProjection({width,math.floor(width*0.64)},math.floor(790000/width),{144.0,43.5})
		elseif args[2]=="東北" then
			projection=createProjection({width,math.floor(width*2)},math.floor(280000/width),{140.6,39.2})
		elseif args[2]=="関東" then
			projection=createProjection({width,math.floor(width*1.23)},math.floor(240000/width),{139.6,35.9})
		elseif args[2]=="近畿" then
			projection=createProjection({width,math.floor(width*1.25)},math.floor(230000/width),{135.4,34.6})
		elseif args[2]=="中国" then
			projection=createProjection({width,math.floor(width*0.82)},math.floor(370000/width),{132.7,35.1})
		elseif args[2]=="四国" then
			projection=createProjection({width,math.floor(width*0.88)},math.floor(280000/width),{133.4,33.6})
		elseif args[2]=="九州" then
			projection=createProjection({width,math.floor(width*1.6)},math.floor(350000/width),{130.3,32.4})
		else
			return "ERROR"
		end
		return frame:extensionTag('graph',mw.text.jsonEncode(create(projection,args[4])),{mode='interactive'})..frame:extensionTag('ref','国土交通省 国土数値情報(行政区域・湖沼)を加工して作成')
	end
}