2

jI'm porting a previous GIS web browser application from OL 2.7 to OL 4.1.1. The app allows searching and diplaying north atlantic hurricanes in table form and on a (Bing) map. The lat/lon data come from the NHC HURDAT project.

When I display (eg.) the Katrina 2005 storm on the map, the lon values are displayed correctly, but the lat values are getting transformed/translated 90 degrees too far south, off the south coast of South America.

I've included the relevant code and console log from the the app below.

The most obvious answer would be that my pre-transform lat values are wrong. But the console.log verifys the pre-transformed (4326) lon/lat values are correct. After transform to 3857, the lat values in 'meters' are way in the negative. If I back-transform from 3857 to 4326, the console.log shows the lat values are approx. 90 degrees south of the correct location.

I've written a smaller, stand-alone version of the app, in which I copied the Katrina HTML table values to an Array instead. That version works correctly. I can't see any differences in the way I'm doing the projection transform in the two versions. Can anyone see what I'm doing wrong?


// Partial table values of HURDAT storm data for Katrina 2005

Point# Date-Time Latitude Longitude
1 2005-08-23 18:00:00 23.1 75.1
2 2005-08-24 00:00:00 23.4 75.7
3 2005-08-24 06:00:00 23.8 76.2


// Code that generates incorrect storm location points

var table;
for (var tableNum = 1; ((table =   document.getElementById("table"+tableNum)) != undefined) && table !=   null; tableNum++) {
  var numRows = table.rows.length;
  for (var rowNum = 1; rowNum < numRows; rowNum++) {
    var date = table.rows[rowNum].cells[1].innerHTML.split('-');
    var lat = table.rows[rowNum].cells[2].innerHTML;
    var lon = table.rows[rowNum].cells[3].innerHTML;
    var wSpeed = table.rows[rowNum].cells[6].innerHTML;
    // THE LAT/LON VALUES ARE BOTH CORRECT FOR KATRINA 2005 BEFORE THE TRANSFORMATION TO '3857'
    console.log("drawStormTracks: lon, lat before transform = " + lon + ", " + lat);
    /***********************/
    // The HURDAT lon values need to be NEGATED for the map.
    var point = new ol.geom.Point([-lon, lat]).transform('EPSG:4326', 'EPSG:3857');
    var coord = point.getCoordinates();
    console.log("drawStormTracks: 'meters' after transform = " + coord[0] + ", " + coord[1]);
    // WHY ARE THE TRANSFORMED 'LAT' VALUES GETTING TRANSLATED SOUTH BY 90 DEGREES ??

    // back-transform the 'meters' to lon/lat just to compare the values
    var xy = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
    console.log("drawStormTracks: lon, lat after transform = " + xy[0] + ", " + xy[1] + "\n\n");
    /************************/

// console.log for incorrect storm location points

drawStormTracks: lon, lat before transform = 75.1, 23.1
drawStormTracks: 'meters' after transform = -8360093.758574844,  -10102137.880170269  
drawStormTracks: lon, lat after transform = -75.1, -66.81

drawStormTracks: lon, lat before transform = 75.7, 23.4
drawStormTracks: 'meters' after transform = -8426885.45305081, -10017843.522516303  
drawStormTracks: lon, lat after transform = -75.7, -66.51

drawStormTracks: lon, lat before transform = 76.2, 23.8
drawStormTracks: 'meters' after transform = -8482545.198447447, -9907016.84037973  
drawStormTracks: lon, lat after transform = -76.2, -66.11

// Image of storm track with lat values approx. 90 too far south [![enter image description here][1]][1]


// code that generates correct storm location points.
var trackArray = [
  [23.1, 75.1, 35], [23.4, 75.7, 35], [23.8, 76.2, 35], 
  [24.5, 76.5, 40], [25.4, 76.9, 45],
  [26.0, 77.7, 50], [26.1, 78.4, 60], [26.2, 79.0, 65], 
  [26.2, 79.6, 70], [25.9, 80.3, 80],
  [25.4, 81.3, 75], [25.1, 82.0, 85], [24.9, 82.6, 100], 
  [24.6, 83.3, 105], [24.4, 84.0, 110],
  [24.4, 84.7, 115], [24.5, 85.3, 115], [24.8, 85.9, 115], 
  [25.2, 86.7, 145], [25.7, 87.7, 165],
  [26.3, 88.6, 175], [27.2, 89.2, 160], [28.2, 89.6, 145], 
  [29.5, 89.6, 125], [31.1, 89.6, 90],
  [32.6, 89.1, 60], [34.1, 88.6, 45], [35.6, 88.0, 35], 
  [37.0, 87.0, 35], [38.6, 85.3, 35], [40.1, 82.9, 30]
];

for (var rowNum = 0; rowNum <= 30; rowNum++) {
  var lat =    trackArray[rowNum][0];
  var lon =    trackArray[rowNum][1];
  var wSpeed = trackArray[rowNum][2];
  console.log("lon, lat before transform = " + lon + ", " + lat);
  /********************/
  // the HURDAT lon values need to be NEGATED for the map
  var point = new ol.geom.Point([-lon, lat]).transform('EPSG:4326', 'EPSG:3857');
  var coord = point.getCoordinates();
  console.log("'meters' after transform = " + coord[0] + ", " + coord[1]);

  // back-transform the 'meters' to lon/lat just to compare the values
  var xy = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
  console.log("lon, lat after transform = " + xy[0] + ", " + xy[1] + "\n\n");
  /********************/

// console.log for correct storm location points

lon, lat before transform = 75.1, 23.1
'meters' after transform = -8360093.758574844, 2644116.4340022053
lon, lat after transform = -75.1, 23.09999999999998

lon, lat before transform = 75.7, 23.4
'meters' after transform = -8426885.45305081, 2680464.081978332
lon, lat after transform = -75.7, 23.400000000000006

lon, lat before transform = 76.2, 23.8
'meters' after transform = -8482545.198447447, 2729056.1076330794
lon, lat after transform = -76.2, 23.799999999999997

  • Could you create breakpoint on transform line for the first sample on dev tool of browser? because the second one looks fine so, before debug the code, it's hard to figure out what's going on. – Chase Choi Jun 14 '17 at 0:43
  • Is it exactly 90 degrees, or approximately 90 degrees? – Steve Bennett Jun 14 '17 at 1:18
  • Check Point's coordinates before doing the reprojection? – mkennedy Jun 14 '17 at 19:34
  • @mkennedy I've split the point creation and point transform into two steps and checked the lon/lat before calling transform. The values are still correct before calling transform. The transform call itself seems to be where things 'go south.' – wmb Jun 16 '17 at 17:25
  • @SteveBennett The lat values are approximately 90 degrees off. They diverge more from 90 the farther south they're translated. I think this may be a feature of the 3857 projection, and was not concerned about the 'stretching.' Am I wrong about this? – wmb Jun 16 '17 at 17:32
2

I just fixed this problem. I think it turned out to be a javascript gotcha. The following lines returns a strings, not numbers:

var lat = table.rows[rowNum].cells[2].innerHTML;
var lon = table.rows[rowNum].cells[3].innerHTML;

In this line, the lat is sent to Point as a string. The lon, however, is converted to a number by the unary '-' operator:

var point = new ol.geom.Point([-lon, lat]);

I guess this caused the OL transform to be OK for lon's and wrong for lat's. I wrapped the lon/lat values in parseFloat(), and the storm track now shows on the map where expected. Oddly, that same code (w/o parseFloat) worked fine long ago in OL 2.7.

Thank you all for your suggestions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.