index.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. var distance_weight_1 = __importDefault(require("@turf/distance-weight"));
  7. var meta_1 = require("@turf/meta");
  8. /**
  9. * Moran's I measures patterns of attribute values associated with features.
  10. * The method reveal whether similar values tend to occur near each other,
  11. * or whether high or low values are interspersed.
  12. *
  13. * Moran's I > 0 means a clusterd pattern.
  14. * Moran's I < 0 means a dispersed pattern.
  15. * Moran's I = 0 means a random pattern.
  16. *
  17. * In order to test the significance of the result. The z score is calculated.
  18. * A positive enough z-score (ex. >1.96) indicates clustering,
  19. * while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern.
  20. *
  21. * the z-score can be calculated based on a normal or random assumption.
  22. *
  23. * **Bibliography***
  24. *
  25. * 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I)
  26. *
  27. * 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html)
  28. *
  29. * 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics.
  30. *
  31. * @name moranIndex
  32. * @param {FeatureCollection<any>} fc
  33. * @param {Object} options
  34. * @param {string} options.inputField the property name, must contain numeric values
  35. * @param {number} [options.threshold=100000] the distance threshold
  36. * @param {number} [options.p=2] the Minkowski p-norm distance parameter
  37. * @param {boolean} [options.binary=false] whether transfrom the distance to binary
  38. * @param {number} [options.alpha=-1] the distance decay parameter
  39. * @param {boolean} [options.standardization=true] wheter row standardization the distance
  40. * @returns {MoranIndex}
  41. * @example
  42. *
  43. * const bbox = [-65, 40, -63, 42];
  44. * const dataset = turf.randomPoint(100, { bbox: bbox });
  45. *
  46. * const result = turf.moranIndex(dataset, {
  47. * inputField: 'CRIME',
  48. * });
  49. */
  50. function default_1(fc, options) {
  51. var inputField = options.inputField;
  52. var threshold = options.threshold || 100000;
  53. var p = options.p || 2;
  54. var binary = options.binary || false;
  55. var alpha = options.alpha || -1;
  56. var standardization = options.standardization || true;
  57. var weight = distance_weight_1.default(fc, {
  58. alpha: alpha,
  59. binary: binary,
  60. p: p,
  61. standardization: standardization,
  62. threshold: threshold,
  63. });
  64. var y = [];
  65. meta_1.featureEach(fc, function (feature) {
  66. var feaProperties = feature.properties || {};
  67. // validate inputField exists
  68. y.push(feaProperties[inputField]);
  69. });
  70. var yMean = mean(y);
  71. var yVar = variance(y);
  72. var weightSum = 0;
  73. var s0 = 0;
  74. var s1 = 0;
  75. var s2 = 0;
  76. var n = weight.length;
  77. // validate y.length is the same as weight.length
  78. for (var i = 0; i < n; i++) {
  79. var subS2 = 0;
  80. for (var j = 0; j < n; j++) {
  81. weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean);
  82. s0 += weight[i][j];
  83. s1 += Math.pow(weight[i][j] + weight[j][i], 2);
  84. subS2 += weight[i][j] + weight[j][i];
  85. }
  86. s2 += Math.pow(subS2, 2);
  87. }
  88. s1 = 0.5 * s1;
  89. var moranIndex = weightSum / s0 / yVar;
  90. var expectedMoranIndex = -1 / (n - 1);
  91. var vNum = n * n * s1 - n * s2 + 3 * (s0 * s0);
  92. var vDen = (n - 1) * (n + 1) * (s0 * s0);
  93. var vNorm = vNum / vDen - expectedMoranIndex * expectedMoranIndex;
  94. var stdNorm = Math.sqrt(vNorm);
  95. var zNorm = (moranIndex - expectedMoranIndex) / stdNorm;
  96. return {
  97. expectedMoranIndex: expectedMoranIndex,
  98. moranIndex: moranIndex,
  99. stdNorm: stdNorm,
  100. zNorm: zNorm,
  101. };
  102. }
  103. exports.default = default_1;
  104. /**
  105. * get mean of a list
  106. * @param {number[]} y
  107. * @returns {number}
  108. *
  109. */
  110. function mean(y) {
  111. var sum = 0;
  112. for (var _i = 0, y_1 = y; _i < y_1.length; _i++) {
  113. var item = y_1[_i];
  114. sum += item;
  115. }
  116. return sum / y.length;
  117. }
  118. /**
  119. * get variance of a list
  120. * @param {number[]} y
  121. * @returns {number}
  122. *
  123. */
  124. function variance(y) {
  125. var yMean = mean(y);
  126. var sum = 0;
  127. for (var _i = 0, y_2 = y; _i < y_2.length; _i++) {
  128. var item = y_2[_i];
  129. sum += Math.pow(item - yMean, 2);
  130. }
  131. return sum / y.length;
  132. }
  133. /**
  134. * @typedef {Object} MoranIndex
  135. * @property {number} moranIndex the moran's Index of the observed feature set
  136. * @property {number} expectedMoranIndex the moran's Index of the random distribution
  137. * @property {number} stdNorm the standard devitaion of the random distribution
  138. * @property {number} zNorm the z-score of the observe samples with regard to the random distribution
  139. */