Utilización de servicios Open data

Note

Fecha Autores
8 Noviembre 2017
  • Victor Pascual

©2017 Victor Pascual

Excepto donde quede reflejado de otra manera, la presente documentación se halla bajo licencia: Creative Commons (Creative Commons - Attribution - Share Alike: http://creativecommons.org/licenses/by-sa/3.0/deed.es)

Ejemplo API CKAN

El API de CKAN http://docs.ckan.org/en/latest/api/index.html no ofrece diferetes niveles y métodos para poder buscar y filtrar datasets.

En este ejemplo utilizaremos el método resource_search http://docs.ckan.org/en/latest/api/index.html#ckan.logic.action.get.resource_search para buscar datasets en cualquier portal de CKAN

Para buscar en portales CKAN necesitamos saber la URL del portal , exemplo http://demo.ckan.org y añadir el path del método a utilizar /api/3/action/resource_search?

http://demo.ckan.org/api/3/action/resource_search?

Descomprimiremos el archivo utilizacion-servicio-opendata.zip en nuestro espacio de trabajo.

Creación de un buscador

  1. Dentro del directorio utilizacion-servicio-opendata creamos un archivo con el nombre de ckan.html.

  2. Abrimos el archivo ckan.html con un editor de texto y copiamos el siguiente código.:

    <!DOCTYPE html>
            <html>
            <head>
                    <meta charset="UTF-8">
                    <title>
                                    Bàsic sample Resource Search API CKAN
                    </title>
                    <link rel="stylesheet" href="javascripts/vendor/bootstrap/3.2.0/css/bootstrap.css" />
                    <script type="text/javascript" src="javascripts/vendor/jquery/1.7.1/jquery.js"></script>
                    <script type="text/javascript" src="javascripts/vendor/bootstrap/3.2.0/js/bootstrap.js"></script>
                    <style>
                                    #results {
                                                    width: 100%;
                                                    background-color: #f2f2f2;
                                                    margin: 5px;
                                    }
                    </style>
            </head>
            <body>
    
            </body>
    </html>
    
  3. Abrimos el archivo ckan.html en el navegador.

  4. Añadimos dentro del tag <body> la maquetación HTML.:

    <div class="container">
            <h3>Resource Search example </h3>
            <p>     Package Search <br>
                            <a target="_blank" href="http://docs.ckan.org/en/latest/api/">http://docs.ckan.org/en/latest/api/</a>
            </p>
            <form>
                            <div class="form-group">
                                            <label for="url_ckan">Url:</label>
    
            <select id="url_ckan" >
                                    <option value="http://demo.ckan.org/api/3/action/resource_search?">ckan.org</option>
                                    <option value="http://old.datahub.io/api/3/action/resource_search?">old.datahub.io</option>
            </select>
                            </div>
                            <div class="form-group">
                                            <label for="text_filter_ckan"> Filter <u>(name, descripton, format )</u></label>
                                            <input type="text" class="form-control" id="text_filter_ckan" value="name:wifi" placeholder="text filter">
                            </div>
            </form>
            <form class="form-inline">
                            <div class="form-group">
                                            <label for="num_results_ckan">Num results</label>
                                            <input type="number" size="3" class="form-control" id="num_results_ckan" value="5">
                            </div>
    
            </form>
            <form>
                            <div class="form-group">
                                            <button id="bt_send" type="button" class="btn btn-default btn-success">Send</button>
                            </div>
            </form>
            <hr>
            <div id="results"></div>
            <div id="mygrid" style="height: 500px"></div>
    </div>
    
  5. Abrimos el archivo ckan.html en el navegador.

  6. Añadimos justo encima de tag </body> el código en JavaScript.:

    <script>
            $.ajaxSetup({
                    cache: true
            });
            $(document).ready(function() {
                    $('#bt_send').on('click', function() {
                            var data = {
                                    rows: $('#num_results_ckan').val(),
                                    query: $('#text_filter_ckan').val()
                            };
                            $.ajax({
                                    url: $('#url_ckan').val(),
                                    data: data,
                                    dataType: 'jsonp',
                                    success: function(data) {
                                            if (data.success) {
                                                    $('#results').html('Total results found: ' + data.result.count);
                                                    $('#mygrid').html('');
    
                                                    if (data.result.count >= 1) {
                                                            $('#mygrid').append('<ul>');
                                                            $.each(data.result.results, function(index, value) {
                                                                    $('#mygrid').append('<li>' + value.name + ': <a href="' + value.url + '">' + value.url + '</a>');
    
                                                                    $('#mygrid').append('</li>');
                                                            });
                                                            $('#mygrid').append('</ul>');
    
                                                    }
    
                                            } else {
                                                    $('#results').html("An error occured: " + data.error.message);
                                            }
                                    },
                                    error: function(xhr) {
                                            $('#results').html("An error occured: " + xhr.status + " " + xhr.statusText);
                                    }
    
                            });
    
                    })
    
            });
    </script>
    
  7. Abrimos pàgina ckan.html y lanzamos búsquedas

  8. Ejercicio 1: Añadir una o más URLs de otros portales de CKAN

  9. Ejercicio 2: ¿Cómo haríamos para qué en los resultados apareciera la fecha de creación del dato?

