[guadec-web: 5/9] added poi search



commit a27938620105eca7110043409d4e21b4ad4d6f7f
Author: Jorge Sanz <xurxosanz gmail com>
Date:   Sat Jun 16 01:57:02 2018 +0200

    added poi search

 content/pages/test-map-v2.md | 259 +++++++++++++++++++++++++++----------------
 1 file changed, 165 insertions(+), 94 deletions(-)
---
diff --git a/content/pages/test-map-v2.md b/content/pages/test-map-v2.md
index 47600bb..4404de4 100644
--- a/content/pages/test-map-v2.md
+++ b/content/pages/test-map-v2.md
@@ -1,34 +1,57 @@
 Title: Test map v2
 Date: 20180615
 
-## OSM Map with MapboxGL
-
-<div id="map" style="width: 100%; height: 100vh;"></div>   
+## GUADEC Map
 
 <link rel='stylesheet' href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' />
 <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
 <script src="https://tyrasd.github.io/osmtogeojson/osmtogeojson.js";></script>
 
 <style>
-       #map {
-               margin: 0;
-               height: 100vh;
-               width: 100%;
-       }
-       .mapboxgl-popup-content a {
-               color: #4a86cf;
-               text-decoration-line: none;
-       }
-       .mapboxgl-popup-content ul {
-               padding-left: 18px;
-       }
-       .osm-source{
-               font-size: 0.7em;
-       }
+    #map {
+        margin: 0;
+        height: 600px;
+        width: 100%;
+    }
+    .mapboxgl-popup-content a {
+        color: #4a86cf;
+        text-decoration-line: none;
+    }
+    .mapboxgl-popup-content ul {
+        padding-left: 18px;
+    }
+    .osm-source{
+        font-size: 0.7em;
+    }
+    .filter-ctrl {
+        position: absolute;
+        top: 10px;
+        right: 50px;
+        z-index: 1;
+        width: 180px;
+    }
+    .filter-ctrl input[type=text] {
+        font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
+        width: 100%;
+        border: 0;
+        background-color: #fff;
+        height: 40px;
+        margin: 0;
+        color: rgba(0,0,0,.5);
+        padding: 10px;
+        box-shadow: 0 0 0 2px rgba(0,0,0,0.1);
+        border-radius: 3px;
+    }
 </style>
- 
+
+<div id="map">
+<div class='filter-ctrl'>
+    <input id='filter-input' type='text' name='filter' placeholder='Filter by name' />
+</div>
+</div>
+
 <script>
-    /* parameters */   
+    /* parameters */
     var /* List of ways to include in the map */
         osm_ways = [
             27152910, // almeria railway
@@ -44,7 +67,7 @@ Date: 20180615
             2870058034, // 292
             974730957, // 144
         ],
-        /* Basemap Styles 
+        /* Basemap Styles
         OpenMapTiles https://openmaptiles.github.io/positron-gl-style/style-cdn.json
         CARTO https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json
         */
@@ -55,8 +78,8 @@ Date: 20180615
         /* Main color to use anywhere */
         main_color = '#4a86cf',
         /* Icon for the points ont the map */
-        icon = 'https://i.imgur.com/cux5ypg.png', // '/theme/img/Gnomelogo-footprint.png',
-        /* White list of properties to allow to 
+        icon = '/theme/img/Gnomelogo-footprint.png',
+        /* White list of properties to allow to
         be displayed in the popup, order matters! */
         popup_properties = [
             'description',
@@ -65,20 +88,12 @@ Date: 20180615
             'adr:street',
             'website','wikidata','wikipedia'
         ]
-        ;  
+        ;
 </script>
 
 <script>
