New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Build clusters depending on some geographical entity #521

Closed
nerik opened this Issue Jun 30, 2015 · 16 comments

Comments

Projects
None yet
10 participants
@nerik

nerik commented Jun 30, 2015

Clusters are built purely with an algorithm. In many cases clustering markers depending on a given geographical entity is better (country, administrative region, zipcode, city, whatever).
People are familiar with such entities, and it avoids putting clusters in locations that don't feel 'natural'.

We developed a map where both algorithmical and 'geographical' approaches are used (depending on the zoom level) : https://thefoodassembly.com/
screen shot 2015-06-30 at 14 21 21

So we are both using Leaflet.markercluster and our own cluster logic. They are totally separated, which is a disadvantage because our own clusters don't benefit from Leaflet.markercluster animations, automatically created clickable polygons, and so on.

So my question is :
Would Leaflet.markercluster benefit from such a feature, or do you consider it out of scope?
I'll be doing a refacto of our codebase anyways so I got three options :

  • fork Leaflet.markercluster, do a PR with this geographical logic;
  • fork Leaflet.markercluster in a separate 'Leaflet.geomarkercluster' project;
  • build a separate 'Leaflet.geomarkercluster' project with a dependency to Leaflet.markercluster.

Would love some thoughts before coding any further :)

@danzel

This comment has been minimized.

Show comment
Hide comment
@danzel

danzel Jun 30, 2015

Member

I feel we had another Issue or PR about something similar lately, but I can't find it.
Recently I wanted to use MarkerCluster with a different implementation of L.DistanceGrid, which turned out to be quite hard.

I would be interested to see how this works, I suspect it would be done by replacing L.DistanceGrid for these?
https://github.com/Leaflet/Leaflet.markercluster/blob/master/src/MarkerClusterGroup.js#L765-L766

It could be good to make replacing this easier, then we could have a geographic (attribute based cluster) cluster implementation of it?

Member

danzel commented Jun 30, 2015

I feel we had another Issue or PR about something similar lately, but I can't find it.
Recently I wanted to use MarkerCluster with a different implementation of L.DistanceGrid, which turned out to be quite hard.

I would be interested to see how this works, I suspect it would be done by replacing L.DistanceGrid for these?
https://github.com/Leaflet/Leaflet.markercluster/blob/master/src/MarkerClusterGroup.js#L765-L766

It could be good to make replacing this easier, then we could have a geographic (attribute based cluster) cluster implementation of it?

@shharald

This comment has been minimized.

Show comment
Hide comment
@shharald

shharald Aug 7, 2015

Your map looks fantastic, and this feature would be a great addition to Leaflet.markercluster.

I was actually searching for exactly this for our student organisation, and wondering how I was going to go about it. Ideally, the home address of students in a particular university would be grouped into one university/city-cluster, which in turn would be clustered into country.

I hope you do it! :)

Ps. I do not understand the colour coding. At first I thought it depended on which day the food assembly was open, but that wasn't it.

shharald commented Aug 7, 2015

Your map looks fantastic, and this feature would be a great addition to Leaflet.markercluster.

I was actually searching for exactly this for our student organisation, and wondering how I was going to go about it. Ideally, the home address of students in a particular university would be grouped into one university/city-cluster, which in turn would be clustered into country.

I hope you do it! :)

Ps. I do not understand the colour coding. At first I thought it depended on which day the food assembly was open, but that wasn't it.

@nerik

This comment has been minimized.

Show comment
Hide comment
@nerik

nerik Aug 11, 2015

Thanks :)
Each food assembly has "theme" which gives them a little bit of identity, and the colored markers simply reflect that.

I'm trying to find the time to have a serious look at that, but I can't give you a date.
You should be able to hack a solution yourself in the meantime, just use regular markers for marker clusters, put them on a distinct layer which you'll show/hide depending on the zoom level. The most tedious part is to have to manually set clickable polygons to interact with the "false clusters".

nerik commented Aug 11, 2015

