geojson-equality.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;"undefined"!=typeof window?o=window:"undefined"!=typeof global?o=global:"undefined"!=typeof self&&(o=self),o.GeojsonEquality=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. //index.js
  3. var deepEqual = require('deep-equal');
  4. var Equality = function(opt) {
  5. this.precision = opt && opt.precision ? opt.precision : 17;
  6. this.direction = opt && opt.direction ? opt.direction : false;
  7. this.pseudoNode = opt && opt.pseudoNode ? opt.pseudoNode : false;
  8. this.objectComparator = opt && opt.objectComparator ? opt.objectComparator : objectComparator;
  9. };
  10. Equality.prototype.compare = function(g1,g2) {
  11. if (g1.type !== g2.type || !sameLength(g1,g2)) return false;
  12. switch(g1.type) {
  13. case 'Point':
  14. return this.compareCoord(g1.coordinates, g2.coordinates);
  15. break;
  16. case 'LineString':
  17. return this.compareLine(g1.coordinates, g2.coordinates,0,false);
  18. break;
  19. case 'Polygon':
  20. return this.comparePolygon(g1,g2);
  21. break;
  22. case 'Feature':
  23. return this.compareFeature(g1, g2);
  24. default:
  25. if (g1.type.indexOf('Multi') === 0) {
  26. var context = this;
  27. var g1s = explode(g1);
  28. var g2s = explode(g2);
  29. return g1s.every(function(g1part) {
  30. return this.some(function(g2part) {
  31. return context.compare(g1part,g2part);
  32. });
  33. },g2s);
  34. }
  35. }
  36. return false;
  37. };
  38. function explode(g) {
  39. return g.coordinates.map(function(part) {
  40. return {
  41. type: g.type.replace('Multi', ''),
  42. coordinates: part}
  43. });
  44. }
  45. //compare length of coordinates/array
  46. function sameLength(g1,g2) {
  47. return g1.hasOwnProperty('coordinates') ?
  48. g1.coordinates.length === g2.coordinates.length
  49. : g1.length === g2.length;
  50. }
  51. // compare the two coordinates [x,y]
  52. Equality.prototype.compareCoord = function(c1,c2) {
  53. if (c1.length !== c2.length) {
  54. return false;
  55. }
  56. for (var i=0; i < c1.length; i++) {
  57. if (c1[i].toFixed(this.precision) !== c2[i].toFixed(this.precision)) {
  58. return false;
  59. }
  60. }
  61. return true;
  62. };
  63. Equality.prototype.compareLine = function(path1,path2,ind,isPoly) {
  64. if (!sameLength(path1,path2)) return false;
  65. var p1 = this.pseudoNode ? path1 : this.removePseudo(path1);
  66. var p2 = this.pseudoNode ? path2 : this.removePseudo(path2);
  67. if (isPoly && !this.compareCoord(p1[0],p2[0])) {
  68. // fix start index of both to same point
  69. p2 = this.fixStartIndex(p2,p1);
  70. if(!p2) return;
  71. }
  72. // for linestring ind =0 and for polygon ind =1
  73. var sameDirection = this.compareCoord(p1[ind],p2[ind]);
  74. if (this.direction || sameDirection
  75. ) {
  76. return this.comparePath(p1, p2);
  77. } else {
  78. if (this.compareCoord(p1[ind],p2[p2.length - (1+ind)])
  79. ) {
  80. return this.comparePath(p1.slice().reverse(), p2);
  81. }
  82. return false;
  83. }
  84. };
  85. Equality.prototype.fixStartIndex = function(sourcePath,targetPath) {
  86. //make sourcePath first point same as of targetPath
  87. var correctPath,ind = -1;
  88. for (var i=0; i< sourcePath.length; i++) {
  89. if(this.compareCoord(sourcePath[i],targetPath[0])) {
  90. ind = i;
  91. break;
  92. }
  93. }
  94. if (ind >= 0) {
  95. correctPath = [].concat(
  96. sourcePath.slice(ind,sourcePath.length),
  97. sourcePath.slice(1,ind+1));
  98. }
  99. return correctPath;
  100. };
  101. Equality.prototype.comparePath = function (p1,p2) {
  102. var cont = this;
  103. return p1.every(function(c,i) {
  104. return cont.compareCoord(c,this[i]);
  105. },p2);
  106. };
  107. Equality.prototype.comparePolygon = function(g1,g2) {
  108. if (this.compareLine(g1.coordinates[0],g2.coordinates[0],1,true)) {
  109. var holes1 = g1.coordinates.slice(1,g1.coordinates.length);
  110. var holes2 = g2.coordinates.slice(1,g2.coordinates.length);
  111. var cont = this;
  112. return holes1.every(function(h1) {
  113. return this.some(function(h2) {
  114. return cont.compareLine(h1,h2,1,true);
  115. });
  116. },holes2);
  117. } else {
  118. return false;
  119. }
  120. };
  121. Equality.prototype.compareFeature = function(g1,g2) {
  122. if (
  123. g1.id !== g2.id ||
  124. !this.objectComparator(g1.properties, g2.properties) ||
  125. !this.compareBBox(g1,g2)
  126. ) {
  127. return false;
  128. }
  129. return this.compare(g1.geometry, g2.geometry);
  130. };
  131. Equality.prototype.compareBBox = function(g1,g2) {
  132. if (
  133. (!g1.bbox && !g2.bbox) ||
  134. (
  135. g1.bbox && g2.bbox &&
  136. this.compareCoord(g1.bbox, g2.bbox)
  137. )
  138. ) {
  139. return true;
  140. }
  141. return false;
  142. };
  143. Equality.prototype.removePseudo = function(path) {
  144. //TODO to be implement
  145. return path;
  146. };
  147. function objectComparator(obj1, obj2) {
  148. return deepEqual(obj1, obj2, {strict: true});
  149. }
  150. module.exports = Equality;
  151. },{"deep-equal":2}],2:[function(require,module,exports){
  152. var pSlice = Array.prototype.slice;
  153. var objectKeys = require('./lib/keys.js');
  154. var isArguments = require('./lib/is_arguments.js');
  155. var deepEqual = module.exports = function (actual, expected, opts) {
  156. if (!opts) opts = {};
  157. // 7.1. All identical values are equivalent, as determined by ===.
  158. if (actual === expected) {
  159. return true;
  160. } else if (actual instanceof Date && expected instanceof Date) {
  161. return actual.getTime() === expected.getTime();
  162. // 7.3. Other pairs that do not both pass typeof value == 'object',
  163. // equivalence is determined by ==.
  164. } else if (typeof actual != 'object' && typeof expected != 'object') {
  165. return opts.strict ? actual === expected : actual == expected;
  166. // 7.4. For all other Object pairs, including Array objects, equivalence is
  167. // determined by having the same number of owned properties (as verified
  168. // with Object.prototype.hasOwnProperty.call), the same set of keys
  169. // (although not necessarily the same order), equivalent values for every
  170. // corresponding key, and an identical 'prototype' property. Note: this
  171. // accounts for both named and indexed properties on Arrays.
  172. } else {
  173. return objEquiv(actual, expected, opts);
  174. }
  175. }
  176. function isUndefinedOrNull(value) {
  177. return value === null || value === undefined;
  178. }
  179. function isBuffer (x) {
  180. if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false;
  181. if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {
  182. return false;
  183. }
  184. if (x.length > 0 && typeof x[0] !== 'number') return false;
  185. return true;
  186. }
  187. function objEquiv(a, b, opts) {
  188. var i, key;
  189. if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
  190. return false;
  191. // an identical 'prototype' property.
  192. if (a.prototype !== b.prototype) return false;
  193. //~~~I've managed to break Object.keys through screwy arguments passing.
  194. // Converting to array solves the problem.
  195. if (isArguments(a)) {
  196. if (!isArguments(b)) {
  197. return false;
  198. }
  199. a = pSlice.call(a);
  200. b = pSlice.call(b);
  201. return deepEqual(a, b, opts);
  202. }
  203. if (isBuffer(a)) {
  204. if (!isBuffer(b)) {
  205. return false;
  206. }
  207. if (a.length !== b.length) return false;
  208. for (i = 0; i < a.length; i++) {
  209. if (a[i] !== b[i]) return false;
  210. }
  211. return true;
  212. }
  213. try {
  214. var ka = objectKeys(a),
  215. kb = objectKeys(b);
  216. } catch (e) {//happens when one is a string literal and the other isn't
  217. return false;
  218. }
  219. // having the same number of owned properties (keys incorporates
  220. // hasOwnProperty)
  221. if (ka.length != kb.length)
  222. return false;
  223. //the same set of keys (although not necessarily the same order),
  224. ka.sort();
  225. kb.sort();
  226. //~~~cheap key test
  227. for (i = ka.length - 1; i >= 0; i--) {
  228. if (ka[i] != kb[i])
  229. return false;
  230. }
  231. //equivalent values for every corresponding key, and
  232. //~~~possibly expensive deep test
  233. for (i = ka.length - 1; i >= 0; i--) {
  234. key = ka[i];
  235. if (!deepEqual(a[key], b[key], opts)) return false;
  236. }
  237. return typeof a === typeof b;
  238. }
  239. },{"./lib/is_arguments.js":3,"./lib/keys.js":4}],3:[function(require,module,exports){
  240. var supportsArgumentsClass = (function(){
  241. return Object.prototype.toString.call(arguments)
  242. })() == '[object Arguments]';
  243. exports = module.exports = supportsArgumentsClass ? supported : unsupported;
  244. exports.supported = supported;
  245. function supported(object) {
  246. return Object.prototype.toString.call(object) == '[object Arguments]';
  247. };
  248. exports.unsupported = unsupported;
  249. function unsupported(object){
  250. return object &&
  251. typeof object == 'object' &&
  252. typeof object.length == 'number' &&
  253. Object.prototype.hasOwnProperty.call(object, 'callee') &&
  254. !Object.prototype.propertyIsEnumerable.call(object, 'callee') ||
  255. false;
  256. };
  257. },{}],4:[function(require,module,exports){
  258. exports = module.exports = typeof Object.keys === 'function'
  259. ? Object.keys : shim;
  260. exports.shim = shim;
  261. function shim (obj) {
  262. var keys = [];
  263. for (var key in obj) keys.push(key);
  264. return keys;
  265. }
  266. },{}]},{},[1])(1)
  267. });
  268. //# sourceMappingURL=geojson-equality.js.map