0

I have spent hours trying to include the code returned (see below) by http://epsg.io/2193.js in to my application.

proj4.defs("EPSG:2193","+proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");

If I copy paste the code above, it works fine but I need to create the URL dynamically and want to include this code using something like:-

var url = 'http://epsg.io/2193.js';
require([url]);

I always get the error that proj4 is undefined (line 1 of the url) so it points to a scoping issue. This is in a dojo widget (in case that is relevant). I am referencing proj4 from //cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js

What am I missing here?

tr3v
  • 431
  • 1
  • 9
  • 19

1 Answers1

1

How are you loading proj4js?

If you're using AMD style then you'll need to wrap it up a bit like this:

require([
    "//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js"
], function(proj4) {
    var url = 'http://epsg.io/2193.js';
    window.proj4 = proj4; // add to global scope
    require([url], function() {
        // now you can use proj4 with NZTM loaded in this block.
    );
});

That seems a little magical to me, because you're hoping that proj4 will always be the correct name and you're adding proj4 to the global scope, which is a little unclean. I'd be inclined to use the .proj4 extension with the dojo/text AMD plugin:

require([
    "//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js"
    "dojo/text!http://epsg.io/2193.proj4"
], function(proj4, epsg2193) {
    proj4.defs(epsg2193);
    // now you can use proj4 with NZTM loaded.
});

That means you can load both resources simultaneously.

Unfortunately it looks like that lack of Access-Control-Allow-Origin headers on the response breaks that approach, but you could look at proxying it through your own domain if you need the performance.


BTW, you could cheat a bit on the first option by defining a fake proj object:

var Proj4Proxy = function() {
    this._defs = [];
}
Proj4Proxy.prototype.defs = function(crs) { this._defs.push(crs); };
var proj4 = new Proj4Proxy();

require([
    "dojo/_base/array",
    "//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js",
    "//epsg.io/2193.js"
], function(array, _proj4) {
    array.forEach(proj4._defs, function(crs) { _proj4.defs(crs); });
    proj4 = _proj4;
    // now you can use proj4 with NZTM loaded.
});

Best of both worlds, if you don't mind the verbosity.

Hamish
  • 22,860
  • 8
  • 53
  • 67
  • It always is proj4. I tried your first suggestion, but proj4 is undefined still. My loading looks something like `define(['//cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.3/proj4.js'], function(proj4) { return declare([], { _init function () { // require for proj4 defs goes here }... This is in a dojo widget, which may be why I am having the scoping problem. – tr3v Nov 25 '14 at 23:17
  • well, that's odd. can you add a minimal failing example to your question? hard to guess where the problem is. – Hamish Nov 25 '14 at 23:18
  • Ah, duh, yeah the script will be executing in the window (global) context so you'll have to set window.proj4. Updated the first option above. – Hamish Nov 26 '14 at 23:31
  • Missed that thanks - I had window.Proj4js instead of window.proj4 {blush}. – tr3v Nov 27 '14 at 00:15