Advertisement
Guest User

Untitled

a guest
Mar 30th, 2021
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.09 KB | None | 0 0
  1. #draw_map.py: draw a rectilinear world map and save it to output.png
  2.  
  3. #Consult https://tools.ietf.org/html/rfc7946 for a specification of several of the types used here
  4.  
  5. import shapefile #https://pypi.org/project/pyshp/
  6. from PIL import Image, ImageDraw
  7.  
  8. #downloaded/unzipped from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/, "Admin 0 - Countries" -> "Download Countries"
  9. SHAPEFILE_PATH = "res/ne_110m_admin_0_countries/ne_110m_admin_0_countries.shp"
  10.  
  11. def to_screen_coords(p):
  12. """convert from lat/long to pixel coordinates using a sensible projection."""
  13. #1:1 rectilinear projection sure is easy
  14. return (p[0] + 180, -p[1] + 90)
  15.  
  16. def render_poly(seq):
  17. """render an RFC7946 Polygon instance."""
  18. #polygons can have multiple independent boundaries (for example, if it's a donut shape), so for wireframe renderings you can think of it more like a collection of polygons
  19. for linear_ring in seq:
  20. for idx, p1 in enumerate(linear_ring[:-1]):
  21. p2 = linear_ring[idx+1]
  22. coords = (to_screen_coords(p1), to_screen_coords(p2))
  23. draw.line(coords, fill="black")
  24.  
  25. image = Image.new("RGB", (260, 180), "white")
  26. draw = ImageDraw.Draw(image)
  27.  
  28. with shapefile.Reader(SHAPEFILE_PATH) as sf:
  29. for shape_rec in sf:
  30. #convert to RFC7946 GeoJSON format
  31. shape = shape_rec.__geo_interface__
  32.  
  33. coords = shape["geometry"]["coordinates"]
  34. t = shape["geometry"]["type"]
  35.  
  36. #handle all geometry types described at https://tools.ietf.org/html/rfc7946#section-3.1.1
  37. if t == "Point":
  38. raise NotImplemented #todo
  39. elif t == "MultiPoint":
  40. raise NotImplemented #todo
  41. elif t == "Polygon":
  42. render_poly(coords)
  43. elif t == "MultiPolygon":
  44. for poly in coords:
  45. render_poly(poly)
  46. elif t == "MultiLineString":
  47. raise Exception("I don't know what a MultiLineString even is, to be honest")
  48. else:
  49. raise Exception(f"Unknown geometry type {t}")
  50.  
  51. image.save("output.png")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement