diff options
author | stevenday <steve@mysociety.org> | 2012-11-20 15:14:22 +0000 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2012-11-26 12:47:10 +0000 |
commit | 2d75d6957ee3a85bd3f11405f8530f4d4bb336bd (patch) | |
tree | 266600319828da45ad36034dff4bcdad9e6a5c9c /web/js/OpenLayers.Projection.CH1903.js | |
parent | 86b8dab75f74fed9297fc689b3f2964425be61fd (diff) |
Add a proper OpenLayers plugin for Swiss<->WGS84 transformations
Diffstat (limited to 'web/js/OpenLayers.Projection.CH1903.js')
-rw-r--r-- | web/js/OpenLayers.Projection.CH1903.js | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/web/js/OpenLayers.Projection.CH1903.js b/web/js/OpenLayers.Projection.CH1903.js new file mode 100644 index 000000000..f050441e6 --- /dev/null +++ b/web/js/OpenLayers.Projection.CH1903.js @@ -0,0 +1,173 @@ +/** + * OpenLayers Swiss (CH1903) grid projection transformations + * + * Provides transform functions for WGS84<->CH1903 projections. + * + * Maths courtesy of the Swiss Federal Office of Topography: + * http://www.swisstopo.admin.ch/internet/swisstopo/en/home/products/software/products/skripts.html + */ + + +OpenLayers.Projection.CH1903 = { + + // Convert SEX DMS angle to DEC + SEXtoDEC: function(angle) { + + // Extract DMS + var deg = parseInt(angle, 10); + var min = parseInt((angle - deg) * 100, 10); + var sec = (((angle - deg) * 100) - min) * 100; + + // Result in degrees sex (dd.mmss) + return deg + ((sec / 60 + min) / 60); + + }, + + // Convert DEC angle to SEX DMS + DECtoSEX: function(angle) { + + // Extract DMS + var deg = parseInt(angle, 10); + var min = parseInt((angle - deg) * 60, 10); + var sec = (((angle - deg) * 60) - min) * 60; + + // Result in degrees sex (dd.mmss) + return deg + (min / 100) + (sec / 10000); + + }, + + // Convert Degrees angle to seconds + DEGtoSEC: function(angle) { + + // Extract DMS + var deg = parseInt( angle ); + var min = parseInt( (angle - deg) * 100 ); + var sec = (((angle - deg) * 100) - min) * 100; + + // Result in degrees sex (dd.mmss) + return sec + (min * 60) + (deg * 3600); + + }, + + // Convert WGS lat/long (° dec) to CH y + WGStoCHy: function(lat, lng) { + + // Converts degrees dec to sex + lat = OpenLayers.Projection.CH1903.DECtoSEX(lat); + lng = OpenLayers.Projection.CH1903.DECtoSEX(lng); + + // Converts degrees to seconds (sex) + lat = OpenLayers.Projection.CH1903.DEGtoSEC(lat); + lng = OpenLayers.Projection.CH1903.DEGtoSEC(lng); + + // Axiliary values (% Bern) + var lat_aux = (lat - 169028.66) / 10000; + var lng_aux = (lng - 26782.5) / 10000; + + // Process Y + y = 600072.37; + y = y + (211455.93 * lng_aux); + y = y - (10938.51 * lng_aux * lat_aux); + y = y - (0.36 * lng_aux * Math.pow(lat_aux, 2)); + y = y - (44.54 * Math.pow(lng_aux, 3)); + + return y; + }, + + // Convert WGS lat/long (° dec) to CH x + WGStoCHx: function(lat, lng) { + + // Converts degrees dec to sex + lat = OpenLayers.Projection.CH1903.DECtoSEX(lat); + lng = OpenLayers.Projection.CH1903.DECtoSEX(lng); + + // Converts degrees to seconds (sex) + lat = OpenLayers.Projection.CH1903.DEGtoSEC(lat); + lng = OpenLayers.Projection.CH1903.DEGtoSEC(lng); + + // Axiliary values (% Bern) + var lat_aux = (lat - 169028.66)/10000; + var lng_aux = (lng - 26782.5)/10000; + + // Process X + x = 200147.07; + x = x + (308807.95 * lat_aux); + x = x + (3745.25 * Math.pow(lng_aux, 2)); + x = x + (76.63 * Math.pow(lat_aux, 2)); + x = x - (194.56 * Math.pow(lng_aux, 2) * lat_aux); + x = x + (119.79 * Math.pow(lat_aux, 3)); + + return x; + + }, + + // Convert CH y/x to WGS lat + chToWGSlat: function(y, x) { + + // Converts militar to civil and to unit = 1000km + // Axiliary values (% Bern) + var y_aux = (y - 600000) / 1000000; + var x_aux = (x - 200000) / 1000000; + + // Process lat + var lat = 16.9023892; + lat = lat + (3.238272 * x_aux); + lat = lat - (0.270978 * Math.pow(y_aux, 2)); + lat = lat - (0.002528 * Math.pow(x_aux, 2)); + lat = lat - (0.0447 * Math.pow(y_aux, 2) * x_aux); + lat = lat - (0.0140 * Math.pow(x_aux, 3)); + + // Unit 10000" to 1 " and converts seconds to degrees (dec) + lat = lat * 100 / 36; + + return lat; + + }, + + // Convert CH y/x to WGS long + chToWGSlng: function(y, x) { + + // Converts militar to civil and to unit = 1000km + // Axiliary values (% Bern) + var y_aux = (y - 600000) / 1000000; + var x_aux = (x - 200000) / 1000000; + + // Process long + var lng = 2.6779094; + lng = lng + (4.728982 * y_aux); + lng = lng + (0.791484 * y_aux * x_aux); + lng = lng + (0.1306 * y_aux * Math.pow(x_aux, 2)); + lng = lng - (0.0436 * Math.pow(y_aux, 3)); + + // Unit 10000" to 1 " and converts seconds to degrees (dec) + lng = lng * 100 / 36; + + return lng; + + }, + + // Function to convert a WGS84 coordinate to a Swiss coordinate. + projectForwardSwiss: function(point) { + var newPoint = {}; + newPoint.x = OpenLayers.Projection.CH1903.WGStoCHx(point.x, point.y); + newPoint.y = OpenLayers.Projection.CH1903.WGStoCHy(point.x, point.y); + return newPoint; + }, + + // Function to convert a Swiss coordinate to a WGS84 coordinate. + projectInverseSwiss: function(point) { + var newPoint = {}; + newPoint.x = OpenLayers.Projection.CH1903.chToWGSlng(point.y, point.x); + newPoint.y = OpenLayers.Projection.CH1903.chToWGSlat(point.y, point.x); + return newPoint; + } +}; + +/** + * Note: One transform declared + * Transforms from EPSG:4326 to EPSG:21781 + */ + OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:21781", + OpenLayers.Projection.CH1903.projectForwardSwiss); + OpenLayers.Projection.addTransform("EPSG:21781", "EPSG:4326", + OpenLayers.Projection.CH1903.projectInverseSwiss);
\ No newline at end of file |