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?
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> — Map data © <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