Get beginning, end co-ordinates & radius of circle drawn in leaflet.js


#1

Hi, trying to work out the code for the co-ordinates at the beginning of drawing a circle, the end of having drawn the circle as well as the radius of the circle in leaflet.js and want to print the results to the console. So far I have the following but cannot work out how to do precisely the beginning, end and radius of circle:

map.on('draw:created', function (e) {
    var type = e.layerType;
    var layer = e.layer;
    var latLngs;

    if (type === 'circle') {
       latLngs = layer.getLatLng();
       console.log("Coordinates: " + latLngs.toString());
    }
    else
       latLngs = layer.getLatLngs(); // Returns an array of the points in the path.

    // process latLngs as you see fit and then save
}) 

Any ideas how to do this?


#2

Well, for starters, the coordinates at the beginning and ending of drawing an actual circle would be the same. That’s how circles (or any polygon) work. They end where they began.

In truth, a circle is better defined by it’s centerpoint and radius than positions, and in fact, you’ll find that’s what Leaflet defines a circle by.

that documentation also specifies that a leaflet circle defines methods for examining it: getLatLng, getRadius.
In a flat plane, valid coordinates of the circle would be Radius distance from the Midpoint. a^2 + b^2 = c^2, or in geometric terms, a point with angle theta from the positive X axis with origin at the center of the circle is formulaic as R * sin(theta) = y, R * cos(theta) = x.


#3

Thank you, that was about as useful as balls on a bishop. If I was looking for the mathematical functions of a circle, PI, the irrational nature of PI, its relation with time as a function of numbers to infinity or the multidimensional nature of reality as implied by all this within the theory of complex numbers then I’d have asked.

However I asked how to get the co-ordinates from a leaflet.js map when you start to draw a circle (its centrepoint at the beginning) to when you stop drawing it (its co-ordinates at the outer edge), including its radius. I find the relationship between layers, events and the circle function/object confusing and since the rules of languages are to a great degree arbitrary, then parsed and compiled down to machine code, I would like someone to tell me the specific code needed to achieve this probably simple operation. Thank you.


#4

The question regarding the start and end coordinates of the circle seems to be as useful too, as it’s an x/y point and the radius that defines the circle. The circle is drawn as an SVG object.

For example:

<path class="leaflet-interactive" stroke="red" stroke-opacity="1"
  stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="#f03"
  fill-opacity="0.5" fill-rule="evenodd"
  d="M793.2035555555485,371.94704600190744a42,42 0 1,0 84,0 a42,42 0 1,0 -84,0 ">
</path>

Run up the debugger when you enter the draw:created event handler, and you can easily explore the event object. Here’s the lat, long, and radius of another circle:

e.layer
editing: e {_shape: e, options: {…}, _initHooksCalled: true}
options: {stroke: true, color: "#f06eaa", weight: 4, opacity: 0.5, fill: true, …}
_events: {add: Array(1), remove: Array(1)}
_initHooksCalled: true
_latlng: M {lat: 51.5255134425896, lng: -0.11020660400390626}
_mRadius: 806.9009495750907
__proto__: e

#5

Apparently all you guys find it difficult to answer a simple question without thinking a demonstration of unrelated expertise is either interesting or germane. As I have pointed out on stackoverflow, programming is no longer just yours, it is not ‘MY TERRITORY!!’ which is what your overcomplication is silently saying, roaring in fact. As if I and others who don’t know what you know have no right to be here, no right to have our questions answered simply and strightforwardly, that it’s beneath your dignity to simply answer the question.

Programming belongs to all of us now, it is across all of society, it is a question of general literacy and general accessibility. It is a question of political and cultural control on the part of all that far outstrips your limited conception of ‘MY TERRITORY!!’.

Thank you.


#6

I don’t think that it’s appropriate for me to assume that you know nothing, and spell out every single little step.

If you don’t know how to do something, then just ask.


#7

It is possible to convert polar (vector) into cartesian (raster) but it is no simple thing. It requires working with trigonometry (sine, cosine)

https://www.mathsisfun.com/polar-cartesian-coordinates.html

IMHO if the script is designed to work with vectors it would likely be easier to give it what it wants and let it do the work.


#8

Alternatively you can take the x/y coordinate and subtract the radius from the x value. That then is a coordinate for a start and end location of the circle.


#9

I provided the code in my question at the outset to show the kind of solution I was looking for (and others no doubt who will also benefit from knowing it). Specifically, the code at the beginning gets the co-ords (lat & long) of the cursor at the end of having drawn the circle and prints these to the console. It does this using an event handler called ‘draw:created’. I have copied and pasted this code into the same page and replaced ‘draw:created’ with draw:start’, ‘draw’ and whatever else I could think of, to no avail, in an effort to get it to give me the starting co-ords (the centrepoint of the circle).

I have looked in the documentation but cannot find whatever other event handler phrase I am supposed to use or if some other code entirely is required to get the starting co-ords. Also what is required to get the radius at the end and print it to the console, even though it is shown on the screen at the end of drawing the circle.

I’m using the full.html example from this leaflet plugin on github: https://github.com/Leaflet/Leaflet.draw/tree/develop/docs/examples.

This is what I am trying to do. Thank you.


#10

If you didn’t notice it from my post, the event object seems to have the information that you want.

The layer information is in regard to the coordinates of the map, and you can get the SVG element to find out the coordinates on the screen.

I like to place debugger at the start of the event function, so that when I have the browser console open, the code execution pauses right there and I can easily investigate things, like the event object.

Am I correct to understand that you want to get from the create circle event, to screen coordinate information about the circle that’s being created?

If I’m misunderstanding what you’re asking about, then please let me know.


#11

On the assumption that you’re wanting screen coordinates, I figured out how to get the SVG element from the draw:created event, which is the on-screen circle.

    var overlayPane = e.target._panes.overlayPane;
    var circle = overlayPane.querySelector("g:last-child");

I use last-child there because when other elements are added, last-child then refers to the most recent circle.

The circle variable refers to the <g> element.

<svg pointer-events="none" class="leaflet-zoom-animated" width="1520" height="960" viewBox="-170 -122 1520 960" style="transform: translate3d(-170px, -122px, 0px);">
  <g>
    <path class="leaflet-interactive" stroke="#f06eaa" stroke-opacity="0.5" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="#f06eaa" fill-opacity="0.2" fill-rule="evenodd" d="M490,298.99471686128527a67,67 0 1,0 134,0 a67,67 0 1,0 -134,0 ">
    </path>
  </g>
</svg>

And when it comes to working with SVG elements, there’s what looks to be a good article about it called How to Translate from DOM to SVG Coordinates and Back Again

That looks like it’ll get you to your desired DOM screen coordinates.


#12

Here’s a tip. You can use the getBoundingClientRect() method to get information about the SVG element.
That gives you top, bottom, left, right, and more information.

For example:

circle.getBoundingClientRect()

bottom: 349.99407958984375
height: 141.99996948242188
left: 487
right: 629
top: 207.99411010742188
width: 142
x: 487
y: 207.99411010742188

In terms of on-screen coordinates:

  • Halfway between the left and right values is the horizontal centre of the circle.
  • Halfway between the top and bottom values is the vertical centre of the circle.
  • And half of the difference between left and right, is the radius of the circle.

For this example, that gives x=558, y=279, r=71


#13

Right, I’ve found a solution to this issue that may help others. It has the character of Paul Pogba falling forward with limbs flying all over the place, held together by sticky tape. But it works!

To find the co-ordinates at the beginning of drawing the circle (its centrepoint) and print them to the console:

map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
console.log(layer.toGeoJSON());
drawnItems.addLayer(layer);
});

To find the co-ordinates at the end of drawing the circle plus its radius and print them to the console:

map.on(‘draw:created’, function (e) {
var type = e.layerType;
var layer = e.layer;
var latLngs;
var theRadius = layer.getRadius();

if (type === 'circle') {
   latLngs = layer.getLatLng();
   console.log("Coordinates: " + latLngs.toString()+ theRadius.toString());
}
else
   latLngs = layer.getLatLngs(); // Returns an array of the points in the path.

// process latLngs as you see fit and then save

})


#14

As you have found a satisfactory solution, it seems that you weren’t after screen coordinates at all, but were instead after latitude and longitude which have nothing to do with where the circle is placed on the screen.

I wasn’t notified, but now I guess I know that I was misunderstanding your intention.


#15

Fair enough, I wasn’t entirely clear, appreciate your efforts.

For those looking for the co-ordinates (as opposed to the lat & long) use the following which will print them to the console as the mouse moves around:

onmousemove = function(e){console.log(“mouse location:”, e.clientX, e.clientY)}

And for mousedown and mouseup events:

map.on(‘mousedown’, function(event) {
console.log("Coordinates-mousedown: " + event.latlng.toString());
});
map.on(‘mouseup’, function(event) {
console.log("Coordinates-mouseup: " + event.latlng.toString());
});