Browsed by
Month: May 2014

“¿A quién votar?” Get to know the candidates for the 2014 Uruguayan Elections

“¿A quién votar?” Get to know the candidates for the 2014 Uruguayan Elections

“¿A quién votar?” (“Who to vote for?”) is a web app that I’ve been developing with @teoiglesias for sharing news and information about the candidates for the next elections in Uruguay.

The UI is very simple. Basically, it’s divided in two sections: “Candidates” and “News”. In the first one you can find information related to the candidates such as the webpage and social media links, while in the second one users can share news regarding a specific candidate from any source such as newspapers, magazines, social networks or others. The news are then displayed by candidate or all of them together.

To make the task of reading the news even more easier, users can follow the twitter account @aquienvotaruy where all the news are tweeted (after a quick validation to avoid possible spam or any other problem).

The web app was developed using Ruby on Rails and Twitter Bootstrap for the UI.

If you want to learn more check the website following the next link:

http://aquienvotar.com.uy

Getting the map coordinates of an address in Ruby on Rails

Getting the map coordinates of an address in Ruby on Rails

If you’re developing a map-based application, something very interesting (and useful) is to get the map coordinates (latitude, longitude) from a given address.

To do this you can use the Geocoder gem. With this gem, apart from getting the map coordinates from an address, you can also calculate the distance between two points, get the address from a given coordinate, get venues close to an address and more. I encourage you to read the complete documentation following the next link:

https://github.com/alexreisner/geocoder

To start with, install the gem by executing the following command:

Read More Read More

Shapefiles in Ruby on Rails

Shapefiles in Ruby on Rails

Continuing with the last post, we’ll now see how to open a shapefile using Ruby on Rails.

I found basically two ways to accomplish this. The first one is by using the RGeo gem while the second one is by converting the shapefile into a GeoJSON file.

Alternative 1: RGeo gem

RGeo is a Ruby Library that provides a implementation of the OGC Simple Features Specification, used for representing geometric objects. To open shapefiles you need an extra module called RGeo::Shapefile.

So to start with, install the gems as follows:

gem install rgeo
gem install rgeo-shapefile

Next there’s an example of how to open a shapefile using this method:

require 'rgeo/shapefile'

def load_opendata_rgeo
    
  factory = RGeo::Geographic.projected_factory(:projection_proj4 => "+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs")
    
  RGeo::Shapefile::Reader.open("#{Rails.root}/script/ep_residuos_decaux.shp", :factory => factory.projection_factory) do |file|
      
    puts "Number of records: #{file.num_records} "
  
    file.each do |record|

      puts "Record #{record.index}"
      geo = record.geometry
      latlon_geometry = factory.unproject(geo)
        
      puts "Coordinates: (#{latlon_geometry.latitude},#{latlon_geometry.longitude})"
        
      puts "Attribute OBJECTID value: #{record.attributes['OBJECTID']}"

    end
  end
end

If you want to display your information in a map (Google maps, OpenStreetMap) you might need to change your coordinate system. This is what “factory.unproject” does. To do so you need to know the coordinate system in which your shapefile is. In my case the coordinate system is “+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs”. You can get this information from QGIS (Right click on the layer > Properties > General > Coordinate reference system).

 

Warning: Now, the reason why I explored a second alternative is because I ran into problems deploying the application to Heroku while using the rgeo gem. The thing is that you need two libraries in the server to make rgeo to work: Geos and Proj. The only way to do this in Heroku is by installing a buildpack. If you need more information check the following link: https://github.com/aaronrenner/heroku-buildpack-rgeo-prep .

 

Alternative 2: Converting the shapefile into a GeoJSON file

GeoJSON is a format for encoding geographic information. The difference with the shapefile format is that GeoJSON is an open standard and also as it’s a JSON you can easily parse it using the json gem.

So, the first thing you need to do is to convert your shapefile into a GeoJSON.

If you have GDAL installed you can use the ogr2ogr utility.

To convert the file run the following command:

ogr2ogr -f GeoJSON -t_srs EPSG:4269 [filename].geojson [filename].shp

The -t_srs parameter is used to reproject/transform the points to a different coordinate system. Two popular systems are crs:84 and EPSG:4269. The difference is that crs:84 has a (longitude, latitude) coordinate order while EPSG:4269 a (latitude, longitude).

The resultant file will be something like this:

{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
                                                                                
"features": [
{ "type": "Feature", "properties": { "GID": 22894498.0, "OBJECTID": 1.0, "IDLI": 128.0, "N__ORDINAL": 1.0, "CCZ": 18.0, "COD_IMM": "CP hm.18.01", "CODIGO__DE": 631.0, "TIPO_RESID": "PILAS", "CONTENIDO": "Pilas", "UCREA": null, "FCREA": null, "UACT": "IM1726246", "FACT": "2012-12-13 14:28:23", "IDAUDITORI": "B8C12E7F22806823D3C7AD55FB5520CF" }, "geometry": { "type": "Point", "coordinates": [ -56.352119473107706, -34.790626820565095 ] } },


(...)

Now that you have your GeoJSON file is very easy to parse it in Ruby.

First, be sure to have the JSON gem installed. If not, run the following command:

gem install json

Finally, you can access the GeoJson file as follows:

def load_opendata_geojson
  file = open("#{Rails.root}/script/ep_residuos_decaux.geojson")
  json = file.read
  parsed = JSON.parse(json)
    
  parsed["features"].each do |record|

    puts record["properties"]["OBJECTID"]
    puts record["geometry"]["coordinates"][1] #latitude
    puts record["geometry"]["coordinates"][0] #longitude

  end
end