Ejemplos API SOCRATA

El API de Socrata https://dev.socrata.com no ofrece diferetes niveles y métodos para poder buscar y filtra datasets.

En este primer ejemplo utilizaremos la Discovery API https://socratadiscovery.docs.apiary.io/ para buscar datasets en cualquier portal de Socrata

Descomprimiremos (ya hecho en ejercicio CKAN) el archivo utilizacion-servicio-opendata.zip en nuestro espacio de trabajo.

Creación de un buscador

  1. Dentro del directorio utilizacion-servicio-opendata creamos un archivo con el nombre de socrata.html.

  2. Abrimos el archivo socrata.html con un editor de texto y copiamos el siguiente código.:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>
        Basic sample API Discovery SOCRATA
      </title>
      <link rel="stylesheet" href="javascripts/vendor/bootstrap/3.2.0/css/bootstrap.css" />
      <script type="text/javascript" src="javascripts/vendor/jquery/1.7.1/jquery.js"></script>
      <script type="text/javascript" src="javascripts/vendor/bootstrap/3.2.0/js/bootstrap.js"></script>
    
      <style>
        #results {
          width: 100%;
          background-color: #f2f2f2;
          margin: 5px;
        }
      </style>
    </head>
    <body>
    
    
    </body>
    </html>
    
  3. Abrimos el archivo socrata.html en el navegador.

  4. Añadimos dentro del tag <body> la maquetación HTML.:

        <div class="container">
    <h3>SOCRATA Resource Search example </h3>
    <p>Discovery API <br>
      <a target="_blank" href="http://docs.socratadiscovery.apiary.io">http://docs.socratadiscovery.apiary.io</a>
    </p>
    <form>
      <div class="form-group">
        <div class="radio">
          <label>
                                <input type="radio" name="optionsRadios" id="optionsRadios1" value="https://api.eu.socrata.com/api/catalog/v1" checked>
                                EU API Discovery
                  </label>
        </div>
        <div class="radio">
          <label>
                                <input type="radio" name="optionsRadios" id="optionsRadios2" value="https://api.us.socrata.com/api/catalog/v1">
                           US API Discovery
                  </label>
        </div>
      </div>
      <div class="form-group">
        <label for="text_filter_socrata"> Filter <u></u></label>
        <input type="text" class="form-control" id="text_filter_socrata" value="Contracts" placeholder="text filter">
      </div>
    </form>
    <form class="form-inline">
      <div class="form-group">
        <label for="num_results_socrata">Num results</label>
        <input type="number" size="3" class="form-control" id="num_results_socrata" value="25">
      </div>
    
    </form>
    <form>
      <div class="form-group">
        <button id="bt_send" type="button" class="btn btn-default btn-success">Send</button>
      </div>
    </form>
    <hr>
    <div id="results"></div>
    <div id="mygrid" style="height: 500px"></div>
        </div>
    
  5. Abrimos el archivo socrata.html en el navegador.

  6. Añadimos justo encima de tag </body> el código en JavaScript.:

          <script>
      $.ajaxSetup({
        cache: true
      });
      $(document).ready(function() {
        $('#bt_send').on('click', function() {
          sendRequest();
        });
    
        $('#text_filter_socrata').on('keypress', function(event) {
          if (event.which == 13) {
            sendRequest();
            event.preventDefault();
          }
        });
    
        function sendRequest() {
          var _data = {
            q: $('#text_filter_socrata').val(),
            limit: $('#num_results_socrata').val()
          };
          $.ajax({
            url: $('input:radio[name=optionsRadios]:checked').val(),
            data: _data,
            method: 'GET',
            dataType: 'json',
            success: function(data) {
              console.info(data);
              if (data) {
                $('#results').html('Total results found: ' + data.resultSetSize);
                $('#mygrid').html('');
    
                if (data.resultSetSize >= 1) {
                  $('#mygrid').append('<ul>');
                  $.each(data.results, function(index, value) {
                    $('#mygrid').append('<li><b>' + value.resource.name + '</b>(' + value.resource.type + '): <a target="_blank" href="' + value.link + '">' + value.link + '</a>');
                    $('#mygrid').append('</li>');
                  });
                  $('#mygrid').append('</ul>');
                }
              } else {
                $('#results').html("An error occured:");
              }
            },
            error: function(xhr) {
              $('#results').html("An error occured: " + xhr.status + " " + xhr.statusText);
            }
          });
        }
      });
    </script>
    
  7. Abrimos pàgina socrata.html y lanzamos búsquedas

  8. Ejercicio 1: ¿Cómo filtraríamos para qué sólo enseñara “assets” de tipo mapa?