-    /* Script */
-    var 
-        overpass_url = 'http://overpass-api.de/api/interpreter'
-        map = new mapboxgl.Map({
-            container: 'map', 
-            style: basemap_style,
-            center: center,
-            zoom: zoom,
-            attributionControl: true
-        }),
+    /* Functions and helpers */
+    var overpass_url = 'http://overpass-api.de/api/interpreter',
         /* from https://www.npmjs.com/package/geojson-polygon-center */
         polygon_center = function (polygon) {
             var minx = miny = 1000,
@@ -105,41 +120,37 @@ Date: 20180615
         },
         /* helper to get the list of ids */
         get_ids = function(el){
-            if (typeof el == "number"){
-                return el
-            } else {
-                return el['osm_id']
-            }
+            return typeof el == "number" ? el : el['osm_id'];
         },
+        /* takes a feature, and augment it with any custom properties 
+           passed on thi list of nodes and ways */
         get_props = function(feature){
-            var properties = feature['properties'],
-                /* feature id */
-                feat_id = properties['id'],
-                /* filter checker */
+            var /* filter checker */
                 filter_node = function(node){
                     return typeof node != "number" && node['osm_id'] == feat_id;
                 },
-                cand = osm_nodes
-                        .filter(filter_node)
-                        .concat(osm_ways.filter(filter_node));
-                
-            if (cand.length == 1){
-                properties = Object.assign(properties,cand[0]);
+                properties = feature['properties'],
+                /* feature id */
+                feat_id = properties['id'],
+                /* candidates */
+                candidate = osm_nodes.filter(filter_node)
+                                .concat(osm_ways.filter(filter_node));
+
+            if (candidate.length == 1){
+                properties = Object.assign(properties,candidate[0]);
             };
 
             return feature;
-
         },
         /* Generate a valid OSM Overpass API request */
         get_osm_query = function(){
-            
-            var ways = osm_ways.map(get_ids);
-            var nodes = osm_nodes.map(get_ids);
+            var ways = osm_ways.map(get_ids).join(',');
+            var nodes = osm_nodes.map(get_ids).join(',');
 
             return `[out:xml][timeout:300];
                     (
-                        way(id:${ways.join(',')});
-                        node(id:${nodes.join(',')});
+                        way(id:${ways});
+                        node(id:${nodes});
                     )->.a;
                     (.a; .a >;);out qt;`
         }
@@ -149,7 +160,13 @@ Date: 20180615
             tags = properties['tags'];
             Object.assign(properties, tags);
             delete properties['tags'];
-            
+
+            if (properties['id'] == undefined){
+                properties['id'] = String(feature['id'])
+            } else {
+                properties['id'] = String(properties['id'])
+            };
+
             // Override the name in Engish, if it exists
             if (properties['name:en'] != undefined){
                 properties['name'] = properties['name:en']
@@ -158,11 +175,9 @@ Date: 20180615
             return feature
         },
         /* transforms OSM data into geojson and adds that as
-        points and labels to the map */
+           points and labels to the map */
         load_osm_data = function(data){
             console.log('loading data...');
-
-           
             var  // Convert to GeoJSON
                 geojson_data = osmtogeojson(data),
                 // Filter ways
@@ -184,79 +199,109 @@ Date: 20180615
                 // Get all properties out from the tags
                 points_geojson_props = all_features.map(tags_to_props),
                 // Override any custom properties
-                final_points = points_geojson_props.map(get_props),
-                // Build final geojson collection
-                geojson = {
-                            'type': 'FeatureCollection',
-                            'features': final_points
-                };
-
-            console.log(geojson);
+                final_points = points_geojson_props.map(get_props);
 
+            // Build final geojson collection
+            return {
+                        'type': 'FeatureCollection',
+                        'features': final_points
+            };           
+        },
+        /* Loads the data retrieved into a mapboxgl map */
+        add_layers = function(map, data){
             map.loadImage(icon, function(error, image) {
                 if (error) throw error;
                 map.addImage('gnome', image);
+
+                /* Icon layer */
                 map.addLayer({
                     'id': 'guadec_icon',
                     'type': 'symbol',
                     'source': {
                         'type': 'geojson',
-                        'data': geojson
+                        'data': geojson_data
                     },
                     'layout': {
                         "symbol-placement": "point",
+                        "text-field": '{name}' ,
                         "icon-image": "gnome",
-                        "icon-allow-overlap": true,
-                        "icon-size": .15
-                    },
-                    'paint': {}
-                });
-                map.addLayer({
-                    'id': 'guadec_label',
-                    'type': 'symbol',
-                    "minzoom": 12,
-                    'source': {
-                        'type': 'geojson',
-                        'data': geojson
-                    },
-                    'layout': {
                         "text-font": ["Open Sans Regular"],
-                        "text-field": "{name}",
-                        "symbol-placement": "point",
-                        "text-size": 20,
-                        "text-offset": [.25,.25],
+                        "icon-allow-overlap": true,
+                        "text-offset": [.3,.3],
                         "text-anchor": "top-left",
+                        "text-max-width": 5,
+                        "text-justify": "left",
                         "text-allow-overlap": false,
                         "text-optional": true,
+                        "icon-size": {
+                            "stops": [
+                                [0, 0.10],
+                                [12, 0.12],
+                                [14, 0.15],
+                                [18, 0.25]
+                            ]
+                        },
+                        "text-size": {
+                            "stops": [
+                                [0, 0],
+                                [9,0],
+                                [12, 15],
+                                [16, 20]
+                            ]
+                        }
                     },
                     'paint': {
                         "text-color": main_color,
+                        "icon-opacity": 1,
+                        "text-opacity": {
+                            "stops": [
+                                [0, 0],
+                                [9,0],
+                                [12, 1]
+                            ]
+                        },
                         "text-halo-color": "white",
-                        "text-halo-width": 1,
+                        "text-halo-width": 1.5,
                         "text-halo-blur": 1
                     }
                 });
-            });
+            }); 
         };
+</script>
 
+<script>
     /* SCRIPT */
+    var geojson_data = {},
+        map = new mapboxgl.Map({
+            container: 'map',
+            style: basemap_style,
+            center: center,
+            zoom: zoom,
+            attributionControl: true
+        });
+    
+    /*Once map is loaded, get data from OSM to add as a new layer */
     map.on('load', function() {
-        /*Once map is loaded, get data from OSM to add as a new layer */
-        // Render ways
         console.log('fetching osm data...')
         fetch(overpass_url,{
             method: "POST",
             body:  get_osm_query()})
             .then(response => response.text())
             .then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
-            .then(load_osm_data)
+            .then(function(data){
+                // Get the geojson to work
+                geojson_data = load_osm_data(data);
+                console.log(geojson_data);
+                // Add it as a layer
+                add_layers(map,geojson_data);
+            })
             .catch(error => console.log("Error:", error));
     });
 
-    // Add navigation controls
+    /* Navigation control */
     map.addControl(new mapboxgl.NavigationControl());
 
-    // Add a popup interactivity
+    /* Popup interactivity */
     map.on('click', function(e) {
         var features = map.queryRenderedFeatures(e.point, {
             layers: ['guadec_icon']
@@ -298,4 +343,30 @@ Date: 20180615
                 .setLngLat(feature.geometry.coordinates)
                 .addTo(map);
     });
-</script>
+
+    /* Filter control */
+    document
+        .getElementById('filter-input')
+        .addEventListener('keyup', function(e) {
+            function normalize(string) {
+                return string.trim().toLowerCase();
+            };
+
+            // Get the value of the input
+            var value = normalize(e.target.value);
+            
+            if (value == ""){
+                // If it's empty remove the filter
+                map.setFilter('guadec_icon', null);
+
+            } else {
+                // Filter the geojson features and get their ids
+                ids = geojson_data.features
+                    .filter( x =>  normalize( x['properties']['name']).match(new RegExp(value,"g")) != null)
+                    .map(x => x['properties']['id'])
+
+                // Set the filter of the layer to match those ids
+                map.setFilter('guadec_icon', ['match', ['get', 'id'], ids, true, false]);
+            }
+        });
+</script>
\ No newline at end of file


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]