Leaflet map probleem met layers via function

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
Ik heb uren zitten te prutsen en alle oplossingen bekeken, maar ik ben helemaal op en mijn hoofd zit even vast (hoofdpijn dus) en daarom ga ik even hulp vragen voor mijn probleem.

Ik ben bezig met een map website voor Black Desert Online.

Leaflet script is gebruikt. Werkt prima. Map zoom en alles doet het.
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
    var map = L.map('right').setView([-39.3683,-67.5], 3);
    mapLink = '<a href="http://www.blackdeserttome.com/map/">Black Desert Tome Map</a>';
    L.tileLayer(
        'images/map/{z}/{x}/{y}.png', {
            attribution: 'Map data &copy; ' + mapLink,
            tms: true,
            continuousWorld: true,
            maxZoom: 7,
            minZoom: 2
            }
        ).addTo(map);
    map.on('click', onMapClick);
    L.control.coordinates().addTo(map);

// load layers
loadnode_layer();
</script>


De volgende stap zijn de iconen toevoegen als nodes.

Dit werkt met:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* icons */
var nodeicon_8 = new LeafIcon({iconUrl: 'data/alchemy.png'});
var nodeicon_5 = new LeafIcon({iconUrl: 'data/camp.png'});
var nodeicon_6 = new LeafIcon({iconUrl: 'data/capital.png'});
var nodeicon_3 = new LeafIcon({iconUrl: 'data/connect.png'});
var nodeicon_10 = new LeafIcon({iconUrl: 'data/hazardous.png'});
var nodeicon_4 = new LeafIcon({iconUrl: 'data/plant.png'});
var nodeicon_11 = new LeafIcon({iconUrl: 'data/tree.png'});
var nodeicon_9 = new LeafIcon({iconUrl: 'data/gateway.png'});
var nodeicon_7 = new LeafIcon({iconUrl: 'data/trade.png'});
var nodeicon_2 = new LeafIcon({iconUrl: 'data/city.png'});
/* map */
var NodeMarkersObject = {};
NodeMarkersObject['node1'] = L.marker([-39.14710270770074,-117.18017578125], {icon: nodeicon_2}).bindPopup('Olvia');
NodeMarkersObject['node2'] = L.marker([-42.78733853171998,-99.68994140625], {icon: nodeicon_6}).bindPopup('Velia');
NodeMarkersObject['node3'] = L.marker([-42.90816007196054,-105.391845703125], {icon: nodeicon_6}).bindPopup('Test');
NodeMarkersObject['node4'] = L.marker([-42.82763863624229,-107.11669921875], {icon: nodeicon_6}).bindPopup('Great');
NodeMarkersObject['node5'] = L.marker([-43.87413818147472,-105.71044921875], {icon: nodeicon_6}).bindPopup('Super');
NodeMarkersObject['node6'] = L.marker([-44.07180046751155,-107.786865234375], {icon: nodeicon_6}).bindPopup('Leeg');
NodeMarkersObject['node7'] = L.marker([-43.45291889355465,-107.40234375], {icon: nodeicon_6}).bindPopup('fffff');
NodeMarkersObject['node8'] = L.marker([-44.26093725039922,-105.22705078125], {icon: nodeicon_6}).bindPopup('tttt');
NodeMarkersObject['node9'] = L.marker([-44.05601169578525,-110.91796875], {icon: nodeicon_8}).bindPopup('boem');
NodeMarkersObject['node10'] = L.marker([-38.75408327579141,-99.580078125], {icon: nodeicon_10}).bindPopup('Castle');
NodeMarkersObject['node11'] = L.marker([-57.13623931917743,-112.8515625], {icon: nodeicon_11}).bindPopup('555555');
NodeMarkersObject['node12'] = L.marker([-59.5343180010956,-123.04687499999999], {icon: nodeicon_3}).bindPopup('fhj');
NodeMarkersObject['node13'] = L.marker([-56.36525013685607,-137.109375], {icon: nodeicon_3}).bindPopup('ygygf');
NodeMarkersObject['node14'] = L.marker([-51.39920565355377,-104.765625], {icon: nodeicon_9}).bindPopup('Gddddd');
NodeMarkersObject['node15'] = L.marker([-57.51582286553883,-106.5234375], {icon: nodeicon_6}).bindPopup('ghj');
NodeMarkersObject['node16'] = L.marker([-59.7120971733229,-83.3203125], {icon: nodeicon_3}).bindPopup('jaap');
NodeMarkersObject['node17'] = L.marker([-47.63578359086485,-125.41992187499999], {icon: nodeicon_5}).bindPopup('dddddd');
var nodelayer = L.layerGroup([NodeMarkersObject['node1'],NodeMarkersObject['node2'],NodeMarkersObject['node3'],NodeMarkersObject['node4'],NodeMarkersObject['node5'],NodeMarkersObject['node6'],NodeMarkersObject['node7'],NodeMarkersObject['node8'],NodeMarkersObject['node9'],NodeMarkersObject['node10'],NodeMarkersObject['node11'],NodeMarkersObject['node12'],NodeMarkersObject['node13'],NodeMarkersObject['node14'],NodeMarkersObject['node15'],NodeMarkersObject['node16'],NodeMarkersObject['node17']]);
if (map.hasLayer(nodelayer)) { map.removeLayer(nodelayer); }
map.addLayer(nodelayer);
var checkboxid=document.getElementById('nodelayer');
checkboxid.checked=true;
/* end node icons */