Thanks :)
Each food assembly has "theme" which gives them a little bit of identity, and the colored markers simply reflect that.

I'm trying to find the time to have a serious look at that, but I can't give you a date.
You should be able to hack a solution yourself in the meantime, just use regular markers for marker clusters, put them on a distinct layer which you'll show/hide depending on the zoom level. The most tedious part is to have to manually set clickable polygons to interact with the "false clusters".

@defelix

This comment has been minimized.

Show comment
Hide comment
@defelix

defelix Aug 11, 2015

Hi nerik.
Congratulations for the solution you implemented, I like it very much.
I ran into this because I am looking for a solution which clusterizes just points which are on the same exact position. I would be interested in investigating your solution of clusters based on geographical entity in order to grab some good ideas for my project.
Would it be possible to have more details? thanks a lot

defelix commented Aug 11, 2015

Hi nerik.
Congratulations for the solution you implemented, I like it very much.
I ran into this because I am looking for a solution which clusterizes just points which are on the same exact position. I would be interested in investigating your solution of clusters based on geographical entity in order to grab some good ideas for my project.
Would it be possible to have more details? thanks a lot

@ken-muturi

This comment has been minimized.

Show comment
Hide comment
@ken-muturi

ken-muturi Aug 21, 2015

Good Work nerik, I am impressed.
I like the idea that the cluster markers feel to be placed central to the geographical location.
Would it be possible to have more details? thanks

Good Work nerik, I am impressed.
I like the idea that the cluster markers feel to be placed central to the geographical location.
Would it be possible to have more details? thanks

@shharald

This comment has been minimized.

Show comment
Hide comment
@shharald

shharald Sep 5, 2015

A workaround that may work for some people is to display a dfferent set of markers depending on the zoom level. This would then mean not using the markercluster.

See http://jsfiddle.net/td2nyan4/1/

The example shows that the marker will show the country marker on high level, then universities, and when clicking on Berlin you'll be zoomed in on the city level and see the specific address markers.

shharald commented Sep 5, 2015

A workaround that may work for some people is to display a dfferent set of markers depending on the zoom level. This would then mean not using the markercluster.

See http://jsfiddle.net/td2nyan4/1/

The example shows that the marker will show the country marker on high level, then universities, and when clicking on Berlin you'll be zoomed in on the city level and see the specific address markers.

@ghybs

This comment has been minimized.

Show comment
Hide comment
@ghybs

ghybs Sep 14, 2015

Contributor

Hi all,

I am also interested in this kind of functionality.

I may be wrong, but it seems to me that if somehow we could nest instances of MarkerClusterGroup, we could easily build a hierarchical tree. Each level would cluster only the children that have themselves clustered to 1 object.

The assignment of markers is then delegated to the application, which can very well decide to assign markers based on their geographical containment in administrative areas (e.g. towns, countys, States, countries and so on, as seems to be needed by @nerik), or whatever criteria (e.g. clients assigned to a regional office, who might not be distributed following a truly fixed geographical rule), hence it is not bound to any predefined rule.

We could even force the clustering of a lower level below certain zoom levels, in order to directly display all countries for example. Otherwise, (geographically) smaller ones could be down to 1 object and may already start clustering each other, whereas big countries would still have several town clusters...

With this kind of solution, it would be quite easy to style every hierarchical level differently (cluster graphism, clustering rules - radius, etc.), or even each branch differently (e.g. one style per country), as this would require only styling a given instance of MarkerClusterGroup.

Now I do not know yet if such a technique would make sense, as it would require dozens of MarkerClusterGroups. What would be the performance cost?

I will try to make up a quick demo later and post it here.

Contributor

ghybs commented Sep 14, 2015

Hi all,

I am also interested in this kind of functionality.

I may be wrong, but it seems to me that if somehow we could nest instances of MarkerClusterGroup, we could easily build a hierarchical tree. Each level would cluster only the children that have themselves clustered to 1 object.

The assignment of markers is then delegated to the application, which can very well decide to assign markers based on their geographical containment in administrative areas (e.g. towns, countys, States, countries and so on, as seems to be needed by @nerik), or whatever criteria (e.g. clients assigned to a regional office, who might not be distributed following a truly fixed geographical rule), hence it is not bound to any predefined rule.

We could even force the clustering of a lower level below certain zoom levels, in order to directly display all countries for example. Otherwise, (geographically) smaller ones could be down to 1 object and may already start clustering each other, whereas big countries would still have several town clusters...

With this kind of solution, it would be quite easy to style every hierarchical level differently (cluster graphism, clustering rules - radius, etc.), or even each branch differently (e.g. one style per country), as this would require only styling a given instance of MarkerClusterGroup.

Now I do not know yet if such a technique would make sense, as it would require dozens of MarkerClusterGroups. What would be the performance cost?

I will try to make up a quick demo later and post it here.

@ghybs

This comment has been minimized.

Show comment
Hide comment
@ghybs

ghybs Sep 24, 2015

Contributor

Hi all,

I do not know if many of you are still interested in this, but here is a demo of nesting Marker Cluster Groups in a hierarchical tree: http://ghybs.github.io/Leaflet.markercluster/hierarchical-tree-of-groups/

It shows USA > States > Counties > Cities (not displayed initially, because it takes a few dozen seconds to compute them; just update the map with the bottom left panel options if you are ready to wait for the processing)

The base data is quite heavy (~5MiB uncompressed, for 30k+ data points), so you may have to wait a few moments before the data is displayed the first time. I apologize, next time I will choose a less data-intensive example.

Cheers!

Contributor

ghybs commented Sep 24, 2015

Hi all,

I do not know if many of you are still interested in this, but here is a demo of nesting Marker Cluster Groups in a hierarchical tree: http://ghybs.github.io/Leaflet.markercluster/hierarchical-tree-of-groups/

It shows USA > States > Counties > Cities (not displayed initially, because it takes a few dozen seconds to compute them; just update the map with the bottom left panel options if you are ready to wait for the processing)

The base data is quite heavy (~5MiB uncompressed, for 30k+ data points), so you may have to wait a few moments before the data is displayed the first time. I apologize, next time I will choose a less data-intensive example.

Cheers!

@shharald

This comment has been minimized.

Show comment
Hide comment
@shharald

shharald Sep 25, 2015

Looks impressive! I haven't had time to look at the code-behind, but this can be very useful. I think in most cases there will not be that many data points, although performance is always a question.

Looks impressive! I haven't had time to look at the code-behind, but this can be very useful. I think in most cases there will not be that many data points, although performance is always a question.

@lovethisshit

This comment has been minimized.

Show comment
Hide comment
@lovethisshit

lovethisshit Oct 28, 2015

Hi,
I'm watching this issue for a while now since we want to do kind of the same thing with leaflet - region/area based clustering. With country boundaries as polygons I feel like a step closer, since I just need to do the following now:

  • get the latlng of a marker
  • check which boundary may include it
  • add it into a cluster with these bounds

But important question is: How can I implement my own clustering function? Had a look at the markercluster source but I got lost - so if someone can give me a hint I would be glad!

Hi,
I'm watching this issue for a while now since we want to do kind of the same thing with leaflet - region/area based clustering. With country boundaries as polygons I feel like a step closer, since I just need to do the following now:

  • get the latlng of a marker
  • check which boundary may include it
  • add it into a cluster with these bounds

But important question is: How can I implement my own clustering function? Had a look at the markercluster source but I got lost - so if someone can give me a hint I would be glad!

@ghybs

This comment has been minimized.

Show comment
Hide comment
@ghybs

ghybs Oct 28, 2015

Contributor

Hi,

What exactly are you trying to achieve? What do you mean by implementing your own clustering function?

If you do not need your country top cluster to cluster with other sibling country clusters, then you could simply create one MCG per country. Since you assign yourself the markers to the appropriate country MCG, they will cluster only with markers within the same MCG, hence from the same country.