Creación de un mapa para ver resultados de Socrata

  1. Dentro del directorio utilizacion-servicio-opendata creamos un archivo con el nombre de socrata_mapa.html.

  2. Abrimos el archivo socrata_mapa.html con un editor de texto y copiamos el siguiente código.:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>
            Basic Leaflet Map sample API Discovery SOCRATA
        </title>
        <link rel="stylesheet" href="javascripts/vendor/bootstrap/3.2.0/css/bootstrap.css" />
        <link rel="stylesheet" href="javascripts/vendor/leaflet/0.7.7/leaflet.css" />
        <script type="text/javascript" src="javascripts/vendor/jquery/1.7.1/jquery.js"></script>
        <script type="text/javascript" src="javascripts/vendor/bootstrap/3.2.0/js/bootstrap.js"></script>
        <script type="text/javascript" src="javascripts/vendor/leaflet/0.7.7/leaflet.js"></script>
        <script type="text/javascript" src="javascripts/vendor/leaflet/0.7.7/leaflet.ajax.min.js"></script>
        <script type="text/javascript" src="javascripts/vendor/leaflet/0.7.7/spin.js"></script>
        <script type="text/javascript" src="javascripts/vendor/leaflet/0.7.7/leaflet.spin.min.js"></script>
        <style>
            #results {
                width: 100%;
                background-color: #f2f2f2;
                margin: 5px;
            }
        </style>
    </head>
    <body>
    
    </body>
    </html>
    
  3. Abrimos el archivo socrata_mapa.html en el navegador.

  4. Añadimos dentro del tag <body> la maquetación HTML.:

        <div class="container">
      <h3>SOCRATA Maps Resources </h3>
      <div class="row">
          <div class="col-md-6">
        <p>Discovery API <br>
            <a target="_blank" href="http://docs.socratadiscovery.apiary.io">http://docs.socratadiscovery.apiary.io</a>
        </p>
    <form>
    <div class="form-group">
        <div class="radio">
            <label>
          <input type="radio" name="optionsRadios" id="optionsRadios1" value="https://api.eu.socrata.com/api/catalog/v1" checked>
          EU API Discovery
          </label>
        </div>
        <div class="radio">
            <label>
          <input type="radio" name="optionsRadios" id="optionsRadios2" value="https://api.us.socrata.com/api/catalog/v1">
           US API Discovery
          </label>
            </div>
        </div>
        <div class="form-group">
            <label for="text_filter_socrata"> Filter <u></u></label>
            <input type="text" class="form-control" id="text_filter_socrata" value="" placeholder="text filter">
    
            <div class="checkbox">
                <label><input type="checkbox" id="chk_transparencia" value="analisi.transparenciacatalunya.cat" >Only https://analisi.transparenciacatalunya.cat</label>
            </div>
            <div> Filter : only=maps</div>
        </div>
    
                </form>
                <form class="form-inline">
                    <div class="form-group">
                        <label for="num_results_socrata">Num results</label>
                        <input type="number" size="3" class="form-control" id="num_results_socrata" value="25">
                    </div>
    
                </form>
                <form>
                    <div class="form-group">
                        <button id="bt_send" type="button" class="btn btn-default btn-success">Send</button>
                    </div>
                </form>
                <hr>
                <div id="results"></div>
                <div id="mygrid" style="height: 365px;overflow:auto">
                </div>
            </div>
            <div class="col-md-6">
                <div id="map" style="width:100%;height:700px"></div>
            </div>
        </div>
    
  5. Abrimos el archivo socrata_mapa.html en el navegador.

  6. Añadimos justo encima de tag </body> el código en JavaScript.:

    <script>
            $.ajaxSetup({
                            cache: true
            });
            var map;
            var geojsonLayer;
            var _LL;
            $(document).ready(function() {
                    map = L.map('map').setView([41.6863, 1.8382], 8);
                    esri = L.tileLayer(
                            'http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
                                            maxZoom: 17,
                                            minZoom: 1,
                                            attribution: 'Tiles © Esri',
                            })
    
                    osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                            maxZoom: 19,
                            minZoom: 1,
                            attribution: 'OSM'
                    }).addTo(map);
    
                    Stamen_Toner = L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png', {
                            attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
                            subdomains: 'abcd',
                            minZoom: 0,
                            maxZoom: 20
                    })
    
                    var baseMaps = {
                            "Orto": esri,
                            "Mapa": osm,
                            "Toner": Stamen_Toner
                    };
    
                    L.control.layers(baseMaps, null).addTo(map);
                    L.control.scale().addTo(map);
    
    
                    $('#bt_send').on('click', function() {
                            sendRequest();
                    });
    
                    $('#text_filter_socrata').on('keypress', function(event) {
                            if (event.which == 13) {
                                            sendRequest();
                                            event.preventDefault();
                            }
                    });
    
                    $(document).on('click', '.btn-xs', function() {
    
                            var attr = $(this).attr('data');
                            if (attr && attr.indexOf('#') != -1) {
                                            var params = attr.split("#");
                                            var _url = 'https://' + params[1] + '/api/views.json?method=getByResourceName&name=' + params[0];
                                            $.ajax({
                                                            url: _url,
                                                            method: 'GET',
                                                            dataType: 'json',
                                                            success: function(data) {
    
                                                                            if (data.childViews) {
                                                                                            //var _url2 = 'https://' + params[1] + '/resource/' + data.childViews[0] + '.json?$limit=30';
                                                                                            var _url2 = 'https://' + params[1] + '/api/geospatial/' + data.childViews[0] + '?method=export&format=GeoJSON';
                                                                                            sendRequestGEOJSON(_url2, true);
                                                                            } else {
                                                                                            var _url2 = 'http://' + params[1] + '/resource/' + params[0] + '.json?$limit=30';
                                                                                            sendRequestGEOJSON(_url2, false);
                                                                            }
                                                            },
                                                            error: function(xhr) {
                                                                            $('#results').html("An error occured: " + xhr.status + " " + xhr.statusText);
                                                            }
    
                                            });
    
                            } else {
                                            alert("No resource available");
                            }
                    });
    
                    function clearLayers() {
                            if (map.hasLayer(geojsonLayer)) {
                                            map.removeLayer(geojsonLayer);
                            };
                            if (map.hasLayer(_LL)) {
                                            map.removeLayer(_LL);
                            };
                    }
    
                    function sendRequestGEOJSON(_url2, isGeoJson) {
                            map.spin(true);
                            var stylePoint = {
                                    radius: 8,
                                    fillColor: "#ff7800",
                                    color: "#000",
                                    weight: 1,
                                    opacity: 1,
                                    fillOpacity: 0.8
                            };
                            clearLayers();
                            $.ajax({
                                    type: "GET",
                                    url: _url2,
                                    // jsonp: "$jsonp",
                                    //  dataType: "jsonp",
                                    success: function(response) {
                                            if (isGeoJson) {
    
                                                    geojsonLayer = L.geoJson(response, {
                                                            style: function(feature) {
                                                                    return {
                                                                            weight: 2,
                                                                            color: "#999",
                                                                            opacity: 1,
                                                                            fillColor: "#B0DE5C",
                                                                            fillOpacity: 0.8
                                                                    };
                                                            },
    
                                                            onEachFeature: popUp
                                                    }).addTo(map);
                                                    map.fitBounds(geojsonLayer.getBounds());
                                                    map.spin(false);
                                            } else {
                                                    _LL = L.featureGroup()
    
                                                    for (var i = 0; i < response.length; i++) {
                                                            var marker = response[i];
    
                                                            if (response[i].location_1) {
                                                                    L.circleMarker([response[i].location_1.latitude, response[i].location_1.longitude], stylePoint).addTo(_LL);
                                                            } else if (response[i].location) {
                                                                    L.circleMarker([response[i].location.latitude, response[i].location.longitude], stylePoint).addTo(_LL);
                                                            } else {
                                                                    $('#results').html("ERROR no locations found");
                                                                    map.spin(false);
    
                                                            }
                                                    }
    
                                                    _LL.addTo(map);
                                                    map.panTo(_LL.getBounds().getCenter());
                                                    map.spin(false);
    
                                            }
                                    },
                                    error: function(xhr) {
                                            $('#results').html("An error occured: " + xhr.status + " " + xhr.statusText);
                                            map.spin(false);
                                    }
                            });
                    }
    
                    function popUp(f, l) {
                                    var out = [];
                                    if (f.properties) {
                                            for (key in f.properties) {
                                                            out.push(key + ": " + f.properties[key]);
                                            }
                                            l.bindPopup(out.join("<br />"));
                                    }
                    }
    
                    function sendRequest() {
                            var _data = {
                                    limit: $('#num_results_socrata').val(),
                                    only: 'maps'
                            };
                            console.info($('#chk_transparencia').attr('checked'));
                            if ($('#chk_transparencia').attr('checked')) {
                                    _data.domains = $('#chk_transparencia').val();
                            }
                            if ($('#text_filter_socrata').val() != "") {
                                    _data.q = $('#text_filter_socrata').val();
                            }
    
                            $.ajax({
                                    url: $('input:radio[name=optionsRadios]:checked').val(),
                                    data: _data,
                                    method: 'GET',
                                    dataType: 'json',
                                    success: function(data) {
                                            console.info(data);
                                            if (data) {
                                                    $('#results').html('Total results found: ' + data.resultSetSize);
                                                    $('#mygrid').html('');
    
                                                    if (data.resultSetSize >= 1) {
                                                            var cList = $('<ul>').appendTo('#mygrid');
                                                            $.each(data.results, function(index, value) {
                                                                    $('<li class="li"><b>' + value.resource.name + ': </b>' +
                                                                            '<a target="_blank" href="' + value.link + '"> Link </a> ' +
                                                                            '<a class="btn btn-success btn-xs"  href="#" data="' + value.resource.id + '#' + value.metadata.domain + '">Map it</a>').appendTo(cList);
    
                                                            });
                                                    }
    
                                            } else {
                                                    console.info(data);
                                                    $('#results').html("An error occured:");
                                            }
                                    },
                                    error: function(xhr) {
                                            $('#results').html("An error occured: " + xhr.status + " " + xhr.statusText);
                                    }
                            });
                    }
            });
    </script>
    
  7. Abrimos pàgina socrat_mapa.html y lanzamos búsquedas

  8. Ejercicio 1: Añadimos attribution y download_count a los resultados

  9. Ejercicio 2: ¿Cambiamos colores y estilos de los puntos del mapa?