imerss-bioinfo 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/README.md +156 -0
  2. package/build.js +196 -0
  3. package/docs/css/imerss-viz-all.css +1227 -0
  4. package/docs/css/imerss-viz-wp-overrides.css +70 -0
  5. package/docs/css/pepiowelh.css +76 -0
  6. package/docs/css/xetthecum-external.css +47 -0
  7. package/docs/css/xetthecum-shared.css +80 -0
  8. package/docs/css/xetthecum.css +526 -0
  9. package/docs/js/imerss-viz-all.js +58 -0
  10. package/docs/js/imerss-viz-all.js.map +1 -0
  11. package/docs/js/jquery.js +10881 -0
  12. package/index.html +81 -0
  13. package/index.js +7 -0
  14. package/indexWithJustMap.html +92 -0
  15. package/indexWithMap.html +79 -0
  16. package/indexWithMapHoweSound.html +91 -0
  17. package/indexWithMapPepiowelh.html +119 -0
  18. package/indexWithMapValdes.html +90 -0
  19. package/indexWithMapXetthecum.html +90 -0
  20. package/package.json +50 -0
  21. package/src/WoRMS/taxonAPI.js +13 -0
  22. package/src/arphify.js +662 -0
  23. package/src/assignNames.js +103 -0
  24. package/src/auxBuild/restoreJQuery.js +1 -0
  25. package/src/buildSource/Comprehensive Lists.html +42 -0
  26. package/src/buildSource/Data Paper Part I Visualisation.html +50 -0
  27. package/src/buildSource/Galiano Life List.html +43 -0
  28. package/src/buildSource/Metchosin/index.html +22 -0
  29. package/src/buildSource/Pe'pi'ow'elh.html +72 -0
  30. package/src/buildSource/Squamish Life List.html +48 -0
  31. package/src/buildSource/Valdes Island Biodiversity.html +64 -0
  32. package/src/buildSource/Xetthecum.html +40 -0
  33. package/src/buildSource/dataPaperSunburstAndMap.html +30 -0
  34. package/src/buildSource/index.html +224 -0
  35. package/src/client/css/imerss-viz-wp-overrides.css +70 -0
  36. package/src/client/css/imerss-viz.css +531 -0
  37. package/src/client/css/pepiowelh.css +76 -0
  38. package/src/client/css/xetthecum-external.css +47 -0
  39. package/src/client/css/xetthecum-shared.css +80 -0
  40. package/src/client/css/xetthecum.css +526 -0
  41. package/src/client/html/imerss-viz-map-only.html +75 -0
  42. package/src/client/html/imerss-viz-map-pepi.html +77 -0
  43. package/src/client/html/imerss-viz-map-xetthecum.html +90 -0
  44. package/src/client/html/imerss-viz-map.html +75 -0
  45. package/src/client/html/imerss-viz.html +58 -0
  46. package/src/client/html/importing Xetthecum patterns.txt +10 -0
  47. package/src/client/html/xetthecum-patterns.html +27 -0
  48. package/src/client/img/Animalia_2.svg +1 -0
  49. package/src/client/img/Animalia_Annelida.svg +655 -0
  50. package/src/client/img/Animalia_Chaetognatha.svg +72 -0
  51. package/src/client/img/Animalia_Cnidaria.svg +173 -0
  52. package/src/client/img/Animalia_Ctenophora.svg +298 -0
  53. package/src/client/img/Animalia_Nemertea.svg +54 -0
  54. package/src/client/img/Animalia_Phoronida.svg +271 -0
  55. package/src/client/img/Animalia_Platyhelminthes.svg +58 -0
  56. package/src/client/img/Animalia_Porifera.svg +220 -0
  57. package/src/client/img/Animalia_Sipuncula.svg +155 -0
  58. package/src/client/img/Arachnoidiscus_schmidtii_web_1-2-scaled.webp +0 -0
  59. package/src/client/img/Arrow-down.svg +11 -0
  60. package/src/client/img/Arrow-up.svg +6 -0
  61. package/src/client/img/Chromista.svg +1 -0
  62. package/src/client/img/Pepiowelh/BlackNoWe2-wb-bb.png +0 -0
  63. package/src/client/img/Pepiowelh/BlackNoWe2-wb.png +0 -0
  64. package/src/client/img/Pepiowelh/BlackNoWe2.png +0 -0
  65. package/src/client/img/Pepiowelh/Ecocultural Mapping Banner.svg +1 -0
  66. package/src/client/img/Plankton.jpg +0 -0
  67. package/src/client/img/Plantae.svg +1 -0
  68. package/src/client/img/Plantae_2.svg +1 -0
  69. package/src/client/img/Protista.svg +1 -0
  70. package/src/client/img/Valdes/Valdes Island Conservancy.jpg +0 -0
  71. package/src/client/img/Xetthecum/Agricultural.jpg +0 -0
  72. package/src/client/img/Xetthecum/Anthropogenic_banner.jpg +0 -0
  73. package/src/client/img/Xetthecum/Broad_Leaf.jpg +0 -0
  74. package/src/client/img/Xetthecum/Caves.jpg +0 -0
  75. package/src/client/img/Xetthecum/Coastal_Bluffs.jpg +0 -0
  76. package/src/client/img/Xetthecum/Conifer_Pole_Sapling.jpg +0 -0
  77. package/src/client/img/Xetthecum/Developed.jpg +0 -0
  78. package/src/client/img/Xetthecum/Dock.jpg +0 -0
  79. package/src/client/img/Xetthecum/Eelgrass.jpg +0 -0
  80. package/src/client/img/Xetthecum/Forests_banner.jpg +0 -0
  81. package/src/client/img/Xetthecum/Freshwater_banner.jpg +0 -0
  82. package/src/client/img/Xetthecum/Greig_Creek.jpg +0 -0
  83. package/src/client/img/Xetthecum/Intertidal.jpg +0 -0
  84. package/src/client/img/Xetthecum/Laughlin_Lake.jpg +0 -0
  85. package/src/client/img/Xetthecum/Marine_banner.jpg +0 -0
  86. package/src/client/img/Xetthecum/Mature_Conifer_Forest.jpg +0 -0
  87. package/src/client/img/Xetthecum/Porlier_Pass_Road.jpg +0 -0
  88. package/src/client/img/Xetthecum/Riparian.jpg +0 -0
  89. package/src/client/img/Xetthecum/Rural.jpg +0 -0
  90. package/src/client/img/Xetthecum/Subtidal.jpg +0 -0
  91. package/src/client/img/Xetthecum/Wetland.jpg +0 -0
  92. package/src/client/img/Xetthecum/Woodland.jpg +0 -0
  93. package/src/client/img/Xetthecum/Woodland_banner.jpg +0 -0
  94. package/src/client/img/Xetthecum/Xetthecum.jpg +0 -0
  95. package/src/client/img/Xetthecum/Young_Conifer_Forest.jpg +0 -0
  96. package/src/client/img/Xetthecum/Young_Mixed_Forest.jpg +0 -0
  97. package/src/client/img/Xetthecum/food.svg +38 -0
  98. package/src/client/img/Xetthecum/indicator.svg +52 -0
  99. package/src/client/img/Xetthecum/material.svg +186 -0
  100. package/src/client/img/Xetthecum/medicinal.svg +62 -0
  101. package/src/client/img/Xetthecum/missing-value.svg +3 -0
  102. package/src/client/img/Xetthecum/spiritual.svg +13 -0
  103. package/src/client/img/Xetthecum/trade.svg +74 -0
  104. package/src/client/img/audio.svg +5 -0
  105. package/src/client/img/external-link.svg +3 -0
  106. package/src/client/img/selected-eye.svg +4 -0
  107. package/src/client/img/selected-tick.svg +3 -0
  108. package/src/client/img/thumbs/BCLeps.jpg +0 -0
  109. package/src/client/img/thumbs/Checklist.jpg +0 -0
  110. package/src/client/img/thumbs/Data-Paper-Figma.jpg +0 -0
  111. package/src/client/img/thumbs/Galiano-Data-Paper.jpg +0 -0
  112. package/src/client/img/thumbs/Galiano.jpg +0 -0
  113. package/src/client/img/thumbs/Maxwell.jpg +0 -0
  114. package/src/client/img/thumbs/Squamish.jpg +0 -0
  115. package/src/client/img/thumbs/Valdes.jpg +0 -0
  116. package/src/client/img/thumbs/Xetthecum.jpg +0 -0
  117. package/src/client/img/up-arrow.svg +4 -0
  118. package/src/client/js/autocomplete.js +53 -0
  119. package/src/client/js/checklist.js +179 -0
  120. package/src/client/js/colour.js +139 -0
  121. package/src/client/js/datasetControls.js +212 -0
  122. package/src/client/js/imerss-viz.js +1397 -0
  123. package/src/client/js/leafletMap.js +357 -0
  124. package/src/client/js/leafletMapWithGrid.js +337 -0
  125. package/src/client/js/leafletMapWithRegions.js +381 -0
  126. package/src/client/js/renderSVG.js +108 -0
  127. package/src/client/js/tabs.js +53 -0
  128. package/src/client/js/xetthecum.js +106 -0
  129. package/src/client/json/emptyPhyloMap.json +1 -0
  130. package/src/client/json/kingdomPhyloMap.json +17 -0
  131. package/src/client/json/phyloMap.json +58 -0
  132. package/src/compare.js +97 -0
  133. package/src/compilecsv.js +47 -0
  134. package/src/dataProcessing/LZ4.js +27 -0
  135. package/src/dataProcessing/coordinatePatch.js +151 -0
  136. package/src/dataProcessing/readCSV.js +107 -0
  137. package/src/dataProcessing/readCSVwithMap.js +90 -0
  138. package/src/dataProcessing/readCSVwithoutMap.js +25 -0
  139. package/src/dataProcessing/readJSON.js +23 -0
  140. package/src/dataProcessing/sqlite.js +174 -0
  141. package/src/dataProcessing/summarise.js +122 -0
  142. package/src/dataProcessing/taxonScrape.js +14 -0
  143. package/src/dataProcessing/worker.js +31 -0
  144. package/src/dataProcessing/writeCSV.js +34 -0
  145. package/src/dataProcessing/writeJSON.js +15 -0
  146. package/src/dbtaxa.js +96 -0
  147. package/src/deAuthorise.js +48 -0
  148. package/src/deqgis.js +148 -0
  149. package/src/expressions/expr.js +65 -0
  150. package/src/expressions/jsep.js +925 -0
  151. package/src/filterFirst.js +51 -0
  152. package/src/geom/geoJSON.js +121 -0
  153. package/src/iNaturalist/examples/api.inaturalist.org-v1-taxa!q=Acmispon americanus americanus.json +200 -0
  154. package/src/iNaturalist/examples/api.inaturalist.org-v1-taxa!q=Flabellina japonica.json +61 -0
  155. package/src/iNaturalist/examples/www.inaturalist.org-taxa-877359.json +132 -0
  156. package/src/iNaturalist/iNatUrls.js +17 -0
  157. package/src/iNaturalist/obsAPI.js +150 -0
  158. package/src/iNaturalist/taxonAPI.js +460 -0
  159. package/src/inatObs.js +120 -0
  160. package/src/inattify.js +123 -0
  161. package/src/intersect.js +80 -0
  162. package/src/intersectFilter.js +48 -0
  163. package/src/landlocked.js +137 -0
  164. package/src/lib/jquery.binarytransport.js +51 -0
  165. package/src/lib/lz4-commentary.txt +9 -0
  166. package/src/lib/lz4.js +73 -0
  167. package/src/lib/point-in-polygon.js +36 -0
  168. package/src/lz4.js +40 -0
  169. package/src/marmalise.js +333 -0
  170. package/src/materialise.js +68 -0
  171. package/src/reintegrate.js +71 -0
  172. package/src/taxonomise.js +615 -0
  173. package/src/unscrewGBIF.js +44 -0
  174. package/src/utils/dataSource.js +173 -0
  175. package/src/utils/settleStructure.js +62 -0
  176. package/src/utils/utils.js +92 -0
  177. package/src/viz/plethify.js +39 -0
  178. package/src/wormify.js +154 -0
  179. package/src/xetthecum/xetthecumFilters.js +126 -0
  180. package/test/testDataSource.js +182 -0
  181. package/test/testiNatObsSource.js +38 -0
  182. package/test/testiNatSource.js +50 -0