Het is rommeltje, maar wel een example. Het gaat via ajax aanroep van een php bestand die dit aanmaakt.
Het verschijnt keurig op het map. Dat is wel met deze:
JavaScript:
1
2
3
function loadnode_layer() {
    getxmlhttp('node_icons.php','','mode=map','code');
}

Het is via function, maar het werkt goed.

Dan heb je ook een layer controle. Ik wil even losse checkbox maken, niet via standaard weg.
HTML:
1
2
<div id="headmenu">
    <input type="checkbox" value="1" name="nodelayer" id="nodelayer" onclick="switch_nodelayer()" /> Show Nodes</div>

Niks bijzonders zou je denken.

Maak ik een functie hiervoor:
PHP:
1
2
3
4
5
6
7
function switch_nodelayer() {
    var checkboxid=document.getElementById('nodelayer');
    if (checkboxid.checked==true) 
        { map.addLayer(nodelayer); }
        else 
        { map.removeLayer(nodelayer); } 
}


Je zou verwachten dat layer switch zou werken. Niet dus. Firefox smijt met een foutmelding:
TypeError: t.onAdd is not a function
(server)/script/leaflet.js


Hetzelfde voor remove, met t.onRemove fout.
Het leek erop dat de function boven opeens "eigen" veld heeft en dus niet meer map kan zien.

Waarom het niet werkt, dat is mij de vraag.
Kan iemand me even uitleg geven over mijn probleem en me in goede richting wijzen hoe het wel moet zodat map.addLayer en map.removeLayer weer gewoon werken zoals het hoort.

Dit is grote struikelblok waarom het niet werkt en moet dus opgelost worden zodat ik rest kan afmaken. Er komen nog paar layers bij met controle en daar wil ik niet weer in problemen komen. 8)7

Ik weet wel dat als ik removeLayer in de HTML script plaats, dat wil het wel. Net even "buitenom" met de function aanroep gaat het niet. Er is ergens kleine aanpassing nodig om alsnog te kunnen werken zonder foutmelding. De probleem is nagetrokken, maar er is geen goed passend uitleg.

Alternatief is een event listener gebruiken op hele pagina, verandering checkbox registeren en doorgeven, maar dat is ook met function (). Daar wacht ik even op, om te kijken of jullie een oplossing hebben voor mij.

Alvast dank!
*gaat even zijn hoofd afkoelen* :|

[ Voor 4% gewijzigd door MrDummy op 08-03-2016 19:05 ]


Acties:
  • 0 Henk 'm!

  • z1rconium
  • Registratie: Augustus 2014
  • Laatst online: 17-09 11:26
Heeft het niet heel toevallig te maken met elementen die worden geladen nadat de DOM al gereed is ? Dan snapt die functie niet waar je het over hebt. Ik doel op de ajax call; wanneer doe je die? misschien de boel aanroepen via een window.onload

code:
1
2
3
window.onload = function() {
        loadnode_layer()
    }

Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
Even voor de duidelijkheid:

- Website start
- Leaflet map wordt ingesteld en ingeladen (goed) (zoomen en schuiven werken)
- loadnode_layer() wordt gerund en toont iconen op de map (goed) (gaat via ajax naar php script die js code genereert vanuit de database, zie hierboven)

Maar nu wil ik die layer aan/uit kunnen zetten. Daarvoor heb ik functie switch_nodelayer() voor gemaakt, dat via onclick wordt aangeroepen en zou dus zonder problemen - naar mijn beeld - layer weg kunnen halen en ook weer zichtbaar maken.
Dat gebeurt niet. Dit veroorzaakt foutmelding.

Ik zit te kijken naar andere voorbeelden die "extern bedienen van de layers" moeten doen. Aantal voorbeelden zet een venstertje met knoppen neer in de map beeld. Maar dat moet hier juist buiten map beeld als checkbox.
Er is nog nergens <form> </form> gemaakt. Er wordt alleen maar via getElementById gedaan om te kunnen lezen en te schakelen.

Uit de foutmelding merk ik op dat door de aparte function de map variabele niet meer kan zien, zodat het fout dus veroorzaakt. Ik moet daarom andere oplossing nemen die probleem moet oplossen: kunnen switchen met checkbox én map variabele moet leesbaar blijven.
Ik weet niet of doorgeven van "map" variabele verschil maakt. Heb eens geprobeerd, maar ook dezelfde probleem.

Ik ga even verder neuzen naar externe voorbeelden.
Reacties zijn nog steeds welkom.

----
Update:

Ik kijk naar plugins van leaflet en daar is ook layer control.
Ik pas even wat aan:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
    var map = new L.map('right');
    var mapLink = '<a href="http://www.blackdeserttome.com/map/">Black Desert Tome Map</a>';
    var bdoAttrib = 'Map data &copy; ' + mapLink;
    var bdoUrl = 'images/map/{z}/{x}/{y}.png';
    var bdo = new L.TileLayer(
            bdoUrl, {
            attribution: bdoAttrib,
            tms: true,
            continuousWorld: true,
            maxZoom: 7,
            minZoom: 2
            }
        );
    map.addLayer(bdo);
    map.setView(new L.LatLng(-39.3683,-67.5), 3);
    map.on('click', onMapClick);
    // minimap  
    var bdo2 = new L.TileLayer(bdoUrl, {minZoom: 2, maxZoom: 2, tms:true, attribution: bdoAttrib });
    var miniMap = new L.Control.MiniMap(bdo2, { toggleDisplay: true, position: 'topright', width:200, height:200, zoomLevelFixed:2 }).addTo(map);

    // L.control.coordinates().addTo(map);

// load layers and control
loadnode_layer();
</script>


Loadnode_layer() is ook wat aangepast met
JavaScript:
1
2
3
4
5
6
7
8
9
10
var nodelayer = L.layerGroup([<?=$nodes;?>]);
if (map.hasLayer(nodelayer)) { map.removeLayer(nodelayer); }
map.addLayer(nodelayer);
var baseMaps = {
    "Black Desert Map": bdo
};
var overlayMaps = {
    "Show Nodes": nodelayer
};
L.control.layers(baseMaps, overlayMaps).addTo(map);


