1//tellen hoeveel er geen of ongeldig plantjaar hebben, en hoeveel wel 2//kleuren per genus weer in zijpaneel tonen 3 4 5// https://leafletjs.com/reference-1.0.0.html#tooltip 6// performance: consider .circleMarker instead of .circle 7// https://stackoverflow.com/questions/43015854/large-dataset-of-markers-or-dots-in-leaflet/43019740#43019740 --> 8 9console.log ('====================================', crlf) ; 10 11 12 13var count_trees = 0 ; 14var count_shrubs = 0 ; 15var count_public = 0 ; 16var count_private = 0 ; 17var count_parks = 0 ; 18var count_streets = 0 ; 19var count_young = 0 ; 20var count_old = 0 ; 21 22var old_radius_modifier = 0 ; 23var log_circles = 0 ; 24var circles_trees = [] ; 25var species_trees = [] ; 26var circles_parks = [] ; 27var markers_parks = [] ; 28 29 30var color_border_blink = '#000000' ; 31var color_msec_elapsed = '#AAAAAA' ; 32var color_stop_blinking = '#FFFF00' ; 33 34var year_marked = 0 ; 35var planted_year_known = 0 ; 36var planted_year_in_range = 0 ; 37 38var grow_radius_per_zoom_level = 1.25 ; 39 40var dfg = 0 ; 41var blink_cycles = 0 ; 42var planted2000 ; 43 44var showing_parks = false ; 45var showing_one_park = false ; 46 47if (mobile_device) 48{ circle_radius_min = 0.14 * radius_multiplier ; } 49else 50{ circle_radius_min = 0.14 * radius_multiplier ; } // smallest radius to cover OSM tree circle 51 52if (mode_arboretum) 53{ circle_radius_min = 0.20 * radius_multiplier ; } 54 55console.log ('Radius settings: ' + crlf + 56 'radius_multiplier: ' + radius_multiplier + crlf + 57 'circle_radius_min: ' + circle_radius_min + crlf + crlf); 58 59 60 61// this debug function allows keeping focus on circles.js in devtools, with 'preserve log' chacked 62function circles_log (text) 63{ console.log (text) ; } 64 65function addCircleToMap (tags, id, ref, index, type, planted,lat,lon,ispublic, 66 color_fill,color_border,radius,weight,opacity,hover_content,popup_content,species_sc, tree_dead) 67{ 68 //if ((tags.context != null) && (tags.context != 'park')) 69 //{ return ('') ; } 70 71// hover_content and popup_content are no longer supplied to this function 72// prerender_dialog_hover and prerender_dialog_popup are always false 73 74 if (! prerender_dialog_hover) // always passes, prerender_dialog_hover is always false 75 { hover_content = index.toString () ; } 76 77 if (! prerender_dialog_popup) // always passes, prerender_dialog_hover is always false 78 { popup_content = index.toString () ; } 79 80 countCircles (tags) ; 81 82//console.log ('qqq addCircleToMap species_sc:',species_sc,', color_fill:',color_fill) ; 83 // radius is in meters 84 if ((lat == null) || (lon == null)) 85 { 86 console.log ('addCircleToMap: !!! coord err ','lat: ',lat,', lon: ',lon) ; 87 return ; 88 } 89 90 if ((map == null) || (map == map_prev)) 91 { alert ('addCircleToMap map not loaded') ; } 92 93 if (type == null) 94 { type = text_tree ; } 95 96 if (type == text_shrub) 97 { 98 color_border = '#FFFFFF' ; // AAAA44' ; 99 weight += 1 ; 100 101 if (index == -1) // white circle 102 { 103 color_border = '#000000' ; 104 color_fill = '#888888' ; 105 } 106 } 107 108 var circle ; 109 110 if (isNaN (radius)) 111 { 112 if (species_sc != null) 113 { console.log ('Error on id ' + id + ':' + species_sc + ' radius NaN') ; } 114 radius = 1 ; 115 } 116 117 if (radius < 1.0) 118 { radius = 1.0 ; } 119 120 // console.log ('addCircleToMap not mobile_mode ' + index + crlf + 121 // ', radius: ' + radius +crlf + 122 // ', color: ' + color_border + crlf + 123 // ', fillColor: ' + color_fill + crlf + 124 // ', opacity: ' + opacity + crlf + 125 // ', weight: ' + weight + crlf + 126 // ', hover ' + hover_content) ; 127 if (tree_dead) 128 { weight = 10 ; } 129 130 if (! color_fill_circles) 131 { color_fill = '#FFFFFF' ; } // bij kaarten voor opmeten 132 133 if (color_fill == '#FFFFFF') 134 { 135 color_border = '#000000' ; 136 weight = 0.2 ; 137 } 138 139 /* find out how to make this work: put gay circle for trees with known species 140 console.log ('SSS1' + species_sc, color_fill) ; 141 if ((! color_fill_circles) && (species_sc == ''))
142 { color_fill = '#8888888' ; } // markeer bij zwart witte kaart welke bomen al bekend zijn 143 console.log ('SSS2' + species_sc, color_fill) ; 144 */ 145 146 circle = new customCircle ([lat, lon], 147 { 148 //test : 'xyxyxyxyxyxxyy', 149 index : index, // index into json array 150 id : id, 151 ref : ref, 152 radius : radius, 153 color : color_border, 154 color2 : color_border, 155 fillColor : color_fill, 156 fillColor2 : color_fill, 157 fillOpacity : opacity, 158 weight : weight, 159 dead : false, // tree_dead, 160 planted : planted, 161 place : place.toLowerCase (), 162 species_sc : species_sc, 163 type : type, 164 // context : tags.context, 165 166 // fillPattern : pattern, 167 // dashArray : "2", 168 }) ; 169 170 indexed_circles [index] = circle ; 171 172 if (hover_content != '') 173 { circle.bindTooltip (hover_content,) ; } 174 175 if (popup_content != '') 176 { 177 circle.bindPopup (popup_content, {maxWidth:maxWidthPopupBox}) 178 circle.bindPopup (popup_content, {autoPan:true}) 179 circle.bindPopup (popup_content, {autoPanSpeed:1}) 180 circle.bindPopup (popup_content, {autoPanPadding:[100,250]}) ; 181 } 182 183 var inc_counts = 1 ; 184 if (index == -1) // white circle 185 { inc_counts = 0 ;} 186 187 if (index != -1) 188 { 189 if ((type == text_tree) && (layer_trees != null)) 190 { circle.addTo (layer_trees) ; count_trees += inc_counts ; } 191 if ((type == text_shrub) && (layer_shrubs != null)) 192 { circle.addTo (layer_shrubs) ; count_shrubs += inc_counts ; } 193 if (ispublic && (layer_public != null)) 194 { circle.addTo (layer_public) ; count_public += inc_counts ; } 195 if (! ispublic && (layer_private != null)) 196 { circle.addTo (layer_private) ; count_private+= inc_counts ;} 197 if (((tags.context != null) && (tags.context == 'park')) || 198 ((tags.data_from != null) && (tags.data_from == 'osm'))) 199 { circle.addTo (layer_parks) ; count_parks += inc_counts ;} 200 if ((tags.context != null) && (tags.context == 'street')) 201 { circle.addTo (layer_streets) ; count_streets += inc_counts ;} 202 203 if (split_trees_on_age) // only for huge trees collections (Amsterdam) 204 { 205 if (planted != null) 206 { 207 if (planted < 1940) 208 { circle.addTo (layer_old) ; count_old += inc_counts ;} 209 else 210 { circle.addTo (layer_young) ; count_young += inc_counts ;} 211 } 212 } 213 } 214 else 215 { 216 if (layer_blink != null) 217 { circle.addTo (layer_blink) ; } 218 } 219 220 if (index == -1) // white circle, no further processing needed 221 { 222 //circle.radius_base = radius ; 223 return (circle) ; 224 } 225 226 //if (tree_count2 % 10000 == 0) 227 //{ addTimeline ('Circles drawn: ' + tree_count2) ; } 228 229 tree_count2 ++ ; 230 231 232 233 circle.radius_base = radius ; 234 tags.radius_base = radius ; 235 return (circle) ; 236 237 //.on("click", circleClick); 238 //circle.popup_content = popup_content ; 239 240 //.on('mouseenter', function (e) { markTaxon (genus)} ); 241 //.bindTooltip (hover_content,{permanent:false, offset:L.point({x:0,y:-50})}) 242 243 //map.on("popupopen", function(e) 244 //{ 245 // console.log ('event popupopen') ; 246 // alert ('popupopen');$("#"+myid+" img").one("load", function(){ e.popup.update(); })}); // !!! hook popup open 247 //https://gis.stackexchange.com/questions/91355/leaflet-center-marker-and-popup-on-map-viewport 248 249 /* 250 if (0) // adjust window position 251 { 252 map.on('popupopen', function(e) 253 { 254 // console.log ('event popupopen') ; 255 // find the pixel location on the map where the popup anchor is 256 var px = map.project(e.popup._latlng); 257 // find the height of the popup container, divide by 2 to centre, subtract from the Y axis of marker location 258 px.y -= e.popup._container.clientHeight/2; 259 // pan to new center 260 map.panTo(map.unproject(px),{animate: true, duration: 2}); 261 }); 262 } 263 */ 264} 265 266function countCircles (tags) 267{ 268 var planted = tags.planted ; 269 270 planted_decennium = -1 ; 271 //console.log (crlf, 'countCircles planted: ', planted) ; 272 273 if (! planted) 274 { 275 planted = tags.plantjaar ; 276 if (! planted) 277 { 278 //console.log ('tags.planted & tags.plantjaar -> undefined') ; 279 planted = '----' ; 280 } 281 } 282 283 284 if (planted != '----') 285 { 286 planted = planted.replace (/\'/g, ''); 287 //console.log (crlf + 'countCircles planted: ', planted) ; 288 289 if (planted != Number (planted)) 290 { 291 console.log ('Make numeric', planted) ; 292 planted = Number (planted) ; 293 console.log ('Made numeric?', planted) ; 294 } 295 if (isNaN (planted)) 296 { 297 console.log ('Not a number:', planted) ; 298 planted = '----' ; 299 } // probably invalid year 300 else if (planted < 1800) 301 { 302 //console.log ('Older than 1800', planted) ; 303 planted = '----' ; 304 } 305 else 306 { planted_decennium = planted - planted % 10 ; } 307 308 //console.log ('planted_decennium:', planted_decennium) ; 309 // console.log ('now newest_year:',newest_year, ', planted:',planted) ; 310 311 if ((planted > newest_year) && (planted <= this_year)) 312 { newest_year = planted ; } 313 //if (planted < 1800)
314 //{ console.log ('id:',id,'parseTagsMetrics age < 1800: ' + planted) ; } 315 316 planted = planted - 1800 ; 317 318 planted_year_known ++ ; 319 } 320 321 if (! trees_planted [planted]) 322 { trees_planted [planted] = 1 ; } 323 else 324 { trees_planted [planted]++ ; } 325 326 //console.log ('planted:',planted,planted_decennium) ; 327 328 if (! trees_planted_decennium [planted_decennium]) 329 { trees_planted_decennium [planted_decennium] = 1 ; } 330 else 331 { trees_planted_decennium [planted_decennium]++ ; } 332} 333 334function addTextMarkerToMap (circle,hover_content,popup_content,species_sc) 335{ 336 var genus = '' ; 337 var family = '' ; 338 var font = "<font class='tree-labels' color=black style='text-align:right;font-weight:500;'>" ; 339 var code ; 340 // add decluttering code ? see : https://github.com/MazeMap/Leaflet.LayerGroup.Collision 341 342 labels_count++ ; 343 if (labels_count > 10000) 344 { 345 alert ('Too many trees to show labels for all (performance issue)') ; 346 //show_text_markers = false ; // 2024_05_03 now also shown text markers on large cities, but not all 347 } 348 349 var name = species_original [species_sc] ; 350 351 //console.log ("addTextMarkerToMap:'",show_text_markers_mode,"'",show_text_markers_local) ; 352 if (show_text_markers_mode == show_text_markers_local) 353 { 354 name = taxonLocalName (ui, species_sc) ; 355 if (name != null) 356 { 357 name = name.replace (/undefined/ig,'').replace (/\?/g,'').replace (/~/g, "'") ; 358 name = ' ' + ucfirst (name) + ' '; 359 name = name.replace (/ /g, "  ") ; 360 font = "<font class='tree-labels' color=#660000 style='text-align:right;font-weight:900;font-style:italic;'>" ; 361 // these labels with white background and position to the right works only on some maps 362 //font = "<font class='tree-labels' color=#660000; style='font-size:10px;background-color:white; text-align:right;font-weight:200;font-style:italic;line-height:1'>" ; 363 } 364 } 365 366 if ((name == null) || onlySpaces (name)) 367 { 368 font = "<font class='tree-labels' color=black style='text-align:right;font-weight:500;'>" ; 369 370 if (mode_arboretum) // only show one letter for family 371 { 372 font = "<font class='tree-labels-large' color=black>" ; 373 374 genus = species_sc.replace (/_.*$/,'') ; 375 family = db [sc][family_name][genus] ; 376 if (family != null) 377 //{ name = ucfirst (family.substring (0,1)) ; } 378 { name = family_codes [family] ; } 379 else 380 { name = 'X' ; 381 family = '?' ; 382 } 383 //console.log ('species_sc: ',species_sc,', genus: ', genus, ', family: ', family, ', name: ', name) ; 384 } 385 else 386 { 387 name = species_sc.replace (/_/g, ' ') ; // no local name -> use scientific name 388 if (name != null) 389 { 390 if ((name.indexOf (' Ã ') > -1) || 391 (name.indexOf (' x ') > -1)) 392 { name = name.replace (/ [Ãx]/, ' Ã').replace (/,.*$/g, '') ; } 393 else 394 { name = name.replace (/ /, ' ').replace (/,.*$/g, '') ; } 395 } 396 else 397 { name = '??' ; } 398 name = ucfirst (name) ; 399 } 400 } 401 402 var delta_y = 30 ; //35 ; 403 if (/ .* /.test (name) ) // 3 or more separate parts in name? 404 { delta_y = 35 ; } // 40 405//name = name.toUpperCase ().substring (0,3) + '<br>99' ; 406 407 var center = circle.getLatLng(); 408 409 name = name.replace (/\~/g,"'") ; 410 411 name = name.replace (/ Ã/,' Ã') ; 412 413 // if this option is specified , a threshold in centimeters can be added: e.g. stem=20 414 if (show_stem_circumference) 415 { 416 if (typeof tags.circumference != 'undefined') 417 { tags.circumference = tags.circumference.replace (/[^\.\d].*$/,'') ; } 418 419 if ((typeof tags.diameter != 'undefined') && (tags.diameter > show_stem_threshold / 100)) 420 { tags.circumference = tags.diameter * 3.14 ; } 421 if ((typeof tags.circumference != 'undefined') && (tags.circumference > 3.14 * show_stem_threshold / 100)) 422 { name = name + '<br><b><font color=blue size=+1>' + Number (tags.circumference).toFixed (2) + '</font></b>'; } 423 else 424 { name = '' ; } 425 } 426 427 // set font size at layout.css .leaflet-container 428 var marker = (L.marker (center, 429 {icon: L.divIcon ( 430 { 431 iconSize: [1,1], 432 //iconAnchor: [-20 - circle.options.radius * 3, delta_y], 433 iconAnchor: [0, delta_y], 434 className: 'label', 435 // html: "<div>" + font + "<p style='line-height:0.7'>
435" + name + "</span></font></div>" // ; margin-top:0px 436 html: "<div>" + font + "<p style='font-size: 8pt;line-height:0.9'>" + name + "</span></font></div>" // ; margin-top:0px 437 }), 438 species_sc: species_sc 439 }, 440 ).addTo(map)); // https://github.com/Leaflet/Leaflet.label/issues/146 441 //}).bindTooltip (hover_content,).addTo(map)); // https://github.com/Leaflet/Leaflet.label/issues/146 442 // https://stackoverflow.com/questions/48872298/add-static-labels-to-circle-markers-in-leaflet 443 //console.log (marker.options.species_sc) ; !!! use to switch local <-> scientific name 444 445 if (popup_content != '') 446 { 447 marker.bindPopup (popup_content, {maxWidth:maxWidthPopupBox}) 448 marker.bindPopup (popup_content, {autoPan:true}) 449 marker.bindPopup (popup_content, {autoPanSpeed:1}) 450 marker.bindPopup (popup_content, {autoPanPadding:[100,250]}) ; 451 marker.bindTooltip (popup_content, {direction: 'center'}); 452 } 453 454 markers_trees.addLayer (marker) ; 455 if (! map.hasLayer (markers_trees)) 456 { map.addLayer (markers_trees) ; } 457 458 species_trees.push (marker) ; 459} 460 461function addTextmarkersToNearCircles (map_center) 462{ 463 if ((! show_text_markers_some) && (! show_text_markers)) 464 { return ; } 465 466 if (typeof map_center === 'undefined') 467 { return ; } 468 469 var zoom = Math.round (100 * map.getZoom ()) / 100 ; 470 if (zoom < 19) 471 { return ; } 472 473 labels_count = 0 ; 474 475 markers_trees.clearLayers () ; 476// if (map.hasLayer(species_trees)) 477// { map.removeLayer (species_trees) ; } 478 479 var count = 0 ; 480 481 for (var circle of circles_trees) // was circles_parks 482 { 483 if (circle.options.type == text_tree) 484 { 485 var lat = circle.getLatLng().lat ; 486 var lon = circle.getLatLng().lng ; 487 488 if ((Math.abs (lat - map_center.lat) < 0.0020) && 489 (Math.abs (lon - map_center.lng) < 0.0020)) 490 { 491 count ++ ; 492 addTextMarkerToMap (circle, '', '', circle.options.species_sc) ; 493 } 494 } 495 } 496 497 if (count > 0) 498 { console.log ('addTextmarkersToNearCircles markers added : ' + count) ; } 499} 500 501function addTextMarkerAtPosition (point, text, count) 502{ 503 var marker = L.marker (point, 504 {icon: L.divIcon ( 505 { 506 iconSize: null, 507 className: 'label', 508 html: '<div>
508' + text + '</div>' 509 }) 510 }) ; 511 if (count >= threshold_large_parks) 512 { marker.addTo (map) ; } 513 //alert ('addTextMarkerAtPosition') ; 514 return (marker) ; 515} 516 517function addLargeTextMarkerAtPosition (point, text, count) 518{ 519 520 var marker = L.marker (point, 521 {icon: L.divIcon ( 522 { 523 iconSize: [0,0], 524 iconAnchor: [0,0], 525 popupAnchor: [0,0], 526 className: 'submit', 527 //html: "<input type='submit' value=' " + text + " ' style='color:green; margin:0px; padding: 20px'>" 528 html: "<input type='text' value='" + text + "' style='color:green; margin-right:0px; padding-right:10px;'>" 529 }) 530 }) ; 531 if (count >= threshold_large_parks) 532 { 533 marker.addTo (map) ; 534 markers_parks.push (marker) ; 535 } 536 537 //alert ('addTextMarkerAtPosition') ; 538 return (marker) ; 539} 540 541function showMarkedCirclesOnMap () 542{ 543 var count = 0 ; 544 // console.log ('circles_marked.length: ',circles_marked.length) ; 545 for (var layer of circles_marked) 546 { 547 count++ ; 548 map.addLayer (layer) ; 549 } 550 551 //console.log (timeStamp (), count + ' circles added to map'); 552 553 return (count) ; 554 555// circles_marked.length = 0 ; 556} 557 558function blinkMarkedCircles () 559{ 560 var msec_start = performance.now () ; 561 562 var count ; 563 //console.log ('blinkMarkedCircles ()') ; 564 565 if (do_mark) 566 { 567 blink_cycles++ ; 568 count = showMarkedCirclesOnMap () ; 569 570 if (blink_cycles <= 1) 571 { console.log ('showMarkedCirclesOnMap (): ' + count + 'x') ; } 572 } 573 else 574 { count = hideMarkedCirclesFromMap () ; 575 //console.log ('hideMarkedCirclesFromMap (): ' + count + 'x') ; 576 } 577 578 do_mark = ! do_mark ; 579 580 if (count > 0) 581 { timer_blink_taxon = setTimeout (function(){ blinkMarkedCircles () ; }, interval_blink); } 582 583 reportStatsMarkedCirclesUpdate (msec_start, count) ; 584} 585 586// returns boolean for success 587function createCirclesForTaxon (taxon) 588{ 589 var zoom = Math.round (100 * map.getZoom ()) / 100 ; 590 var weight ; 591 592 blink_cycles = 0 ; 593 old_radius_modifier = 0 ; 594 do_mark = true ; // always begin with adding circles, not removing them 595 596 var color_border_blink = '' ; 597 598 circles_marked.length = 0 ; // delete old circles 599 600 var msec_animation_started = performance.now () ; 601 var found = 0 ; 602 var match = false ; 603 var ref ; 604 605 // make sure both taxon_original (with spaces and quotes) and internal format can be handled here 606 var taxon2 = taxon.replace (/ /g, '_') ; 607 console.log ('createCirclesForTaxon (taxon=' + taxon + '/ taxon2=' + taxon2 + ')') ; 608 609 var genus = taxon2.split ('_') [0].toLowerCase () ; 610 611 612 var color_fill = genera_color [genus] ; 613 614 if ((color_fill == null) || (color_fill == '')) 615 { alert ('genus: ' + genus) ; } 616//console.log (genus, color_fill) ; 617 618 taxon = taxon.replace (/Ã/g, "x").toLowerCase () ; 619 620 var radius_modifier = calcRadiusModifierBasedOnZoomlevel (1) ; 621 if (zoom <= 16) // here number of marked circles is not yet known 622 // so make circles even easier to detect on low zoom levels is not applicable 623 { radius_modifier *= 2 ; } 624 625 if (zoom >= 17) { weight = 0.6 ; } 626 else if (zoom >= 15) { weight = 0.4 ; } 627 else if (zoom >= 13) { weight = 0.2 ; } 628 else { weight = 0.1 ; } 629 630 for (var key in data.elements) // https://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript 631 { 632 tree = data.elements [key] ; 633 //console.log ('key:',key,', tree:', tree) ; // 2022_05_15 634 635 //if (tree && tree.tags && tree.tags.species) // instead use optional chaining? is it widely enough supported in 2022? 636 //{ species = tree.tags.species.replace (/'/g,'~').toLowerCase () ; }
637 //else { continue ; } 638 639 if (tree && tree.tags && tree.tags.species_sc) // instead use optional chaining? is it widely enough supported in 2022? 640 { species = tree.tags.species_sc ; } 641 else { continue ; } 642 643 var find_genus = (taxon2.indexOf ('_') == -1) ; 644 // .indexOf (...) == 0, means string should begin with ... 645 if (find_genus) 646 { match = (species.indexOf (genus) == 0) ; } //console.log ("ACTL genus: '" + species + "', taxon: '" + taxon + "': " + 647 // ((match == true)? 'match' : 'nope') + crlf) ; 648 else 649 { match = (species.indexOf (taxon) == 0) ; } //console.log ("ACTL match taxon '" + taxon + "' and '" + species + "' <- '" + 650 // tree.tags.species + "': " + ((match == true)? 'match' : 'nope')) ; 651 //if (species.indexOf ('quercus') > -1) 652 //{ console.log ('test_string:',species,', pattern:',taxon, ', match:',match) ; } 653 654 655 if (match) 656 { 657 found ++ ; 658 659 /* 660 radius = tree_radius [tree.id] ; 661 if (radius == null) 662 { radius = radius_unknown_tree ; } 663 */ 664 radius = tree.tags.radius_base * radius_modifier ; 665 // some species that match may be tree other shrubs, 666 // also db [sc][object_type][taxon] uses internal format, here external format is tested for match 667 668 type = tree.tags.natural ; 669 670 if (type == null) 671 { type = text_tree ; } 672 673 if (type == text_tree) 674 { 675 color_border_blink = (zoom < 17) ? '#FF0000' : '#000000' ; 676 if (index == -1) // white circle 677 { color_border_blink = '#000000' ; color_fill = '#888888' ; } // CCCCCCCCCC find this line 678 } 679 680 if (type == text_shrub) 681 { 682 color_border_blink = (zoom < 17) ? '#FF0000' : '#FFFFFF' ; 683 if (index == -1) // white circle 684 { color_border_blink = '#000000' ; color_fill = '#888888' ; } 685 } 686 687 ref = tree.tags.admin_ref ; 688 if (ref == null) 689 { ref = tree.tags.reference ; } 690 691 //color_border_blink = hue_shift_bright (color_fill,180) ; 692 color_fill2 = hue_shift_bright (color_fill,180) ; 693 color_fill2 = color_fill ; 694 695 if (color_fill == '#FF0000') 696 { color_fill = '#FFFFFF' ; } 697 else 698 { color_fill = '#FF0000' ; } 699 color_fill = '#FFFFFF' ; 700 701 fill_opacity = 0 ; 702 color_border_blink = '#FFFFFF' ; 703 color_fill_blink = '#FF0000' ; 704 705 //if (touch_device) 706 //{ color_fill2 = '#FF00FF' ; } 707 //else 708 //{ color_fill2 = '#000000' ; } 709 var color_line = '#FFFF00' ; 710 color_fill2 = '#000000' ; 711 circle = L.circle ([tree.lat, tree.lon], 712 { 713 id : tree.id, 714 ref : ref, 715 radius : radius / 2, 716 radius_base : radius, 717 color : '#FFFF00', // color_line, 718 color_border_blink, 719 fillColor : color_fill2, 720 fillOpacity : 1, 721 weight : 4, // weight, 722 //dashArray : '2,2', 723 }) ; 724 725 // radius -= 0.3 ; 726 727 circles_marked.push (circle) ; 728 circle.addTo (map) ; 729 circle.bringToFront () ; 730 } 731 732 // return if exceededAnimationRuntime () ; 733 } 734 735 old_radius_modifier = radius_modifier ; 736 el_navbar_stop_blinking.style.display = 'block' ; 737 738 739 return (found) ; 740} 741 742// returns boolean for success 743function createCirclesForPlantYearOrPark (year, range, park) 744{ 745 var new_radius_modifier = calcRadiusModifierBasedOnZoomlevel (1) ; 746 if (zoom <= 16) // here number of marked circles is not yet known 747 // so make circles even easier to detect on low zoom levels is not applicable 748 { new_radius_modifier *= 2 ; } 749 var weight = adjustWeight (new_radius_modifier) ; 750 751 var planted ; 752 var color_fill2 ; 753 var age ; 754 755 blink_cycles = 0 ; 756 old_radius_modifier = 0 ; 757 do_mark = true ; // always begin with adding circles, not removing them 758 759 var color_border_blink = '' ; 760 761 circles_marked.length = 0 ; // delete old circles 762 763 var msec_animation_started = performance.now () ; 764 var found = 0 ; 765 var match = false ; 766 var ref ; 767 768 age = newest_year - year ; 769 770 color_fill = colorByYear (year, color_circles_by_year_range) ; 771 color_fill2 = hue_shift_bright (color_fill,45) ; // shift hue by 1/8 of color circle 772 773 for (var key in data.elements) // https://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript 774 { 775 tree = data.elements [key] ; 776 planted = 0 ; 777 778 if (! tree || ! tree.tags) // instead use optional chaining? is it widely enough supported in 2022? 779 { continue ; } 780 781 if (park == '') 782 { 783 planted = tree.tags.planted ; 784 if (isNaN (planted)) 785 { planted = tree.tags.plantjaar ; } 786 if (isNaN (planted) || (planted < 1800)) 787 { continue ; } 788 789 if (range == 999) // test for decennium 790 { planted = planted - planted % 10 ; } 791 792 found ++ ;
793 markCircle (tree, new_radius_modifier, color_fill2, weight) ; 794 } 795 else 796 { 797 if ((! tree.tags.place) || (tree.tags.place.indexOf (park) == -1)) 798 { continue ; } 799 800 found ++ ; 801 tot_lat += tree.lat ; 802 tot_lon += tree.lon ; 803 tot_coords ++ ; 804 markCircle (tree, new_radius_modifier, '#FF0000', weight) ; 805 } 806 } 807 808 old_radius_modifier = new_radius_modifier ; 809 el_navbar_stop_blinking.style.display = 'block' ; 810 var avg_lat = tot_lat / tot_coords ; 811 var avg_lon = tot_lon / tot_coords ; 812 doMapSetView (new L.LatLng(avg_lat, avg_lon), map.getZoom ()); // upd_map 813// reportCircleCount () ; 814 return (found) ; 815} 816 817function markCircle (tree, radius_modifier, color_fill, weight) 818{ 819 ref = tree.tags.admin_ref ; 820 if (ref == null) 821 { ref = tree.tags.reference ; } 822 823 radius = tree.tags.radius_base * radius_modifier ; 824 var circle = L.circle ([tree.lat, tree.lon], 825 { 826 id : tree.id, 827 ref : ref, 828 radius : radius, 829 radius_base : radius, 830 color_border_blink, 831 fillColor : color_fill, 832 fillOpacity : 1, 833 weight : weight, 834 //dashArray : '2,2', 835 }) ; 836 837 // radius -= 0.3 ; 838 839 circles_marked.push (circle) ; 840 circle.addTo (map) ; 841 circle.bringToFront () ; 842} 843 844function reportCircleCount () 845{ 846 var count = 0; 847 map.eachLayer (function(layer) 848 { 849 // check if the layer has any objects 850 if (typeof layer.getLatLng === 'function') 851 { count++; } 852 else if (typeof layer.getLayers === 'function') 853 { // layer is a group of markers or circles 854 count += layer.getLayers().length; 855 } 856 }) ; 857 alert (count) ; 858} 859 860function adjustWeight (radius_modifier) 861{ 862 var zoom = Math.round (100 * map.getZoom ()) / 100 ; 863 864 if (zoom >= 17) { weight = 0.6 ; } 865 else if (zoom >= 15) { weight = 0.4 ; } 866 else if (zoom >= 13) { weight = 0.2 ; } 867 else { weight = 0.1 ; } 868 869 return (weight) ; 870} 871 872function reportStatsMarkedCirclesUpdate (msec_start, found) 873{ 874//console.log ('reportStatsMarkedCirclesUpdate (msec_start:',msec_start,', found:',found) ; 875 if (color_msec_elapsed == '#AAAAAA') 876 { color_msec_elapsed = '#888888' ; } 877 else 878 { color_msec_elapsed = '#AAAAAA' ; } 879 880 if (color_stop_blinking == '#CCCC00') 881 { color_stop_blinking = '#FFFF00' ; } 882 else 883 { color_stop_blinking = '#CCCC00' ; } 884 885 el = el_navbar_stop_blinking ; 886 el.style.display = 'block' ; 887 el.style.color = color_stop_blinking ; 888 889 var msec_animation_elapsed = performance.now () - msec_start ; 890 var element = Element('msec_animation_elapsed') ; 891 if (element) 892 { element.innerHTML = '<small><small><font color=' + color_msec_elapsed + '>' + found + ' trees<br>' + msec_animation_elapsed + ' msec</font></small></small>' ; } 893} 894 895function exceededAnimationRuntime () 896{ 897 if (checked % 250 == 0) 898 { 899 var msec_animation_elapsed = performance.now () - msec_animation_started ; 900 if (msec_animation_elapsed > 1000) 901 { 902 hideMarkedCirclesFromMap () ; 903 904 if (element) 905 { element.innerHTML = "<font color=white><small><small></b>Too many trees</b><br>" + 906 "animation cancelled<br> after " + msec_animation_elapsed + 907 " msec</small></small></font>" ; } 908 909 return true ; 910 } 911 } 912 return false ; 913} 914 915function findCircleById (id) 916{ 917 for (var circle of circles_trees) 918 { 919 if ((String (circle.options.id) .indexOf (id) > -1) || 920 (String (circle.options.ref).indexOf (id) > -1)) 921 { 922 circle.setRadius (2) ; 923 circle.options.weight = 3 ; 924 mark_circle = circle ; 925 926 doMapFlyTo (circle._latlng, 19) ; 927 928 return ; 929 } 930 //console.log ('circle: ', circle.options.id, circle.options.ref) ; 931 } 932 alert (ui_text_find_tree_failed + ' ' + id) ; 933} 934 935function jumpToPark (content) 936{ 937 var index = content; 938 index = index.replace (/>.*$/gm,'') ; // '<x123>abc' -> '<x123' ; 939 index = index.replace (/[^\d]/gm,'') ; // '<x123' -> 123 940 941 if (! index) 942 { 943 console.log ("jumpToPark: no index '" + index + "'") ; 944 return (index) ; 945 } 946 947 var tree = data.elements [index]; 948 if (tree == null) 949 { 950 console.log ("jumpToPark: no tree data for index '" + index + "'") ; 951 return (index) ; 952 } 953 954 var type = tree.tags.place ; 955 956 console.log ('jumpToPark place:', place) ; 957 958 showing_all_parks = false ; 959} 960 961function markTreesInPark (park) 962{ 963 showing_one_park = true ; 964 showing_all_parks = false ; 965 el_header_h1.innerHTML = titleCase (park) ; 966//el_navbar.style.height = '60px' ; 967 968 park = park.replace (/^\s*/,'') ; 969 park = park.replace (/\s*$/,'') ; 970 971 console.log (crlf + "markTreesInPark + '" + park + "'") ; 972 973 var count = 0 ; 974 var tot_lat = 0 ; 975 var tot_lon = 0 ; 976 var tot_coords = 0 ; 977 var min_lat = 99999 ; 978 var max_lat = -99999 ; 979 var min_lng = 99999 ; 980 var max_lng = -99999 ; 981 982 /* 983 layer_parks.eachLayer (function(layer) 984 { 985 console.log ('layer.context:',layer.context) ; 986 }); 987 */ 988 989 for (var circle of circles_trees) 990 { 991 //if ((circle.options.place.indexOf (park) > -1) || 992 // (((file_json.indexOf ('leiden') > -1) && 993 // (park.match (singelpark_park_names))))) 994 if (circle.options.place.indexOf (park) > -1) 995 { 996 count ++ ; 997 var lat = circle.getLatLng().lat ; 998 var lon = circle.getLatLng().lng ; 999 tot_lat += lat ; 1000 tot_lon += lon ; 1001 tot_coords ++ ; 1002 if (lat < min_lat) { min_lat = lat ; } ; 1003 if (lat > max_lat) { max_lat = lat ; } ; 1004 if (lon < min_lng) { min_lng = lon ; } ; 1005 if (lon > max_lng) { max_lng = lon ; } ; 1006 1007 //circle.options.weight = circle.options.weight + 1 ; 1008 //circle.fillColor = '#FF0000' ; 1009 //circle.redraw () ; 1010 circle.setStyle({fillColor: 'green'}); 1011 } 1012 else 1013 { 1014 // circle.setStyle({fillColor: 'white'}); 1015 // circle.setStyle({color: circle.options.color2}); 1016 circle.setStyle({opacity: 0.0}); 1017 } 1018 //console.log ('circle: ', circle.options.id, circle.options.ref) ; 1019 } 1020 //console.log ('min/max lat/lng', min_lat, max_lat, min_lng, max_lng); 1021if (1) 1022{ 1023 map.fitBounds ([ 1024 [max_lat + 0.0001, min_lng - 0.0001], // max_lat extra to deal with panel overlapping 1025 [min_lat - 0.0001, max_lng + 0.0001] 1026 ]); 1027} 1028 //showArea2 (max_lat, min_lat, max_lng, min_lng) ; // place red dots around area, only for debugging 1029 1030 //console.log (crlf + "map.fitBounds ([" + max_lat +',' + min_lng + "],[" + min_lat + ',' + max_lng + "])") ; 1031 1032 if (count == 0) 1033 { 1034 alert ("Park '" + titleCase (park) + "' niet gevonden.") ; 1035 return ; 1036 } 1037 1038 timer_reset_tree_colors = setTimeout (function(){ unmarkTreesInPark (park) ; }, interval_unmark_trees); 1039 1040 var avg_lat = tot_lat / tot_coords ; 1041 var avg_lon = tot_lon / tot_coords ;
1042//x map.setView (new L.LatLng(avg_lat, avg_lon), map.getZoom ()); // upd_map 1043 1044 reportCountsOnePark (park) ; 1045 1046 /* 1047 if (touch_device) 1048 { toggleExpandParksList () ;} 1049 else 1050 { toggleExpandParksList () ;} 1051 */ 1052//alert (count) ; 1053 1054/* 1055 el_navbar_header2.innerHTML = "<a href='#' alt='Toon alle parken' onclick='openPanelParks();return false' style='position:absolute;right:220px;'><font color=yellow> Terug =></font></a><img id='tooptip124' class='icon' src='assets/park3.png' width=40 bgcolor=#00bb00 alt='Toon alle parken' onclick='openPanelParks();return false' style='position:absolute;right:175px;'>" ; 1056*/ 1057// el_navbar_header2.style.display = 'block' ; 1058 1059} 1060 1061function markTreesAllParks () 1062{ 1063 console.log (crlf + "markTreesAllParks") ; 1064 text_list_topic = 'parken' ; // can switch between paken <> plantenfamilies 1065 1066 var count = 0 ; 1067 var count_plantsoen = 0 ; 1068 var tot_lat_plantsoen = 0 ; 1069 var tot_lon_plantsoen = 0 ; 1070 var tot_lat = 0 ; 1071 var tot_lon = 0 ; 1072 var tot_coords = 0 ; 1073 var min_lat = 99999 ; 1074 var max_lat = -99999 ; 1075 var min_lng = 99999 ; 1076 var max_lng = -99999 ; 1077 var place ; 1078 1079 var points = [] ; 1080 1081 showing_all_parks = true ; 1082 select_trees_park = false ; 1083 circles_recolored = true ; 1084 1085 //closeSidebar () ; 1086 easy_button_park_labels_state = 1 ; 1087 1088 //console.log ('blacklist_park_names:', blacklist_park_names) ; 1089 //console.log ('whitelist_park_names:', whitelist_park_names) ; 1090 for (var circle of circles_trees) // was circles_parks 1091 { 1092 place = circle.options.place ; 1093 //place = 'park' ; // force content for debugging 1094 // console.log ('place:', place) ; 1095 if ((! place.match (blacklist_park_names)) && 1096 (place.match (whitelist_park_names))) 1097 { 1098 count ++ ; 1099 var lat = circle.getLatLng().lat ; 1100 var lon = circle.getLatLng().lng ; 1101 1102 //var marker = addLargeTextMarkerAtPosition ([lat,lon], place) ; 1103 1104 if (place.indexOf ('park') > -1) 1105 { 1106 tot_lat_plantsoen += lat ; 1107 tot_lon_plantsoen += lon ; 1108 count_plantsoen ++ ; 1109 1110 points.push ([lat, lon]) ; 1111 //console.log (place, lat, lon) ; 1112 } 1113 1114 tot_lat += lat ; 1115 tot_lon += lon ; 1116 tot_coords ++ ; 1117 if (lat < min_lat) { min_lat = lat ; } ; 1118 if (lat > max_lat) { max_lat = lat ; } ; 1119 if (lon < min_lng) { min_lng = lon ; } ; 1120 if (lon > max_lng) { max_lng = lon ; } ; 1121 1122 //circle.options.weight = circle.options.weight + 1 ; 1123 //circle.fillColor = '#FF0000' ; 1124 //circle.redraw () ; 1125 circle.setStyle({fillColor: 'green'}); 1126 } 1127 else 1128 { 1129 //circle.setStyle({fillColor: 'red'}); 1130 circle.setStyle({fillOpacity: 0.0, 1131 opacity: 0.0}) ; 1132 } 1133 } 1134 console.log ('All circles green or white') ; 1135 el_navbar_img_expand.src = 'assets/expand_up_blue.png' ; 1136 el_navbar_submit_hint.value = 'Verberg overzicht' ; 1137 parks_list_showing = true ; 1138 1139 1140/* 1141 // Define the Leaflet icon 1142var myIcon = L.icon({ 1143 iconUrl: 'assets/zoom_bw2.png', 1144 iconSize: [32, 32], // size of the icon 1145 iconAnchor: [16, 32], // point of the icon which will correspond to marker's location 1146 popupAnchor: [0, -32], // point from which the popup should open relative to the iconAnchor 1147 className: 'zoom_to_park' // class name for styling the icon 1148}); 1149 1150// Define the Leaflet marker with the icon and text 1151var myMarker = L.marker([52.15734, 4.50356], { 1152 icon: myIcon, 1153 title: 'Groenesteeg' 1154}).bindPopup('Zoom to Groenesteeg').on('click',markTreesInPark ('Park')); 1155 1156 //iconsMonument.push (L.marker([52.157174, 4.50387], {icon: iconMonument}) .addTo(map).addTo (markers_icons). 1157 //addTo (markers_icons2).on('click',markTreesInPark ('Park'))) ; 1158 1159// Add the marker to the map 1160myMarker.addTo(map); 1161*/ 1162 1163 1164 1165 //console.log ('circle: ', circle.options.id, circle.options.ref) ; 1166 1167 //console.log ('min/max lat/lng', min_lat, max_lat, min_lng, max_lng); 1168 1169 map.fitBounds ([ 1170 [max_lat + 0.001, min_lng - 0.001], // max_lat extra to deal with panel overlapping 1171 [min_lat - 0.001, max_lng + 0.001] 1172 ]); 1173 1174 //if (count == 0) 1175 //{ 1176 // alert ("Park '" + titleCase (park) + "' niet gevonden.") ; 1177 // return ; 1178 //} 1179 1180 var avg_lat = tot_lat / tot_coords ; 1181 var avg_lon = tot_lon / tot_coords ; 1182 1183 //console.log ('tot_lat:', tot_lat, ', tot_lon:',tot_lon, ', tot_coords:', tot_coords) ; 1184 if (tot_coords == 0) // (! avg_lat) || (! avg_lon) ) 1185 { 1186 console.log ("markTreesAllParks: No valid coordinates found -> avg_lat and avg_lon cannot be calculated") ; 1187 1188 if (blacklist_park_names == '') 1189 { alert ("function markTreesAllParks: regexp var 'blacklist_park_names' is empty") ; } 1190 else 1191 if (whitelist_park_names == '') 1192 { alert ("function markTreesAllParks: regexp var 'whitelist_park_names' is empty") ; } 1193 else 1194 { alert ("No park information found for any tree (field 'place' in json input)") ; } 1195 } 1196
1197// map.setView (new L.LatLng(avg_lat, avg_lon), map.getZoom ()); // upd_map 1198 var marker = new L.Marker(avg_lat, avg_lon); 1199 1200/* 1201//var polygon = L.polygon(turf.polygon ([points]),{ // error 'turf is not defined' 1202//var test = turf.polygon (points) ; 1203var polygon = L.polygon(points,{ 1204 color: 'black', 1205 fillColor: 'red', // green', 1206 fillOpacity: 1, // 0.2, 1207 weight: 0.1, 1208 opacity: 0.7 1209}); 1210 1211polygon.on('click', function(e) {alert('You clicked the polygon!');}); 1212 1213// add the polygon to the map 1214polygon.addTo(map); 1215*/ 1216 1217 1218 var avg_lat_plantsoen = tot_lat_plantsoen / count_plantsoen ; 1219 var avg_lon_plantsoen = tot_lon_plantsoen / count_plantsoen ; 1220 1221 Object.values(coords_per_park).forEach((park) => 1222 { 1223 var marker = addLargeTextMarkerAtPosition ([park.avg_lat,park.avg_lon], titleCase (park.name) + " (" + park.count + ")", park.count) ; 1224 1225 if (park.count > threshold_large_parks) 1226 { buttons_parks_large.addLayer (marker) ; } 1227 else 1228 { buttons_parks_other.addLayer (marker) ; } 1229 1230 marker.on('click', function() 1231 { 1232 marker.remove () ; 1233 markTreesInPark (park.name); 1234 }); 1235 }); 1236 1237 //setTimeout (function(){ unmarkTreesAllParks () ; }, 5000); 1238/* 1239var marker = addLargeTextMarkerAtPosition ([avg_lat_plantsoen,avg_lon_plantsoen], "Plantsoen (" + count_plantsoen + ")") ; // , park.count) ; 1240marker.on('click', function() { 1241 openSidebar () ; 1242 marker.remove () ; 1243 markTreesInPark ('all'); 1244}); 1245console.log ('points1:', points) ; 1246 points.sort (function(a, b) 1247 { return a.lng - b.lng; }); 1248console.log ('points2:', points) ; 1249*/ 1250 1251 1252//alert (count) ; 1253} 1254 1255function unmarkTreesAllParks () 1256{ 1257 unmarkAllTrees () ; // obsolete (remove?) : better to restore colors for all trees, not only in parks 1258 return ; 1259 1260 console.log (crlf + "unmarkTreesAllParks") ; 1261 1262 1263 //closeSidebar () ; 1264 for (var circle of circles_trees) // was circles_parks 1265 { 1266 circle.setStyle({fillOpacity: 1, 1267 color: circle.options.color2}); 1268 } 1269 console.log ('All circle colors in parks are reapplied') ; 1270 1271 circles_recolored = false ; 1272 1273 reportStatus (copy_to_thumbs, 'Verleg focus') ; 1274} 1275 1276function unmarkTreesInPark (park) 1277{ 1278 console.log (crlf + "unmarkTreesInPark '" + park + "'") ; 1279 for (var circle of circles_trees) 1280 { 1281 if ((circle.options.place.indexOf (park) > -1) || 1282 (((file_json.indexOf ('leiden') > -1) && 1283 (circle.options.place.match (singelpark_park_names))))) 1284 { 1285 count ++ ; 1286 //circle.options.weight = circle.options.weight + 1 ; // !!!! 1287 circle.setStyle({fillColor: circle.options.fillColor2, 1288 color: circle.options.color2}); 1289 } 1290 } 1291} 1292 1293function unmarkAllTrees () 1294{ 1295 console.log (crlf + 'unmarkAllTrees') ; 1296 for (var circle of circles_trees) 1297 { 1298 circle.setStyle ({fillColor: circle.options.fillColor2, 1299 fillOpacity: 1, 1300 opacity: 1}); 1301 } 1302 console.log (crlf + 'unmarkAllTrees : all circle colors have been reapplied') ; 1303} 1304 1305function markTaxon (taxon, index_taxon) 1306{ 1307 if (++console_log_mark_taxon < 50) 1308 { console.log (crlf + '***********' + crlf + "markTaxon: '" + taxon + "', ndx: " + index_taxon + crlf + '***********') ; } 1309 1310 if ((navbar.style.display == 'block') && (innerWidth < 800)) 1311 { navbar.style.display = 'none' ; } 1312 1313 log_mark_taxon = true ; 1314 1315 if (index_taxon_selected != index_taxon) 1316 { showTaxonSelected (taxon, index_taxon) ; } 1317 //showTaxonomy (taxon) ; 1318 1319 if (taxon_selected != prev_taxon) 1320 { blink_iterations = 0 ; } 1321 1322 prev_taxon = taxon ; 1323 taxon_selected = taxon ; 1324 1325 clearTimeout (timer_blink_taxon) ; 1326 1327 hideMarkedCirclesFromMap () ; 1328 var trees_found = createCirclesForTaxon (taxon) ; 1329 1330 if (trees_found) 1331 { 1332 console.log ('Trees_found for taxon: ' + taxon + ' = ' + trees_found) ; 1333 timer_blink_taxon = setTimeout (function(){ blinkMarkedCircles () ; }, interval_blink); 1334 } 1335 else 1336 { console.log ('No trees found for taxon: ',taxon,'!!!!!') ; } 1337} 1338 1339function markYearPlanted (year, range) 1340{ 1341 console.log ('markYearPlanted: ' + year + ',' + range) ; 1342 1343 stopBlinking () ; 1344 const collection = document.getElementsByClassName("markYear" + year); 1345 for (let i = 0; i < collection.length; i++) 1346 { collection[i].style.fontWeight = '900' ; } 1347 year_marked = year ; 1348 1349// if ((navbar.style.display == 'block') && (innerWidth < 800)) 1350// { navbar.style.display = 'none' ; } 1351 1352 log_mark_taxon = true ; 1353 1354 if (index_taxon_selected != index_taxon) 1355 { showTaxonSelected (taxon, index_taxon) ; } 1356 1357//showYearPlanted (year) ; 1358 1359 if (taxon_selected != prev_taxon) 1360 { blink_iterations = 0 ; } 1361 1362 prev_taxon = taxon ; 1363 taxon_selected = taxon ; 1364 1365 clearTimeout (timer_blink_taxon) ; 1366 1367 hideMarkedCirclesFromMap () ; 1368 var trees_found = createCirclesForPlantYearOrPark (year, range, '') ; 1369 1370 if (trees_found) 1371 { 1372 //console.log ('Trees marked: ' + trees_found) ; 1373 timer_blink_taxon = setTimeout (function(){ blinkMarkedCircles () ; }, interval_blink); 1374 } 1375 else 1376 { console.log ('No trees found for year: ',year,'!!!!!') ; } 1377} 1378 1379function hideMarkedCirclesFromMap () 1380{ 1381 var count = 0 ; 1382 for (var layer of circles_marked) 1383 { 1384 count ++ ; 1385 map.removeLayer (layer) ; 1386 } 1387 1388 //console.log (timeStamp(),count + ' circles removed from map') ; 1389 1390 return (count) ; 1391 1392// circles_marked.length = 0 ; 1393} 1394 1395function stopBlinking () 1396{
1397 console.log ('stopBlinking') ; 1398 clearTimeout (timer_blink_taxon) ; 1399 hideMarkedCirclesFromMap () ; 1400 circles_marked.length = 0 ; 1401 el_navbar_stop_blinking.style.display = 'none' ; 1402 if (year_marked != 0) 1403 { 1404 const collection = document.getElementsByClassName("markYear" + year_marked); 1405 for (let i = 0; i < collection.length; i++) 1406 { collection[i].style.fontWeight = '400' ; } // normal 1407 year_marked = 0 ; 1408 } 1409} 1410 1411function adjustCircleBorderToZoomLevel (radius_modifier) 1412{ 1413 return ; 1414 var zoom = Math.round (100 * map.getZoom ()) / 100 ; 1415 var weight, weight_shrub ; 1416 //console.log ('adjustCircleBorderToZoomLevel zoom:',zoom,', radius_modifier',radius_modifier) ; 1417 1418 if (zoom >= 17) { weight = 0.6 ; } 1419 else if (zoom >= 15) { weight = 0.4 ; } 1420 else if (zoom >= 13) { weight = 0.2 ; } 1421 else { weight = 0.1 ; } 1422//var new_radius_modifier = calcRadiusModifierBasedOnZoomlevel (2) ; 1423 circle_ndx = 0 ; 1424 for (var circle of circles_trees) 1425 { 1426 circle.setRadius (circle.radius_base * radius_modifier) ; 1427 circle.bringToFront () ; 1428 1429 if ((circle.options ['color'] == "#FFFFFF") || 1430 (circle.options ['color'] == "#ffffff")) 1431 { 1432 if (circle.radius_base < 1) 1433 { weight_shrub = 1.2 ; } 1434 else 1435 { weight_shrub = 1.5 ; } 1436 1437 circle.options ['weight'] = weight_shrub ; 1438 } 1439 else 1440 { circle.options ['weight'] = weight ; } 1441 1442 if (circle.options ['dead']) 1443 { circle.options ['weight'] = 3 ; } 1444 } 1445} 1446 1447function adjustCircleRadiusToZoomLevel (radius_modifier) 1448{ 1449// I am totally confused why this doesn't work 1450// So do not alter circle radius and weight depending on zoom level 1451// It's quite allright without this cosmetic adjustment 1452 1453 return; 1454 1455 var zoom = Math.round (100 * map.getZoom ()) / 100 ; 1456 var weight, radius ;
1457 //new_radius_modifier = calcRadiusModifierBasedOnZoomlevel (3) ; 1458 if ((zoom <= 16) && (circles_marked.length <= 10)) // make circles even larger on low zoom levels 1459 //{ new_radius_modifier *= 2 ; } 1460 { radius_modifier *= 2 ; } 1461 1462 //console.log ('adjustCircleRadiusToZoomLevel zoom:',zoom,', radius_modifier',radius_modifier) ; 1463 1464 if (zoom >= 19) { weight = 0.1 ; radius = 1.4 } 1465 else if (zoom >= 18) { weight = 0.1 ; radius = 1.8 } 1466 else if (zoom >= 17) { weight = 0.1 ; radius = 2 } 1467 else if (zoom >= 16) { weight = 0.1 ; radius = 3 } 1468 else if (zoom >= 15) { weight = 0.2 ; radius = 5 } 1469 else if (zoom >= 14) { weight = 0.2 ; radius = 7 } 1470 else if (zoom >= 13) { weight = 0.3 ; radius = 10 } 1471 else { weight = 0.4 ; radius = 15 } 1472 weight = radius / 2 ; 1473 1474 console.log ('www adjustCircleRadiusToZoomLevel zoom ' + zoom + ', weight ' + weight + ', radius ' + radius) ; 1475 if (circles_marked.length > 0) 1476 { 1477 //console.log ('radius_modifier old: ',round (old_radius_modifier,2),' ->
1477 new ',round (new_radius_modifier,2)) ; 1478 console.log ('radius_modifier old: ',round (old_radius_modifier,2),' -> new ',round (radius_modifier,2)) ; 1479 1480 // if (new_radius_modifier != old_radius_modifier) 1481 // { 1482 //old_radius_modifier = new_radius_modifier ; 1483 old_radius_modifier = radius_modifier ; 1484 1485 for (var circle of circles_marked) 1486 { 1487 //circle.setRadius (circle.options.radius_base * new_radius_modifier) ; 1488 //circle.setRadius (circle.options.radius_base * radius_modifier) ; 1489 circle.setRadius (radius) ; 1490 circle.bringToFront () ; 1491 //console.log ('circle.options.radius:',circle.options.radius,'radius_base',circle.radius_base) ; 1492 1493 /* 1494 if ((circle.options ['color'] == "#FFFFFF") || 1495 (circle.options ['color'] == "#ffffff")) 1496 { 1497 if (circle.radius_base < 1) 1498 { weight_shrub = 1.2 ; } 1499 else 1500 { weight_shrub = 1.5 ; } 1501 1502 circle.options ['weight'] = weight_shrub ; 1503 } 1504 else 1505 { circle.options ['weight'] = weight ; } 1506 */ 1507 circle.options ['weight'] = weight ; 1508 // } 1509 } 1510 } 1511} 1512 1513function adjustMarkedCircle () 1514{ 1515 if (mark_circle != null) // from findCircleById 1516 { 1517 mark_circle.bringToFront () ; 1518 mark_circle.setRadius (3) ; 1519 mark_circle.options.weight = 5 ; 1520 } 1521} 1522 1523// https://gis.stackexchange.com/questions/258515/show-hide-markers-depending-on-zoom-level 1524 1525function adjustTextMarkers () 1526{ 1527 var zoom = map.getZoom () ; 1528 if (show_text_markers || mode_arboretum) 1529 { 1530 if (map.hasLayer(markers_trees)) 1531 { 1532 // keep markers visible on touch screens even for zoom levels below 20 1533 // the idea is lowering zoom level is essential on small screens, to find out where you are 1534 // also the texts will overlap more on lower zoom levels, but one can enlarge the screen temporarily with pinch-to-zoom gesture 1535 var show_markers_until_zoom = 19 ; 1536 var show_markers_from_zoom = 19.5 ; 1537 if (small_touch_device) 1538 { show_markers_until_zoom = 18.5 ; } 1539 1540 if ((zoom < show_markers_until_zoom) && (! mode_arboretum)) 1541 { 1542 console.log ('adjustCircleRadiusToZoomLevel: map has layers markers_trees -> remove on zoom ' + zoom) ; 1543 map.removeLayer (markers_trees) ; 1544 } 1545 if (mobile_device) 1546 { setThumbs (' ' + '<small>' + ui_text_header_thumbs_mobile + '</small>') ; } 1547 else 1548 { setThumbs (' ' + ui_text_header_thumbs) ; } 1549 } 1550 else 1551 { 1552 if (zoom >= show_markers_from_zoom) 1553 { 1554 console.log ('adjustCircleRadiusToZoomLevel: map does not have layers markers_trees -> add on zoom ' + zoom) ; 1555 map.addLayer (markers_trees) ; 1556 setThumbs (' ' + ui_text_header_explain_labels) ; 1557 } 1558 } 1559 } 1560} 1561 1562function adjustTreeLayersToZoomlevel (zoom) 1563{ 1564 var threshold = 14 ; 1565 var element ; 1566 zoom = round (zoom, 1) ; 1567 1568 element = el_info_box ; 1569 if (! element) 1570 { return ; } 1571 1572 if (split_trees_on_age) 1573 { 1574 if (map.hasLayer(layer_young) && (zoom < threshold)) 1575 { 1576 console.log ('zoom ' + zoom + ' -> adjustTreeLayersToZoomlevel remove layer_young') ; 1577 1578 if (++ count_msg_zoom_threshold <= 2) 1579 { reportStatus (copy_to_thumbs, 'Zoom: ' + zoom + '<br>Toon alleen bomen met plantjaar tot 1940.<br>Vanaf zoom ' + threshold + 1580 ' toon alle bomen.') ; } 1581 map.removeLayer (layer_young) ; 1582 console.log ('1 map.removeLayer (layer_streets)') ; 1583 1584 } 1585 else 1586 if (! map.hasLayer(layer_young) && (zoom >= threshold)) 1587 { 1588 if (++ count_msg_zoom_threshold <= 3) 1589 { reportStatus (copy_to_thumbs, 'Zoom: ' + zoom + '<br>Toon alle bomen vanaf zoom ' + threshold + '. Daaronder alleen parken en plantsoenen.') ; } 1590 console.log ('zoom ' + zoom + ' -> adjustTreeLayersToZoomlevel add layer_young') ; 1591 map.addLayer (layer_young) ; 1592 console.log ('2 map.addLayer (layer_streets)') ; 1593 } 1594 else 1595 { reportStatus (! copy_to_thumbs, 'Zoom: ' + zoom) ; } 1596 } 1597 else 1598 if (split_trees_on_context) 1599 { 1600 if (map.hasLayer(layer_streets) && (zoom < threshold)) 1601 { 1602 console.log ('zoom ' + zoom + ' -> adjustTreeLayersToZoomlevel remove layer_streets') ; 1603 if (++ count_msg_zoom_threshold <= 2) 1604 { reportStatus (copy_to_thumbs, 'Zoom: ' + zoom + '<br>Toon alleen bomen in parken, plantsoenen tot zoom ' + threshold) ; } 1605 map.removeLayer (layer_streets) ; 1606 console.log ('3 map.removeLayer (layer_streets)') ; ; 1607 } 1608 else 1609 if (! map.hasLayer(layer_streets) && (zoom >= threshold)) 1610 { 1611 if (++ count_msg_zoom_threshold <= 3) 1612 { reportStatus (copy_to_thumbs, 'Zoom :' + zoom + '<br>Toon alle bomen vanaf zoom ' + threshold + '.' + 1613 ' Daaronder alleen parken en plantsoenen') ; } 1614 console.log ('zoom ' + zoom + ' -> adjustTreeLayersToZoomlevel add layer_streets') ; 1615 map.addLayer (layer_streets) ; 1616 console.log ('4 map.addLayer (layer_streets)') ; 1617 } 1618 else 1619 { reportStatus (! copy_to_thumbs, '<center>Zoom: ' + zoom + '</center>') ; } 1620 } 1621 else 1622 { 1623 if (zoom == 12) 1624 { reportStatus (! copy_to_thumbs, '<center>Zoom: ' + zoom + ' (min)</center>') ; } 1625 else 1626 if (zoom < 20) 1627 { 1628 // do not show every zoom level on small screens, it is already in bottom-left corner 1629 // for really large screens that would not be noticable enough
1630 if (! small_touch_device) 1631 { reportStatus (! copy_to_thumbs, '<center>Zoom: ' + zoom + '</center>') ; } 1632 } 1633 else 1634 if (! show_text_markers) 1635 { reportStatus (! copy_to_thumbs, '<center>Zoom: ' + zoom + ' (max)</center>') ; } 1636 else 1637 { 1638 count_msg_zoom_20 ++ ; 1639 if (count_msg_zoom_20 <= 1) 1640 { reportStatus (copy_to_thumbs, 'Zoom: ' + zoom + '. Toon soortnamen, alleen voor bomen') ; } 1641 } 1642 } 1643} 1644 1645// range x is 'last x years' 1646// range 999 is 'all ages' 1647function colorCirclesByYearPlanted (range) 1648{ 1649 circles_recolored = true ; 1650 1651 var count = 0 ; 1652 var count_unknown = 0 ; 1653 var color = '#000000' ; 1654 var count_plant_year = 0 ; 1655 var age ; 1656 var html_button1, html_button2, html_button3, html_button4 ; 1657 var oldest_year_shown = 9999 ; 1658 1659 color_circles_by_year_range = range ; 1660 1661 for (var circle of circles_trees) 1662 { 1663 count ++ ; 1664 planted = circle.options.planted ; 1665 ref = circle.options.ref ; 1666 //console.log ('ref:', ref) ; 1667 if (isNaN (planted)) // ((planted == null) || (planted == '????') || (planted == '----')) 1668 { 1669 if ((range == 0) && (! isNaN (ref))) // only mark trees without plant year if municipal 1670 { circle.options.fillColor = '#FF0000' ; } 1671 else 1672 { circle.options.fillColor = '#FFFFFF' ; } 1673 count_unknown++ ; 1674 } 1675 else 1676 { 1677 if (range == 0) 1678 { circle.options.fillColor = '#FFFFFF' ; } 1679 else 1680 { circle.options.fillColor = colorByYear (planted, range) ; } 1681 } 1682 } 1683 1684 var delta_i = 1 ; 1685 if (range == 999) 1686 { delta_i = 10 ; } 1687 1688 var i0 = trees_planted.length - 1 ; 1689 if (range == 999) 1690 { i0 = i0 - i0 % 10 ; } 1691 1692 planted_year_in_range = 0 ; 1693 html_planted_year = "<table width=100%>" + crlf ; 1694 1695 for (var i = i0 ; i > -1 ; i = i - delta_i) 1696 { 1697 if (trees_planted [i] != null) 1698 { 1699 year = i + 1800 ; 1700 age = newest_year - year ; 1701 if (age < range) 1702 { 1703 if (year < oldest_year_shown) 1704 { oldest_year_shown = year ; } 1705 html_planted_year += htmlPlantedTableRow (year, range) ; 1706 } 1707 } 1708 } 1709 1710 planted_year_out_range = planted_year_known - planted_year_in_range ; 1711 if (range < 999) 1712 { html_planted_year += "<tr><td bgcolor='#FFFFFF' border='1px'><div border=1px> </div></td><td><" + oldest_year_shown + "</td><td align=right>" + planted_year_out_range + "</td></tr>" ; } 1713 1714 1715 if (count_unknown > 0) 1716 { html_planted_year += "<tr><td bgcolor='#888888'> </td><td>----</td><td align=right>" + count_unknown + "</td></tr>" ; } 1717 1718 html_planted_year += "</table>" ; 1719 1720 1721 1722 if (range==999) 1723 { 1724 html_button1 = "<button" + 1725 " type='button' style='background-color:#888888' width=100%><b>" + 1726 ui_show_per_decade + "</b></button>" ; 1727 html_button2 = "<button onclick='colorCirclesByYearPlanted(50);'" + 1728 " type='button' style='background-color:#00AA00' width=100%><b>" + 1729 ui_show_last_50_years + "</b></button>" ; 1730 html_button3 = "<button onclick='colorCirclesByYearPlanted(15);'" + 1731 " type='button' style='background-color:#00AA00' width=100%><b>" + 1732 ui_show_last_15_years + "</b></button>" 1733 html_button4 = "<button onclick='colorCirclesByYearPlanted(0);'" + 1734 " type='button' style='background-color:#00AA00' width=100%><b>" + 1735 ui_text_no_year + "</b></button>" 1736 } 1737 else 1738 if (range==50) 1739 { 1740 html_button1 = "<button onclick='colorCirclesByYearPlanted(999);'" + 1741 " type='button' style='background-color:#00AA00' width=100%><b>" + 1742 ui_show_per_decade + "</b></button>" ; 1743 html_button2 = "<button onclick='colorCirclesByYearPlanted(50);'" + 1744 " type='button' style='background-color:#888888' width=100%><b>" + 1745 ui_show_last_50_years + "</b></button>" ; 1746 html_button3 = "<button onclick='colorCirclesByYearPlanted(15);'" + 1747 " type='button' style='background-color:#00AA00' width=100%><b>" + 1748 ui_show_last_15_years + "</b></button>" 1749 html_button4 = "<button onclick='colorCirclesByYearPlanted(0);'" + 1750 " type='button' style='background-color:#00AA00' width=100%><b>" + 1751 ui_text_no_year + "</b></button>" 1752 } 1753 else 1754 if (range == 15) 1755 { 1756 html_button1 = "<button onclick='colorCirclesByYearPlanted(999);'" + 1757 " type='button' style='background-color:#00AA00' width=100%><b>" + 1758 ui_show_per_decade + "</b></button>" ; 1759 html_button2 = "<button onclick='colorCirclesByYearPlanted(50);'" + 1760 " type='button' style='background-color:#00AA00' width=100%><b>" + 1761 ui_show_last_50_years + "</b></button>" 1762 html_button3 = "<button onclick='colorCirclesByYearPlanted(15);'" + 1763 " type='button' style='background-color:#888888' width=100%><b>" + 1764 ui_show_last_15_years + "</b></button>" 1765 html_button4 = "<button onclick='colorCirclesByYearPlanted(0);'" + 1766 " type='button' style='background-color:#00AA00' width=100%><b>" + 1767 ui_text_no_year + "</b></button>" 1768 } 1769 else // range == 0 1770 { 1771 html_button1 = "<button onclick='colorCirclesByYearPlanted(999);'" + 1772 " type='button' style='background-color:#00AA00' width=100%><b>" + 1773 ui_show_per_decade + "</b></button>" ; 1774 html_button2 = "<button onclick='colorCirclesByYearPlanted(50);'" + 1775 " type='button' style='background-color:#00AA00' width=100%><b>" + 1776 ui_show_last_50_years + "</b></button>" 1777 html_button3 = "<button onclick='colorCirclesByYearPlanted(15);'" + 1778 " type='button' style='background-color:#00AA00 ' width=100%><b>" + 1779 ui_show_last_15_years + "</b></button>" 1780 html_button4 = "<button onclick='colorCirclesByYearPlanted(0);'" + 1781 " type='button' style='background-color:#888888' width=100%><b>" + 1782 ui_text_no_year + "</b></button>" 1783 } 1784 1785 html_button5 = "<button onclick='location.reload();' type='button' style='background-color:#00AA00'><b>" + 1786 ui_show_normal_colors + "</b></button>" ; 1787 1788 var html_buttons = "<table width=100%>" + 1789 "<tr>
1789<td width=100%>" + html_button1 + "</td></tr>" + 1790 "<tr><td>" + html_button2 + "</td></tr>" + 1791 "<tr><td>" + html_button3 + "</td></tr>" + 1792 "<tr><td>" + html_button4 + "</td></tr>" + 1793 "<tr><td>" + html_button5 + "</td></tr>" + 1794 "</table>" ; 1795 1796 showSortSequence (10, 'planted') ; 1797 el_sidebar.innerHTML = html_buttons + html_planted_year ; 1798 SetNavbarHeader (1, "<b>" + ucfirst (ui_text_planting_year) + "</b>") ; 1799 openSidebar () ; 1800 repaintMap () ; 1801} 1802 1803function htmlPlantedTableRow(year, range) 1804{ 1805 var entry = '' ; 1806 var i = year - 1800 ; 1807 var count ; 1808 var decennium = 0 ; 1809 1810 if (range == 999) 1811 { 1812 if (! isNaN (year)) 1813 { 1814 decennium = year ; 1815 if (decennium == 0) 1816 { console.log ('htmlPlantedTableRow:', year, range) ; } 1817 count = trees_planted_decennium [decennium] ; 1818 } 1819 } 1820 else 1821 { count = trees_planted [i] ; } 1822 1823 planted_year_in_range += count ; 1824 1825 var color = colorByYear (year, range) ; 1826 1827 var year_label = year ; 1828 if (range == 999) 1829 { year_label = year_label + "'s" ; } 1830 1831 entry = "<tr><td bgcolor=" + color + "> </td>" + 1832 "<td align=left>" + 1833 "<span class='markYear" + year + "' onclick=\"markYearPlanted(" + year + "," + range + ");\">" + year_label + "</span>" + 1834 "</td>" + 1835 "<td align=right>" + "<span class='markYear" + year + "' >" + count + "</span>" + "</td>" + 1836 "</tr>\n" ; 1837 return (entry) ; 1838} 1839 1840function test () 1841{ 1842} 1843 1844function calcRadiusModifierBasedOnZoomlevel (caller) 1845{ 1846 zoom = round (map.getZoom (), 2) ; 1847 1848 var radius_modifier = 1 ; 1849 1850 if (zoom <= 19) { radius_modifier *= grow_radius_per_zoom_level ; } 1851 if (zoom <= 18) { radius_modifier *= grow_radius_per_zoom_level ; } 1852 if (zoom <= 17) { radius_modifier *= grow_radius_per_zoom_level ; } 1853 if (zoom <= 16) { radius_modifier *= grow_radius_per_zoom_level ; } 1854 if (zoom <= 15) { radius_modifier *= grow_radius_per_zoom_level ; } 1855 if (zoom <= 14) { radius_modifier *= grow_radius_per_zoom_level ; } 1856 if (zoom <= 13) { radius_modifier *= grow_radius_per_zoom_level ; } 1857 1858 //console.log ('caller ' + caller +', adjust to zoom:', zoom, ', radius_modifier', round (radius_modifier,2)) ; 1859 return (radius_modifier) ; 1860} 1861 1862function adjustToNewZoomLevel (reason) 1863{ 1864 if (! load_trees_completed) 1865 { 1866 console.log ('adjustToNewZoomLevel skipped: too early') ; 1867 return; 1868 } 1869 //console.log ('adjustToNewZoomLevel on ', reason) ; 1870 1871 var radius_modifier = calcRadiusModifierBasedOnZoomlevel (0) ; 1872 console.log ('radius_modifier radius_modifier: ', radius_modifier) ; 1873 adjustCircleBorderToZoomLevel (radius_modifier) ; // adjust circles border weight to zoom level 1874 adjustCircleRadiusToZoomLevel (radius_modifier) ; // adjust circle size to zoom level 1875 adjustMarkedCircle () 1876 adjustTextMarkers () ; 1877//adjustMarkerIconsToZoomlevel () ; // show or hide different icon sets depending on zoom level 1878 adjustTreeLayersToZoomlevel (zoom) ; 1879 old_radius_modifier = radius_modifier ; 1880} 1881 1882function updateTaxonNames () 1883{ 1884 var font = "<font class='tree-labels' color=black style='text-align:right;font-weight:500;'>" ; 1885 1886 console.log ('updateTaxonNames ()') ; 1887 for (var marker of species_trees) 1888 { 1889 var species_sc = marker.options.species_sc ; 1890 1891 if (show_text_markers_mode == show_text_markers_local) 1892 { 1893 ui = 'nl' ; // to do : generalize to all supported language 1894 name = taxonLocalName (ui, species_sc) ; 1895 if (name != null) 1896 { 1897 name = name.replace (/undefined/ig,'').replace (/\?/g,'').replace (/~/g, "'") ; 1898 name = ucfirst (name) ; 1899 font = "<font class='tree-labels' color=#660000 style='text-align:right;font-weight:900;font-style:italic;'>" ; 1900 } 1901 } 1902 else 1903 { 1904 var name = species_sc.replace (/_/g, ' ') ; // no local name -> use scientific name 1905 if (name != null) 1906 { 1907 if ((name.indexOf (' Ã ') > -1) || 1908 (name.indexOf (' x ') > -1)) 1909 { name = name.replace (/ [Ãx]/, ' Ã').replace (/,.*$/g, '') ; } 1910 else 1911 { name = name.replace (/ /, ' ').replace (/,.*$/g, '') ; } 1912 } 1913 else 1914 { name = '??' ; } 1915 name = ucfirst (name) ; 1916 } 1917 1918 //console.log ('marker:', marker.options) ; 1919 //console.log (marker.options.species_sc) ; //!!! use to switch local <-> scientific name 1920 //console.log (marker) ; 1921 if (marker._icon != null) 1922 { marker._icon.innerHTML = "<div>" + font + "<p style='line-height:0.9'>" + name + "</span></font></div>" ; } 1923 } 1924} 1925 1926function makeAllCirclesTransparent () 1927{
1928 console.log ('makeAllCirclesTransparent') ; 1929 var count = 0 ; 1930 for (var circle of circles_trees) 1931 { 1932 count ++ ; 1933 circle.setStyle ({fillColor: 'white ', 1934 fillOpacity: 0, 1935 weight: 2 }); 1936 } 1937} 1938 1939function uncheckCircles (latlngs) 1940{ 1941 var lon, lat, tmp ; 1942 var index, count = 0 ; 1943 if (! latlngs) 1944 { return ; } 1945 1946 var minlat = latlngs [0][0] ; 1947 var maxlat = latlngs [1][0] ; 1948 var minlon = latlngs [0][1] ; 1949 var maxlon = latlngs [1][1] ; 1950 if (minlat > maxlat) 1951 { tmp = minlat ; minlat = maxlat ; maxlat = tmp ; } 1952 if (minlon > maxlon) 1953 { tmp = minlon ; minlon = maxlon ; maxlon = tmp ; } 1954 1955 SetNavbarHeaders ('trees removed') ; 1956 1957 console.log (latlngs, 'minlat:',minlat, ', maxlat:',maxlat, ', minlon:',minlon, ', maxlon:',maxlon) ; 1958 for (var circle of circles_trees) 1959 { 1960 lat = circle.getLatLng().lat ; 1961 lon = circle.getLatLng().lng ; 1962 1963 if (lat >= minlat && lat <= maxlat && 1964 lon >= minlon && lon <= maxlon) 1965 { 1966 index = parseInt (circle.options.index) ; 1967 1968 var tree = data.elements [index]; 1969 1970 if (select_trees_park || 1971 (select_trees_skip && (tree.data_from == 'gov'))) 1972 { 1973 count ++ ; 1974 uncheckTree (index) ; 1975 } 1976 else 1977 { map.removeLayer (indexed_circles [index]) ; } 1978 } 1979 } 1980 1981 return (count) ; 1982} 1983 1984function removeTooltip () 1985{ 1986// map.eachLayer (function (layer) 1987// { 1988// if (layer.options.pane === "tooltipPane") 1989// { layer.removeFrom (map) ; } 1990//}) ; 1991} 1992 1993function removeWhiteDots () 1994{ 1995 for (var layer of circles_marked) 1996 { 1997 if (layer != null) 1998 { map.removeLayer (layer) ; } 1999 } 2000} 2001 2002function resetMarkedTree () 2003{ 2004 if (mark_circle != null) // from findCircleById 2005 { 2006 var zoom = Math.round (100 * map.getZoom ()) / 100 ; 2007 var factor_larger = Math.pow (1.3, (19 - zoom)) ; 2008 mark_circle.setRadius (mark_circle.radius_base * factor_larger) ; 2009 if (zoom >= 17) { weight = 0.6 ; } 2010 else if (zoom >= 15) { weight = 0.4 ; } 2011 else if (zoom >= 13) { weight = 0.2 ; } 2012 else { weight = 0.1 ; } 2013 mark_circle.options.weight = weight ; 2014 } 2015} 2016 2017function showUncheckedTrees () 2018{ 2019 return ; 2020 if (list_unchecked && list_unchecked != '') 2021 { alert ('Reference numbers of clicked cirkels (which should be filtered from input):' + crlf + list_unchecked) ; } 2022 else 2023 { alert ('No selected trees in list') ; } 2024}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.