Changeset 2479440
- Timestamp:
- 02/22/2021 11:27:20 PM (5 years ago)
- Location:
- spotmap
- Files:
-
- 8 added
- 2 deleted
- 20 edited
- 1 copied
-
tags/0.10.1 (copied) (copied from spotmap/trunk)
-
tags/0.10.1/LICENSE (added)
-
tags/0.10.1/admin/class-spotmap-admin.php (modified) (1 diff)
-
tags/0.10.1/config/maps.json (modified) (5 diffs)
-
tags/0.10.1/includes/class-spotmap-database.php (modified) (2 diffs)
-
tags/0.10.1/public/class-spotmap-public.php (modified) (11 diffs)
-
tags/0.10.1/public/css/custom.css (modified) (1 diff)
-
tags/0.10.1/public/js/block.js (modified) (1 diff)
-
tags/0.10.1/public/js/maphandler.js (modified) (22 diffs)
-
tags/0.10.1/public/leaflet-easy-button (added)
-
tags/0.10.1/public/leaflet-easy-button/easy-button.css (added)
-
tags/0.10.1/public/leaflet-easy-button/easy-button.js (added)
-
tags/0.10.1/public/leafletfullscreen/fullscreen@2x.png (deleted)
-
tags/0.10.1/public/leafletfullscreen/leaflet.fullscreen.css (modified) (1 diff)
-
tags/0.10.1/readme.txt (modified) (4 diffs)
-
tags/0.10.1/spotmap.php (modified) (2 diffs)
-
trunk/LICENSE (added)
-
trunk/admin/class-spotmap-admin.php (modified) (1 diff)
-
trunk/config/maps.json (modified) (5 diffs)
-
trunk/includes/class-spotmap-database.php (modified) (2 diffs)
-
trunk/public/class-spotmap-public.php (modified) (11 diffs)
-
trunk/public/css/custom.css (modified) (1 diff)
-
trunk/public/js/block.js (modified) (1 diff)
-
trunk/public/js/maphandler.js (modified) (22 diffs)
-
trunk/public/leaflet-easy-button (added)
-
trunk/public/leaflet-easy-button/easy-button.css (added)
-
trunk/public/leaflet-easy-button/easy-button.js (added)
-
trunk/public/leafletfullscreen/fullscreen@2x.png (deleted)
-
trunk/public/leafletfullscreen/leaflet.fullscreen.css (modified) (1 diff)
-
trunk/readme.txt (modified) (4 diffs)
-
trunk/spotmap.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
spotmap/tags/0.10.1/admin/class-spotmap-admin.php
r2382782 r2479440 100 100 'spotmap-thirdparties-group' 101 101 ); 102 foreach (['mapbox','thunderforest','timezonedb' ] as $index) {102 foreach (['mapbox','thunderforest','timezonedb','linz.govt.nz','geoservices.ign.fr'] as $index) { 103 103 $value = isset( get_option('spotmap_api_tokens')[$index] ) ? get_option('spotmap_api_tokens')[$index] : ''; 104 104 add_settings_field( -
spotmap/tags/0.10.1/config/maps.json
r2360204 r2479440 6 6 "tileSize": 512, 7 7 "mapboxToken": "", 8 "maxZoom": 23, 8 9 "zoomOffset": -1, 9 10 "attribution": "© <a href='https://apps.mapbox.com/feedback/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>" … … 16 17 "tileSize": 512, 17 18 "mapboxToken": "", 19 "maxZoom": 23, 18 20 "zoomOffset": -1, 19 21 "attribution": "© <a href='https://apps.mapbox.com/feedback/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>" … … 26 28 "tileSize": 512, 27 29 "mapboxToken": "", 30 "maxZoom": 23, 28 31 "zoomOffset": -1, 29 32 "attribution": "© <a href='https://apps.mapbox.com/feedback/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>" … … 61 64 "url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", 62 65 "options": { 66 "maxZoom": 19, 63 67 "attribution": "© <a href='https://openstreetmap.org/copyright/'>OpenStreetMap</a>" 64 68 } … … 71 75 "attribution": "© <a href='http://opentopomap.org/'>OpenTopoMap</a> <a href='https://creativecommons.org/licenses/by-sa/3.0/'>(CC-BY-SA)</a> | © <a href='https://openstreetmap.org/copyright/'>OpenStreetMap</a>" 72 76 } 77 }, 78 "spain-ign-topo": { 79 "wms": "true", 80 "label": "Spain IGN Topo", 81 "url": "http://www.ign.es/wms-inspire/mapa-raster", 82 "options": { 83 "layers": "mtn_rasterizado", 84 "format": "image/jpeg", 85 "transparent": "false", 86 "maxZoom": 20, 87 "continuousWorld" : "true", 88 "attribution": "© <a href='http://www.ign.es/ign/main/index.do' target='_blank'>Instituto Geográfico Nacional de España</a>" 89 } 90 }, 91 "france-ign-topo": { 92 "label": "France IGN Topo", 93 "url": "https://wxs.ign.fr/{geoportailToken}/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT={format}&LAYER={layer}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}", 94 "options": { 95 "geoportailToken": "", 96 "format": "image/jpeg", 97 "transparent": "false", 98 "maxZoom": 16, 99 "attribution": "© <a target='_blank' href='https://www.geoportail.gouv.fr/'>Geoportail France</a>", 100 "layer": "GEOGRAPHICALGRIDSYSTEMS.MAPS" 101 } 102 }, 103 "newzealand-topo50": { 104 "label": "NZ Topo 50", 105 "url": "http://tiles-{s}.data-cdn.linz.govt.nz/services;key={LINZToken}/tiles/v4/layer=50767/EPSG:3857/{z}/{x}/{y}.png", 106 "options": { 107 "LINZToken": "", 108 "subdomains":"abcd", 109 "format": "image/jpeg", 110 "transparent": "false", 111 "maxZoom": 16, 112 "attribution": "<a href='http://data.linz.govt.nz'>Sourced from LINZ. CC BY 4.0</a>" 113 } 114 }, 115 "newzealand-topo250": { 116 "label": "NZ Topo 250", 117 "url": "http://tiles-{s}.data-cdn.linz.govt.nz/services;key={LINZToken}/tiles/v4/layer=50798/EPSG:3857/{z}/{x}/{y}.png", 118 "options": { 119 "LINZToken": "", 120 "subdomains":"abcd", 121 "format": "image/jpeg", 122 "transparent": "false", 123 "maxZoom": 16, 124 "attribution": "<a href='http://data.linz.govt.nz'>Sourced from LINZ. CC BY 4.0</a>" 125 } 126 }, 127 "stamen-watercolor": { 128 "label": "Watercolor", 129 "url": "https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg", 130 "options": { 131 "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='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors", 132 "subdomains": "abcd", 133 "minZoom": "1", 134 "maxZoom": "16" 135 } 136 }, 137 "esri-natgeoworldmap": { 138 "label": "Nat Geo Map", 139 "url": "https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}", 140 "options": { 141 "attribution": "Tiles © Esri — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC", 142 "maxZoom": "12" 143 } 73 144 } 74 145 } 146 -
spotmap/tags/0.10.1/includes/class-spotmap-database.php
r2382782 r2479440 60 60 } else if(!empty($filter['date-range'])){ 61 61 if(!empty($filter['date-range']['to'])){ 62 62 63 $date = date_create($filter['date-range']['to']); 64 if(substr($filter['date-range']['to'],0,5) == 'last-'){ 65 $rel_string = substr($filter['date-range']['to'],5); 66 $rel_string = str_replace("-"," ",$rel_string); 67 $date = date_create("@".strtotime('-'.$rel_string)); 68 } 69 63 70 if($date != null){ 64 71 $where .= "AND FROM_UNIXTIME(time) <= '" . date_format( $date,"Y-m-d H:i:s" ) . "' "; … … 67 74 if (!empty($filter['date-range']['from'])){ 68 75 $date = date_create($filter['date-range']['from']); 76 if(substr($filter['date-range']['from'],0,5) == 'last-'){ 77 $rel_string = substr($filter['date-range']['from'],5); 78 $rel_string = str_replace("-"," ",$rel_string); 79 $date = date_create("@".strtotime('-'.$rel_string)); 80 } 69 81 if($date != null){ 70 82 $where .= "AND FROM_UNIXTIME(time) >= '" . date_format( $date,"Y-m-d H:i:s" ) . "' "; -
spotmap/tags/0.10.1/public/class-spotmap-public.php
r2382782 r2479440 10 10 11 11 public function enqueue_styles() { 12 wp_enqueue_style( 'leaflet css', plugin_dir_url( __FILE__ ) . 'leaflet/leaflet.css');12 wp_enqueue_style( 'leaflet', plugin_dir_url( __FILE__ ) . 'leaflet/leaflet.css'); 13 13 wp_enqueue_style( 'custom', plugin_dir_url( __FILE__ ) . 'css/custom.css'); 14 wp_enqueue_style( 'leafletfullscreencss', plugin_dir_url( __FILE__ ) . 'leafletfullscreen/leaflet.fullscreen.css'); 14 wp_enqueue_style( 'leaflet-fullscreen', plugin_dir_url( __FILE__ ) . 'leafletfullscreen/leaflet.fullscreen.css'); 15 wp_enqueue_style( 'leaflet-easybutton', plugin_dir_url( __FILE__ ) . 'leaflet-easy-button/easy-button.css'); 16 wp_enqueue_style( 'dashicon', '/wp-includes/css/dashicons.css'); 15 17 } 16 18 … … 21 23 'spotmap-block', 22 24 plugins_url('js/block.js', __FILE__), 23 ['wp-blocks', 'wp-element'] 25 [ 26 'wp-blocks', 27 'wp-element', 28 'wp-block-editor', 29 'wp-components', 30 'wp-compose', 31 ] 24 32 ); 33 34 wp_localize_script('spotmap-block', 'spotmapjsobj', [ 35 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 36 'maps' => $this->get_maps(), 37 'url' => plugin_dir_url( __FILE__ ), 38 'feeds' => $this->db->get_all_feednames(), 39 ]); 40 41 register_block_type( 'spotmap/spotmap', array( 42 'editor_script' => 'spotmap-block', 43 'render_callback' => [$this, 'show_spotmap_block'], 44 ) ); 25 45 } 26 46 27 47 public function enqueue_scripts(){ 48 wp_enqueue_script('spotmap-handler', plugins_url('js/maphandler.js', __FILE__), ['jquery','moment','lodash'], false, true); 49 wp_localize_script('spotmap-handler', 'spotmapjsobj', [ 50 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 51 'maps' => $this->get_maps(), 52 'url' => plugin_dir_url( __FILE__ ), 53 'feeds' => $this->db->get_all_feednames(), 54 ]); 28 55 wp_enqueue_script('leaflet', plugins_url( 'leaflet/leaflet.js', __FILE__ )); 29 56 wp_enqueue_script('leaflet-fullscreen',plugin_dir_url( __FILE__ ) . 'leafletfullscreen/leaflet.fullscreen.js'); 30 57 wp_enqueue_script('leaflet-gpx',plugin_dir_url( __FILE__ ) . 'leaflet-gpx/gpx.js'); 58 wp_enqueue_script('leaflet-easybutton',plugin_dir_url( __FILE__ ) . 'leaflet-easy-button/easy-button.js'); 31 59 wp_enqueue_script('leaflet-swisstopo', 'https://unpkg.com/leaflet-tilelayer-swiss@2.1.0/dist/Leaflet.TileLayer.Swiss.umd.js'); 32 wp_enqueue_script('spotmap-handler', plugins_url('js/maphandler.js', __FILE__), ['jquery','moment','lodash'], false, true); 33 34 wp_localize_script('spotmap-handler', 'spotmapjsobj', [ 35 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 36 'maps' => $this->get_maps(), 37 'url' => plugin_dir_url( __FILE__ ) 38 39 ]); 60 40 61 } 41 62 // TODO: move to admin class … … 62 83 unset($maps[$name]); 63 84 } 85 else if(isset($data['options']['LINZToken'])){ 86 if(!empty($api_tokens['linz.govt.nz'])){ 87 $data['options']['LINZToken'] = $api_tokens['linz.govt.nz']; 88 continue; 89 } 90 unset($maps[$name]); 91 } 92 else if(isset($data['options']['geoportailToken'])){ 93 if(!empty($api_tokens['geoservices.ign.fr'])){ 94 $data['options']['geoportailToken'] = $api_tokens['geoservices.ign.fr']; 95 continue; 96 } 97 unset($maps[$name]); 98 } 64 99 } 65 100 return ($maps); … … 74 109 } 75 110 function show_point_overview($atts){ 76 $a = shortcode_atts([ 111 error_log("Shortcode init vals: ".wp_json_encode($atts)); 112 $a = array_merge( 113 shortcode_atts([ 77 114 'count'=> 10, 78 115 'types'=>'HELP,HELP-CANCEL,OK,CUSTOM', … … 82 119 'date' => '', 83 120 'date-range-to' => '', 84 'auto-reload' => '0', 85 ], $atts); 121 'auto-reload' => FALSE, 122 'filter-points' => !empty( get_option('spotmap_default_values')['filter-points'] ) ?get_option('spotmap_default_values')['filter-points'] : 5, 123 ], $atts), 124 $atts); 125 // get the keys that don't require a value 126 if(array_key_exists('auto-reload',$atts)){ 127 $a['auto-reload']=TRUE; 128 } 129 error_log("Shortcode after vals: ".wp_json_encode($a)); 86 130 foreach (['types','feeds'] as $value) { 87 131 if(!empty($a[$value]) && !is_array($a[$value])){ … … 103 147 'select' => "type,id,message,local_timezone,feed_name, time", 104 148 'type'=>$a['types'], 149 'filterPoints' => $a['filter-points'], 105 150 'feeds' => $a['feeds'], 106 'date -range' => [151 'dateRange' => [ 107 152 'from' => $a['date-range-from'], 108 153 'to' => $a['date-range-to'] … … 115 160 ]; 116 161 $table_id = "spotmap-table-".mt_rand(); 117 return '<table id='.$table_id.'></table>' 118 .'<script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('. wp_json_encode($options).');spotmap.initTable("'.$table_id.'")})</script>'; 119 120 } 121 122 123 function show_spotmap($atts,$content){ 162 return ' 163 <table id='.$table_id.'></table> 164 <script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('. wp_json_encode($options).');spotmap.initTable("'.$table_id.'")})</script>'; 165 166 } 167 168 public function show_spotmap_block($options){ 169 $options_json = wp_json_encode($options); 170 error_log("BLOCK init vals: ". $options_json); 171 return '<div id="'.$options['mapId'].'" class='. (!empty($a['align']) ? 'align'.$a['align'] : '' ). ' style="z-index: 0;"></div> 172 <script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('.$options_json.');spotmap.initMap()})</script>'; 173 } 174 public function show_spotmap($atts,$content = null){ 175 124 176 error_log("Shortcode init vals: ".wp_json_encode($atts)); 125 177 // $atts['feeds'] = $atts['devices']; 126 $a = shortcode_atts( [ 127 'height' => !empty( get_option('spotmap_default_values')['height'] ) ?get_option('spotmap_default_values')['height'] : 500, 128 'mapcenter' => !empty( get_option('spotmap_default_values')['mapcenter'] ) ?get_option('spotmap_default_values')['mapcenter'] : 'all', 129 'feeds' => $this->db->get_all_feednames(), 130 'width' => !empty(get_option('spotmap_default_values')['width']) ?get_option('spotmap_default_values')['width'] : 'normal', 131 'colors' => !empty(get_option('spotmap_default_values')['color']) ?get_option('spotmap_default_values')['color'] : 'blue,red', 132 'splitlines' => !empty(get_option('spotmap_default_values')['splitlines']) ?get_option('spotmap_default_values')['splitlines'] : '12', 133 'tiny-types' => !empty(get_option('spotmap_default_values')['tiny-types']) ?get_option('spotmap_default_values')['tiny-types'] : NULL, 134 'auto-reload' => '0', 135 'date-range-from' => NULL, 136 'date' => NULL, 137 'date-range-to' => NULL, 138 'gpx-name' => [], 139 'gpx-url' => [], 140 'gpx-color' => ['blue', 'gold', 'red', 'green', 'orange', 'yellow', 'violet'], 141 'maps' => !empty( get_option('spotmap_default_values')['maps'] ) ?get_option('spotmap_default_values')['maps'] : 'openstreetmap,opentopomap', 142 'map-overlays' => !empty( get_option('spotmap_default_values')['map-overlays'] ) ?get_option('spotmap_default_values')['map-overlays'] : NULL, 143 'debug'=> '0', 144 ], $atts ); 178 $a = array_merge( 179 shortcode_atts( [ 180 'height' => !empty( get_option('spotmap_default_values')['height'] ) ?get_option('spotmap_default_values')['height'] : 500, 181 'mapcenter' => !empty( get_option('spotmap_default_values')['mapcenter'] ) ?get_option('spotmap_default_values')['mapcenter'] : 'all', 182 'feeds' => $this->db->get_all_feednames(), 183 'width' => !empty(get_option('spotmap_default_values')['width']) ?get_option('spotmap_default_values')['width'] : 'normal', 184 'colors' => !empty(get_option('spotmap_default_values')['color']) ?get_option('spotmap_default_values')['color'] : 'blue,red', 185 'splitlines' => !empty(get_option('spotmap_default_values')['splitlines']) ?get_option('spotmap_default_values')['splitlines'] : '12', 186 'tiny-types' => !empty(get_option('spotmap_default_values')['tiny-types']) ?get_option('spotmap_default_values')['tiny-types'] : NULL, 187 'auto-reload' => FALSE, 188 'date-range-from' => NULL, 189 'date' => NULL, 190 'date-range-to' => NULL, 191 'gpx-name' => [], 192 'gpx-url' => [], 193 'gpx-color' => ['blue', 'gold', 'red', 'green', 'orange', 'yellow', 'violet'], 194 'maps' => !empty( get_option('spotmap_default_values')['maps'] ) ?get_option('spotmap_default_values')['maps'] : 'openstreetmap,opentopomap', 195 'map-overlays' => !empty( get_option('spotmap_default_values')['map-overlays'] ) ?get_option('spotmap_default_values')['map-overlays'] : NULL, 196 'filter-points' => !empty( get_option('spotmap_default_values')['filter-points'] ) ?get_option('spotmap_default_values')['filter-points'] : 5, 197 'debug'=> FALSE, 198 ], $atts ), 199 $atts); 200 // get the keys that don't require a value 201 if(array_key_exists('auto-reload',$atts)){ 202 $a['auto-reload']=TRUE; 203 } 204 if(array_key_exists('debug',$atts)){ 205 $a['debug']=TRUE; 206 } 207 145 208 146 209 foreach (['feeds','splitlines','colors','gpx-name','gpx-url','gpx-color','maps','map-overlays','tiny-types'] as $value) { … … 195 258 $count_present_numbers = count($a['gpx-color']); 196 259 if($count_present_numbers < $number_of_tracks){ 197 $fillup_array = array_fill($count_present_numbers, $number_of_tracks - $count_present_numbers, $a['gpx-color'][0]); 198 $a['gpx-color'] = array_merge($a['gpx-color'],$fillup_array); 199 260 $fillup_array = []; 261 for ($i = $count_present_numbers; $i < $number_of_tracks; $i++) { 262 $value = $a['gpx-color'][$i % $count_present_numbers]; 263 $a['gpx-color'] = array_merge($a['gpx-color'],[$value]); 264 } 200 265 error_log(print_r($a['gpx-color'],true)); 266 } 267 if(empty($a['gpx-name'])){ 268 $a['gpx-name'][0] = "GPX"; 201 269 } 202 270 if(count($a['gpx-name']) < $number_of_tracks){ … … 206 274 $name = $a['gpx-name'][$key]; 207 275 $gpx[] = [ 208 ' name' => $name,276 'title' => $name, 209 277 'url' => $url, 210 278 "color" => $a['gpx-color'][$key] … … 216 284 $options = wp_json_encode([ 217 285 'feeds' => $a['feeds'], 286 'filterPoints' => $a['filter-points'], 218 287 'styles' => $styles, 219 288 'gpx' => $gpx, … … 237 306 } 238 307 239 return '<div id="'.$map_id.'" style="'.$css.'"></div><script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('.$options.');spotmap.initMap()})</script>'; 308 return ' 309 <div id="'.$map_id.'" style="'.$css.'"></div> 310 <script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('.$options.');spotmap.initMap()})</script>'; 240 311 } 241 312 -
spotmap/tags/0.10.1/public/css/custom.css
r2360204 r2479440 35 35 border-color: rgb(255, 255, 0.85); 36 36 } 37 38 39 40 div.easy-button-container > button.easy-button-button.leaflet-bar-part { 41 background-color: white; 42 padding: 0px; 43 } 44 45 46 span.button-state.state-all.all-active > .dashicons { 47 position: absolute; 48 top: 4px; 49 left: 5px; 50 } -
spotmap/tags/0.10.1/public/js/block.js
r2319128 r2479440 1 1 // block.js 2 ( function( blocks, element, i18n) {2 (function (blocks, element, i18n, blockEditor, components, compose) { 3 3 var el = element.createElement; 4 4 const { __ } = i18n; 5 function renderMap( props ) { 6 return el('div',{}, 7 el('div', {id: 'spotmap-container', 'data-mapcenter': 'all',style: {'height': 500+'px', 'max-width': 100+'%'}}), 8 el('script', {type: 'text/javascript'},'jQuery( document ).ready(function() {initMap();});') 9 ) 10 } 11 blocks.registerBlockType( 'spotmap/spotmap', { 12 title: __('Spotmap'), 5 const { InspectorControls, MediaUpload } = blockEditor; 6 const { FormTokenField } = components; 7 const { SelectControl, TextControl, Button , ToggleControl, ColorPalette, PanelBody, PanelRow, DateTimePicker , RadioGroup, UnitControl, } = components; 8 9 blocks.registerBlockType('spotmap/spotmap', { 10 title: 'Spotmap', 11 supports: { 12 align: ['full','wide'] 13 }, 13 14 icon: 'location-alt', 14 15 category: 'embed', 15 edit: function( props ) { 16 jQuery( document ).ready(function() {initMap();}); 17 return renderMap( props ) 16 edit: function (props) { 17 // if block has just been created 18 if (!props.attributes.height){ 19 // set all default props 20 let mapId = 'spotmap-container-' + Math.random()*10E17; 21 props.setAttributes({ mapId: mapId}); 22 props.setAttributes({ maps: ['opentopomap', 'openstreetmap',] }); 23 props.setAttributes({ feeds: spotmapjsobj.feeds }); 24 props.setAttributes({ styles: lodash.zipObject(spotmapjsobj.feeds,lodash.fill(new Array(spotmapjsobj.feeds.length),{color:'blue',splitLines:'0'})) }); 25 props.setAttributes({ autoReload: false }); 26 props.setAttributes({ debug: false }); 27 props.setAttributes({ height: '500' }); 28 props.setAttributes({ dateRange: {to:'',from:'', }}); 29 props.setAttributes({ mapcenter: 'all' }); 30 props.setAttributes({ gpx: [] }); 31 return [el('div', { 32 id: mapId, 33 style: { 34 class: 'align' + props.attributes.align, 35 'z-index': 0, 36 }, 37 }, '' 38 ),] 39 } 40 var spotmap = new Spotmap (props.attributes); 41 // jQuery("#"+props.attributes.mapId).empty().removeClass(); 42 try { 43 setTimeout(function(){ 44 spotmap.initMap(); 45 },500); 46 } catch (e) { 47 console.log(e) 48 } 49 return [el('div', { 50 id: props.attributes.mapId, 51 style: { 52 'height': props.attributes.height + 'px', 53 class: 'align' + props.attributes.align, 54 'z-index': 0, 55 }, 56 }, '' 57 ), 58 el(InspectorControls, {}, 59 generalSettings(props), 60 feedPanel(props), 61 gpxPanel(props), 62 el(PanelBody, { title: 'Experimental', initialOpen: false }, 63 // /* Toggle Field TODO: use form toggle instead 64 el(PanelRow, {}, 65 el(ToggleControl, 66 { 67 label: 'Debug', 68 onChange: (value) => { 69 props.setAttributes({ debug: value }); 70 }, 71 checked: props.attributes.debug, 72 } 73 ) 74 ), 75 /* Toggle Field */ 76 el(PanelRow, {}, 77 el(ToggleControl, 78 { 79 label: 'automatic reload', 80 onChange: (value) => { 81 props.setAttributes({ 'autoReload': value }); 82 }, 83 checked: props.attributes["autoReload"], 84 help: "If enabled this will create" 85 } 86 ) 87 ), 88 ), 89 )] 18 90 }, 19 20 save: function( props ) { 21 jQuery( document ).ready(function() {initMap();}); 22 return renderMap( props ); 91 attributes: { 92 maps: { 93 type: 'array', 94 }, 95 feeds: { 96 type: 'array', 97 }, 98 styles: { 99 type: 'object', 100 }, 101 dateRange: { 102 type: 'object', 103 }, 104 gpx: { 105 type: 'array', 106 }, 107 mapcenter: { 108 type: 'string', 109 }, 110 height: { 111 type: 'string', 112 }, 113 debug: { 114 type: 'boolean', 115 }, 116 autoReload: { 117 type: 'boolean', 118 }, 119 mapId: { 120 type: 'string', 121 }, 23 122 }, 24 keywords: ['findmespot', 'spot', 'gps', __('map')], 25 } ); 26 } )( 123 keywords: ['findmespot', 'spot', 'gps', 'spotmap', 'gpx', __('map')], 124 }); 125 126 function generalSettings(props){ 127 let panels = []; 128 let general = el(PanelBody, { title: __('General Settings'), initialOpen: false }, 129 el(PanelRow, {}, 130 el(FormTokenField, { 131 label: "Feeds", 132 suggestions: Object.keys(spotmapjsobj.feeds), 133 onChange: (value) => { 134 props.setAttributes({ feeds: value }); 135 }, 136 value: props.attributes.feeds, 137 }) 138 ), 139 140 el(PanelRow, {}, 141 el(FormTokenField, { 142 label: "maps", 143 suggestions: Object.keys(spotmapjsobj.maps), 144 onChange: (value) => { 145 props.setAttributes({ maps: value }); 146 }, 147 value: props.attributes.maps, 148 help: "test" 149 }) 150 ), 151 152 /* Text Field */ 153 el(PanelRow, {}, 154 el(SelectControl, 155 { 156 label: 'Zoom to', 157 onChange: (value) => { 158 props.setAttributes({ mapcenter: value }); 159 }, 160 value: props.attributes.mapcenter, 161 options: [ 162 { label: 'all points', value: 'all' }, 163 { label: 'latest point', value: 'last' }, 164 { label: 'GPX tracks', value: 'gpx' } 165 ], 166 labelPosition: "side", 167 168 } 169 ) 170 ), 171 172 /* Text Field */ 173 el(PanelRow, {}, 174 el(TextControl, 175 { 176 label: 'height', 177 onChange: (value) => { 178 props.setAttributes({ height: value }); 179 }, 180 value: props.attributes.height 181 } 182 ) 183 ), 184 ); 185 panels.push(general); 186 let options = [ 187 { label: 'don\'t filter', value: '' }, 188 { label: 'last week', value: 'last-1-week' }, 189 { label: 'last 10 days', value: 'last-10-days' }, 190 { label: 'last 2 weeks', value: 'last-2-weeks' }, 191 { label: 'last month', value: 'last-1-month' }, 192 { label: 'last year', value: 'last-1-year' }, 193 { label: 'a specific date', value: 'specific' }, 194 ]; 195 // if option is set to sth else (aka custom date) 196 if(!lodash.findKey(options, function(o) { return o.value === props.attributes.dateRange.from}) ){ 197 options[lodash.last(options)] = { label: 'choose new date', value: 'specific' }; 198 options.push({ label: props.attributes.dateRange.from, value: props.attributes.dateRange.from}) 199 } 200 let dateFrom = [ 201 el(PanelRow, {}, 202 el(SelectControl, 203 { 204 label: 'Show points from', 205 onChange: (value) => { 206 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 207 returnArray.from = value; 208 props.setAttributes({ dateRange: returnArray}); 209 }, 210 value: props.attributes.dateRange.from, 211 options: options, 212 labelPosition: "side", 213 } 214 ) 215 ),]; 216 217 if(props.attributes.dateRange.from === 'specific' || !lodash.findKey(options, function(o) { return o.value === props.attributes.dateRange.from})){ 218 dateFrom.push( 219 el(DateTimePicker, 220 { 221 onChange: (currentDate) => { 222 console.log(currentDate); 223 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 224 returnArray.from = currentDate; 225 props.setAttributes({ dateRange: returnArray}); 226 }, 227 currentDate: new Date(), 228 } 229 ) 230 ) 231 } 232 233 options = [ 234 { label: 'don\'t filter', value: '' }, 235 { label: 'last 30 minutes', value: 'last-30-minutes' }, 236 { label: 'last hour', value: 'last-1-hour' }, 237 { label: 'last 2 hours', value: 'last-2-hour' }, 238 { label: 'last day', value: 'last-1-day' }, 239 { label: 'a specific date', value: 'specific' }, 240 ]; 241 if(!lodash.findKey(options, function(o) { return o.value === props.attributes.dateRange.to}) ){ 242 options.push({ label: props.attributes.dateRange.to, value: props.attributes.dateRange.to}) 243 } 244 let dateTo = [ 245 el(PanelRow, {}, 246 el(SelectControl, 247 { 248 label: 'Show points to', 249 onChange: (value) => { 250 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 251 returnArray.to = value; 252 props.setAttributes({ dateRange: returnArray}); 253 }, 254 value: props.attributes.dateRange.to, 255 options: options, 256 labelPosition: "side", 257 } 258 ) 259 ),]; 260 261 if(props.attributes.dateRange.to === 'specific'){ 262 dateTo.push( 263 el(DateTimePicker, 264 { 265 onChange: (currentDate) => { 266 console.log(currentDate); 267 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 268 returnArray.to = currentDate; 269 props.setAttributes({ dateRange: returnArray}); 270 }, 271 currentDate: new Date(), 272 } 273 ) 274 ) 275 } 276 panels.push(el(PanelBody, { title: 'Point Filering', initialOpen: false },dateFrom,dateTo)); 277 return panels; 278 279 } 280 281 function feedPanel(props) { 282 let panel; 283 let panels = []; 284 if( !props.attributes.feeds){ 285 return []; 286 } 287 // console.log(props) 288 for (let i = 0; i < props.attributes.feeds.length; i++) { 289 const feed = props.attributes.feeds[i]; 290 // console.log(feed); 291 let options = []; 292 if (!props.attributes.styles[feed]){ 293 let returnArray = lodash.cloneDeep(props.attributes.styles); 294 returnArray[feed] = {color: 'blue', splitLines: 12}; 295 props.setAttributes({ styles: returnArray}); 296 } 297 options.push(el(PanelRow, {}, 298 el(ColorPalette , { 299 label: "Colors", 300 colors: [ 301 {name: "black", color: "black"}, 302 {name: "blue", color: "blue"}, 303 {name: "gold", color: "gold"}, 304 {name: "green", color: "green"}, 305 {name: "grey", color: "grey"}, 306 {name: "red", color: "red"}, 307 {name: "violet", color: "violet"}, 308 {name: "yellow", color: "yellow"}, 309 ], 310 onChange: (value) => { 311 let returnArray = lodash.cloneDeep(props.attributes.styles); 312 console.log(value,returnArray) 313 returnArray[feed]['color'] = value; 314 props.setAttributes({ styles: returnArray}); 315 }, 316 value: props.attributes.styles[feed]['color'] || 'blue', 317 disableCustomColors: true, 318 }) 319 ), 320 321 // /* Toggle Field TODO: use form toggle instead 322 el(PanelRow, {}, 323 el(ToggleControl, 324 { 325 label: 'connect points wih line', 326 onChange: (value) => { 327 let returnArray = lodash.cloneDeep(props.attributes.styles); 328 console.log(value,returnArray) 329 returnArray[feed]['splitLinesEnabled'] = value; 330 331 if(value && !returnArray[feed]['splitLines'] ){ 332 returnArray[feed]['splitLines'] = 12; 333 } 334 props.setAttributes({ styles: returnArray}); 335 }, 336 checked: props.attributes.styles[feed]['splitLinesEnabled'], 337 } 338 ) 339 )); 340 341 if(props.attributes.styles[feed]['splitLinesEnabled'] === true){ 342 options.push( 343 el(PanelRow, {}, 344 el(TextControl, 345 { 346 label: 'Splitlines', 347 onChange: (value) => { 348 let returnArray = lodash.cloneDeep(props.attributes.styles); 349 console.log(value,returnArray) 350 returnArray[feed]['splitLines'] = value; 351 props.setAttributes({ styles: returnArray}); 352 }, 353 value:props.attributes.styles[feed]['splitLines'], 354 } 355 ) 356 )) 357 } 358 panel = el(PanelBody, { title: feed +' Feed', initialOpen: false }, options); 359 360 361 panels.push(panel); 362 363 } 364 return panels; 365 } 366 function gpxPanel(props) { 367 let panels = []; 368 if( !props.attributes.feeds){ 369 return []; 370 } 371 372 // console.log(feed); 373 let options = []; 374 375 options.push(el(PanelRow, {}, 376 el(ColorPalette , { 377 label: "Colors", 378 colors: [ 379 {name: "black", color: "black"}, 380 {name: "blue", color: "blue"}, 381 {name: "gold", color: "gold"}, 382 {name: "green", color: "green"}, 383 {name: "grey", color: "grey"}, 384 {name: "red", color: "red"}, 385 {name: "violet", color: "violet"}, 386 {name: "yellow", color: "yellow"}, 387 ], 388 onChange: (value) => { 389 let returnArray = []; 390 let gpx = lodash.cloneDeep(props.attributes.gpx); 391 lodash.forEach(gpx,(track)=>{ 392 track.color = value; 393 returnArray.push(track); 394 }) 395 props.setAttributes({ gpx: returnArray}); 396 }, 397 value: props.attributes.gpx[0]? props.attributes.gpx[0].color : 'gold', 398 disableCustomColors: true, 399 }) 400 ), 401 402 el(PanelRow, {}, 403 el(MediaUpload,{ 404 allowedTypes: ['text/xml'], 405 multiple: true, 406 value: props.attributes.gpx.map(entry => entry.id), 407 title: "Choose gpx tracks (Hint: press ctrl to select multiple)", 408 onSelect: function (gpx){ 409 let returnArray = []; 410 lodash.forEach(gpx,(track)=>{ 411 track = lodash.pick(track,['id','url','title']); 412 returnArray.push(track); 413 }) 414 props.setAttributes({ gpx: returnArray}); 415 }, 416 render: function (callback){ 417 return el(Button, 418 {className: "test", 419 onClick: callback.open 420 },"Open Media Library" 421 422 )} 423 }) 424 )); 425 426 427 panels.push(el(PanelBody, { title: 'GPX', initialOpen: false }, options)); 428 429 return panels; 430 } 431 432 })( 27 433 window.wp.blocks, 28 434 window.wp.element, 29 window.wp.i18n 435 window.wp.i18n, 436 window.wp.blockEditor, 437 window.wp.components, 438 window.wp.compose, 30 439 ); 440 441 -
spotmap/tags/0.10.1/public/js/maphandler.js
r2382782 r2479440 5 5 class Spotmap { 6 6 constructor (options) { 7 if(!options.maps || !options.feeds){ 8 console.error("Missing important options!!"); 9 } 7 10 this.options = options; 11 this.mapcenter = {}; 8 12 this.debug("Spotmap obj created."); 9 13 this.debug(this.options); 14 this.map = {}; 10 15 } 11 16 12 17 initMap(){ 13 18 jQuery('#'+ this.options.mapId).height(this.options.height); 19 var self = this; 20 21 // https://github.com/Leaflet/Leaflet/issues/3962 22 var container = L.DomUtil.get(this.options.mapId); 23 if(container != null){ 24 if(lodash.isEqual(this.options,this.oldOptions)){ 25 console.log("SAME!!") 26 } else { 27 console.log("NOT SAME!!") 28 console.log(this.oldOptions) 29 30 } 31 container._leaflet_id = null; 32 jQuery('#'+ this.options.mapId + " > .leaflet-control-container" ).empty(); 33 jQuery('#'+ this.options.mapId + " > .leaflet-pane" ).empty(); 34 } 35 this.oldOptions = this.options; 14 36 this.debug("Lodash version: " + lodash.VERSION); 15 37 … … 26 48 this.map.once('focus', function() { self.map.scrollWheelZoom.enable(); }); 27 49 50 // zoom to bounds btn 51 let zoomOptions = {duration: 2}; 52 let last = L.easyButton({ 53 states: [{ 54 stateName: 'all', 55 icon: '<span class="target">🌐</span>', 56 title: 'show all points', 57 onClick: function(control) { 58 self.map.flyToBounds(self.mapcenter.all,zoomOptions); 59 control.state('last'); 60 } 61 }, { 62 icon: '<span class="target">📍</span>', 63 stateName: 'last', 64 onClick: function(control) { 65 self.map.flyTo(self.mapcenter.last, 14,zoomOptions); 66 if(self.mapcenter.gpx) 67 control.state('gpx'); 68 else 69 control.state('all'); 70 }, 71 title: 'show last point' 72 }, { 73 icon: '<span class="target">👣</span>', 74 stateName: 'gpx', 75 onClick: function(control) { 76 self.map.flyToBounds(self.mapcenter.gpx,zoomOptions); 77 control.state('all'); 78 }, 79 title: 'show gpx tracks' 80 }] 81 }); 82 // the users position 83 let position = L.easyButton('<span class="target">🏡</span>',function(){ 84 self.map.locate({setView: true, maxZoom: 16}); 85 }) 86 // add all btns to map 87 L.easyBar([last,position]).addTo(this.map); 88 28 89 baseLayers[Object.keys(baseLayers)[0]].addTo(this.map); 29 90 var Marker = L.Icon.extend({ … … 64 125 body.feeds = this.options.feeds; 65 126 } 66 var self = this; 67 jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) { 127 this.getPoints(function (response) { 68 128 69 129 var overlays = {}, … … 107 167 overlays[lastFeed] = {"group": L.layerGroup(group), "label":lastFeed}; 108 168 } 109 line = []; 169 if(this.getOption('splitLines', { 'feed': entry.feed_name })){ 170 line = []; 171 } 110 172 group = []; 111 173 feeds.push(entry.feed_name); … … 117 179 line = [[entry.latitude, entry.longitude]]; 118 180 } 119 181 120 182 // a normal iteration adding stuff with default values 121 else {183 else if (this.getOption('splitLines', { 'feed': entry.feed_name })) { 122 184 line.push([entry.latitude, entry.longitude]); 123 185 } 124 125 186 let message = ''; 126 187 let tinyTypes = this.getOption('tinyTypes', { 'feed': entry.feed_name }); … … 146 207 if (entry.battery_status == 'LOW') 147 208 message += 'Battery status is low!' + '</br>'; 148 209 if (entry.hiddenPoints) 210 message += 'There are ' + entry.hiddenPoints.count + ' hidden Points within a radius of '+ entry.hiddenPoints.radius+' meters</br>'; 211 149 212 150 213 var marker = L.marker([entry.latitude, entry.longitude], markerOptions).bindPopup(message); … … 176 239 var gpxOverlays = {}; 177 240 if (self.options.gpx) { 241 // set the gpx overlays, so the gpx will be added first (= below the feeds) 242 let gpxnames = lodash.map(self.options.gpx, 'title'); 243 lodash.forEach(gpxnames,function(title){ 244 gpxOverlays[title] = null; 245 }); 178 246 // reversed so the first one is added last == on top of all others 179 247 for (var i=0; i < self.options.gpx.length; i++) { … … 201 269 // e.target.getLayers()[0].bindPopup(entry.name); 202 270 // console.log(e) 271 let gpxBound = e.target.getBounds(); 272 let point = L.latLng(gpxBound._northEast.lat, gpxBound._northEast.lng); 273 let point2 = L.latLng(gpxBound._southWest.lat, gpxBound._southWest.lng); 274 if (!gpxBounds) { 275 gpxBounds = L.latLngBounds([point, point2]); 276 } else { 277 gpxBounds.extend(L.latLngBounds([point, point2])) 278 } 279 self.mapcenter.gpx = gpxBounds; 203 280 if (self.options.mapcenter == 'gpx' || response.error) { 204 let gpxBound = e.target.getBounds();205 let point = L.latLng(gpxBound._northEast.lat, gpxBound._northEast.lng);206 let point2 = L.latLng(gpxBound._southWest.lat, gpxBound._southWest.lng);207 if (!gpxBounds) {208 gpxBounds = L.latLngBounds([point, point2]);209 } else {210 gpxBounds.extend(L.latLngBounds([point, point2]))211 }212 281 self.map.fitBounds(gpxBounds); 213 282 } 214 283 }).on('addline', function(e) { 215 e.line.bindPopup(entry. name);284 e.line.bindPopup(entry.title); 216 285 }); 217 286 let html = ' <span class="dot" style="position: relative;height: 10px;width: 10px;background-color: ' + color + ';border-radius: 50%;display: inline-block;"></span>'; 218 if (gpxOverlays[entry. name]) {219 gpxOverlays[entry. name].group.addLayer(track);287 if (gpxOverlays[entry.title]) { 288 gpxOverlays[entry.title].group.addLayer(track); 220 289 } else { 221 gpxOverlays[entry. name] = {group: L.layerGroup([track]), 'label': entry.name + html};290 gpxOverlays[entry.title] = {group: L.layerGroup([track]), 'label': entry.title + html}; 222 291 } 223 292 … … 225 294 } 226 295 // reverse order in menu to have the first element added last but shown on the menu first again 227 lodash.forEachRight(gpxOverlays, function(value, key) { overlays[key] = value });296 lodash.forEachRight(gpxOverlays, function(value,entryName) { overlays[entryName] = value }); 228 297 var displayOverlays = {}; 229 298 for (let key in overlays) { … … 244 313 } 245 314 } 246 if (self.options.mapcenter == 'all') { 247 var group = new L.featureGroup(all); 248 let bounds = group.getBounds(); 249 self.map.fitBounds(bounds); 250 } else if (self.options.mapcenter == 'last') { 251 var lastPoint; 252 var time = 0; 253 if (response.length > 0 && !response.error){ 254 response.forEach(function(entry, index) { 255 if (time < entry.unixtime) { 256 time = entry.unixtime; 257 lastPoint = [entry.latitude, entry.longitude]; 258 } 259 }); 315 var group = new L.featureGroup(all); 316 let bounds = group == undefined ? undefined : group.getBounds(); 317 self.mapcenter.all = bounds; 318 319 320 var lastPoint; 321 var time = 0; 322 if (response.length > 0 && !response.error){ 323 response.forEach(function(entry, index) { 324 if (time < entry.unixtime) { 325 time = entry.unixtime; 326 lastPoint = [entry.latitude, entry.longitude]; 327 } 328 }); 329 } 330 self.mapcenter.last = lastPoint; 331 // error key is only set on an empty response 332 if(!response.hasOwnProperty("error")){ 333 if(self.options.mapcenter == 'gpx' && self.options.gpx.length == 0){ 334 self.options.mapcenter = 'all'; 335 } 336 if (self.options.mapcenter == 'all') { 337 self.map.fitBounds(bounds); 338 } else if (self.options.mapcenter == 'last') { 260 339 self.map.setView([lastPoint[0], lastPoint[1]], 13); 261 340 } 262 263 }341 } 342 264 343 for (let index in self.options.mapOverlays) { 265 344 let overlay = self.options.mapOverlays[index]; … … 270 349 } 271 350 } 272 351 352 // hide map option, if only one 273 353 if(Object.keys(baseLayers).length == 1){ 274 354 baseLayers = {}; … … 276 356 if (Object.keys(displayOverlays).length == 1) { 277 357 displayOverlays[Object.keys(displayOverlays)[0]].addTo(self.map); 278 L.control.layers(baseLayers).addTo(self.map); 358 if(Object.keys(baseLayers).length > 1) 359 L.control.layers(baseLayers).addTo(self.map); 279 360 } else { 280 361 L.control.layers(baseLayers, displayOverlays).addTo(self.map); … … 308 389 body.groupBy = 'feed_name'; 309 390 body.orderBy = 'time DESC'; 310 jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) { 391 self.getPoints(function (response) { 392 if(response.error){ 393 return; 394 } 311 395 // debug("Checking for new points ...",self.options.debug); 312 396 response.forEach(function(entry, index) { … … 337 421 if (entry.battery_status == 'LOW') 338 422 message += 'Battery status is low!' + '</br>'; 423 if (entry.hiddenPoints) 424 message += 'There are ' + entry.hiddenPoints.count + ' hidden Points within a radius of '+ entry.hiddenPoints.radius+' meters</br>'; 339 425 340 426 let marker = L.marker([entry.latitude, entry.longitude], markerOptions).bindPopup(message); … … 346 432 }); 347 433 348 } );434 },{body: body, filter: self.options.filterPoints}); 349 435 }, 30000); 350 436 } 351 } );352 } 437 },{body: body, filter: this.options.filterPoints}); 438 }world 353 439 354 440 getOption(option, config) { … … 364 450 return baseLayers; 365 451 } 366 for (let mapName in spotmapjsobj.maps) { 367 if (this.options.maps.includes(mapName)) { 452 for (let mapName in this.options.maps) { 453 mapName = this.options.maps[mapName]; 454 if (lodash.keys(spotmapjsobj.maps).includes(mapName)) { 368 455 let map = spotmapjsobj.maps[mapName]; 369 baseLayers[map.label] = L.tileLayer(map.url, map.options); 456 if(map.wms){ 457 baseLayers[map.label] = L.tileLayer.wms(map.url, map.options); 458 } else { 459 baseLayers[map.label] = L.tileLayer(map.url, map.options); 460 } 370 461 } 371 462 } … … 386 477 } 387 478 if (option == 'splitLines' && config.feed) { 479 if (this.options.styles[config.feed] && this.options.styles[config.feed].splitLinesEnabled && this.options.styles[config.feed].splitLinesEnabled === false) 480 return false; 388 481 if (this.options.styles[config.feed] && this.options.styles[config.feed].splitLines) 389 482 return this.options.styles[config.feed].splitLines; 390 return 'false';483 return false; 391 484 } 392 485 if (option == 'tinyTypes' && config.feed) { … … 397 490 } 398 491 debug(message){ 399 if(this.options .debug)492 if(this.options && this.options.debug) 400 493 console.log(message) 401 494 } 402 495 496 getPoints(callback,options){ 497 jQuery.post(spotmapjsobj.ajaxUrl, options.body, function (response){ 498 // filter out close by points, never filter if group option is set 499 if(options.filter && ! options.body.groupBy && !response.error){ 500 let indexesToBeDeleted = []; 501 response = lodash.each(response, function (element, index){ 502 // if we spliced the array, loop to the end with undefinded elements 503 if(!element) 504 return 505 // continue so we can check against another value 506 if(index == 0) 507 return; 508 let lastPoint; 509 for (let i = index; i <= response.length; i++) { 510 if(!lodash.includes(indexesToBeDeleted, index)){ 511 lastPoint = [response[index-i].latitude,response[index-i].longitude]; 512 response[index-i].hiddenPoints = {count: i,radius: options.filter}; 513 break; 514 } 515 } 516 let dif = L.latLng(element.latitude, element.longitude).distanceTo(lastPoint); 517 // console.log(dif) 518 if(dif < options.filter){ 519 // indexesToBeDeleted.push(index); 520 response[index] = undefined; 521 } 522 }); 523 // lodash.each(indexesToBeDeleted,function(element){ 524 // response[element] = undefined; 525 // }); 526 response = response.filter(function( element ) { 527 return element !== undefined; 528 }); 529 530 } 531 callback(response); 532 }); 533 } 403 534 initTable(id){ 404 535 // define obj to post data … … 406 537 'action': 'get_positions', 407 538 'date-range': this.options.dateRange, 539 'type': this.options.type, 408 540 'date': this.options.date, 409 541 'orderBy': this.options.orderBy, … … 415 547 } 416 548 var self = this; 417 jQuery.post(spotmapjsobj.ajaxUrl, body,function (response) {549 this.getPoints(function (response) { 418 550 let headerElements = ["Type", "Message", "Time"]; 419 551 let hasLocaltime = false; … … 429 561 row += '<tr>' 430 562 table.append(jQuery(row)); 431 lodash.forEach(response,function(entry){ 432 if(!entry.local_timezone){ 433 entry.localdate = ''; 434 entry.localtime = ''; 435 } 436 if(!entry.message) 437 entry.message = ''; 438 let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>"; 439 if (hasLocaltime) 440 row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>"; 441 row += "</tr>"; 442 table.append(jQuery(row)) 443 }); 563 if(response.error == true){ 564 self.options.autoReload = false; 565 table.append(jQuery("<tr><td></td><td>No data found</td><td></td></tr>")) 566 return; 567 } else 568 lodash.forEach(response,function(entry){ 569 if(!entry.local_timezone){ 570 entry.localdate = ''; 571 entry.localtime = ''; 572 } 573 if(!entry.message) 574 entry.message = ''; 575 let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>"; 576 if (hasLocaltime) 577 row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>"; 578 row += "</tr>"; 579 table.append(jQuery(row)) 580 }); 444 581 if(self.options.autoReload == true){ 445 582 var oldResponse = response; 446 583 var refresh = setInterval(function(){ 447 jQuery.post(spotmapjsobj.ajaxUrl, body,function (response) {584 self.getPoints(function (response) { 448 585 if( lodash.head(oldResponse).unixtime < lodash.head(response).unixtime){ 449 586 var table = jQuery('#' + id); … … 475 612 }); 476 613 } else { 477 console.log('same response!');614 self.debug('same response!'); 478 615 } 479 616 480 } );617 },{body: body, filter: self.options.filterPoints}); 481 618 }, 10000); 482 619 } 483 } );620 },{body: body, filter: this.options.filterPoints}); 484 621 } 485 622 } -
spotmap/tags/0.10.1/public/leafletfullscreen/leaflet.fullscreen.css
r2241659 r2479440 31 31 z-index:99999; 32 32 } 33 34 @media 35 (-webkit-min-device-pixel-ratio:2), 36 (min-resolution:192dpi) { 37 .leaflet-control-fullscreen a { 38 background-image:url(fullscreen@2x.png); 39 } 40 } 33 -
spotmap/tags/0.10.1/readme.txt
r2382782 r2479440 6 6 License URI: http://www.gnu.org/licenses/gpl-2.0.html 7 7 Requires at least: 5.3 8 Tested up to: 5. 58 Tested up to: 5.6 9 9 10 10 See your Spot device movements on an embedded map inside your Blog! 🗺 Add GPX tracks, routes and waypoints to see a planned route. … … 15 15 Your Wordpress Site will store all positions ever sent. It checks for new positions every 2.5 minutes. 16 16 It supports different devices (They can even belong to different accounts). 17 18 🆕 Support of Gutenberg block editor. Just type `/spotmap` and open the settings on the right. 17 19 18 20 With a shortcode you can add an embedded map to your post or page. By default it will show all positions ever sent. … … 138 140 139 141 ## Changelog 142 = 0.10.1 = 143 Full Gutenberg Block support 144 added NZtopomap 145 added France IGN Topo map token 146 140 147 = 0.9.1 = 141 142 148 Fix Gutenberg editor issue 143 149 spotmessages supports auto update … … 145 151 146 152 = 0.9 = 147 148 If you upgrade to this version from a previous one please delete and reinstall the plugin.149 WARNING: all data will be lost. if you like to upgrade please post in the support forum.150 151 153 - new shortcode to show table of messages 152 154 - add gpx overlays -
spotmap/tags/0.10.1/spotmap.php
r2382782 r2479440 4 4 * Plugin URI: https://github.com/techtimo/spotmap 5 5 * Description: Add an embedded map that shows the movement of a Spot device 6 * Version: 0. 9.16 * Version: 0.10.1 7 7 * Author: Timo Giese 8 8 * Author URI: https://github.com/techtimo … … 11 11 * Text Domain: spotmap 12 12 * Domain Path: /languages 13 * GitHub Plugin URI: https://github.com/techtimo/spotmap 13 14 */ 14 15 -
spotmap/trunk/admin/class-spotmap-admin.php
r2382782 r2479440 100 100 'spotmap-thirdparties-group' 101 101 ); 102 foreach (['mapbox','thunderforest','timezonedb' ] as $index) {102 foreach (['mapbox','thunderforest','timezonedb','linz.govt.nz','geoservices.ign.fr'] as $index) { 103 103 $value = isset( get_option('spotmap_api_tokens')[$index] ) ? get_option('spotmap_api_tokens')[$index] : ''; 104 104 add_settings_field( -
spotmap/trunk/config/maps.json
r2360204 r2479440 6 6 "tileSize": 512, 7 7 "mapboxToken": "", 8 "maxZoom": 23, 8 9 "zoomOffset": -1, 9 10 "attribution": "© <a href='https://apps.mapbox.com/feedback/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>" … … 16 17 "tileSize": 512, 17 18 "mapboxToken": "", 19 "maxZoom": 23, 18 20 "zoomOffset": -1, 19 21 "attribution": "© <a href='https://apps.mapbox.com/feedback/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>" … … 26 28 "tileSize": 512, 27 29 "mapboxToken": "", 30 "maxZoom": 23, 28 31 "zoomOffset": -1, 29 32 "attribution": "© <a href='https://apps.mapbox.com/feedback/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>" … … 61 64 "url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", 62 65 "options": { 66 "maxZoom": 19, 63 67 "attribution": "© <a href='https://openstreetmap.org/copyright/'>OpenStreetMap</a>" 64 68 } … … 71 75 "attribution": "© <a href='http://opentopomap.org/'>OpenTopoMap</a> <a href='https://creativecommons.org/licenses/by-sa/3.0/'>(CC-BY-SA)</a> | © <a href='https://openstreetmap.org/copyright/'>OpenStreetMap</a>" 72 76 } 77 }, 78 "spain-ign-topo": { 79 "wms": "true", 80 "label": "Spain IGN Topo", 81 "url": "http://www.ign.es/wms-inspire/mapa-raster", 82 "options": { 83 "layers": "mtn_rasterizado", 84 "format": "image/jpeg", 85 "transparent": "false", 86 "maxZoom": 20, 87 "continuousWorld" : "true", 88 "attribution": "© <a href='http://www.ign.es/ign/main/index.do' target='_blank'>Instituto Geográfico Nacional de España</a>" 89 } 90 }, 91 "france-ign-topo": { 92 "label": "France IGN Topo", 93 "url": "https://wxs.ign.fr/{geoportailToken}/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT={format}&LAYER={layer}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}", 94 "options": { 95 "geoportailToken": "", 96 "format": "image/jpeg", 97 "transparent": "false", 98 "maxZoom": 16, 99 "attribution": "© <a target='_blank' href='https://www.geoportail.gouv.fr/'>Geoportail France</a>", 100 "layer": "GEOGRAPHICALGRIDSYSTEMS.MAPS" 101 } 102 }, 103 "newzealand-topo50": { 104 "label": "NZ Topo 50", 105 "url": "http://tiles-{s}.data-cdn.linz.govt.nz/services;key={LINZToken}/tiles/v4/layer=50767/EPSG:3857/{z}/{x}/{y}.png", 106 "options": { 107 "LINZToken": "", 108 "subdomains":"abcd", 109 "format": "image/jpeg", 110 "transparent": "false", 111 "maxZoom": 16, 112 "attribution": "<a href='http://data.linz.govt.nz'>Sourced from LINZ. CC BY 4.0</a>" 113 } 114 }, 115 "newzealand-topo250": { 116 "label": "NZ Topo 250", 117 "url": "http://tiles-{s}.data-cdn.linz.govt.nz/services;key={LINZToken}/tiles/v4/layer=50798/EPSG:3857/{z}/{x}/{y}.png", 118 "options": { 119 "LINZToken": "", 120 "subdomains":"abcd", 121 "format": "image/jpeg", 122 "transparent": "false", 123 "maxZoom": 16, 124 "attribution": "<a href='http://data.linz.govt.nz'>Sourced from LINZ. CC BY 4.0</a>" 125 } 126 }, 127 "stamen-watercolor": { 128 "label": "Watercolor", 129 "url": "https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg", 130 "options": { 131 "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='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors", 132 "subdomains": "abcd", 133 "minZoom": "1", 134 "maxZoom": "16" 135 } 136 }, 137 "esri-natgeoworldmap": { 138 "label": "Nat Geo Map", 139 "url": "https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}", 140 "options": { 141 "attribution": "Tiles © Esri — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC", 142 "maxZoom": "12" 143 } 73 144 } 74 145 } 146 -
spotmap/trunk/includes/class-spotmap-database.php
r2382782 r2479440 60 60 } else if(!empty($filter['date-range'])){ 61 61 if(!empty($filter['date-range']['to'])){ 62 62 63 $date = date_create($filter['date-range']['to']); 64 if(substr($filter['date-range']['to'],0,5) == 'last-'){ 65 $rel_string = substr($filter['date-range']['to'],5); 66 $rel_string = str_replace("-"," ",$rel_string); 67 $date = date_create("@".strtotime('-'.$rel_string)); 68 } 69 63 70 if($date != null){ 64 71 $where .= "AND FROM_UNIXTIME(time) <= '" . date_format( $date,"Y-m-d H:i:s" ) . "' "; … … 67 74 if (!empty($filter['date-range']['from'])){ 68 75 $date = date_create($filter['date-range']['from']); 76 if(substr($filter['date-range']['from'],0,5) == 'last-'){ 77 $rel_string = substr($filter['date-range']['from'],5); 78 $rel_string = str_replace("-"," ",$rel_string); 79 $date = date_create("@".strtotime('-'.$rel_string)); 80 } 69 81 if($date != null){ 70 82 $where .= "AND FROM_UNIXTIME(time) >= '" . date_format( $date,"Y-m-d H:i:s" ) . "' "; -
spotmap/trunk/public/class-spotmap-public.php
r2382782 r2479440 10 10 11 11 public function enqueue_styles() { 12 wp_enqueue_style( 'leaflet css', plugin_dir_url( __FILE__ ) . 'leaflet/leaflet.css');12 wp_enqueue_style( 'leaflet', plugin_dir_url( __FILE__ ) . 'leaflet/leaflet.css'); 13 13 wp_enqueue_style( 'custom', plugin_dir_url( __FILE__ ) . 'css/custom.css'); 14 wp_enqueue_style( 'leafletfullscreencss', plugin_dir_url( __FILE__ ) . 'leafletfullscreen/leaflet.fullscreen.css'); 14 wp_enqueue_style( 'leaflet-fullscreen', plugin_dir_url( __FILE__ ) . 'leafletfullscreen/leaflet.fullscreen.css'); 15 wp_enqueue_style( 'leaflet-easybutton', plugin_dir_url( __FILE__ ) . 'leaflet-easy-button/easy-button.css'); 16 wp_enqueue_style( 'dashicon', '/wp-includes/css/dashicons.css'); 15 17 } 16 18 … … 21 23 'spotmap-block', 22 24 plugins_url('js/block.js', __FILE__), 23 ['wp-blocks', 'wp-element'] 25 [ 26 'wp-blocks', 27 'wp-element', 28 'wp-block-editor', 29 'wp-components', 30 'wp-compose', 31 ] 24 32 ); 33 34 wp_localize_script('spotmap-block', 'spotmapjsobj', [ 35 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 36 'maps' => $this->get_maps(), 37 'url' => plugin_dir_url( __FILE__ ), 38 'feeds' => $this->db->get_all_feednames(), 39 ]); 40 41 register_block_type( 'spotmap/spotmap', array( 42 'editor_script' => 'spotmap-block', 43 'render_callback' => [$this, 'show_spotmap_block'], 44 ) ); 25 45 } 26 46 27 47 public function enqueue_scripts(){ 48 wp_enqueue_script('spotmap-handler', plugins_url('js/maphandler.js', __FILE__), ['jquery','moment','lodash'], false, true); 49 wp_localize_script('spotmap-handler', 'spotmapjsobj', [ 50 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 51 'maps' => $this->get_maps(), 52 'url' => plugin_dir_url( __FILE__ ), 53 'feeds' => $this->db->get_all_feednames(), 54 ]); 28 55 wp_enqueue_script('leaflet', plugins_url( 'leaflet/leaflet.js', __FILE__ )); 29 56 wp_enqueue_script('leaflet-fullscreen',plugin_dir_url( __FILE__ ) . 'leafletfullscreen/leaflet.fullscreen.js'); 30 57 wp_enqueue_script('leaflet-gpx',plugin_dir_url( __FILE__ ) . 'leaflet-gpx/gpx.js'); 58 wp_enqueue_script('leaflet-easybutton',plugin_dir_url( __FILE__ ) . 'leaflet-easy-button/easy-button.js'); 31 59 wp_enqueue_script('leaflet-swisstopo', 'https://unpkg.com/leaflet-tilelayer-swiss@2.1.0/dist/Leaflet.TileLayer.Swiss.umd.js'); 32 wp_enqueue_script('spotmap-handler', plugins_url('js/maphandler.js', __FILE__), ['jquery','moment','lodash'], false, true); 33 34 wp_localize_script('spotmap-handler', 'spotmapjsobj', [ 35 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 36 'maps' => $this->get_maps(), 37 'url' => plugin_dir_url( __FILE__ ) 38 39 ]); 60 40 61 } 41 62 // TODO: move to admin class … … 62 83 unset($maps[$name]); 63 84 } 85 else if(isset($data['options']['LINZToken'])){ 86 if(!empty($api_tokens['linz.govt.nz'])){ 87 $data['options']['LINZToken'] = $api_tokens['linz.govt.nz']; 88 continue; 89 } 90 unset($maps[$name]); 91 } 92 else if(isset($data['options']['geoportailToken'])){ 93 if(!empty($api_tokens['geoservices.ign.fr'])){ 94 $data['options']['geoportailToken'] = $api_tokens['geoservices.ign.fr']; 95 continue; 96 } 97 unset($maps[$name]); 98 } 64 99 } 65 100 return ($maps); … … 74 109 } 75 110 function show_point_overview($atts){ 76 $a = shortcode_atts([ 111 error_log("Shortcode init vals: ".wp_json_encode($atts)); 112 $a = array_merge( 113 shortcode_atts([ 77 114 'count'=> 10, 78 115 'types'=>'HELP,HELP-CANCEL,OK,CUSTOM', … … 82 119 'date' => '', 83 120 'date-range-to' => '', 84 'auto-reload' => '0', 85 ], $atts); 121 'auto-reload' => FALSE, 122 'filter-points' => !empty( get_option('spotmap_default_values')['filter-points'] ) ?get_option('spotmap_default_values')['filter-points'] : 5, 123 ], $atts), 124 $atts); 125 // get the keys that don't require a value 126 if(array_key_exists('auto-reload',$atts)){ 127 $a['auto-reload']=TRUE; 128 } 129 error_log("Shortcode after vals: ".wp_json_encode($a)); 86 130 foreach (['types','feeds'] as $value) { 87 131 if(!empty($a[$value]) && !is_array($a[$value])){ … … 103 147 'select' => "type,id,message,local_timezone,feed_name, time", 104 148 'type'=>$a['types'], 149 'filterPoints' => $a['filter-points'], 105 150 'feeds' => $a['feeds'], 106 'date -range' => [151 'dateRange' => [ 107 152 'from' => $a['date-range-from'], 108 153 'to' => $a['date-range-to'] … … 115 160 ]; 116 161 $table_id = "spotmap-table-".mt_rand(); 117 return '<table id='.$table_id.'></table>' 118 .'<script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('. wp_json_encode($options).');spotmap.initTable("'.$table_id.'")})</script>'; 119 120 } 121 122 123 function show_spotmap($atts,$content){ 162 return ' 163 <table id='.$table_id.'></table> 164 <script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('. wp_json_encode($options).');spotmap.initTable("'.$table_id.'")})</script>'; 165 166 } 167 168 public function show_spotmap_block($options){ 169 $options_json = wp_json_encode($options); 170 error_log("BLOCK init vals: ". $options_json); 171 return '<div id="'.$options['mapId'].'" class='. (!empty($a['align']) ? 'align'.$a['align'] : '' ). ' style="z-index: 0;"></div> 172 <script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('.$options_json.');spotmap.initMap()})</script>'; 173 } 174 public function show_spotmap($atts,$content = null){ 175 124 176 error_log("Shortcode init vals: ".wp_json_encode($atts)); 125 177 // $atts['feeds'] = $atts['devices']; 126 $a = shortcode_atts( [ 127 'height' => !empty( get_option('spotmap_default_values')['height'] ) ?get_option('spotmap_default_values')['height'] : 500, 128 'mapcenter' => !empty( get_option('spotmap_default_values')['mapcenter'] ) ?get_option('spotmap_default_values')['mapcenter'] : 'all', 129 'feeds' => $this->db->get_all_feednames(), 130 'width' => !empty(get_option('spotmap_default_values')['width']) ?get_option('spotmap_default_values')['width'] : 'normal', 131 'colors' => !empty(get_option('spotmap_default_values')['color']) ?get_option('spotmap_default_values')['color'] : 'blue,red', 132 'splitlines' => !empty(get_option('spotmap_default_values')['splitlines']) ?get_option('spotmap_default_values')['splitlines'] : '12', 133 'tiny-types' => !empty(get_option('spotmap_default_values')['tiny-types']) ?get_option('spotmap_default_values')['tiny-types'] : NULL, 134 'auto-reload' => '0', 135 'date-range-from' => NULL, 136 'date' => NULL, 137 'date-range-to' => NULL, 138 'gpx-name' => [], 139 'gpx-url' => [], 140 'gpx-color' => ['blue', 'gold', 'red', 'green', 'orange', 'yellow', 'violet'], 141 'maps' => !empty( get_option('spotmap_default_values')['maps'] ) ?get_option('spotmap_default_values')['maps'] : 'openstreetmap,opentopomap', 142 'map-overlays' => !empty( get_option('spotmap_default_values')['map-overlays'] ) ?get_option('spotmap_default_values')['map-overlays'] : NULL, 143 'debug'=> '0', 144 ], $atts ); 178 $a = array_merge( 179 shortcode_atts( [ 180 'height' => !empty( get_option('spotmap_default_values')['height'] ) ?get_option('spotmap_default_values')['height'] : 500, 181 'mapcenter' => !empty( get_option('spotmap_default_values')['mapcenter'] ) ?get_option('spotmap_default_values')['mapcenter'] : 'all', 182 'feeds' => $this->db->get_all_feednames(), 183 'width' => !empty(get_option('spotmap_default_values')['width']) ?get_option('spotmap_default_values')['width'] : 'normal', 184 'colors' => !empty(get_option('spotmap_default_values')['color']) ?get_option('spotmap_default_values')['color'] : 'blue,red', 185 'splitlines' => !empty(get_option('spotmap_default_values')['splitlines']) ?get_option('spotmap_default_values')['splitlines'] : '12', 186 'tiny-types' => !empty(get_option('spotmap_default_values')['tiny-types']) ?get_option('spotmap_default_values')['tiny-types'] : NULL, 187 'auto-reload' => FALSE, 188 'date-range-from' => NULL, 189 'date' => NULL, 190 'date-range-to' => NULL, 191 'gpx-name' => [], 192 'gpx-url' => [], 193 'gpx-color' => ['blue', 'gold', 'red', 'green', 'orange', 'yellow', 'violet'], 194 'maps' => !empty( get_option('spotmap_default_values')['maps'] ) ?get_option('spotmap_default_values')['maps'] : 'openstreetmap,opentopomap', 195 'map-overlays' => !empty( get_option('spotmap_default_values')['map-overlays'] ) ?get_option('spotmap_default_values')['map-overlays'] : NULL, 196 'filter-points' => !empty( get_option('spotmap_default_values')['filter-points'] ) ?get_option('spotmap_default_values')['filter-points'] : 5, 197 'debug'=> FALSE, 198 ], $atts ), 199 $atts); 200 // get the keys that don't require a value 201 if(array_key_exists('auto-reload',$atts)){ 202 $a['auto-reload']=TRUE; 203 } 204 if(array_key_exists('debug',$atts)){ 205 $a['debug']=TRUE; 206 } 207 145 208 146 209 foreach (['feeds','splitlines','colors','gpx-name','gpx-url','gpx-color','maps','map-overlays','tiny-types'] as $value) { … … 195 258 $count_present_numbers = count($a['gpx-color']); 196 259 if($count_present_numbers < $number_of_tracks){ 197 $fillup_array = array_fill($count_present_numbers, $number_of_tracks - $count_present_numbers, $a['gpx-color'][0]); 198 $a['gpx-color'] = array_merge($a['gpx-color'],$fillup_array); 199 260 $fillup_array = []; 261 for ($i = $count_present_numbers; $i < $number_of_tracks; $i++) { 262 $value = $a['gpx-color'][$i % $count_present_numbers]; 263 $a['gpx-color'] = array_merge($a['gpx-color'],[$value]); 264 } 200 265 error_log(print_r($a['gpx-color'],true)); 266 } 267 if(empty($a['gpx-name'])){ 268 $a['gpx-name'][0] = "GPX"; 201 269 } 202 270 if(count($a['gpx-name']) < $number_of_tracks){ … … 206 274 $name = $a['gpx-name'][$key]; 207 275 $gpx[] = [ 208 ' name' => $name,276 'title' => $name, 209 277 'url' => $url, 210 278 "color" => $a['gpx-color'][$key] … … 216 284 $options = wp_json_encode([ 217 285 'feeds' => $a['feeds'], 286 'filterPoints' => $a['filter-points'], 218 287 'styles' => $styles, 219 288 'gpx' => $gpx, … … 237 306 } 238 307 239 return '<div id="'.$map_id.'" style="'.$css.'"></div><script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('.$options.');spotmap.initMap()})</script>'; 308 return ' 309 <div id="'.$map_id.'" style="'.$css.'"></div> 310 <script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('.$options.');spotmap.initMap()})</script>'; 240 311 } 241 312 -
spotmap/trunk/public/css/custom.css
r2360204 r2479440 35 35 border-color: rgb(255, 255, 0.85); 36 36 } 37 38 39 40 div.easy-button-container > button.easy-button-button.leaflet-bar-part { 41 background-color: white; 42 padding: 0px; 43 } 44 45 46 span.button-state.state-all.all-active > .dashicons { 47 position: absolute; 48 top: 4px; 49 left: 5px; 50 } -
spotmap/trunk/public/js/block.js
r2319128 r2479440 1 1 // block.js 2 ( function( blocks, element, i18n) {2 (function (blocks, element, i18n, blockEditor, components, compose) { 3 3 var el = element.createElement; 4 4 const { __ } = i18n; 5 function renderMap( props ) { 6 return el('div',{}, 7 el('div', {id: 'spotmap-container', 'data-mapcenter': 'all',style: {'height': 500+'px', 'max-width': 100+'%'}}), 8 el('script', {type: 'text/javascript'},'jQuery( document ).ready(function() {initMap();});') 9 ) 10 } 11 blocks.registerBlockType( 'spotmap/spotmap', { 12 title: __('Spotmap'), 5 const { InspectorControls, MediaUpload } = blockEditor; 6 const { FormTokenField } = components; 7 const { SelectControl, TextControl, Button , ToggleControl, ColorPalette, PanelBody, PanelRow, DateTimePicker , RadioGroup, UnitControl, } = components; 8 9 blocks.registerBlockType('spotmap/spotmap', { 10 title: 'Spotmap', 11 supports: { 12 align: ['full','wide'] 13 }, 13 14 icon: 'location-alt', 14 15 category: 'embed', 15 edit: function( props ) { 16 jQuery( document ).ready(function() {initMap();}); 17 return renderMap( props ) 16 edit: function (props) { 17 // if block has just been created 18 if (!props.attributes.height){ 19 // set all default props 20 let mapId = 'spotmap-container-' + Math.random()*10E17; 21 props.setAttributes({ mapId: mapId}); 22 props.setAttributes({ maps: ['opentopomap', 'openstreetmap',] }); 23 props.setAttributes({ feeds: spotmapjsobj.feeds }); 24 props.setAttributes({ styles: lodash.zipObject(spotmapjsobj.feeds,lodash.fill(new Array(spotmapjsobj.feeds.length),{color:'blue',splitLines:'0'})) }); 25 props.setAttributes({ autoReload: false }); 26 props.setAttributes({ debug: false }); 27 props.setAttributes({ height: '500' }); 28 props.setAttributes({ dateRange: {to:'',from:'', }}); 29 props.setAttributes({ mapcenter: 'all' }); 30 props.setAttributes({ gpx: [] }); 31 return [el('div', { 32 id: mapId, 33 style: { 34 class: 'align' + props.attributes.align, 35 'z-index': 0, 36 }, 37 }, '' 38 ),] 39 } 40 var spotmap = new Spotmap (props.attributes); 41 // jQuery("#"+props.attributes.mapId).empty().removeClass(); 42 try { 43 setTimeout(function(){ 44 spotmap.initMap(); 45 },500); 46 } catch (e) { 47 console.log(e) 48 } 49 return [el('div', { 50 id: props.attributes.mapId, 51 style: { 52 'height': props.attributes.height + 'px', 53 class: 'align' + props.attributes.align, 54 'z-index': 0, 55 }, 56 }, '' 57 ), 58 el(InspectorControls, {}, 59 generalSettings(props), 60 feedPanel(props), 61 gpxPanel(props), 62 el(PanelBody, { title: 'Experimental', initialOpen: false }, 63 // /* Toggle Field TODO: use form toggle instead 64 el(PanelRow, {}, 65 el(ToggleControl, 66 { 67 label: 'Debug', 68 onChange: (value) => { 69 props.setAttributes({ debug: value }); 70 }, 71 checked: props.attributes.debug, 72 } 73 ) 74 ), 75 /* Toggle Field */ 76 el(PanelRow, {}, 77 el(ToggleControl, 78 { 79 label: 'automatic reload', 80 onChange: (value) => { 81 props.setAttributes({ 'autoReload': value }); 82 }, 83 checked: props.attributes["autoReload"], 84 help: "If enabled this will create" 85 } 86 ) 87 ), 88 ), 89 )] 18 90 }, 19 20 save: function( props ) { 21 jQuery( document ).ready(function() {initMap();}); 22 return renderMap( props ); 91 attributes: { 92 maps: { 93 type: 'array', 94 }, 95 feeds: { 96 type: 'array', 97 }, 98 styles: { 99 type: 'object', 100 }, 101 dateRange: { 102 type: 'object', 103 }, 104 gpx: { 105 type: 'array', 106 }, 107 mapcenter: { 108 type: 'string', 109 }, 110 height: { 111 type: 'string', 112 }, 113 debug: { 114 type: 'boolean', 115 }, 116 autoReload: { 117 type: 'boolean', 118 }, 119 mapId: { 120 type: 'string', 121 }, 23 122 }, 24 keywords: ['findmespot', 'spot', 'gps', __('map')], 25 } ); 26 } )( 123 keywords: ['findmespot', 'spot', 'gps', 'spotmap', 'gpx', __('map')], 124 }); 125 126 function generalSettings(props){ 127 let panels = []; 128 let general = el(PanelBody, { title: __('General Settings'), initialOpen: false }, 129 el(PanelRow, {}, 130 el(FormTokenField, { 131 label: "Feeds", 132 suggestions: Object.keys(spotmapjsobj.feeds), 133 onChange: (value) => { 134 props.setAttributes({ feeds: value }); 135 }, 136 value: props.attributes.feeds, 137 }) 138 ), 139 140 el(PanelRow, {}, 141 el(FormTokenField, { 142 label: "maps", 143 suggestions: Object.keys(spotmapjsobj.maps), 144 onChange: (value) => { 145 props.setAttributes({ maps: value }); 146 }, 147 value: props.attributes.maps, 148 help: "test" 149 }) 150 ), 151 152 /* Text Field */ 153 el(PanelRow, {}, 154 el(SelectControl, 155 { 156 label: 'Zoom to', 157 onChange: (value) => { 158 props.setAttributes({ mapcenter: value }); 159 }, 160 value: props.attributes.mapcenter, 161 options: [ 162 { label: 'all points', value: 'all' }, 163 { label: 'latest point', value: 'last' }, 164 { label: 'GPX tracks', value: 'gpx' } 165 ], 166 labelPosition: "side", 167 168 } 169 ) 170 ), 171 172 /* Text Field */ 173 el(PanelRow, {}, 174 el(TextControl, 175 { 176 label: 'height', 177 onChange: (value) => { 178 props.setAttributes({ height: value }); 179 }, 180 value: props.attributes.height 181 } 182 ) 183 ), 184 ); 185 panels.push(general); 186 let options = [ 187 { label: 'don\'t filter', value: '' }, 188 { label: 'last week', value: 'last-1-week' }, 189 { label: 'last 10 days', value: 'last-10-days' }, 190 { label: 'last 2 weeks', value: 'last-2-weeks' }, 191 { label: 'last month', value: 'last-1-month' }, 192 { label: 'last year', value: 'last-1-year' }, 193 { label: 'a specific date', value: 'specific' }, 194 ]; 195 // if option is set to sth else (aka custom date) 196 if(!lodash.findKey(options, function(o) { return o.value === props.attributes.dateRange.from}) ){ 197 options[lodash.last(options)] = { label: 'choose new date', value: 'specific' }; 198 options.push({ label: props.attributes.dateRange.from, value: props.attributes.dateRange.from}) 199 } 200 let dateFrom = [ 201 el(PanelRow, {}, 202 el(SelectControl, 203 { 204 label: 'Show points from', 205 onChange: (value) => { 206 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 207 returnArray.from = value; 208 props.setAttributes({ dateRange: returnArray}); 209 }, 210 value: props.attributes.dateRange.from, 211 options: options, 212 labelPosition: "side", 213 } 214 ) 215 ),]; 216 217 if(props.attributes.dateRange.from === 'specific' || !lodash.findKey(options, function(o) { return o.value === props.attributes.dateRange.from})){ 218 dateFrom.push( 219 el(DateTimePicker, 220 { 221 onChange: (currentDate) => { 222 console.log(currentDate); 223 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 224 returnArray.from = currentDate; 225 props.setAttributes({ dateRange: returnArray}); 226 }, 227 currentDate: new Date(), 228 } 229 ) 230 ) 231 } 232 233 options = [ 234 { label: 'don\'t filter', value: '' }, 235 { label: 'last 30 minutes', value: 'last-30-minutes' }, 236 { label: 'last hour', value: 'last-1-hour' }, 237 { label: 'last 2 hours', value: 'last-2-hour' }, 238 { label: 'last day', value: 'last-1-day' }, 239 { label: 'a specific date', value: 'specific' }, 240 ]; 241 if(!lodash.findKey(options, function(o) { return o.value === props.attributes.dateRange.to}) ){ 242 options.push({ label: props.attributes.dateRange.to, value: props.attributes.dateRange.to}) 243 } 244 let dateTo = [ 245 el(PanelRow, {}, 246 el(SelectControl, 247 { 248 label: 'Show points to', 249 onChange: (value) => { 250 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 251 returnArray.to = value; 252 props.setAttributes({ dateRange: returnArray}); 253 }, 254 value: props.attributes.dateRange.to, 255 options: options, 256 labelPosition: "side", 257 } 258 ) 259 ),]; 260 261 if(props.attributes.dateRange.to === 'specific'){ 262 dateTo.push( 263 el(DateTimePicker, 264 { 265 onChange: (currentDate) => { 266 console.log(currentDate); 267 let returnArray = lodash.cloneDeep(props.attributes.dateRange); 268 returnArray.to = currentDate; 269 props.setAttributes({ dateRange: returnArray}); 270 }, 271 currentDate: new Date(), 272 } 273 ) 274 ) 275 } 276 panels.push(el(PanelBody, { title: 'Point Filering', initialOpen: false },dateFrom,dateTo)); 277 return panels; 278 279 } 280 281 function feedPanel(props) { 282 let panel; 283 let panels = []; 284 if( !props.attributes.feeds){ 285 return []; 286 } 287 // console.log(props) 288 for (let i = 0; i < props.attributes.feeds.length; i++) { 289 const feed = props.attributes.feeds[i]; 290 // console.log(feed); 291 let options = []; 292 if (!props.attributes.styles[feed]){ 293 let returnArray = lodash.cloneDeep(props.attributes.styles); 294 returnArray[feed] = {color: 'blue', splitLines: 12}; 295 props.setAttributes({ styles: returnArray}); 296 } 297 options.push(el(PanelRow, {}, 298 el(ColorPalette , { 299 label: "Colors", 300 colors: [ 301 {name: "black", color: "black"}, 302 {name: "blue", color: "blue"}, 303 {name: "gold", color: "gold"}, 304 {name: "green", color: "green"}, 305 {name: "grey", color: "grey"}, 306 {name: "red", color: "red"}, 307 {name: "violet", color: "violet"}, 308 {name: "yellow", color: "yellow"}, 309 ], 310 onChange: (value) => { 311 let returnArray = lodash.cloneDeep(props.attributes.styles); 312 console.log(value,returnArray) 313 returnArray[feed]['color'] = value; 314 props.setAttributes({ styles: returnArray}); 315 }, 316 value: props.attributes.styles[feed]['color'] || 'blue', 317 disableCustomColors: true, 318 }) 319 ), 320 321 // /* Toggle Field TODO: use form toggle instead 322 el(PanelRow, {}, 323 el(ToggleControl, 324 { 325 label: 'connect points wih line', 326 onChange: (value) => { 327 let returnArray = lodash.cloneDeep(props.attributes.styles); 328 console.log(value,returnArray) 329 returnArray[feed]['splitLinesEnabled'] = value; 330 331 if(value && !returnArray[feed]['splitLines'] ){ 332 returnArray[feed]['splitLines'] = 12; 333 } 334 props.setAttributes({ styles: returnArray}); 335 }, 336 checked: props.attributes.styles[feed]['splitLinesEnabled'], 337 } 338 ) 339 )); 340 341 if(props.attributes.styles[feed]['splitLinesEnabled'] === true){ 342 options.push( 343 el(PanelRow, {}, 344 el(TextControl, 345 { 346 label: 'Splitlines', 347 onChange: (value) => { 348 let returnArray = lodash.cloneDeep(props.attributes.styles); 349 console.log(value,returnArray) 350 returnArray[feed]['splitLines'] = value; 351 props.setAttributes({ styles: returnArray}); 352 }, 353 value:props.attributes.styles[feed]['splitLines'], 354 } 355 ) 356 )) 357 } 358 panel = el(PanelBody, { title: feed +' Feed', initialOpen: false }, options); 359 360 361 panels.push(panel); 362 363 } 364 return panels; 365 } 366 function gpxPanel(props) { 367 let panels = []; 368 if( !props.attributes.feeds){ 369 return []; 370 } 371 372 // console.log(feed); 373 let options = []; 374 375 options.push(el(PanelRow, {}, 376 el(ColorPalette , { 377 label: "Colors", 378 colors: [ 379 {name: "black", color: "black"}, 380 {name: "blue", color: "blue"}, 381 {name: "gold", color: "gold"}, 382 {name: "green", color: "green"}, 383 {name: "grey", color: "grey"}, 384 {name: "red", color: "red"}, 385 {name: "violet", color: "violet"}, 386 {name: "yellow", color: "yellow"}, 387 ], 388 onChange: (value) => { 389 let returnArray = []; 390 let gpx = lodash.cloneDeep(props.attributes.gpx); 391 lodash.forEach(gpx,(track)=>{ 392 track.color = value; 393 returnArray.push(track); 394 }) 395 props.setAttributes({ gpx: returnArray}); 396 }, 397 value: props.attributes.gpx[0]? props.attributes.gpx[0].color : 'gold', 398 disableCustomColors: true, 399 }) 400 ), 401 402 el(PanelRow, {}, 403 el(MediaUpload,{ 404 allowedTypes: ['text/xml'], 405 multiple: true, 406 value: props.attributes.gpx.map(entry => entry.id), 407 title: "Choose gpx tracks (Hint: press ctrl to select multiple)", 408 onSelect: function (gpx){ 409 let returnArray = []; 410 lodash.forEach(gpx,(track)=>{ 411 track = lodash.pick(track,['id','url','title']); 412 returnArray.push(track); 413 }) 414 props.setAttributes({ gpx: returnArray}); 415 }, 416 render: function (callback){ 417 return el(Button, 418 {className: "test", 419 onClick: callback.open 420 },"Open Media Library" 421 422 )} 423 }) 424 )); 425 426 427 panels.push(el(PanelBody, { title: 'GPX', initialOpen: false }, options)); 428 429 return panels; 430 } 431 432 })( 27 433 window.wp.blocks, 28 434 window.wp.element, 29 window.wp.i18n 435 window.wp.i18n, 436 window.wp.blockEditor, 437 window.wp.components, 438 window.wp.compose, 30 439 ); 440 441 -
spotmap/trunk/public/js/maphandler.js
r2382782 r2479440 5 5 class Spotmap { 6 6 constructor (options) { 7 if(!options.maps || !options.feeds){ 8 console.error("Missing important options!!"); 9 } 7 10 this.options = options; 11 this.mapcenter = {}; 8 12 this.debug("Spotmap obj created."); 9 13 this.debug(this.options); 14 this.map = {}; 10 15 } 11 16 12 17 initMap(){ 13 18 jQuery('#'+ this.options.mapId).height(this.options.height); 19 var self = this; 20 21 // https://github.com/Leaflet/Leaflet/issues/3962 22 var container = L.DomUtil.get(this.options.mapId); 23 if(container != null){ 24 if(lodash.isEqual(this.options,this.oldOptions)){ 25 console.log("SAME!!") 26 } else { 27 console.log("NOT SAME!!") 28 console.log(this.oldOptions) 29 30 } 31 container._leaflet_id = null; 32 jQuery('#'+ this.options.mapId + " > .leaflet-control-container" ).empty(); 33 jQuery('#'+ this.options.mapId + " > .leaflet-pane" ).empty(); 34 } 35 this.oldOptions = this.options; 14 36 this.debug("Lodash version: " + lodash.VERSION); 15 37 … … 26 48 this.map.once('focus', function() { self.map.scrollWheelZoom.enable(); }); 27 49 50 // zoom to bounds btn 51 let zoomOptions = {duration: 2}; 52 let last = L.easyButton({ 53 states: [{ 54 stateName: 'all', 55 icon: '<span class="target">🌐</span>', 56 title: 'show all points', 57 onClick: function(control) { 58 self.map.flyToBounds(self.mapcenter.all,zoomOptions); 59 control.state('last'); 60 } 61 }, { 62 icon: '<span class="target">📍</span>', 63 stateName: 'last', 64 onClick: function(control) { 65 self.map.flyTo(self.mapcenter.last, 14,zoomOptions); 66 if(self.mapcenter.gpx) 67 control.state('gpx'); 68 else 69 control.state('all'); 70 }, 71 title: 'show last point' 72 }, { 73 icon: '<span class="target">👣</span>', 74 stateName: 'gpx', 75 onClick: function(control) { 76 self.map.flyToBounds(self.mapcenter.gpx,zoomOptions); 77 control.state('all'); 78 }, 79 title: 'show gpx tracks' 80 }] 81 }); 82 // the users position 83 let position = L.easyButton('<span class="target">🏡</span>',function(){ 84 self.map.locate({setView: true, maxZoom: 16}); 85 }) 86 // add all btns to map 87 L.easyBar([last,position]).addTo(this.map); 88 28 89 baseLayers[Object.keys(baseLayers)[0]].addTo(this.map); 29 90 var Marker = L.Icon.extend({ … … 64 125 body.feeds = this.options.feeds; 65 126 } 66 var self = this; 67 jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) { 127 this.getPoints(function (response) { 68 128 69 129 var overlays = {}, … … 107 167 overlays[lastFeed] = {"group": L.layerGroup(group), "label":lastFeed}; 108 168 } 109 line = []; 169 if(this.getOption('splitLines', { 'feed': entry.feed_name })){ 170 line = []; 171 } 110 172 group = []; 111 173 feeds.push(entry.feed_name); … … 117 179 line = [[entry.latitude, entry.longitude]]; 118 180 } 119 181 120 182 // a normal iteration adding stuff with default values 121 else {183 else if (this.getOption('splitLines', { 'feed': entry.feed_name })) { 122 184 line.push([entry.latitude, entry.longitude]); 123 185 } 124 125 186 let message = ''; 126 187 let tinyTypes = this.getOption('tinyTypes', { 'feed': entry.feed_name }); … … 146 207 if (entry.battery_status == 'LOW') 147 208 message += 'Battery status is low!' + '</br>'; 148 209 if (entry.hiddenPoints) 210 message += 'There are ' + entry.hiddenPoints.count + ' hidden Points within a radius of '+ entry.hiddenPoints.radius+' meters</br>'; 211 149 212 150 213 var marker = L.marker([entry.latitude, entry.longitude], markerOptions).bindPopup(message); … … 176 239 var gpxOverlays = {}; 177 240 if (self.options.gpx) { 241 // set the gpx overlays, so the gpx will be added first (= below the feeds) 242 let gpxnames = lodash.map(self.options.gpx, 'title'); 243 lodash.forEach(gpxnames,function(title){ 244 gpxOverlays[title] = null; 245 }); 178 246 // reversed so the first one is added last == on top of all others 179 247 for (var i=0; i < self.options.gpx.length; i++) { … … 201 269 // e.target.getLayers()[0].bindPopup(entry.name); 202 270 // console.log(e) 271 let gpxBound = e.target.getBounds(); 272 let point = L.latLng(gpxBound._northEast.lat, gpxBound._northEast.lng); 273 let point2 = L.latLng(gpxBound._southWest.lat, gpxBound._southWest.lng); 274 if (!gpxBounds) { 275 gpxBounds = L.latLngBounds([point, point2]); 276 } else { 277 gpxBounds.extend(L.latLngBounds([point, point2])) 278 } 279 self.mapcenter.gpx = gpxBounds; 203 280 if (self.options.mapcenter == 'gpx' || response.error) { 204 let gpxBound = e.target.getBounds();205 let point = L.latLng(gpxBound._northEast.lat, gpxBound._northEast.lng);206 let point2 = L.latLng(gpxBound._southWest.lat, gpxBound._southWest.lng);207 if (!gpxBounds) {208 gpxBounds = L.latLngBounds([point, point2]);209 } else {210 gpxBounds.extend(L.latLngBounds([point, point2]))211 }212 281 self.map.fitBounds(gpxBounds); 213 282 } 214 283 }).on('addline', function(e) { 215 e.line.bindPopup(entry. name);284 e.line.bindPopup(entry.title); 216 285 }); 217 286 let html = ' <span class="dot" style="position: relative;height: 10px;width: 10px;background-color: ' + color + ';border-radius: 50%;display: inline-block;"></span>'; 218 if (gpxOverlays[entry. name]) {219 gpxOverlays[entry. name].group.addLayer(track);287 if (gpxOverlays[entry.title]) { 288 gpxOverlays[entry.title].group.addLayer(track); 220 289 } else { 221 gpxOverlays[entry. name] = {group: L.layerGroup([track]), 'label': entry.name + html};290 gpxOverlays[entry.title] = {group: L.layerGroup([track]), 'label': entry.title + html}; 222 291 } 223 292 … … 225 294 } 226 295 // reverse order in menu to have the first element added last but shown on the menu first again 227 lodash.forEachRight(gpxOverlays, function(value, key) { overlays[key] = value });296 lodash.forEachRight(gpxOverlays, function(value,entryName) { overlays[entryName] = value }); 228 297 var displayOverlays = {}; 229 298 for (let key in overlays) { … … 244 313 } 245 314 } 246 if (self.options.mapcenter == 'all') { 247 var group = new L.featureGroup(all); 248 let bounds = group.getBounds(); 249 self.map.fitBounds(bounds); 250 } else if (self.options.mapcenter == 'last') { 251 var lastPoint; 252 var time = 0; 253 if (response.length > 0 && !response.error){ 254 response.forEach(function(entry, index) { 255 if (time < entry.unixtime) { 256 time = entry.unixtime; 257 lastPoint = [entry.latitude, entry.longitude]; 258 } 259 }); 315 var group = new L.featureGroup(all); 316 let bounds = group == undefined ? undefined : group.getBounds(); 317 self.mapcenter.all = bounds; 318 319 320 var lastPoint; 321 var time = 0; 322 if (response.length > 0 && !response.error){ 323 response.forEach(function(entry, index) { 324 if (time < entry.unixtime) { 325 time = entry.unixtime; 326 lastPoint = [entry.latitude, entry.longitude]; 327 } 328 }); 329 } 330 self.mapcenter.last = lastPoint; 331 // error key is only set on an empty response 332 if(!response.hasOwnProperty("error")){ 333 if(self.options.mapcenter == 'gpx' && self.options.gpx.length == 0){ 334 self.options.mapcenter = 'all'; 335 } 336 if (self.options.mapcenter == 'all') { 337 self.map.fitBounds(bounds); 338 } else if (self.options.mapcenter == 'last') { 260 339 self.map.setView([lastPoint[0], lastPoint[1]], 13); 261 340 } 262 263 }341 } 342 264 343 for (let index in self.options.mapOverlays) { 265 344 let overlay = self.options.mapOverlays[index]; … … 270 349 } 271 350 } 272 351 352 // hide map option, if only one 273 353 if(Object.keys(baseLayers).length == 1){ 274 354 baseLayers = {}; … … 276 356 if (Object.keys(displayOverlays).length == 1) { 277 357 displayOverlays[Object.keys(displayOverlays)[0]].addTo(self.map); 278 L.control.layers(baseLayers).addTo(self.map); 358 if(Object.keys(baseLayers).length > 1) 359 L.control.layers(baseLayers).addTo(self.map); 279 360 } else { 280 361 L.control.layers(baseLayers, displayOverlays).addTo(self.map); … … 308 389 body.groupBy = 'feed_name'; 309 390 body.orderBy = 'time DESC'; 310 jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) { 391 self.getPoints(function (response) { 392 if(response.error){ 393 return; 394 } 311 395 // debug("Checking for new points ...",self.options.debug); 312 396 response.forEach(function(entry, index) { … … 337 421 if (entry.battery_status == 'LOW') 338 422 message += 'Battery status is low!' + '</br>'; 423 if (entry.hiddenPoints) 424 message += 'There are ' + entry.hiddenPoints.count + ' hidden Points within a radius of '+ entry.hiddenPoints.radius+' meters</br>'; 339 425 340 426 let marker = L.marker([entry.latitude, entry.longitude], markerOptions).bindPopup(message); … … 346 432 }); 347 433 348 } );434 },{body: body, filter: self.options.filterPoints}); 349 435 }, 30000); 350 436 } 351 } );352 } 437 },{body: body, filter: this.options.filterPoints}); 438 }world 353 439 354 440 getOption(option, config) { … … 364 450 return baseLayers; 365 451 } 366 for (let mapName in spotmapjsobj.maps) { 367 if (this.options.maps.includes(mapName)) { 452 for (let mapName in this.options.maps) { 453 mapName = this.options.maps[mapName]; 454 if (lodash.keys(spotmapjsobj.maps).includes(mapName)) { 368 455 let map = spotmapjsobj.maps[mapName]; 369 baseLayers[map.label] = L.tileLayer(map.url, map.options); 456 if(map.wms){ 457 baseLayers[map.label] = L.tileLayer.wms(map.url, map.options); 458 } else { 459 baseLayers[map.label] = L.tileLayer(map.url, map.options); 460 } 370 461 } 371 462 } … … 386 477 } 387 478 if (option == 'splitLines' && config.feed) { 479 if (this.options.styles[config.feed] && this.options.styles[config.feed].splitLinesEnabled && this.options.styles[config.feed].splitLinesEnabled === false) 480 return false; 388 481 if (this.options.styles[config.feed] && this.options.styles[config.feed].splitLines) 389 482 return this.options.styles[config.feed].splitLines; 390 return 'false';483 return false; 391 484 } 392 485 if (option == 'tinyTypes' && config.feed) { … … 397 490 } 398 491 debug(message){ 399 if(this.options .debug)492 if(this.options && this.options.debug) 400 493 console.log(message) 401 494 } 402 495 496 getPoints(callback,options){ 497 jQuery.post(spotmapjsobj.ajaxUrl, options.body, function (response){ 498 // filter out close by points, never filter if group option is set 499 if(options.filter && ! options.body.groupBy && !response.error){ 500 let indexesToBeDeleted = []; 501 response = lodash.each(response, function (element, index){ 502 // if we spliced the array, loop to the end with undefinded elements 503 if(!element) 504 return 505 // continue so we can check against another value 506 if(index == 0) 507 return; 508 let lastPoint; 509 for (let i = index; i <= response.length; i++) { 510 if(!lodash.includes(indexesToBeDeleted, index)){ 511 lastPoint = [response[index-i].latitude,response[index-i].longitude]; 512 response[index-i].hiddenPoints = {count: i,radius: options.filter}; 513 break; 514 } 515 } 516 let dif = L.latLng(element.latitude, element.longitude).distanceTo(lastPoint); 517 // console.log(dif) 518 if(dif < options.filter){ 519 // indexesToBeDeleted.push(index); 520 response[index] = undefined; 521 } 522 }); 523 // lodash.each(indexesToBeDeleted,function(element){ 524 // response[element] = undefined; 525 // }); 526 response = response.filter(function( element ) { 527 return element !== undefined; 528 }); 529 530 } 531 callback(response); 532 }); 533 } 403 534 initTable(id){ 404 535 // define obj to post data … … 406 537 'action': 'get_positions', 407 538 'date-range': this.options.dateRange, 539 'type': this.options.type, 408 540 'date': this.options.date, 409 541 'orderBy': this.options.orderBy, … … 415 547 } 416 548 var self = this; 417 jQuery.post(spotmapjsobj.ajaxUrl, body,function (response) {549 this.getPoints(function (response) { 418 550 let headerElements = ["Type", "Message", "Time"]; 419 551 let hasLocaltime = false; … … 429 561 row += '<tr>' 430 562 table.append(jQuery(row)); 431 lodash.forEach(response,function(entry){ 432 if(!entry.local_timezone){ 433 entry.localdate = ''; 434 entry.localtime = ''; 435 } 436 if(!entry.message) 437 entry.message = ''; 438 let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>"; 439 if (hasLocaltime) 440 row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>"; 441 row += "</tr>"; 442 table.append(jQuery(row)) 443 }); 563 if(response.error == true){ 564 self.options.autoReload = false; 565 table.append(jQuery("<tr><td></td><td>No data found</td><td></td></tr>")) 566 return; 567 } else 568 lodash.forEach(response,function(entry){ 569 if(!entry.local_timezone){ 570 entry.localdate = ''; 571 entry.localtime = ''; 572 } 573 if(!entry.message) 574 entry.message = ''; 575 let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>"; 576 if (hasLocaltime) 577 row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>"; 578 row += "</tr>"; 579 table.append(jQuery(row)) 580 }); 444 581 if(self.options.autoReload == true){ 445 582 var oldResponse = response; 446 583 var refresh = setInterval(function(){ 447 jQuery.post(spotmapjsobj.ajaxUrl, body,function (response) {584 self.getPoints(function (response) { 448 585 if( lodash.head(oldResponse).unixtime < lodash.head(response).unixtime){ 449 586 var table = jQuery('#' + id); … … 475 612 }); 476 613 } else { 477 console.log('same response!');614 self.debug('same response!'); 478 615 } 479 616 480 } );617 },{body: body, filter: self.options.filterPoints}); 481 618 }, 10000); 482 619 } 483 } );620 },{body: body, filter: this.options.filterPoints}); 484 621 } 485 622 } -
spotmap/trunk/public/leafletfullscreen/leaflet.fullscreen.css
r2241659 r2479440 31 31 z-index:99999; 32 32 } 33 34 @media 35 (-webkit-min-device-pixel-ratio:2), 36 (min-resolution:192dpi) { 37 .leaflet-control-fullscreen a { 38 background-image:url(fullscreen@2x.png); 39 } 40 } 33 -
spotmap/trunk/readme.txt
r2382782 r2479440 6 6 License URI: http://www.gnu.org/licenses/gpl-2.0.html 7 7 Requires at least: 5.3 8 Tested up to: 5. 58 Tested up to: 5.6 9 9 10 10 See your Spot device movements on an embedded map inside your Blog! 🗺 Add GPX tracks, routes and waypoints to see a planned route. … … 15 15 Your Wordpress Site will store all positions ever sent. It checks for new positions every 2.5 minutes. 16 16 It supports different devices (They can even belong to different accounts). 17 18 🆕 Support of Gutenberg block editor. Just type `/spotmap` and open the settings on the right. 17 19 18 20 With a shortcode you can add an embedded map to your post or page. By default it will show all positions ever sent. … … 138 140 139 141 ## Changelog 142 = 0.10.1 = 143 Full Gutenberg Block support 144 added NZtopomap 145 added France IGN Topo map token 146 140 147 = 0.9.1 = 141 142 148 Fix Gutenberg editor issue 143 149 spotmessages supports auto update … … 145 151 146 152 = 0.9 = 147 148 If you upgrade to this version from a previous one please delete and reinstall the plugin.149 WARNING: all data will be lost. if you like to upgrade please post in the support forum.150 151 153 - new shortcode to show table of messages 152 154 - add gpx overlays -
spotmap/trunk/spotmap.php
r2382782 r2479440 4 4 * Plugin URI: https://github.com/techtimo/spotmap 5 5 * Description: Add an embedded map that shows the movement of a Spot device 6 * Version: 0. 9.16 * Version: 0.10.1 7 7 * Author: Timo Giese 8 8 * Author URI: https://github.com/techtimo … … 11 11 * Text Domain: spotmap 12 12 * Domain Path: /languages 13 * GitHub Plugin URI: https://github.com/techtimo/spotmap 13 14 */ 14 15
Note: See TracChangeset
for help on using the changeset viewer.