Closed alextychan closed 6 years ago
In my opinion, you can just add the copied elements to labelleddata object by generating new Ids for each shape. And then reload the workarea tag. In this way your code will reduce and you've not have to take care of attaching events.
I understand that your suggestion is to use this: //use the new IDs : shapetype + shapeIndex, shapetype + shapeIndex + point + pointIndex
The thing I'm not sure about is how do I generate unique ID's that do not overlap. This is because one shape can be copied and pasted multiple times.
Do I need to keep a count of all the shapes and points in a separate global variable for this? e.g. shapeIndex = 1, pointIndex = 1
you need not to keep the count. Instead you can check the length of already added shapes and add one to it. ${image_index}_${shape_type}_${image1.shapes.length}
From my perspective, there might be a bug if implemented that way. Here's a simple example.
eg. User creates polygon#1, then copies and paste 2 times. Now there are 3 polygons(image1.shapes.length = 3). Polygon#1, Polygon#2, Polygon#3
User removes polygon#2. Now we have 2 polygons(image1.shapes.length = 2): Polygon#1, Polygon#3
User copies and paste a new polygon. Now we have 3 polygons(image1.shapes.length = 3): Polygon#1, Polygon#3, Polygon#3
Now we have 2 polygons with the same ids. That's why I thought we might need something like a global count that only increments, so that the ID's will always be unique.
Could you provide an example of your idea for comparison? Thanks.
Hmm.. agree with your point.
One more issue, data is temporarily saved in browser. If we have a global counter starts from 1 (let's suppose), we restart the application, data will be loaded from browser, but the counter will reset to 1. And we can get duplicate id again.
what if calculate the highest id assigned to a shape for particular image? (we can remove any prefix from the id to make it simple)
You also raised a good point. I didn't think about the browser cache.
Would you say that storing the global variable in labellingData is a good idea? My thought process is that each image shall hold a counter that can be used as a unique ID. So image 1, 2, 3, all have individual counters.
The benefit of doing that would be that each image has a separate counter and the data would automatically be stored in our save files. Besides that, we don't need to compute the highest id, as that might be costly if we have a large dataset.
The labellingData schema would look like this
labellingData: { 'imageName': { ... 'shapes', 'shapeindex' #polygon/shape counter } }
Well! we were planning to store application conifguration in browser cache ( image opacity, point size and color etc). But counter may not be suitable because it'll keep increasing otherwise. However I doubt it is ever gonna to reach to it's maximum value. But just a thought.
I've observed people labeling up to 350 images in a session. Assume there are 3 shape on each image and each shape has approx 120 feature points. We can have 350 x 3 x 120 = 126000 points. Now let's suppose, use copy paste each shape 2-3 times. We are still fine.
So ok you can go with that approach. But in this case, persist the app configuration in browser cache not the single counter.
I hope there is no other condition which may duplicate the Ids.
I missed your point to have counter for each image. Yeas you can do that as well
It took me a while, but I managed to fix a bug with the positioning. The bug was as follows.
Add a new feature point after copy pasting. The result is that the point is drawn on the canvas wrongly but the coordinates were correct.
Problem:
When adding a new point, in getPointToDraw, the containerOffset was incorrect. This is because of the plugin "svg-pan-zoom". The plugin adds a new
Note: Groups do not have a geometry of their own, it's inherited from their content. Therefore groups do not listen to x, y, width, and height attributes.
Solution: Just make sure the containerOffset referenced the correct parent.
Here's a brief description of the current implementation.
"Copy" will grab the shape and point metadata and store it in copiedElements array. The reason I store metadata rather than the object itself is to allow copy-pasting between images, because some metadata requires context that changes, like shape.rbox(myCanvas).
"Paste" will add all the shapes and points into the image, then call self.update() which redraws the current shapes in the image.
Note: There is a small bug in the "getPoints" function regarding the polygon points. The issue was the same as the wrongly drawn points. The container we grabbed was the
As for the number of shapes possible, that shouldn't be a problem as the Javascript max int is pretty large.
The MAX_SAFE_INTEGER constant has a value of 9007199254740991 (9,007,199,254,740,991 or ~9 quadrillion).
That goes for the number of points as well.
I've also noticed that after drawing a shape and adding a point. When you zoom in and add a point, the position of the point is incorrect. I suspect that has something to do with zoomScale. But that should be saved for another issue. This issue exists in the original implementation as well.
Purpose / Goal
Implemented copy paste svg elements.
Notes: 1) My implementation works by copying then instantiating the attributes of all selected shapes and points. 2) The code may need to be refactored, but I'm not exactly sure how. There are similarities between the functions in "paste" and "drawOnCanvas".
In conjunction with issue #53
Type
Please mention the type of PR
Note : Please ensure that you've read contribution guidelines before raising this PR.