Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Editing of large polylines (many points) #176

Open
florianf opened this Issue Aug 19, 2013 · 5 comments

Comments

Projects
None yet
4 participants

Currently it's almost impossible to edit a polyline with many points (1000+). The bottleneck is adding all edit markers right when loading the polyline.

It would be great if only those edit markers would be added that are actually needed. A good solution would be, that edit markers only appear after hovering over the polyline, f.ex. -4/+4 markers surrounding the hover position.

Owner

jacobtoye commented Aug 21, 2013

Yes I could see how this would present a problem. You are most welcome to fork the repo and have a go. I'd be keen to see what you come up with :)

Contributor

mapmeld commented Oct 2, 2013

@florianf I'm having the same challenge... did you come up with a solution for editing a large polyline or a set of several large polylines?

florianf commented Oct 4, 2013

@mapmeld I added a quick hack directly into leaflet.draw.js. basically the markers are generated when the mouse hovers over the line. I didn't have the time to finish it properly (hence no pull), and it has some quirks (not generating virtual markes when to hovered sections are generated next to each other) but it basically works.

in the method addHooks in L.Edit.Poly I added the following (i misuse the clickable option for triggering the mouseover behaviour):

if (this._poly.options.clickable) {
    this._poly.on("mouseover", this._onPolyHover, this);
    this._createdEditMarkers = {};
}

And the _onPolyHover method:

_onPolyHover : function(event) {
        var minDist = Math.pow(2, 53); //== Integer.MAX
        var pointIdx = 0;

        var points = this._poly._latlngs;

        for (var i=0;i<points.length;i++) {
            var dist = event.latlng.distanceTo(points[i]);
            if (dist < minDist) {
                minDist = dist;
                pointIdx = i;
            }
        }

        var marker, markerLeft, markerRight;
        var newMarkers = [];

        for (var i=-2;i<=2;i++) {
            var idx = pointIdx + i;
            if (idx >= 0 && idx < points.length && !this._createdEditMarkers[idx]) {
                marker = this._createMarker(points[idx], idx);
                marker.on('click', this._onMarkerClick, this);
                this._markers.push(marker);
                this._createdEditMarkers[idx] = marker;
                newMarkers.push(marker);
            }
        }

        for (var i=0;i<newMarkers.length;i++) {
            var index = newMarkers[i]._index;
            var nextIndex = index+1;
            if (this._createdEditMarkers[index] && this._createdEditMarkers[nextIndex]) {
                this._createMiddleMarker(this._createdEditMarkers[index], this._createdEditMarkers[nextIndex]);
                this._updatePrevNext(this._createdEditMarkers[index], this._createdEditMarkers[nextIndex]);
            }
        }
    },

The Google Maps API has this same problem. We got around it by splitting large polygons into a set of small lines. It was a little tricky because you have to tie the ends of lines together and account for deleting vertices, but it's not too bad and is the most elegant solution we could find.

Here's our solution to this problem for Google Maps: https://github.com/openplacedatabase/gmaps-large-polygons

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment