Reduce the number of roundtrips for DistArray.get_localshapes to zero.

This also adds functions to metadata utils that could be useful for local map construction. But that can wait for another PR.
@cowlicks I'd prefer if there was a `.get_localshapes()` method on client-side `Distribution` objects, and `DistArray.get_localshapes()` just returns `self.distribution.get_localshapes()`.  The `Distribution.get_localshapes()` would just do:

```python
return get_shape_from_dim_data_per_rank(self.get_dim_data_per_rank())
```

Having a `Distribution.get_localshapes()` method will be useful in other places as well.