Commit e01b7eb8 authored by Michael Adair's avatar Michael Adair
Browse files

re #2: dynamic loading through the <script> tag means a proxy script is no longer required.

remove dependency on OpenLayers; 
parent 237495b0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -17,8 +17,9 @@
    
  </style>
  
  <script src="lib/proj4js-combined.js"></script>
  <script src="lib/proj4js-compressed.js"></script>
 
  <script src="lib/defs/EPSG54009.js"></script>
  <script src="lib/defs/EPSG42304.js"></script>
  <script src="lib/defs/EPSG25833.js"></script>
  <script src="lib/defs/EPSG27563.js"></script>
+517 −88

File changed.

Preview size limit exceeded, changes collapsed.

+23 −7

File changed.

Preview size limit exceeded, changes collapsed.

lib/proj4js-openlayers.js

deleted100755 → 0
+0 −4608

File deleted.

Preview size limit exceeded, changes collapsed.

+285 −83
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
Author:       Mike Adair madairATdmsolutions.ca
              Richard Greenwood rich@greenwoodmap.com
License:      LGPL as per: http://www.gnu.org/copyleft/lesser.html
              Note: This program is an almost direct port of the C library Proj4.

$Id: Proj.js 2956 2007-07-09 12:17:52Z steven $
*/

@@ -19,8 +19,8 @@ $Id: Proj.js 2956 2007-07-09 12:17:52Z steven $
 * 
 * Proj4js must have access to coordinate system initialization strings (which
 * are the same as for PROJ.4 command line).  Thes can be included in your 
 * application using a <script> tag or Proj4js can be configured to load CS
 * initialization strings froma web service such as spatialreference.org.
 * application using a <script> tag or Proj4js can load CS initialization 
 * strings from a local directory or a web service such as spatialreference.org.
 *
 * Similarly, Proj4js must have access to projection transform code.  These can
 * be included individually using a <script> tag in your page, built into a 
@@ -28,16 +28,22 @@ $Id: Proj.js 2956 2007-07-09 12:17:52Z steven $
 * -combined and -compressed versions of Proj4js includes all projection class
 * code by default.
 *
 * Note that dynamic loading of defs and code happens ascynchrously, check the
 * Proj.readyToUse flag before using the Proj object.  If the defs and code
 * required by your application are loaded through script tags, dynamic loading
 * is not required and the Proj object will be readyToUse on return from the 
 * constructor.
 * 
 * All coordinates are handled as points which have a .x and a .y property
 * which will be modified in place.
 *
 * Override Proj4js.log and Proj4js.reportError for output of alerts and warnings.
 * Override Proj4js.reportError for output of alerts and warnings.
 *
 * See http://trac.osgeo.org/proj4js/wiki/UserGuide for full details.
*/

/**
 * Global namespace object for Proj4js library to use
 * Global namespace object for Proj4js library
 */
