From d754a7fdc7fe99193e69f842951d4be847b9940d Mon Sep 17 00:00:00 2001 From: Sajjad Anwar Date: Wed, 13 Mar 2019 17:13:30 +0530 Subject: [PATCH 01/14] add option to get way node refs in the geojson --- README.md | 1 + index.js | 9 ++++++++- test/osm.test.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b43f75..a92921f 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Converts OSM data into GeoJSON. * `data`: the OSM data. Either as a XML DOM or in [OSM JSON](http://overpass-api.de/output_formats.html#json). * `options`: optional. The following options can be used: * `flatProperties`: If true, the resulting GeoJSON feature's properties will be a simple key-value list instead of a structured json object (with separate tags and metadata). default: false + * `wayRefs`: If true, the GeoJSON will have a `ndrefs` property, which is an array of all the node members of the `way`. default: false * `uninterestingTags`: Either a [blacklist](https://github.com/tyrasd/osmtogeojson/blob/2.0.0/index.js#L14-L24) of tag keys or a callback function. Will be used to decide if a feature is *interesting* enough for its own GeoJSON feature. * `polygonFeatures`: Either a [json object](https://github.com/tyrasd/osmtogeojson/blob/2.0.0/polygon_features.json) or callback function that is used to determine if a closed way should be treated as a Polygon or LineString. [read more](https://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features) diff --git a/index.js b/index.js index 17d18d7..2fd96c7 100644 --- a/index.js +++ b/index.js @@ -37,6 +37,7 @@ osmtogeojson = function( data, options, featureCallback ) { { verbose: false, flatProperties: true, + wayRefs: false, uninterestingTags: { "source": true, "source_ref": true, @@ -455,7 +456,6 @@ osmtogeojson = function( data, options, featureCallback ) { return _convert2geoJSON(nodes,ways,rels); } function _convert2geoJSON(nodes,ways,rels) { - // helper function that checks if there are any tags other than "created_by", "source", etc. or any tag provided in ignore_tags function has_interesting_tags(t, ignore_tags) { if (typeof ignore_tags !== "object") @@ -510,12 +510,14 @@ osmtogeojson = function( data, options, featureCallback ) { var waynids = new Object(); for (var i=0;i Date: Wed, 13 Mar 2019 18:05:54 +0530 Subject: [PATCH 02/14] package. add tinyify dependency --- osmtogeojson.js | 3 +-- package.json | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osmtogeojson.js b/osmtogeojson.js index bce35b9..8454909 100644 --- a/osmtogeojson.js +++ b/osmtogeojson.js @@ -1,2 +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.osmtogeojson=e()}}(function(){return function e(t,n,r){function o(i,u){if(!n[i]){if(!t[i]){var s="function"==typeof require&&require;if(!u&&s)return s(i,!0);if(a)return a(i,!0);var l=new Error("Cannot find module '"+i+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[i]={exports:{}};t[i][0].call(c.exports,function(e){var n=t[i][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;i(t.version||0)?e:t:o.merge(e,t)}var o=e("./lodash.custom.js"),a=e("geojson-rewind"),i={};e("osm-polygon-features").forEach(function(e){if("all"===e.polygon)i[e.key]=!0;else{var t="whitelist"===e.polygon?"included_values":"excluded_values",n={};e.values.forEach(function(e){n[e]=!0}),i[e.key]={},i[e.key][t]=n}});var u={};u=function(e,t){function n(e){function t(e){var t=o.clone(e);t.lat=e.center.lat,t.lon=e.center.lon,t.__is_center_placeholder=!0,i.push(t)}function n(e){function t(e,t,r){var o={type:"node",id:"_"+n.type+"/"+n.id+"bounds"+r,lat:e,lon:t};n.nodes.push(o.id),i.push(o)}var n=o.clone(e);n.nodes=[],t(n.bounds.minlat,n.bounds.minlon,1),t(n.bounds.maxlat,n.bounds.minlon,2),t(n.bounds.maxlat,n.bounds.maxlon,3),t(n.bounds.minlat,n.bounds.maxlon,4),n.nodes.push(n.nodes[0]),n.__is_bounds_placeholder=!0,u.push(n)}function r(e){function t(e,t,n){var r={type:"node",id:n,lat:e,lon:t};i.push(r)}o.isArray(e.nodes)||(e.nodes=e.geometry.map(function(e){return null!==e?"_anonymous@"+e.lat+"/"+e.lon:"_anonymous@unknown_location"})),e.geometry.forEach(function(n,r){n&&t(n.lat,n.lon,e.nodes[r])})}function a(e){function t(e,t,n){var r={type:"node",id:n,lat:e,lon:t};i.push(r)}function n(e,t){function n(e,t){var n={type:"node",id:"_anonymous@"+e+"/"+t,lat:e,lon:t};r.nodes.push(n.id),i.push(n)}if(!u.some(function(e){return"way"==e.type&&e.id==t})){var r={type:"way",id:t,nodes:[]};e.forEach(function(e){e?n(e.lat,e.lon):r.nodes.push(void 0)}),u.push(r)}}e.members.forEach(function(e,r){"node"==e.type?e.lat&&t(e.lat,e.lon,e.ref):"way"==e.type&&e.geometry&&(e.ref="_fullGeom"+e.ref,n(e.geometry,e.ref))})}for(var i=new Array,u=new Array,l=new Array,c=0;c0});y.center&&t(y),d?a(y):y.bounds&&n(y)}return s(i,u,l)}function u(e){function t(e,t,n){e.hasAttribute(n)&&(t[n]=e.getAttribute(n))}function n(e,n){var r=o.clone(e);t(n,r,"lat"),t(n,r,"lon"),r.__is_center_placeholder=!0,u.push(r)}function r(e,t){function n(e,t,n){var o={type:"node",id:"_"+r.type+"/"+r.id+"bounds"+n,lat:e,lon:t};r.nodes.push(o.id),u.push(o)}var r=o.clone(e);r.nodes=[],n(t.getAttribute("minlat"),t.getAttribute("minlon"),1),n(t.getAttribute("maxlat"),t.getAttribute("minlon"),2),n(t.getAttribute("maxlat"),t.getAttribute("maxlon"),3),n(t.getAttribute("minlat"),t.getAttribute("maxlon"),4),r.nodes.push(r.nodes[0]),r.__is_bounds_placeholder=!0,l.push(r)}function a(e,t){function n(e,t,n){var r={type:"node",id:n,lat:e,lon:t};return u.push(r),r.id}o.isArray(e.nodes)||(e.nodes=[],o.each(t,function(t,n){e.nodes.push("_anonymous@"+t.getAttribute("lat")+"/"+t.getAttribute("lon"))})),o.each(t,function(t,r){t.getAttribute("lat")&&n(t.getAttribute("lat"),t.getAttribute("lon"),e.nodes[r])})}function i(e,t){function n(e,t,n){var r={type:"node",id:n,lat:e,lon:t};u.push(r)}function r(e,t){function n(e,t){var n={type:"node",id:"_anonymous@"+e+"/"+t,lat:e,lon:t};r.nodes.push(n.id),u.push(n)}if(!l.some(function(e){return"way"==e.type&&e.id==t})){var r={type:"way",id:t,nodes:[]};o.each(e,function(e){e.getAttribute("lat")?n(e.getAttribute("lat"),e.getAttribute("lon")):r.nodes.push(void 0)}),l.push(r)}}o.each(t,function(t,o){"node"==e.members[o].type?t.getAttribute("lat")&&n(t.getAttribute("lat"),t.getAttribute("lon"),e.members[o].ref):"way"==e.members[o].type&&t.getElementsByTagName("nd").length>0&&(e.members[o].ref="_fullGeom"+e.members[o].ref,r(t.getElementsByTagName("nd"),e.members[o].ref))})}var u=new Array,l=new Array,c=new Array;o.each(e.getElementsByTagName("node"),function(e,n){var r={};o.each(e.getElementsByTagName("tag"),function(e){r[e.getAttribute("k")]=e.getAttribute("v")});var a={type:"node"};t(e,a,"id"),t(e,a,"lat"),t(e,a,"lon"),t(e,a,"version"),t(e,a,"timestamp"),t(e,a,"changeset"),t(e,a,"uid"),t(e,a,"user"),o.isEmpty(r)||(a.tags=r),u.push(a)});var f,p;return o.each(e.getElementsByTagName("way"),function(e,i){var u={},s=[];o.each(e.getElementsByTagName("tag"),function(e){u[e.getAttribute("k")]=e.getAttribute("v")});var c=!1;o.each(e.getElementsByTagName("nd"),function(e,t){var n;(n=e.getAttribute("ref"))&&(s[t]=n),!c&&e.getAttribute("lat")&&(c=!0)});var y={type:"way"};t(e,y,"id"),t(e,y,"version"),t(e,y,"timestamp"),t(e,y,"changeset"),t(e,y,"uid"),t(e,y,"user"),s.length>0&&(y.nodes=s),o.isEmpty(u)||(y.tags=u),(f=e.getElementsByTagName("center")[0])&&n(y,f),c?a(y,e.getElementsByTagName("nd")):(p=e.getElementsByTagName("bounds")[0])&&r(y,p),l.push(y)}),o.each(e.getElementsByTagName("relation"),function(e,a){var u={},s=[];o.each(e.getElementsByTagName("tag"),function(e){u[e.getAttribute("k")]=e.getAttribute("v")});var l=!1;o.each(e.getElementsByTagName("member"),function(e,n){s[n]={},t(e,s[n],"ref"),t(e,s[n],"role"),t(e,s[n],"type"),(!l&&"node"==s[n].type&&e.getAttribute("lat")||"way"==s[n].type&&e.getElementsByTagName("nd").length>0)&&(l=!0)});var y={type:"relation"};t(e,y,"id"),t(e,y,"version"),t(e,y,"timestamp"),t(e,y,"changeset"),t(e,y,"uid"),t(e,y,"user"),s.length>0&&(y.members=s),o.isEmpty(u)||(y.tags=u),(f=e.getElementsByTagName("center")[0])&&n(y,f),l?i(y,e.getElementsByTagName("member")):(p=e.getElementsByTagName("bounds")[0])&&r(y,p),c.push(y)}),s(u,l,c)}function s(e,n,r){function i(e,n){if("object"!=typeof n&&(n={}),"function"==typeof t.uninterestingTags)return!t.uninterestingTags(e,n);for(var r in e)if(t.uninterestingTags[r]!==!0&&n[r]!==!0&&n[r]!==e[r])return!0;return!1}function u(e){var t={timestamp:e.timestamp,version:e.version,changeset:e.changeset,user:e.user,uid:e.uid};for(var n in t)void 0===t[n]&&delete t[n];return t}function s(e,n){function r(e){for(var n,r,o,a,i,u,s=function(e){return e[0]},f=function(e){return e[e.length-1]},p=[];e.length;)for(n=e.pop().nodes.slice(),p.push(n);e.length&&s(n)!==f(n);){for(r=s(n),o=f(n),a=0;ar!=c>r&&n<(l-u)*(r-s)/(c-s)+u;f&&(o=!o)}return o};for(e=o(e),t=0;t-1}function N(e,t){var n=this.__data__,r=J(n,e);return r<0?n.push([e,t]):n[r][1]=t,this}function P(e){var t=-1,n=e?e.length:0;for(this.clear();++t1?n[o-1]:Tt,i=o>2?n[2]:Tt;for(a=e.length>3&&"function"==typeof a?(o--,a):Tt,i&&Xe(n[0],n[1],i)&&(a=o<3?Tt:a,o=1),t=Object(t);++ru))return!1;var c=a.get(e);if(c&&a.get(t))return c==t;var f=-1,p=!0,y=o&St?new D:Tt;for(a.set(e,t),a.set(t,e);++f-1&&e%1==0&&e-1&&e%1==0&&e<=Dt}function dt(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function gt(e){return!!e&&"object"==typeof e}function vt(e){if(!gt(e)||$n.call(e)!=Xt||d(e))return!1;var t=qn(e);if(null===t)return!0;var n=Rn.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&Dn.call(n)==Un}function ht(e){return"symbol"==typeof e||gt(e)&&$n.call(e)==Yt}function bt(e){return Te(e,jt(e))}function mt(e){return null==e?"":be(e)}function _t(e,t,n){var r=null==e?Tt:ee(e,t);return r===Tt?n:r}function wt(e,t){return null!=e&&Ge(e,t,re)}function At(e){return lt(e)?V(e):ce(e)}function jt(e){return lt(e)?V(e,!0):fe(e)}function kt(e){return e}function Ot(e){return le("function"==typeof e?e:Q(e,!0))}function Et(e){return He(e)?c(tt(e)):ve(e)}function xt(){return[]}function Mt(){return!1}var Tt,Nt="4.15.0",Pt=200,Bt="Expected a function",Ft="__lodash_hash_undefined__",St=1,Lt=2,It=1/0,Dt=9007199254740991,Rt="[object Arguments]",Ut="[object Array]",$t="[object Boolean]",Ct="[object Date]",Gt="[object Error]",zt="[object Function]",Wt="[object GeneratorFunction]",qt="[object Map]",Vt="[object Number]",Xt="[object Object]",Ht="[object Promise]",Jt="[object RegExp]",Kt="[object Set]",Qt="[object String]",Yt="[object Symbol]",Zt="[object WeakMap]",en="[object ArrayBuffer]",tn="[object DataView]",nn="[object Float32Array]",rn="[object Float64Array]",on="[object Int8Array]",an="[object Int16Array]",un="[object Int32Array]",sn="[object Uint8Array]",ln="[object Uint8ClampedArray]",cn="[object Uint16Array]",fn="[object Uint32Array]",pn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,yn=/^\w*$/,dn=/^\./,gn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,vn=/[\\^$.*+?()[\]{}|]/g,hn=/\\(\\)?/g,bn=/\w*$/,mn=/^\[object .+?Constructor\]$/,_n=/^(?:0|[1-9]\d*)$/,wn={};wn[nn]=wn[rn]=wn[on]=wn[an]=wn[un]=wn[sn]=wn[ln]=wn[cn]=wn[fn]=!0,wn[Rt]=wn[Ut]=wn[en]=wn[$t]=wn[tn]=wn[Ct]=wn[Gt]=wn[zt]=wn[qt]=wn[Vt]=wn[Xt]=wn[Jt]=wn[Kt]=wn[Qt]=wn[Zt]=!1;var An={};An[Rt]=An[Ut]=An[en]=An[tn]=An[$t]=An[Ct]=An[nn]=An[rn]=An[on]=An[an]=An[un]=An[qt]=An[Vt]=An[Xt]=An[Jt]=An[Kt]=An[Qt]=An[Yt]=An[sn]=An[ln]=An[cn]=An[fn]=!0,An[Gt]=An[zt]=An[Zt]=!1;var jn="object"==typeof e&&e&&e.Object===Object&&e,kn="object"==typeof self&&self&&self.Object===Object&&self,On=jn||kn||Function("return this")(),En="object"==typeof n&&n&&!n.nodeType&&n,xn=En&&"object"==typeof t&&t&&!t.nodeType&&t,Mn=xn&&xn.exports===En,Tn=Mn&&jn.process,Nn=function(){try{return Tn&&Tn.binding("util")}catch(e){}}(),Pn=Nn&&Nn.isTypedArray,Bn=Array.prototype,Fn=Function.prototype,Sn=Object.prototype,Ln=On["__core-js_shared__"],In=function(){var e=/[^.]+$/.exec(Ln&&Ln.keys&&Ln.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}(),Dn=Fn.toString,Rn=Sn.hasOwnProperty,Un=Dn.call(Object),$n=Sn.toString,Cn=RegExp("^"+Dn.call(Rn).replace(vn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Gn=Mn?On.Buffer:Tt,zn=On.Symbol,Wn=On.Uint8Array,qn=v(Object.getPrototypeOf,Object),Vn=Object.create,Xn=Sn.propertyIsEnumerable,Hn=Bn.splice,Jn=Object.getOwnPropertySymbols,Kn=Gn?Gn.isBuffer:Tt,Qn=v(Object.keys,Object),Yn=Math.max,Zn=Ce(On,"DataView"),er=Ce(On,"Map"),tr=Ce(On,"Promise"),nr=Ce(On,"Set"),rr=Ce(On,"WeakMap"),or=Ce(Object,"create"),ar=!Xn.call({valueOf:1},"valueOf"),ir=nt(Zn),ur=nt(er),sr=nt(tr),lr=nt(nr),cr=nt(rr),fr=zn?zn.prototype:Tt,pr=fr?fr.valueOf:Tt,yr=fr?fr.toString:Tt;m.prototype.clear=_,m.prototype.delete=w,m.prototype.get=A,m.prototype.has=j,m.prototype.set=k,O.prototype.clear=E,O.prototype.delete=x,O.prototype.get=M,O.prototype.has=T,O.prototype.set=N,P.prototype.clear=B,P.prototype.delete=F,P.prototype.get=S,P.prototype.has=L,P.prototype.set=I,D.prototype.add=D.prototype.push=R,D.prototype.has=U,$.prototype.clear=C,$.prototype.delete=G,$.prototype.get=z,$.prototype.has=W,$.prototype.set=q;var dr=Be(Z),gr=Fe(),vr=Jn?v(Jn,Object):xt,hr=ne;(Zn&&hr(new Zn(new ArrayBuffer(1)))!=tn||er&&hr(new er)!=qt||tr&&hr(tr.resolve())!=Ht||nr&&hr(new nr)!=Kt||rr&&hr(new rr)!=Zt)&&(hr=function(e){var t=$n.call(e),n=t==Xt?e.constructor:Tt,r=n?nt(n):Tt;if(r)switch(r){case ir:return tn;case ur:return qt;case sr:return Ht; -case lr:return Kt;case cr:return Zt}return t});var br=at(function(e){e=mt(e);var t=[];return dn.test(e)&&t.push(""),e.replace(gn,function(e,n,r,o){t.push(r?o.replace(hn,"$1"):n||e)}),t});at.Cache=P;var mr=Array.isArray,_r=Kn||Mt,wr=Pn?p(Pn):se,Ar=Pe(function(e,t,n){de(e,t,n)});b.compact=rt,b.iteratee=Ot,b.keys=At,b.keysIn=jt,b.memoize=at,b.merge=Ar,b.property=Et,b.toPlainObject=bt,b.clone=it,b.eq=ut,b.forEach=ot,b.get=_t,b.hasIn=wt,b.identity=kt,b.isArguments=st,b.isArray=mr,b.isArrayLike=lt,b.isArrayLikeObject=ct,b.isBuffer=_r,b.isEmpty=ft,b.isFunction=pt,b.isLength=yt,b.isObject=dt,b.isObjectLike=gt,b.isPlainObject=vt,b.isSymbol=ht,b.isTypedArray=wr,b.stubArray=xt,b.stubFalse=Mt,b.toString=mt,b.each=ot,b.VERSION=Nt,xn&&((xn.exports=b)._=b,En._=b)}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(e,t,n){function r(e,t){switch(e&&e.type||null){case"FeatureCollection":return e.features=e.features.map(o(r,t)),e;case"Feature":return e.geometry=r(e.geometry,t),e;case"Polygon":case"MultiPolygon":return a(e,t);default:return e}}function o(e,t){return function(n){return e(n,t)}}function a(e,t){return"Polygon"===e.type?e.coordinates=i(e.coordinates,t):"MultiPolygon"===e.type&&(e.coordinates=e.coordinates.map(o(i,t))),e}function i(e,t){t=!!t,e[0]=u(e[0],!t);for(var n=1;n=0}var l=e("geojson-area");t.exports=r},{"geojson-area":4}],4:[function(e,t,n){function r(e){if("Polygon"===e.type)return o(e.coordinates);if("MultiPolygon"===e.type){for(var t=0,n=0;n0){t+=Math.abs(a(e[0]));for(var n=1;n2){for(var n,r,o=0;o-1},qe.prototype.set=function(e,t){var n=this.__data__,r=et(n,e);return r<0?n.push([e,t]):n[r][1]=t,this},He.prototype.clear=function(){this.__data__={hash:new Xe,map:new(Pe||qe),string:new Xe}},He.prototype.delete=function(e){return ht(this,e).delete(e)},He.prototype.get=function(e){return ht(this,e).get(e)},He.prototype.has=function(e){return ht(this,e).has(e)},He.prototype.set=function(e,t){return ht(this,e).set(e,t),this},Je.prototype.add=Je.prototype.push=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this},Je.prototype.has=function(e){return this.__data__.has(e)},Ke.prototype.clear=function(){this.__data__=new qe},Ke.prototype.delete=function(e){return this.__data__.delete(e)},Ke.prototype.get=function(e){return this.__data__.get(e)},Ke.prototype.has=function(e){return this.__data__.has(e)},Ke.prototype.set=function(e,t){var n=this.__data__;if(n instanceof qe){var r=n.__data__;if(!Pe||r.length<199)return r.push([e,t]),this;n=this.__data__=new He(r)}return n.set(e,t),this};var nt,rt=(nt=function(e,t){return e&&ot(e,t,Jt)},function(e,t){if(null==e)return e;if(!Ft(e))return nt(e,t);for(var n=e.length,r=-1,o=Object(e);++rc))return!1;var p=s.get(e);if(p&&s.get(t))return p==t;var y=-1,d=!0,g=u&o?new Je:n;for(s.set(e,t),s.set(t,e);++y-1&&e%1==0&&e-1&&e%1==0&&e<=u}function Dt(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function Ut(e){return!!e&&"object"==typeof e}function Gt(e){if(!Ut(e)||he.call(e)!=h||oe(e))return!1;var t=Ae(e);if(null===t)return!0;var n=ge.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&de.call(n)==ve}function zt(e){return"symbol"==typeof e||Ut(e)&&he.call(e)==w}var Ct,Wt=Y?(Ct=Y,function(e){return Ct(e)}):function(e){return Ut(e)&&$t(e.length)&&!!z[he.call(e)]};function Vt(e){return dt(e,Kt(e))}function Xt(e){return null==e?"":function(e){if("string"==typeof e)return e;if(zt(e))return We?We.call(e):"";var t=e+"";return"0"==t&&1/e==-a?"-0":t}(e)}function qt(e,t,r){var o=null==e?n:it(e,t);return o===n?r:o}function Ht(e,t){return null!=e&&function(e,t,n){for(var r,o=-1,i=(t=At(t,e)?[t]:ft(t)).length;++o1?r[i-1]:n,u=i>2?r[2]:n;for(a=e.length>3&&"function"==typeof a?(i--,a):n,u&&function(e,t,n){if(!Dt(n))return!1;var r=typeof t;return!!("number"==r?Ft(n)&&wt(t,n.length):"string"==r&&t in n)&&Pt(n[t],e)}(r[0],r[1],u)&&(a=i<3?n:a,i=1),t=Object(t);++o2){for(s=0;s=0}(e)===t?e:e.reverse()}n.ring=r;var s,l=function e(t,n){switch(t&&t.type||null){case"FeatureCollection":return t.features=t.features.map(i(e,n)),t;case"Feature":return t.geometry=e(t.geometry,n),t;case"Polygon":case"MultiPolygon":return function(e,t){return"Polygon"===e.type?e.coordinates=a(e.coordinates,t):"MultiPolygon"===e.type&&(e.coordinates=e.coordinates.map(i(a,t))),e}(t,n);default:return t}},c={};function f(t,n){return(t.version||n.version)&&t.version!==n.version?(+t.version||0)>(+n.version||0)?t:n:e.merge(t,n)}function p(e){for(var t,n,r,o,i,a,u=function(e){return e[0]},s=function(e){return e[e.length-1]},l=function(e,t){return void 0!==e&&void 0!==t&&e.id===t.id},c=[];e.length;)for(t=e.pop().nodes.slice(),c.push(t);e.length&&!l(u(t),s(t));){for(n=u(t),r=s(t),o=0;o0&&(y.nodes=f),e.isEmpty(u)||(y.tags=u),(n=t.getElementsByTagName("center")[0])&&l(y,n),p?function(t,n){e.isArray(t.nodes)||(t.nodes=[],e.each(n,function(e,n){t.nodes.push("_anonymous@"+e.getAttribute("lat")+"/"+e.getAttribute("lon"))})),e.each(n,function(e,n){var r,o,a;e.getAttribute("lat")&&(r=e.getAttribute("lat"),o=e.getAttribute("lon"),a={type:"node",id:t.nodes[n],lat:r,lon:o},i.push(a))})}(y,t.getElementsByTagName("nd")):(r=t.getElementsByTagName("bounds")[0])&&c(y,r),a.push(y)}),e.each(t.getElementsByTagName("relation"),function(t,o){var f={},p=[];e.each(t.getElementsByTagName("tag"),function(e){f[e.getAttribute("k")]=e.getAttribute("v")});var y=!1;e.each(t.getElementsByTagName("member"),function(e,t){p[t]={},s(e,p[t],"ref"),s(e,p[t],"role"),s(e,p[t],"type"),(!y&&"node"==p[t].type&&e.getAttribute("lat")||"way"==p[t].type&&e.getElementsByTagName("nd").length>0)&&(y=!0)});var d={type:"relation"};s(t,d,"id"),s(t,d,"version"),s(t,d,"timestamp"),s(t,d,"changeset"),s(t,d,"uid"),s(t,d,"user"),p.length>0&&(d.members=p),e.isEmpty(f)||(d.tags=f),(n=t.getElementsByTagName("center")[0])&&l(d,n),y?function(t,n){e.each(n,function(n,r){var o,u,s;"node"==t.members[r].type?n.getAttribute("lat")&&(o=n.getAttribute("lat"),u=n.getAttribute("lon"),s={type:"node",id:t.members[r].ref,lat:o,lon:u},i.push(s)):"way"==t.members[r].type&&n.getElementsByTagName("nd").length>0&&(t.members[r].ref="_fullGeom"+t.members[r].ref,function(t,n){if(!a.some(function(e){return"way"==e.type&&e.id==n})){var r={type:"way",id:n,nodes:[]};e.each(t,function(e){var t,n,o;e.getAttribute("lat")?(o={type:"node",id:"_anonymous@"+(t=e.getAttribute("lat"))+"/"+(n=e.getAttribute("lon")),lat:t,lon:n},r.nodes.push(o.id),i.push(o)):r.nodes.push(void 0)}),a.push(r)}}(n.getElementsByTagName("nd"),t.members[r].ref))})}(d,t.getElementsByTagName("member")):(r=t.getElementsByTagName("bounds")[0])&&c(d,r),u.push(d)}),o(i,a,u)}(t):function(t){var n=new Array,r=new Array,i=new Array;function a(t){var r=e.clone(t);r.lat=t.center.lat,r.lon=t.center.lon,r.__is_center_placeholder=!0,n.push(r)}function u(t){var o=e.clone(t);function i(e,t,r){var i={type:"node",id:"_"+o.type+"/"+o.id+"bounds"+r,lat:e,lon:t};o.nodes.push(i.id),n.push(i)}o.nodes=[],i(o.bounds.minlat,o.bounds.minlon,1),i(o.bounds.maxlat,o.bounds.minlon,2),i(o.bounds.maxlat,o.bounds.maxlon,3),i(o.bounds.minlat,o.bounds.maxlon,4),o.nodes.push(o.nodes[0]),o.__is_bounds_placeholder=!0,r.push(o)}function s(t){e.isArray(t.nodes)||(t.nodes=t.geometry.map(function(e){return null!==e?"_anonymous@"+e.lat+"/"+e.lon:"_anonymous@unknown_location"})),t.geometry.forEach(function(e,r){var o,i,a;e&&(o=e.lat,i=e.lon,a={type:"node",id:t.nodes[r],lat:o,lon:i},n.push(a))})}function l(e){e.members.forEach(function(e,t){var o,i,a;"node"==e.type?e.lat&&(o=e.lat,i=e.lon,a={type:"node",id:e.ref,lat:o,lon:i},n.push(a)):"way"==e.type&&e.geometry&&(e.ref="_fullGeom"+e.ref,function(e,t){if(!r.some(function(e){return"way"==e.type&&e.id==t})){var o={type:"way",id:t,nodes:[]};e.forEach(function(e){var t,r,i;e?(i={type:"node",id:"_anonymous@"+(t=e.lat)+"/"+(r=e.lon),lat:t,lon:r},o.nodes.push(i.id),n.push(i)):o.nodes.push(void 0)}),r.push(o)}}(e.geometry,e.ref))})}for(var c=0;c0});y.center&&a(y),d?l(y):y.bounds&&u(y)}return o(n,r,i)}(t);function o(t,o,a){function u(e,t){if("object"!=typeof t&&(t={}),"function"==typeof n.uninterestingTags)return!n.uninterestingTags(e,t);for(var r in e)if(!0!==n.uninterestingTags[r]&&!0!==t[r]&&t[r]!==e[r])return!0;return!1}function s(e){var t={timestamp:e.timestamp,version:e.version,changeset:e.changeset,user:e.user,uid:e.uid};for(var n in t)void 0===t[n]&&delete t[n];return t}for(var c=new Object,f=new Object,y=0;yr!=c>r&&n<(l-u)*(r-s)/(c-s)+u&&(o=!o)}return o};for(e=r(e),t=0;t=0.5" From a98b344b1267656a870bcca4f513a86642af25e3 Mon Sep 17 00:00:00 2001 From: Sajjad Anwar Date: Wed, 13 Mar 2019 19:12:08 +0530 Subject: [PATCH 03/14] make ndrefs part of meta, add another test for wayRefs with flatProperties --- index.js | 9 +++------ test/osm.test.js | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 2fd96c7..1f1e905 100644 --- a/index.js +++ b/index.js @@ -475,7 +475,8 @@ osmtogeojson = function( data, options, featureCallback ) { "version": object.version, "changeset": object.changeset, "user": object.user, - "uid": object.uid + "uid": object.uid, + "ndrefs": object.hasOwnProperty('ndrefs') && options.wayRefs ? object.ndrefs : undefined }; for (var k in res) if (res[k] === undefined) @@ -517,7 +518,7 @@ osmtogeojson = function( data, options, featureCallback ) { } wayids[way.id] = way; if (_.isArray(way.nodes)) { - way.ndrefs = Object.assign([], way.nodes) + way.ndrefs = Object.assign([], way.nodes); for (var j=0;j Date: Wed, 13 Mar 2019 19:12:33 +0530 Subject: [PATCH 04/14] build --- osmtogeojson.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osmtogeojson.js b/osmtogeojson.js index 8454909..eb01058 100644 --- a/osmtogeojson.js +++ b/osmtogeojson.js @@ -1 +1 @@ -!function(){var e={exports:{}};(function(t){(function(){var n,r="Expected a function",o=1,i=2,a=1/0,u=9007199254740991,s="[object Arguments]",l="[object Array]",c="[object Boolean]",f="[object Date]",p="[object Error]",y="[object Function]",d="[object GeneratorFunction]",g="[object Map]",v="[object Number]",h="[object Object]",b="[object RegExp]",m="[object Set]",_="[object String]",w="[object Symbol]",A="[object WeakMap]",j="[object ArrayBuffer]",k="[object DataView]",O="[object Float32Array]",E="[object Float64Array]",x="[object Int8Array]",T="[object Int16Array]",M="[object Int32Array]",B="[object Uint8Array]",P="[object Uint8ClampedArray]",S="[object Uint16Array]",N="[object Uint32Array]",F=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,L=/^\w*$/,R=/^\./,I=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,$=/\\(\\)?/g,D=/\w*$/,U=/^\[object .+?Constructor\]$/,G=/^(?:0|[1-9]\d*)$/,z={};z[O]=z[E]=z[x]=z[T]=z[M]=z[B]=z[P]=z[S]=z[N]=!0,z[s]=z[l]=z[j]=z[c]=z[k]=z[f]=z[p]=z[y]=z[g]=z[v]=z[h]=z[b]=z[m]=z[_]=z[A]=!1;var C={};C[s]=C[l]=C[j]=C[k]=C[c]=C[f]=C[O]=C[E]=C[x]=C[T]=C[M]=C[g]=C[v]=C[h]=C[b]=C[m]=C[_]=C[w]=C[B]=C[P]=C[S]=C[N]=!0,C[p]=C[y]=C[A]=!1;var W="object"==typeof t&&t&&t.Object===Object&&t,V="object"==typeof self&&self&&self.Object===Object&&self,X=W||V||Function("return this")(),q="object"==typeof e.exports&&e.exports&&!e.exports.nodeType&&e.exports,H=q&&e&&!e.nodeType&&e,J=H&&H.exports===q,K=J&&W.process,Q=function(){try{return K&&K.binding("util")}catch(e){}}(),Y=Q&&Q.isTypedArray;function Z(e,t){return e.set(t[0],t[1]),e}function ee(e,t){return e.add(t),e}function te(e,t){for(var n=-1,r=e?e.length:0;++n-1},qe.prototype.set=function(e,t){var n=this.__data__,r=et(n,e);return r<0?n.push([e,t]):n[r][1]=t,this},He.prototype.clear=function(){this.__data__={hash:new Xe,map:new(Pe||qe),string:new Xe}},He.prototype.delete=function(e){return ht(this,e).delete(e)},He.prototype.get=function(e){return ht(this,e).get(e)},He.prototype.has=function(e){return ht(this,e).has(e)},He.prototype.set=function(e,t){return ht(this,e).set(e,t),this},Je.prototype.add=Je.prototype.push=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this},Je.prototype.has=function(e){return this.__data__.has(e)},Ke.prototype.clear=function(){this.__data__=new qe},Ke.prototype.delete=function(e){return this.__data__.delete(e)},Ke.prototype.get=function(e){return this.__data__.get(e)},Ke.prototype.has=function(e){return this.__data__.has(e)},Ke.prototype.set=function(e,t){var n=this.__data__;if(n instanceof qe){var r=n.__data__;if(!Pe||r.length<199)return r.push([e,t]),this;n=this.__data__=new He(r)}return n.set(e,t),this};var nt,rt=(nt=function(e,t){return e&&ot(e,t,Jt)},function(e,t){if(null==e)return e;if(!Ft(e))return nt(e,t);for(var n=e.length,r=-1,o=Object(e);++rc))return!1;var p=s.get(e);if(p&&s.get(t))return p==t;var y=-1,d=!0,g=u&o?new Je:n;for(s.set(e,t),s.set(t,e);++y-1&&e%1==0&&e-1&&e%1==0&&e<=u}function Dt(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function Ut(e){return!!e&&"object"==typeof e}function Gt(e){if(!Ut(e)||he.call(e)!=h||oe(e))return!1;var t=Ae(e);if(null===t)return!0;var n=ge.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&de.call(n)==ve}function zt(e){return"symbol"==typeof e||Ut(e)&&he.call(e)==w}var Ct,Wt=Y?(Ct=Y,function(e){return Ct(e)}):function(e){return Ut(e)&&$t(e.length)&&!!z[he.call(e)]};function Vt(e){return dt(e,Kt(e))}function Xt(e){return null==e?"":function(e){if("string"==typeof e)return e;if(zt(e))return We?We.call(e):"";var t=e+"";return"0"==t&&1/e==-a?"-0":t}(e)}function qt(e,t,r){var o=null==e?n:it(e,t);return o===n?r:o}function Ht(e,t){return null!=e&&function(e,t,n){for(var r,o=-1,i=(t=At(t,e)?[t]:ft(t)).length;++o1?r[i-1]:n,u=i>2?r[2]:n;for(a=e.length>3&&"function"==typeof a?(i--,a):n,u&&function(e,t,n){if(!Dt(n))return!1;var r=typeof t;return!!("number"==r?Ft(n)&&wt(t,n.length):"string"==r&&t in n)&&Pt(n[t],e)}(r[0],r[1],u)&&(a=i<3?n:a,i=1),t=Object(t);++o2){for(s=0;s=0}(e)===t?e:e.reverse()}n.ring=r;var s,l=function e(t,n){switch(t&&t.type||null){case"FeatureCollection":return t.features=t.features.map(i(e,n)),t;case"Feature":return t.geometry=e(t.geometry,n),t;case"Polygon":case"MultiPolygon":return function(e,t){return"Polygon"===e.type?e.coordinates=a(e.coordinates,t):"MultiPolygon"===e.type&&(e.coordinates=e.coordinates.map(i(a,t))),e}(t,n);default:return t}},c={};function f(t,n){return(t.version||n.version)&&t.version!==n.version?(+t.version||0)>(+n.version||0)?t:n:e.merge(t,n)}function p(e){for(var t,n,r,o,i,a,u=function(e){return e[0]},s=function(e){return e[e.length-1]},l=function(e,t){return void 0!==e&&void 0!==t&&e.id===t.id},c=[];e.length;)for(t=e.pop().nodes.slice(),c.push(t);e.length&&!l(u(t),s(t));){for(n=u(t),r=s(t),o=0;o0&&(y.nodes=f),e.isEmpty(u)||(y.tags=u),(n=t.getElementsByTagName("center")[0])&&l(y,n),p?function(t,n){e.isArray(t.nodes)||(t.nodes=[],e.each(n,function(e,n){t.nodes.push("_anonymous@"+e.getAttribute("lat")+"/"+e.getAttribute("lon"))})),e.each(n,function(e,n){var r,o,a;e.getAttribute("lat")&&(r=e.getAttribute("lat"),o=e.getAttribute("lon"),a={type:"node",id:t.nodes[n],lat:r,lon:o},i.push(a))})}(y,t.getElementsByTagName("nd")):(r=t.getElementsByTagName("bounds")[0])&&c(y,r),a.push(y)}),e.each(t.getElementsByTagName("relation"),function(t,o){var f={},p=[];e.each(t.getElementsByTagName("tag"),function(e){f[e.getAttribute("k")]=e.getAttribute("v")});var y=!1;e.each(t.getElementsByTagName("member"),function(e,t){p[t]={},s(e,p[t],"ref"),s(e,p[t],"role"),s(e,p[t],"type"),(!y&&"node"==p[t].type&&e.getAttribute("lat")||"way"==p[t].type&&e.getElementsByTagName("nd").length>0)&&(y=!0)});var d={type:"relation"};s(t,d,"id"),s(t,d,"version"),s(t,d,"timestamp"),s(t,d,"changeset"),s(t,d,"uid"),s(t,d,"user"),p.length>0&&(d.members=p),e.isEmpty(f)||(d.tags=f),(n=t.getElementsByTagName("center")[0])&&l(d,n),y?function(t,n){e.each(n,function(n,r){var o,u,s;"node"==t.members[r].type?n.getAttribute("lat")&&(o=n.getAttribute("lat"),u=n.getAttribute("lon"),s={type:"node",id:t.members[r].ref,lat:o,lon:u},i.push(s)):"way"==t.members[r].type&&n.getElementsByTagName("nd").length>0&&(t.members[r].ref="_fullGeom"+t.members[r].ref,function(t,n){if(!a.some(function(e){return"way"==e.type&&e.id==n})){var r={type:"way",id:n,nodes:[]};e.each(t,function(e){var t,n,o;e.getAttribute("lat")?(o={type:"node",id:"_anonymous@"+(t=e.getAttribute("lat"))+"/"+(n=e.getAttribute("lon")),lat:t,lon:n},r.nodes.push(o.id),i.push(o)):r.nodes.push(void 0)}),a.push(r)}}(n.getElementsByTagName("nd"),t.members[r].ref))})}(d,t.getElementsByTagName("member")):(r=t.getElementsByTagName("bounds")[0])&&c(d,r),u.push(d)}),o(i,a,u)}(t):function(t){var n=new Array,r=new Array,i=new Array;function a(t){var r=e.clone(t);r.lat=t.center.lat,r.lon=t.center.lon,r.__is_center_placeholder=!0,n.push(r)}function u(t){var o=e.clone(t);function i(e,t,r){var i={type:"node",id:"_"+o.type+"/"+o.id+"bounds"+r,lat:e,lon:t};o.nodes.push(i.id),n.push(i)}o.nodes=[],i(o.bounds.minlat,o.bounds.minlon,1),i(o.bounds.maxlat,o.bounds.minlon,2),i(o.bounds.maxlat,o.bounds.maxlon,3),i(o.bounds.minlat,o.bounds.maxlon,4),o.nodes.push(o.nodes[0]),o.__is_bounds_placeholder=!0,r.push(o)}function s(t){e.isArray(t.nodes)||(t.nodes=t.geometry.map(function(e){return null!==e?"_anonymous@"+e.lat+"/"+e.lon:"_anonymous@unknown_location"})),t.geometry.forEach(function(e,r){var o,i,a;e&&(o=e.lat,i=e.lon,a={type:"node",id:t.nodes[r],lat:o,lon:i},n.push(a))})}function l(e){e.members.forEach(function(e,t){var o,i,a;"node"==e.type?e.lat&&(o=e.lat,i=e.lon,a={type:"node",id:e.ref,lat:o,lon:i},n.push(a)):"way"==e.type&&e.geometry&&(e.ref="_fullGeom"+e.ref,function(e,t){if(!r.some(function(e){return"way"==e.type&&e.id==t})){var o={type:"way",id:t,nodes:[]};e.forEach(function(e){var t,r,i;e?(i={type:"node",id:"_anonymous@"+(t=e.lat)+"/"+(r=e.lon),lat:t,lon:r},o.nodes.push(i.id),n.push(i)):o.nodes.push(void 0)}),r.push(o)}}(e.geometry,e.ref))})}for(var c=0;c0});y.center&&a(y),d?l(y):y.bounds&&u(y)}return o(n,r,i)}(t);function o(t,o,a){function u(e,t){if("object"!=typeof t&&(t={}),"function"==typeof n.uninterestingTags)return!n.uninterestingTags(e,t);for(var r in e)if(!0!==n.uninterestingTags[r]&&!0!==t[r]&&t[r]!==e[r])return!0;return!1}function s(e){var t={timestamp:e.timestamp,version:e.version,changeset:e.changeset,user:e.user,uid:e.uid};for(var n in t)void 0===t[n]&&delete t[n];return t}for(var c=new Object,f=new Object,y=0;yr!=c>r&&n<(l-u)*(r-s)/(c-s)+u&&(o=!o)}return o};for(e=r(e),t=0;t-1},qe.prototype.set=function(e,t){var n=this.__data__,r=et(n,e);return r<0?n.push([e,t]):n[r][1]=t,this},He.prototype.clear=function(){this.__data__={hash:new Xe,map:new(Pe||qe),string:new Xe}},He.prototype.delete=function(e){return ht(this,e).delete(e)},He.prototype.get=function(e){return ht(this,e).get(e)},He.prototype.has=function(e){return ht(this,e).has(e)},He.prototype.set=function(e,t){return ht(this,e).set(e,t),this},Je.prototype.add=Je.prototype.push=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this},Je.prototype.has=function(e){return this.__data__.has(e)},Ke.prototype.clear=function(){this.__data__=new qe},Ke.prototype.delete=function(e){return this.__data__.delete(e)},Ke.prototype.get=function(e){return this.__data__.get(e)},Ke.prototype.has=function(e){return this.__data__.has(e)},Ke.prototype.set=function(e,t){var n=this.__data__;if(n instanceof qe){var r=n.__data__;if(!Pe||r.length<199)return r.push([e,t]),this;n=this.__data__=new He(r)}return n.set(e,t),this};var nt,rt=(nt=function(e,t){return e&&ot(e,t,Jt)},function(e,t){if(null==e)return e;if(!Ft(e))return nt(e,t);for(var n=e.length,r=-1,o=Object(e);++rc))return!1;var p=s.get(e);if(p&&s.get(t))return p==t;var y=-1,d=!0,g=u&o?new Je:n;for(s.set(e,t),s.set(t,e);++y-1&&e%1==0&&e-1&&e%1==0&&e<=u}function Dt(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function Ut(e){return!!e&&"object"==typeof e}function Gt(e){if(!Ut(e)||he.call(e)!=h||oe(e))return!1;var t=Ae(e);if(null===t)return!0;var n=ge.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&de.call(n)==ve}function zt(e){return"symbol"==typeof e||Ut(e)&&he.call(e)==w}var Ct,Wt=Y?(Ct=Y,function(e){return Ct(e)}):function(e){return Ut(e)&&$t(e.length)&&!!z[he.call(e)]};function Vt(e){return dt(e,Kt(e))}function Xt(e){return null==e?"":function(e){if("string"==typeof e)return e;if(zt(e))return We?We.call(e):"";var t=e+"";return"0"==t&&1/e==-a?"-0":t}(e)}function qt(e,t,r){var o=null==e?n:it(e,t);return o===n?r:o}function Ht(e,t){return null!=e&&function(e,t,n){for(var r,o=-1,i=(t=At(t,e)?[t]:ft(t)).length;++o1?r[i-1]:n,u=i>2?r[2]:n;for(a=e.length>3&&"function"==typeof a?(i--,a):n,u&&function(e,t,n){if(!Dt(n))return!1;var r=typeof t;return!!("number"==r?Ft(n)&&wt(t,n.length):"string"==r&&t in n)&&Pt(n[t],e)}(r[0],r[1],u)&&(a=i<3?n:a,i=1),t=Object(t);++o2){for(s=0;s=0}(e)===t?e:e.reverse()}n.ring=r;var s,l=function e(t,n){switch(t&&t.type||null){case"FeatureCollection":return t.features=t.features.map(i(e,n)),t;case"Feature":return t.geometry=e(t.geometry,n),t;case"Polygon":case"MultiPolygon":return function(e,t){return"Polygon"===e.type?e.coordinates=a(e.coordinates,t):"MultiPolygon"===e.type&&(e.coordinates=e.coordinates.map(i(a,t))),e}(t,n);default:return t}},c={};function f(t,n){return(t.version||n.version)&&t.version!==n.version?(+t.version||0)>(+n.version||0)?t:n:e.merge(t,n)}function p(e){for(var t,n,r,o,i,a,u=function(e){return e[0]},s=function(e){return e[e.length-1]},l=function(e,t){return void 0!==e&&void 0!==t&&e.id===t.id},c=[];e.length;)for(t=e.pop().nodes.slice(),c.push(t);e.length&&!l(u(t),s(t));){for(n=u(t),r=s(t),o=0;o0&&(y.nodes=f),e.isEmpty(u)||(y.tags=u),(n=t.getElementsByTagName("center")[0])&&l(y,n),p?function(t,n){e.isArray(t.nodes)||(t.nodes=[],e.each(n,function(e,n){t.nodes.push("_anonymous@"+e.getAttribute("lat")+"/"+e.getAttribute("lon"))})),e.each(n,function(e,n){var r,o,a;e.getAttribute("lat")&&(r=e.getAttribute("lat"),o=e.getAttribute("lon"),a={type:"node",id:t.nodes[n],lat:r,lon:o},i.push(a))})}(y,t.getElementsByTagName("nd")):(r=t.getElementsByTagName("bounds")[0])&&c(y,r),a.push(y)}),e.each(t.getElementsByTagName("relation"),function(t,o){var f={},p=[];e.each(t.getElementsByTagName("tag"),function(e){f[e.getAttribute("k")]=e.getAttribute("v")});var y=!1;e.each(t.getElementsByTagName("member"),function(e,t){p[t]={},s(e,p[t],"ref"),s(e,p[t],"role"),s(e,p[t],"type"),(!y&&"node"==p[t].type&&e.getAttribute("lat")||"way"==p[t].type&&e.getElementsByTagName("nd").length>0)&&(y=!0)});var d={type:"relation"};s(t,d,"id"),s(t,d,"version"),s(t,d,"timestamp"),s(t,d,"changeset"),s(t,d,"uid"),s(t,d,"user"),p.length>0&&(d.members=p),e.isEmpty(f)||(d.tags=f),(n=t.getElementsByTagName("center")[0])&&l(d,n),y?function(t,n){e.each(n,function(n,r){var o,u,s;"node"==t.members[r].type?n.getAttribute("lat")&&(o=n.getAttribute("lat"),u=n.getAttribute("lon"),s={type:"node",id:t.members[r].ref,lat:o,lon:u},i.push(s)):"way"==t.members[r].type&&n.getElementsByTagName("nd").length>0&&(t.members[r].ref="_fullGeom"+t.members[r].ref,function(t,n){if(!a.some(function(e){return"way"==e.type&&e.id==n})){var r={type:"way",id:n,nodes:[]};e.each(t,function(e){var t,n,o;e.getAttribute("lat")?(o={type:"node",id:"_anonymous@"+(t=e.getAttribute("lat"))+"/"+(n=e.getAttribute("lon")),lat:t,lon:n},r.nodes.push(o.id),i.push(o)):r.nodes.push(void 0)}),a.push(r)}}(n.getElementsByTagName("nd"),t.members[r].ref))})}(d,t.getElementsByTagName("member")):(r=t.getElementsByTagName("bounds")[0])&&c(d,r),u.push(d)}),o(i,a,u)}(t):function(t){var n=new Array,r=new Array,i=new Array;function a(t){var r=e.clone(t);r.lat=t.center.lat,r.lon=t.center.lon,r.__is_center_placeholder=!0,n.push(r)}function u(t){var o=e.clone(t);function i(e,t,r){var i={type:"node",id:"_"+o.type+"/"+o.id+"bounds"+r,lat:e,lon:t};o.nodes.push(i.id),n.push(i)}o.nodes=[],i(o.bounds.minlat,o.bounds.minlon,1),i(o.bounds.maxlat,o.bounds.minlon,2),i(o.bounds.maxlat,o.bounds.maxlon,3),i(o.bounds.minlat,o.bounds.maxlon,4),o.nodes.push(o.nodes[0]),o.__is_bounds_placeholder=!0,r.push(o)}function s(t){e.isArray(t.nodes)||(t.nodes=t.geometry.map(function(e){return null!==e?"_anonymous@"+e.lat+"/"+e.lon:"_anonymous@unknown_location"})),t.geometry.forEach(function(e,r){var o,i,a;e&&(o=e.lat,i=e.lon,a={type:"node",id:t.nodes[r],lat:o,lon:i},n.push(a))})}function l(e){e.members.forEach(function(e,t){var o,i,a;"node"==e.type?e.lat&&(o=e.lat,i=e.lon,a={type:"node",id:e.ref,lat:o,lon:i},n.push(a)):"way"==e.type&&e.geometry&&(e.ref="_fullGeom"+e.ref,function(e,t){if(!r.some(function(e){return"way"==e.type&&e.id==t})){var o={type:"way",id:t,nodes:[]};e.forEach(function(e){var t,r,i;e?(i={type:"node",id:"_anonymous@"+(t=e.lat)+"/"+(r=e.lon),lat:t,lon:r},o.nodes.push(i.id),n.push(i)):o.nodes.push(void 0)}),r.push(o)}}(e.geometry,e.ref))})}for(var c=0;c0});y.center&&a(y),d?l(y):y.bounds&&u(y)}return o(n,r,i)}(t);function o(t,o,a){function u(e,t){if("object"!=typeof t&&(t={}),"function"==typeof n.uninterestingTags)return!n.uninterestingTags(e,t);for(var r in e)if(!0!==n.uninterestingTags[r]&&!0!==t[r]&&t[r]!==e[r])return!0;return!1}function s(e){var t={timestamp:e.timestamp,version:e.version,changeset:e.changeset,user:e.user,uid:e.uid,ndrefs:e.hasOwnProperty("ndrefs")&&n.wayRefs?e.ndrefs:void 0};for(var r in t)void 0===t[r]&&delete t[r];return t}for(var c=new Object,f=new Object,y=0;yr!=c>r&&n<(l-u)*(r-s)/(c-s)+u&&(o=!o)}return o};for(e=r(e),t=0;t Date: Wed, 13 Mar 2019 19:18:50 +0530 Subject: [PATCH 05/14] update docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a92921f..0f61267 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Converts OSM data into GeoJSON. * `data`: the OSM data. Either as a XML DOM or in [OSM JSON](http://overpass-api.de/output_formats.html#json). * `options`: optional. The following options can be used: * `flatProperties`: If true, the resulting GeoJSON feature's properties will be a simple key-value list instead of a structured json object (with separate tags and metadata). default: false - * `wayRefs`: If true, the GeoJSON will have a `ndrefs` property, which is an array of all the node members of the `way`. default: false + * `wayRefs`: If true, the GeoJSON will have a `ndrefs` property when flat, or in `meta` when not flat, which is an array of all the node members of the `way`. default: false * `uninterestingTags`: Either a [blacklist](https://github.com/tyrasd/osmtogeojson/blob/2.0.0/index.js#L14-L24) of tag keys or a callback function. Will be used to decide if a feature is *interesting* enough for its own GeoJSON feature. * `polygonFeatures`: Either a [json object](https://github.com/tyrasd/osmtogeojson/blob/2.0.0/polygon_features.json) or callback function that is used to determine if a closed way should be treated as a Polygon or LineString. [read more](https://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features) From 88eeed8fb91add6cede16762bc81e02826f2d1f4 Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Wed, 18 Sep 2019 12:24:06 +0100 Subject: [PATCH 06/14] test - include everything, even uninteresting tags --- index.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 1f1e905..5ebc622 100644 --- a/index.js +++ b/index.js @@ -458,15 +458,16 @@ osmtogeojson = function( data, options, featureCallback ) { function _convert2geoJSON(nodes,ways,rels) { // helper function that checks if there are any tags other than "created_by", "source", etc. or any tag provided in ignore_tags function has_interesting_tags(t, ignore_tags) { - if (typeof ignore_tags !== "object") - ignore_tags={}; - if (typeof options.uninterestingTags === "function") - return !options.uninterestingTags(t, ignore_tags); - for (var k in t) - if (!(options.uninterestingTags[k]===true) && - !(ignore_tags[k]===true || ignore_tags[k]===t[k])) - return true; - return false; + return true; + // if (typeof ignore_tags !== "object") + // ignore_tags={}; + // if (typeof options.uninterestingTags === "function") + // return !options.uninterestingTags(t, ignore_tags); + // for (var k in t) + // if (!(options.uninterestingTags[k]===true) && + // !(ignore_tags[k]===true || ignore_tags[k]===t[k])) + // return true; + // return false; }; // helper function to extract meta information function build_meta_information(object) { From 31d435693035c70c9f4787fd8dc14ec4cc107b9b Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Wed, 18 Sep 2019 12:33:47 +0100 Subject: [PATCH 07/14] ensure node.tags is never undefined, test returning all nodes --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 5ebc622..b926cfe 100644 --- a/index.js +++ b/index.js @@ -373,8 +373,8 @@ osmtogeojson = function( data, options, featureCallback ) { copy_attribute( node, nodeObject, 'changeset' ); copy_attribute( node, nodeObject, 'uid' ); copy_attribute( node, nodeObject, 'user' ); - if (!_.isEmpty(tags)) - nodeObject.tags = tags; + // if (!_.isEmpty(tags)) + nodeObject.tags = tags; nodes.push(nodeObject); }); // ways From f5c84013337cf91163af2be3e440575296c2d4ab Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Wed, 18 Sep 2019 17:58:52 +0100 Subject: [PATCH 08/14] tmp commit, test if condition --- index.js | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index b926cfe..0f496c2 100644 --- a/index.js +++ b/index.js @@ -38,6 +38,7 @@ osmtogeojson = function( data, options, featureCallback ) { verbose: false, flatProperties: true, wayRefs: false, + allNodes: false, uninterestingTags: { "source": true, "source_ref": true, @@ -373,8 +374,10 @@ osmtogeojson = function( data, options, featureCallback ) { copy_attribute( node, nodeObject, 'changeset' ); copy_attribute( node, nodeObject, 'uid' ); copy_attribute( node, nodeObject, 'user' ); - // if (!_.isEmpty(tags)) - nodeObject.tags = tags; + if (!_.isEmpty(tags)) + // always set nodeObject.tags to tags, even if tags is and empty object. + // this ensures we get valid properties when returning data for all nodes + nodeObject.tags = tags; nodes.push(nodeObject); }); // ways @@ -458,16 +461,19 @@ osmtogeojson = function( data, options, featureCallback ) { function _convert2geoJSON(nodes,ways,rels) { // helper function that checks if there are any tags other than "created_by", "source", etc. or any tag provided in ignore_tags function has_interesting_tags(t, ignore_tags) { - return true; - // if (typeof ignore_tags !== "object") - // ignore_tags={}; - // if (typeof options.uninterestingTags === "function") - // return !options.uninterestingTags(t, ignore_tags); - // for (var k in t) - // if (!(options.uninterestingTags[k]===true) && - // !(ignore_tags[k]===true || ignore_tags[k]===t[k])) - // return true; - // return false; + + // if the allNodes option is set, we always return all nodes, regardless of tags + if (options.allNodes) + return true; + if (typeof ignore_tags !== "object") + ignore_tags={}; + if (typeof options.uninterestingTags === "function") + return !options.uninterestingTags(t, ignore_tags); + for (var k in t) + if (!(options.uninterestingTags[k]===true) && + !(ignore_tags[k]===true || ignore_tags[k]===t[k])) + return true; + return false; }; // helper function to extract meta information function build_meta_information(object) { From 59ac07408b0ec58d8dd7db88cb6f3244d3e0b26a Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Wed, 18 Sep 2019 18:06:03 +0100 Subject: [PATCH 09/14] remove if statement, set tags to empty object --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 0f496c2..0cbc2a7 100644 --- a/index.js +++ b/index.js @@ -374,10 +374,9 @@ osmtogeojson = function( data, options, featureCallback ) { copy_attribute( node, nodeObject, 'changeset' ); copy_attribute( node, nodeObject, 'uid' ); copy_attribute( node, nodeObject, 'user' ); - if (!_.isEmpty(tags)) // always set nodeObject.tags to tags, even if tags is and empty object. // this ensures we get valid properties when returning data for all nodes - nodeObject.tags = tags; + nodeObject.tags = tags; nodes.push(nodeObject); }); // ways From c241577deec117aa9c15dfa03db5904c1cfef308 Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Wed, 18 Sep 2019 18:36:42 +0100 Subject: [PATCH 10/14] minor, typo --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 0cbc2a7..022cfb7 100644 --- a/index.js +++ b/index.js @@ -374,7 +374,7 @@ osmtogeojson = function( data, options, featureCallback ) { copy_attribute( node, nodeObject, 'changeset' ); copy_attribute( node, nodeObject, 'uid' ); copy_attribute( node, nodeObject, 'user' ); - // always set nodeObject.tags to tags, even if tags is and empty object. + // always set nodeObject.tags to tags, even if tags is an empty object. // this ensures we get valid properties when returning data for all nodes nodeObject.tags = tags; nodes.push(nodeObject); From 831159333c0ff1a47d826f0ba30f788de29ca062 Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Fri, 24 Jan 2020 11:18:18 +0530 Subject: [PATCH 11/14] add test for allNodes option --- osmtogeojson | 2 ++ test/osm.test.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/osmtogeojson b/osmtogeojson index 87c2d7d..822133c 100755 --- a/osmtogeojson +++ b/osmtogeojson @@ -8,6 +8,7 @@ var osmtogeojson = require('./'), .boolean('n').describe('n', 'numeric properties. if set, the resulting GeoJSON feature\'s properties will be numbers if possible') .boolean('v').describe('v', 'verbose mode. output diagnostic information during processing') .boolean('m').describe('m', 'minify output json (no identation and linebreaks)') + .boolean('a').describe('a', 'return all nodes. if set, the resulting GeoJSON will contain ALL nodes as separate features, even those that do not have tags (i.e. that are parts of ways) ') .boolean('ndjson').describe('ndjson', 'output newline delimited geojson instead of a single featurecollection (implies -m enabled)') .boolean('version').describe('version','display software version') .boolean('help').describe('help','print this help message'), @@ -139,6 +140,7 @@ function legacyParsers(data) { function convert(data) { var geojson = osmtogeojson(data, { flatProperties: !enhanced_geojson, + allNodes: argv.a, verbose: argv.v }, argv.ndjson ? outputNdgeojson : null); if (!argv.ndjson) diff --git a/test/osm.test.js b/test/osm.test.js index d2d074b..c1ab727 100644 --- a/test/osm.test.js +++ b/test/osm.test.js @@ -125,6 +125,100 @@ describe("osm (xml)", function () { expect(osmtogeojson(xml, {flatProperties: false})).to.eql(geojson); }); + it("allNodes true", function () { + var xml, geojson; + + xml = ""; + xml = (new DOMParser()).parseFromString(xml, 'text/xml'); + geojson = { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": "way/1", + "properties": { + "type": "way", + "id": 1, + "tags": {}, + "relations": [], + "meta": {} + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 1, + 0 + ], + [ + 1.1, + 0 + ], + [ + 1.2, + 0.1 + ] + ] + } + }, + { + "type": "Feature", + "id": "node/2", + "properties": { + "type": "node", + "id": "2", + "tags": {}, + "relations": [], + "meta": {} + }, + "geometry": { + "type": "Point", + "coordinates": [ + 1, + 0 + ] + } + }, + { + "type": "Feature", + "id": "node/3", + "properties": { + "type": "node", + "id": "3", + "tags": {}, + "relations": [], + "meta": {} + }, + "geometry": { + "type": "Point", + "coordinates": [ + 1.1, + 0 + ] + } + }, + { + "type": "Feature", + "id": "node/4", + "properties": { + "type": "node", + "id": "4", + "tags": {}, + "relations": [], + "meta": {} + }, + "geometry": { + "type": "Point", + "coordinates": [ + 1.2, + 0.1 + ] + } + } + ] + }; + expect(osmtogeojson(xml, {flatProperties: false, allNodes: true})).to.eql(geojson); + }); }); From f1cbcc0c7b582b886c69d91d5c728602453d4547 Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Fri, 24 Jan 2020 14:50:18 +0530 Subject: [PATCH 12/14] sketch out forking handling of relations with an option flag - creates a set of feature ids that are part of relations, also outputs nodes separately from geojson, also throws out relations before geometry processing --- index.js | 66 ++++++++++++++-------- test/osm.test.js | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 23 deletions(-) diff --git a/index.js b/index.js index 022cfb7..cf96c58 100644 --- a/index.js +++ b/index.js @@ -39,6 +39,7 @@ osmtogeojson = function( data, options, featureCallback ) { flatProperties: true, wayRefs: false, allNodes: false, + mapRelations: false, uninterestingTags: { "source": true, "source_ref": true, @@ -234,6 +235,8 @@ osmtogeojson = function( data, options, featureCallback ) { var nodes = new Array(); var ways = new Array(); var rels = new Array(); + var featuresInRelation = new Set(); + // helper function function copy_attribute( x, o, attr ) { if (x.hasAttribute(attr)) @@ -420,42 +423,59 @@ osmtogeojson = function( data, options, featureCallback ) { _.each( xml.getElementsByTagName('relation'), function( relation, i ) { var tags = {}; var members = []; - _.each( relation.getElementsByTagName('tag'), function( tag ) { - tags[tag.getAttribute('k')] = tag.getAttribute('v'); - }); + var has_full_geometry = false; _.each( relation.getElementsByTagName('member'), function( member, i ) { members[i] = {}; + copy_attribute( member, members[i], 'ref' ); copy_attribute( member, members[i], 'role' ); copy_attribute( member, members[i], 'type' ); + if (!has_full_geometry && (members[i].type == 'node' && member.getAttribute('lat')) || (members[i].type == 'way' && member.getElementsByTagName('nd').length>0) ) has_full_geometry = true; + if (options.mapRelations) { + featuresInRelation.add(`${members[i].type}/${members[i].ref}`); + } }); - var relObject = { - "type": "relation" + + if (!options.mapRelations) { + _.each( relation.getElementsByTagName('tag'), function( tag ) { + tags[tag.getAttribute('k')] = tag.getAttribute('v'); + }); + var relObject = { + "type": "relation" + } + copy_attribute( relation, relObject, 'id' ); + copy_attribute( relation, relObject, 'version' ); + copy_attribute( relation, relObject, 'timestamp' ); + copy_attribute( relation, relObject, 'changeset' ); + copy_attribute( relation, relObject, 'uid' ); + copy_attribute( relation, relObject, 'user' ); + if (members.length > 0) + relObject.members = members; + if (!_.isEmpty(tags)) + relObject.tags = tags; + if (centroid = relation.getElementsByTagName('center')[0]) + centerGeometry(relObject,centroid); + if (has_full_geometry) + fullGeometryRelation(relObject, relation.getElementsByTagName('member')); + else if (bounds = relation.getElementsByTagName('bounds')[0]) + boundsGeometry(relObject,bounds); + rels.push(relObject); } - copy_attribute( relation, relObject, 'id' ); - copy_attribute( relation, relObject, 'version' ); - copy_attribute( relation, relObject, 'timestamp' ); - copy_attribute( relation, relObject, 'changeset' ); - copy_attribute( relation, relObject, 'uid' ); - copy_attribute( relation, relObject, 'user' ); - if (members.length > 0) - relObject.members = members; - if (!_.isEmpty(tags)) - relObject.tags = tags; - if (centroid = relation.getElementsByTagName('center')[0]) - centerGeometry(relObject,centroid); - if (has_full_geometry) - fullGeometryRelation(relObject, relation.getElementsByTagName('member')); - else if (bounds = relation.getElementsByTagName('bounds')[0]) - boundsGeometry(relObject,bounds); - rels.push(relObject); }); - return _convert2geoJSON(nodes,ways,rels); + if (options.mapRelations) { + return { + geojson: _convert2geoJSON(nodes,ways,rels), + featuresInRelation: Array.from(featuresInRelation), + nodes: nodes + } + } else { + return _convert2geoJSON(nodes,ways,rels); + } } function _convert2geoJSON(nodes,ways,rels) { // helper function that checks if there are any tags other than "created_by", "source", etc. or any tag provided in ignore_tags diff --git a/test/osm.test.js b/test/osm.test.js index c1ab727..4c712e0 100644 --- a/test/osm.test.js +++ b/test/osm.test.js @@ -220,6 +220,148 @@ describe("osm (xml)", function () { expect(osmtogeojson(xml, {flatProperties: false, allNodes: true})).to.eql(geojson); }); + it('relation', function() { + var xml, geojson; + + xml = ""; + xml = (new DOMParser()).parseFromString(xml, 'text/xml'); + + expectedResult = { + "geojson": { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": "way/2", + "properties": { + "type": "way", + "id": 2, + "tags": { + "area": "yes" + }, + "relations": [], + "meta": {} + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1, + -1 + ], + [ + 1, + -1 + ], + [ + 1, + 1 + ], + [ + -1, + 1 + ], + [ + -1, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "id": "way/3", + "properties": { + "type": "way", + "id": 3, + "tags": {}, + "relations": [], + "meta": {} + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 0, + -0.5 + ], + [ + 0, + 0.5 + ], + [ + 0.5, + 0 + ], + [ + 0, + -0.5 + ] + ] + } + } + ] + }, + "featuresInRelation": [ + "way/2", + "way/3" + ], + "nodes": [ + { + "type": "node", + "id": "4", + "lat": "-1.0", + "lon": "-1.0", + "tags": {} + }, + { + "type": "node", + "id": "5", + "lat": "-1.0", + "lon": "1.0", + "tags": {} + }, + { + "type": "node", + "id": "6", + "lat": "1.0", + "lon": "1.0", + "tags": {} + }, + { + "type": "node", + "id": "7", + "lat": "1.0", + "lon": "-1.0", + "tags": {} + }, + { + "type": "node", + "id": "8", + "lat": "-0.5", + "lon": "0.0", + "tags": {} + }, + { + "type": "node", + "id": "9", + "lat": "0.5", + "lon": "0.0", + "tags": {} + }, + { + "type": "node", + "id": "10", + "lat": "0.0", + "lon": "0.5", + "tags": {} + } + ] + }; + expect(osmtogeojson(xml, {flatProperties: false, mapRelations: true})).to.eql(expectedResult); + }); }); describe("osm (json)", function () { From 0e9e2ec1548ba13590e813b2da43d97ad2bb176b Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Fri, 7 Feb 2020 14:18:00 +0530 Subject: [PATCH 13/14] remove allNodes option as it is redundant with mapRelations --- index.js | 5 --- test/osm.test.js | 95 ------------------------------------------------ 2 files changed, 100 deletions(-) diff --git a/index.js b/index.js index cf96c58..9834663 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,6 @@ osmtogeojson = function( data, options, featureCallback ) { verbose: false, flatProperties: true, wayRefs: false, - allNodes: false, mapRelations: false, uninterestingTags: { "source": true, @@ -480,10 +479,6 @@ osmtogeojson = function( data, options, featureCallback ) { function _convert2geoJSON(nodes,ways,rels) { // helper function that checks if there are any tags other than "created_by", "source", etc. or any tag provided in ignore_tags function has_interesting_tags(t, ignore_tags) { - - // if the allNodes option is set, we always return all nodes, regardless of tags - if (options.allNodes) - return true; if (typeof ignore_tags !== "object") ignore_tags={}; if (typeof options.uninterestingTags === "function") diff --git a/test/osm.test.js b/test/osm.test.js index 4c712e0..16db05e 100644 --- a/test/osm.test.js +++ b/test/osm.test.js @@ -125,101 +125,6 @@ describe("osm (xml)", function () { expect(osmtogeojson(xml, {flatProperties: false})).to.eql(geojson); }); - it("allNodes true", function () { - var xml, geojson; - - xml = ""; - xml = (new DOMParser()).parseFromString(xml, 'text/xml'); - geojson = { - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "id": "way/1", - "properties": { - "type": "way", - "id": 1, - "tags": {}, - "relations": [], - "meta": {} - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 1, - 0 - ], - [ - 1.1, - 0 - ], - [ - 1.2, - 0.1 - ] - ] - } - }, - { - "type": "Feature", - "id": "node/2", - "properties": { - "type": "node", - "id": "2", - "tags": {}, - "relations": [], - "meta": {} - }, - "geometry": { - "type": "Point", - "coordinates": [ - 1, - 0 - ] - } - }, - { - "type": "Feature", - "id": "node/3", - "properties": { - "type": "node", - "id": "3", - "tags": {}, - "relations": [], - "meta": {} - }, - "geometry": { - "type": "Point", - "coordinates": [ - 1.1, - 0 - ] - } - }, - { - "type": "Feature", - "id": "node/4", - "properties": { - "type": "node", - "id": "4", - "tags": {}, - "relations": [], - "meta": {} - }, - "geometry": { - "type": "Point", - "coordinates": [ - 1.2, - 0.1 - ] - } - } - ] - }; - expect(osmtogeojson(xml, {flatProperties: false, allNodes: true})).to.eql(geojson); - }); - it('relation', function() { var xml, geojson; From 22f5ea1d2cd719359b393e830fff055d9a66432c Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Fri, 7 Feb 2020 14:26:49 +0530 Subject: [PATCH 14/14] document usage of mapRelations flag in README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0f61267..be49a84 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Converts OSM data into GeoJSON. * `wayRefs`: If true, the GeoJSON will have a `ndrefs` property when flat, or in `meta` when not flat, which is an array of all the node members of the `way`. default: false * `uninterestingTags`: Either a [blacklist](https://github.com/tyrasd/osmtogeojson/blob/2.0.0/index.js#L14-L24) of tag keys or a callback function. Will be used to decide if a feature is *interesting* enough for its own GeoJSON feature. * `polygonFeatures`: Either a [json object](https://github.com/tyrasd/osmtogeojson/blob/2.0.0/polygon_features.json) or callback function that is used to determine if a closed way should be treated as a Polygon or LineString. [read more](https://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features) + * `mapRelations` either `true` or `false`. If set to true, osmtogeojson returns some additional data, apart from the GeoJSON. The data returned will now be an object containing `geojson`, `featuresInRelation` and `nodes`. `geojson` will be the current geojson format. `featuresInRelation` is an array of feature ids that are members of relations. `nodes` is an array of node objects, including nodes without tags. Additionally, if `mapRelations` is passed, geometry processing of relations is ignored, and relations are omitted from the `geojson` output. The result is a javascript object of GeoJSON data: