Last active
June 28, 2016 18:35
-
-
Save helderdarocha/47fff819307ef8488607007ebb4f8b92 to your computer and use it in GitHub Desktop.
Path simplification example with Leaflet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: cc-by-sa-4.0 | |
height: 550 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<style> | |
#map { | |
height: 500px; | |
width: 700px; | |
} | |
#slider { | |
width: 900px; | |
padding: 10px 20px 0 10px; | |
} | |
#info { | |
width: 200px; | |
float: left; | |
padding: 0 20px 0 10px; | |
} | |
textarea { | |
margin-left: 5px; | |
width: 100%; | |
height: 120px; | |
} | |
button {width: 100%} | |
input { | |
width: 50%; | |
} | |
</style> | |
<meta charset="UTF-8"> | |
<title>Track simplification using Leaflet</title> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.js"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.css"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script> | |
</head> | |
<body> | |
<div id="info"> | |
<form> | |
<h4>Original data</h4> | |
<p>points: <span id="val_orig_point_count">0</span> | |
<br/>distance: <span id="val_original_distance">0</span> meters</br> | |
<p><button type="button" id="btn_load">(Re)load data</button></p> | |
<h4>Current</h4> | |
<p>points: <span id="val_current_point_count">0</span> | |
<br/>distance: <span id="val_current_distance">0</span> meters</br> | |
<h4>Slider configuration</h4> | |
<p>Max distance<br><input type="number" id="slider_max" value="100"/> meters</p> | |
<p>Step<br><input type="number" id="slider_step" value="1"/> meters</p> | |
</form> | |
</div> | |
<div id="map"></div> | |
<div id="slider"> | |
<form> | |
Slide to simplify path (max distance to perpendicular line segment of point to remove): <span id="val_tolerance">0</span> meters | |
<input type="range" id="tolerance" | |
name="tolerance" value="0" | |
min="0" | |
max="100" | |
step="1"> | |
</form> | |
</div> | |
<script> | |
// SAMPLE DATA - replace this with different data in this format | |
var trail_data = [{lat:-23.5394387,lng:-46.6788375},{lat:-23.5396059,lng:-46.6785693},{lat:-23.5397239,lng:-46.6783333},{lat:-23.5398813,lng:-46.6781509},{lat:-23.540019,lng:-46.6779792},{lat:-23.5401567,lng:-46.6777647},{lat:-23.5402255,lng:-46.6775823},{lat:-23.5403141,lng:-46.6774642},{lat:-23.5404124,lng:-46.6773248},{lat:-23.5405993,lng:-46.677078},{lat:-23.540737,lng:-46.6769063},{lat:-23.540855,lng:-46.676724},{lat:-23.5409829,lng:-46.6765523},{lat:-23.5410714,lng:-46.6763484},{lat:-23.5411403,lng:-46.6762304},{lat:-23.5411993,lng:-46.6762626},{lat:-23.5412878,lng:-46.6762304},{lat:-23.541455,lng:-46.6762948},{lat:-23.5415632,lng:-46.6763484},{lat:-23.5417698,lng:-46.6764343},{lat:-23.541937,lng:-46.6764343},{lat:-23.5421337,lng:-46.6764772},{lat:-23.542419,lng:-46.6765094},{lat:-23.542714,lng:-46.6765738},{lat:-23.5428419,lng:-46.6766167},{lat:-23.5429599,lng:-46.6766059},{lat:-23.5430681,lng:-46.6766059},{lat:-23.5431665,lng:-46.6766274},{lat:-23.5433632,lng:-46.6766596},{lat:-23.5434812,lng:-46.6767132},{lat:-23.5436681,lng:-46.6766918},{lat:-23.5437665,lng:-46.676681},{lat:-23.5438845,lng:-46.6767025},{lat:-23.544032,lng:-46.6767025},{lat:-23.5442189,lng:-46.6767025},{lat:-23.5444845,lng:-46.6767132},{lat:-23.5446713,lng:-46.6767454},{lat:-23.5449271,lng:-46.6767454},{lat:-23.5451336,lng:-46.6767561},{lat:-23.545586,lng:-46.6768527},{lat:-23.5458713,lng:-46.6768634},{lat:-23.5460582,lng:-46.6768634},{lat:-23.5462549,lng:-46.6768634},{lat:-23.5464417,lng:-46.6768849},{lat:-23.546727,lng:-46.6769493},{lat:-23.547022,lng:-46.6769707},{lat:-23.5472679,lng:-46.6770029},{lat:-23.547504,lng:-46.6770244},{lat:-23.5479072,lng:-46.6770673},{lat:-23.5482711,lng:-46.6771209},{lat:-23.5484973,lng:-46.6771209},{lat:-23.5487826,lng:-46.6772711},{lat:-23.5491268,lng:-46.6773677},{lat:-23.5493235,lng:-46.6775286},{lat:-23.5496382,lng:-46.6774213},{lat:-23.5498349,lng:-46.6774321},{lat:-23.5502185,lng:-46.6774321},{lat:-23.5504349,lng:-46.6774642},{lat:-23.5506513,lng:-46.6774964},{lat:-23.5507791,lng:-46.6775393},{lat:-23.5510348,lng:-46.6776359},{lat:-23.5512611,lng:-46.6777647},{lat:-23.5514184,lng:-46.6778827},{lat:-23.5516348,lng:-46.6780329},{lat:-23.5518118,lng:-46.6782153},{lat:-23.5520479,lng:-46.6783762},{lat:-23.5522839,lng:-46.6785371},{lat:-23.5524019,lng:-46.6786659},{lat:-23.552579,lng:-46.6786981},{lat:-23.5526773,lng:-46.6788268},{lat:-23.5528543,lng:-46.678977},{lat:-23.5530215,lng:-46.6791058},{lat:-23.5531592,lng:-46.6791809},{lat:-23.5532969,lng:-46.6793203},{lat:-23.5534444,lng:-46.6795027},{lat:-23.553592,lng:-46.6796207},{lat:-23.5537985,lng:-46.6797817},{lat:-23.553946,lng:-46.6798997},{lat:-23.5541722,lng:-46.6800714},{lat:-23.5543591,lng:-46.6803288},{lat:-23.5544968,lng:-46.6804576},{lat:-23.554723,lng:-46.6806614},{lat:-23.5549492,lng:-46.6810584},{lat:-23.5551164,lng:-46.6812515},{lat:-23.5552639,lng:-46.681509},{lat:-23.5555098,lng:-46.6818094},{lat:-23.5556081,lng:-46.6819596},{lat:-23.5556966,lng:-46.6821849},{lat:-23.5559523,lng:-46.682539},{lat:-23.55609,lng:-46.6827106},{lat:-23.5562572,lng:-46.6828501},{lat:-23.5564736,lng:-46.682936},{lat:-23.5567686,lng:-46.6829467},{lat:-23.5571128,lng:-46.6828179},{lat:-23.55728,lng:-46.6827321},{lat:-23.5575357,lng:-46.6825604},{lat:-23.5577718,lng:-46.6824532},{lat:-23.5579095,lng:-46.6823244},{lat:-23.5580471,lng:-46.6822064},{lat:-23.5583028,lng:-46.682142},{lat:-23.5584602,lng:-46.6821206},{lat:-23.5587159,lng:-46.6820133},{lat:-23.5589913,lng:-46.6819382},{lat:-23.5591486,lng:-46.6818416},{lat:-23.5593256,lng:-46.6817236},{lat:-23.5595223,lng:-46.6815841},{lat:-23.5597092,lng:-46.681391},{lat:-23.5599747,lng:-46.6811872},{lat:-23.5602107,lng:-46.6810155},{lat:-23.5603779,lng:-46.6809082},{lat:-23.5606631,lng:-46.6807044},{lat:-23.560791,lng:-46.6806078},{lat:-23.5609778,lng:-46.6804683},{lat:-23.5611548,lng:-46.680361},{lat:-23.5613024,lng:-46.6802645},{lat:-23.5614892,lng:-46.680243},{lat:-23.5615089,lng:-46.6803288},{lat:-23.5615974,lng:-46.6802001},{lat:-23.5614991,lng:-46.6801357},{lat:-23.5616564,lng:-46.6800177},{lat:-23.5618826,lng:-46.6798139},{lat:-23.5622661,lng:-46.6795456},{lat:-23.5625513,lng:-46.6793203},{lat:-23.5628365,lng:-46.6791272},{lat:-23.5631119,lng:-46.6789448},{lat:-23.5633086,lng:-46.6787732},{lat:-23.5635348,lng:-46.6786551},{lat:-23.5637216,lng:-46.6785264},{lat:-23.5639871,lng:-46.6783118},{lat:-23.5642035,lng:-46.6781616},{lat:-23.5643412,lng:-46.6780329},{lat:-23.5644592,lng:-46.6779363},{lat:-23.5646854,lng:-46.6777325},{lat:-23.5648624,lng:-46.6775286},{lat:-23.5650394,lng:-46.6773248},{lat:-23.5652066,lng:-46.6770887},{lat:-23.5653541,lng:-46.6769385},{lat:-23.5654721,lng:-46.6767776},{lat:-23.5655704,lng:-46.6766167},{lat:-23.5657769,lng:-46.6763484},{lat:-23.5658851,lng:-46.6761553},{lat:-23.5659933,lng:-46.6759837},{lat:-23.5661408,lng:-46.6758013},{lat:-23.5662391,lng:-46.6756725},{lat:-23.5663572,lng:-46.6755116},{lat:-23.566485,lng:-46.6753614},{lat:-23.566544,lng:-46.6752005},{lat:-23.566603,lng:-46.6750932},{lat:-23.566839,lng:-46.6748464},{lat:-23.566898,lng:-46.6747713},{lat:-23.5671242,lng:-46.6745245},{lat:-23.5672422,lng:-46.6743529},{lat:-23.5673504,lng:-46.6742456},{lat:-23.5676061,lng:-46.6739881},{lat:-23.5677437,lng:-46.6738701},{lat:-23.5679208,lng:-46.6736555},{lat:-23.5680289,lng:-46.6735482},{lat:-23.5682944,lng:-46.67328},{lat:-23.5684223,lng:-46.6731191},{lat:-23.5686386,lng:-46.6729259},{lat:-23.5688156,lng:-46.6727436},{lat:-23.5689336,lng:-46.6726148},{lat:-23.5690713,lng:-46.6724861},{lat:-23.5691795,lng:-46.6723359},{lat:-23.5693467,lng:-46.6721964},{lat:-23.569445,lng:-46.6720891},{lat:-23.5696908,lng:-46.6718102},{lat:-23.5698187,lng:-46.6716385},{lat:-23.5699564,lng:-46.6714776},{lat:-23.5700842,lng:-46.6713595},{lat:-23.5702317,lng:-46.6711879},{lat:-23.5704677,lng:-46.6709304},{lat:-23.5705857,lng:-46.6708231},{lat:-23.5707431,lng:-46.6706622},{lat:-23.5709004,lng:-46.6705227},{lat:-23.5710872,lng:-46.6703403},{lat:-23.5712446,lng:-46.6702116},{lat:-23.5713429,lng:-46.6700399},{lat:-23.5714904,lng:-46.6699004},{lat:-23.5716379,lng:-46.6697824},{lat:-23.5718051,lng:-46.6695786},{lat:-23.5719526,lng:-46.6693854},{lat:-23.5721394,lng:-46.6691816},{lat:-23.5722378,lng:-46.6690528},{lat:-23.5723951,lng:-46.6688919},{lat:-23.5724934,lng:-46.6688168},{lat:-23.5725918,lng:-46.6687202},{lat:-23.5727098,lng:-46.6685808},{lat:-23.5728573,lng:-46.6684735},{lat:-23.5729753,lng:-46.6683555},{lat:-23.573113,lng:-46.6683233},{lat:-23.5732113,lng:-46.6684842},{lat:-23.5733293,lng:-46.668613},{lat:-23.5734178,lng:-46.668731},{lat:-23.573526,lng:-46.6688704},{lat:-23.5736243,lng:-46.6689777},{lat:-23.5736833,lng:-46.6691065},{lat:-23.573762,lng:-46.6692245},{lat:-23.5738406,lng:-46.6693211},{lat:-23.5739488,lng:-46.6694713},{lat:-23.5740275,lng:-46.6696107},{lat:-23.5741258,lng:-46.6697609},{lat:-23.5742045,lng:-46.6698575},{lat:-23.5743028,lng:-46.6698575},{lat:-23.5744601,lng:-46.6698039},{lat:-23.574529,lng:-46.6697073},{lat:-23.5746666,lng:-46.6695678},{lat:-23.5747551,lng:-46.669482},{lat:-23.574883,lng:-46.6695571},{lat:-23.5749518,lng:-46.6697073},{lat:-23.5750895,lng:-46.669879},{lat:-23.5751583,lng:-46.6700506},{lat:-23.5752861,lng:-46.6701686},{lat:-23.5754041,lng:-46.6702652},{lat:-23.5754238,lng:-46.670351},{lat:-23.5755123,lng:-46.6704583},{lat:-23.5756008,lng:-46.6705334},{lat:-23.575709,lng:-46.6704583},{lat:-23.5757876,lng:-46.6703081},{lat:-23.5758958,lng:-46.6701579},{lat:-23.575945,lng:-46.6700721},{lat:-23.5760925,lng:-46.6700721},{lat:-23.5761711,lng:-46.6702116},{lat:-23.57624,lng:-46.6703188},{lat:-23.5763678,lng:-46.6704583},{lat:-23.576476,lng:-46.6705549},{lat:-23.576535,lng:-46.6706836},{lat:-23.5766235,lng:-46.670866},{lat:-23.5767218,lng:-46.6710162},{lat:-23.5768791,lng:-46.6711342},{lat:-23.5770168,lng:-46.6712415},{lat:-23.5771643,lng:-46.6713166},{lat:-23.5773806,lng:-46.6713381},{lat:-23.5776265,lng:-46.6712844},{lat:-23.5778428,lng:-46.6712523},{lat:-23.5779903,lng:-46.6712308},{lat:-23.5780886,lng:-46.6712308},{lat:-23.5782066,lng:-46.6712093},{lat:-23.5785114,lng:-46.6711664},{lat:-23.5786393,lng:-46.671102},{lat:-23.5787671,lng:-46.6710806},{lat:-23.5788949,lng:-46.6710591},{lat:-23.5790523,lng:-46.6710162},{lat:-23.5791703,lng:-46.6709948},{lat:-23.5793079,lng:-46.6709733},{lat:-23.5793964,lng:-46.6709197},{lat:-23.5796127,lng:-46.6709197},{lat:-23.5797307,lng:-46.6708767},{lat:-23.5798586,lng:-46.6708446},{lat:-23.5802126,lng:-46.6708016},{lat:-23.5803699,lng:-46.6707373},{lat:-23.5806255,lng:-46.6706944},{lat:-23.5808714,lng:-46.6706622},{lat:-23.5810385,lng:-46.67063},{lat:-23.5812745,lng:-46.6705978},{lat:-23.5814318,lng:-46.6705871},{lat:-23.5815597,lng:-46.6705656},{lat:-23.5817268,lng:-46.6705441},{lat:-23.5819038,lng:-46.6705227},{lat:-23.5821398,lng:-46.6705334},{lat:-23.5823561,lng:-46.670469},{lat:-23.5825921,lng:-46.670469},{lat:-23.5827494,lng:-46.6704369},{lat:-23.5828871,lng:-46.6704047},{lat:-23.5830543,lng:-46.6703403},{lat:-23.5831919,lng:-46.6703403},{lat:-23.5833787,lng:-46.6703403},{lat:-23.5834869,lng:-46.6705871},{lat:-23.5835754,lng:-46.6708875},{lat:-23.5836344,lng:-46.6710913},{lat:-23.5836934,lng:-46.6713488},{lat:-23.5837819,lng:-46.6716385},{lat:-23.5838016,lng:-46.6718531},{lat:-23.5838605,lng:-46.6720247},{lat:-23.5835754,lng:-46.6721106},{lat:-23.5833492,lng:-46.6721964},{lat:-23.5830936,lng:-46.67225},{lat:-23.5828281,lng:-46.672411},{lat:-23.5826315,lng:-46.6724539},{lat:-23.5824545,lng:-46.672529},{lat:-23.5822775,lng:-46.6725826},{lat:-23.5822086,lng:-46.6724002},{lat:-23.5821693,lng:-46.6721213},{lat:-23.5821005,lng:-46.6719496},{lat:-23.5820218,lng:-46.6716063},{lat:-23.5819727,lng:-46.6714025},{lat:-23.581894,lng:-46.6711879},{lat:-23.5818547,lng:-46.6710269},{lat:-23.5818153,lng:-46.6709089},{lat:-23.581776,lng:-46.6707158},{lat:-23.581776,lng:-46.6704261},{lat:-23.581953,lng:-46.6703939},{lat:-23.5821201,lng:-46.6703725},{lat:-23.5822873,lng:-46.670351},{lat:-23.5824741,lng:-46.6703081},{lat:-23.5826511,lng:-46.6702867},{lat:-23.5828674,lng:-46.6702545},{lat:-23.5829854,lng:-46.6702437},{lat:-23.5831526,lng:-46.6702008},{lat:-23.5833001,lng:-46.6701794},{lat:-23.5834771,lng:-46.6701794},{lat:-23.5836541,lng:-46.6701794},{lat:-23.5838409,lng:-46.6702008},{lat:-23.5839589,lng:-46.6702652},{lat:-23.584185,lng:-46.6702974},{lat:-23.5844013,lng:-46.6703939},{lat:-23.5846078,lng:-46.6704583},{lat:-23.5847357,lng:-46.6705334},{lat:-23.5850208,lng:-46.6706407},{lat:-23.585306,lng:-46.6707158},{lat:-23.5854928,lng:-46.6708231},{lat:-23.5857386,lng:-46.6709411},{lat:-23.5860336,lng:-46.6711128},{lat:-23.586358,lng:-46.6713059},{lat:-23.586535,lng:-46.6713488},{lat:-23.58683,lng:-46.6714454},{lat:-23.5870168,lng:-46.6715312},{lat:-23.5872233,lng:-46.6715634},{lat:-23.5874003,lng:-46.671617},{lat:-23.5875478,lng:-46.6716492},{lat:-23.5877837,lng:-46.6717243},{lat:-23.5880885,lng:-46.6718209},{lat:-23.5882262,lng:-46.6718638},{lat:-23.5883737,lng:-46.671896},{lat:-23.5885998,lng:-46.6719925},{lat:-23.5888063,lng:-46.6720569},{lat:-23.5890226,lng:-46.6721106},{lat:-23.5892389,lng:-46.6721749},{lat:-23.5895437,lng:-46.6722608},{lat:-23.589878,lng:-46.6723359},{lat:-23.5900648,lng:-46.672411},{lat:-23.5904286,lng:-46.6724968},{lat:-23.5906155,lng:-46.672529},{lat:-23.5908514,lng:-46.6725934},{lat:-23.5910972,lng:-46.6726255},{lat:-23.5913234,lng:-46.6727114},{lat:-23.5917265,lng:-46.6727757},{lat:-23.5920411,lng:-46.6728079},{lat:-23.5922181,lng:-46.6728187},{lat:-23.5926802,lng:-46.6729045},{lat:-23.5928473,lng:-46.6729152},{lat:-23.5930538,lng:-46.6729474},{lat:-23.5931816,lng:-46.6729474},{lat:-23.5934274,lng:-46.6729581},{lat:-23.5936241,lng:-46.6729689},{lat:-23.59386,lng:-46.6729796},{lat:-23.5940075,lng:-46.6730332},{lat:-23.594214,lng:-46.673044},{lat:-23.5944303,lng:-46.6730869},{lat:-23.5946269,lng:-46.6731191},{lat:-23.5948334,lng:-46.6731298},{lat:-23.5952168,lng:-46.6731834},{lat:-23.5954331,lng:-46.6732156},{lat:-23.5955413,lng:-46.6732156},{lat:-23.5959149,lng:-46.6733229},{lat:-23.5960329,lng:-46.6733873},{lat:-23.5961902,lng:-46.6734517},{lat:-23.5963967,lng:-46.6735804},{lat:-23.596672,lng:-46.673677},{lat:-23.5968194,lng:-46.6737843},{lat:-23.5969866,lng:-46.6738594},{lat:-23.5972127,lng:-46.6739666},{lat:-23.5974487,lng:-46.6739881},{lat:-23.5976453,lng:-46.6740203},{lat:-23.5978911,lng:-46.6740203},{lat:-23.5984318,lng:-46.6739774},{lat:-23.598658,lng:-46.6739774},{lat:-23.5988153,lng:-46.6739881},{lat:-23.5990119,lng:-46.6739666},{lat:-23.5992478,lng:-46.6739666},{lat:-23.5995035,lng:-46.6739666},{lat:-23.5997591,lng:-46.6739666},{lat:-23.599995,lng:-46.6740096},{lat:-23.6002605,lng:-46.6739881},{lat:-23.6004964,lng:-46.6740417},{lat:-23.6007226,lng:-46.6740203},{lat:-23.6009782,lng:-46.6740417},{lat:-23.601165,lng:-46.6740847},{lat:-23.6013714,lng:-46.6741383},{lat:-23.6016172,lng:-46.6741383},{lat:-23.601745,lng:-46.6741705},{lat:-23.6018925,lng:-46.674192},{lat:-23.6020301,lng:-46.6742563},{lat:-23.6021776,lng:-46.6743207},{lat:-23.6020891,lng:-46.6745353},{lat:-23.6020301,lng:-46.6747713},{lat:-23.6019318,lng:-46.6749001},{lat:-23.6018532,lng:-46.6751039},{lat:-23.6017942,lng:-46.6752756},{lat:-23.6016959,lng:-46.6754901},{lat:-23.6015976,lng:-46.6756296},{lat:-23.6015091,lng:-46.6757476},{lat:-23.6014501,lng:-46.6758657},{lat:-23.6013223,lng:-46.6757476},{lat:-23.6012141,lng:-46.6756833},{lat:-23.601106,lng:-46.6756296},{lat:-23.6009782,lng:-46.6755223},{lat:-23.60087,lng:-46.675458},{lat:-23.6007717,lng:-46.6754258},{lat:-23.6006636,lng:-46.6753507},{lat:-23.6005358,lng:-46.6752756},{lat:-23.6003981,lng:-46.6751897},{lat:-23.6002113,lng:-46.6751254},{lat:-23.6000934,lng:-46.6750717},{lat:-23.5999262,lng:-46.6749644},{lat:-23.5997787,lng:-46.6749215},{lat:-23.5996706,lng:-46.674825},{lat:-23.5994543,lng:-46.6752434},{lat:-23.5993265,lng:-46.6756082},{lat:-23.5992085,lng:-46.6758549},{lat:-23.5990316,lng:-46.6761661},{lat:-23.5989332,lng:-46.6764021},{lat:-23.5988349,lng:-46.6765738},{lat:-23.5986481,lng:-46.6769922},{lat:-23.5985695,lng:-46.6772175},{lat:-23.5984712,lng:-46.6774857},{lat:-23.5981959,lng:-46.6779792},{lat:-23.5980877,lng:-46.6781402},{lat:-23.5979992,lng:-46.6784942},{lat:-23.5979206,lng:-46.6786659},{lat:-23.5977534,lng:-46.6789556},{lat:-23.5976355,lng:-46.679256},{lat:-23.5975273,lng:-46.6794384},{lat:-23.5974782,lng:-46.6795564},{lat:-23.597488,lng:-46.6797173},{lat:-23.5977534,lng:-46.6798246},{lat:-23.5981074,lng:-46.6799963},{lat:-23.5983138,lng:-46.6801357},{lat:-23.598422,lng:-46.6799748},{lat:-23.5985301,lng:-46.679728},{lat:-23.5987858,lng:-46.6792238},{lat:-23.5989627,lng:-46.6788483},{lat:-23.5990119,lng:-46.6786015},{lat:-23.5990905,lng:-46.6784084},{lat:-23.5991594,lng:-46.6782475},{lat:-23.5992872,lng:-46.6780972},{lat:-23.5993265,lng:-46.6779149},{lat:-23.5994248,lng:-46.6777754},{lat:-23.599474,lng:-46.6776145},{lat:-23.599592,lng:-46.6773999},{lat:-23.5996313,lng:-46.677314},{lat:-23.5996706,lng:-46.6772121},{lat:-23.5997198,lng:-46.6771048},{lat:-23.5997738,lng:-46.6770083},{lat:-23.5998132,lng:-46.6768903},{lat:-23.5998771,lng:-46.6767561},{lat:-23.5999016,lng:-46.6766757},{lat:-23.5998082,lng:-46.6766381},{lat:-23.5997247,lng:-46.6766381},{lat:-23.5996313,lng:-46.6766274},{lat:-23.5995625,lng:-46.6765845},{lat:-23.5994986,lng:-46.6765362},{lat:-23.5994936,lng:-46.6763967},{lat:-23.5995428,lng:-46.6763109},{lat:-23.5996214,lng:-46.6762626}]; | |
// PATH SIMPLIFICATION ALGORITHM | |
// Douglas Peucker path simplification algorithm | |
// This code is based on https://gist.github.com/adammiller/826148 | |
var Line = function( p1, p2 ) { | |
this.p1 = p1; | |
this.p2 = p2; | |
this.distanceToPoint = function( point ) { | |
// slope | |
var m = ( this.p2[0] - this.p1[0] ) / ( this.p2[1] - this.p1[1] ), | |
// y offset | |
b = this.p1[0] - ( m * this.p1[1] ), | |
d = []; | |
// distance to the linear equation | |
d.push( Math.abs( point[0] - ( m * point[1] ) - b ) / Math.sqrt( Math.pow( m, 2 ) + 1 ) ); | |
// distance to p1 | |
d.push( Math.sqrt( Math.pow( ( point[1] - this.p1[1] ), 2 ) + Math.pow( ( point[0] - this.p1[0] ), 2 ) ) ); | |
// distance to p2 | |
d.push( Math.sqrt( Math.pow( ( point[1] - this.p2[1] ), 2 ) + Math.pow( ( point[0] - this.p2[0] ), 2 ) ) ); | |
// return the smallest distance | |
return d.sort( function( a, b ) { | |
return ( a - b ); //causes an array to be sorted numerically and ascending | |
} )[0]; | |
}; | |
}; | |
var simplify = function(points, tolerance) { | |
var douglasPeucker = function( points, tolerance ) { | |
if ( points.length <= 2 ) { | |
return [points[0]]; | |
} | |
var returnPoints = [], | |
// make line from start to end | |
line = new Line( points[0], points[points.length - 1] ), | |
// find the largest distance from intermediate poitns to this line | |
maxDistance = 0, | |
maxDistanceIndex = 0, | |
p; | |
for( var i = 1; i <= points.length - 2; i++ ) { | |
var distance = line.distanceToPoint( points[ i ] ); | |
if( distance > maxDistance ) { | |
maxDistance = distance; | |
maxDistanceIndex = i; | |
} | |
} | |
// check if the max distance is greater than our tollerance allows | |
if ( maxDistance >= tolerance ) { | |
p = points[maxDistanceIndex]; | |
line.distanceToPoint( p, true ); | |
// include this point in the output | |
returnPoints = returnPoints.concat( douglasPeucker( points.slice( 0, maxDistanceIndex + 1 ), tolerance ) ); | |
// returnPoints.push( points[maxDistanceIndex] ); | |
returnPoints = returnPoints.concat( douglasPeucker( points.slice( maxDistanceIndex, points.length ), tolerance ) ); | |
} else { | |
// ditching this point | |
p = points[maxDistanceIndex]; | |
line.distanceToPoint( p, true ); | |
returnPoints = [points[0]]; | |
} | |
return returnPoints; | |
}; | |
var result = douglasPeucker( points, tolerance ); | |
// always have to push the very last point on so it doesn't get left off | |
result.push( points[points.length - 1 ] ); | |
return result; | |
}; | |
// Polyline distanceTo - calculates an approximate distance | |
// From http://stackoverflow.com/questions/31221088/how-to-calculate-the-distance-of-a-polyline-in-leaflet-like-geojson-io | |
L.Polyline = L.Polyline.extend({ | |
getDistance: function() { // in meters | |
var d = 0; | |
for (var i = 1; i < this._latlngs.length; i++) { | |
d += this._latlngs[i].distanceTo(this._latlngs[i - 1]); | |
} | |
return d; | |
} | |
}); | |
// GLOBAL VARS | |
// original points (ajax load this from a file or database) | |
var original = []; | |
// this will locally store points after editing and simplification | |
// after editing, the points array changes and can only be restored | |
// by reloading the data | |
var points = cloneCoords(original); | |
// this will locally store points during simplification | |
// it will allow you to slide in both directions while applying the algorithm | |
var simplified = cloneCoords(original); | |
var track; // this will be the L.polyline containing the points | |
$("#tolerance").prop("disabled", true); | |
// FUNCTIONS | |
// makes a deep copy of the array | |
function cloneCoords(sourceArray) { | |
var destArray = []; | |
for(var i = 0; i < sourceArray.length; i++) { | |
destArray.push([sourceArray[i][0], sourceArray[i][1]]); | |
} | |
return destArray; | |
} | |
// Converts [{lat,lng},...,{lat,lng}] to [[0][1],...,[0][1]] | |
function convertToArrayOfArray(sourceArray) { | |
var destArray = []; | |
for(var i = 0; i < sourceArray.length; i++) { | |
destArray.push([sourceArray[i].lat, sourceArray[i].lng]); | |
} | |
return destArray; | |
} | |
function formatNumber(number) { | |
return Math.round(number * 100)/100; | |
} | |
// These two functions allow you to express the epsilon factor | |
// (max distance to perpendicular line segment of point to remove) | |
// in metres. | |
// About this value see | |
// https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm | |
function degreesToMeters(degrees) { // this is approximate (spherical earth, average circumference, not considering altitude, etc.) | |
var earth = 40075000; // average circumference in metres at sea level | |
return degrees * earth / 360.0; | |
} | |
function metersToDegrees(meters) { // this is approximate (spherical earth, average circumference, not considering altitude, etc.) | |
var earth = 40075000; // average circumference in metres at sea level | |
return meters * 360.0 / earth; | |
} | |
// Apply simplification algorithm using specified tolerance & redraw shape | |
// Save points in memory | |
function simplifyPath() { | |
var toleranceInDegrees = metersToDegrees($('#tolerance').val()); // value from slider | |
simplified = simplify(points, toleranceInDegrees); | |
// change the array for the path & redraw | |
track.setLatLngs(simplified); | |
$("#val_tolerance").html(formatNumber(degreesToMeters(toleranceInDegrees))); | |
$("#val_current_distance").html(formatNumber(track.getDistance())); | |
$("#val_current_point_count").html(simplified.length); | |
} | |
// Load data and revert shape to original points | |
function loadFromDatabase() { | |
if(points.length == 0 || confirm("Reset all changes and revert to original path?")) { | |
// mock data - load your points from database into this variable | |
original = convertToArrayOfArray(trail_data); | |
points = cloneCoords(original); | |
simplified = cloneCoords(original); | |
if(!track) { | |
track = L.polyline(points) | |
.addTo(trailLayer); | |
} else { | |
track.setLatLngs(points); | |
} | |
$("#tolerance").val(0); | |
$("#tolerance").prop("disabled", false); | |
$("#val_tolerance").html("0"); | |
$("#val_original_distance").html(formatNumber(track.getDistance())); | |
$("#val_current_distance").html(formatNumber(track.getDistance())); | |
$("#val_orig_point_count").html(original.length); | |
$("#val_current_point_count").html(points.length); | |
} | |
} | |
function saveToDatabase() { | |
alert("Save path to database") | |
// insert here your ajax call to send the data to the server. | |
} | |
// MAP | |
map = new L.Map('map'); | |
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; | |
var osmAttrib = 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'; | |
var osm = new L.TileLayer(osmUrl, { | |
maxZoom: 22, | |
attribution: osmAttrib | |
}); | |
map.addLayer(osm); | |
// original trail for comparison | |
var trailPath_opti = L.polyline(trail_data, { | |
color: '#3EA9DE'}).addTo(map); | |
map.fitBounds(trailPath_opti.getBounds()); | |
// Add the editable layer (renamed mygroup to trailLayer) | |
var trailLayer = L.featureGroup().addTo(map); | |
var polyline_options = { | |
color: '#000' | |
}; | |
// Initialise the draw control and pass it the FeatureGroup of editable layers | |
var drawControl = new L.Control.Draw({ | |
draw: false, | |
edit: { | |
featureGroup: trailLayer | |
} | |
}).addTo(map); | |
// Editing events | |
// Using this to disable the slider | |
map.on('draw:editstart', function (e) { | |
console.log("started editing") | |
$("#tolerance").prop("disabled", true); | |
}); | |
// updates the points aray with the edited array | |
map.on('draw:edited', function (e) { | |
console.log("finished editing") | |
var editedPoints = []; | |
var coords = track._latlngs; | |
for (var i = 0; i < coords.length; i++) { | |
var obj = coords[i]; | |
editedPoints.push([obj.lat, obj.lng]); | |
} | |
console.log("edited points length", editedPoints.length) | |
points = cloneCoords(editedPoints); | |
$("#val_current_point_count").html(points.length); | |
$("#val_current_distance").html(formatNumber(track.getDistance())); | |
$("#tolerance").val(0); | |
$("#val_tolerance").html("0"); | |
}); | |
// Using this to enable the slider | |
map.on('draw:editstop', function (e) { | |
console.log("saved or cancelled") | |
$("#tolerance").prop("disabled", false); | |
}); | |
// HTML BINDINGS | |
$('#tolerance').on("input", simplifyPath); | |
$('#btn_load').on("click", loadFromDatabase); | |
$('#btn_save').on("click", saveToDatabase); | |
$('#slider_max').on("change", function() { | |
$('#tolerance').prop("max", $(this).val()); | |
}); | |
$('#slider_step').on("change", function() { | |
$('#tolerance').prop("step", $(this).val()); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment