New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

geojson-vt

Package Overview
Dependencies
Maintainers
2
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

geojson-vt - npm Package Compare versions

Comparing version 2.4.0 to 3.0.0

.nyc_output/4121e72ec4e7f9ddcea0716e6a482ab6.json

2

geojson-vt.js

@@ -1,1 +0,1 @@

!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.geojsonvt=e()}}(function(){return function e(t,n,r){function o(s,u){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!u&&l)return l(s,!0);if(i)return i(s,!0);var a=new Error("Cannot find module '"+s+"'");throw a.code="MODULE_NOT_FOUND",a}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(e){var n=t[s][1][e];return o(n?n:e)},f,f.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(e,t,n){"use strict";function r(e,t,n,r,s,l,a,f){if(n/=t,r/=t,a>=n&&r>=f)return e;if(a>r||n>f)return null;for(var h=[],p=0;p<e.length;p++){var m,c,d=e[p],g=d.geometry,v=d.type;if(m=d.min[s],c=d.max[s],m>=n&&r>=c)h.push(d);else if(!(m>r||n>c)){var x=1===v?o(g,n,r,s):i(g,n,r,s,l,3===v);x.length&&h.push(u(d.tags,v,x,d.id))}}return h.length?h:null}function o(e,t,n,r){for(var o=[],i=0;i<e.length;i++){var s=e[i],u=s[r];u>=t&&n>=u&&o.push(s)}return o}function i(e,t,n,r,o,i){for(var u=[],l=0;l<e.length;l++){var a,f,h,p=0,m=0,c=null,d=e[l],g=d.area,v=d.dist,x=d.outer,y=d.length,M=[];for(f=0;y-1>f;f++)a=c||d[f],c=d[f+1],p=m||a[r],m=c[r],t>p?m>n?(M.push(o(a,c,t),o(a,c,n)),i||(M=s(u,M,g,v,x))):m>=t&&M.push(o(a,c,t)):p>n?t>m?(M.push(o(a,c,n),o(a,c,t)),i||(M=s(u,M,g,v,x))):n>=m&&M.push(o(a,c,n)):(M.push(a),t>m?(M.push(o(a,c,t)),i||(M=s(u,M,g,v,x))):m>n&&(M.push(o(a,c,n)),i||(M=s(u,M,g,v,x))));a=d[y-1],p=a[r],p>=t&&n>=p&&M.push(a),h=M[M.length-1],i&&h&&(M[0][0]!==h[0]||M[0][1]!==h[1])&&M.push(M[0]),s(u,M,g,v,x)}return u}function s(e,t,n,r,o){return t.length&&(t.area=n,t.dist=r,void 0!==o&&(t.outer=o),e.push(t)),[]}t.exports=r;var u=e("./feature")},{"./feature":3}],2:[function(e,t,n){"use strict";function r(e,t){var n=[];if("FeatureCollection"===e.type)for(var r=0;r<e.features.length;r++)o(n,e.features[r],t);else"Feature"===e.type?o(n,e,t):o(n,{geometry:e},t);return n}function o(e,t,n){if(null!==t.geometry){var r,u,l,f,h=t.geometry,p=h.type,m=h.coordinates,c=t.properties,d=t.id;if("Point"===p)e.push(a(c,1,[s(m)],d));else if("MultiPoint"===p)e.push(a(c,1,i(m),d));else if("LineString"===p)e.push(a(c,2,[i(m,n)],d));else if("MultiLineString"===p||"Polygon"===p){for(l=[],r=0;r<m.length;r++)f=i(m[r],n),"Polygon"===p&&(f.outer=0===r),l.push(f);e.push(a(c,"Polygon"===p?3:2,l,d))}else if("MultiPolygon"===p){for(l=[],r=0;r<m.length;r++)for(u=0;u<m[r].length;u++)f=i(m[r][u],n),f.outer=0===u,l.push(f);e.push(a(c,3,l,d))}else{if("GeometryCollection"!==p)throw new Error("Input data is not a valid GeoJSON object.");for(r=0;r<h.geometries.length;r++)o(e,{geometry:h.geometries[r],properties:c},n)}}}function i(e,t){for(var n=[],r=0;r<e.length;r++)n.push(s(e[r]));return t&&(l(n,t),u(n)),n}function s(e){var t=Math.sin(e[1]*Math.PI/180),n=e[0]/360+.5,r=.5-.25*Math.log((1+t)/(1-t))/Math.PI;return r=0>r?0:r>1?1:r,[n,r,0]}function u(e){for(var t,n,r=0,o=0,i=0;i<e.length-1;i++)t=n||e[i],n=e[i+1],r+=t[0]*n[1]-n[0]*t[1],o+=Math.abs(n[0]-t[0])+Math.abs(n[1]-t[1]);e.area=Math.abs(r/2),e.dist=o}t.exports=r;var l=e("./simplify"),a=e("./feature")},{"./feature":3,"./simplify":5}],3:[function(e,t,n){"use strict";function r(e,t,n,r){var i={id:r||null,type:t,geometry:n,tags:e||null,min:[1/0,1/0],max:[-(1/0),-(1/0)]};return o(i),i}function o(e){var t=e.geometry,n=e.min,r=e.max;if(1===e.type)i(n,r,t);else for(var o=0;o<t.length;o++)i(n,r,t[o]);return e}function i(e,t,n){for(var r,o=0;o<n.length;o++)r=n[o],e[0]=Math.min(r[0],e[0]),t[0]=Math.max(r[0],t[0]),e[1]=Math.min(r[1],e[1]),t[1]=Math.max(r[1],t[1])}t.exports=r},{}],4:[function(e,t,n){"use strict";function r(e,t){return new o(e,t)}function o(e,t){t=this.options=l(Object.create(this.options),t);var n=t.debug;n&&console.time("preprocess data");var r=1<<t.maxZoom,o=f(e,t.tolerance/(r*t.extent));this.tiles={},this.tileCoords=[],n&&(console.timeEnd("preprocess data"),console.log("index: maxZoom: %d, maxPoints: %d",t.indexMaxZoom,t.indexMaxPoints),console.time("generate tiles"),this.stats={},this.total=0),o=m(o,t.buffer/t.extent,s),o.length&&this.splitTile(o,0,0,0),n&&(o.length&&console.log("features: %d, points: %d",this.tiles[0].numFeatures,this.tiles[0].numPoints),console.timeEnd("generate tiles"),console.log("tiles generated:",this.total,JSON.stringify(this.stats)))}function i(e,t,n){return 32*((1<<e)*n+t)+e}function s(e,t,n){return[n,(n-e[0])*(t[1]-e[1])/(t[0]-e[0])+e[1],1]}function u(e,t,n){return[(n-e[1])*(t[0]-e[0])/(t[1]-e[1])+e[0],n,1]}function l(e,t){for(var n in t)e[n]=t[n];return e}function a(e,t,n){var r=e.source;if(1!==r.length)return!1;var o=r[0];if(3!==o.type||o.geometry.length>1)return!1;var i=o.geometry[0].length;if(5!==i)return!1;for(var s=0;i>s;s++){var u=h.point(o.geometry[0][s],t,e.z2,e.x,e.y);if(u[0]!==-n&&u[0]!==t+n||u[1]!==-n&&u[1]!==t+n)return!1}return!0}t.exports=r;var f=e("./convert"),h=e("./transform"),p=e("./clip"),m=e("./wrap"),c=e("./tile");o.prototype.options={maxZoom:14,indexMaxZoom:5,indexMaxPoints:1e5,solidChildren:!1,tolerance:3,extent:4096,buffer:64,debug:0},o.prototype.splitTile=function(e,t,n,r,o,l,f){for(var h=[e,t,n,r],m=this.options,d=m.debug,g=null;h.length;){r=h.pop(),n=h.pop(),t=h.pop(),e=h.pop();var v=1<<t,x=i(t,n,r),y=this.tiles[x],M=t===m.maxZoom?0:m.tolerance/(v*m.extent);if(!y&&(d>1&&console.time("creation"),y=this.tiles[x]=c(e,v,n,r,M,t===m.maxZoom),this.tileCoords.push({z:t,x:n,y:r}),d)){d>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",t,n,r,y.numFeatures,y.numPoints,y.numSimplified),console.timeEnd("creation"));var P="z"+t;this.stats[P]=(this.stats[P]||0)+1,this.total++}if(y.source=e,o){if(t===m.maxZoom||t===o)continue;var b=1<<o-t;if(n!==Math.floor(l/b)||r!==Math.floor(f/b))continue}else if(t===m.indexMaxZoom||y.numPoints<=m.indexMaxPoints)continue;if(m.solidChildren||!a(y,m.extent,m.buffer)){y.source=null,d>1&&console.time("clipping");var w,Z,z,E,S,C,F=.5*m.buffer/m.extent,O=.5-F,T=.5+F,j=1+F;w=Z=z=E=null,S=p(e,v,n-F,n+T,0,s,y.min[0],y.max[0]),C=p(e,v,n+O,n+j,0,s,y.min[0],y.max[0]),S&&(w=p(S,v,r-F,r+T,1,u,y.min[1],y.max[1]),Z=p(S,v,r+O,r+j,1,u,y.min[1],y.max[1])),C&&(z=p(C,v,r-F,r+T,1,u,y.min[1],y.max[1]),E=p(C,v,r+O,r+j,1,u,y.min[1],y.max[1])),d>1&&console.timeEnd("clipping"),e.length&&(h.push(w||[],t+1,2*n,2*r),h.push(Z||[],t+1,2*n,2*r+1),h.push(z||[],t+1,2*n+1,2*r),h.push(E||[],t+1,2*n+1,2*r+1))}else o&&(g=t)}return g},o.prototype.getTile=function(e,t,n){var r=this.options,o=r.extent,s=r.debug,u=1<<e;t=(t%u+u)%u;var l=i(e,t,n);if(this.tiles[l])return h.tile(this.tiles[l],o);s>1&&console.log("drilling down to z%d-%d-%d",e,t,n);for(var f,p=e,m=t,c=n;!f&&p>0;)p--,m=Math.floor(m/2),c=Math.floor(c/2),f=this.tiles[i(p,m,c)];if(!f||!f.source)return null;if(s>1&&console.log("found parent tile z%d-%d-%d",p,m,c),a(f,o,r.buffer))return h.tile(f,o);s>1&&console.time("drilling down");var d=this.splitTile(f.source,p,m,c,e,t,n);if(s>1&&console.timeEnd("drilling down"),null!==d){var g=1<<e-d;l=i(d,Math.floor(t/g),Math.floor(n/g))}return this.tiles[l]?h.tile(this.tiles[l],o):null}},{"./clip":1,"./convert":2,"./tile":6,"./transform":7,"./wrap":8}],5:[function(e,t,n){"use strict";function r(e,t){var n,r,i,s,u=t*t,l=e.length,a=0,f=l-1,h=[];for(e[a][2]=1,e[f][2]=1;f;){for(r=0,n=a+1;f>n;n++)i=o(e[n],e[a],e[f]),i>r&&(s=n,r=i);r>u?(e[s][2]=r,h.push(a),h.push(s),a=s):(f=h.pop(),a=h.pop())}}function o(e,t,n){var r=t[0],o=t[1],i=n[0],s=n[1],u=e[0],l=e[1],a=i-r,f=s-o;if(0!==a||0!==f){var h=((u-r)*a+(l-o)*f)/(a*a+f*f);h>1?(r=i,o=s):h>0&&(r+=a*h,o+=f*h)}return a=u-r,f=l-o,a*a+f*f}t.exports=r},{}],6:[function(e,t,n){"use strict";function r(e,t,n,r,i,s){for(var u={features:[],numPoints:0,numSimplified:0,numFeatures:0,source:null,x:n,y:r,z2:t,transformed:!1,min:[2,1],max:[-1,0]},l=0;l<e.length;l++){u.numFeatures++,o(u,e[l],i,s);var a=e[l].min,f=e[l].max;a[0]<u.min[0]&&(u.min[0]=a[0]),a[1]<u.min[1]&&(u.min[1]=a[1]),f[0]>u.max[0]&&(u.max[0]=f[0]),f[1]>u.max[1]&&(u.max[1]=f[1])}return u}function o(e,t,n,r){var o,s,u,l,a=t.geometry,f=t.type,h=[],p=n*n;if(1===f)for(o=0;o<a.length;o++)h.push(a[o]),e.numPoints++,e.numSimplified++;else for(o=0;o<a.length;o++)if(u=a[o],r||!(2===f&&u.dist<n||3===f&&u.area<p)){var m=[];for(s=0;s<u.length;s++)l=u[s],(r||l[2]>p)&&(m.push(l),e.numSimplified++),e.numPoints++;3===f&&i(m,u.outer),h.push(m)}else e.numPoints+=u.length;if(h.length){var c={geometry:h,type:f,tags:t.tags||null};null!==t.id&&(c.id=t.id),e.features.push(c)}}function i(e,t){var n=s(e);0>n===t&&e.reverse()}function s(e){for(var t,n,r=0,o=0,i=e.length,s=i-1;i>o;s=o++)t=e[o],n=e[s],r+=(n[0]-t[0])*(t[1]+n[1]);return r}t.exports=r},{}],7:[function(e,t,n){"use strict";function r(e,t){if(e.transformed)return e;var n,r,i,s=e.z2,u=e.x,l=e.y;for(n=0;n<e.features.length;n++){var a=e.features[n],f=a.geometry,h=a.type;if(1===h)for(r=0;r<f.length;r++)f[r]=o(f[r],t,s,u,l);else for(r=0;r<f.length;r++){var p=f[r];for(i=0;i<p.length;i++)p[i]=o(p[i],t,s,u,l)}}return e.transformed=!0,e}function o(e,t,n,r,o){var i=Math.round(t*(e[0]*n-r)),s=Math.round(t*(e[1]*n-o));return[i,s]}n.tile=r,n.point=o},{}],8:[function(e,t,n){"use strict";function r(e,t,n){var r=e,i=s(e,1,-1-t,t,0,n,-1,2),u=s(e,1,1-t,2+t,0,n,-1,2);return(i||u)&&(r=s(e,1,-t,1+t,0,n,-1,2)||[],i&&(r=o(i,1).concat(r)),u&&(r=r.concat(o(u,-1)))),r}function o(e,t){for(var n=[],r=0;r<e.length;r++){var o,s=e[r],l=s.type;if(1===l)o=i(s.geometry,t);else{o=[];for(var a=0;a<s.geometry.length;a++)o.push(i(s.geometry[a],t))}n.push(u(s.tags,l,o,s.id))}return n}function i(e,t){var n=[];n.area=e.area,n.dist=e.dist;for(var r=0;r<e.length;r++)n.push([e[r][0]+t,e[r][1],e[r][2]]);return n}var s=e("./clip"),u=e("./feature");t.exports=r},{"./clip":1,"./feature":3}]},{},[4])(4)});
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).geojsonvt=e()}}(function(){return function e(t,n,i){function o(s,u){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!u&&l)return l(s,!0);if(r)return r(s,!0);var a=new Error("Cannot find module '"+s+"'");throw a.code="MODULE_NOT_FOUND",a}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(e){var n=t[s][1][e];return o(n||e)},f,f.exports,e,t,n,i)}return n[s].exports}for(var r="function"==typeof require&&require,s=0;s<i.length;s++)o(i[s]);return o}({1:[function(e,t,n){"use strict";function i(e,t,n,i,o){for(var r=0;r<e.length;r+=3){var s=e[r+o];s>=n&&s<=i&&(t.push(e[r]),t.push(e[r+1]),t.push(e[r+2]))}}function o(e,t,n,i,o,r){for(var a=[],f=0===o?u:l,h=0;h<e.length-3;h+=3){var m=e[h],p=e[h+1],g=e[h+2],c=e[h+3],d=e[h+4],v=0===o?m:p,x=0===o?c:d,y=!1;v<n?x>=n&&f(a,m,p,c,d,n):v>i?x<=i&&f(a,m,p,c,d,i):s(a,m,p,g),x<n&&v>=n&&(f(a,m,p,c,d,n),y=!0),x>i&&v<=i&&(f(a,m,p,c,d,i),y=!0),!r&&y&&(a.size=e.size,t.push(a),a=[])}var M=e.length-3;m=e[M],p=e[M+1],g=e[M+2],(v=0===o?m:p)>=n&&v<=i&&s(a,m,p,g),M=a.length-3,r&&M>=3&&(a[M]!==a[0]||a[M+1]!==a[1])&&s(a,a[0],a[1],a[2]),a.length&&(a.size=e.size,t.push(a))}function r(e,t,n,i,r,s){for(var u=0;u<e.length;u++)o(e[u],t,n,i,r,s)}function s(e,t,n,i){e.push(t),e.push(n),e.push(i)}function u(e,t,n,i,o,r){e.push(r),e.push(n+(r-t)*(o-n)/(i-t)),e.push(1)}function l(e,t,n,i,o,r){e.push(t+(r-n)*(i-t)/(o-n)),e.push(r),e.push(1)}t.exports=function(e,t,n,s,u,l,f){if(n/=t,s/=t,l>=n&&f<=s)return e;if(l>s||f<n)return null;for(var h=[],m=0;m<e.length;m++){var p=e[m],g=p.geometry,c=p.type,d=0===u?p.minX:p.minY,v=0===u?p.maxX:p.maxY;if(d>=n&&v<=s)h.push(p);else if(!(d>s||v<n)){var x=[];if("Point"===c||"MultiPoint"===c)i(g,x,n,s,u);else if("LineString"===c)o(g,x,n,s,u,!1);else if("MultiLineString"===c)r(g,x,n,s,u,!1);else if("Polygon"===c)r(g,x,n,s,u,!0);else if("MultiPolygon"===c)for(var y=0;y<g.length;y++){var M=[];r(g[y],M,n,s,u,!0),M.length&&x.push(M)}x.length&&("LineString"!==c&&"MultiLineString"!==c||(1===x.length?(c="LineString",x=x[0]):c="MultiLineString"),"Point"!==c&&"MultiPoint"!==c||(c=3===x.length?"Point":"MultiPoint"),h.push(a(p.id,c,x,p.tags)))}}return h.length?h:null};var a=e("./feature")},{"./feature":3}],2:[function(e,t,n){"use strict";function i(e,t,n){if(t.geometry){var u=t.geometry.coordinates,l=t.geometry.type,a=n*n,h=[];if("Point"===l)o(u,h);else if("MultiPoint"===l)for(var m=0;m<u.length;m++)o(u[m],h);else if("LineString"===l)r(u,h,a,!1);else if("MultiLineString"===l)s(u,h,a,!1);else if("Polygon"===l)s(u,h,a,!0);else{if("MultiPolygon"!==l){if("GeometryCollection"===l){for(m=0;m<t.geometry.geometries.length;m++)i(e,{geometry:t.geometry.geometries[m],properties:t.properties},n);return}throw new Error("Input data is not a valid GeoJSON object.")}for(m=0;m<u.length;m++){var p=[];s(u[m],p,a,!0),h.push(p)}}e.push(f(t.id,l,h,t.properties))}}function o(e,t){t.push(u(e[0])),t.push(l(e[1])),t.push(0)}function r(e,t,n,i){for(var o,r,s=0,f=0;f<e.length;f++){var h=u(e[f][0]),m=l(e[f][1]);t.push(h),t.push(m),t.push(0),f>0&&(s+=i?(o*m-h*r)/2:Math.sqrt(Math.pow(h-o,2)+Math.pow(m-r,2))),o=h,r=m}var p=t.length-3;t[2]=1,a(t,0,p,n),t[p+2]=1,t.size=Math.abs(s)}function s(e,t,n,i){for(var o=0;o<e.length;o++){var s=[];r(e[o],s,n,i),t.push(s)}}function u(e){return e/360+.5}function l(e){var t=Math.sin(e*Math.PI/180),n=.5-.25*Math.log((1+t)/(1-t))/Math.PI;return n<0?0:n>1?1:n}t.exports=function(e,t){var n=[];if("FeatureCollection"===e.type)for(var o=0;o<e.features.length;o++)i(n,e.features[o],t);else"Feature"===e.type?i(n,e,t):i(n,{geometry:e},t);return n};var a=e("./simplify"),f=e("./feature")},{"./feature":3,"./simplify":5}],3:[function(e,t,n){"use strict";function i(e){var t=e.geometry,n=e.type;if("Point"===n||"MultiPoint"===n||"LineString"===n)o(e,t);else if("Polygon"===n||"MultiLineString"===n)for(var i=0;i<t.length;i++)o(e,t[i]);else if("MultiPolygon"===n)for(i=0;i<t.length;i++)for(var r=0;r<t[i].length;r++)o(e,t[i][r])}function o(e,t){for(var n=0;n<t.length;n+=3)e.minX=Math.min(e.minX,t[n]),e.minY=Math.min(e.minY,t[n+1]),e.maxX=Math.max(e.maxX,t[n]),e.maxY=Math.max(e.maxY,t[n+1])}t.exports=function(e,t,n,o){var r={id:e||null,type:t,geometry:n,tags:o,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};return i(r),r}},{}],4:[function(e,t,n){"use strict";function i(e,t){var n=(t=this.options=r(Object.create(this.options),t)).debug;if(n&&console.time("preprocess data"),t.maxZoom<0||t.maxZoom>24)throw new Error("maxZoom should be in the 0-24 range");var i=1<<t.maxZoom,o=s(e,t.tolerance/(i*t.extent));this.tiles={},this.tileCoords=[],n&&(console.timeEnd("preprocess data"),console.log("index: maxZoom: %d, maxPoints: %d",t.indexMaxZoom,t.indexMaxPoints),console.time("generate tiles"),this.stats={},this.total=0),(o=a(o,t.buffer/t.extent)).length&&this.splitTile(o,0,0,0),n&&(o.length&&console.log("features: %d, points: %d",this.tiles[0].numFeatures,this.tiles[0].numPoints),console.timeEnd("generate tiles"),console.log("tiles generated:",this.total,JSON.stringify(this.stats)))}function o(e,t,n){return 32*((1<<e)*n+t)+e}function r(e,t){for(var n in t)e[n]=t[n];return e}t.exports=function(e,t){return new i(e,t)};var s=e("./convert"),u=e("./transform"),l=e("./clip"),a=e("./wrap"),f=e("./tile");i.prototype.options={maxZoom:14,indexMaxZoom:5,indexMaxPoints:1e5,tolerance:3,extent:4096,buffer:64,debug:0},i.prototype.splitTile=function(e,t,n,i,r,s,u){for(var a=[e,t,n,i],h=this.options,m=h.debug;a.length;){i=a.pop(),n=a.pop(),t=a.pop(),e=a.pop();var p=1<<t,g=o(t,n,i),c=this.tiles[g],d=t===h.maxZoom?0:h.tolerance/(p*h.extent);if(!c&&(m>1&&console.time("creation"),c=this.tiles[g]=f(e,p,n,i,d,t===h.maxZoom),this.tileCoords.push({z:t,x:n,y:i}),m)){m>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",t,n,i,c.numFeatures,c.numPoints,c.numSimplified),console.timeEnd("creation"));var v="z"+t;this.stats[v]=(this.stats[v]||0)+1,this.total++}if(c.source=e,r){if(t===h.maxZoom||t===r)continue;var x=1<<r-t;if(n!==Math.floor(s/x)||i!==Math.floor(u/x))continue}else if(t===h.indexMaxZoom||c.numPoints<=h.indexMaxPoints)continue;if(c.source=null,0!==e.length){m>1&&console.time("clipping");var y,M,P,Y,S,X,w=.5*h.buffer/h.extent,L=.5-w,z=.5+w,b=1+w;y=M=P=Y=null,S=l(e,p,n-w,n+z,0,c.minX,c.maxX),X=l(e,p,n+L,n+b,0,c.minX,c.maxX),e=null,S&&(y=l(S,p,i-w,i+z,1,c.minY,c.maxY),M=l(S,p,i+L,i+b,1,c.minY,c.maxY),S=null),X&&(P=l(X,p,i-w,i+z,1,c.minY,c.maxY),Y=l(X,p,i+L,i+b,1,c.minY,c.maxY),X=null),m>1&&console.timeEnd("clipping"),a.push(y||[],t+1,2*n,2*i),a.push(M||[],t+1,2*n,2*i+1),a.push(P||[],t+1,2*n+1,2*i),a.push(Y||[],t+1,2*n+1,2*i+1)}}},i.prototype.getTile=function(e,t,n){var i=this.options,r=i.extent,s=i.debug;if(e<0||e>24)return null;var l=1<<e,a=o(e,t=(t%l+l)%l,n);if(this.tiles[a])return u.tile(this.tiles[a],r);s>1&&console.log("drilling down to z%d-%d-%d",e,t,n);for(var f,h=e,m=t,p=n;!f&&h>0;)h--,m=Math.floor(m/2),p=Math.floor(p/2),f=this.tiles[o(h,m,p)];return f&&f.source?(s>1&&console.log("found parent tile z%d-%d-%d",h,m,p),s>1&&console.time("drilling down"),this.splitTile(f.source,h,m,p,e,t,n),s>1&&console.timeEnd("drilling down"),this.tiles[a]?u.tile(this.tiles[a],r):null):null}},{"./clip":1,"./convert":2,"./tile":6,"./transform":7,"./wrap":8}],5:[function(e,t,n){"use strict";function i(e,t,n,r){for(var s,u=r,l=e[t],a=e[t+1],f=e[n],h=e[n+1],m=t+3;m<n;m+=3){var p=o(e[m],e[m+1],l,a,f,h);p>u&&(s=m,u=p)}u>r&&(s-t>3&&i(e,t,s,r),e[s+2]=u,n-s>3&&i(e,s,n,r))}function o(e,t,n,i,o,r){var s=o-n,u=r-i;if(0!==s||0!==u){var l=((e-n)*s+(t-i)*u)/(s*s+u*u);l>1?(n=o,i=r):l>0&&(n+=s*l,i+=u*l)}return s=e-n,u=t-i,s*s+u*u}t.exports=i},{}],6:[function(e,t,n){"use strict";function i(e,t,n,i){var r=t.geometry,s=t.type,u=[];if("Point"===s||"MultiPoint"===s)for(var l=0;l<r.length;l+=3)u.push(r[l]),u.push(r[l+1]),e.numPoints++,e.numSimplified++;else if("LineString"===s)o(u,r,e,n,i,!1,!1);else if("MultiLineString"===s||"Polygon"===s)for(l=0;l<r.length;l++)o(u,r[l],e,n,i,"Polygon"===s,0===l);else if("MultiPolygon"===s)for(var a=0;a<r.length;a++){var f=r[a];for(l=0;l<f.length;l++)o(u,f[l],e,n,i,!0,0===l)}if(u.length){var h={geometry:u,type:"Polygon"===s||"MultiPolygon"===s?3:"LineString"===s||"MultiLineString"===s?2:1,tags:t.tags||null};null!==t.id&&(h.id=t.id),e.features.push(h)}}function o(e,t,n,i,o,s,u){var l=i*i;if(!o&&t.size<(s?l:i))n.numPoints+=t.length/3;else{for(var a=[],f=0;f<t.length;f+=3)(o||t[f+2]>l)&&(n.numSimplified++,a.push(t[f]),a.push(t[f+1])),n.numPoints++;s&&r(a,u),e.push(a)}}function r(e,t){for(var n=0,i=0,o=e.length,r=o-2;i<o;r=i,i+=2)n+=(e[i]-e[r])*(e[i+1]+e[r+1]);if(n>0===t)for(i=0,o=e.length;i<o/2;i+=2){var s=e[i],u=e[i+1];e[i]=e[o-2-i],e[i+1]=e[o-1-i],e[o-2-i]=s,e[o-1-i]=u}}t.exports=function(e,t,n,o,r,s){for(var u={features:[],numPoints:0,numSimplified:0,numFeatures:0,source:null,x:n,y:o,z2:t,transformed:!1,minX:2,minY:1,maxX:-1,maxY:0},l=0;l<e.length;l++){u.numFeatures++,i(u,e[l],r,s);var a=e[l].minX,f=e[l].minY,h=e[l].maxX,m=e[l].maxY;a<u.minX&&(u.minX=a),f<u.minY&&(u.minY=f),h>u.maxX&&(u.maxX=h),m>u.maxY&&(u.maxY=m)}return u}},{}],7:[function(e,t,n){"use strict";function i(e,t,n,i,o,r){return[Math.round(n*(e*i-o)),Math.round(n*(t*i-r))]}n.tile=function(e,t){if(e.transformed)return e;var n,o,r,s=e.z2,u=e.x,l=e.y;for(n=0;n<e.features.length;n++){var a=e.features[n],f=a.geometry,h=a.type;if(a.geometry=[],1===h)for(o=0;o<f.length;o+=2)a.geometry.push(i(f[o],f[o+1],t,s,u,l));else for(o=0;o<f.length;o++){var m=[];for(r=0;r<f[o].length;r+=2)m.push(i(f[o][r],f[o][r+1],t,s,u,l));a.geometry.push(m)}}return e.transformed=!0,e},n.point=i},{}],8:[function(e,t,n){"use strict";function i(e,t){for(var n=[],i=0;i<e.length;i++){var r,u=e[i],l=u.type;if("Point"===l||"MultiPoint"===l||"LineString"===l)r=o(u.geometry,t);else if("MultiLineString"===l||"Polygon"===l){r=[];for(var a=0;a<u.geometry.length;a++)r.push(o(u.geometry[a],t))}else if("MultiPolygon"===l)for(r=[],a=0;a<u.geometry.length;a++){for(var f=[],h=0;h<u.geometry[a].length;h++)f.push(o(u.geometry[a][h],t));r.push(f)}n.push(s(u.id,l,r,u.tags))}return n}function o(e,t){var n=[];n.size=e.size;for(var i=0;i<e.length;i+=3)n.push(e[i]+t,e[i+1],e[i+2]);return n}var r=e("./clip"),s=e("./feature");t.exports=function(e,t){var n=e,o=r(e,1,-1-t,t,0,-1,2),s=r(e,1,1-t,2+t,0,-1,2);return(o||s)&&(n=r(e,1,-t,1+t,0,-1,2)||[],o&&(n=i(o,1).concat(n)),s&&(n=n.concat(i(s,-1)))),n}},{"./clip":1,"./feature":3}]},{},[4])(4)});
{
"name": "geojson-vt",
"version": "2.4.0",
"version": "3.0.0",
"description": "Slice GeoJSON data into vector tiles efficiently",

@@ -19,15 +19,18 @@ "homepage": "https://github.com/mapbox/geojson-vt",

"devDependencies": {
"benchmark": "^2.1.0",
"browserify": "^13.0.1",
"coveralls": "^2.11.9",
"eslint": "^2.10.2",
"benchmark": "^2.1.4",
"browserify": "^14.4.0",
"coveralls": "^2.13.1",
"eslint": "^4.5.0",
"eslint-config-mourner": "^2.0.1",
"faucet": "0.0.1",
"istanbul": "^0.4.3",
"tape": "^4.5.1",
"uglify-js": "^2.6.2",
"watchify": "^3.7.0"
"nyc": "^11.1.0",
"tape": "^4.8.0",
"uglify-js": "^3.0.28",
"watchify": "^3.9.0"
},
"eslintConfig": {
"extends": "mourner"
"extends": "mourner",
"globals": {
"topojson": true
}
},

@@ -37,3 +40,3 @@ "license": "ISC",

"test": "eslint src/*.js test/*.js debug/viz.js && tape test/test-*.js | faucet",
"cov": "istanbul cover tape test/test*.js",
"cov": "nyc --reporter=lcov --reporter=text-summary tape test/test*.js",
"coveralls": "npm run cov && coveralls < ./coverage/lcov.info",

@@ -40,0 +43,0 @@ "build-min": "browserify src/index.js -s geojsonvt | uglifyjs -c -m -o geojson-vt.js",

@@ -57,3 +57,3 @@ ## geojson-vt &mdash; GeoJSON Vector Tiles

var tileIndex = geojsonvt(data, {
maxZoom: 14, // max zoom to preserve detail on
maxZoom: 14, // max zoom to preserve detail on; can't be higher than 24
tolerance: 3, // simplification tolerance (higher means simpler)

@@ -70,2 +70,6 @@ extent: 4096, // tile extent (both width and height)

By default, tiles at zoom levels above `indexMaxZoom` are generated on the fly, but you can pre-generate all possible tiles for `data` by setting `indexMaxZoom` and `maxZoom` to the same value, setting `indexMaxPoints` to `0`, and then accessing the resulting tile coordinates from the `tileCoords` property of `tileIndex`.
GeoJSON-VT only operates on zoom levels up to 24.
### Browser builds

@@ -72,0 +76,0 @@

@@ -14,3 +14,3 @@ 'use strict';

function clip(features, scale, k1, k2, axis, intersect, minAll, maxAll) {
function clip(features, scale, k1, k2, axis, minAll, maxAll) {

@@ -27,9 +27,8 @@ k1 /= scale;

var feature = features[i],
geometry = feature.geometry,
type = feature.type,
min, max;
var feature = features[i];
var geometry = feature.geometry;
var type = feature.type;
min = feature.min[axis];
max = feature.max[axis];
var min = axis === 0 ? feature.minX : feature.minY;
var max = axis === 0 ? feature.maxX : feature.maxY;

@@ -39,114 +38,147 @@ if (min >= k1 && max <= k2) { // trivial accept

continue;
} else if (min > k2 || max < k1) continue; // trivial reject
var slices = type === 1 ?
clipPoints(geometry, k1, k2, axis) :
clipGeometry(geometry, k1, k2, axis, intersect, type === 3);
if (slices.length) {
// if a feature got clipped, it will likely get clipped on the next zoom level as well,
// so there's no need to recalculate bboxes
clipped.push(createFeature(feature.tags, type, slices, feature.id));
} else if (min > k2 || max < k1) { // trivial reject
continue;
}
}
return clipped.length ? clipped : null;
}
var newGeometry = [];
function clipPoints(geometry, k1, k2, axis) {
var slice = [];
if (type === 'Point' || type === 'MultiPoint') {
clipPoints(geometry, newGeometry, k1, k2, axis);
for (var i = 0; i < geometry.length; i++) {
var a = geometry[i],
ak = a[axis];
} else if (type === 'LineString') {
clipLine(geometry, newGeometry, k1, k2, axis, false);
if (ak >= k1 && ak <= k2) slice.push(a);
}
return slice;
}
} else if (type === 'MultiLineString') {
clipLines(geometry, newGeometry, k1, k2, axis, false);
function clipGeometry(geometry, k1, k2, axis, intersect, closed) {
} else if (type === 'Polygon') {
clipLines(geometry, newGeometry, k1, k2, axis, true);
var slices = [];
} else if (type === 'MultiPolygon') {
for (var j = 0; j < geometry.length; j++) {
var polygon = [];
clipLines(geometry[j], polygon, k1, k2, axis, true);
if (polygon.length) {
newGeometry.push(polygon);
}
}
}
for (var i = 0; i < geometry.length; i++) {
if (newGeometry.length) {
if (type === 'LineString' || type === 'MultiLineString') {
if (newGeometry.length === 1) {
type = 'LineString';
newGeometry = newGeometry[0];
} else {
type = 'MultiLineString';
}
}
if (type === 'Point' || type === 'MultiPoint') {
type = newGeometry.length === 3 ? 'Point' : 'MultiPoint';
}
var ak = 0,
bk = 0,
b = null,
points = geometry[i],
area = points.area,
dist = points.dist,
outer = points.outer,
len = points.length,
a, j, last;
clipped.push(createFeature(feature.id, type, newGeometry, feature.tags));
}
}
var slice = [];
return clipped.length ? clipped : null;
}
for (j = 0; j < len - 1; j++) {
a = b || points[j];
b = points[j + 1];
ak = bk || a[axis];
bk = b[axis];
function clipPoints(geom, newGeom, k1, k2, axis) {
for (var i = 0; i < geom.length; i += 3) {
var a = geom[i + axis];
if (ak < k1) {
if (a >= k1 && a <= k2) {
newGeom.push(geom[i]);
newGeom.push(geom[i + 1]);
newGeom.push(geom[i + 2]);
}
}
}
if ((bk > k2)) { // ---|-----|-->
slice.push(intersect(a, b, k1), intersect(a, b, k2));
if (!closed) slice = newSlice(slices, slice, area, dist, outer);
function clipLine(geom, newGeom, k1, k2, axis, isPolygon) {
} else if (bk >= k1) slice.push(intersect(a, b, k1)); // ---|--> |
var slice = [];
var intersect = axis === 0 ? intersectX : intersectY;
} else if (ak > k2) {
for (var i = 0; i < geom.length - 3; i += 3) {
var ax = geom[i];
var ay = geom[i + 1];
var az = geom[i + 2];
var bx = geom[i + 3];
var by = geom[i + 4];
var a = axis === 0 ? ax : ay;
var b = axis === 0 ? bx : by;
var sliced = false;
if ((bk < k1)) { // <--|-----|---
slice.push(intersect(a, b, k2), intersect(a, b, k1));
if (!closed) slice = newSlice(slices, slice, area, dist, outer);
if (a < k1) {
// ---|--> |
if (b >= k1) intersect(slice, ax, ay, bx, by, k1);
} else if (a > k2) {
// | <--|---
if (b <= k2) intersect(slice, ax, ay, bx, by, k2);
} else {
addPoint(slice, ax, ay, az);
}
if (b < k1 && a >= k1) {
// <--|--- | or <--|-----|---
intersect(slice, ax, ay, bx, by, k1);
sliced = true;
}
if (b > k2 && a <= k2) {
// | ---|--> or ---|-----|-->
intersect(slice, ax, ay, bx, by, k2);
sliced = true;
}
} else if (bk <= k2) slice.push(intersect(a, b, k2)); // | <--|---
} else {
slice.push(a);
if (bk < k1) { // <--|--- |
slice.push(intersect(a, b, k1));
if (!closed) slice = newSlice(slices, slice, area, dist, outer);
} else if (bk > k2) { // | ---|-->
slice.push(intersect(a, b, k2));
if (!closed) slice = newSlice(slices, slice, area, dist, outer);
}
// | --> |
}
if (!isPolygon && sliced) {
slice.size = geom.size;
newGeom.push(slice);
slice = [];
}
}
// add the last point
a = points[len - 1];
ak = a[axis];
if (ak >= k1 && ak <= k2) slice.push(a);
// add the last point
var last = geom.length - 3;
ax = geom[last];
ay = geom[last + 1];
az = geom[last + 2];
a = axis === 0 ? ax : ay;
if (a >= k1 && a <= k2) addPoint(slice, ax, ay, az);
// close the polygon if its endpoints are not the same after clipping
// close the polygon if its endpoints are not the same after clipping
last = slice.length - 3;
if (isPolygon && last >= 3 && (slice[last] !== slice[0] || slice[last + 1] !== slice[1])) {
addPoint(slice, slice[0], slice[1], slice[2]);
}
last = slice[slice.length - 1];
if (closed && last && (slice[0][0] !== last[0] || slice[0][1] !== last[1])) slice.push(slice[0]);
// add the final slice
if (slice.length) {
slice.size = geom.size;
newGeom.push(slice);
}
}
// add the final slice
newSlice(slices, slice, area, dist, outer);
function clipLines(geom, newGeom, k1, k2, axis, isPolygon) {
for (var i = 0; i < geom.length; i++) {
clipLine(geom[i], newGeom, k1, k2, axis, isPolygon);
}
}
return slices;
function addPoint(out, x, y, z) {
out.push(x);
out.push(y);
out.push(z);
}
function newSlice(slices, slice, area, dist, outer) {
if (slice.length) {
// we don't recalculate the area/length of the unclipped geometry because the case where it goes
// below the visibility threshold as a result of clipping is rare, so we avoid doing unnecessary work
slice.area = area;
slice.dist = dist;
if (outer !== undefined) slice.outer = outer;
function intersectX(out, ax, ay, bx, by, x) {
out.push(x);
out.push(ay + (x - ax) * (by - ay) / (bx - ax));
out.push(1);
}
slices.push(slice);
}
return [];
function intersectY(out, ax, ay, bx, by, y) {
out.push(ax + (y - ay) * (bx - ax) / (by - ay));
out.push(y);
out.push(1);
}

@@ -17,2 +17,3 @@ 'use strict';

}
} else if (data.type === 'Feature') {

@@ -25,99 +26,105 @@ convertFeature(features, data, tolerance);

}
return features;
}
function convertFeature(features, feature, tolerance) {
if (feature.geometry === null) {
// ignore features with null geometry
return;
}
function convertFeature(features, geojson, tolerance) {
if (!geojson.geometry) return;
var geom = feature.geometry,
type = geom.type,
coords = geom.coordinates,
tags = feature.properties,
id = feature.id,
i, j, rings, projectedRing;
var coords = geojson.geometry.coordinates;
var type = geojson.geometry.type;
var tol = tolerance * tolerance;
var geometry = [];
if (type === 'Point') {
features.push(createFeature(tags, 1, [projectPoint(coords)], id));
convertPoint(coords, geometry);
} else if (type === 'MultiPoint') {
features.push(createFeature(tags, 1, project(coords), id));
for (var i = 0; i < coords.length; i++) {
convertPoint(coords[i], geometry);
}
} else if (type === 'LineString') {
features.push(createFeature(tags, 2, [project(coords, tolerance)], id));
convertLine(coords, geometry, tol, false);
} else if (type === 'MultiLineString' || type === 'Polygon') {
rings = [];
for (i = 0; i < coords.length; i++) {
projectedRing = project(coords[i], tolerance);
if (type === 'Polygon') projectedRing.outer = (i === 0);
rings.push(projectedRing);
}
features.push(createFeature(tags, type === 'Polygon' ? 3 : 2, rings, id));
} else if (type === 'MultiLineString') {
convertLines(coords, geometry, tol, false);
} else if (type === 'Polygon') {
convertLines(coords, geometry, tol, true);
} else if (type === 'MultiPolygon') {
rings = [];
for (i = 0; i < coords.length; i++) {
for (j = 0; j < coords[i].length; j++) {
projectedRing = project(coords[i][j], tolerance);
projectedRing.outer = (j === 0);
rings.push(projectedRing);
}
var polygon = [];
convertLines(coords[i], polygon, tol, true);
geometry.push(polygon);
}
features.push(createFeature(tags, 3, rings, id));
} else if (type === 'GeometryCollection') {
for (i = 0; i < geom.geometries.length; i++) {
for (i = 0; i < geojson.geometry.geometries.length; i++) {
convertFeature(features, {
geometry: geom.geometries[i],
properties: tags
geometry: geojson.geometry.geometries[i],
properties: geojson.properties
}, tolerance);
}
return;
} else {
throw new Error('Input data is not a valid GeoJSON object.');
}
features.push(createFeature(geojson.id, type, geometry, geojson.properties));
}
function project(lonlats, tolerance) {
var projected = [];
for (var i = 0; i < lonlats.length; i++) {
projected.push(projectPoint(lonlats[i]));
}
if (tolerance) {
simplify(projected, tolerance);
calcSize(projected);
}
return projected;
function convertPoint(coords, out) {
out.push(projectX(coords[0]));
out.push(projectY(coords[1]));
out.push(0);
}
function projectPoint(p) {
var sin = Math.sin(p[1] * Math.PI / 180),
x = (p[0] / 360 + 0.5),
y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI);
function convertLine(ring, out, tol, isPolygon) {
var x0, y0;
var size = 0;
y = y < 0 ? 0 :
y > 1 ? 1 : y;
for (var j = 0; j < ring.length; j++) {
var x = projectX(ring[j][0]);
var y = projectY(ring[j][1]);
return [x, y, 0];
}
out.push(x);
out.push(y);
out.push(0);
// calculate area and length of the poly
function calcSize(points) {
var area = 0,
dist = 0;
if (j > 0) {
if (isPolygon) {
size += (x0 * y - x * y0) / 2; // area
} else {
size += Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)); // length
}
}
x0 = x;
y0 = y;
}
for (var i = 0, a, b; i < points.length - 1; i++) {
a = b || points[i];
b = points[i + 1];
var last = out.length - 3;
out[2] = 1;
simplify(out, 0, last, tol);
out[last + 2] = 1;
area += a[0] * b[1] - b[0] * a[1];
out.size = Math.abs(size);
}
// use Manhattan distance instead of Euclidian one to avoid expensive square root computation
dist += Math.abs(b[0] - a[0]) + Math.abs(b[1] - a[1]);
function convertLines(rings, out, tol, isPolygon) {
for (var i = 0; i < rings.length; i++) {
var geom = [];
convertLine(rings[i], geom, tol, isPolygon);
out.push(geom);
}
points.area = Math.abs(area / 2);
points.dist = dist;
}
function projectX(x) {
return x / 360 + 0.5;
}
function projectY(y) {
var sin = Math.sin(y * Math.PI / 180);
var y2 = 0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI;
return y2 < 0 ? 0 : y2 > 1 ? 1 : y2;
}

@@ -5,3 +5,3 @@ 'use strict';

function createFeature(tags, type, geom, id) {
function createFeature(id, type, geom, tags) {
var feature = {

@@ -11,5 +11,7 @@ id: id || null,

geometry: geom,
tags: tags || null,
min: [Infinity, Infinity], // initial bbox values
max: [-Infinity, -Infinity]
tags: tags,
minX: Infinity,
minY: Infinity,
maxX: -Infinity,
maxY: -Infinity
};

@@ -20,27 +22,30 @@ calcBBox(feature);

// calculate the feature bounding box for faster clipping later
function calcBBox(feature) {
var geometry = feature.geometry,
min = feature.min,
max = feature.max;
var geom = feature.geometry;
var type = feature.type;
if (feature.type === 1) {
calcRingBBox(min, max, geometry);
} else {
for (var i = 0; i < geometry.length; i++) {
calcRingBBox(min, max, geometry[i]);
if (type === 'Point' || type === 'MultiPoint' || type === 'LineString') {
calcLineBBox(feature, geom);
} else if (type === 'Polygon' || type === 'MultiLineString') {
for (var i = 0; i < geom.length; i++) {
calcLineBBox(feature, geom[i]);
}
} else if (type === 'MultiPolygon') {
for (i = 0; i < geom.length; i++) {
for (var j = 0; j < geom[i].length; j++) {
calcLineBBox(feature, geom[i][j]);
}
}
}
return feature;
}
function calcRingBBox(min, max, points) {
for (var i = 0, p; i < points.length; i++) {
p = points[i];
min[0] = Math.min(p[0], min[0]);
max[0] = Math.max(p[0], max[0]);
min[1] = Math.min(p[1], min[1]);
max[1] = Math.max(p[1], max[1]);
function calcLineBBox(feature, geom) {
for (var i = 0; i < geom.length; i += 3) {
feature.minX = Math.min(feature.minX, geom[i]);
feature.minY = Math.min(feature.minY, geom[i + 1]);
feature.maxX = Math.max(feature.maxX, geom[i]);
feature.maxY = Math.max(feature.maxY, geom[i + 1]);
}
}

@@ -23,2 +23,4 @@ 'use strict';

if (options.maxZoom < 0 || options.maxZoom > 24) throw new Error('maxZoom should be in the 0-24 range');
var z2 = 1 << options.maxZoom, // 2^z

@@ -38,3 +40,3 @@ features = convert(data, options.tolerance / (z2 * options.extent));

features = wrap(features, options.buffer / options.extent, intersectX);
features = wrap(features, options.buffer / options.extent);

@@ -55,3 +57,2 @@ // start slicing from the top tile down

indexMaxPoints: 100000, // max number of points per tile in the tile index
solidChildren: false, // whether to tile solid square tiles further
tolerance: 3, // simplification tolerance (higher means simpler)

@@ -67,4 +68,3 @@ extent: 4096, // tile extent

options = this.options,
debug = options.debug,
solid = null;
debug = options.debug;

@@ -119,11 +119,7 @@ // avoid recursion by using a processing queue

// stop tiling if the tile is solid clipped square
if (!options.solidChildren && isClippedSquare(tile, options.extent, options.buffer)) {
if (cz) solid = z; // and remember the zoom if we're drilling down
continue;
}
// if we slice further down, no need to keep source geometry
tile.source = null;
if (features.length === 0) continue;
if (debug > 1) console.time('clipping');

@@ -140,13 +136,16 @@

left = clip(features, z2, x - k1, x + k3, 0, intersectX, tile.min[0], tile.max[0]);
right = clip(features, z2, x + k2, x + k4, 0, intersectX, tile.min[0], tile.max[0]);
left = clip(features, z2, x - k1, x + k3, 0, tile.minX, tile.maxX);
right = clip(features, z2, x + k2, x + k4, 0, tile.minX, tile.maxX);
features = null;
if (left) {
tl = clip(left, z2, y - k1, y + k3, 1, intersectY, tile.min[1], tile.max[1]);
bl = clip(left, z2, y + k2, y + k4, 1, intersectY, tile.min[1], tile.max[1]);
tl = clip(left, z2, y - k1, y + k3, 1, tile.minY, tile.maxY);
bl = clip(left, z2, y + k2, y + k4, 1, tile.minY, tile.maxY);
left = null;
}
if (right) {
tr = clip(right, z2, y - k1, y + k3, 1, intersectY, tile.min[1], tile.max[1]);
br = clip(right, z2, y + k2, y + k4, 1, intersectY, tile.min[1], tile.max[1]);
tr = clip(right, z2, y - k1, y + k3, 1, tile.minY, tile.maxY);
br = clip(right, z2, y + k2, y + k4, 1, tile.minY, tile.maxY);
right = null;
}

@@ -156,11 +155,7 @@

if (features.length) {
stack.push(tl || [], z + 1, x * 2, y * 2);
stack.push(bl || [], z + 1, x * 2, y * 2 + 1);
stack.push(tr || [], z + 1, x * 2 + 1, y * 2);
stack.push(br || [], z + 1, x * 2 + 1, y * 2 + 1);
}
stack.push(tl || [], z + 1, x * 2, y * 2);
stack.push(bl || [], z + 1, x * 2, y * 2 + 1);
stack.push(tr || [], z + 1, x * 2 + 1, y * 2);
stack.push(br || [], z + 1, x * 2 + 1, y * 2 + 1);
}
return solid;
};

@@ -173,2 +168,4 @@

if (z < 0 || z > 24) return null;
var z2 = 1 << z;

@@ -199,15 +196,6 @@ x = ((x % z2) + z2) % z2; // wrap tile x coordinate

// it parent tile is a solid clipped square, return it instead since it's identical
if (isClippedSquare(parent, extent, options.buffer)) return transform.tile(parent, extent);
if (debug > 1) console.time('drilling down');
var solid = this.splitTile(parent.source, z0, x0, y0, z, x, y);
this.splitTile(parent.source, z0, x0, y0, z, x, y);
if (debug > 1) console.timeEnd('drilling down');
// one of the parent tiles was a solid clipped square
if (solid !== null) {
var m = 1 << (z - solid);
id = toID(solid, Math.floor(x / m), Math.floor(y / m));
}
return this.tiles[id] ? transform.tile(this.tiles[id], extent) : null;

@@ -220,9 +208,2 @@ };

function intersectX(a, b, x) {
return [x, (x - a[0]) * (b[1] - a[1]) / (b[0] - a[0]) + a[1], 1];
}
function intersectY(a, b, y) {
return [(y - a[1]) * (b[0] - a[0]) / (b[1] - a[1]) + a[0], y, 1];
}
function extend(dest, src) {

@@ -232,22 +213,1 @@ for (var i in src) dest[i] = src[i];

}
// checks whether a tile is a whole-area fill after clipping; if it is, there's no sense slicing it further
function isClippedSquare(tile, extent, buffer) {
var features = tile.source;
if (features.length !== 1) return false;
var feature = features[0];
if (feature.type !== 3 || feature.geometry.length > 1) return false;
var len = feature.geometry[0].length;
if (len !== 5) return false;
for (var i = 0; i < len; i++) {
var p = transform.point(feature.geometry[0][i], extent, tile.z2, tile.x, tile.y);
if ((p[0] !== -buffer && p[0] !== extent + buffer) ||
(p[1] !== -buffer && p[1] !== extent + buffer)) return false;
}
return true;
}

@@ -7,39 +7,23 @@ 'use strict';

function simplify(points, tolerance) {
function simplify(coords, first, last, sqTolerance) {
var maxSqDist = sqTolerance;
var index;
var sqTolerance = tolerance * tolerance,
len = points.length,
first = 0,
last = len - 1,
stack = [],
i, maxSqDist, sqDist, index;
var ax = coords[first];
var ay = coords[first + 1];
var bx = coords[last];
var by = coords[last + 1];
// always retain the endpoints (1 is the max value)
points[first][2] = 1;
points[last][2] = 1;
// avoid recursion by using a stack
while (last) {
maxSqDist = 0;
for (i = first + 1; i < last; i++) {
sqDist = getSqSegDist(points[i], points[first], points[last]);
if (sqDist > maxSqDist) {
index = i;
maxSqDist = sqDist;
}
for (var i = first + 3; i < last; i += 3) {
var d = getSqSegDist(coords[i], coords[i + 1], ax, ay, bx, by);
if (d > maxSqDist) {
index = i;
maxSqDist = d;
}
}
if (maxSqDist > sqTolerance) {
points[index][2] = maxSqDist; // save the point importance in squared pixels as a z coordinate
stack.push(first);
stack.push(index);
first = index;
} else {
last = stack.pop();
first = stack.pop();
}
if (maxSqDist > sqTolerance) {
if (index - first > 3) simplify(coords, first, index, sqTolerance);
coords[index + 2] = maxSqDist;
if (last - index > 3) simplify(coords, index, last, sqTolerance);
}

@@ -49,9 +33,6 @@ }

// square distance from a point to a segment
function getSqSegDist(p, a, b) {
function getSqSegDist(px, py, x, y, bx, by) {
var x = a[0], y = a[1],
bx = b[0], by = b[1],
px = p[0], py = p[1],
dx = bx - x,
dy = by - y;
var dx = bx - x;
var dy = by - y;

@@ -58,0 +39,0 @@ if (dx !== 0 || dy !== 0) {

@@ -16,4 +16,6 @@ 'use strict';

transformed: false,
min: [2, 1],
max: [-1, 0]
minX: 2,
minY: 1,
maxX: -1,
maxY: 0
};

@@ -24,9 +26,11 @@ for (var i = 0; i < features.length; i++) {

var min = features[i].min,
max = features[i].max;
var minX = features[i].minX;
var minY = features[i].minY;
var maxX = features[i].maxX;
var maxY = features[i].maxY;
if (min[0] < tile.min[0]) tile.min[0] = min[0];
if (min[1] < tile.min[1]) tile.min[1] = min[1];
if (max[0] > tile.max[0]) tile.max[0] = max[0];
if (max[1] > tile.max[1]) tile.max[1] = max[1];
if (minX < tile.minX) tile.minX = minX;
if (minY < tile.minY) tile.minY = minY;
if (maxX > tile.maxX) tile.maxX = maxX;
if (maxY > tile.maxY) tile.maxY = maxY;
}

@@ -40,9 +44,8 @@ return tile;

type = feature.type,
simplified = [],
sqTolerance = tolerance * tolerance,
i, j, ring, p;
simplified = [];
if (type === 1) {
for (i = 0; i < geom.length; i++) {
if (type === 'Point' || type === 'MultiPoint') {
for (var i = 0; i < geom.length; i += 3) {
simplified.push(geom[i]);
simplified.push(geom[i + 1]);
tile.numPoints++;

@@ -52,30 +55,17 @@ tile.numSimplified++;

} else {
} else if (type === 'LineString') {
addLine(simplified, geom, tile, tolerance, noSimplify, false, false);
// simplify and transform projected coordinates for tile geometry
} else if (type === 'MultiLineString' || type === 'Polygon') {
for (i = 0; i < geom.length; i++) {
ring = geom[i];
addLine(simplified, geom[i], tile, tolerance, noSimplify, type === 'Polygon', i === 0);
}
// filter out tiny polylines & polygons
if (!noSimplify && ((type === 2 && ring.dist < tolerance) ||
(type === 3 && ring.area < sqTolerance))) {
tile.numPoints += ring.length;
continue;
}
} else if (type === 'MultiPolygon') {
var simplifiedRing = [];
for (j = 0; j < ring.length; j++) {
p = ring[j];
// keep points with importance > tolerance
if (noSimplify || p[2] > sqTolerance) {
simplifiedRing.push(p);
tile.numSimplified++;
}
tile.numPoints++;
for (var k = 0; k < geom.length; k++) {
var polygon = geom[k];
for (i = 0; i < polygon.length; i++) {
addLine(simplified, polygon[i], tile, tolerance, noSimplify, true, i === 0);
}
if (type === 3) rewind(simplifiedRing, ring.outer);
simplified.push(simplifiedRing);
}

@@ -87,3 +77,4 @@ }

geometry: simplified,
type: type,
type: type === 'Polygon' || type === 'MultiPolygon' ? 3 :
type === 'LineString' || type === 'MultiLineString' ? 2 : 1,
tags: feature.tags || null

@@ -98,15 +89,41 @@ };

function rewind(ring, clockwise) {
var area = signedArea(ring);
if (area < 0 === clockwise) ring.reverse();
function addLine(result, geom, tile, tolerance, noSimplify, isPolygon, isOuter) {
var sqTolerance = tolerance * tolerance;
if (!noSimplify && (geom.size < (isPolygon ? sqTolerance : tolerance))) {
tile.numPoints += geom.length / 3;
return;
}
var ring = [];
for (var i = 0; i < geom.length; i += 3) {
if (noSimplify || geom[i + 2] > sqTolerance) {
tile.numSimplified++;
ring.push(geom[i]);
ring.push(geom[i + 1]);
}
tile.numPoints++;
}
if (isPolygon) rewind(ring, isOuter);
result.push(ring);
}
function signedArea(ring) {
var sum = 0;
for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
p1 = ring[i];
p2 = ring[j];
sum += (p2[0] - p1[0]) * (p1[1] + p2[1]);
function rewind(ring, clockwise) {
var area = 0;
for (var i = 0, len = ring.length, j = len - 2; i < len; j = i, i += 2) {
area += (ring[i] - ring[j]) * (ring[i + 1] + ring[j + 1]);
}
return sum;
if (area > 0 === clockwise) {
for (i = 0, len = ring.length; i < len / 2; i += 2) {
var x = ring[i];
var y = ring[i + 1];
ring[i] = ring[len - 2 - i];
ring[i + 1] = ring[len - 1 - i];
ring[len - 2 - i] = x;
ring[len - 1 - i] = y;
}
}
}

@@ -21,9 +21,15 @@ 'use strict';

feature.geometry = [];
if (type === 1) {
for (j = 0; j < geom.length; j++) geom[j] = transformPoint(geom[j], extent, z2, tx, ty);
for (j = 0; j < geom.length; j += 2) {
feature.geometry.push(transformPoint(geom[j], geom[j + 1], extent, z2, tx, ty));
}
} else {
for (j = 0; j < geom.length; j++) {
var ring = geom[j];
for (k = 0; k < ring.length; k++) ring[k] = transformPoint(ring[k], extent, z2, tx, ty);
var ring = [];
for (k = 0; k < geom[j].length; k += 2) {
ring.push(transformPoint(geom[j][k], geom[j][k + 1], extent, z2, tx, ty));
}
feature.geometry.push(ring);
}

@@ -38,6 +44,6 @@ }

function transformPoint(p, extent, z2, tx, ty) {
var x = Math.round(extent * (p[0] * z2 - tx)),
y = Math.round(extent * (p[1] * z2 - ty));
return [x, y];
function transformPoint(x, y, extent, z2, tx, ty) {
return [
Math.round(extent * (x * z2 - tx)),
Math.round(extent * (y * z2 - ty))];
}

@@ -8,9 +8,9 @@ 'use strict';

function wrap(features, buffer, intersectX) {
function wrap(features, buffer) {
var merged = features,
left = clip(features, 1, -1 - buffer, buffer, 0, intersectX, -1, 2), // left world copy
right = clip(features, 1, 1 - buffer, 2 + buffer, 0, intersectX, -1, 2); // right world copy
left = clip(features, 1, -1 - buffer, buffer, 0, -1, 2), // left world copy
right = clip(features, 1, 1 - buffer, 2 + buffer, 0, -1, 2); // right world copy
if (left || right) {
merged = clip(features, 1, -buffer, 1 + buffer, 0, intersectX, -1, 2) || []; // center world copy
merged = clip(features, 1, -buffer, 1 + buffer, 0, -1, 2) || []; // center world copy

@@ -33,5 +33,6 @@ if (left) merged = shiftFeatureCoords(left, 1).concat(merged); // merge left into center

if (type === 1) {
if (type === 'Point' || type === 'MultiPoint' || type === 'LineString') {
newGeometry = shiftCoords(feature.geometry, offset);
} else {
} else if (type === 'MultiLineString' || type === 'Polygon') {
newGeometry = [];

@@ -41,5 +42,14 @@ for (var j = 0; j < feature.geometry.length; j++) {

}
} else if (type === 'MultiPolygon') {
newGeometry = [];
for (j = 0; j < feature.geometry.length; j++) {
var newPolygon = [];
for (var k = 0; k < feature.geometry[j].length; k++) {
newPolygon.push(shiftCoords(feature.geometry[j][k], offset));
}
newGeometry.push(newPolygon);
}
}
newFeatures.push(createFeature(feature.tags, type, newGeometry, feature.id));
newFeatures.push(createFeature(feature.id, type, newGeometry, feature.tags));
}

@@ -52,9 +62,8 @@

var newPoints = [];
newPoints.area = points.area;
newPoints.dist = points.dist;
newPoints.size = points.size;
for (var i = 0; i < points.length; i++) {
newPoints.push([points[i][0] + offset, points[i][1], points[i][2]]);
for (var i = 0; i < points.length; i += 3) {
newPoints.push(points[i] + offset, points[i + 1], points[i + 2]);
}
return newPoints;
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc