After further investigation, I've managed to solve the problem. What is causing the problem is that Proj4js will dynamically load any parts it needs rather than immediately loading all of it's scripts.
Internet Explorer has most trouble with this, but also Firefox and Chrome show the symptom. IE managed to not be able to use any transformations, even after a subsequent ajax call to get data had already finished. Both Firefox and Chrome did not have the transformations available on time for the center of the map being set correctly, but did have them very shortly after, resulting in my ajax-loaded data to be transformed correctly for displaying on the map.
From Visual Studio I could see that after each call to create a new projection, scripts would be dynamically loaded. Firstly, it would load the projection definition:
/Scripts/proj4js/defs/EPSG27700.js
From the definition it would then load the projection type being used (in this case transverse mercator):
/Scripts/proj4js/projCode/tmerc.js
The only problem was that apparantly, the browser was not able to process these files in time before needing to use them, resulting in no transformation actually taking place. The solution to this was to add any needed definitions to my script-includes manually:
<script type="text/javascript" src="/OpenLayers-2.10/OpenLayers.js"></script>
<script type="text/javascript" src="/Scripts/proj4js/proj4js.js"></script>
<script type="text/javascript" src="/Scripts/proj4js/projCode/merc.js"></script>
<script type="text/javascript" src="/Scripts/proj4js/projCode/tmerc.js"></script>
<script type="text/javascript" src="/Scripts/proj4js/defs/EPSG27700.js"></script>
<script type="text/javascript" src="/Scripts/proj4js/defs/EPSG900913.js"></script>
And now all the transformations I needed were avaiable as soon as the page had loaded, so it would perform all transformations correctly.
In order to know what extra files to include, see which (EPSG) definitions you need. Inlcude those definitions. Look inside those files and see which projections they use For example, EPSG 27700 is defined as follows:
Proj4js.defs["EPSG:27700"] = "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs";
So we can see that it uses tmerc
(transverse mercator), so we include that projection. Do this for any definition you need.
Note that WGS84 (EPSG:4326) is included by default. It doesn't even have a separate defining javascript file.
Best Answer
You have two choices
Solution 1:
You can change the reference to proj4js. OpenLayers 2.x default support is with Proj4js 1.1 whereas you use 2.x.
Demo 1 (open the browser console to see)
Solution 2:
Or you can use the new proj4js version by adding a wrapper to match previous version behaviour:
Demo 2 (open the browser console to see)
You may encounter some border effects although it seems minor according to the thread about OpenLayers 2.x support with Proj4js 2.x series
There was small difference between both results but now it's OK. It was due to parameters correction with proj4js for this particular projection (EPSG:31466).