Voer ik alles uit, dan verschijnt de layer icoon op de map, en even kijken of Nodes layer werkt.... inderdaad.
Ga ik even terug naar checkbox versie, dan krijg ik weer bekende foutmelding:

Fout: TypeError: layer.onAdd is not a function
Bronbestand: /script/leaflet-src.js

Zal dus nog moeten uitvogelen waar het probleem precies is en hoe het wel moet.
Maar door aanpassing van code krijg ik 2 layers voor terug en dan heb ik wel juiste basemap en overlaymap ingesteld, zodat het wel werkt. Dit was niet duidelijk aangegeven in de eerste code in de eerste post.

Ik ben in elk geval stukje verder. De raadsel van de checkbox probleem is alleen nog niet eruit.

[ Voor 42% gewijzigd door MrDummy op 10-03-2016 01:16 ]


Acties:
  • 0 Henk 'm!

  • q-enf0rcer.1
  • Registratie: Maart 2009
  • Laatst online: 09-10 14:44
Mijn gevoel zegt dat je hier de mist in gaat:

map.addLayer(nodelayer);

Ik weet niet hoe addLayer werkt in Leaflet, maar ik kan me niet voorstellen dat het de bedoeling is dat je hier de hele layergroup moet in knallen. Simpelweg omdat je volgens de methodname maar 1 layer kunt toevoegen.

Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
Je kunt meerdere layers toevoegen. De layer moet je van te voren definieren in een variabele. Dan wil het wel. Er is ook controle hasLayer() zodat je niet per ongeluk nog een layer overheen gooit.

De plattegrond met tiles is baseLayer.
Wat bovenop komt is overlayLayer, en dat kan gerust meerdere layers zijn.
De foutmelding komt doordat variabele "map" niet bestaat in de function. Met andere woorden, function ziet het niet.

De layergroup is een verzameling markers, samengevoegd als 1 groep.
Je moet maar voor je beeld eens tutorial uitproberen. Dan begrijp je ook wat beter.

Ik wil graag checkbox controle boven neerzetten. Omdat dat niet goed werkt, moet ik maar code bekijken van andere websites die wat hebben gemaakt.

Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
Ik ontdek iets tijdens Googlen een opvallende reactie waarbij bij mij een lampje gaat branden.
https://groups.google.com...ic/leaflet-js/xa7KfClLEpk

En het komt overeen met aantal problemen.
Ik heb niet overal global variabele gemaakt en zelfs binnen function script opnieuw VAR variabele opnieuw opgeroepen met dezelfde naam. Dat heb ik voorheen gedaan.

Met global (dus hoofscript):
"var nodelayer"

maar als ik ook in function script zet:
"var nodelayer"

Dit veroorzaakt reset van global en bestaat dus niet meer. Maar ik heb al geleerd dat aangemaakte variabelen binnen function niet naar buiten gaan en dus werkt het elders ook niet meer. Andere functions werken niet meer goed als ze proberen die variabele te gebruiken. Dan krijg je inderdaad foutmeldingen dat variabele anders is geworden en niet meer herkend is.

Ik heb nu script even nagelopen en onbedoelde VAR eraf gehaald binnen de functions zodat er niet per ongeluk een global gereset wordt. Met toevoegen van paar globals werkt het beter.
Nu kan ik wel aantal functies uitvoeren zoals ik heb verwacht, aantal foutmeldingen zijn weg.
Belangrijk om te onthouden: pas op dat je global niet ergens per ongeluk reset binnen function met VAR ervoor.

De probleem met checkbox is ook opgelost. De oorzaak is: er is geen global gemaakt (er is maar eentje binnen function namelijk) en dat werkt dus niet goed. Dat heb ik goedgezet en de foutmeldingen zijn weg.

[ Voor 8% gewijzigd door MrDummy op 11-03-2016 02:22 ]

Pagina: 1