docs: def build_geometry_by_shape(
      feed: "Feed",
      shape_ids: Optional[List[str]] = None,
      *,
      use_utm: bool = False,
  ) -> Dict:
      """
      Return a dictionary with structure shape_id -> Shapely LineString
      of shape.
  
      Parameters
      ----------
      feed : Feed
      shape_ids : list
          IDs of shapes in ``feed.shapes`` to restrict output to; return
          all shapes if ``None``.
      use_utm : boolean
          If ``True``, then use local UTM coordinates; otherwise, use
          WGS84 coordinates
  
      Returns
      -------
      dictionary
          Has the structure
          shape_id -> Shapely LineString of shape.
          If ``feed.shapes is None``, then return ``None``.
  
          Return the empty dictionary if ``feed.shapes is None``.
  
      """
      if feed.shapes is None:
          return {}
  
      # Note the output for conversion to UTM with the utm package:
      # >>> u = utm.from_latlon(47.9941214, 7.8509671)
      # >>> print u
      # (414278, 5316285, 32, 'T')
      d = {}
      shapes = feed.shapes.copy()
      if shape_ids is not None:
          shapes = shapes[shapes["shape_id"].isin(shape_ids)]
  
      if use_utm:
          for shape, group in shapes.groupby("shape_id"):
              lons = group["shape_pt_lon"].values
              lats = group["shape_pt_lat"].values
              xys = [
                  utm.from_latlon(lat, lon)[:2] for lat, lon in zip(lats, lons)
              ]
              d[shape] = sg.LineString(xys)
      else:
          for shape, group in shapes.groupby("shape_id"):
              lons = group["shape_pt_lon"].values
              lats = group["shape_pt_lat"].values
              lonlats = zip(lons, lats)
              d[shape] = sg.LineString(lonlats)
      return d