Click event handling for draw features in Openlayers 3` - javascript

I have implemented the following example from the Openlayers 3 library where you can measure lines and areas.
http://openlayers.org/en/latest/examples/measure.html
Specifically for areas, to complete the shape you can either double click at the last vertex you want to draw, or single click back at the start of the shape when the cursor snaps to the original point.
I have an issue whereby many users are taking their cursor back to the original point and it is snapping, but they are double clicking thinking therefore completing the original shape and inadvertently starting a new one.
How am I able to code this example so that if a double click occurs at the original point, then the shape is completed but a new shape not started?
Thanks

You can set property snapTolerance into 1, it should help:
new ol.interaction.Draw( {
snapTolerance: 1,
...
You still can finish shape with single click, but you have to click exactly in the first point.
I set snapTolerance for myself some time before and people are happy now :).

Related

Dygraph how to always show values in the legend

Is it possible to always show the values of the signals in the legend even when the mouse is not over the figure?
I think values appearing and disappearing when the mouse is not over the figure are a bit annoying and I would like to come up with a solution which:
Until the user goes over the figure with the mouse, the legend shows signal names and their values at x = 0
While the user moves the mouse on the figure the legend should work as usual (i.e. being interactive)
When the mouse is no longer over the figure the legend shows last values pointed
Would it be possible to get something like this? If yes, how?
EDIT: I found out there are callbacks sensitive to mouse events. In particular, highlightCallback and unhighlightCallback may be used to obtain what I want. Unfortunately, I do not find any example that shows how to change what's shown in the legend, I've only found examples which add HTML below the figure, like in this callback example.
The numbers in the legend reflect the current selection. If there's no selection, there will be no numbers. So try calling setSelection in unhighlightCallback.
Alternatively, use the new legendFormatter option. (Until v2 is released, this will require you to build dygraphs from HEAD.)

How to change the order of a layer when set visible in openlayers?

I am working on a website that uses OpenLayers to draw a map and add layers of information on top of it. Everything works fine but one thing.
When I add a new layer of information, I want it to be on top of the other layers, but when add a layer of information before, I want to other layers to be on top.
My point is: The last clicked should be on top.
Right now, when I want to set the visibility of the layer to yes, this is was is triggered:
myLayer.setVisibility(true);
map.setLayerIndex(myLayer, 700);
I tried replacing the 700 by a really high value and it changed nothing. I also tried this:
map.raiseLayer(myLayer, map.layers.length);
But nothing seems to work. The layer still appears under the other layers...
Please if you have an idea, tell me.
Thanks in advance for the help!
PS: This is the website (not sure if you can see it):
http://labqc.wul.qc.ec.gc.ca/MetViewer/
To test, you have to select a layer on the left (images will be shown) then you click the (+) icon at the top-right to select the layer, and you add, let's say BV - Canada. Polygons will appear under the image insteaf of on top, I want the reverse situation.
.
You need to explicitly request that the layer redraws itself, after you have used the raiseLayer or setLayerIndex functions, as these functions do not automatically trigger a redraw: see http://trac.osgeo.org/openlayers/browser/trunk/openlayers/lib/OpenLayers/Map.js. A simple
this.redraw();
or
map.layers[layerIndex].redraw();
depending on where you are handling this from, should be enough.

Finding the minimum translation vector using intersection points

I'm building an application based on Paper.js.
I have a list of items, each composed from a top level group and a bunch of paths as children.
I need to implement collision detection, which currently works like so:
When an item is dragged, its components (the paths it's comprised of) are checked against any other path in the same layer using the
Path#getIntersections(path) method.
If the method returns a non empty array (of CurveLocations, which describe the points of intersection) I know there's a collision. I
stop dragging and combine the items.
If the returned array is empty, there's no collision to handle so no need to interrupt the drag. I translate (move) the dragged item by
the distance it was dragged.
And now, here's what I need to do in step 2:
Upon detecting a collision, I need to move the item to the nearest
"legal" position (the closest to the current mouse position without
overlapping any other shape/border).
Now I can go about implementing SAT or GJK and solving it without the getIntersections method, but the only thing I'm lacking here is the MTV (if I'm not mistaken).
Can someone please confirm if this is either possible or not, and if it is, then how?
Update
After some fiddling with the various mouse events, I've come to a current (imperfect) solution:
onMouseDown: Save the mouse offset (item position minus mouse position)
onMouseDrag: Check for intersections. If so, translate the dragged object by event.delta.negate() while the check returns true. When done, update the offset.
If no intersection is detected, just move the dragged item to the mouse position minus offset.
onMouseUp: The same as in the drag event, except if no collision is detected then do nothing.
This is more or less working, except it's jittery and it doesn't deal with containment.
Will update with an example as time permits.
If you only have two shapes and they are all quite close to circles and boxes and have similar sizes you could get the center of the bounding box of the shapes and use those center points as a direction vector. Then you move it incrementally away until there is no intersection anymore. But if you have shapes like a U or O that surround another smaller shape it is likely that this method will not give the shortest distance. The same if the moving away will hit other objects.
So I think what you really need is a numerical solution that moves the shape away from its center point in a circular fashion with growing diameter until there wont be any intersections anymore.
Another problem could be when your shape is enclosed in another shape and you will not even have any intersections. So I guess it would be better to use hittest.
Edit:
Here is a very easy not very well optimized example of what I tried to explain with the middle points. Reload it if you do not see any overlays. For the circular way the checking just gets more complicated because you would move the shape not only away but also in all other kind of directions.
Edit2: Second example that checks for intersection and moves the shape outside. As you can see intersection alone is not enough to check for if the obstacle gets bigger than the dragged item.

KineticJS - Draw free with mouse

I'm building a canvas paint tool where the use simply drags his mouse to draw on the canvas. As I understand it lines is the best way for the job. So on mouse down I create a KineticJS Line object and when the user drags I add a point between the last mouse position and the current. Note, I only have one line object that has multiple points.
When the user releases his mouse the Line is finished and whenever you click again to draw more, I create a new line object.
Problem with this is that if you are going to draw a text, say "My name is x" That would result in many line objects, 1 for each character (and 2 for "x" and "i").
Is there a better way to do this? My idea was to have only one line object, and onmousedown you simply not add a line from the previous position, and then when u drag you do. But I don't think KineticJS Line supports that.
So basically, can I improve the way I let the user draw?
Your current design of having 1-2 polylines that define one letter is fine.
Both canvas and Kinetic can support a whole paragraph of characters before lagging in performance.
If you want 1 single definition for a whole sentence, you can use a custom Kinetic.Shape.
With Shape, you get full access to a wrapped canvas context. You could use that context to do your second idea--a single context.path drawing a sentence through a saved set of moveTo and lineTo commands.
Personally I would go with your current design (1-2 polylines per character) because the performance is fine and you get more flexibility. (For example, if you want to draw the person's name in a different color is easier in your current design).

Getting Click Event for Editable Polygon Point (Google Maps API v3)

When drawing an editable Polygon on a map using Google's V3 API, is there some event I could register for that tells me when one of the polygon's points (only made visible by the editable flag) is clicked? I want to be able to enable a user to draw a polygon, using right clicks, and "complete" the polygon by clicking on the first point plotted. I begin by creating a Polygon of one point, and add each successive point with each right-click. I use the mousemove event to create two "completion" lines, two fainter lines (two Polylines) from the last point plotted to the current mouse position on the map, and from the current mouse position on the map to the first ("anchor") point. When I click on that first point, I'd like to be able to "finish" the Polygon, by taking away these completion lines, inferring the intent of the user now to either edit the points already drawn with the handles the editable Polygon provides, or save the Polygon's coordinates to my application.
Is there a way to do this? (As I've written this, I've thought of one solution: create a small circle, invisible, around the first ("anchor") point, and detect when that invisible circle is clicked. But I wanted to see if there was something built-in in the API that I could use.)
Are you trying to roll your own polygon editor? I would suggest using the drawing library instead:
http://code.google.com/apis/maps/documentation/javascript/overlays.html#drawing_tools
Also see events section:
http://code.google.com/apis/maps/documentation/javascript/reference.html#DrawingManager

Categories

Resources