Thanks Jody. I prefer option (b) as the default. It ensures that the user will get something based on their data even if they forget to set bounds explicitly. I guess you could require them to set the bounds by making that field null initially, but that seems unfriendly.
It's not always the case that shared viewports will have been hand-made. The DefaultRenderingExecutor class in gt-swing deals with rendering layers into separate graphics by creating temp MapContents which all share the viewport of the original, and that viewport can easily be the default one.
Meanwhile, we seem to have circled back to taking the CRS from the first Layer with a non-null CRS (if present). I think it would be good for MapContent to do that (rather than a client like JMapPane for instance). To prevent automagic changes to a viewport's CRS when it is shared I've added MapViewport.setEditable( boolean ) as per the sub-task
GEOT-3815.
The viewport can be created by a call to MapContent.getViewport() before any layers have been added. In that case, it will have its default CRS and the MapContent would have to "know" to set a new one when the first layer is added. Also, the user might set a viewport explicitly before adding any layers. In this case we probably don't want to change the CRS.
What about a case where layers are added, then all removed, then added. Should CRS only be set the first time we go from no layers to one layer ?
Multiple MapContents can share a single viewport and we don't want them all vying to change the CRS as layers are added to them.
For now, it seems safest to not implement this feature but instead to require the viewport CRS to be set explicitly by the user.