package/src/inatObs.js ADDED
@@ -0,0 +1,120 @@
1
+ /* eslint-env node */
2
+
3
+ "use strict";
4
+
5
+ const fluid = require("infusion");
6
+ const minimist = require("minimist");
7
+ const fs = require("fs");
8
+
9
+ require("./dataProcessing/readJSON.js");
10
+ require("./dataProcessing/writeJSON.js");
11
+ require("./dataProcessing/writeCSV.js");
12
+
13
+ require("./iNaturalist/obsAPI.js");
14
+
15
+ const hortis = fluid.registerNamespace("hortis");
16
+
17
+ hortis.iNatProjects = {
18
+ GalianoData: {
19
+ paramMap: {
20
+ project_id: 5799,
21
+ taxon_id: 1
22
+ },
23
+ outputFile: "data/iNaturalist/Galiano_Catalogue_Animalia_%Date.csv"
24
+ },
25
+ Valdes: {
26
+ paramMap: {
27
+ project_id: 43522,
28
+ taxon_id: 48460 // Life
29
+ },
30
+ outputFile: "data/Valdes/iNaturalist_Catalogue_%Date.csv"
31
+ },
32
+ Xetthecum: {
33
+ paramMap: {
34
+ project_id: "xetthecum",
35
+ taxon_id: 48460 // Life
36
+ },
37
+ outputFile: "data/Xetthecum/iNaturalist_Catalogue_%Date.csv"
38
+ },
39
+ Pepiowelh: {
40
+ paramMap: {
41
+ project_id: "pe-pi-ow-elh",
42
+ taxon_id: 48460 // Life
43
+ },
44
+ outputFile: "data/Pepiowelh/iNaturalist_Catalogue_%Date.csv"
45
+ }
46
+ };
47
+
48
+ const parsedArgs = minimist(process.argv.slice(2));
49
+
50
+ console.log("parsedArgs", parsedArgs);
51
+
52
+ const projectArgs = hortis.iNatProjects[parsedArgs._[0] || "GalianoData"];
53
+
54
+ const jwt = hortis.readJSONSync("jwt.json", "reading JWT token file");
55
+
56
+ const source = hortis.iNat.obsSource({
57
+ headers: {
58
+ Authorization: "Bearer " + jwt.api_token
59
+ },
60
+ paramMap: projectArgs.paramMap
61
+ });
62
+
63
+ const fileVars = {
64
+ Date: new Date().toISOString().substring(0, 10).replaceAll("-", "_")
65
+ };
66
+
67
+ fluid.setLogging(true);
68
+
69
+ const rows = [];
70
+
71
+ const directModel = {
72
+ per_page: 200
73
+ };
74
+
75
+ hortis.logObsResponse = function (data) {
76
+ const tolog = Object.assign({}, data);
77
+ tolog.results = "[ " + data.results.length + " ]";
78
+ fluid.log("Got response " + JSON.stringify(tolog, null, 4));
79
+ };
80
+
81
+ hortis.writeObs = function (filename, rows) {
82
+ const togo = fluid.promise();
83
+ const headers = Object.keys(rows[0]);
84
+ hortis.writeCSV(filename, headers, rows, togo);
85
+ return togo;
86
+ };
87
+
88
+ hortis.applyResponse = function (data) {
89
+ hortis.logObsResponse(data);
90
+ hortis.writeJSONSync("obsoutput.json", data);
91
+ if (data.results.length > 0) {
92
+ hortis.pushResultRows(rows, data);
93
+ const lastId = fluid.peek(rows).id;
94
+ console.log("got last id " + lastId);
95
+ directModel.id_above = lastId;
96
+ setTimeout(function () {
97
+ hortis.makeObsRequest(directModel);
98
+ }, 1000);
99
+ } else {
100
+ hortis.writeObs("obsoutput.csv", rows).then(function () {
101
+ const fileTarget = fluid.stringTemplate(projectArgs.outputFile, fileVars);
102
+ fs.copyFileSync("obsoutput.csv", fileTarget);
103
+ const stats = fs.statSync(fileTarget);
104
+ console.log("Written " + stats.size + " bytes to " + fileTarget);
105
+ });
106
+ }
107
+ };
108
+
109
+ hortis.makeObsRequest = function (directModel) {
110
+ console.log("Making request ", directModel);
111
+ const promise = source.get(directModel);
112
+
113
+ promise.then(function (data) {
114
+ hortis.applyResponse(data);
115
+ }, function (error) {
116
+ console.log("Got ERROUR: ", error);
117
+ });
118
+ };
119
+
120
+ hortis.makeObsRequest(directModel);
@@ -0,0 +1,123 @@
1
+ /* eslint-env node */
2
+
3
+ "use strict";
4
+
5
+ // This script is now obsoleted by the new-style "taxonomise.js" using taxonAPI.js to cache results within the SQLite database
6
+ // %imerss-bioinfo/data/iNaturalist/taxa.db/taxa.sqlite3 - will be kept for a while for reference purposes
7
+
8
+ const fluid = require("infusion");
9
+ const fs = require("fs");
10
+ const kettle = require("kettle");
11
+ const minimist = require("minimist");
12
+
13
+ require("./utils/utils.js");
14
+ require("./utils/settleStructure.js");
15
+ require("./dataProcessing/readJSON.js");
16
+ require("./dataProcessing/readCSV.js");
17
+ require("./dataProcessing/readCSVwithMap.js");
18
+ require("./dataProcessing/taxonScrape.js");
19
+
20
+ require("./iNaturalist/taxonAPI.js");
21
+
22
+ const hortis = fluid.registerNamespace("hortis");
23
+ const taxonAPIFileBase = "data/iNaturalist/taxonAPI";
24
+
25
+ const source = kettle.dataSource.URL({
26
+ url: "https://www.inaturalist.org/taxa/%id.json",
27
+ termMap: {
28
+ id: "%id"
29
+ }
30
+ });
31
+
32
+ const parsedArgs = minimist(process.argv.slice(2));
33
+
34
+ const mapFile = parsedArgs.map || "data/Galiano WoL/Galiano-data-out-map.json";
35
+ const map = hortis.readJSONSync(mapFile);
36
+
37
+ const files = parsedArgs._;
38
+
39
+ const readFiles = files.map(function (file) {
40
+ return hortis.csvReaderWithMap({
41
+ inputFile: file,
42
+ mapColumns: map.columns
43
+ }).completionPromise;
44
+ });
45
+
46
+ const resultsPromise = hortis.settleStructure(readFiles);
47
+
48
+ resultsPromise.then(function (results) {
49
+ const allRows = fluid.flatten(fluid.transform(results, function (oneResult) {
50
+ return oneResult.rows;
51
+ }));
52
+
53
+ console.log("Got " + allRows.length + " rows");
54
+
55
+ console.log(allRows[0]);
56
+ const queue = fluid.transform(allRows, function (row) {
57
+ return {id: row.iNaturalistTaxonId};
58
+ });
59
+ hortis.queueFetchWork(queue);
60
+ });
61
+
62
+ // fluid.setLogging(true);
63
+
64
+ hortis.enqueueAncestry = function (doc, queue) {
65
+ const ancestours = hortis.iNat.parentTaxaIds(doc);
66
+ const elements = ancestours.map(function (oneAnc) {
67
+ return {id: oneAnc};
68
+ });
69
+ queue.unshift.apply(queue, elements);
70
+ };
71
+
72
+ hortis.logWork = function (that) {
73
+ console.log("Remaining " + that.queue.length + "/" + (that.queue.length + that.fetched.length));
74
+ };
75
+
76
+ hortis.noteSkip = function (that, message) {
77
+ ++that.skipCount;
78
+ if (that.skipCount % 50000 === 0) {
79
+ console.log(message);
80
+ hortis.logWork(that);
81
+ }
82
+ };
83
+
84
+ hortis.queueFetchWork = function (queue) {
85
+ const nextWork = function () {
86
+ hortis.logWork(that);
87
+ setTimeout(oneWork, 1000);
88
+ };
89
+ const that = {
90
+ queue: queue,
91
+ cache: {},
92
+ skipCount: 0,
93
+ fetched: []
94
+ };
95
+ const oneWork = function () {
96
+ if (that.queue.length) {
97
+ const head = that.queue.shift();
98
+ const filename = hortis.iNat.filenameFromTaxonId(taxonAPIFileBase, head.id);
99
+ let doc;
100
+ if (that.cache[filename] || fs.existsSync(filename)) {
101
+ hortis.noteSkip(that, "File " + filename + " exists, skipping");
102
+ doc = that.cache[filename];
103
+ if (!doc) {
104
+ doc = hortis.readJSONSync(filename);
105
+ that.cache[filename] = doc;
106
+ }
107
+ hortis.enqueueAncestry(doc, that.queue);
108
+ fluid.invokeLater(oneWork);
109
+ } else {
110
+ doc = source.get(head).then(function (doc) {
111
+ that.fetched.push(head);
112
+ hortis.enqueueAncestry(doc, that.queue);
113
+ hortis.writeTaxonDoc(filename, doc);
114
+ that.cache[filename] = doc;
115
+ nextWork();
116
+ }, function (err) {
117
+ console.log("Received ERROR for id " + head.id, err);
118
+ });
119
+ }
120
+ }
121
+ };
122
+ nextWork();
123
+ };
@@ -0,0 +1,80 @@
1
+ /* eslint-env node */
2
+
3
+ "use strict";
4
+
5
+ var fluid = require("infusion");
6
+ var fs = require("fs");
7
+
8
+ require("./dataProcessing/readCSV.js");
9
+ require("./dataProcessing/readCSVwithMap.js");
10
+ require("./lib/point-in-polygon.js");
11
+ require("./geom/geoJSON.js");
12
+
13
+ var hortis = fluid.registerNamespace("hortis");
14
+ fluid.registerNamespace("hortis.intersect");
15
+
16
+ var protected_areas = require("../data/Galiano/Protected_Areas_2013_2.json");
17
+
18
+ var map = require("../data/iNaturalist-obs-map.json");
19
+
20
+ var completionPromise = hortis.imerss.csvReader({
21
+ inputFile: "data/Galiano/observations-iNat.csv",
22
+ mapColumns: map.columns
23
+ }).completionPromise;
24
+
25
+ hortis.countUniqueInFeature = function (counts, feature, mappedRows) {
26
+ mappedRows.forEach(function (row) {
27
+ if (hortis.intersectsFeature(feature, row)) {
28
+ if (counts[row.id]) {
29
+ counts[row.id]++;
30
+ } else {
31
+ counts[row.id] = 1;
32
+ }
33
+ }
34
+ });
35
+ };
36
+
37
+ hortis.intersect.mapOneiNaturalistRow = function (row) {
38
+ return {
39
+ id: row.scientificName,
40
+ point: [
41
+ row.longitude,
42
+ row.latitude
43
+ ]
44
+ };
45
+ };
46
+
47
+ var fileHeader = "var json_Protected_Areas_2013_2 = {\n\"type\": \"FeatureCollection\",\n\"name\": \"Protected_Areas_2013_2\",\n\"crs\": { \"type\": \"name\""
48
+ + ", \"properties\": { \"name\": \"urn:ogc:def:crs:OGC:1.3:CRS84\" } },\n\"features\": [\n";
49
+ var fileFooter = "\n]\n}\n";
50
+
51
+ hortis.intersect.writeUpdatedFeatures = function (featuresWithCounts) {
52
+ var outFile = fs.openSync("Protected_Areas_2013_2_counts.js", "w");
53
+ fs.writeSync(outFile, fileHeader);
54
+ var body = featuresWithCounts.map(function (feature) {
55
+ return JSON.stringify(feature);
56
+ });
57
+ fs.writeSync(outFile, body.join(",\n"));
58
+ fs.writeSync(outFile, fileFooter);
59
+ fs.closeSync(outFile);
60
+ };
61
+
62
+ var start = Date.now();
63
+
64
+ completionPromise.then(function (result) {
65
+ var read = Date.now();
66
+ console.log("Read " + result.rows.length + " in " + (read - start) + "ms");
67
+ console.log(JSON.stringify(result.rows[0], null, 2));
68
+ var mappedRows = result.rows.map(hortis.intersect.mapOneiNaturalistRow);
69
+ var featureCounts = protected_areas.features.map(function (feature) {
70
+ console.log("Mapping feature " + feature.properties.NAME + " id " + feature.properties.ID);
71
+ var counts = hortis.countUniqueInFeature(counts, feature, mappedRows);
72
+ return Object.keys(counts).length;
73
+ });
74
+ console.log("Mapped " + result.rows.length + " against " + protected_areas.features.length + " features in " + (Date.now() - read) + "ms");
75
+ console.log("Got featureCounts ", featureCounts);
76
+ var featuresWithCounts = protected_areas.features.map(function (feature, index) {
77
+ return fluid.extend(true, {}, feature, {properties: {speciesCount: featureCounts[index]}});
78
+ });
79
+ hortis.intersect.writeUpdatedFeatures(featuresWithCounts);
80
+ });
@@ -0,0 +1,48 @@
1
+ /* eslint-env node */
2
+
3
+ "use strict";
4
+
5
+ var fluid = require("infusion");
6
+
7
+ require("./dataProcessing/readCSV.js");
8
+ require("./dataProcessing/writeCSV.js");
9
+ require("./dataProcessing/readCSVwithoutMap.js");
10
+ require("./lib/point-in-polygon.js");
11
+ require("./geom/geoJSON.js");
12
+
13
+ var hortis = fluid.registerNamespace("hortis");
14
+ fluid.registerNamespace("hortis.intersect");
15
+
16
+ var polygon = require("../data/Galiano/Galiano-boundary.json");
17
+
18
+ var completionPromise = hortis.imerss.csvReaderWithoutMap({
19
+ inputFile: process.argv[2],
20
+ csvOptions: {
21
+ separator: "\t",
22
+ quote: "\0",
23
+ escape: "\0"
24
+ }
25
+ }).completionPromise;
26
+
27
+ hortis.intersect.mapGBIFRow = function (row) {
28
+ return {
29
+ point: [
30
+ Number.parseFloat(row.decimalLongitude),
31
+ Number.parseFloat(row.decimalLatitude)
32
+ ]
33
+ };
34
+ };
35
+
36
+ completionPromise.then(function (result) {
37
+ console.log(JSON.stringify(result.rows[0], null, 2));
38
+ var feature = polygon.features[0];
39
+ var outs = [];
40
+ result.rows.forEach(function (oneRow) {
41
+ var mappedRow = hortis.intersect.mapGBIFRow(oneRow);
42
+ if (hortis.intersectsFeature(feature, mappedRow)) {
43
+ outs.push(oneRow);
44
+ }
45
+ });
46
+ console.log("Found " + outs.length + " intersecting rows");
47
+ hortis.imerss.writeCSV("intersected.csv", result.headers, outs, fluid.promise());
48
+ });
@@ -0,0 +1,137 @@
1
+ /* eslint-env node */
2
+
3
+ "use strict";
4
+
5
+ var fluid = require("infusion");
6
+ var minimist = require("minimist");
7
+ fluid.require("%imerss-bioinfo");
8
+
9
+ require("./utils/utils.js");
10
+ require("./dataProcessing/readJSON.js");
11
+ require("./dataProcessing/readCSV.js");
12
+ require("./dataProcessing/readCSVwithMap.js");
13
+ require("./dataProcessing/readCSVwithoutMap.js");
14
+ require("./dataProcessing/writeCSV.js");
15
+ require("./lib/point-in-polygon.js");
16
+ require("./geom/geoJSON.js");
17
+
18
+ var hortis = fluid.registerNamespace("hortis");
19
+
20
+ fluid.setLogging(true);
21
+
22
+ fluid.loadInContext(fluid.module.resolvePath("%imerss-bioinfo/data/Galiano/Galiano_map_0.js"), true); // produces json_Galiano_map_0
23
+ fluid.loadInContext(fluid.module.resolvePath("%imerss-bioinfo/data/Xetthecum/Site_class_4.js"), true); // produces json_Site_Class_4
24
+ fluid.loadInContext(fluid.module.resolvePath("%imerss-bioinfo/data/Xetthecum/Trincomali_2.js"), true); // produces json_Trincomali_2
25
+ // var xetthecum_boundary = hortis.readJSONSync(fluid.module.resolvePath("%imerss-bioinfo/data/Xetthecum/Xetthecum_Project_Boundary_WGS_84.geojson"), "Xetthecum boundary");
26
+
27
+ var parsedArgs = minimist(process.argv.slice(2));
28
+
29
+ var outputFile = parsedArgs.o || "landlocked.csv";
30
+ var inputFile = parsedArgs._[0] || "%imerss-bioinfo/data/dataPaper/reintegrated-obs.csv";
31
+ var mapFile = parsedArgs.map || "%imerss-bioinfo/data/dataPaper/combinedOutMap-obs.json";
32
+
33
+ var map = hortis.readJSONSync(fluid.module.resolvePath(mapFile), "reading map file");
34
+
35
+ var reader = hortis.csvReaderWithMap({
36
+ inputFile: fluid.module.resolvePath(inputFile),
37
+ mapColumns: map.columns
38
+ });
39
+
40
+ var Galiano_island = fluid.global.json_Galiano_map_0.features;
41
+ var Xetthecum_site_class = fluid.global.json_Site_Class_4.features;
42
+ var Trincomali = fluid.global.json_Trincomali_2.features;
43
+
44
+ var Xetthecum_extract_props = ["CLASS", "SUB_CLASS"];
45
+ var Xetthecum_id_prop = "fid";
46
+
47
+ hortis.findFeatureProperties = function (allFeatures, row, properties, idprop) {
48
+ var features = allFeatures.filter(function (feature) {
49
+ return hortis.intersectsFeature(feature, row);
50
+ });
51
+ // features array of each feature which contains the row
52
+ var propValues = properties.map(function (propKey) {
53
+ return fluid.getMembers(features, ["properties", propKey]);
54
+ });
55
+ // propValues has one element for each property, element for each feature containing property value
56
+ var propVals = propValues.map(function (propList, index) {
57
+ var hash = fluid.arrayToHash(propList);
58
+ var keys = Object.keys(hash);
59
+ if (keys.length > 1) {
60
+ console.log("Warning: row ", row, " matched multiple features with ids ", fluid.getMembers(features, idprop),
61
+ " with mismatching values for property " + properties[index] + ": values were ", keys);
62
+ }
63
+ return keys[0];
64
+ });
65
+ return propVals;
66
+ };
67
+
68
+ var TrincomaliFeature = fluid.extend(true, Trincomali[0], {
69
+ properties: {
70
+ fid: 99,
71
+ CLASS: "Trincomali",
72
+ SUB_CLASS: ""
73
+ }
74
+ });
75
+
76
+ var allXetthecumFeatures = Xetthecum_site_class.concat(TrincomaliFeature);
77
+
78
+ hortis.getXetthecumProps = function (obsRows) {
79
+ var now = Date.now();
80
+ var extractedProps = obsRows.map(function (row) {
81
+ row.point = [hortis.parseFloat(row.longitude), hortis.parseFloat(row.latitude)];
82
+ return hortis.findFeatureProperties(allXetthecumFeatures, row, Xetthecum_extract_props, Xetthecum_id_prop);
83
+ });
84
+ console.log("Evaluated " + hortis.intersections + " intersections in " + (Date.now() - now) + " ms");
85
+ var filtered = [];
86
+ obsRows.forEach(function (row, index) {
87
+ if (extractedProps[index][0]) {
88
+ var asProps = {};
89
+ Xetthecum_extract_props.forEach(function (prop, propIndex) {
90
+ asProps[prop] = extractedProps[index][propIndex];
91
+ });
92
+ filtered.push(fluid.extend(true, {}, row, asProps));
93
+ }
94
+ });
95
+ return filtered;
96
+ };
97
+
98
+ // NB: These are not (yet) the same as "filters" in "taxonomise"
99
+ fluid.registerNamespace("hortis.filters");
100
+
101
+ hortis.filters.Xetthecum = {
102
+ filter: function (rows) {
103
+ return hortis.getXetthecumProps(rows);
104
+ },
105
+ extraProps: Xetthecum_extract_props
106
+ };
107
+
108
+ hortis.filters.Galiano = {
109
+ filter: hortis.makeFeatureRowFilter(Galiano_island),
110
+ extraProps: []
111
+ };
112
+
113
+ var activeFilter =
114
+ // hortis.filters.Xetthecum;
115
+ hortis.filters.Galiano;
116
+
117
+ reader.completionPromise.then(function () {
118
+ var obsRows = reader.rows;
119
+ console.log("Matching against " + obsRows.length + " observations");
120
+
121
+ var filtered = activeFilter.filter(obsRows);
122
+
123
+ var mapped = filtered.map(function (row) {
124
+ var outRow = {
125
+ observationId: row.observationId,
126
+ latitude: row.point[1],
127
+ longitude: row.point[0],
128
+ iNaturalistTaxonName: row.iNaturalistTaxonName
129
+ };
130
+ activeFilter.extraProps.forEach(function (prop) {
131
+ outRow[prop] = row[prop];
132
+ });
133
+ return outRow;
134
+ });
135
+ var completion = fluid.promise();
136
+ hortis.writeCSV(fluid.module.resolvePath(outputFile), ["observationId", "latitude", "longitude", "iNaturalistTaxonName"].concat(activeFilter.extraProps), mapped, completion);
137
+ });
@@ -0,0 +1,51 @@
1
+ /*
2
+ * jquery.binarytransport.js
3
+ *
4
+ * @description. jQuery ajax transport for making binary data type requests.
5
+ * @version 1.0
6
+ * @author Henry Algus <henryalgus@gmail.com>
7
+ *
8
+ */
9
+
10
+ // use this transport for "binary" data type
11
+ $.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
12
+ // check for conditions and support for blob / arraybuffer response type
13
+ if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
14
+ {
15
+ return {
16
+ // create new XMLHttpRequest
17
+ send: function(headers, callback){
18
+ // setup all variables
19
+ var xhr = new XMLHttpRequest(),
20
+ url = options.url,
21
+ type = options.type,
22
+ async = options.async || true,
23
+ // blob or arraybuffer. Default is blob
24
+ dataType = options.responseType || "blob",
25
+ data = options.data || null,
26
+ username = options.username || null,
27
+ password = options.password || null;
28
+
29
+ xhr.addEventListener('load', function(){
30
+ var data = {};
31
+ data[options.dataType] = xhr.response;
32
+ // make callback and send data
33
+ callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
34
+ });
35
+
36
+ xhr.open(type, url, async, username, password);
37
+
38
+ // setup custom headers
39
+ for (var i in headers ) {
40
+ xhr.setRequestHeader(i, headers[i] );
41
+ }
42
+
43
+ xhr.responseType = dataType;
44
+ xhr.send(data);
45
+ },
46
+ abort: function(){
47
+ jqXHR.abort();
48
+ }
49
+ };
50
+ }
51
+ });
@@ -0,0 +1,9 @@
1
+ This implementation was grabbed from the inside of the bower package for the 0.6.0 release of
2
+ https://github.com/pierrec/node-lz4 since
3
+ - the build/lz4.js file was found to be mysteriously irrelevant, despite being updated recently
4
+ - the actual build shell script failed even when tested in a Linux VM on "not finding ./bindings", perhaps a node mismatch issue
5
+
6
+ There is a sign we could revisit this at some point and produce a smaller and more reproducible decoder by mashing
7
+ together the 3 files in "Benzinga's" https://github.com/Benzinga/lz4js
8
+
9
+ Better notion: Move to standard zlib operated by pako https://github.com/nodeca/pako