If you also want the cluster to split into all its individual markers in one click, simply use the disableClusteringAtZoom option.

But if you DO want sibling country clusters to merge together once they have collected all their children markers, this is a big step in complexity. I achieved this in my above demo, but I am still wondering how to generalize this code in a robust way, and whether this should be a separate plugin or if it can be embedded in MCG code, as it is mainly modifying the core functions to support more cases.

Hope this helps.

Contributor

ghybs commented Oct 28, 2015

Hi,

What exactly are you trying to achieve? What do you mean by implementing your own clustering function?

If you do not need your country top cluster to cluster with other sibling country clusters, then you could simply create one MCG per country. Since you assign yourself the markers to the appropriate country MCG, they will cluster only with markers within the same MCG, hence from the same country.

If you also want the cluster to split into all its individual markers in one click, simply use the disableClusteringAtZoom option.

But if you DO want sibling country clusters to merge together once they have collected all their children markers, this is a big step in complexity. I achieved this in my above demo, but I am still wondering how to generalize this code in a robust way, and whether this should be a separate plugin or if it can be embedded in MCG code, as it is mainly modifying the core functions to support more cases.

Hope this helps.

@danzel

This comment has been minimized.

Show comment
Hide comment
@danzel

danzel Dec 22, 2015

Member

Closing, example provided by ghybs shows how to implement this outside of L.MarkerCluster

Member

danzel commented Dec 22, 2015

Closing, example provided by ghybs shows how to implement this outside of L.MarkerCluster

@xiaofanwu

This comment has been minimized.

Show comment
Hide comment
@xiaofanwu

xiaofanwu Jul 8, 2016

@nerik Hi Nerik,

Do you mind share you source code. I am working on a similar problem and would love to learn something from you did! Thanks!

@nerik Hi Nerik,

Do you mind share you source code. I am working on a similar problem and would love to learn something from you did! Thanks!

@kavinsky-

This comment has been minimized.

Show comment
Hide comment
@kavinsky-

kavinsky- Jun 15, 2017

Hi @ghybs

I really need this functionality, but your demo is not available, do you mind sharing it again ?
Thanks in advance :)

Hi @ghybs

I really need this functionality, but your demo is not available, do you mind sharing it again ?
Thanks in advance :)

@ghybs

This comment has been minimized.

Show comment
Hide comment
@ghybs

ghybs Jun 15, 2017

Contributor

Hi @kavinsky-,

Hum I am afraid I accidentally deleted the branch a few days ago unfortunately… T_T
I might have a local copy somewhere on an external drive, I will see if I can find it in the next days.

But to be honest, even though the demo was functional, it required highly modifying the code of Leaflet.markercluster about everywhere, so it was kind of bound to that particular version, which is quite old now (I think it was still on Leaflet 0.7).

I think it should be possible to do a better job, especially in turning it into a plugin, but that would certainly require quite some time to re-engineer it.

Sorry I cannot help you right now…

Contributor

ghybs commented Jun 15, 2017

Hi @kavinsky-,

Hum I am afraid I accidentally deleted the branch a few days ago unfortunately… T_T
I might have a local copy somewhere on an external drive, I will see if I can find it in the next days.

But to be honest, even though the demo was functional, it required highly modifying the code of Leaflet.markercluster about everywhere, so it was kind of bound to that particular version, which is quite old now (I think it was still on Leaflet 0.7).

I think it should be possible to do a better job, especially in turning it into a plugin, but that would certainly require quite some time to re-engineer it.

Sorry I cannot help you right now…

@Abir1988

This comment has been minimized.

Show comment
Hide comment
@Abir1988

Abir1988 Nov 21, 2017

Hi,

Is there any option to achieve the following protoype.

Continent >Country > States > Cities

Abir1988 commented Nov 21, 2017

Hi,

Is there any option to achieve the following protoype.

Continent >Country > States > Cities

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment