Giter VIP home page Giter VIP logo

leaflet-pip's Introduction

point in polygon for Leaflet

build status

A Leaflet-friendly API for point in polygon operations, using substack's point in polygon library.

install

With browserify

npm install @mapbox/leaflet-pip

Resolve for a CDN/packaged version:

https://unpkg.com/@mapbox/leaflet-pip@latest/leaflet-pip.js

example

var gjLayer = L.geoJson(statesData);
var results = leafletPip.pointInLayer([-88, 38], gjLayer);
// results is an array of L.Polygon objects containing that point

api

leafletPip.pointInLayer(point, layer L.GeoJSON, [first])

Point can be:

  • A two-element array of [lng, lat]
  • A L.LatLng object

Layer must be:

  • A L.geoJSON layer

first can be:

  • boolean: true to accept the first match, or false to return all polygons containing this point. This can be useful if you know that your polygons are non-overlapping or don't care about more than one result, since it will be much faster. By default, this is false and all matches are returned.

Returns:

An array of polygons in which the given point resides, an empty array if there are none. The polygons are returned as direct sublayers, so they can include MultiPolygons. You can call pointInLayer again on those if you want the sub-polygon result.

leafletPip.bassackwards

Leaflet treats literate coordinate arrays as [lat, lon], unlike GeoJSON and any true scotsman. leaflet-pip treats literate coordinate arrays as [lon, lat], but if you set bassackwards to true, it'll do things the Leaflet/Google Maps API way.

leaflet-pip's People

Contributors

codebling avatar jfirebaugh avatar tmcw 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

leaflet-pip's Issues

Some areas of MultiPolygon not returning from pointInLayer

I'm having a weird issue with a MultiPolygon not returning the layer when clicking on said layer.

I've modified the example you created to highlight the issue I am seeing:
http://rousseau.io/leaflet-pip/

Code for the site can be found here:
https://github.com/jvrousseau/leaflet-pip/blob/gh-pages/site/site.js

Here is the GeoJSON for the polygon that is shown in the example:
https://github.com/jvrousseau/leaflet-pip/blob/gh-pages/site/broken.js

Please let me know if there is any other information I can provide.

More than likely, I am either doing something wrong, or the GeoJSON is bad in some way, shape, or form. Please let me know if that's the case.

Release a new version

Current is 0.1.0 which unfortunately does not include bower.json and Bower is then complaining about missing "main" and "ignore" entries. Since bower.json is committed in the repository already, it would be nice to release a new version to please Bower. :-)

Uncaught TypeError: Cannot read property '1' of undefined

Hello! I'm trying to use this api library. I have my code looking like the following:

When I run this, and try to click on a polygon, all I get is this:

I hope I explained this enough, I'm not sure what else to say other than I've been banging my head off my desk the past few days.

Please let me know if you need any more additional information.

any reason this shouldn't work with leaflet-headless?

I have a geoJson file of a bunch of NWS alert zone polygons in it. I simply want to find what polygon (if any) a given lat/lng point is in. I want to do this entirely headless (no browser).

I'm using leaflet-headless and leaflet-pip to try and pull this off - but I keep getting a [TypeError: Expecting a function in instanceof check, but got undefined] error when I invoke leafletPip.pointInLayer().

Before I spend lots of time digging into the leaflet[-pip] code, was wondering if you knew off the top of your head why this would not work? Here is my code:

let Promise    = require('bluebird'),
    fs         = Promise.promisifyAll(require("fs")),
    srcDataDir = __dirname + '/../srcData',
    L          = require('leaflet-headless'),
    leafletPip = require('leaflet-pip');

module.exports.generate = function() {
  let rochesterMn = {
    lat: 44.0150757,
    lng: -92.4775256
  };

  return fs.readFileAsync(srcDataDir + '/simplifiedZones.geojson')
    .then(data => {
      var geoJSON = {};
      try {
        geoJSON = JSON.parse(data);
      } catch (err) {
        throw err;
      }

      let ugcZoneLayer = L.geoJson(geoJSON);

      let foundPoly = leafletPip.pointInLayer([rochesterMn.lng, rochesterMn.lat], ugcZoneLayer, true);

      console.log(foundPoly);
  });
};

thanks in advance. FWIW im on OSX

Use leaflet-pip to find point-in-polygon in php file or online database?

This is more of a question than an issue, I was just wondering if there is a way to use leaflet-pip to query data stored in php. The reason I ask is that I have record set that is too large to bring in to the client with out crashing it. Thanks ahead of time. If you could even give me some starter tips it would be appreciated.

Problem with GeoJSON converted from EsriJSON and Multipolygons

Hello Thanks for the very useful plugin.
I recently ran into an issue where i'm using data from an arcgis rest service that's spitting out ESRI JSON that I then convert to GeoJSON with ogr2ogr. Because there is no 'Multipolygon' in ESRI the multipolygons get converted as just 'Polygon' in the GeoJSON. Leaflet renders them fine as multipoly's on the map, but the leaflet-pip function would fail to check all of the associated polygons in the layer.

I re-wrote the function to add a check to see if there was more than one polygon in the function and if there were to loop through and check all of them. Is this worth a pull request? Not sure if this solves any of the other multipoly issues.

