Skip to content

Instantly share code, notes, and snippets.

@gabrielflorit
Last active May 15, 2019 17:50
Show Gist options
  • Save gabrielflorit/225b3802829cbebb0521f45216c34f18 to your computer and use it in GitHub Desktop.
Save gabrielflorit/225b3802829cbebb0521f45216c34f18 to your computer and use it in GitHub Desktop.
Equidistant map perimeter circles

Equidistant map perimeter circles circles

Made with blockup.

Display the source blob
Display the rendered blob
Raw
{"type":"Topology","arcs":[[[9769,0],[84,78],[46,-45],[-130,-33]],[[0,7510],[18,70],[153,-72],[147,-17],[46,21],[58,-58],[0,37],[27,10],[34,-81],[-46,-66],[-2,49],[-76,-152],[63,17],[-55,-6],[130,168],[18,-52],[-19,-3],[17,-52],[-15,-9],[11,-14],[-18,-59],[6,-13],[-12,-21],[-22,21],[15,29],[-21,-15],[5,-65],[-27,76],[-10,-30],[1,-33],[41,-20],[20,24],[15,36],[-5,8],[24,-16],[27,26],[-24,99],[47,114],[-39,67],[-19,-17],[27,-38],[-35,25],[-4,37],[36,12],[-42,50],[-35,6],[24,19],[30,-17],[-14,34],[25,7],[-25,56],[-18,-26],[-14,13],[-33,66],[14,19],[826,0],[893,-1],[844,0],[924,0],[925,0],[1026,1],[845,-1],[1,123],[44,-5],[32,-15],[39,-184],[183,-36],[11,-36],[123,40],[68,-4],[73,-28],[-18,-25],[58,-16],[20,-61],[25,42],[47,2],[22,-40],[91,-40],[-2,-21],[68,12],[87,53],[30,-50],[139,7],[56,-39],[93,8],[-314,-145],[-279,-245],[30,-34],[252,89],[24,-23],[-46,-93],[49,30],[68,-41],[147,82],[86,8],[100,50],[126,117],[112,35],[49,-25],[-55,-4],[-62,-60],[-61,-141],[80,67],[-32,-46],[46,31],[60,-9],[51,-35],[52,-87],[81,8],[37,-32],[34,2],[5,39],[21,-31],[96,65],[149,2],[118,31],[-6,-93],[88,1],[10,-22],[104,37],[7,-87],[-35,-26],[29,1],[57,-59],[25,8],[-12,29],[54,-6],[24,-32],[-12,-23],[-133,19],[-60,-15],[-64,39],[-21,-69],[-61,56],[-110,27],[-45,-44],[-132,-5],[-77,-107],[-23,22],[40,68],[-55,-9],[-41,-60],[-16,52],[-129,-219],[-7,-54],[-43,-9],[-37,-73],[-14,-49],[23,-12],[76,99],[51,8],[33,96],[59,39],[-111,-235],[-10,-114],[-47,-81],[3,-80],[-47,-139],[33,-148],[-14,-164],[69,-178],[46,-28],[146,71],[82,148],[24,194],[-74,222],[25,63],[-19,77],[56,92],[3,110],[38,16],[5,52],[59,14],[61,83],[-26,-115],[12,-27],[28,72],[-11,-77],[30,58],[5,108],[104,39],[-46,47],[39,54],[-14,17],[62,8],[62,-43],[56,-6],[27,-44],[163,-72],[26,-78],[-43,2],[42,-101],[-14,-119],[-47,-29],[-10,-61],[-67,-31],[-17,-67],[61,-51],[47,40],[10,54],[20,-5],[-14,16],[112,48],[62,-69],[52,-279],[-24,-115],[-38,-31],[14,48],[-43,-9],[-18,-80],[-46,-31],[-9,-65],[-73,-114],[119,-68],[23,23],[80,-65],[107,42],[62,-8],[103,86],[218,88],[268,165],[68,75],[-51,91],[1,59],[160,36],[139,-11],[47,-33],[135,10],[123,80],[42,3],[-14,104],[38,19],[-58,39],[16,51],[91,54],[209,194],[795,11],[14,72],[36,20],[34,-18],[28,32],[35,-37],[13,63],[37,-14],[-20,41],[106,120],[-8,96],[54,71],[14,89],[175,244],[42,-11],[-2,-54],[34,-25],[140,58],[113,-93],[-6,-437],[88,-35],[-14,-97],[33,-49],[14,21],[29,-10],[47,-110],[-71,-67],[-8,32],[-22,-4],[6,-21],[-47,-21],[15,-20],[-18,-16],[-41,32],[-64,-69],[-30,17],[-4,-47],[-46,5],[5,57],[-42,-9],[-9,-124],[-29,60],[12,20],[-34,15],[5,68],[-44,-32],[-18,-144],[-56,-37],[6,24],[-20,-11],[-10,19],[-17,-38],[-46,-5],[-29,-38],[-21,25],[-55,-34],[-57,-100],[-31,-12],[-60,-141],[9,-59],[42,-17],[-63,-30],[-31,-84],[28,9],[36,-32],[20,-41],[-17,-26],[68,-81],[35,-10],[57,28],[-20,74],[-34,10],[43,-8],[27,-73],[-12,-85],[-4,41],[-78,-12],[-136,-72],[66,43],[8,52],[-22,9],[-53,-70],[-55,-18],[-11,51],[0,-46],[-25,-7],[18,53],[18,18],[-21,-12],[-22,47],[-23,-132],[-242,-38],[-79,-2],[-4,17],[-45,-47],[-121,-47],[-32,-66],[68,48],[58,-13],[27,21],[108,3],[81,57],[-9,-23],[49,-30],[56,25],[-314,-142],[-160,-26],[-24,47],[-4,-32],[-47,-32],[65,-13],[-26,-218],[-174,-262],[-25,0],[19,69],[-60,10],[-87,86],[6,72],[-18,-11],[0,-60],[42,-66],[0,-60],[48,-83],[23,-3],[10,-110],[-38,-124],[-70,-84],[-33,-114],[-66,-113],[-16,55],[20,98],[63,126],[-54,-11],[16,66],[-30,1],[26,24],[-16,16],[12,31],[-24,-40],[-7,45],[-7,-50],[-51,34],[-18,53],[20,10],[-7,28],[57,-14],[-48,54],[-25,-16],[11,45],[24,-2],[-4,37],[-37,-28],[14,59],[34,-11],[4,29],[-20,-23],[-9,46],[23,54],[39,11],[7,60],[-29,-6],[8,-29],[-37,-30],[-6,31],[-7,-48],[-17,30],[3,-43],[-23,-20],[-32,21],[43,-80],[-37,-77],[54,-233],[-27,40],[-8,-19],[-26,36],[-47,7],[-7,35],[-3,-29],[-18,11],[-22,49],[-53,-20],[-3,42],[35,38],[-32,1],[-16,-80],[18,-17],[45,22],[18,-59],[79,-21],[86,-83],[-23,-74],[13,-13],[-18,-1],[-34,10],[-95,108],[88,-116],[55,-18],[-14,-13],[22,-12],[-3,-55],[-31,29],[15,-40],[-35,-13],[48,-34],[-3,-40],[-28,-10],[-51,80],[-68,3],[48,-27],[12,17],[5,-49],[44,-52],[35,1],[4,26],[69,-14],[105,-364],[-103,238],[44,-145],[-29,55],[4,-25],[-64,42],[28,-49],[-48,14],[13,-29],[-53,31],[33,-32],[-63,-27],[-32,44],[6,42],[-13,-42],[14,-64],[143,15],[7,-109],[19,98],[22,6],[31,-90],[-99,-117],[-76,14],[-23,44],[26,15],[-37,-15],[12,-39],[-101,41],[127,-76],[-30,-66],[-46,-33],[-42,30],[2,-17],[49,-27],[68,49],[15,-32],[25,10],[-54,-103],[-18,33],[-16,-23],[34,-20],[111,130],[-114,-150],[-32,33],[-71,-7],[-129,-80],[-62,-81],[-32,-102],[-94,19],[-98,-51],[-62,-82],[-23,-99],[-40,-53],[-45,4],[-4,-36],[-34,-32],[-45,-8],[9,-31],[-26,-25],[-108,-34],[2,-57],[-40,-20],[-26,16],[19,-28],[-53,-53],[14,-16],[-24,-33],[-27,-7],[0,-34],[-31,-16],[16,-30],[-29,-24],[19,-10],[-26,-98],[-46,-74],[20,-6],[-10,-145],[65,-301],[145,-349],[-18,-39],[9,-77],[122,-413],[-22,-326],[-7,-34],[-9,25],[-24,-42],[-15,-104],[44,64],[-42,-106],[-48,-64],[-22,-14],[39,44],[7,52],[-140,-29],[-48,181],[-74,66],[-17,-13],[-41,167],[-43,54],[-11,-21],[-17,63],[20,-5],[7,91],[-25,-11],[6,-40],[-27,-22],[-109,260],[21,-5],[57,114],[-17,15],[1,-34],[-19,9],[0,37],[-31,20],[-6,-29],[30,-39],[-33,-64],[-27,79],[-2,113],[17,-51],[27,136],[-5,134],[-27,77],[-56,-5],[-6,39],[-73,84],[-3,48],[-61,79],[-73,57],[-58,2],[-25,-30],[4,-36],[-37,7],[-86,-62],[-4,20],[-49,-22],[25,-30],[73,45],[-81,-56],[-70,23],[-14,58],[17,-48],[6,45],[-62,71],[-162,98],[-103,9],[-291,-54],[62,17],[-34,42],[-3,73],[-20,15],[-29,-116],[-179,23],[-84,-28],[-10,22],[-29,-63],[-90,-54],[45,-45],[40,68],[25,-7],[-13,-21],[14,-25],[35,19],[-24,-27],[19,-3],[-33,-12],[25,-26],[-26,10],[-11,-42],[-20,22],[8,-34],[-45,-1],[40,-73],[73,-13],[18,-46],[24,-7],[-24,-8],[16,-6],[-23,-46],[-25,29],[-38,-48],[28,85],[-22,-24],[-56,53],[-47,9],[-86,-74],[-19,58],[-22,-11],[-10,37],[-96,-93],[-21,40],[-78,27],[15,33],[26,-38],[-2,28],[-24,31],[-22,-14],[-5,38],[-24,-13],[-21,51],[-22,1],[6,32],[-59,-7],[12,37],[-84,-24],[21,-45],[20,1],[-60,-26],[-204,75],[-67,0],[-142,-35],[-151,-95],[58,58],[-63,-4],[20,52],[-14,28],[-31,-39],[-17,13],[-12,-46],[25,-19],[4,-60],[-61,-38],[-1,-24],[81,76],[20,-7],[-151,-148],[-190,-119],[-114,-104],[-112,-181],[-38,-198],[48,-285],[-26,148],[-20,4],[15,8],[-22,99],[9,147],[63,178],[151,160],[-56,-34],[-23,32],[-7,-59],[-31,-32],[-23,20],[-40,-31],[43,6],[-37,-90],[-75,14],[59,-55],[-34,-116],[-29,-17],[7,28],[-31,-36],[49,4],[-5,-209],[38,-107],[-3,-53],[32,-14],[1,-29],[-63,-41],[-52,57],[-124,11],[-58,52],[-50,6],[-31,42],[-63,9],[-42,142],[-41,57],[-15,173],[-75,63],[-20,69],[-81,93],[-88,263],[-88,114],[-44,20],[0,33],[-12,-15],[-25,57],[-159,11],[-47,28],[-15,-36],[-66,-9],[-47,-124],[4,-39],[-29,-15],[-28,-62],[-71,18],[-139,89],[-107,101],[-95,308],[-106,79],[-128,162],[-57,33],[-56,95],[-400,6],[0,-144],[-652,0],[-851,370],[21,71],[-548,-59],[-78,243],[-151,145],[-63,-3],[-25,91],[-65,-9],[-74,32],[-98,99],[-207,11],[-38,38],[-2,183],[-48,21],[-6,71],[-91,78],[-50,103],[-88,97],[-20,88],[37,33],[-11,79],[-55,7],[-68,77],[-26,108],[9,87],[21,-6],[2,-59],[76,-47],[-88,161],[36,35],[-50,12],[12,-73],[-21,-20],[-74,63],[-38,-7],[10,87],[-170,207],[-29,291],[-116,136],[-11,56],[62,156],[17,163],[-44,109],[12,64],[-35,42],[-10,163],[-34,68],[93,355],[46,543],[-19,180],[39,-23],[70,35],[-122,1],[3,116],[24,-82],[1,83],[29,23],[-59,10],[-11,52],[15,-14],[48,28],[-59,30],[-13,-37],[-56,258],[-47,49],[-23,89]]],"transform":{"scale":[0.004393337667274939,0.003142808130699088],"translate":[-124.731746,24.568745]},"objects":{"boundary":{"type":"GeometryCollection","geometries":[{"type":"MultiLineString","arcs":[[0],[1]],"properties":{"TYPE":0}}]}}}
.buttons{margin:0 auto;text-align:center}.map svg{display:block;margin:0 auto}.map svg circle{fill:#8f092a;fill-opacity:.25;stroke:#8f092a}
var margin={top:10,right:10,bottom:10,left:10};d3.json("./boundary.topojson",function(t){var e=topojson.feature(t,t.objects.boundary),n=(d3.geoBounds(e),d3.geoCentroid(e),d3.geoAlbers()),r=d3.geoPath().projection(n),a=r.bounds(e),o=(a[1][0]-a[0][0])/(a[1][1]-a[0][1]),i=460,c=i*o,u=c-margin.left-margin.right,l=i-margin.top-margin.bottom,d=d3.select(".map svg").attrs({width:c,height:i}).append("g").attr("transform","translate("+margin.left+", "+margin.top+")");n.fitSize([u,l],e);var s=_(e.features).map("geometry").flatten().map("coordinates").flatten().sortBy("length").map(function(t){return turf.lineString(t)}).value(),f=_(s).map(function(t){return turf.lineDistance(t)}).sum(),m=1e3,g=m,p=_(s).map(function(t){var e=turf.lineDistance(t),n=Math.ceil(e*m/f),r=Math.min(g,n);g-=r;var a=e/r,o=d3.range(r).map(function(e){return turf.along(t,e*a)});return o}).flatten().map(function(t){return n(t.geometry.coordinates)}).value(),v=function(){var t=d.selectAll("circle").data(p);t.enter().append("circle").attrs({cx:u/2,cy:l/2,r:0}).transition("enter").duration(1e3).delay(function(t,e){return 10*e}).attrs({cx:function(t){return t[0]},cy:function(t){return t[1]},r:1})},y=function(){var t=d.selectAll("circle").data(p);t.transition("exit").duration(250).delay(function(t,e){return 2*e}).attrs({cx:u/2,cy:l/2,r:0}).remove()};v(),document.querySelector("button.enter").addEventListener("click",v),document.querySelector("button.exit").addEventListener("click",y)});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjcmlwdC5qcyJdLCJuYW1lcyI6WyJjb25zdCIsIm1hcmdpbiIsInRvcCIsInJpZ2h0IiwiYm90dG9tIiwibGVmdCIsImQzIiwianNvbiIsImZlYXR1cmUiLCJ0b3BvanNvbiIsIm9iamVjdHMiLCJib3VuZGFyeSIsInByb2plY3Rpb24iLCJnZW9Cb3VuZHMiLCJnZW9DZW50cm9pZCIsImdlb0FsYmVycyIsInBhdGgiLCJnZW9QYXRoIiwiYiIsImJvdW5kcyIsImFzcGVjdCIsIm91dGVySGVpZ2h0Iiwib3V0ZXJXaWR0aCIsIndpZHRoIiwiaGVpZ2h0IiwiZyIsInNlbGVjdCIsImF0dHJzIiwiYXBwZW5kIiwiYXR0ciIsImZpdFNpemUiLCJsaW5lU3RyaW5ncyIsIl8iLCJmZWF0dXJlcyIsIm1hcCIsImZsYXR0ZW4iLCJzb3J0QnkiLCJkIiwidHVyZiIsImxpbmVTdHJpbmciLCJ2YWx1ZSIsInRvdGFsTGVuZ3RoIiwibGluZURpc3RhbmNlIiwic3VtIiwicG9pbnRzQ291bnQiLCJwb2ludHNSZW1haW5pbmciLCJwb2ludHMiLCJsaW5lIiwibGluZUxlbmd0aCIsInVwcGVyQ291bnQiLCJNYXRoIiwiY2VpbCIsImxpbmVQb2ludHNDb3VudCIsIm1pbiIsInN0ZXAiLCJsaW5lUG9pbnRzIiwicmFuZ2UiLCJhbG9uZyIsImdlb21ldHJ5IiwiY29vcmRpbmF0ZXMiLCJlbnRlciIsImNpcmNsZXMiLCJzZWxlY3RBbGwiLCJkYXRhIiwiY3giLCJjeSIsInIiLCJ0cmFuc2l0aW9uIiwiZHVyYXRpb24iLCJkZWxheSIsImkiLCJleGl0IiwicmVtb3ZlIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwiYWRkRXZlbnRMaXN0ZW5lciJdLCJtYXBwaW5ncyI6IkFBQ0FBLEdBQU1DLFNBQVdDLElBQU8sR0FBRUMsTUFBUyxHQUFFQyxPQUFVLEdBQUVDLEtBQVEsR0FHekRDLElBQUdDLEtBQUssc0JBQXVCLFNBQUFBLEdBRTlCUCxHQUFNUSxHQUFVQyxTQUFTRCxRQUFRRCxFQUFNQSxFQUFLRyxRQUFRQyxVQVc5Q0MsR0FSV04sR0FBQ08sVUFBVUwsR0FDVEYsR0FBQ1EsWUFBWU4sR0FPWEYsR0FBQ1MsYUFHaEJDLEVBQVNWLEdBQUNXLFVBQVVMLFdBQVdBLEdBRzlCTSxFQUFHRixFQUFLRyxPQUFPWCxHQUdoQlksR0FBWUYsRUFBRSxHQUFHLEdBQUtBLEVBQUUsR0FBRyxLQUFPQSxFQUFFLEdBQUcsR0FBS0EsRUFBRSxHQUFHLElBRWpERyxFQUFjLElBQ2RDLEVBQWFELEVBQWNELEVBRTNCRyxFQUFRRCxFQUFhckIsT0FBT0ksS0FBT0osT0FBT0UsTUFDMUNxQixFQUFTSCxFQUFjcEIsT0FBT0MsSUFBTUQsT0FBT0csT0FHMUNxQixFQUFLbkIsR0FBQ29CLE9BQU8sWUFDakJDLE9BQVFKLE1BQU9ELEVBQVlFLE9BQVFILElBQ3BDTyxPQUFPLEtBQ05DLEtBQUssWUFBYSxhQUFXNUIsT0FBUyxLQUFBLEtBQUlBLE9BQUcsSUFBQSxJQUdoRFcsR0FBV2tCLFNBQVNQLEVBQU9DLEdBQVNoQixFQUdwQ1IsSUFBTStCLEdBQWdCQyxFQUFBeEIsRUFBUXlCLFVBQzVCQyxJQUFJLFlBQ0pDLFVBQ0FELElBQUksZUFDSkMsVUFDQUMsT0FBTyxVQUNQRixJQUFJLFNBQUFHLEdBQUEsTUFBQUMsTUFBQUMsV0FBRUYsS0FDTkcsUUFHSUMsRUFBZ0JULEVBQUFELEdBQ3BCRyxJQUFJLFNBQUFHLEdBQUEsTUFBQUMsTUFBQUksYUFBS0wsS0FDVE0sTUFHSUMsRUFBYyxJQUNoQkMsRUFBa0JELEVBRWhCRSxFQUFXZCxFQUFBRCxHQUNmRyxJQUFJLFNBQUFhLEdBS0ovQyxHQUFNZ0QsR0FBYVYsS0FBS0ksYUFBYUssR0FHL0JFLEVBQWFDLEtBQUtDLEtBQUtILEVBQWFKLEVBQWNILEdBR2xEVyxFQUFrQkYsS0FBS0csSUFBSVIsRUFBaUJJLEVBR2xESixJQUFtQk8sQ0FJbkJwRCxJQUFNc0QsR0FBT04sRUFBYUksRUFFcEJHLEVBQWVqRCxHQUFDa0QsTUFBTUosR0FDMUJsQixJQUFJLFNBQUFHLEdBQUEsTUFBQUMsTUFBQW1CLE1BQUVWLEVBQUdWLEVBQUlpQixJQUVmLE9BQU9DLEtBR1BwQixVQUNBRCxJQUFJLFNBQUFHLEdBQUEsTUFBQXpCLEdBQUV5QixFQUFBcUIsU0FBR0MsZUFDVG5CLFFBR0lvQixFQUFRLFdBR2I1RCxHQUFNNkQsR0FBWXBDLEVBQUFxQyxVQUFVLFVBQ3pCQyxLQUFLakIsRUFHUmUsR0FBUUQsUUFBUWhDLE9BQU8sVUFDcEJELE9BQ0FxQyxHQUFJekMsRUFBTSxFQUNWMEMsR0FBSXpDLEVBQU8sRUFDWDBDLEVBQUcsSUFFSkMsV0FBVyxTQUNWQyxTQUFTLEtBQ1RDLE1BQU0sU0FBQWhDLEVBQUFpQyxHQUFBLE1BQUssSUFBSkEsSUFDUDNDLE9BQ0FxQyxHQUFJLFNBQUEzQixHQUFBLE1BQUFBLEdBQUEsSUFDSjRCLEdBQUksU0FBQTVCLEdBQUEsTUFBQUEsR0FBQSxJQUNKNkIsRUFBRyxLQU1ESyxFQUFPLFdBR1p2RSxHQUFNNkQsR0FBWXBDLEVBQUFxQyxVQUFVLFVBQ3pCQyxLQUFLakIsRUFHUmUsR0FDRU0sV0FBVyxRQUNWQyxTQUFTLEtBQ1RDLE1BQU0sU0FBQWhDLEVBQUFpQyxHQUFBLE1BQUssR0FBSkEsSUFDUDNDLE9BQ0FxQyxHQUFJekMsRUFBTSxFQUNWMEMsR0FBSXpDLEVBQU8sRUFDWDBDLEVBQUcsSUFFSk0sU0FLSFosS0FHQWEsU0FBU0MsY0FBYyxnQkFBZ0JDLGlCQUFpQixRQUFTZixHQUNqRWEsU0FBU0MsY0FBYyxlQUFlQyxpQkFBaUIsUUFBU0oiLCJmaWxlIjoic2NyaXB0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gU2V0dXAgY2hhcnQgZGltZW5zaW9ucy5cbmNvbnN0IG1hcmdpbiA9IHsgdG9wOiAxMCwgcmlnaHQ6IDEwLCBib3R0b206IDEwLCBsZWZ0OiAxMCB9XG5cbi8vIEdldCBHZW9KU09OLlxuZDMuanNvbignLi9ib3VuZGFyeS50b3BvanNvbicsIGpzb24gPT4ge1xuXG5cdGNvbnN0IGZlYXR1cmUgPSB0b3BvanNvbi5mZWF0dXJlKGpzb24sIGpzb24ub2JqZWN0cy5ib3VuZGFyeSlcblxuXHQvLyBHZXQgZmVhdHVyZSdzIGJvdW5kcyBhbmQgY2VudHJvaWQuXG5cdGNvbnN0IGJvdW5kcyA9IGQzLmdlb0JvdW5kcyhmZWF0dXJlKVxuXHRjb25zdCBjZW50cm9pZCA9IGQzLmdlb0NlbnRyb2lkKGZlYXR1cmUpXG5cblx0Ly8gY29uc3QgcHJvamVjdGlvbiA9IGQzLmdlb0NvbmljQ29uZm9ybWFsKClcblx0Ly8gXHQucGFyYWxsZWxzKFtib3VuZHNbMF1bMV0sIGJvdW5kc1sxXVsxXV0pXG5cdC8vIFx0LnJvdGF0ZShbLWNlbnRyb2lkWzBdLCAwXSlcblx0Ly8gXHQuY2VudGVyKFswLCAtY2VudHJvaWRbMV1dKVxuXG5cdGNvbnN0IHByb2plY3Rpb24gPSBkMy5nZW9BbGJlcnMoKVxuXG5cdC8vIEdldCB0aGUgcGF0aC5cblx0Y29uc3QgcGF0aCA9IGQzLmdlb1BhdGgoKS5wcm9qZWN0aW9uKHByb2plY3Rpb24pXG5cblx0Ly8gR2V0IHRoZSBwYXRoJ3MgYm91bmRzIChpLmUuLCBpbiBwaXhlbHMpLlxuXHRjb25zdCBiID0gcGF0aC5ib3VuZHMoZmVhdHVyZSlcblxuXHQvLyBHZXQgYXNwZWN0IHJhdGlvLlxuXHRjb25zdCBhc3BlY3QgPSAoYlsxXVswXSAtIGJbMF1bMF0pIC8gKGJbMV1bMV0gLSBiWzBdWzFdKVxuXG5cdGNvbnN0IG91dGVySGVpZ2h0ID0gNDYwXG5cdGNvbnN0IG91dGVyV2lkdGggPSBvdXRlckhlaWdodCAqIGFzcGVjdFxuXG5cdGNvbnN0IHdpZHRoID0gb3V0ZXJXaWR0aCAtIG1hcmdpbi5sZWZ0IC0gbWFyZ2luLnJpZ2h0XG5cdGNvbnN0IGhlaWdodCA9IG91dGVySGVpZ2h0IC0gbWFyZ2luLnRvcCAtIG1hcmdpbi5ib3R0b21cblxuXHQvLyBQcmVwYXJlIHN2Zy5cblx0Y29uc3QgZyA9IGQzLnNlbGVjdCgnLm1hcCBzdmcnKVxuXHRcdFx0LmF0dHJzKHsgd2lkdGg6IG91dGVyV2lkdGgsIGhlaWdodDogb3V0ZXJIZWlnaHQgfSlcblx0XHQuYXBwZW5kKCdnJylcblx0XHRcdC5hdHRyKCd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlKCR7bWFyZ2luLmxlZnR9LCAke21hcmdpbi50b3B9KWApXG5cblx0Ly8gRml0IHRoZSBmZWF0dXJlIHRvIHRoZSBjb250YWluZXIncyB3aWR0aC5cblx0cHJvamVjdGlvbi5maXRTaXplKFt3aWR0aCwgaGVpZ2h0XSwgZmVhdHVyZSlcblxuXHQvLyBHZXQgdGhlIGluZGl2aWR1YWwgbGluZSBzdHJpbmdzLlxuXHRjb25zdCBsaW5lU3RyaW5ncyA9IF8oZmVhdHVyZS5mZWF0dXJlcylcblx0XHQubWFwKCdnZW9tZXRyeScpXG5cdFx0LmZsYXR0ZW4oKVxuXHRcdC5tYXAoJ2Nvb3JkaW5hdGVzJylcblx0XHQuZmxhdHRlbigpXG5cdFx0LnNvcnRCeSgnbGVuZ3RoJylcblx0XHQubWFwKGQgPT4gdHVyZi5saW5lU3RyaW5nKGQpKVxuXHRcdC52YWx1ZSgpXG5cblx0Ly8gQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGxpbmUgc3RyaW5nIGxlbmd0aC5cblx0Y29uc3QgdG90YWxMZW5ndGggPSBfKGxpbmVTdHJpbmdzKVxuXHRcdC5tYXAoZCA9PiB0dXJmLmxpbmVEaXN0YW5jZShkKSlcblx0XHQuc3VtKClcblxuXHQvLyBEZXNpcmVkIG51bWJlciBvZiB0b3RhbCBwb2ludHMuXG5cdGNvbnN0IHBvaW50c0NvdW50ID0gMTAwMFxuXHRsZXQgcG9pbnRzUmVtYWluaW5nID0gcG9pbnRzQ291bnRcblxuXHRjb25zdCBwb2ludHMgPSBfKGxpbmVTdHJpbmdzKVxuXHRcdC5tYXAobGluZSA9PiB7XG5cblx0XHRcdC8vIEhvdyBtYW55IHBvaW50cyB3aWxsIHRoaXMgbGluZSBnZXQ/XG5cblx0XHRcdC8vIEZpcnN0LCBjYWxjdWxhdGUgdGhpcyBsaW5lJ3MgbGVuZ3RoLlxuXHRcdFx0Y29uc3QgbGluZUxlbmd0aCA9IHR1cmYubGluZURpc3RhbmNlKGxpbmUpXG5cblx0XHRcdC8vIE5leHQsIGdldCB0aGlzIGxpbmUncyBwb2ludHMgcHJvcG9ydGlvbiwgcm91bmRlZCB1cC5cblx0XHRcdGNvbnN0IHVwcGVyQ291bnQgPSBNYXRoLmNlaWwobGluZUxlbmd0aCAqIHBvaW50c0NvdW50IC8gdG90YWxMZW5ndGgpXG5cblx0XHRcdC8vIERvbid0IGdldCBtb3JlIHBvaW50cyB0aGF0IGFyZSBhdmFpbGFibGUuXG5cdFx0XHRjb25zdCBsaW5lUG9pbnRzQ291bnQgPSBNYXRoLm1pbihwb2ludHNSZW1haW5pbmcsIHVwcGVyQ291bnQpXG5cblx0XHRcdC8vIE1ha2Ugc3VyZSB0byB1cGRhdGUgcG9pbnRzIHJlbWFpbmluZy5cblx0XHRcdHBvaW50c1JlbWFpbmluZyAtPSBsaW5lUG9pbnRzQ291bnRcblxuXHRcdFx0Ly8gTm93IHRoYXQgd2Uga25vdyBob3cgbWFueSBwb2ludHMgdGhpcyBsaW5lIHdpbGwgZ2V0LFxuXHRcdFx0Ly8gY2FsY3VsYXRlIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHBvaW50cyAtIHRoZSBzdGVwOlxuXHRcdFx0Y29uc3Qgc3RlcCA9IGxpbmVMZW5ndGggLyBsaW5lUG9pbnRzQ291bnRcblxuXHRcdFx0Y29uc3QgbGluZVBvaW50cyA9IGQzLnJhbmdlKGxpbmVQb2ludHNDb3VudClcblx0XHRcdFx0Lm1hcChkID0+IHR1cmYuYWxvbmcobGluZSwgZCAqIHN0ZXApKVxuXG5cdFx0XHRyZXR1cm4gbGluZVBvaW50c1xuXG5cdFx0fSlcblx0XHQuZmxhdHRlbigpXG5cdFx0Lm1hcChkID0+IHByb2plY3Rpb24oZC5nZW9tZXRyeS5jb29yZGluYXRlcykpXG5cdFx0LnZhbHVlKClcblxuXHQvLyBUaGlzIGZ1bmN0aW9uIGFkZHMgdGhlIGNpcmNsZXMuXG5cdGNvbnN0IGVudGVyID0gKCkgPT4ge1xuXG5cdFx0Ly8gSk9JTiBuZXcgZGF0YSB3aXRoIG9sZCBlbGVtZW50cy5cblx0XHRjb25zdCBjaXJjbGVzID0gZy5zZWxlY3RBbGwoJ2NpcmNsZScpXG5cdFx0XHRcdC5kYXRhKHBvaW50cylcblxuXHRcdC8vIEVOVEVSIG5ldyBlbGVtZW50cyBwcmVzZW50IGluIG5ldyBkYXRhLlxuXHRcdGNpcmNsZXMuZW50ZXIoKS5hcHBlbmQoJ2NpcmNsZScpXG5cdFx0XHRcdC5hdHRycyh7XG5cdFx0XHRcdFx0Y3g6IHdpZHRoLzIsXG5cdFx0XHRcdFx0Y3k6IGhlaWdodC8yLFxuXHRcdFx0XHRcdHI6IDAsXG5cdFx0XHRcdH0pXG5cdFx0XHQudHJhbnNpdGlvbignZW50ZXInKVxuXHRcdFx0XHQuZHVyYXRpb24oMTAwMClcblx0XHRcdFx0LmRlbGF5KChkLCBpKSA9PiBpICogMTApXG5cdFx0XHRcdC5hdHRycyh7XG5cdFx0XHRcdFx0Y3g6IGQgPT4gZFswXSxcblx0XHRcdFx0XHRjeTogZCA9PiBkWzFdLFxuXHRcdFx0XHRcdHI6IDEsXG5cdFx0XHRcdH0pXG5cblx0fVxuXG5cdC8vIFRoaXMgZnVuY3Rpb24gcmVtb3ZlcyB0aGUgY2lyY2xlcy5cblx0Y29uc3QgZXhpdCA9ICgpID0+IHtcblxuXHRcdC8vIEpPSU4gbmV3IGRhdGEgd2l0aCBvbGQgZWxlbWVudHMuXG5cdFx0Y29uc3QgY2lyY2xlcyA9IGcuc2VsZWN0QWxsKCdjaXJjbGUnKVxuXHRcdFx0XHQuZGF0YShwb2ludHMpXG5cblx0XHQvLyBVUERBVEUgb2xkIGVsZW1lbnRzIHByZXNlbnQgaW4gbmV3IGRhdGEuXG5cdFx0Y2lyY2xlc1xuXHRcdFx0LnRyYW5zaXRpb24oJ2V4aXQnKVxuXHRcdFx0XHQuZHVyYXRpb24oMjUwKVxuXHRcdFx0XHQuZGVsYXkoKGQsIGkpID0+IGkgKiAyKVxuXHRcdFx0XHQuYXR0cnMoe1xuXHRcdFx0XHRcdGN4OiB3aWR0aC8yLFxuXHRcdFx0XHRcdGN5OiBoZWlnaHQvMixcblx0XHRcdFx0XHRyOiAwLFxuXHRcdFx0XHR9KVxuXHRcdFx0LnJlbW92ZSgpXG5cblx0fVxuXG5cdC8vIEZpcmUgdGhlIGVudGVyIGZ1bmN0aW9uIG9uIHBhZ2UgbG9hZC5cblx0ZW50ZXIoKVxuXG5cdC8vIExpc3RlbiB0byBidXR0b24gY2xpY2tzLlxuXHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdidXR0b24uZW50ZXInKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGVudGVyKVxuXHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdidXR0b24uZXhpdCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXhpdClcblxufSlcbiJdfQ==
<!DOCTYPE html>
<title>Equidistant outline circles</title>
<link href='dist.css' rel='stylesheet' />
<body>
<div class='map'>
<svg></svg>
</div>
<div class='buttons'>
<button class='enter'>Enter</button>
<button class='exit'>Exit</button>
</div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-selection-multi.v1.min.js'></script>
<script src='https://d3js.org/topojson.v2.min.js'></script>
<script src='https://npmcdn.com/@turf/turf@3.10.2/turf.min.js'></script>
<script src='https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js'></script>
<script src='dist.js'></script>
</body>
all:
rm boundary.topojson;
mapshaper -i ~/Downloads/cb_2015_us_nation_5m/cb_2015_us_nation_5m.shp name=boundary -clip bbox=-126,23,-65,50 -filter-slivers min-area=700000000 -lines -simplify dp 5% -o format=topojson boundary.topojson;
// Setup chart dimensions.
const margin = { top: 10, right: 10, bottom: 10, left: 10 }
// Get GeoJSON.
d3.json('./boundary.topojson', json => {
const feature = topojson.feature(json, json.objects.boundary)
// Get feature's bounds and centroid.
const bounds = d3.geoBounds(feature)
const centroid = d3.geoCentroid(feature)
// const projection = d3.geoConicConformal()
// .parallels([bounds[0][1], bounds[1][1]])
// .rotate([-centroid[0], 0])
// .center([0, -centroid[1]])
const projection = d3.geoAlbers()
// Get the path.
const path = d3.geoPath().projection(projection)
// Get the path's bounds (i.e., in pixels).
const b = path.bounds(feature)
// Get aspect ratio.
const aspect = (b[1][0] - b[0][0]) / (b[1][1] - b[0][1])
const outerHeight = 460
const outerWidth = outerHeight * aspect
const width = outerWidth - margin.left - margin.right
const height = outerHeight - margin.top - margin.bottom
// Prepare svg.
const g = d3.select('.map svg')
.attrs({ width: outerWidth, height: outerHeight })
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
// Fit the feature to the container's width.
projection.fitSize([width, height], feature)
// Get the individual line strings.
const lineStrings = _(feature.features)
.map('geometry')
.flatten()
.map('coordinates')
.flatten()
.sortBy('length')
.map(d => turf.lineString(d))
.value()
// Calculate the overall line string length.
const totalLength = _(lineStrings)
.map(d => turf.lineDistance(d))
.sum()
// Desired number of total points.
const pointsCount = 1000
let pointsRemaining = pointsCount
const points = _(lineStrings)
.map(line => {
// How many points will this line get?
// First, calculate this line's length.
const lineLength = turf.lineDistance(line)
// Next, get this line's points proportion, rounded up.
const upperCount = Math.ceil(lineLength * pointsCount / totalLength)
// Don't get more points that are available.
const linePointsCount = Math.min(pointsRemaining, upperCount)
// Make sure to update points remaining.
pointsRemaining -= linePointsCount
// Now that we know how many points this line will get,
// calculate the distance between points - the step:
const step = lineLength / linePointsCount
const linePoints = d3.range(linePointsCount)
.map(d => turf.along(line, d * step))
return linePoints
})
.flatten()
.map(d => projection(d.geometry.coordinates))
.value()
// This function adds the circles.
const enter = () => {
// JOIN new data with old elements.
const circles = g.selectAll('circle')
.data(points)
// ENTER new elements present in new data.
circles.enter().append('circle')
.attrs({
cx: width/2,
cy: height/2,
r: 0,
})
.transition('enter')
.duration(1000)
.delay((d, i) => i * 10)
.attrs({
cx: d => d[0],
cy: d => d[1],
r: 1,
})
}
// This function removes the circles.
const exit = () => {
// JOIN new data with old elements.
const circles = g.selectAll('circle')
.data(points)
// UPDATE old elements present in new data.
circles
.transition('exit')
.duration(250)
.delay((d, i) => i * 2)
.attrs({
cx: width/2,
cy: height/2,
r: 0,
})
.remove()
}
// Fire the enter function on page load.
enter()
// Listen to button clicks.
document.querySelector('button.enter').addEventListener('click', enter)
document.querySelector('button.exit').addEventListener('click', exit)
})
$red = #8f092a
.buttons
margin 0 auto
text-align center
.map
svg
display block
margin 0 auto
circle
fill $red
fill-opacity 0.25
stroke $red
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment