Coder Social home page Coder Social logo

sandropibia / leaflet.selectareafeature Goto Github PK

View Code? Open in Web Editor NEW
31.0 0.0 15.0 146 KB

Plugin that selects feature(s) by drawing an area on the map

License: GNU General Public License v3.0

JavaScript 100.00%
leaflet selectarea feature featureselect leafletjs leaflet-plugin

leaflet.selectareafeature's Introduction

Leaflet.SelectAreaFeature

Plugin that selects feature(s) by drawing an area on the map.

Supports Leaflet 1.0.0+ branches, tested with 1.2.0 and 1.9.4.

This plugin let the user draw an area, once it is activated, on the map by holding the left mouse button and moving it. As a developer you can get the layers that are within the bounding box of that area. Once you have the instances of the layers you can manipulate them separately.

selectareafeature

Features

  • easy enable it
  • easy disable it
  • draw an area around the objects
  • get instance(s) of all selected objects or only instances of polygon(s), polyline(s), marker(s), rectangle(s) and circle(s)
  • manipulate slected features
  • customisable

Example

Here you can find a demo

Usage

Include Leaflet.SelectAreaFeature in your JavaScript project using npm install leaflet-selectareafeature.

You can then include Leaflet.SelectAreaFeature in your web application by adding the following HTML tags (paths below are relative to your project's root):

<script src="./lib/js/Leaflet.SelectAreaFeature.js"></script>

Put it after leaflet is loaded. Once your page is loaded you can easily use it by enable it like:

var selectfeature = map.selectAreaFeature.enable();

After the plugin is enabled the user can draw an area by holding the left mouse button and start drawing. You can disable the plugin by:

selectfeature.disable();

Than the mouse events for drawing stop working with the map.

Options

The following options are available with SelectAreaFeature (showing you here with the default settings):

Property Description Default value Example
color The color of the line when drawing. For example 'blue' , '#333333' 'green' selectfeature.options.color = '#663399' ;
weight The weight of the line 2 selectfeature.options.weight = 1 ;
dashArray Sets or read the stroke dash pattern of the line '5, 5, 1, 5' selectfeature.options.dasArray = '2, 2, 4, 2' ;

Methods

The following methods are supported by the plugin:

Method Input parameter Mandatory Returns Description
getAreaLatLng Array of latlng Gets all the latlng of the latest drawn area on the map
removeAllArea Removes all the drawn area from the map
removeLastArea Remove the latest drawn area from the map
getFeaturesSelected(layertype) layertype String Yes Array of layers selected of layertype is one of the following values: 'polyline', 'polygon', 'rectangle', ' marker', 'circle' or 'all'

Events

The following events are raised by the plugin:

Method Parameters Description Example Data
onDrawStart Starting Point Event fired when user begins selection {"latlng":{"lat":33.01447033717771,"lng":-96.82496721390636}}
onDrawEnd Array of selection points Event fired when user ends selection. Note: array can be large. [{"lat":33.00295088449869,"lng":-96.8394228955731},{"lat":32.98536856753931,"lng":-96.71727228909732},{"lat":32.932621581506616,"lng":-96.89001782331617},{"lat":32.93504675534242,"lng":-96.89146340824665}]

How to subscribe to these events:

map.on('onDrawStart', function(evData) {
  // Your handling code here
};
map.on('onDrawEnd', function(selectionLatLng) {
  // Your handling code here
};

License

Leaflet.SelectAreaFeature is free software, and may be redistributed under the GPL-3.0 license.

leaflet.selectareafeature's People

Contributors

alex870 avatar cornbrandon avatar sandropibia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

leaflet.selectareafeature's Issues

Use Leaflet's Events to fire an event when features might be selected

Hi,
Thanks for the great code. I would like to propose, and I think I saw it mentioned in another of the issues, an event being fired on mouse up. What this would allow for is for anybody using this plugin to easily add a listener to determine when features are added/ removed.

In our use case it's because we have a submit button, to send a list of features over AJAX; that will need to be toggled on/ off depending on whether features are selected.

It should just be a one liner, as events are already added as Evented to the map object in Leaflet. so, fireEvent is already available.

_doMouseUp: function(ev) {
// Rest of existing code
 this._map.off('mousemove');
         this._map.fireEvent('selectAreaFeature:mouseUp', ev);

BTW, if it helps I could submit a pull request for this.
Thanks!

Predefined shapes - Enhancement suggestion

I'd like to suggest an enhancement of locking the drawing process to using predefined shapes like circles and rectangles etc, This would be in addition to the existing capability of drawing a free-form area.

There might be a new API method added for selecting a defined shape like a circle, for instance. Then the user would click the center point on the map and then click a second time some distance away to define the radius.

I've not seen anything like this from other plugins and it would be a fantastic addition to the great functionality you already have. Great work!

Events and better match algorithm

Great work!

I wold sugest some enhancements that I am using:

  1. Add callbacks on draw start and End.

Something like:
(...)
onDrawStart: null,
_doMouseDown: function(ev) {
if (this.onDrawStart) this.onDrawStart();
(...)

  1. Better match algorith that checks irregular shapes:
    (from: https://github.com/substack/point-in-polygon/blob/master/index.js)

isMarkerInsidePolygon: function (marker, poly) {
var polyPoints = poly.getLatLngs()[0];
var x = marker.getLatLng().lat, y = marker.getLatLng().lng;

    var inside = false;
    for (var i = 0, j = polyPoints.length - 1; i < polyPoints.length; j = i++) {
        var xi = polyPoints[i].lat, yi = polyPoints[i].lng;
        var xj = polyPoints[j].lat, yj = polyPoints[j].lng;

        var intersect = ((yi > y) != (yj > y))
            && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
        if (intersect) inside = !inside;
    }
    return inside;
}
  1. Add support for cluster plugin in the getFeaturesSelected function
    (...)
    if ((layertype == 'marker' || layertype == 'all') && layer instanceof L.MarkerCluster) {
    var child = layer.getAllChildMarkers();
    if (child) {
    _.forEach(child, function (m) {
    if (pol.contains(m.getLatLng()) && insideChecker(m, polLayer)) {
    layers_found.push(m);
    }
    });
    }
    }
    (...)

Mouse up error with Leaflet 1.8

The event mouseUp (when selecting an area) keeps triggering the error:

core.js:6498 ERROR TypeError: Cannot use 'in' operator to search for '_leaflet_id' in
at o (leaflet-src.js:68:10)
at t.hasLayer (leaflet-src.js:6681:12)
at t._doMouseUp (Leaflet.SelectAreaFeature.js:73:19)
at t.fire (leaflet-src.js:613:13)
at t._fireDOMEvent (leaflet-src.js:4419:17)
at t._handleDOMEvent (leaflet-src.js:4368:10)
at HTMLDivElement.s (leaflet-src.js:2692:15)
at c.invokeTask (zone.js:406:37)
at Object.onInvokeTask (core.js:28668:33)
at c.invokeTask (zone.js:405:60)

This only happens with Leaflet v1.8, with previous ones is still working.

(Question) How to make SelectAreaFeature to work with Leaflet.ContextMenu

Hello,
First of all many thanks for this really useful and nice feature - one of the best plugins for me :)

Due to design limitations I cannot use the buttons for starting/stopping, etc. of area selection. I tried feature functionallity with them and it worked perfectly.

That is why I tried implementing it with Leaflet.ContextMenu. Enabling, disabling of feature and selected area deletion work fine. The problem is that I cannot achieve exporting of markers popups, which is my target. I managed to do that with the button version, but with context menu I couldn't. What is strange to me is that when I have both versions in the same script, when I select the area with the buttons, then I can export it either way - with buttons or with contextmenu. But when I select it with context menu I cannot export it neither way.

I created one simplified JS Bin showing the problem.

The error message is below:
Uncaught TypeError: Cannot read property 'lat' of undefined at T.contains (leaflet.js:5) at Leaflet.SelectAreaFeature.js:172 at eachLayer (leaflet.js:5) at e.getFeaturesSelected (Leaflet.SelectAreaFeature.js:170) at exportSel (index.html:935) at HTMLAnchorElement.<anonymous> (leaflet.contextmenu.js:328) at HTMLAnchorElement.r (leaflet.js:5)

My code in short:

  • Definition of map with context menu for Area selection:
  		var mymap = L.map('mapid', {
		center: [53.748711, -2.579041],
		zoom: 12,
		zoomControl: false,
		
			contextmenu: true,
			contextmenuWidth: 140,
			contextmenuItems:
			[
			{
				text: 'Start Selecting',
				callback: startSel
			},
			{
				text: 'Stop Selecting',
				callback: stopSel
			},
			{
				text: 'Delete selected',
				callback: deleteSel
			},
			{
				text: 'Export selected',
				callback: exportSel
			}
			
			]
		
		});

Definition of related functions for each action:

		function startSel() {
			selectfeature = mymap.selectAreaFeature.enable();
	  
			selectfeature.options.color = '#663399' ;
			selectfeature.options.weight = 3 ;
		};
		
		function stopSel() {
			selectfeature.disable();
		};
		
		function deleteSel() {
			selectfeature.removeAllArea()
		};
		
		function exportSel() {
			selected_features = selectfeature.getFeaturesSelected( 'all' );
			var stringBuilder="";
			if ( selected_features.length != 0 && selected_features.length >= 1 ) {
				for (i=0; i < selected_features.length; i++ ) {
					var popup = selected_features[i].getPopup();
					var content = popup.getContent();
					stringBuilder=stringBuilder+content.toString()+","
					}  
				console.log(stringBuilder);
			}	
		};

I would be very happy for some help. Thank you in advance!

Leaflet tiles flashes and being selected while drawing to select

Hi,
Thanks for sharing the plugin. I found that drawing to select does not work properly in IE 11. I did not test with lower versions of IE yet. It will flash and also select the tiles while drawing arounds layers to select.
How to reproduce:

  1. Load the example page on IE 11
    URL: https://sandropibia.github.io/Leaflet.SelectAreaFeature/examples/index.html
  2. Click on Enable button.
  3. Draw around some layers on the map.

Anyone has any ideas how to resolve this?

Thanks a lot.

Selected Areas Remain Upon Map Reload

Hi, I'm absolutely loving this plug-in!

However, I'm running into an issue where my selected areas reappear after I've deleted them and the map updates. For example, my deleted selection returns upon zooming in/out on the map. Is there a way to avoid this that I seem to be missing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.