0

I have one array of places which i am displaying in in a table and also in Map. I am displaying marker and one of either circle or polygon for each element in table. When i select ant element from table marker icon changes for that particular element. I also have one slider to change the radius of circles for every element. All this is happening successfully but i want to separate marker, circle and polygon layer separately and then group them using layerGroup so that when i change radius i only update circle layer(right now i have to reset layer and update marker, polygon and circle). Same way if i select any element in table then i should need to update only marker layer and not all three. I have tried to group layers like this:

    updateLayers(layerData) {
    this.marker = [];
    for (const ld of layerData) {
      this.marker.push(
        marker([ld['latitude'], ld['longitude']], {
          icon: icon({
            iconSize: [20, 32],
            iconAnchor: [10, 16],
            iconUrl: this.selectedPlaces.indexOf(ld) !== -1 ? this.iconEnablelink : this.iconDisableLink
          })
        }),
        // ld['geofence_type'] && ld['geofence_type'] == 'POLYGON' ? polygon([ld['geofence']['coordinates'][0][0]]) : circle([ld['latitude'], ld['longitude']], { radius: this.radius }),
      );
    }
    console.log('lg', layerGroup([this.marker]));
    this.layers = layerGroup([this.marker]);
  }

Response is some this:

   options: {}
   _initHooksCalled: true
   _layers: {45: Array(25)}
   __proto__: NewClass

I am getting following error: "Error trying to diff '[object Object]'. Only arrays and iterables are allowed"

Is there any way to implement this efficiently.

Edit: Below is working code. Everytime i click on a checkbox i add or remove that element to selectedPlaces. Then i call this function. Even on slider change i have to call this function again and again. I am using marker, polygon and slider in the layers but i want to separate layers in three parts so that when i select any element i update only marker (if possible then marker for that particular element) and not all circles and polygons. If i update radius using slider then i should be able to update only circles without modifying markers and polygons.

updateLayers(layerData) {
this.layers = [];
for (const ld of layerData) {
  this.layers.push(
    marker([ld['latitude'], ld['longitude']], {
      icon: icon({
        iconSize: [20, 32],
        iconAnchor: [10, 16],
        iconUrl: this.selectedPlaces.indexOf(ld) !== -1 ? this.iconEnablelink : this.iconDisableLink
      })
    }),
    ld['geofence_type'] && ld['geofence_type'] == 'POLYGON' ? polygon([ld['geofence']['coordinates'][0][0]]) : circle([ld['latitude'], ld['longitude']], { radius: this.radius }),
  );
}
Naresh Mobarsa
  • 101
  • 1
  • 9
  • This has nothing to do with Angular. – gotnull May 29 '18 at 06:36
  • You talk about a lot of functionalities but do not show up much code or even screenshot. Hard to understand what you describe, what you are trying to achieve, and what could cause the error you show. – ghybs May 29 '18 at 06:45
  • @ghybs I have edited my question. This function is where i am updating all my layers. You see on every change i am resetting layers to empty and then adding all the markers, circles and polygons. I wanted to separate this so that if i am changing then i only update circle layers. If i am selecting or removing any element then i only update marker for that particular element. – Naresh Mobarsa May 29 '18 at 07:36

2 Answers2

0

If I understand correctly, you just want to change the radius of all your circles when you use your slider.

You already built some Leaflet layers and stored them in a Layer Group in your this.layers property.

In that case, you would simply:

  1. Iterate the layers in your Layer Group with the eachLayer method.
  2. Check if the layer is an instance of L.Circle (or Circle if you import {circle, Circle} from 'leaflet')
  3. Change the Circle radius using its setRadius method.

var paris = [48.86, 2.35];
var map = L.map('map').setView(paris, 11);
var group = L.layerGroup().addTo(map);

document.getElementById('radius').addEventListener('input', changeRadius);

function changeRadius(event) {
  var newRadius = event.target.value;

  group.eachLayer(function(layer) {
    if (layer instanceof L.Circle) {
      layer.setRadius(newRadius);
    }
  });
}

var circle = L.circle(paris, {
  radius: 1000,
}).addTo(group);

var marker = L.marker(paris).addTo(group);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>

<input id="radius" type="range" min=500 max=3000 value=1000 />
<div id="map" style="height: 160px"></div>
ghybs
  • 47,565
  • 6
  • 74
  • 99
0

I think the issue is you're assigning this.layers directly to a layerGroup, which isn't allowed. this.layers needs to be an array or an iterable (which is why you're getting the error).

Try this instead:

updateLayers(layerData) {
    this.marker = [];

    ...

    console.log('lg', layerGroup([this.marker]));
    this.layers = [ layerGroup([this.marker]) ];
}

The ngx-leaflet plugin expects this.layers to be an array. It can be an array of anything that Leaflet recognizes as a Layer. Which means it can be an array of layerGroups... e.g.:

this.layers = [ layerGroup([...], layerGroup[...], ...];
reblace
  • 4,115
  • 16
  • 16