2

I'm trying to setup a Mollweide map, and only see a single projection of the world. Without the doubly projected areas in the corners of the map (see included images for clarification). Is there a technique that achieves this?

See the JSFiddle here: https://jsfiddle.net/7901arop/150/

Wanted result

Wanted result

Actually achieved results

Achieved results

I added the Graticule to better visualise what part of the map I want to show, and what part of the map has to be cropped / hidden / covered / ....

In the right picture i set the wrapX option of the OSM source to false, which comes close to a possible solution but introduces other weird artefacts.

Current implementation
//Setup layers
const streetMap = new ol.layer.Tile({
  source: new ol.source.OSM({
    wrapX: true,
    //wrapX: false   
    
    /* If set to false, it acomplishes 
       the wanted effect on the west side 
       of the globe, but not on the east side  */
  })
})
const Graticule = new ol.layer.Graticule({targetSize: 30})




//Setup Projection
proj4.defs('ESRI:54009', '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 units=m +no_defs');
ol.proj.proj4.register(proj4);
const sphereMollweideProjection = new ol.proj.Projection({
  code: 'ESRI:54009',
  extent: [-18019909.21177587, -9009954.605703328, 18019909.21177587, 9009954.605703328],
  worldExtent: [-179.99, -89.99, 179.99, 89],
});



//Set map on the screen
var map = new ol.Map({
  layers: [streetMap, Graticule],
  target: 'map',
  view: new ol.View({
    projection: sphereMollweideProjection,
    center: [0, 0],
    zoom: 0.5
  })
});
1
  • @TomazicM Thanks for the heads up. I edited the question to include my current implementation.
    – oogie
    Jun 1, 2022 at 14:06

1 Answer 1

3

You can use vector clipping similar to this example https://openlayers.org/en/latest/examples/layer-clipping-vector.html

Instead of a feature for Switzerland create a polygon for the visible world

var coordinates = [];
for (var i = 90; i >= -90; --i) {
  coordinates.push([-179.99, i * 0.9999]);
}
for (var i = -90; i <= 90; ++i) {
  coordinates.push([179.99, i * 0.9999]);
}
coordinates.push(coordinates[0]);

var clip = new ol.geom.Polygon([coordinates]).transform('EPSG:4326', sphereMollweideProjection);

var style = new ol.style.Style({
  fill: new ol.style.Fill({
    color: 'black'
  })
});

streetMap.on('postrender', function (e) {
  var vectorContext = ol.render.getVectorContext(e);
  e.context.globalCompositeOperation = 'destination-in';
  vectorContext.setStyle(style);
  vectorContext.drawGeometry(clip);
  e.context.globalCompositeOperation = 'source-over';
});

https://jsfiddle.net/f2013vy9/

1
  • Thank you very much! This is exactly what I was looking for, also thanks for the elaborate answer!
    – oogie
    Jun 1, 2022 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.