Skip to content

Instantly share code, notes, and snippets.

@tomowarkar
Created July 8, 2022 13:52
Show Gist options
  • Save tomowarkar/e64c8aa68220180f0e05ea73c22f0ec7 to your computer and use it in GitHub Desktop.
Save tomowarkar/e64c8aa68220180f0e05ea73c22f0ec7 to your computer and use it in GitHub Desktop.
地域メッシュコードでマリオが描きたかった
import itertools
from functools import lru_cache
from PIL import Image, ImageDraw
from staticmap import CircleMarker
from staticmap import StaticMap as _StaticMap
from staticmap.staticmap import _lat_to_y, _lon_to_x
class Mesh:
def __init__(self, code):
self.code = str(code)
self.coord = self._coord()
@property
def width(self):
return 1 / self.scale
@property
def height(self):
return 2 / 3 / self.scale
@property
def center(self):
lat, lng = self.coord
return lat + self.height / 2, lng + self.width / 2
def _coord(self):
len_ = len(self.code)
lng = lat = 0
if len_ < 4:
raise ValueError
ratio = 1
if 3 < len_: # 1次メッシュ
lat += int(self.code[0:2]) * 2 / 3
lng += int(self.code[2:4]) + 100
if 5 < len_: # 2次メッシュ 10km
ratio *= 8
lat += int(self.code[4]) * 2 / 3 / ratio
lng += int(self.code[5]) / ratio
if 7 < len_: # 3次メッシュ 1km
ratio *= 10
lat += int(self.code[6]) * 2 / 3 / ratio
lng += int(self.code[7]) / ratio
for i in itertools.count():
if 8 + i < len_: # 4次メッシュ 500m ...
ratio *= 2
lat += (self.code[8 + i] in ("3", "4")) * 2 / 3 / ratio
lng += (self.code[8 + i] in ("2", "4")) / ratio
else:
break
self.scale = ratio
return lat, lng
class StaticMap(_StaticMap):
def __init__(self, width, height, *args, **kwargs):
super().__init__(width, height, *args, **kwargs)
self.meshs = []
def _draw_meshs(self, image):
image_meshs = Image.new(
"RGBA", (self.width * 2, self.height * 2), (255, 0, 0, 0)
)
draw = ImageDraw.Draw(image_meshs)
for mesh in filter(lambda m: isinstance(m, Mesh), self.meshs):
lat, lng = mesh.coord
a = self._x_to_px(_lon_to_x(lng, self.zoom)) * 2
b = self._y_to_px(_lat_to_y(lat, self.zoom)) * 2
c = self._x_to_px(_lon_to_x(lng + mesh.width, self.zoom)) * 2
d = self._y_to_px(_lat_to_y(lat + mesh.height, self.zoom)) * 2
draw.rectangle((a, d, c, b), fill=mesh.color)
image_meshs = image_meshs.resize(
(self.width, self.height), Image.Resampling.LANCZOS
)
image.paste(image_meshs, (0, 0), image_meshs)
def add_mesh(self, code, color):
mesh = Mesh(code)
mesh.color = color
lat, lng = mesh.coord
h, w = mesh.height, mesh.width
self.add_marker(CircleMarker((lng, lat), "#ffff", 1))
self.add_marker(CircleMarker((lng, lat + h), "#ffff", 1))
self.add_marker(CircleMarker((lng + w, lat), "#ffff", 1))
self.add_marker(CircleMarker((lng + w, lat + h), "#ffff", 1))
self.meshs.append(mesh)
def render(self, zoom=None, center=None):
image = super().render(zoom, center)
self._draw_meshs(image)
return image
StaticMap.get = lru_cache(StaticMap.get)
if __name__ == "__main__":
smap = StaticMap(800, 600)
smap.meshs = []
smap.markers = []
clear = "#0000"
red = "#f00e"
brown = "#8b4513ee"
wheat = "#f5deb3ee"
mesh3rd = "52350349"
smap.add_mesh(mesh3rd + "112", brown)
smap.add_mesh(mesh3rd + "1123", clear)
smap.add_mesh(mesh3rd + "1143", wheat)
smap.add_mesh(mesh3rd + "1144", wheat)
smap.add_mesh(mesh3rd + "12", red)
smap.add_mesh(mesh3rd + "121", brown)
smap.add_mesh(mesh3rd + "122", clear)
smap.add_mesh(mesh3rd + "1242", clear)
smap.add_mesh(mesh3rd + "132", wheat)
smap.add_mesh(mesh3rd + "134", brown)
smap.add_mesh(mesh3rd + "1343", clear)
smap.add_mesh(mesh3rd + "14", red)
smap.add_mesh(mesh3rd + "1411", wheat)
smap.add_mesh(mesh3rd + "1413", brown)
smap.add_mesh(mesh3rd + "1423", wheat)
smap.add_mesh(mesh3rd + "143", brown)
smap.add_mesh(mesh3rd + "1444", brown)
smap.add_mesh(mesh3rd + "21", red)
smap.add_mesh(mesh3rd + "211", clear)
smap.add_mesh(mesh3rd + "2131", clear)
smap.add_mesh(mesh3rd + "212", brown)
smap.add_mesh(mesh3rd + "221", brown)
smap.add_mesh(mesh3rd + "2214", clear)
smap.add_mesh(mesh3rd + "2233", wheat)
smap.add_mesh(mesh3rd + "2234", wheat)
smap.add_mesh(mesh3rd + "23", red)
smap.add_mesh(mesh3rd + "2314", wheat)
smap.add_mesh(mesh3rd + "2322", wheat)
smap.add_mesh(mesh3rd + "2324", brown)
smap.add_mesh(mesh3rd + "2333", brown)
smap.add_mesh(mesh3rd + "234", brown)
smap.add_mesh(mesh3rd + "241", wheat)
smap.add_mesh(mesh3rd + "243", brown)
smap.add_mesh(mesh3rd + "2434", clear)
smap.add_mesh(mesh3rd + "3142", brown)
smap.add_mesh(mesh3rd + "3144", brown)
smap.add_mesh(mesh3rd + "3322", brown)
smap.add_mesh(mesh3rd + "32", wheat)
smap.add_mesh(mesh3rd + "3211", brown)
smap.add_mesh(mesh3rd + "3212", brown)
smap.add_mesh(mesh3rd + "3213", clear)
smap.add_mesh(mesh3rd + "3221", red)
smap.add_mesh(mesh3rd + "3222", brown)
smap.add_mesh(mesh3rd + "3231", brown)
smap.add_mesh(mesh3rd + "3234", brown)
smap.add_mesh(mesh3rd + "3243", brown)
smap.add_mesh(mesh3rd + "34", red)
smap.add_mesh(mesh3rd + "341", brown)
smap.add_mesh(mesh3rd + "3411", wheat)
smap.add_mesh(mesh3rd + "342", wheat)
smap.add_mesh(mesh3rd + "3423", brown)
smap.add_mesh(mesh3rd + "3433", clear)
smap.add_mesh(mesh3rd + "41", wheat)
smap.add_mesh(mesh3rd + "4111", brown)
smap.add_mesh(mesh3rd + "4112", brown)
smap.add_mesh(mesh3rd + "4121", clear)
smap.add_mesh(mesh3rd + "4122", clear)
smap.add_mesh(mesh3rd + "4132", brown)
smap.add_mesh(mesh3rd + "414", brown)
smap.add_mesh(mesh3rd + "4144", wheat)
smap.add_mesh(mesh3rd + "423", wheat)
smap.add_mesh(mesh3rd + "4231", brown)
smap.add_mesh(mesh3rd + "4232", clear)
smap.add_mesh(mesh3rd + "43", red)
smap.add_mesh(mesh3rd + "431", wheat)
smap.add_mesh(mesh3rd + "4312", brown)
smap.add_mesh(mesh3rd + "4314", brown)
smap.add_mesh(mesh3rd + "432", wheat)
smap.add_mesh(mesh3rd + "4324", clear)
smap.add_mesh(mesh3rd + "4343", clear)
smap.add_mesh(mesh3rd + "4344", clear)
smap.add_mesh(mesh3rd + "4431", red)
smap.add_mesh(mesh3rd + "4432", red)
image = smap.render(zoom=15)
image.save("osaka_mario.png")
@tomowarkar
Copy link
Author

これで十分だった

from staticmap import StaticMap, Polygon

def _add_mesh(self, mesh, color):
    if not isinstance(mesh, Mesh):
        raise ValueError
    lat, lng = mesh.coord
    h, w = mesh.height, mesh.width
    polygon = Polygon(
        [(lng, lat), (lng, lat+h), (lng+w, lat+h), (lng+w, lat)], 
        color, outline_color=color, simplify=True
    )
    self.polygons.append(polygon)

StaticMap.add_mesh = _add_mesh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment