Coder Social home page Coder Social logo

makinacorpus / leaflet.geometryutil Goto Github PK

View Code? Open in Web Editor NEW
251.0 39.0 94.0 1.27 MB

Leaflet utility function on geometries

Home Page: http://makinacorpus.github.io/Leaflet.GeometryUtil/

License: BSD 3-Clause "New" or "Revised" License

HTML 4.51% JavaScript 95.49%

leaflet.geometryutil's Introduction

npm npm

Leaflet.GeometryUtil

  • Tested with stable Leaflet 0.7.0
  • Tested with Leaflet 1.0.0-rc.3

Usage

Using Node:

    npm install leaflet-geometryutil

Or browser:

    <script src="leaflet.geometryutil.js"></script>

Check out online documentation.

Development

Running tests in command-line

    sudo apt-get install nodejs

    npm install
  • Ready !
    npm test

Changelog

0.10.3

  • add support for closestOnCircle (#101, thanks to @danyhoron)

0.10.2

  • use leaflet's earth radius in destination function (#96, thanks to @viliusstanga)
  • Changed imports to acommodate to new ngx-leaflet organization (#97, thanks to @rtrevinnoc)

0.10.1

  • Enhance precision for meter values (metric / imperial) (#94, thanks @karlbeecken)

0.10.0

  • Add TypeScript definitions (#90, thanks @cdauth)

0.9.3

  • Increase locateOnLine() tolerance

0.9.2

  • Fixes a crash if a multilinestring has an element with only one vertex (fixes #84, thanks @runette)

0.9.1

  • Fix locateOnLine() doesn't return correct subline (#79, thanks @lepetittim)

0.9.0

  • Fix interpolateOnLine() doesn't return correct predecessor (#66, thanks @jb2b38)
  • Add angle() and destinationOnSegment() (#71, thanks @trandaison)

0.8.1

  • Remove a deprecated function in Leaflet 1.x (#69)

0.8.0

  • Update leaflet dependency to >=0.7.0 (#64, thanks @kozze89)
  • Add nClosestLayer (#62, thanks @haoliangyu)

0.7.2

  • Fix #59, closest method using a shallow copy of latLngs => deep copy now

0.7.1

  • Fix closest method for last segment on Polygon and nested Polygons

0.7.0

  • Tested for Leaflet 1.0.0-rc.3

0.6.0

  • Add nested arrays for layer param in closest method

0.5.1

  • Fix closestLayer to be able to work with GeoJSON nested layers
  • Restrict closest method to Array and L.Polyline (L.Polygon extend L.Polyline)

0.5.0

  • Add function layersWithin() (#34, thanks @haoliangyu)
  • Fix safety check on the ratio value in ``interpolateOnLine()` (#29, thanks @Marcussacapuces91)

0.4.0

  • Same version as v0.3.3, new release as v0.4.0 to keep numbering coherent as a new feature has been added

0.3.3

  • Add bearing and destination functions (thanks @doublestranded)

0.3.2

  • Use a soft dependency for Leaflet (thanks Erik Escoffier)

0.3.1

  • Make sure interpolateOnLine() always returns a L.LatLng object (thanks Justin Manley)

0.3.0

  • Added UMD style initialization (thanks @PerLiedman)
  • Added readable distance (thanks @Mylen)
  • Fix side effects on latlngs with closest() (thanks @AndrewIngram)

0.2.0

  • Locate point on line
  • Rotate point around center
  • Fixed bug if closest point was on last segment

0.1.0

  • Line subpart extraction
  • Line lengths
  • Angle and slope computation
  • Line reverse
  • Line interpolation

0.0.1

  • Initial working version

License

  • BSD New

Authors

Makina Corpus

leaflet.geometryutil's People

Contributors

andrewingram avatar babastienne avatar bastyen avatar bbecquet avatar cdauth avatar danyhoron avatar fiendish avatar fredericbonifas avatar haoliangyu avatar justinmanley avatar karlbeecken avatar lepetittim avatar leplatrem avatar marcussacapuces91 avatar mdartic avatar perliedman avatar rtrevinnoc avatar runette avatar trandaison avatar viliusstanga 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

leaflet.geometryutil's Issues

Extract returns wrong line in case of narrow angles in line

I had situation where I need to find line segment from start to certain point along line (with snapping along line). It works fine with wide angles but with smaller than 90 degrees it will "jump" to previous line segment. I got fraction from locateOnLine.

Turf for example, handles it correctly. Also input as starting and ending point is better approach than blurry fraction.

length and locateOnLine - accuracy

I cant figure this on out. Have a look at this example:
https://jsfiddle.net/krillmcrawl/8wy3jhor/9/

Move the mouse along the line and check the console.

The actual lenght of the line is 4367.02(FME) or 4367.078(Qgis)
The lenght reported from Leaflet.GeometryUtil is 4353.622 (13 meter difference seems quite far off)

In the example I have generated stations lines every 10 meters(for easier debugging). As you can see the "locateOnLine" reports the correct measures in the beginning of the line but after a while it starts "drifting". At station line 60 it turf reports 59.8 and further in at 850 turf reports 847.3 and even further in at 2660 turf reports 2651.

The accuracy it not quite there. Is there a setting somewhere that I can use to increase accuracy of the length and "locateOnLine" calculations?

Thanks. Kristian

Incorrect destination calculations

I created a function to calculate the point on a perpendicular line from a line, but it feels the calculations are incorrect. Can you look into what might be going wrong here

export function getPerpendicularDestination(map, from, point2, distance, clockwise) {
	let pointOnLine = L.GeometryUtil.rotatePoint(
		map,
		point2,
		clockwise ? 90 : -90,
		from
	);
	let bearing = L.GeometryUtil.bearing(from, pointOnLine);
	let destination = L.GeometryUtil.destination(from, bearing, distance);

	return destination;
}

Now lets look at this image and understand what from, point2, distance and the output destination are. But the destination doesn't seem to be perpendicular all the time
screen shot 2018-08-07 at 11 06 37 am

This video might give you better understanding of what I am intending to implement here
https://www.useloom.com/share/932338b4b66d420293c894ca9b1b82a2

Can we get an export default L.GeometryUtil?

I am building a plugin for leaflet which uses this wonderful little plugin as a dependency. I would love for those who use my plugin to not have to put a link to L.GeometryUtil in their HTML file, but rather simply import my plugin into their index.js (or whatever module uses it), which in turn will import L.GeometryUtil (after having installed it through a npm install). At the top of my plugin, I have:

import GeometryUtil from './leaflet.geometryutil.js'

But that only works when I add this to the end of the L.GeometryUtil source file:

export default L.GeometryUtil

However, if people are installing my plugin using npm install, my package.json which references l.geometryutil, which does not have that last export line in there, as it references this repo here. Can we get that line added for more seamless module use? Or is there a different way to do this that I'm not thinking of?

Calculating Area with Leaflet 1.0

I know that Leaflet has changed the way it sends information on .getLatLngs()

I used to use this library to compute geodesic area. Is there a plan to add this to the 1.0 version in the future? What is the best way to compute areas with Leaflet 1.0?

A bug of function "closest"

When layer is a polygon, this funtion modifies the layer's LatLngs:

if (layer instanceof L.Polygon) {
    latlngs.push(latlngs[0]);
}

This shouldn't happen.
Maybe the solution is:

    var updateResult = function (latlngA, latlngB) {
        distance = L.GeometryUtil.distanceSegment(map, latlng, latlngA, latlngB);
        if (distance <= mindist) {
            mindist = distance;
            result = L.GeometryUtil.closestOnSegment(map, latlng, latlngA, latlngB);
            result.distance = distance;
        }
    };

    // Keep the closest point of all segments
    for (i = 0, n = latlngs.length; i < n-1; i++) {
        updateResult(latlngs[i], latlngs[i+1]);
    }

    if (layer instanceof L.Polygon) {
        updateResult(latlngs[n-1], latlngs[0]);
    }

angular-mocks tricks Leaflet.GeometryUtil into thinking modules are available

image

I am setting up unit tests using angular 1, karma and jasmine. All our modules and plugins and scripts are statically included. When using jasmine and angular-mocks module is defined in the window scope. So when leaflet.GeometryUtil tries to add itself to leaflet it assumes module.export will exist (because the module object is defined), but it doesn't exist. In my case I expect it to install itself to a global L that is statically included, and not required.

we are using a few other leaflet plugins, but this seems to be the only one with this problem.

Perhaps you can look to see what these ones are doing when performing the // Packaging/modules magic dance.
Leaflet-semicircle
Leaflet-heatmap
Leaflet.markercluster

this is what the heatmap plugin is doing:

  // Supports UMD. AMD, CommonJS/Node.js and browser context
  if (typeof module !== "undefined" && module.exports) {
    module.exports = factory(
      require('heatmap.js'),
      require('leaflet')
    );
  } else if (typeof define === "function" && define.amd) {
    define(['heatmap.js', 'leaflet'], factory);
  } else {
    // browser globals
    if (typeof window.h337 === 'undefined') {
      throw new Error('heatmap.js must be loaded before the leaflet heatmap plugin');
    }
    if (typeof window.L === 'undefined') {
      throw new Error('Leaflet must be loaded before the leaflet heatmap plugin');
    }
    context[name] = factory(window.h337, window.L);
  }

I think an extra check for the fully qualified module.exports would solve my problem.
Why they put that in the global scope to begin with, I am not sure.

I cant upgrade frameworks for business reasons.

closestLayerSnap returns latlng which can't be found on the provided layer

closestLayerSnap returns latlng which can't be found on the provided layer, would expect null or object with latlng from the layer.

// Calling closestLayerSnap
result = L.GeometryUtil.closestLayerSnap(map, [layer], event.latlng, 10, true);

// Inside: event
// - it's a mousedown event
// - latlng is added as property to the event 
event.latlng = {
    "lat": 51.50617819737357,
    "lng": -0.1680135726928711
};

// Inside: result
// - latlng of the result property  
result.latlng = {
    "lat": 51.50609608531908,
    "lng": -0.16801639863359252
};
// -layer property is equal to the provided layer
result.layer = layer;

// Inside: layer
// - this will be returned by calling "layer.getLatLngs();"
layer._latlngs = [{
    "lat": 51.51969,
    "lng": -0.15871,
    "distance": 553.3263051762495
}, {
    "lat": 51.51969,
    "lng": -0.15871
}, {
    "lat": 51.519639999999995,
    "lng": -0.15868,
    "distance": 551.487080537704
}, {
    "lat": 51.519149999999996,
    "lng": -0.15846,
    "distance": 537.4476718714111
}, {
    "lat": 51.51909,
    "lng": -0.15844,
    "distance": 534.7195526628889
}, {
    "lat": 51.51903,
    "lng": -0.15841,
    "distance": 533.3216665390597
}, {
    "lat": 51.51899,
    "lng": -0.15839,
    "distance": 532.4143123545797
}, {
    "lat": 51.51777,
    "lng": -0.15784,
    "distance": 497.12976173228657
}, {
    "lat": 51.51714,
    "lng": -0.15756,
    "distance": 479.69260990763655
}, {
    "lat": 51.51708,
    "lng": -0.15753,
    "distance": 477.97175648776573
}, {
    "lat": 51.517,
    "lng": -0.15749,
    "distance": 475.908604671107
}, {
    "lat": 51.516960000000005,
    "lng": -0.15747999999999998,
    "distance": 475.05157614726426
}, {
    "lat": 51.516580000000005,
    "lng": -0.15729999999999997,
    "distance": 464.93440397544254
}, {
    "lat": 51.516360000000006,
    "lng": -0.15719999999999998,
    "distance": 459.30382101611127
}, {
    "lat": 51.516070000000006,
    "lng": -0.15705999999999998,
    "distance": 451.83404032896857
}, {
    "lat": 51.51597,
    "lng": -0.15700999999999998,
    "distance": 449.92888326934514
}, {
    "lat": 51.5159,
    "lng": -0.15697999999999998,
    "distance": 448.0379448216412
}, {
    "lat": 51.515550000000005,
    "lng": -0.15680999999999998,
    "distance": 439.8147337231894
}, {
    "lat": 51.5155,
    "lng": -0.15677999999999997,
    "distance": 438.80291703679455
}, {
    "lat": 51.51512,
    "lng": -0.15660999999999997,
    "distance": 430.11626335213134
}, {
    "lat": 51.51503,
    "lng": -0.15656999999999996,
    "distance": 427.6037885706814
}, {
    "lat": 51.514970000000005,
    "lng": -0.15653999999999996,
    "distance": 426.04342501674637
}, {
    "lat": 51.51493000000001,
    "lng": -0.15651999999999996,
    "distance": 425.8931790954159
}, {
    "lat": 51.514540000000004,
    "lng": -0.15633999999999995,
    "distance": 416.94124286282835
}, {
    "lat": 51.51451,
    "lng": -0.15632999999999994,
    "distance": 416.1838536031882
}, {
    "lat": 51.51437,
    "lng": -0.15627999999999995,
    "distance": 413.0726328383424
}, {
    "lat": 51.51424,
    "lng": -0.15620999999999996,
    "distance": 410.67018396762137
}, {
    "lat": 51.51381,
    "lng": -0.15600999999999995,
    "distance": 402.3940854436109
}, {
    "lat": 51.51376,
    "lng": -0.15619999999999995,
    "distance": 397.4845908963013
}, {
    "lat": 51.51369,
    "lng": -0.15690999999999994,
    "distance": 384.365711269879
}, {
    "lat": 51.513659999999994,
    "lng": -0.15717999999999993,
    "distance": 378.93667017062364
}, {
    "lat": 51.51358999999999,
    "lng": -0.15777999999999992,
    "distance": 367.48333295538725
}, {
    "lat": 51.51353999999999,
    "lng": -0.15827999999999992,
    "distance": 359.6804137008297
}, {
    "lat": 51.51349999999999,
    "lng": -0.1582699999999999,
    "distance": 358.1312608527773
}, {
    "lat": 51.513459999999995,
    "lng": -0.1582599999999999,
    "distance": 357.3583635512117
}, {
    "lat": 51.513439999999996,
    "lng": -0.1582799999999999,
    "distance": 356.58659537341
}, {
    "lat": 51.51342999999999,
    "lng": -0.1583199999999999,
    "distance": 355.95083930228344
}, {
    "lat": 51.51340999999999,
    "lng": -0.1583399999999999,
    "distance": 354.54336829223024
}, {
    "lat": 51.51339999999999,
    "lng": -0.1583599999999999,
    "distance": 353.7711124441904
}, {
    "lat": 51.51338999999999,
    "lng": -0.15837999999999988,
    "distance": 353.1359511576243
}, {
    "lat": 51.51332999999999,
    "lng": -0.1584399999999999,
    "distance": 350.9558376776201
}, {
    "lat": 51.513229999999986,
    "lng": -0.15856999999999988,
    "distance": 345.9609804587795
}, {
    "lat": 51.51320999999999,
    "lng": -0.15866999999999987,
    "distance": 343.91859501922835
}, {
    "lat": 51.512849999999986,
    "lng": -0.15853999999999988,
    "distance": 335.9315406448165
}, {
    "lat": 51.512849999999986,
    "lng": -0.15858999999999987,
    "distance": 335.2745143908198
}, {
    "lat": 51.51271999999999,
    "lng": -0.15853999999999988,
    "distance": 332.18217893198306
}, {
    "lat": 51.512709999999984,
    "lng": -0.15856999999999988,
    "distance": 331.5177219998955
}, {
    "lat": 51.51263999999998,
    "lng": -0.15854999999999989,
    "distance": 329.94848082693153
}, {
    "lat": 51.512579999999986,
    "lng": -0.1585599999999999,
    "distance": 327.79414271765137
}, {
    "lat": 51.512509999999985,
    "lng": -0.15865999999999988,
    "distance": 324.2283146179556
}, {
    "lat": 51.51244999999999,
    "lng": -0.1587499999999999,
    "distance": 321.40317359976393
}, {
    "lat": 51.512439999999984,
    "lng": -0.15881999999999988,
    "distance": 319.3195891266303
}, {
    "lat": 51.51242999999998,
    "lng": -0.15892999999999988,
    "distance": 317.98270393214784
}, {
    "lat": 51.51236999999998,
    "lng": -0.15905999999999987,
    "distance": 314.4932431706602
}, {
    "lat": 51.512349999999984,
    "lng": -0.15911999999999987,
    "distance": 312.41798923877604
}, {
    "lat": 51.512349999999984,
    "lng": -0.15912999999999988
}, {
    "lat": 51.512379999999986,
    "lng": -0.1591699999999999
}, {
    "lat": 51.51235999999999,
    "lng": -0.15948999999999988,
    "distance": 307.17584540455
}, {
    "lat": 51.512329999999984,
    "lng": -0.1595299999999999,
    "distance": 305.766250590218
}, {
    "lat": 51.512309999999985,
    "lng": -0.1595299999999999
}, {
    "lat": 51.51217999999999,
    "lng": -0.1592999999999999,
    "distance": 305.2752856030111
}, {
    "lat": 51.51211999999999,
    "lng": -0.15925999999999987,
    "distance": 303.71203466441693
}, {
    "lat": 51.51206999999999,
    "lng": -0.15921999999999986,
    "distance": 303.64617567161946
}, {
    "lat": 51.51204999999999,
    "lng": -0.15909999999999985
}, {
    "lat": 51.512019999999985,
    "lng": -0.15910999999999986,
    "distance": 303.5341825890455
}, {
    "lat": 51.51198999999998,
    "lng": -0.15902999999999987
}, {
    "lat": 51.511389999999984,
    "lng": -0.15907999999999986,
    "distance": 287.17242207426534
}, {
    "lat": 51.51114999999999,
    "lng": -0.15909999999999985,
    "distance": 281.04270138183625
}, {
    "lat": 51.510789999999986,
    "lng": -0.15911999999999984,
    "distance": 271.7075633838705
}, {
    "lat": 51.50991999999999,
    "lng": -0.15915999999999986,
    "distance": 250.76881783826315
}, {
    "lat": 51.50936999999999,
    "lng": -0.15918999999999986,
    "distance": 239.4159560263267
}, {
    "lat": 51.50878999999999,
    "lng": -0.15919999999999987,
    "distance": 228.53008554673934
}, {
    "lat": 51.50842999999999,
    "lng": -0.15920999999999988,
    "distance": 222.69710370815332
}, {
    "lat": 51.50798999999999,
    "lng": -0.1592499999999999,
    "distance": 216.00231480241132
}, {
    "lat": 51.50769999999999,
    "lng": -0.1592499999999999,
    "distance": 212.6405417600322
}, {
    "lat": 51.50740999999999,
    "lng": -0.15870999999999988
}, {
    "lat": 51.506859999999996,
    "lng": -0.15767999999999988
}, {
    "lat": 51.5066,
    "lng": -0.15724999999999986
}, {
    "lat": 51.506409999999995,
    "lng": -0.15689999999999987
}, {
    "lat": 51.50592999999999,
    "lng": -0.15610999999999986
}, {
    "lat": 51.50551999999999,
    "lng": -0.15538999999999986
}, {
    "lat": 51.50510999999999,
    "lng": -0.15468999999999986
}, {
    "lat": 51.504609999999985,
    "lng": -0.15386999999999987
}, {
    "lat": 51.504159999999985,
    "lng": -0.15311999999999987
}, {
    "lat": 51.504159999999985,
    "lng": -0.15313999999999986
}, {
    "lat": 51.504339999999985,
    "lng": -0.15411999999999987
}, {
    "lat": 51.50461999999998,
    "lng": -0.15583999999999987
}, {
    "lat": 51.50463999999998,
    "lng": -0.15593999999999986
}, {
    "lat": 51.50485999999998,
    "lng": -0.15718999999999986
}, {
    "lat": 51.505229999999976,
    "lng": -0.15914999999999985,
    "distance": 209.45882650296693
}, {
    "lat": 51.50530999999997,
    "lng": -0.15955999999999984,
    "distance": 199.27117202445515
}, {
    "lat": 51.50538999999997,
    "lng": -0.15990999999999983,
    "distance": 190.91883092036784
}, {
    "lat": 51.50549999999997,
    "lng": -0.16045999999999982,
    "distance": 177.36967046256808
}, {
    "lat": 51.50578999999997,
    "lng": -0.16168999999999983,
    "distance": 147.48898263938224
}, {
    "lat": 51.50594999999997,
    "lng": -0.16244999999999984,
    "distance": 130.13838787997952
}, {
    "lat": 51.50603999999997,
    "lng": -0.16297999999999985,
    "distance": 117.01709276853532
}, {
    "lat": 51.50610999999997,
    "lng": -0.16347999999999985,
    "distance": 106
}, {
    "lat": 51.50614999999997,
    "lng": -0.16415999999999986,
    "distance": 90.0222194794152
}, {
    "lat": 51.50614999999997,
    "lng": -0.16443999999999986,
    "distance": 83.02409288875127
}, {
    "lat": 51.50614999999997,
    "lng": -0.16488999999999987,
    "distance": 73.02739212103907
}, {
    "lat": 51.50607999999997,
    "lng": -0.16582999999999987,
    "distance": 51.0098029794274
}, {
    "lat": 51.506069999999966,
    "lng": -0.16605999999999987,
    "distance": 46.010868281309364
}, {
    "lat": 51.506109999999964,
    "lng": -0.16905999999999988,
    "distance": 24
}, {
    "lat": 51.50613999999997,
    "lng": -0.16933999999999988
}, {
    "lat": 51.50612999999996,
    "lng": -0.1693199999999999
}, {
    "lat": 51.50613999999997,
    "lng": -0.16933999999999988
}, {
    "lat": 51.50616999999997,
    "lng": -0.16940999999999987
}, {
    "lat": 51.50623999999997,
    "lng": -0.16949999999999987
}, {
    "lat": 51.50637999999997,
    "lng": -0.16966999999999988
}, {
    "lat": 51.50637999999997,
    "lng": -0.1697099999999999
}, {
    "lat": 51.50648999999997,
    "lng": -0.1697399999999999
}, {
    "lat": 51.50711999999997,
    "lng": -0.1699899999999999
}, {
    "lat": 51.507329999999975,
    "lng": -0.1700699999999999
}, {
    "lat": 51.507379999999976,
    "lng": -0.1700999999999999
}, {
    "lat": 51.507599999999975,
    "lng": -0.1701299999999999
}, {
    "lat": 51.50791999999998,
    "lng": -0.17019999999999988
}, {
    "lat": 51.508049999999976,
    "lng": -0.1702099999999999
}, {
    "lat": 51.50951999999997,
    "lng": -0.1703499999999999
}, {
    "lat": 51.50988999999997,
    "lng": -0.1704299999999999
}, {
    "lat": 51.510079999999974,
    "lng": -0.1705199999999999
}, {
    "lat": 51.510239999999975,
    "lng": -0.17064999999999989
}, {
    "lat": 51.51038999999997,
    "lng": -0.1708499999999999
}, {
    "lat": 51.51055999999997,
    "lng": -0.1711599999999999
}, {
    "lat": 51.51072999999997,
    "lng": -0.1715599999999999
}, {
    "lat": 51.51079999999997,
    "lng": -0.1717299999999999
}, {
    "lat": 51.51089999999997,
    "lng": -0.17190999999999992
}, {
    "lat": 51.51097999999997,
    "lng": -0.17198999999999992
}, {
    "lat": 51.51107999999997,
    "lng": -0.17204999999999993
}, {
    "lat": 51.51121999999997,
    "lng": -0.17208999999999994
}, {
    "lat": 51.51139999999997,
    "lng": -0.17210999999999993
}, {
    "lat": 51.51141999999997,
    "lng": -0.17211999999999994
}, {
    "lat": 51.511429999999976,
    "lng": -0.17194999999999994
}, {
    "lat": 51.511359999999975,
    "lng": -0.17191999999999993
}, {
    "lat": 51.51136999999998,
    "lng": -0.17172999999999994
}, {
    "lat": 51.51137999999998,
    "lng": -0.17133999999999994
}, {
    "lat": 51.51137999999998,
    "lng": -0.17113999999999993
}, {
    "lat": 51.51145999999998,
    "lng": -0.16955999999999993
}, {
    "lat": 51.51148999999998,
    "lng": -0.16843999999999992
}, {
    "lat": 51.51155999999998,
    "lng": -0.16782999999999992
}, {
    "lat": 51.51175999999998,
    "lng": -0.1663199999999999
}, {
    "lat": 51.51181999999998,
    "lng": -0.16584999999999991
}, {
    "lat": 51.51184999999998,
    "lng": -0.1656999999999999
}, {
    "lat": 51.51207999999998,
    "lng": -0.1640499999999999
}, {
    "lat": 51.51211999999998,
    "lng": -0.1634699999999999
}, {
    "lat": 51.51206999999998,
    "lng": -0.1627699999999999
}, {
    "lat": 51.51206999999998,
    "lng": -0.16261999999999988
}, {
    "lat": 51.51201999999998,
    "lng": -0.16234999999999988
}, {
    "lat": 51.512099999999975,
    "lng": -0.1622199999999999
}, {
    "lat": 51.512079999999976,
    "lng": -0.1621599999999999
}, {
    "lat": 51.51205999999998,
    "lng": -0.16200999999999988
}, {
    "lat": 51.51206999999998,
    "lng": -0.16130999999999987
}, {
    "lat": 51.51205999999998,
    "lng": -0.16105999999999987
}, {
    "lat": 51.51203999999998,
    "lng": -0.16081999999999988
}, {
    "lat": 51.51208999999998,
    "lng": -0.1608299999999999
}, {
    "lat": 51.51228999999998,
    "lng": -0.15984999999999988
}, {
    "lat": 51.51230999999998,
    "lng": -0.1598599999999999
}, {
    "lat": 51.51237999999998,
    "lng": -0.15987999999999988
}, {
    "lat": 51.51242999999998,
    "lng": -0.1594399999999999
}, {
    "lat": 51.512439999999984,
    "lng": -0.15917999999999988
}, {
    "lat": 51.51245999999998,
    "lng": -0.15889999999999987
}, {
    "lat": 51.512439999999984,
    "lng": -0.15881999999999988
}, {
    "lat": 51.51244999999999,
    "lng": -0.1587499999999999
}, {
    "lat": 51.512509999999985,
    "lng": -0.15865999999999988
}, {
    "lat": 51.512579999999986,
    "lng": -0.1585599999999999
}, {
    "lat": 51.51263999999998,
    "lng": -0.15854999999999989
}, {
    "lat": 51.512709999999984,
    "lng": -0.15856999999999988
}, {
    "lat": 51.51271999999999,
    "lng": -0.15853999999999988
}, {
    "lat": 51.512849999999986,
    "lng": -0.15858999999999987
}, {
    "lat": 51.512849999999986,
    "lng": -0.15853999999999988
}, {
    "lat": 51.51320999999999,
    "lng": -0.15866999999999987
}, {
    "lat": 51.513229999999986,
    "lng": -0.15856999999999988
}, {
    "lat": 51.51332999999999,
    "lng": -0.1584399999999999
}, {
    "lat": 51.51338999999999,
    "lng": -0.15837999999999988
}, {
    "lat": 51.51339999999999,
    "lng": -0.1583599999999999
}, {
    "lat": 51.51340999999999,
    "lng": -0.1583399999999999
}, {
    "lat": 51.51342999999999,
    "lng": -0.1583199999999999
}, {
    "lat": 51.513439999999996,
    "lng": -0.1582799999999999
}, {
    "lat": 51.513459999999995,
    "lng": -0.1582599999999999
}, {
    "lat": 51.51349999999999,
    "lng": -0.1582699999999999
}, {
    "lat": 51.51353999999999,
    "lng": -0.15827999999999992
}, {
    "lat": 51.51358999999999,
    "lng": -0.15777999999999992
}, {
    "lat": 51.513659999999994,
    "lng": -0.15717999999999993
}, {
    "lat": 51.51369,
    "lng": -0.15690999999999994
}, {
    "lat": 51.51376,
    "lng": -0.15619999999999995
}, {
    "lat": 51.51381,
    "lng": -0.15600999999999995
}, {
    "lat": 51.51424,
    "lng": -0.15620999999999996
}, {
    "lat": 51.51437,
    "lng": -0.15627999999999995
}, {
    "lat": 51.51451,
    "lng": -0.15632999999999994
}, {
    "lat": 51.514540000000004,
    "lng": -0.15633999999999995
}, {
    "lat": 51.51493000000001,
    "lng": -0.15651999999999996
}, {
    "lat": 51.514970000000005,
    "lng": -0.15653999999999996
}, {
    "lat": 51.51503,
    "lng": -0.15656999999999996
}, {
    "lat": 51.51512,
    "lng": -0.15660999999999997
}, {
    "lat": 51.5155,
    "lng": -0.15677999999999997
}, {
    "lat": 51.515550000000005,
    "lng": -0.15680999999999998
}, {
    "lat": 51.5159,
    "lng": -0.15697999999999998
}, {
    "lat": 51.51597,
    "lng": -0.15700999999999998
}, {
    "lat": 51.516070000000006,
    "lng": -0.15705999999999998
}, {
    "lat": 51.516360000000006,
    "lng": -0.15719999999999998
}, {
    "lat": 51.516580000000005,
    "lng": -0.15729999999999997
}, {
    "lat": 51.516960000000005,
    "lng": -0.15747999999999998
}, {
    "lat": 51.517,
    "lng": -0.15749
}, {
    "lat": 51.51708,
    "lng": -0.15753
}, {
    "lat": 51.51714,
    "lng": -0.15756
}, {
    "lat": 51.51777,
    "lng": -0.15784
}, {
    "lat": 51.51899,
    "lng": -0.15839
}, {
    "lat": 51.51903,
    "lng": -0.15841
}, {
    "lat": 51.51909,
    "lng": -0.15844
}, {
    "lat": 51.519149999999996,
    "lng": -0.15846
}, {
    "lat": 51.519639999999995,
    "lng": -0.15868
}, {
    "lat": 51.51969,
    "lng": -0.15871
}]

Make the plugin work with Leaflet 1.0

Leaflet is in 1.0.0-rc.3

Tests of GeometryUtil show breaks : Polygon and Polyline have evolved, the R (radius) of earth change too.

  • change tests to accept a new radius
  • accept the evolution of Polygon & Polyline without breaking compatibility with 0.7.7

Why does layersWithin take a distance in pixels?

I think this would be an extremely useful function if it took a search radius in meters. I have no idea how it is useful if it takes a search radius in screen pixels.

Am I missing something?

TypeScript support

I'm using Leaflet.GeometryUtil in a TypeScript project. As far as I'm aware, there are no typings yet, as mentioned in #73.

I would like to write some typings. There are 3 options:

  1. Write typings and publish them as a separate @types/leaflet-geometryutil package.
  2. Write typings and include them in this repository. This would involve creating a .d.ts definition file and referencing it in the "types" field in package.json.
  3. Convert the whole source code to TypeScript. This would involve changing the setup a bit. A build script would have to be run before publishing the project.

The first option is the least intrusive to this project, the third one is the most proper one, since it makes sure that the type definitions are really in sync with the code.

Which one would you prefer?

closestLayer

I'm pretty new to Leaflet. We have some geoMapping code that's been running for quite some time. We use Google Maps API and all of our geoData is stored in SQL Server tables. We jump through quite a few hoops to render polygons and calculate area and distance and such.

So, things like MapBox, Leaflet, and GeometryUtil are starting to look quite appealing as we ramp up to re-build our software using these newer technologies.

We have one use case where we have a LatLng pair and we want to know which of our polygons that point is inside of. It may be in one or, due to overlapping or concentric polygons, it may be in more than one. The Leaflet PIP plugin seems as though it will help with that problem.

Another use case, where GeometryUtil looks handy, relates to a LatLng pair that doesn't fall inside any of our Polygons. However, we want to know which of our Polygons is "closest" to the LatLng point. My hope is that your closestLayer will do that. I would be more confident if it were called closesPolygon or closestFeature, but I'm thinking that if I create a "set" of layers (each containing a single polygon) your closestLayer will tell me which one is closest.

True??

Thanks in advance.

Function for combining bounding boxes

Scenario
A have a map where i need to add several geojsons which can be at different places and i need to set the bounds of the map to a combined bounding box from all the geojsons.

Possible solution
let merged = merge([BoundingBoxA, BoundingBoxB,....]);

Looked into the documentation and i can't see anything like this there - is there a plan to add something like this?

Using closest function with GeoJSON layer

Hi, I thought it could be used because L.geoJson implements ILayer, however I can't get it working.
The GeoJson file is a set of points (markers) which is being properly rendered.

The error: Uncaught TypeError: Cannot read property 'lat' of null . It happens at 'closest' function within the code.
It refers to "distanceSegment: function (map, latlng, latlngA, latlngB) "
Thanks!

function nearestBiciAmigo()
{               
    if (typeof latlngmap != "undefined")
    {
        if ((latlngmap.lat != null) && (latlngmap.lng != null))
        {       

            var nlatlng = L.GeometryUtil.closest(mapa, geoBiciAmigos.getLayers() ,latlngmap);                                                               
            mapa.setView(nlatlng,13);                                   
        }
        else
            alert("Click sobre el lugar");                  
    }        
    else
        alert("Click sobre el lugar");
}

Npm package not updated

Hi,
the latest published npm package has a dependency on leaflet >=0.7.0, that is causing a misalignment on leaflet versions after a npm install:

Screenshot 2021-04-06 at 17 49 59

In master branch the dependency on leaflet is actually set to ^1.6.0: could you please update the npm package?

Please provide complete source tarball

Please provide a complet esource tarball, inbcluding the sources for docs/ and everything else needed for a complete build. At the very least, alle make targets should work from the source tarball.

Please, if possible, also provide a changelog and sign the release tarball.

Write use cases for a demo

To make this plugin easier to test, it could be a good idea to write some examples in a demo.

If you have use cases, don't hesitate to suggest yours.

Array<Array<L.LatLng>>

It is possible that some features have an Array of Arrays of LatLngs instead of a single imbrication.
The plugin does not support this right now.

Bower install

please make this package available for installation via bower :)

Point rotation?

Hi,

I've been researching on how I could rotate lat/long points around a known point. For example, I would like to calculate what the coordinates would be if I rotate point (lat: 37 degrees, lon: -80 degrees) around lat/long (36 degrees/-79 degrees) by 20 degrees.

I was wondering if this is something that could be added this library?

Thanks,

Nick,

Ambiguity in the result of closestLayer()

If I input an array of layers, it will return the nearest layer, which is an element of the input array. However, if I input a mixed array of layers and layer groups, it may return a layer within a layer group, which isn't an element of the input array.

I am raising this question for the consistency of the function output, though it may not cause any problem actually...

Doesn't work with leaflet 1.1.0

The function Leaflet.Polyline._flat has been moved to Leaflet.LineUtil._flat so this has to be updated to make it work with Leaflet 1.1.0

Closest layer between Circle and Line

When line traverse circle in center, what is the closest layer in case of

  1. mouse is over border of circle
  2. line is the first layer in the layers array?
    Now line is the closest layer to mouse position. But correct - circle is the closest layer. Need to find closest distance to mouse position using latlng of circle center and it's radius!

maybe edit method closestLayer: function (map, layers, latlng);
like:

closestLayer: function (map, layers, latlng) {
        var mindist = Infinity,
            result = null,
            ll = null,
            distance = Infinity;

        for (var i = 0, n = layers.length; i < n; i++) {
            var layer = layers[i];
            // Single dimension, snap on points, else snap on closest
            if (typeof layer.getLatLng == 'function') {
                ll = layer.getLatLng();
                distance = L.GeometryUtil.distance(map, latlng, ll);

                if (layer instanceof L.Circle){
                    distance = distance - layer.getRadius();
                }
            }
            else {
                ll = L.GeometryUtil.closest(map, layer, latlng);
                if (ll) distance = ll.distance; // Can return null if layer has no points.
            }
            if (distance < mindist) {
                mindist = distance;
                result = {layer: layer, latlng: ll, distance: distance};
            }
        }
        return result;
    }

Distance function : Cannot read property 'distance' of undefined

Hello,
I'm developing a map in vuejs using leaflet, and I want to use GeometryUtil to calculate the distance between two points. For that, I use the tuto distance-length but when I use the function I got an error in the console :
Cannot read property 'distance' of undefined

var firstLatLng = {lat:48.858372,lng:2.294479};
var secondLatLng = {lat:48.847258,lng:2.352742}
var distance = L.GeometryUtil.distance(map, firstLatLng, secondLatLng)
console.log(distance)

Is this because I'm using vuejs or because I didn't use well the function?

Thank you for your help

MultilineString Bug in ClosestLayer (and Closest)

I have another utility (actually osmtogeojson that is creating Multilinestring features where one of the segments (that translate to elements in latlngs Array when they get to GeometryUtil) has a single point. This causes GeometryUtil to crash @ line 187

if (subResult.distance < mindist)

since subResult is null.

Without arguing whether this is a valid feature - the crash is very easy to prevent - I will send a PR>

Function "closest" adds extra points to layers

There is an issue, described in title
Please see this plunk
Click to set markers and see in console how latlngs of polygon grows.
It seems to me, that it happens because function "slice()" does not makes deep copy for nested arrays (line 205 in source)

How use closestLayerSnap?

I use:
L.GeometryUtil.closestLayerSnap(map, [L.polyline(...)], map.getCenter(),9000)
and result [Object object]. What the [Object object]???
And if i use Geojson(not L.polyline), can i?

Change directory structure to Leaflet Guide

According to leaflet recommendations for file structure, from the plugin guide,

/src        - JS source files
/dist       - minified plugin JS, CSS, images
/spec       - test files
/lib        - any external libraries/plugins if necessary
/examples   - HTML examples of plugin usage
README.md
LICENSE
package.json

We are not going to put examples at the root, but in a 'docs' directory, that will be displayed in github pages.

  • move source file into src directory
  • minify the plugin into dist directory
  • move test files into spec directory
  • fix package.json & test files to use the src file

The "withVertices" parameter of closestLayerSnap is not acting correctly and returns points on segments as well

Hello,

I am using the closestLayerSnap function with the withVertices parameter set to true, like:

 var result = L.GeometryUtil.closestLayerSnap(this.map, layers, latlng, tolerance, true);

I would expect the snapping to only happen on vectrices that exist on the layer but instead, I also get result on segments.
I believe this is also what happened to the issue #21 and the fix (infinite tolerance or documentation fix #22 ) is not really a fix. The parameter "withVertices" should only return points that belong to the layer.

After digging a little, it is logic because of the way the code is currently implemented.
First pass is calling closestLayer:
https://github.com/makinacorpus/Leaflet.GeometryUtil/blob/master/dist/leaflet.geometryutil.js#L242

Which has no "withVertices" parameter and snap on closest, see this comment:
https://github.com/makinacorpus/Leaflet.GeometryUtil/blob/master/dist/leaflet.geometryutil.js#L211
It calls

ll = L.GeometryUtil.closest(map, layer, latlng);

without passing it the fourth parameter "withVertices" so if your position is close enough to the middle of a segment, it will return a point on this segment.
Because there is at least a result during first pass, it is then returned by closestLayerSnap

I believe the appropriate behaviour would be to pass the withVertices parameter everywhere so that the behaviour is consistent

I'll add a PR

Thanks,
Fabien

exports is undefined in IE8

The first line of the file, that defines the namespace causes an error in IE8
var L = L || exports;

exports is undefined. Seems to work without this declaration. I'm not sure what exports is/does.

License

Can you specify what license Leaflet.GeometryUtil is governed by?

Error in ratio estimation on locateOnLine and interpolateOnLine

I've found an inconsistency in the results if locateOnLine and interpolateOnline.

I've tried to compute the ratio of a point along a road of 320 km ca then convert the ratio to a latlon again. There is a variable misplacement, pretty high in my opinion, it could go above 1km.

I've fixed implementing my own version of the functions


interpolateOnLine = function (map, latLngs, ratio) {
    latLngs = (latLngs instanceof L.Polyline) ? latLngs.getLatLngs() : latLngs;
    var maxzoom = map.getMaxZoom();
    if (maxzoom === Infinity)
        maxzoom = map.getZoom();
    var pts = latLngs.map(function (x) {
        return map.project(x);
    });

    if (ratio <= 0)
        return latLngs[0];
    if (ratio >= 1)
        return latLngs[latLngs - 1];

    var dt = 0.;
    for (var i = 1; i < pts.length; i++)
        dt += pts[i - 1].distanceTo(pts[i]);

    var dp = dt * ratio;


    var dt = 0.;
    for (var i = 1; i < pts.length; i++)
    {
        var d = pts[i - 1].distanceTo(pts[i]);
        if (dt + d > dp)
        {
            //console.log((dp-dt)/d);
            var p = L.GeometryUtil.interpolateOnPointSegment(pts[i - 1], pts[i], (dp - dt) / d);
            return map.unproject(p);
        }
        dt += d;

    }

    return latLngs[latLngs - 1];
};


locateOnLine = function (map, polyline, latlng) {
    var maxzoom = map.getMaxZoom();
    if (maxzoom === Infinity)
        maxzoom = map.getZoom();
    var pts = polyline.getLatLngs().map(function (x) {
        return map.project(x);
    });
    var point = map.project(L.GeometryUtil.closest(map, polyline, latlng, false));


    var d = 0.;
    var dt = 0.;
    for (var i = 1; i < pts.length; i++)
    {
        var dd = pts[i - 1].distanceTo(pts[i]);
        if (L.GeometryUtil.belongsSegment(point, pts[i - 1], pts[i], 0.0001))
            d = dt + pts[i - 1].distanceTo(point);
        dt += dd;
    }
    return d / dt;
};


I've tested converting latlon to ratio to latlon to ratio .... till 10 times and now it seems to be very stable and consistent

PLEASE NOTE THAT interpolateOnLine here is not returning the precedent point , just the interpolated one

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.