Proj4js = {

@@ -49,7 +55,8 @@ Proj4js = {

    /** 
    * Method: transform(source, dest, point)
    * Transform a point coordinate from one map projection to another.
    * Transform a point coordinate from one map projection to another.  This is
    * really the only public method you should need to use.
    *
    * Parameters:
    * source - {Proj4js.Proj} source map projection for the transformation
@@ -193,68 +200,17 @@ Proj4js = {

    /**
     * Function: reportError
     * An internal method to report errors back to user. Should be overridden
     * by applications to deliver error messages.
     * An internal method to report errors back to user. 
     * Override this in applications to report error messages or throw exceptions.
     */
    reportError: function(msg) {
      //console.log(msg);
    },

/**
     * Function: log
     * An internal method to log events. 
     */
    log: function(msg) {
    },

/**
 * Function: loadProjDefinition
 * Stub for loading the coordinate system initialization string.  
 *     This version assumes the definition is already included through a <script>
 *     tag in your application.
 *     This method is overriden in proj4js-dynamicLoad.js.
 *
 * Parameters:
 * proj - {Object} A Proj4js.Proj object with srsCode defined
 *
 * Returns:
 * {String} The CS initialization string
 */
    loadProjDefinition: function(proj) {

      //check in memory
      if (this.defs[proj.srsCode]) {
        return this.defs[proj.srsCode];
      } else {
        Proj4js.reportError("Unable to find projection definition for "+proj.srsCode);
        return null;
      }

    },

/**
 * Function: loadProjCode
 * Stub for loading the projection transform code.  This version assumes 
 *     projection code is already included either through a script tag or in
 *     a custom build.  This method is overriden in proj4js-dynamicLoad.js.
 *
 * Parameters:
 * projName - {String} The projection clas name e.g. 'lcc'
 *
 * Returns:
 * {Object} The projection class transform object.
 */
    loadProjCode: function(projName) {
      if (this.Proj[projName]) {
        return;
      } else {
        Proj4js.reportError("Unable to find projection classes for "+projName);
        return;
      }
    },
    
/**
 * This is a minimal implementation of the OpenLayers Class object so that 
 * This is a minimal implementation of JavaScript inheritance methods so that 
 * Proj4js can be used as a stand-alone library.
 * These are copies of the equivalent OpenLayers methods at v2.7
 *
 * Function: extend
 * Copy all properties of a source object to a destination object.  Modifies
@@ -282,7 +238,7 @@ Proj4js = {
    },

/**
 * Constructor: OpenLayers.Class
 * Constructor: Class
 * Base class used to construct all other classes. Includes support for 
 *     multiple inheritance. 
 *  
@@ -307,20 +263,135 @@ Proj4js = {
      Class.prototype = extended;
      
      return Class;
    },

    /**
     * Function: bind
     * Bind a function to an object.  Method to easily create closures with
     *     'this' altered.
     * 
     * Parameters:
     * func - {Function} Input function.
     * object - {Object} The object to bind to the input function (as this).
     * 
     * Returns:
     * {Function} A closure with 'this' set to the passed in object.
     */
    bind: function(func, object) {
        // create a reference to all arguments past the second one
        var args = Array.prototype.slice.apply(arguments, [2]);
        return function() {
            // Push on any additional arguments from the actual function call.
            // These will come after those sent to the bind call.
            var newArgs = args.concat(
                Array.prototype.slice.apply(arguments, [0])
            );
            return func.apply(object, newArgs);
        };
    },
    
    /**
     * Property: scriptName
     * {String} The filename of this script without any path.
     */
    scriptName: "proj4js.js",

    /**
     * Property: defsLookupService
     * AJAX service to retreive projection definition parameters from
     */
    defsLookupService: 'http://spatialreference.org/ref',

    /**
     * Property: libPath
     * internal: http server path to library code.
     */
    libPath: null,

    /**
     * Function: getScriptLocation
     * Return the path to this script.
     *
     * Returns:
     * Path to this script
     */
    getScriptLocation: function () {
        if (this.libPath) return this.libPath;
        var scriptName = this.scriptName;
        var scriptNameLen = scriptName.length;

        var scripts = document.getElementsByTagName('script');
        for (var i = 0; i < scripts.length; i++) {
            var src = scripts[i].getAttribute('src');
            if (src) {
                var index = src.lastIndexOf(scriptName);
                // is it found, at the end of the URL?
                if ((index > -1) && (index + scriptNameLen == src.length)) {
                    this.libPath = src.slice(0, -scriptNameLen);
                    break;
                }
            }
        }
        return this.libPath||"";
    },

    /**
     * Function: loadScript
     * Load a JS file from a URL into a <script> tag in the page.
     * 
     * Parameters:
     * url - {String} The URL containing the script to load
     * onload - {Function} A method to be executed when the script loads successfully
     * onfail - {Function} A method to be executed when there is an error loading the script
     * loadCheck - {Function} A boolean method that checks to see if the script 
     *            has loaded.  Typically this just checks for the existance of
     *            an object in the file just loaded.
     */
    loadScript: function(url, onload, onfail, loadCheck) {
      var script = document.createElement('script');
      script.defer = false;
      script.type = "text/javascript";
      script.id = url;
      script.src = url;
      script.onload = onload;
      script.onerror = onfail;
      script.loadCheck = loadCheck;
      if (/MSIE/.test(navigator.userAgent)) {
        script.onreadystatechange = this.checkReadyState;
      }
      document.getElementsByTagName('head')[0].appendChild(script);
    },
    
    /**
     * Function: checkReadyState
     * IE workaround since there is no onerror handler.  Calls the user defined 
     * loadCheck method to determine if the script is loaded.
     * 
     */
    checkReadyState: function() {
      if (this.readyState == 'loaded') {
        if (!this.loadCheck()) {
          this.onerror();
        } else {
          this.onload();
        }
      }
    }
};

/**
 * Class: Proj4js.Proj
 
 * Projection objects provide transformation methods for point coordinates
 * Proj objects provide transformation methods for point coordinates
 * between geodetic latitude/longitude and a projected coordinate system. 
 * once they have been initialized with a projection code.
 *
 * Initialization of Proj objects is with a projection code, usually EPSG codes,
 * which is the key that will be used with the Proj4js.defs array.
 * The code passed in will be stripped of colons (':') and converted to uppercase
 * for internal use.
 * 
 * The code passed in will be stripped of colons and converted to uppercase
 * to locate projection definition files.
 *
 * A projection object has properties for units and title strings.
 */
Proj4js.Proj = Proj4js.Class({
@@ -383,27 +454,158 @@ Proj4js.Proj = Proj4js.Class({
          this.srsAuth = '';
          this.srsProjNumber = this.srsCode;
      }
      this.loadProjDefinition();
  },
  
/**
 * Function: loadProjDefinition
 *    Loads the coordinate system initialization string if required.
 *    Note that dynamic loading happens asynchronously so an application must 
 *    wait for the readyToUse property is set to true.
 *    To prevent dynamic loading, include the defs through a script tag in
 *    your application.
 *
 */
    loadProjDefinition: function() {
      //check in memory
      if (Proj4js.defs[this.srsCode]) {
        this.defsLoaded();
        return;
      }

      //else check for def on the server
      var url = Proj4js.getScriptLocation() + 'defs/' + this.srsAuth.toUpperCase() + this.srsProjNumber + '.js';
      Proj4js.loadScript(url, 
                Proj4js.bind(this.defsLoaded, this),
                Proj4js.bind(this.loadFromService, this),
                Proj4js.bind(this.checkDefsLoaded, this) );
    },

/**
 * Function: loadFromService
 *    Creates the REST URL for loading the definition from a web service and 
 *    loads it.
 *
 */
    loadFromService: function() {
      //else load from web service
      var url = Proj4js.defsLookupService +'/' + this.srsAuth +'/'+ this.srsProjNumber + '/proj4js';
      Proj4js.loadScript(url, 
            Proj4js.bind(this.defsLoaded, this),
            Proj4js.bind(this.defsFailed, this),
            Proj4js.bind(this.checkDefsLoaded, this) );
    },

/**
 * Function: defsLoaded
 * Continues the Proj object initilization once the def file is loaded
 *
 */
    defsLoaded: function() {
      this.parseDefs();
      this.loadProjCode(this.projName);
    },
    
/**
 * Function: checkDefsLoaded
 *    This is the loadCheck method to see if the def object exists
 *
 */
    checkDefsLoaded: function() {
      if (Proj4js.defs[this.srsCode]) {
        return true;
      } else {
        return false;
      }
    },

 /**
 * Function: defsFailed
 *    Report an error in loading the defs file, but continue on using WGS84
 *
 */
   defsFailed: function() {
      Proj4js.reportError('failed to load projection definition for: '+this.srsCode);
      Proj4js.extend(Proj4js.defs[this.srsCode], Proj4js.defs['WGS84']);  //set it to something so it can at least continue
      this.defsLoaded();
    },

/**
 * Function: loadProjCode
 *    Loads projection class code dynamically if required.
 *     Projection code may be included either through a script tag or in
 *     a built version of proj4js
 *
 */
    loadProjCode: function(projName) {
      if (Proj4js.Proj[projName]) {
        this.initTransforms();
        return;
      }

      var defs = Proj4js.loadProjDefinition(this);
      if (defs) {
          this.parseDefs(defs);
          Proj4js.loadProjCode(this.projName);
      //the URL for the projection code
      var url = Proj4js.getScriptLocation() + 'projCode/' + projName + '.js';
      Proj4js.loadScript(url, 
              Proj4js.bind(this.loadProjCodeSuccess, this, projName),
              Proj4js.bind(this.loadProjCodeFailure, this, projName), 
              Proj4js.bind(this.checkCodeLoaded, this, projName) );
    },

 /**
 * Function: loadProjCodeSuccess
 *    Loads any proj dependencies or continue on to final initialization.
 *
 */
    loadProjCodeSuccess: function(projName) {
      if (Proj4js.Proj[projName].dependsOn){
        this.loadProjCode(Proj4js.Proj[projName].dependsOn);
      } else {
        this.initTransforms();
      }
    },

 /**
 * Function: defsFailed
 *    Report an error in loading the proj file.  Initialization of the Proj
 *    object has failed and the readyToUse flag will never be set.
 *
 */
    loadProjCodeFailure: function(projName) {
      Proj4js.reportError("failed to find projection file for: " + projName);
      //TBD initialize with identity transforms so proj will still work?
    },
    
/**
 * Function: checkCodeLoaded
 *    This is the loadCheck method to see if the projection code is loaded
 *
 */
    checkCodeLoaded: function(projName) {
      if (Proj4js.Proj[projName]) {
        return true;
      } else {
        return false;
      }
    },

/**
 * Function: initTransforms
 *    Finalize the initialization of the Proj object
 *
 */
    initTransforms: function() {
      Proj4js.extend(this, Proj4js.Proj[this.projName]);
      this.init();
      this.readyToUse = true;
      }

  },

/**
 * Function: parseDefs
 * Parses the PROJ.4 initialization string and sets the associated properties.
 *
 * Parameters:
 * proj4opts - {String} PROJ.4 initialization string
 */
  parseDefs : function(proj4opts) {
      this.defData = proj4opts;
  parseDefs: function() {
      this.defData = Proj4js.defs[this.srsCode];
      var paramName, paramVal;
      var paramArray=this.defData.split("+");

@@ -449,7 +651,7 @@ Proj4js.Proj = Proj4js.Class({
                             this.from_greenwich *= Proj4js.common.D2R; 
                             break;
              case "no_defs": break; 
              default: Proj4js.log("Unrecognized parameter: " + paramName);
              default: //alert("Unrecognized parameter: " + paramName);
          } // switch()
      } // for paramArray
      this.deriveConstants();
Loading