Saltar a contenido

API servicios Open Data (CKAN y SOCRATA)

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 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?

Ver ejemplos online

Creación de un buscador

  • Dentro de nuestor espacio de trabaj creamos un archivo con el nombre de ckan.html.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
 <!DOCTYPE html>
  <html>
<head>
    <meta charset="UTF-8">
    <title>
            Bàsic sample Resource Search API CKAN
    </title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <style>
            #results {
                    width: 100%;
                    background-color: #f2f2f2;
                    margin: 5px;
            }
    </style>
</head>
<body>
</body>
</html>
  • Abrimos el archivo ckan.html en el navegador.

  • Añadimos dentro del tag <body> la maquetación HTML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<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 id="_form">
    <div class="form-group">
      <label for="url_ckan">Url:</label>

      <select id="url_ckan">
        <option value="https://demo.ckan.org/api/3/action/resource_search?">ckan.org</option>
        <option value="https://old.datahub.io/api/3/action/resource_search?">old.datahub.io</option>
                <!-- añadimos BCN opendata -->
      </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>
  • Abrimos el archivo ckan.html en el navegador.

  • Añadimos just encima del tag </head> el siguiente código javascript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<script>
    $.ajaxSetup({
    cache: true
  });
  $(document).ready(function () {
    $('#bt_send').on('click', function () {
      sendRequest();
    });

    $( "#_form" ).submit(function( event ) {
      sendRequest();
      event.preventDefault();
    });


    function sendRequest(){
      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>
  • Abrimos pàgina ckan.html y lanzamos búsquedas

Note

Ejercicio 1: Añadir una o más URLs de otros portales de CKAN, por ejemplo OpenDataBCN

Note

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

Note

Ejercicio 3: Descargamos CSV accidentes

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

Creación de un buscador

  • Creamos un archivo con el nombre de socrata.html.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>
        Basic sample API Discovery SOCRATA
    </title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

    <style>
        #results {
            width: 100%;
            background-color: #f2f2f2;
            margin: 5px;
        }
    </style>
</head>

<body>

</body>

</html>
  • Abrimos el archivo socrata.html en el navegador.

  • Añadimos dentro del tag * <body>* la maquetación HTML.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<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>
  • Abrimos el archivo socrata.html en el navegador.

  • Añadimos just encima del tag </head> el siguiente código javascript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<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>
  • Abrimos pàgina socrata.html y lanzamos búsquedas

Note

Ejercicio 1: ¿Cómo filtraríamos para qué sólo enseñara "assets" de tipo "map", only:map?

Creación de un mapa para ver resultados de Socrata

  • Creamos un archivo con el nombre de socrata_mapa.html.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>
        Basic Leaflet Map sample API Discovery SOCRATA
    </title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css" />
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Leaflet.Spin/1.1.0/leaflet.spin.min.js"></script>
    <style>
        #results {
            width: 100%;
            background-color: #f2f2f2;
            margin: 5px;
        }
    </style>
</head>
<body>

</body>
</html>
  • Añadimos dentro del tag <body> la maquetación HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<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>
  • Abrimos el archivo socrata_mapa.html en el navegador.

  • Añadimos just encima del tag </head> el siguiente código javascript

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<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>
  • Abrimos pàgina socrat_mapa.html y lanzamos búsquedas

Note

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

Note

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

Tip

Ejemplos creados downloads/utilizacion-servicio-opendata.zip en nuestro espacio de trabajo.

Referencias

http://docs.ckan.org/en/latest/api/ http://ckan.org https://www.socrata.com http://docs.socratadiscovery.apiary.io