gju.pointInPolygon = function (p, poly) {
    var coords = (poly.type == "Polygon") ? [ poly.coordinates ] : poly.coordinates
    var insideBox = false
    var insidePoly = false

    if(coords[0].length>1){ //check if multipoly
      for (var i = 0; i < coords[0].length; i++){
        if (!insideBox){
          var coordsMulti = [];
          coordsMulti.push(coords[0][i]);
          if (gju.pointInBoundingBox(p, boundingBoxAroundPolyCoords(coordsMulti))) insideBox = true
        }
      }

      if (!insideBox) return false

      for (var i = 0; i < coords[0].length; i++){  
        if (!insidePoly){
          var coordsMulti = [];
          coordsMulti.push(coords[0][i]);
           if (pnpoly(p.coordinates[1], p.coordinates[0], coordsMulti)) insidePoly = true
        }
      }
    }
    else{ //is singlepoly
      var insideBox = false
      for (var i = 0; i < coords.length; i++) {
        if (!insideBox){
          if (gju.pointInBoundingBox(p, boundingBoxAroundPolyCoords(coords[i]))) insideBox = true
        }
      }
      if (!insideBox) return false

      for (var i = 0; i < coords.length; i++) {
        if (!insidePoly){
          if (pnpoly(p.coordinates[1], p.coordinates[0], coords[i])) insidePoly = true
        }
      }
    }

    return insidePoly
  }

Example isn't working over HTTP on Chrome

On Chrome you get the warning:

"getCurrentPosition() and watchPosition() are deprecated on insecure origins."

for the example of HTTP. You also get a lot of mixed content warnings over HTTPS: https://mapbox.github.io/leaflet-pip/

I think changing the description URL to HTTPS would be beneficial to people coming to the page. Happy to make the pull request if require.

Add bower package

Could you please add a bower package and make it available on bower.io?
This would ease usage for many web-projects :-)

Leaflet-pip is not working with Leaflet-draw plugin

Hello,
I've tried to update my app with leaflet 1.0.x and I'm facing up to an incompatibility between 2 plugins:

Since this commit in leaflet-pip, function is_poly is not anymore able to take into account polygons just created with leaflet-draw. I thought leaflet-draw created an incorrect polygon in this issue but I suspect now leaflet-pip is maybe not enough permissive.
I would suggest a PR which updates the is_poly function from your plugin:

function isPoly(l) {
    if (l instanceof L.Polygon) return true;
    return l.feature && l.feature.geometry && l.feature.geometry.type &&
        ['Polygon', 'MultiPolygon'].indexOf(l.feature.geometry.type) !== -1;
}

Indeed layer created by leaflet-draw has no l.feature && l.feature.geometry && l.feature.geometry.type attribute...

And maybe rollback entirely ff2b2f4 for is_poly:

function isPoly(l) {
    return L.MultiPolygon && l instanceof L.MultiPolygon ||
        l instanceof L.Polygon ||
        l.feature && l.feature.geometry && l.feature.geometry.type &&
        ['Polygon', 'MultiPolygon'].indexOf(l.feature.geometry.type) !== -1;
}

What do you thinking about it ?

Fabien

Publish latest version to npm?

Hi there,

I recently upgraded to the 1.0.0 rc for Leaflet, and noticed some changes to leaflet-pip in the repo that do not seem to be available via the npm package. Would you be able to publish the latest version at some point? I'm currently adding it directly so I'm not blocked, but it would be nice to have as an installed npm module.

Thanks!

Doen't seem to support GeometryCollection

Leaflet-pip does not seem to find polygons inside of a GeometryCollection. If I get it right then not only mush layers be iterated, if the layer contains a GeometryCollection then all items within that must also be subjected to isPoly(l), but that probably require a bit of refactoring to process GeoJSON objects rather than layers.

So currently a Polygon as the one the below will never be found.
{ "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "class": "LYRESTAD" }, "geometry": { "type": "GeometryCollection", "geometries": [{ "type": "Polygon", "coordinates": [ [ [14.00881897363853, 58.759130043177166], [13.928815204319006, 58.93581644468062], [14.120750873038237, 58.8843341034047], [14.121862332723687, 58.88126014491872], [14.174039271588722, 58.78656397216331], [14.145110948923927, 58.767173887639935], [14.12508839353722, 58.758541330342304], [14.11335950201629, 58.76108407639584], [14.06140521182085, 58.77226018822536], [14.00881897363853, 58.759130043177166] ] ] }] } }

Limit to one polygon per point

Is it possible to speed up the algorithm by adding an option to assume that each point is only contained in one polygon? Hence return once a match has been found.

I need to classify a large number of points, so speed is an issue for me.

Server side

I need to use this server side to give a reward, so therefore I cannot trust the client. Is there anyway of using this server side in nodejs? I notice in the source it seems to be actually drawing polygons to determine so I'm thinking not? Sorry for my ignorance.

leaflet 1.0.3?

any plans to make this awesome plugin work with leaflet 1.0.3?

Feature request, expose working centroid function

gju.centroid for the following shape outputs a point 1/2mi away from the polygon.

"geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -87.84772709012032,
              41.095232882536514
            ],
            [
              -87.84772709012032,
              41.09527128838847
            ],
            [
              -87.84766271710394,
              41.09527128838847
            ],
            [
              -87.84766271710394,
              41.095232882536514
            ],
            [
              -87.84772709012032,
              41.095232882536514
            ]
          ]
        ]
      }
    }

Leaflet PIP not Returning all Results

I have a scenario where leaflet-pip will not return any data when you click on certain polygons, but when you click on another polygon it does return correct data. All of the polygons I'm referencing are in a GeoJson layer.

An example is here: http://livestormchasing.com/dev, and try clicking on all of the polygons and some of the polygons will not work correctly. I'm logging information to the console as well to help with debugging.

I've been trying to figure this out for quite some time, just can't seem to derive a solution.

Many thanks.

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.