5

The javascript at https://jsfiddle.net/nsands/kvhcuL72/ is the simplest demonstration I've come up with for this issue. It is based on OpenLayers example code, but I've defined the map projection using proj4js.

It works fine for my custom EPSG:28355 projection, but it does not work for my custom EPSG:4326 projection, which results in an empty map. The projection is correct according to https://epsg.io/4326.

Below are the two proj4.defs() lines from the jsfiddle.

This first one works fine and OpenLayers reprojects (warps) the OSM map (EPSG:3857) to EPSG:28355 no problems:

//  EPSG:28355
proj4.defs('BLAH', '+proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');

(It does take a little time for the map to appear, as warping rasters is not a super-fast process.)

This second one does not work and results in an empty white map:

//  EPSG:4326
proj4.defs('BLAH', '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs');

If I use the already built-in EPSG:4326, instead of my own custom defined one, it also works just fine and reprojects the map perfectly. In the jsfiddle, this can be tested by changing which of the projection: lines is uncommented in the map's view definition.

Why does my custom definition of EPSG:4326 not work in my OpenLayers code, even though the built in EPSG:4326 and my custom EPSG:28355 both work fine?

I assume I'm using the libraries incorrectly, or perhaps assuming functionality that does not exist. But from the documentation I've seen, I had expected it to work.

(I'm using a custom definition of EPSG:4326 because in my real OpenLayers app, the projection is determined at run-time and the EPSG code may not be available, even then - only the proj4 string. Therefore I cannot hard-code the projection in the javascript, and I need to be able to work without an EPSG code. It needs to work for whatever projection is passed in, including the proj4 string for EPSG:4326.)

UPDATE - Documentation:

I had been under the impression that OpenLayers could simply use proj4js defined projections. Although the OL documentation is not entirely clear on this, I had got this impression from several 3rd party examples, from the snippets of OpenLayers documentation below, AND because it appears to work fine in my JSFiddle linked in the first line of this post above.

From the OpenLayers Example's comments in the code at https://openlayers.org/en/latest/examples/wms-image-custom-proj.html :

If you use Proj4js only to transform coordinates, you don't even need to create an ol.proj.Projection instance. ol.proj.get() will take care of it internally.

From the OpenLayers API documentation at https://openlayers.org/en/latest/apidoc/ol.proj.html :

[OpenLayers] will check if the Proj4js library and the necessary definition are loaded; if so, it will register the appropriate ol.proj.Projection object and add transform functions between the new projection and all the existing ones.

From the OpenLayers API documentation at https://openlayers.org/en/latest/apidoc/ol.proj.Projection.html :

You can use [ol.proj.Projections] in applications, but this is not required, as API params and options use ol.ProjectionLike which means the simple string code will suffice. ... If you use proj4js, aliases can be added using proj4.defs()

1 Answer 1

3

Edit:

You have to add a new ol.proj.Projection in order to use your custom projection, you can't just use the proj4js-name or variable you gave your projection as an OpenLayers projection.

Make sure your new OL-projection has a correct extent and make sure you use a correct center in ol.View (depending on what your projection is).

projCode = 'BLAH';

// EPSG:4326
proj4.defs(projCode, '+proj=longlat +datum=WGS84 +no_defs');

var myProjection = new ol.proj.Projection({
    code: projCode,
    extent: [-170.0, -80.0, 170.0, 80.0]
  });

And later:

var map = new ol.Map({
    layers: layers,
    target: 'map',
    view: new ol.View({
      projection: myProjection,
      center: [0, 0]
      zoom: 2
    })
  });

See working example: https://jsfiddle.net/kvhcuL72/17/

6
  • I edited my answer. You need to use "new ol.proj.Projection", you can't directly use the proj4.defs.
    – Zeronull
    Commented Jun 22, 2017 at 9:16
  • I suspect you're right (or at least close to the answer), and I will do some further testing to confirm. However, why does my original fiddle work? (As linked in the first line of the question.) It only defines the EPSG:28355 projection using proj4.defs() and the projection is only set in OL by calling the proj4js alias, but it appears to work just fine. Also, take a look at the OpenLayers documentation I've added to the end of my question. Not entirely clear, but I think it implies that it should work. Commented Jun 22, 2017 at 22:10
  • Why does your fiddle fail if I change the extent to: extent: [-180.0, -90.0, 180.0, 90.0] (which is the true extent of EPSG:4326)? Since this is greater than the extent of EPSG:3857, shouldn't it still work (with some blank areas at top and bottom)? Is this problem actually all about extents? Commented Jun 22, 2017 at 22:51
  • I'm not sure about that. epsg.io/3857 states that the WGS84 bounds for EPSG:3857 are [-180.0, -85.06, 180.0, 85.06]. It seems OL needs an extent that is equal or smaller than that to work in this case, maybe because it internally still uses 3857. But that is just a guess.
    – Zeronull
    Commented Jun 23, 2017 at 11:24
  • This still doesn't quite add up. If you add this line at the very beginning of your jsfiddle (or in any OL script), console.log(ol.proj.get('EPSG:4326').getExtent());, then you get the output, [-180, -90, 180, 90]. So why does the standard OL EPSG:4326 work fine (as tested in your fiddle by using 'EPSG:4326' instead of myProjection as the view's projection). But the custom projection does not work if it is configured with that same extent. I think we are heading in the right direction, but I still don't understand enough to have a workable solution. Commented Jun 24, 2017 at 4:48

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.