Created
May 10, 2022 18:32
-
-
Save darrenwiens/5369c959a7e1976132cdcc2ad92fad05 to your computer and use it in GitHub Desktop.
Geographic font
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fontforge | |
import json | |
from shapely.geometry import MultiPolygon, shape | |
from shapely.affinity import translate | |
font_file = "path/to/font.sfd" # path to sfd font file, created in FontForge GUI | |
geo_file = "path/to/features.geojson" # path to geographic features file | |
font = fontforge.open(font_file) | |
glyph_w = 1000 # glyph width | |
glyph_h = 800 # glyph height | |
with open(geo_file, "r") as f: | |
features = json.load(f)["features"] | |
def scaled_xy(x, y, minx, miny, maxx, maxy): # scale coordinates to fit inside glyph | |
scaled_x = (x - minx)/(maxx - minx) | |
scaled_y = (y - miny)/(maxy - miny) | |
return (scaled_x * glyph_w, scaled_y * glyph_h) | |
for i, feature in enumerate(features): # create a glyph for each feature | |
mpoly = shape(feature["geometry"]) | |
new_geoms = [] | |
for part in mpoly: # handle features that straddle antimeridian | |
if part.centroid.x < 0: | |
new_geoms.append(translate(part, xoff=360.0, yoff=0.0, zoff=0.0)) | |
else: | |
new_geoms.append(part) | |
new_mpoly = MultiPolygon(new_geoms) | |
bnds = new_mpoly.bounds # feature bbox | |
font.createChar(i) # create a new glyph | |
pen = font[i].glyphPen() # create a new glyph pen | |
for j, part in enumerate(new_mpoly): # draw a glyph part for each feature part | |
coords = scaled_xy(*part.exterior.coords[0], *bnds) # get glyph coordinates for feature point | |
pen.moveTo(coords) # move the pen to the starting location | |
for coords in part.exterior.coords[1:]: | |
pen.lineTo(scaled_xy(*coords, *bnds)) # move the pen, drawing a line | |
pen.closePath() # finally, close the glyph part | |
pen = None # delete the pen | |
font.generate(font_file) # generate the font | |
font.save() # save the font |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment