Leaflet / Leaflet.draw

Vector drawing and editing plugin for Leaflet
https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html
MIT License
1.96k stars 992 forks source link

Rectangle display bug when drawing in 1.0.3 or 1.0.4 - "type is not defined" #1026

Open joelhickok opened 3 years ago

joelhickok commented 3 years ago

How to reproduce

When drawing a rectangle using Leaflet.draw version 1.0.3 or greater, I am seeing the error below. If I rollback to version 1.0.2 the error is gone. Essentially, in 1.0.3 or greater, the rectangle path DOES NOT draw when sizing the rectangle over the map, but the layer is created on the "created" event. In version 1.0.2 the rectangle DOES draw and resize as you drag the rectangle over the map.

leaflet.draw.js:9 Uncaught ReferenceError: type is not defined
    at Object.readableArea (leaflet.draw.js:9)
    at NewClass._getTooltipText (leaflet.draw.js:8)
    at NewClass._onMouseMove (leaflet.draw.js:8)
    at NewClass.fire (Events.js:190)
    at NewClass._touchEvent (leaflet.draw.js:9)
    at NewClass._onTouchMove (leaflet.draw.js:9)
    at handler (DomEvent.js:92)
    at _handlePointer (DomEvent.Pointer.js:98)
    at HTMLDivElement.onMove [as _leaflet_touchmovetouchmove28_26] (DomEvent.Pointer.js:108)
SudhagarMurugesan commented 2 years ago

Uncaught ReferenceError: type is not defined at Object.readableArea (leaflet.draw.js:9) at NewClass._getTooltipText (leaflet.draw.js:8) at NewClass._onMouseMove (leaflet.draw.js:8) at NewClass.fire (leaflet-src.js:588) at NewClass._touchEvent (leaflet.draw.js:9) at NewClass._onTouchMove (leaflet.draw.js:9) at handler (leaflet-src.js:2669) at _handlePointer (leaflet-src.js:2102) at HTMLDivElement.onMove [as _leaflet_touchmovetouchmove28_26] (leaflet-src.js:2112) at ZoneDelegate.invokeTask (zone.js:406)

i am also facing the same error while drawing the rectangle

Zeng-Wenquan commented 2 years ago

image

matafokka commented 2 years ago

Since project looks dead, and some people might be wondering how to fix this issue, I want to explain the fix. Sorry for the necroposting and information that might be obvious.

Right after you import Leaflet.Draw, create a global variable named type like so:

require("leaflet-draw");
window.type = true; // Doesn't matter what value to put here, just initialize the thing

Before you do that, verify that none of your dependencies uses this variable! To do so, run your app, open console and type window.type. If it outputs something different from undefined, find and get rid of the library that uses this variable or switch to another drawing library (for example, geoman).

This trick works for my build process, though, you might want to modify it for your build system. For example, it might remove unused object properties, so you have to read or write this value somewhere or add it to the ignore list. How to solve it is up to you.

The whole thing might introduce a drawback. I have no idea how and when readableArea() is called, so I assume there might be some kind of race conditions, so different Leaflet.Draw instances that use different measurements will override this variable in the middle of the execution.

The solution is to be consistent with measurements across your application. Or don't use isMetric parameter and, if you want, disable measurements output.

zwq000 commented 2 years ago

This is obviously not feasible and will pollute the global variables, The only way to fix this problem is to create a new branch

Zeng-Wenquan commented 2 years ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。

matafokka commented 2 years ago

Yes, I hate creating unnecessary global variables too. Another fix might be to monkey-patch this method. I'm talking about users fixing it, not devs, haha :)

Indeed, it would be great, if problem was fixed by devs, but this project seems abandoned. Is there a patched fork, by any chance? I couldn't find one.

Rafnuss commented 1 year ago

Any update on this issue. @matafokka solution works. Is there a another cleaner way? How to disable measurements output on draw?

Zeng-Wenquan commented 1 year ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。

jcgiuffrida commented 1 year ago

I think the fix is just to add type to the var declaration at the top of readableArea. That would be scoped to the function and not conflict with the global namespace.

If you don't want to mess with vendor source code, you can use @matafokka's solution. I just did window.type = '' so that anything that checks if (window.type) still returns false.

Zeng-Wenquan commented 1 year ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。

movahhedi commented 1 month ago

This should be extremely easy to fix, huh?

Zeng-Wenquan commented 1 month ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。

movahhedi commented 1 month ago

I never thought auto-reply could cause a problem 😆

Translation:

This is a holiday auto-reply email from QQ mailbox. Hello, I am on vacation recently and cannot reply to your email in person. I will reply to you as soon as possible after the vacation.

gaojiangtao-git commented 2 weeks ago

Is there any solution to this problem

Zeng-Wenquan commented 2 weeks ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。

greenroach commented 15 hours ago

Another solution if you do not want to add type to window

You can copy the original function from the repo, fix the type variable, and then replace it.

(I didn’t change the original function except for one line where the type variable is declared and copied defaultPrecision that is being referenced from the original fuction.)


L.GeometryUtil = L.extend(L.GeometryUtil || {}, {
    readableArea: function (area, isMetric, precision) {

        // Also defaultPrecision copied from the module closure
        var defaultPrecision = {
            km: 2,
            ha: 2,
            m: 0,
            mi: 2,
            ac: 2,
            yd: 0,
            ft: 0,
            nm: 2
        };

        var areaStr,
            units,
            type,
          // ^ Note type variable is added here 
            precision = L.Util.extend({}, defaultPrecision, precision);

        if (isMetric) {
            units = ['ha', 'm'];
            type = typeof isMetric;
            if (type === 'string') {
                units = [isMetric];
            } else if (type !== 'boolean') {
                units = isMetric;
            }

            if (area >= 1000000 && units.indexOf('km') !== -1) {
                areaStr = L.GeometryUtil.formattedNumber(area * 0.000001, precision['km']) + ' km²';
            } else if (area >= 10000 && units.indexOf('ha') !== -1) {
                areaStr = L.GeometryUtil.formattedNumber(area * 0.0001, precision['ha']) + ' ha';
            } else {
                areaStr = L.GeometryUtil.formattedNumber(area, precision['m']) + ' m²';
            }
        } else {
            area /= 0.836127; // Square yards in 1 meter

            if (area >= 3097600) { //3097600 square yards in 1 square mile
                areaStr = L.GeometryUtil.formattedNumber(area / 3097600, precision['mi']) + ' mi²';
            } else if (area >= 4840) { //4840 square yards in 1 acre
                areaStr = L.GeometryUtil.formattedNumber(area / 4840, precision['ac']) + ' acres';
            } else {
                areaStr = L.GeometryUtil.formattedNumber(area, precision['yd']) + ' yd²';
            }
        }

        return areaStr;
    }
});

or just by that


L.GeometryUtil.readableArea = function (area, isMetric, precision) {...
Zeng-Wenquan commented 15 hours ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。