You can configure a 2D WebGLMap
with a cylindrical projection, like a Mercator projection or an equidistant cylindrical projection, to wrap around the date
line. This article tells you how.
What’s date line wrapping?
With date line wrapping, the 2D map wraps around back to the other side of the world at the date line. It makes it easier to work with data around the date line, because users can just pan across the date line. Without it, the user has to pan back and forth to the other side of the map.
How do I enable date line wrapping?
You enable date line wrapping by specifying wrapAroundWorld: true
as an option when you’re constructing a WebGLMap
.
const map = new WebGLMap("map", {
reference: getReference("EPSG:3857"), // Web Mercator projection
wrapAroundWorld: true
});
Date line wrapping is supported on a |
Limiting the number of worlds visible at once
By default, you can only see one world at a time.
You can configure this limit with the MapNavigator.constraints
API.
map.mapNavigator.constraints.wrapAroundWorld = {
maxNumberOfWorlds: 3
};
If you allow only one world at a time, users can pan across the date line, but they can see any point of the world on their screen only once. The map part that falls off at one end becomes visible on the other side. Users can’t zoom out beyond a single world width on the screen.
If you allow more than one world, users can zoom out as far as they want. This configuration duplicates all information on all visible worlds, and might affect map performance.
What to consider when working with these maps?
Most things work out-of-the-box on this type of map. However, inspect your codebase for these API uses:
-
Pay attention when you are creating a transformation from map reference to model reference,
CRS:84
for example, when using a map that is wrapped around the dateline. The map’s X coordinate might need special attention to normalize it to projection bounds. This problem is handled for you if you create your transformation usingcreateTransformation
method and by passingCreateTransformationOptions.normalizeWrapAround: map.wrapAroundWorld
as option to it.Program: Transforming view points to the map reference without taking date line wrapping into accountconst map2LLH = createTransformation(map.reference, getReference("CRS:84")); const centerViewPoint = createPoint(null, [map.viewSize[0] / 2, map.viewSize[1] / 2]); const viewToMap = map.getViewToMapTransformation(); const centerMapPoint = viewToMap.transform(centerViewPoint); const centerLLHPoint = map2LLH.transform(centerMapPoint);
Program: Transforming view points to the map reference, taking date line wrapping into accountconst map2LLH = createTransformation(map.reference, getReference("CRS:84"), {normalizeWrapAround: map.wrapAroundWorld}); let centerViewPoint = createPoint(null, [map.viewSize[0] / 2, map.viewSize[1] / 2]); const viewToMap = map.getViewToMapTransformation(LocationMode.TERRAIN); const centerMapPoint = viewToMap.transform(centerViewPoint); // the wrapAround normalization might've caused the point to be normalized to a different location on-screen // go back to view again, to make sure centerMapPoint matches centerViewPoint centerViewPoint = map.mapToViewTransformation.transform(centerMapPoint); const centerLLHPoint = map2LLH.transform(centerMapPoint);
-
Use of
Map.mapToViewTransformation
.Map.mapToViewTransformation
takes multiple wrap-around worlds into account. The transformation returns a point in view if it exists. If more than one full world is visible, the returned view point is only for one of the worlds, typically the most central one.Figure 3. A map showing in green the pixel returned by a call toMap.mapToViewTransformation
for map coordinates corresponding to Belgium. The map shows in red the pixels corresponding to Belgium on other worlds not returned byMap.mapToViewTransformation
. -
Use of
Map.mapBounds
.Map.mapBounds
returned a bounds instance representing the visible part of the map. If the map can visualize more than one world at once, a single bounds might not be enough. Because of this,Map.mapBounds
has been depecrated. Replace usages ofMap.mapBounds
with its newer counterpart:Map.getMapBounds()
. This method returns an array of bounds instead of a single bounds instance. Additionally, it takes options to transform bounds to a target (model) reference.Figure 4. The bounds in red and blue are the two distinct bounds returned by a call toMap.getMapBounds()
. IfMap.mapBounds
had been used instead, only one of the bounds would have been returned.