Traveling Salesman problem i arbres singulars de Barcelona
Contingut
- 1 Introducció
- 2 Referències
- 3 Problema del viatjant de comerç
- 4 Exemple1: Eixample, Gràcia, El Coll, Parc Güell, Vallcarca, Guinardó
- 5 Solució arbres_singulars_example_coll_pguell_vallcarca_guinardo.csv
- 6 Dibuixar la ruta amb OSM i OpenLayers
- 7 Més millores: fitxer JSON
- 8 Ruta arbres singulars #2
- 9 Ruta arbres singulars #2. Més Modificacions
Introducció
L'any passat estava encaparrat amb la idea d'una activitat didàctica per conèixer diferents tipus d'arbre que tenim en el nostre entorn (per exemple, els arbres singulars de Barcelona).
Anem a proposar ara aquesta activitat ajuntant d'una banda la tecnologia que em permet dibuixar sobre un mapa OSM (dibuixar icones i línies); i d'altra banda, amb programació Python, resoldre el problema del comercial viatger: com un comercial pot visitar diferents punts, sense repetir-los, minimitzant el cost del viatge (minimitzant la distància en el cas més senzill).
Referències
- https://ca.wikipedia.org/wiki/Problema_del_viatjant_de_comer%C3%A7
- https://github.com/Forceflow/Ambiance_TSP
- https://wiki.openstreetmap.org/wiki/OpenLayers
Problema del viatjant de comerç
En Python hi ha diferents implementacions, que he estat mirant. Nosaltres volem recórrer una sèrie d'arbres de forma que l'inici i el final siguin el mateix punt (retornar a l'inici).
La solució que m'ha agradat més és:
i l'adapto al meu cas dels arbres singulars. Amb OSM seleccionaré els arbres que vull visitar.
Exemple1: Eixample, Gràcia, El Coll, Parc Güell, Vallcarca, Guinardó
NOTA: aquesta exemple no és el millor. Està clar que per la disposició dels arbres, la solució serà una ruta circular. D'altra banda, el fet d'unir amb una línia recta és només una aproximació del cost de la ruta. En el nostre cas haurem de travessar el Túnel de la Rovira, que implica pujar i baixar de la muntanya. A més, hem de tenir present que els arbres del Parc Güell no es poden visitar a no ser que paguis l'entrada.
- www.overpass-turbo.eu
node["name"~"arbre singular"] ({{bbox}}); (._;>;); out; {{style: node[natural=tree] { icon-image: url('https://img.icons8.com/cotton/2x/tree.png'); icon-width: 25; icon-height: 25; } }}
Dades obtingudes:
<?xml version="1.0" encoding="UTF-8"?> <osm version="0.6" generator="Overpass API 0.7.55.7 8b86ff77"> <note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note> <meta osm_base="2019-11-21T19:25:01Z"/> <node id="4618686054" lat="41.4151676" lon="2.1536067"> <tag k="name" v="arbre singular: Garrofer"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. Parc Güell (viaductes)"/> <tag k="species" v="Ceratónia siliqua"/> <tag k="species:ca" v="Garrofer"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-garrofer-parc-guell-viaductes_99400455077.html"/> </node> <node id="4618688164" lat="41.4149403" lon="2.1547896"> <tag k="name" v="arbre singular: Ullastre"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. Parc Güell"/> <tag k="species" v="Olea europaea L. var. sylvestris"/> <tag k="species:ca" v="Ullastre"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-ullastre-parc-guell_99400454989.html"/> </node> <node id="4618690960" lat="41.4071839" lon="2.1556486"> <tag k="name" v="arbre singular: Xicranda"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. pl. del Nord"/> <tag k="species" v="Jacaranda mimosifolia"/> <tag k="species:ca" v="Xicranda"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-xicranda-pl-del-nord_99400454976.html"/> </node> <node id="4618692827" lat="41.4136463" lon="2.1466483"> <tag k="name" v="arbre singular: Pi blanc"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. c. Sant Camil, 32"/> <tag k="species" v="Pinus halepensis"/> <tag k="species:ca" v="Pi blanc"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-pi-blanc-c-sant-camil-32_99400455000.html"/> </node> <node id="4618711799" lat="41.4073894" lon="2.1507417"> <tag k="name" v="arbre singular: Washingtònia de Mèxic"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. pl. Lesseps"/> <tag k="species" v="Washingtonia robusta"/> <tag k="species:ca" v="Washingtònia de Mèxic"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-washingtonia-de-mexic-pl-lesseps_99400454986.html"/> </node> <node id="4618730503" lat="41.4056619" lon="2.1623828"> <tag k="name" v="arbre singular: Arbre de l'amor, arbre de Jude"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. pl. Joanic"/> <tag k="species" v="Cercis siliquastrum"/> <tag k="species:ca" v="Arbre de l'amor, arbre de Jude"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-arbre-de-l-amor-arbre-de-jude-pl-joanic_99400455041.html"/> </node> <node id="4618744084" lat="41.4141479" lon="2.1530253"> <tag k="name" v="arbre singular: Garrofer"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. Parc Güell"/> <tag k="species" v="Ceratónia siliqua"/> <tag k="species:ca" v="Garrofer"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-garrofer-parc-guell_99400455078.html"/> </node> <node id="4618762649" lat="41.4134138" lon="2.1652644"> <tag k="name" v="arbre singular: Figuera"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. Parc de les Aigües del Guinardó"/> <tag k="species" v="Ficus carica"/> <tag k="species:ca" v="Figuera"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-figuera-parc-de-les-aigues-del-guinardo_99400455012.html"/> </node> <node id="4657040434" lat="41.4190239" lon="2.1643387"> <tag k="name" v="arbre singular: Arbre de l'amor, arbre de Jude"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. c. Panorama, s/n"/> <tag k="species" v="Cercis siliquastrum"/> <tag k="species:ca" v="Arbre de l'amor, arbre de Jude"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-arbre-de-l-amor-arbre-de-jude-c-panorama-sn_99400455042.html"/> </node> <node id="4657043843" lat="41.4132134" lon="2.1656951"> <tag k="name" v="arbre singular: Fotínia del Japó"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. Parc de les Aigües del Guinardó"/> <tag k="species" v="Photinia serrulata"/> <tag k="species:ca" v="Fotínia del Japó"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-fotinia-del-japo-parc-de-les-aigues-del-guinardo_99400455010.html"/> </node> <node id="6924087390" lat="41.4055670" lon="2.1586280"> <tag k="name" v="arbre singular: Alzina"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. c. Encarnació 13"/> <tag k="species" v="Quercus ilex ssp. ilex"/> <tag k="species:ca" v="Alzina"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-alzina-c-encarnacio-13_99400638027.html"/> </node> <node id="6924253586" lat="41.4187200" lon="2.1482400"> <tag k="name" v="arbre singular: Llentiscle, mata"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. Parc de la Creueta del Coll"/> <tag k="species" v="Pistacia lentiscus"/> <tag k="species:ca" v="Llentiscle, mata"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-llentiscle-mata-parc-de-la-creueta-del-coll_99400638023.html"/> </node> <node id="6924265587" lat="41.4077640" lon="2.1539350"> <tag k="name" v="arbre singular: Palmera de Canàries"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. Jardins Mestre Balcells"/> <tag k="species" v="Phoenix canariensis"/> <tag k="species:ca" v="Palmera de Canàries"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-palmera-de-canaries-jardins-mestre-balcells_99400455049.html"/> </node> <node id="6924265588" lat="41.4080160" lon="2.1484960"> <tag k="name" v="arbre singular: Washingtònia de Califòrnia"/> <tag k="natural" v="tree"/> <tag k="note" v="Arbres d'interès local de Barcelona. av. República Argentina 16-18-26"/> <tag k="species" v="Washingtonia filifera"/> <tag k="species:ca" v="Washingtònia de Califòrnia"/> <tag k="website" v="https://www.barcelona.cat/ca/que-pots-fer-a-bcn/parcs-i-jardins/arbres-interes-local/arbre-d-interes-local-washingtonia-de-california-av-republica-argentina-16-18-26-antiga-masia-c_99400454980.html"/> </node> </osm>
I el CSV amb els arbres, arbres_singulars_example_coll_pguell_vallcarca_guinardo.csv:
Place,Name_Cat,Name_Sc,Lat,Long arbre1,Garrofer,Ceratónia siliqua,41.4151676,2.1536067 arbre2,Ullastre,Olea europaea L. var. sylvestris,41.4149403,2.1547896 arbre3,Xicranda,Jacaranda mimosifolia,41.4071839,2.1556486 arbre4,Pi blanc,Pinus halepensis,41.4136463,2.1466483 arbre5,Washingtònia de Mèxic,Washingtonia robusta,41.4073894,2.1507417 arbre6,Arbre de l'amor,Cercis siliquastrum,41.4056619,2.1623828 arbre7,Garrofer,Ceratónia siliqua,41.4141479,2.1530253 arbre8,Figuera,Ficus carica,41.4134138,2.1652644 arbre9,Arbre de l'amor,Cercis siliquastrum,41.4190239,2.1643387 arbre10,Fotínia del Japó,Photinia serrulata,41.4132134,2.1656951 arbre11,Alzina,Quercus ilex ssp. ilex,41.4055670,2.1586280 arbre12,Llentiscle (mata),Pistacia lentiscus,41.4187200,2.1482400 arbre13,Palmera de Canàries,Phoenix canariensis,41.4077640,2.1539350 arbre14,Washingtònia de Califòrnia,Washingtonia filifera,41.4080160,2.1484960
Solució arbres_singulars_example_coll_pguell_vallcarca_guinardo.csv
$ python3 TSP_v2.py arbres_singulars_example_coll_pguell_vallcarca_guinardo.csv # Brought to you by Nerdland podcast - www.nerdland.be # Info: Using arbres_singulars_example_coll_pguell_vallcarca_guinardo.csv as input for location data # Loaded 14 places from csv file: arbre1 | 41.4151676 2.1536067 arbre2 | 41.4149403 2.1547896 arbre3 | 41.4071839 2.1556486 arbre4 | 41.4136463 2.1466483 arbre5 | 41.4073894 2.1507417 arbre6 | 41.4056619 2.1623828 arbre7 | 41.4141479 2.1530253 arbre8 | 41.4134138 2.1652644 arbre9 | 41.4190239 2.1643387 arbre10 | 41.4132134 2.1656951 arbre11 | 41.4055670 2.1586280 arbre12 | 41.4187200 2.1482400 arbre13 | 41.4077640 2.1539350 arbre14 | 41.4080160 2.1484960 # Original route: arbre1 -> arbre2 -> arbre3 -> arbre4 -> arbre5 -> arbre6 -> arbre7 -> arbre8 -> arbre9 -> arbre10 -> arbre11 -> arbre12 -> arbre13 -> arbre14 -> arbre1 # Solving route (time limit: 30 seconds) # Optimized route: arbre1 -> arbre2 -> arbre9 -> arbre8 -> arbre10 -> arbre6 -> arbre11 -> arbre3 -> arbre13 -> arbre5 -> arbre14 -> arbre4 -> arbre12 -> arbre7 -> arbre1
I per tant, l'ordre dels punts amb què hem de pintar la ruta és:
arbre1 | 41.4151676 2.1536067 arbre2 | 41.4149403 2.1547896 arbre9 | 41.4190239 2.1643387 arbre8 | 41.4134138 2.1652644 arbre10 | 41.4132134 2.1656951 arbre6 | 41.4056619 2.1623828 arbre11 | 41.4055670 2.1586280 arbre3 | 41.4071839 2.1556486 arbre13 | 41.4077640 2.1539350 arbre5 | 41.4073894 2.1507417 arbre14 | 41.4080160 2.1484960 arbre4 | 41.4136463 2.1466483 arbre12 | 41.4187200 2.1482400 arbre7 | 41.4141479 2.1530253 arbre1 | 41.4151676 2.1536067
Dibuixar la ruta amb OSM i OpenLayers
Amb OpenLayers hem aconseguit ficar una capa d'icones i de text sobre els punts. mapa_arbres_singulars_v3.html:
<!doctype html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.4/ol.css" type="text/css"> <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Ubuntu" /> <style> body {background-color: lightblue;} .map { width:1100px; height: 1000px; } .info { position: absolute; margin-left:1120px; font-family: Ubuntu; font-size: 24px; font-style: normal; } h1 { font-family: Ubuntu; font-size: 34px; font-style: normal; font-weight: bold; } h2 { font-family: Ubuntu; font-size: 24px; font-style: normal; font-weight: bold; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.4/ol.js"></script> <title>OpenLayers example</title> </head> <body> <h1>Ruta Arbres Singulars: Eixample, Gràcia, El Coll, Parc Güell, Vallcarca, Guinardó</h1> <div id="info" class="info"> <!-- <ul> <li>hh rt eiui ih</li> <li>hh rtui ih</li> <li>hh rt ei cgdr rreui ih</li> </ul> --> </div> <div id="map" class="map"></div> <script type="text/javascript"> var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([2.15750,41.41188]), zoom: 16 }) }); /* arbre1 | 41.4151676 2.1536067 - 2.1536067,41.4151676 arbre2 | 41.4149403 2.1547896 - 2.1547896,41.4149403 arbre9 | 41.4190239 2.1643387 - 2.1643387,41.4190239 arbre8 | 41.4134138 2.1652644 - 2.1652644,41.4134138 arbre10 | 41.4132134 2.1656951 - 2.1656951,41.4132134 arbre6 | 41.4056619 2.1623828 - 2.1623828,41.4056619 arbre11 | 41.4055670 2.1586280 - 2.1586280,41.4055670 arbre3 | 41.4071839 2.1556486 - 2.1556486,41.4071839 arbre13 | 41.4077640 2.1539350 - 2.1539350,41.4077640 arbre5 | 41.4073894 2.1507417 - 2.1507417,41.4073894 arbre14 | 41.4080160 2.1484960 - 2.1484960,41.4080160 arbre4 | 41.4136463 2.1466483 - 2.1466483,41.4136463 arbre12 | 41.4187200 2.1482400 - 2.1482400,41.4187200 arbre7 | 41.4141479 2.1530253 - 2.1530253,41.4141479 arbre1 | 41.4151676 2.1536067 - 2.1536067,41.4151676 arbre1,Garrofer,Ceratónia siliqua,41.4151676,2.1536067 arbre2,Ullastre,Olea europaea L. var. sylvestris,41.4149403,2.1547896 arbre3,Xicranda,Jacaranda mimosifolia,41.4071839,2.1556486 arbre4,Pi blanc,Pinus halepensis,41.4136463,2.1466483 arbre5,Washingtònia de Mèxic,Washingtonia robusta,41.4073894,2.1507417 arbre6,Arbre de l'amor,Cercis siliquastrum,41.4056619,2.1623828 arbre7,Garrofer,Ceratónia siliqua,41.4141479,2.1530253 arbre8,Figuera,Ficus carica,41.4134138,2.1652644 arbre9,Arbre de l'amor,Cercis siliquastrum,41.4190239,2.1643387 arbre10,Fotínia del Japó,Photinia serrulata,41.4132134,2.1656951 arbre11,Alzina,Quercus ilex ssp. ilex,41.4055670,2.1586280 arbre12,Llentiscle (mata),Pistacia lentiscus,41.4187200,2.1482400 arbre13,Palmera de Canàries,Phoenix canariensis,41.4077640,2.1539350 arbre14,Washingtònia de Califòrnia,Washingtonia filifera,41.4080160,2.1484960 */ var arbres = [ {'name':'Garrofer','point':[2.1536067,41.4151676]}, {'name':'Ullastre','point':[2.1547896,41.4149403]}, {'name':'Arbre de l\'amor','point':[2.1643387,41.4190239]}, {'name':'Figuera','point':[2.1652644,41.4134138]}, {'name':'Fotínia del Japó','point':[2.1656951,41.4132134]}, {'name':'Arbre de l\'amor','point':[2.1623828,41.4056619]}, {'name':'Alzina','point':[2.1586280,41.4055670]}, {'name':'Xicranda','point':[2.1556486,41.4071839]}, {'name':'Palmera de Canàries','point':[2.1539350,41.4077640]}, {'name':'Washingtònia de Mèxic','point':[2.1507417,41.4073894]}, {'name':'Washingtònia de Califòrnia','point':[2.1484960,41.4080160]}, {'name':'Pi blanc','point':[2.1466483,41.4136463]}, {'name':'Llentiscle','point':[2.1482400,41.4187200]}, {'name':'Garrofer','point':[2.1530253,41.4141479]}, {'name':'Garrofer','point':[2.1536067,41.4151676]} ]; var linies = [] var icones = [] for ( var i = 0; i < arbres.length; i++) { arbres[i].point = ol.proj.fromLonLat(arbres[i].point); } var linies = []; var linia_style = [ // linestring new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#d12710', width: 4 }) }) ]; for ( var i = 0; i < arbres.length-1; i++) { //console.log(arbres[i].name) //console.log(arbres[i].point) var linia = new ol.layer.Vector({ source: new ol.source.Vector({ features: [new ol.Feature({ geometry: new ol.geom.LineString([arbres[i].point, arbres[i+1].point]), name: 'Line', })] }) }); linia.setStyle(linia_style); linies.push(linia); var iconPoint = new ol.Feature({ geometry: new ol.geom.Point(arbres[i].point) }); iconPoint.setStyle(styleFunction); iconPoint.set('description', (i+1) + "." + arbres[i].name); icones.push(iconPoint); } var vectorSourceIcones = new ol.source.Vector({ features: icones }); var vectorLayerIcones = new ol.layer.Vector({ source: vectorSourceIcones }); map.addLayer(vectorLayerIcones); for (var i = 0; i < linies.length; i++) { map.addLayer(linies[i]); } omplir_llista_arbres(arbres); //https://stackoverflow.com/questions/39006597/openlayers-3-add-text-label-to-feature //he afegit la funcionalitat de ficar una icona que tenia en la versió anterior function styleFunction() { return [ new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255,255,255,1)' }), image: new ol.style.Icon(({ anchor: [0.5, 1], src: "./img/tree_25_25.png" })), stroke: new ol.style.Stroke({ color: '#3399CC', width: 3.25 }), text: new ol.style.Text({ font: '14px Calibri,sans-serif', offsetY: '-15', textAlign: 'left', fill: new ol.style.Fill({ color: '#000' }), stroke: new ol.style.Stroke({ color: '#fff', width: 2 }), // get the text from the feature - `this` is ol.Feature // and show only under certain resolution text: map.getView().getZoom() > 12 ? ' ' + this.get('description') : '' }) }) ]; } function omplir_llista_arbres(arbres) { var ol = document.createElement('ol'); for ( var i = 0; i < arbres.length-1; i++) { console.log(arbres[i].name); var li = document.createElement('li'); li.innerHTML= arbres[i].name; ol.appendChild(li); } document.getElementById("info").appendChild(ol); } </script> </body> </html>
Ara la única cosa que faltarà és minimitzar el copy-paste. La sortida del fitxer python l'he de poder llegir automàticament en el html. I també he de cercar un exemple més interessant, que no sigui obvi la ruta circular. (TBD)
Més millores: fitxer JSON
La versió 3 (TSP_v3.py) genera el fitxer output.json, que podrem carregar directament des de la pàgina html.
$ python3 TSP_v3.py --json arbres_singulars_example_coll_pguell_vallcarca_guinardo.csv # Info: Using arbres_singulars_example_coll_pguell_vallcarca_guinardo.csv as input for location data # Info: Enviant la sortida a html/output.json # Loaded 14 places from csv file: arbre1 | Garrofer | 41.4151676 2.1536067 arbre2 | Ullastre | 41.4149403 2.1547896 arbre3 | Xicranda | 41.4071839 2.1556486 arbre4 | Pi blanc | 41.4136463 2.1466483 arbre5 | Washingtònia de Mèxic | 41.4073894 2.1507417 arbre6 | Arbre de l'amor | 41.4056619 2.1623828 arbre7 | Garrofer | 41.4141479 2.1530253 arbre8 | Figuera | 41.4134138 2.1652644 arbre9 | Arbre de l'amor | 41.4190239 2.1643387 arbre10 | Fotínia del Japó | 41.4132134 2.1656951 arbre11 | Alzina | 41.4055670 2.1586280 arbre12 | Llentiscle (mata) | 41.4187200 2.1482400 arbre13 | Palmera de Canàries | 41.4077640 2.1539350 arbre14 | Washingtònia de Califòrnia | 41.4080160 2.1484960 # Original route: arbre1 -> arbre2 -> arbre3 -> arbre4 -> arbre5 -> arbre6 -> arbre7 -> arbre8 -> arbre9 -> arbre10 -> arbre11 -> arbre12 -> arbre13 -> arbre14 -> arbre1 # Solving route (time limit: 30 seconds) # Optimized route: solució a html/output.json
output.json:
[ {"name":"Garrofer","point":[2.1536067,41.4151676]}, {"name":"Ullastre","point":[2.1547896,41.4149403]}, {"name":"Arbre de l'amor","point":[2.1643387,41.4190239]}, {"name":"Figuera","point":[2.1652644,41.4134138]}, {"name":"Fotínia del Japó","point":[2.1656951,41.4132134]}, {"name":"Arbre de l'amor","point":[2.1623828,41.4056619]}, {"name":"Alzina","point":[2.1586280,41.4055670]}, {"name":"Xicranda","point":[2.1556486,41.4071839]}, {"name":"Palmera de Canàries","point":[2.1539350,41.4077640]}, {"name":"Washingtònia de Mèxic","point":[2.1507417,41.4073894]}, {"name":"Pi blanc","point":[2.1466483,41.4136463]}, {"name":"Llentiscle (mata)","point":[2.1482400,41.4187200]}, {"name":"Garrofer","point":[2.1530253,41.4141479]}, {"name":"Garrofer","point":[2.1536067,41.4151676]} ]
I ara hem de dibuixar el mapa important les dades del fitxer JSON. Necessitarem fer una crida AJAX, i per tant necessitarem visualitzar la web des del servidor web (crida http):
La manera com fem la crida JSON:
function loadJSON(callback) { var xobj = new XMLHttpRequest(); xobj.overrideMimeType("application/json"); xobj.open('GET', 'output.json', true); // Replace 'my_data' with the path to your file xobj.onreadystatechange = function () { if (xobj.readyState == 4 && xobj.status == "200") { // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode callback(xobj.responseText); } }; xobj.send(null); }
I ara cridem fem la crida:
loadJSON(function(response) { // Parse JSON string into object arbres = JSON.parse(response); //alert(arbres.length); var linies = [] var icones = [] for ( var i = 0; i < arbres.length; i++) { arbres[i].point = ol.proj.fromLonLat(arbres[i].point); } ...
Ruta arbres singulars #2
$ python3 TSP_v3.py --json colleccio_arbres2.csv # Info: Using colleccio_arbres2.csv as input for location data # Info: Enviant la sortida a html/output.json # Loaded 57 places from csv file: arbre1 | Siris blanc | 41.4009770 2.1470945 arbre2 | Còcul | 41.4005146 2.1468057 arbre3 | Xicranda | 41.3994030 2.1485156 arbre4 | Grevillea robusta | 41.3978637 2.1347232 arbre5 | Margalló | 41.3887570 2.1607406 arbre6 | Bellaombra | 41.3925498 2.1443776 arbre7 | Washingtònia de Mèxic | 41.3891488 2.1603995 arbre8 | Palmera blava | 41.3873786 2.1222567 arbre9 | Roure | 41.3846197 2.1104121 arbre10 | Pi pinyer | 41.3891153 2.1163129 arbre11 | Arbre ampolla | 41.3889060 2.1159964 arbre12 | Pi pinyer | 41.3881412 2.1158908 arbre13 | Pi blanc | 41.3887569 2.1151854 arbre14 | Washingtònia de Califòrnia | 41.3928539 2.1435309 arbre15 | Figuera | 41.3873000 2.1208904 arbre16 | Pi de l'Himàlaia | 41.3898315 2.1315334 arbre17 | Pi pinyer | 41.3861449 2.1339903 arbre18 | Alvocater | 41.3835981 2.1308039 arbre19 | Tuia articulada (Savina de mor) | 41.3870076 2.1183141 arbre20 | Pi blanc | 41.4034793 2.1162956 arbre21 | Tipuana | 41.4089554 2.1368708 arbre22 | Ginjoler | 41.4045959 2.1372812 arbre23 | Cedre de l'Himàlaia | 41.4080797 2.1341301 arbre24 | Lledoner | 41.3920160 2.1272462 arbre25 | Pebrer bord | 41.3922011 2.1219891 arbre26 | Alzina | 41.4140929 2.1045461 arbre27 | Pi pinyer | 41.3985601 2.1248668 arbre28 | Palmera de Canàries | 41.3925168 2.1225333 arbre29 | Alzina surera | 41.4024879 2.1411862 arbre30 | Magnòlia | 41.4066326 2.1311748 arbre31 | Eucaliptus comú | 41.3978064 2.1113720 arbre32 | Cirerer de Santa Llúcia | 41.3984704 2.1090761 arbre33 | Plàtan d'ombra | 41.3926132 2.1228760 arbre34 | Tell argentat | 41.4014334 2.1237453 arbre35 | Xicranda | 41.4071839 2.1556486 arbre36 | Pi blanc | 41.4136463 2.1466483 arbre37 | Washingtònia de Mèxic | 41.4073894 2.1507417 arbre38 | Freixe de Mèxic | 41.3993611 2.1528378 arbre39 | Garrofer | 41.4141479 2.1530253 arbre40 | Aladern de fulla ampla | 41.4083980 2.1313580 arbre41 | Alzina | 41.4030720 2.1136660 arbre42 | Alzina | 41.3801420 2.1257710 arbre43 | Alzina | 41.4055670 2.1586280 arbre44 | Còcul | 41.3934560 2.1303450 arbre45 | Còcul | 41.3961030 2.1595140 arbre46 | Eucaliptus blanc | 41.4053230 2.1308730 arbre47 | Eucaliptus comú | 41.3929060 2.1226570 arbre48 | Pi canari | 41.3994370 2.1333650 arbre49 | Roure pènol | 41.4106600 2.1351440 arbre50 | Pi blanc | 41.3958050 2.1189410 arbre51 | Llentiscle | 41.4064060 2.1170520 arbre52 | Lledoner | 41.3962440 2.1468710 arbre53 | Morera blanca | 41.4086150 2.1312560 arbre54 | Palmera de Canàries | 41.4077640 2.1539350 arbre55 | Washingtònia de Califòrnia | 41.4080160 2.1484960 arbre56 | Pi pinyer | 41.3936770 2.1184360 arbre57 | Til·ler | 41.3955000 2.1573580
Solució:
# Optimized route: arbre1 -> arbre2 -> arbre29 -> arbre22 -> arbre21 -> arbre49 -> arbre23 -> arbre40 -> arbre53 -> arbre30 -> arbre46 -> arbre48 -> arbre4 -> arbre44 -> arbre24 -> arbre33 -> arbre47 -> arbre28 -> arbre25 -> arbre56 -> arbre50 -> arbre27 -> arbre34 -> arbre51 -> arbre20 -> arbre41 -> arbre26 -> arbre32 -> arbre31 -> arbre9 -> arbre13 -> arbre11 -> arbre10 -> arbre12 -> arbre19 -> arbre15 -> arbre8 -> arbre42 -> arbre18 -> arbre17 -> arbre16 -> arbre14 -> arbre6 -> arbre52 -> arbre3 -> arbre38 -> arbre57 -> arbre7 -> arbre5 -> arbre45 -> arbre43 -> arbre35 -> arbre54 -> arbre39 -> arbre36 -> arbre55 -> arbre37 -> arbre1
Solució: output.json:
[ {"name":"Siris blanc","point":[2.1470945,41.4009770]}, {"name":"Còcul","point":[2.1468057,41.4005146]}, {"name":"Alzina surera","point":[2.1411862,41.4024879]}, {"name":"Ginjoler","point":[2.1372812,41.4045959]}, {"name":"Tipuana","point":[2.1368708,41.4089554]}, {"name":"Roure pènol","point":[2.1351440,41.4106600]}, {"name":"Cedre de l'Himàlaia","point":[2.1341301,41.4080797]}, {"name":"Aladern de fulla ampla","point":[2.1313580,41.4083980]}, {"name":"Morera blanca","point":[2.1312560,41.4086150]}, {"name":"Magnòlia","point":[2.1311748,41.4066326]}, {"name":"Eucaliptus blanc","point":[2.1308730,41.4053230]}, {"name":"Pi canari","point":[2.1333650,41.3994370]}, {"name":"Grevillea robusta","point":[2.1347232,41.3978637]}, {"name":"Còcul","point":[2.1303450,41.3934560]}, {"name":"Lledoner","point":[2.1272462,41.3920160]}, {"name":"Plàtan d'ombra","point":[2.1228760,41.3926132]}, {"name":"Eucaliptus comú","point":[2.1226570,41.3929060]}, {"name":"Palmera de Canàries","point":[2.1225333,41.3925168]}, {"name":"Pebrer bord","point":[2.1219891,41.3922011]}, {"name":"Pi pinyer","point":[2.1184360,41.3936770]}, {"name":"Pi blanc","point":[2.1189410,41.3958050]}, {"name":"Pi pinyer","point":[2.1248668,41.3985601]}, {"name":"Tell argentat","point":[2.1237453,41.4014334]}, {"name":"Llentiscle","point":[2.1170520,41.4064060]}, {"name":"Pi blanc","point":[2.1162956,41.4034793]}, {"name":"Alzina","point":[2.1136660,41.4030720]}, {"name":"Alzina","point":[2.1045461,41.4140929]}, {"name":"Cirerer de Santa Llúcia","point":[2.1090761,41.3984704]}, {"name":"Eucaliptus comú","point":[2.1113720,41.3978064]}, {"name":"Roure","point":[2.1104121,41.3846197]}, {"name":"Pi blanc","point":[2.1151854,41.3887569]}, {"name":"Arbre ampolla","point":[2.1159964,41.3889060]}, {"name":"Pi pinyer","point":[2.1163129,41.3891153]}, {"name":"Pi pinyer","point":[2.1158908,41.3881412]}, {"name":"Tuia articulada (Savina de mor)","point":[2.1183141,41.3870076]}, {"name":"Figuera","point":[2.1208904,41.3873000]}, {"name":"Palmera blava","point":[2.1222567,41.3873786]}, {"name":"Alzina","point":[2.1257710,41.3801420]}, {"name":"Alvocater","point":[2.1308039,41.3835981]}, {"name":"Pi pinyer","point":[2.1339903,41.3861449]}, {"name":"Pi de l'Himàlaia","point":[2.1315334,41.3898315]}, {"name":"Washingtònia de Califòrnia","point":[2.1435309,41.3928539]}, {"name":"Bellaombra","point":[2.1443776,41.3925498]}, {"name":"Lledoner","point":[2.1468710,41.3962440]}, {"name":"Xicranda","point":[2.1485156,41.3994030]}, {"name":"Freixe de Mèxic","point":[2.1528378,41.3993611]}, {"name":"Washingtònia de Mèxic","point":[2.1603995,41.3891488]}, {"name":"Margalló","point":[2.1607406,41.3887570]}, {"name":"Còcul","point":[2.1595140,41.3961030]}, {"name":"Alzina","point":[2.1586280,41.4055670]}, {"name":"Xicranda","point":[2.1556486,41.4071839]}, {"name":"Palmera de Canàries","point":[2.1539350,41.4077640]}, {"name":"Garrofer","point":[2.1530253,41.4141479]}, {"name":"Pi blanc","point":[2.1466483,41.4136463]}, {"name":"Washingtònia de Califòrnia","point":[2.1484960,41.4080160]}, {"name":"Washingtònia de Mèxic","point":[2.1507417,41.4073894]}, {"name":"Siris blanc","point":[2.1470945,41.4009770]} ]
Ruta arbres singulars #2. Més Modificacions
Estic fent més modificacions, per tal de poder incloure aquest projecte al curs de Realitat Virtual i Augmentada que estic fent.
Faig una petita modificació de manera que en el fitxer de sortida, output.json, inclogui el id de l'arbre:
$ python3 TSP_v4.py --json colleccio_arbres2.csv
output.json:
[ {"id":"arbre1","name":"Siris blanc","point":[2.1470945,41.4009770]}, {"id":"arbre2","name":"Còcul","point":[2.1468057,41.4005146]}, {"id":"arbre29","name":"Alzina surera","point":[2.1411862,41.4024879]}, {"id":"arbre22","name":"Ginjoler","point":[2.1372812,41.4045959]}, {"id":"arbre21","name":"Tipuana","point":[2.1368708,41.4089554]}, {"id":"arbre49","name":"Roure pènol","point":[2.1351440,41.4106600]}, ...
i el resultat (com es veu a la imatge) es correspon al script mapa_arbres_singulars_v5.html. En aquest hem afegit com a capa un popup.
Programació didàctica de una unitat didàctica per al curs de Realitat Virtual a l'aula:
creat per Joan Quintana Compte, novembre 2019