Loading...
Logo
Processing Forum
I used the following code to visualize the Zurich bus stop locations information in the stop.json file (geojson format) as shared via:
https://github.com/swissnexSF/Urban-Data-Challenge/tree/master/public-transportation/zurich/geo/geojson

However, I found the proportion of the geo positions as visualized is skewed as compared to that visualized by Raymon Sutedjo & Sandra Lee ( http://ray-mon.com/urbandatachallenge/zurich.html).

May I ask how to correctly visualize the latitude and longitude data so that the map is shown with proper overall proportion?

Thanks!

my viz:


Raymon Sutedjo & Sandra Lee's viz ( http://ray-mon.com/urbandatachallenge/zurich.html):



my code:

Copy code
  1. // coded by Ji Zhang (hope.zh@gmail.com)
  2. // Sep-2013

  3. JSONObject stopsJSON;
  4. JSONArray stops;

  5. Stop[] stations;

  6. float latitude_min = 90;
  7. float latitude_max = 0;
  8. float longitude_min = 180;
  9. float longitude_max = 0;

  10. float canvas_width;
  11. float canvas_height;


  12. ///////////////////////////////////////////////////////////////////////////
  13. void setup() {
  14.   size(1000, 1000);
  15.  
  16.   stopsJSON = loadJSONObject("stops.json");
  17.  
  18.   stops = stopsJSON.getJSONArray("features");
  19.   //println(stops.size());
  20.   stations = new Stop[stops.size()];
  21.  
  22.   for (int i = 0; i < stops.size(); i++) {
  23.     JSONObject stop_i = stops.getJSONObject(i);
  24.     JSONObject stop_i_properties = stop_i.getJSONObject("properties");
  25.     int stopId            = stop_i_properties.getInt("stopId");
  26.     int stopNumber        = stop_i_properties.getInt("stopNumber");
  27.     String stopName       = stop_i_properties.getString("stopName");
  28.     String stopName_short = stop_i_properties.getString("stopNameShort");
  29.    
  30.     JSONObject stop_i_geometry = stop_i.getJSONObject("geometry");
  31.     double stop_longitude = stop_i_geometry.getJSONArray("coordinates").getDouble(0);
  32.     double stop_latitude  = stop_i_geometry.getJSONArray("coordinates").getDouble(1);
  33.    
  34.     if ( (float)stop_longitude < longitude_min ) {
  35.       longitude_min = (float)stop_longitude ;
  36.     } else if ( (float)stop_longitude > longitude_max ) {
  37.       longitude_max = (float)stop_longitude ;
  38.     }
  39.    
  40.     if ( (float)stop_latitude < latitude_min ) {
  41.       latitude_min = (float)stop_latitude ;
  42.     } else if ( (float)stop_latitude > latitude_max ) {
  43.       latitude_max = (float)stop_latitude ;
  44.     }
  45.    
  46.     println("_________________________");
  47.     println("stop sequence: " + i);
  48.     println("stopId: " + stopId);   
  49.     println("stopNumber: " + stopNumber);
  50.     println("stopName: " + stopName);
  51.     println("stopName_short: " + stopName_short);
  52.     println("stop_longitude: " + stop_longitude);
  53.     println("stop_latitude: " + stop_latitude);
  54.    
  55.     stations[i] = new Stop();
  56.     stations[i].stopId = stopId;
  57.     stations[i].stopNumber = stopNumber;
  58.     stations[i].stopName = stopName;
  59.     stations[i].stopName_short = stopName_short;
  60.     stations[i].stop_longitude = stop_longitude;
  61.     stations[i].stop_latitude = stop_latitude;
  62.    
  63.   }
  64.  
  65.   println("longitude_min: " + longitude_min);
  66.   println("longitude_max: " + longitude_max);
  67.   println("latitude_min: "  + latitude_min);
  68.   println("latitude_max: "  + latitude_max);
  69.  
  70.   float canvas_proportion = ((float)latitude_max - (float)latitude_min) / ((float)longitude_max - (float)longitude_min);
  71.   println("canvas_proportion: " + canvas_proportion);
  72.  
  73.   if ( (height/width) >= canvas_proportion ) {
  74.     canvas_width = width;
  75.     canvas_height = canvas_proportion * width;
  76.   } else if ( (height/width) < canvas_proportion ) {
  77.     canvas_width = height / canvas_proportion;
  78.     canvas_height = height;
  79.   } 

  80. }


  81. ///////////////////////////////////////////////////////////////////////////
  82. void draw() {
  83.   background(0);
  84.  
  85.   fill(30);
  86.   noStroke();
  87.   rect( (width - (width-canvas_width)/2 - canvas_width),
  88.         (height - (height - canvas_height)/2 - canvas_height),
  89.         canvas_width, canvas_height);
  90.        
  91.   strokeWeight(2);
  92.   stroke(255);
  93.  
  94.   for (Stop stop : stations) {
  95.     stop.drawStop();
  96.   }
  97. }


  98. class Stop {
  99.   int stopId;
  100.   int stopNumber;
  101.   String stopName;
  102.   String stopName_short;
  103.   double stop_longitude;
  104.   double stop_latitude;
  105.  
  106.   void Stop () {}
  107.  
  108.   void drawStop () {
  109.     float ptX = map((float)stop_longitude, longitude_min,longitude_max,
  110.                     width - (width-canvas_width)/2 - canvas_width,
  111.                     width - (width-canvas_width)/2);
  112.     float ptY = map((float)stop_latitude,  latitude_max,latitude_min,
  113.                     height - (height - canvas_height)/2 - canvas_height,
  114.                     height - (height - canvas_height)/2);
  115.     point(ptX, ptY);
  116.   }
  117.  
  118. }


Replies(7)

advices are greatly appreciated!
personally i cannot tell the difference by just looking at these two pics..
however, since i cannot open the link (raymon etc) and i do not know which file format did they use and how the did i will make a guess...
if you use the shp files you can play around with the thousands different map projections that exist...i assume it can be done with the json data too but it gets a bit complicated
Hi, dimiro, I'm reading point coordinates from a geojson file. I haven't touch the "reading shape file and draw polygons" part ...
The range of values for longitude and latitude are

longitude range: 0.3300457
latitude range:  0.15697479

but then you map these to the width and height of the display (bothe the same at 1000) so the result is stretched in the vertical direction.
Yes, quarks, I'm aware of the issue, and that's why I have a "canvas_proportion" variable, which is used to compare with the processing screen proportion to determine the position of the dots (I only cropped the middle part of the output image to show over here)

I'm aware of the issue, and that's why I have a "canvas_proportion" variable, which is used to compare with the processing screen proportion to determine the position of the dots
Sorry missed that - I was having trouble following the maths logic. Anyway I have simplified your program. The plot area (shown in light grey) is now the largest square that fits in the display window and is centred in the window.

I have also simplified some of the maths getting rid of the screen correction factor. You should be able to work out what is happening.

HTH

Copy code
  1. // coded by Ji Zhang (hope.zh@gmail.com)
  2. // Sep-2013
  3. JSONObject stopsJSON;
  4. JSONArray stops;
  5. Stop[] stations;
  6. float latitude_mid;
  7. float latitude_min = 360;
  8. float latitude_max = -360;
  9. float longitude_mid;
  10. float longitude_min = 360;
  11. float longitude_max = -360;
  12. float delta_max;
  13. float plotSize, halfPlotSize;

  14. ///////////////////////////////////////////////////////////////////////////
  15. void setup() {
  16.   size(800, 500);
  17.   plotSize = min(width, height);
  18.   halfPlotSize = plotSize/2;
  19.   stopsJSON = loadJSONObject("stops.json");
  20.   stops = stopsJSON.getJSONArray("features");
  21.   //println(stops.size());
  22.   stations = new Stop[stops.size()];
  23.   for (int i = 0; i < stops.size(); i++) {
  24.     JSONObject stop_i = stops.getJSONObject(i);
  25.     JSONObject stop_i_properties = stop_i.getJSONObject("properties");
  26.     int stopId            = stop_i_properties.getInt("stopId");
  27.     int stopNumber        = stop_i_properties.getInt("stopNumber");
  28.     String stopName       = stop_i_properties.getString("stopName");
  29.     String stopName_short = stop_i_properties.getString("stopNameShort");
  30.     JSONObject stop_i_geometry = stop_i.getJSONObject("geometry");
  31.     double stop_longitude = stop_i_geometry.getJSONArray("coordinates").getDouble(0);
  32.     double stop_latitude  = stop_i_geometry.getJSONArray("coordinates").getDouble(1);

  33.     if ( (float)stop_longitude < longitude_min ) {
  34.       longitude_min = (float)stop_longitude ;
  35.     }
  36.     else if ( (float)stop_longitude > longitude_max ) {
  37.       longitude_max = (float)stop_longitude ;
  38.     }

  39.     if ( (float)stop_latitude < latitude_min ) {
  40.       latitude_min = (float)stop_latitude ;
  41.     }
  42.     else if ( (float)stop_latitude > latitude_max ) {
  43.       latitude_max = (float)stop_latitude ;
  44.     }

  45.     println("_________________________");
  46.     println("stop sequence: " + i);
  47.     println("stopId: " + stopId);   
  48.     println("stopNumber: " + stopNumber);
  49.     println("stopName: " + stopName);
  50.     println("stopName_short: " + stopName_short);
  51.     println("stop_longitude: " + stop_longitude);
  52.     println("stop_latitude: " + stop_latitude);

  53.     stations[i] = new Stop();
  54.     stations[i].stopId = stopId;
  55.     stations[i].stopNumber = stopNumber;
  56.     stations[i].stopName = stopName;
  57.     stations[i].stopName_short = stopName_short;
  58.     stations[i].stop_longitude = stop_longitude;
  59.     stations[i].stop_latitude = stop_latitude;
  60.   }

  61.   latitude_mid = (latitude_max + latitude_min)/2;
  62.   longitude_mid = (longitude_max + longitude_min)/2;
  63.   delta_max = max((latitude_max - latitude_min), (longitude_max-longitude_min));
  64.   println("longitude_min: " + longitude_min);
  65.   println("longitude_max: " + longitude_max);
  66.   println("latitude_min: "  + latitude_min);
  67.   println("latitude_max: "  + latitude_max);
  68.   println("longitude_max: " + longitude_max);
  69. }

  70. ///////////////////////////////////////////////////////////////////////////
  71. void draw() {
  72.   background(0);
  73.   fill(96);
  74.   noStroke();
  75.   rect((width-plotSize)/2, (height-plotSize)/2, plotSize, plotSize);
  76.  
  77.   strokeWeight(2);
  78.   stroke(255);
  79.   for (Stop stop : stations) {
  80.     stop.drawStop();
  81.   }
  82. }

  83. class Stop {
  84.   int stopId;
  85.   int stopNumber;
  86.   String stopName;
  87.   String stopName_short;
  88.   double stop_longitude;
  89.   double stop_latitude;

  90.   void Stop () {
  91.   }

  92.   void drawStop () {
  93.     float ptX = (float)(stop_longitude - longitude_mid) / delta_max;
  94.     ptX = map(ptX, -0.5, 0.5, -halfPlotSize, halfPlotSize);
  95.     float ptY = (float)(latitude_mid - stop_latitude) / delta_max;
  96.     ptY = map(ptY, -0.5, 0.5, -halfPlotSize, halfPlotSize);
  97.     point(ptX + width/2, ptY + height/2);
  98.   }
  99. }