2

I am going thru a development feature for a map based application wherein I need to do two things:

  1. Detect which all shapes are overlapped on one another (coordinates match).
  2. Click on the top of them to split them up

Here is the picture of the requirement to get the clear understanding of it:

click here to see the requirement image

So in this image, left state is the default one and the right one is, once we click on them and that state becomes split state wherein all the shapes are kinda scattered but connected with the label name which is "G108" in this case.

These two shapes data will be coming from two different APIs. What I need to do detect is the overlapping. So do I need to loop over the children inside a "stage" element provided by the createJs which seems to a time consuming? So on what basis should detection be checked? There could be 3 or 4 shapes getting plotted from various APIs and have no relation with one another.

For splitting, what could be the approach to handle it?

Here is the stackblitz link, in case you might want to try it out. I've implemented a default scenario.

Libraries being used:

  1. Leaflet for map features
  2. Custom Layer for canvas
  3. For implementing these two shapes, create JS

I would really appreciate if you could suggest me or share an approach or help in this regard.

James Z
  • 12,209
  • 10
  • 24
  • 44
jogo
  • 25
  • 7
  • @FalkeDesign Hey there, in case if you've any idea on this, please comment. Thank you. – jogo Jun 21 '21 at 13:04
  • Oof this might be more complicated than you think. I do not know the library so there might be a built-in way. But if not... are we just talking about rectangles and circles? – Elias Jun 21 '21 at 14:31
  • @Elias thank you for your comment. Yes. It's like rectangles are from the API 1 and circles from API 2 , some of them are sharing same coordinates, hence overlapping – jogo Jun 21 '21 at 15:02
  • I would recommend looking into [leaflet markercluster](https://github.com/Leaflet/Leaflet.markercluster) and using that as a starting point. It already comes with sipderify-on-click functionality, which is what you're looking for. However, you'll need to [customize the cluster icon](https://github.com/Leaflet/Leaflet.markercluster#customising-the-clustered-markers), as well as the markers themselves. Depending on the type of data coming back from the server, this may not be easy, but I'd start with that plugin first – Seth Lutske Jun 21 '21 at 16:44
  • @SethLutske Thank you for your comment. It works with GEOJSON kinda format data I think and something which is native to leaflet. In my case, plotting of data is happening thru createJS but still I will have a look into that. – jogo Jun 21 '21 at 17:23

2 Answers2

1

You don't really need a library for this. You don't really need to check if the two shapes overlap. You don't even need to click. All you need is to check if your mouse is inside both paths (shapes) by CanvasRenderingContext2D.isPointInPath(). If both is true then animate them away from eachother the way you like.

Redu
  • 25,060
  • 6
  • 56
  • 76
  • Thank you for your answer. Since I am using a library for my drawings not Canvas native I wonder how and where I am gonna use this. Still I will check this out. Do you have any example for this where something similar is done ? – jogo Jun 21 '21 at 17:25
  • I feel like this answer needs some details and even an example...its a bit hand-wave-ey – Seth Lutske Jun 21 '21 at 19:33
  • @Seth Lutske Yes right, but i don't really have time to do it right now. I have just intended to give the directions at first. I will edit my answer to include an example at my earliest convenience your honour. :) – Redu Jun 21 '21 at 19:37
0

I was able to accomplish this with the user of leaflet-markercluster and leaflet-canvasicon.

Create custom icons

import "leaflet-canvasicon";

export const circleIcon = L.canvasIcon({
  iconSize: [50, 50],
  iconAnchor: [25, 25],
  fillStyle: "rgba(255,0,0,.5)",
  drawIcon: function (icon, type) {
    // canvas code here - maybe you can use create-js?
  }
});

export const squareIcon = L.canvasIcon({
  // options and drawIcon function
});

export const combinedIcon = L.canvasIcon({
  // options and drawIcon function which combined both of the above
});

Create a markercluster using these icons:

const marker1 = L.marker(center, {
  icon: circleIcon
});

const marker2 = L.marker(center, {
  icon: squareIcon
});

const group = L.markerClusterGroup({
  iconCreateFunction: function (cluster) {
    return combinedIcon;
  }
});

group.addLayer(marker1).addLayer(marker2);
group.addTo(map);

Working codesandbox

This will take some careful tweaking of the drawIcon functions to get right. You may be able to combine this with create-js. But this is an option. Also my example works on click, not hover, so you may have to

Seth Lutske
  • 9,154
  • 5
  • 29
  • 78