diff --git a/NGCHM/WebContent/chm.html b/NGCHM/WebContent/chm.html
index f50c76be..a19c7fa3 100644
--- a/NGCHM/WebContent/chm.html
+++ b/NGCHM/WebContent/chm.html
@@ -497,7 +497,6 @@
Font & Paper Options:
-
diff --git a/NGCHM/WebContent/javascript/CreateWebLoader.js b/NGCHM/WebContent/javascript/CreateWebLoader.js
deleted file mode 100644
index 542ca476..00000000
--- a/NGCHM/WebContent/javascript/CreateWebLoader.js
+++ /dev/null
@@ -1,179 +0,0 @@
-(function() {
- 'use strict';
- NgChm.markFile();
-
- const MMGR = NgChm.createNS('NgChm.MMGR');
- const CFG = NgChm.importNS('NgChm.CFG');
- const UTIL = NgChm.importNS('NgChm.UTIL');
-
-//Create a worker thread to request/receive json data and tiles. Using a separate
-//thread allows the large I/O to overlap extended periods of heavy computation.
-MMGR.createWebLoader = function (fileSrc) {
-
- const debug = false;
- const baseURL = getLoaderBaseURL (fileSrc);
-
- // Define worker script.
- // (it was seen to cause problems to include "use strict" in wS [code string passed to web worker])
-let wS = `const debug = ${debug};`;
- wS += `const maxActiveRequests = 2;`; // Maximum number of tile requests that can be in flight concurrently
- wS += `var active = 0;`; // Number of tile requests in flight
- wS += `const pending = [];`; // Additional tile requests
- wS += `const baseURL = "${baseURL}";`; // Base URL to prepend to requests.
- wS += `var mapId = "${UTIL.mapId}";`; // Map ID.
- wS += `const mapNameRef = "${UTIL.mapNameRef}";`; // Map name (if specified).
-
- // Create a function that determines the get tile request.
- // Body of function depends on the fileSrc of the NG-CHM.
- wS += 'function tileURL(job){return baseURL+';
- if (fileSrc === MMGR.WEB_SOURCE) {
- wS += '"GetTile?map=" + mapId + "&datalayer=" + job.layer + "&level=" + job.level + "&tile=" + job.tileName';
- } else {
- // [bmb] Is LOCAL_SOURCE ever used? ".bin" files were obsoleted years ago.
- wS += 'job.layer+"/"+job.level+"/"+job.tileName+".bin"';
- }
- wS += ";}";
-
- // The following function is stringified and sent to the web loader.
- function loadTile (job) {
- if (active === maxActiveRequests) {
- pending.push(job);
- return;
- }
- active++;
- const req = new XMLHttpRequest();
- req.open("GET", tileURL(job), true);
- req.responseType = "arraybuffer";
- req.onreadystatechange = function () {
- if (req.readyState == req.DONE) {
- active--;
- if (pending.length > 0) {
- loadTile (pending.shift());
- }
- if (req.status != 200) {
- postMessage({ op: 'tileLoadFailed', job });
- } else {
- // Transfer buffer to main thread.
- postMessage({ op: 'tileLoaded', job, buffer: req.response }, [req.response]);
- }
- }
- };
- req.send();
- }
- wS += loadTile.toString();
-
- // Create a function that determines the get JSON file request.
- // Body of function depends on the fileSrc of the NG-CHM.
- wS += 'function jsonFileURL(name){return baseURL+';
- if (fileSrc === MMGR.WEB_SOURCE) {
- wS += '"GetDescriptor?map=" + mapId + "&type=" + name';
- } else {
- wS += 'name+".json"';
- }
- wS += ";}";
-
- // The following function is stringified and sent to the web loader.
- function loadJson (name) {
- const req = new XMLHttpRequest();
- req.open("GET", jsonFileURL(name), true);
- req.responseType = "json";
- req.onreadystatechange = function () {
- if (req.readyState == req.DONE) {
- if (req.status != 200) {
- postMessage({ op: 'jsonLoadFailed', name });
- } else {
- // Send json to main thread.
- postMessage({ op:'jsonLoaded', name, json: req.response });
- }
- }
- };
- req.send();
- };
- wS += loadJson.toString();
-
- // This function will be stringified and sent to the web loader.
- function handleMessage(e) {
- if (debug) console.log({ m: 'Worker: got message', e, t: performance.now() });
- if (e.data.op === 'loadTile') { loadTile (e.data.job); }
- else if (e.data.op === 'loadJSON') { loadJson (e.data.name); }
- }
- wS += handleMessage.toString();
-
- // This function will be stringified and sent to the web loader.
- function getConfigAndData() {
- // Retrieve all map configuration data.
- loadJson('mapConfig');
- // Retrieve all map supporting data (e.g. labels, dendros) from JSON.
- loadJson('mapData');
- }
- wS += getConfigAndData.toString();
-
- // If the map was specified by name, send the code to find the
- // map's id by name. Otherwise just get the map's config
- // and data.
- if (UTIL.mapId === '' && UTIL.mapNameRef !== '') {
- function getMapId () {
- fetch (baseURL + "GetMapByName/" + mapNameRef)
- .then (res => {
- if (res.status === 200) {
- res.json().then (mapinfo => {
- mapId = mapinfo.data.id;
- getConfigAndData();
- });
- } else {
- postMessage({ op: 'jsonLoadFailed', name: 'GetMapByName' });
- }
- });
- }
- wS += getMapId.toString();
- wS += getMapId.name + '();';
- } else {
- wS += getConfigAndData.name + '();';
- }
-
- wS += `onmessage = ${handleMessage.name};`;
- if (debug) wS += `console.log ({ m:'TileLoader loaded', t: performance.now() });`;
-
- // Create blob and start worker.
- const blob = new Blob([wS], {type: 'application/javascript'});
- if (debug) console.log({ m: 'MMGR.createWebLoader', blob, wS });
- MMGR.webLoader = new Worker(URL.createObjectURL(blob));
- // It is possible for the web worker to post a reply to the main thread
- // before the message handler is defined. Stash any such messages away
- // and play them back once it has been.
- const pendingMessages = [];
- MMGR.webLoader.onmessage = function(e) {
- pendingMessages.push(e);
- };
- MMGR.webLoader.setMessageHandler = function (mh) {
- // Run asychronously so that the heatmap can be defined before processing messages.
- setTimeout(function() {
- while (pendingMessages.length > 0) {
- mh (pendingMessages.shift());
- }
- MMGR.webLoader.onmessage = mh;
- }, 0);
- };
-
- // Called locally.
- function getLoaderBaseURL (fileSrc) {
- var URL;
- if (fileSrc == MMGR.WEB_SOURCE) {
- // Because a tile worker thread doesn't share our origin, we have to pass it
- // an absolute URL, and to substitute in the CFG.api variable, we want to
- // build the URL using the same logic as a browser for relative vs. absolute
- // paths.
- URL = document.location.origin;
- if (CFG.api[0] !== '/') { // absolute
- URL += '/' + window.location.pathname.substr(1, window.location.pathname.lastIndexOf('/'));
- }
- URL += CFG.api;
- } else {
- console.log (`getLoaderBaseURL: fileSrc==${fileSrc}`);
- URL = MMGR.localRepository+"/"+MMGR.embeddedMapName+"/";
- }
- return URL;
- }
-};
-
-})();
diff --git a/NGCHM/WebContent/javascript/MatrixManager.js b/NGCHM/WebContent/javascript/MatrixManager.js
index f12c8a21..31fff163 100644
--- a/NGCHM/WebContent/javascript/MatrixManager.js
+++ b/NGCHM/WebContent/javascript/MatrixManager.js
@@ -18,8 +18,7 @@
//
// Define Namespace for NgChm MatrixManager
- const MMGR = NgChm.importNS('NgChm.MMGR');
-
+ const MMGR = NgChm.createNS('NgChm.MMGR');
const UTIL = NgChm.importNS('NgChm.UTIL');
const FLICK = NgChm.importNS('NgChm.FLICK');
@@ -59,6 +58,186 @@ MMGR.localRepository= '/NGCHM';
form.submit();
}
+//Create a worker thread to request/receive json data and tiles. Using a separate
+//thread allows the large I/O to overlap extended periods of heavy computation.
+MMGR.createWebLoader = function (fileSrc) {
+
+ const debug = false;
+ const baseURL = getLoaderBaseURL (fileSrc);
+
+ var nameLookupURL = undefined;
+ if (UTIL.mapNameRef !== '') {
+ nameLookupURL = baseURL + "GetMapByName/" + UTIL.mapNameRef;
+ }
+
+
+ // Define worker script.
+ // (it was seen to cause problems to include "use strict" in wS [code string passed to web worker])
+let wS = `const debug = ${debug};`;
+ wS += `const maxActiveRequests = 2;`; // Maximum number of tile requests that can be in flight concurrently
+ wS += `var active = 0;`; // Number of tile requests in flight
+ wS += `const pending = [];`; // Additional tile requests
+ wS += `const baseURL = "${baseURL}";`; // Base URL to prepend to requests.
+ wS += `var mapId = "${UTIL.mapId}";`; // Map ID.
+ //wS += `const mapNameRef = "${UTIL.mapNameRef}";`; // Map name (if specified).
+ wS += `const nameLookupURL = "${nameLookupURL}";`
+
+
+ // Create a function that determines the get tile request.
+ // Body of function depends on the fileSrc of the NG-CHM.
+ wS += 'function tileURL(job){return baseURL+';
+ if (fileSrc === MMGR.WEB_SOURCE) {
+ wS += '"GetTile?map=" + mapId + "&datalayer=" + job.layer + "&level=" + job.level + "&tile=" + job.tileName';
+ } else {
+ // [bmb] Is LOCAL_SOURCE ever used? ".bin" files were obsoleted years ago.
+ wS += 'job.layer+"/"+job.level+"/"+job.tileName+".bin"';
+ }
+ wS += ";}";
+
+ // The following function is stringified and sent to the web loader.
+ function loadTile (job) {
+ if (active === maxActiveRequests) {
+ pending.push(job);
+ return;
+ }
+ active++;
+ const req = new XMLHttpRequest();
+ req.open("GET", tileURL(job), true);
+ req.responseType = "arraybuffer";
+ req.onreadystatechange = function () {
+ if (req.readyState == req.DONE) {
+ active--;
+ if (pending.length > 0) {
+ loadTile (pending.shift());
+ }
+ if (req.status != 200) {
+ postMessage({ op: 'tileLoadFailed', job });
+ } else {
+ // Transfer buffer to main thread.
+ postMessage({ op: 'tileLoaded', job, buffer: req.response }, [req.response]);
+ }
+ }
+ };
+ req.send();
+ }
+ wS += loadTile.toString();
+
+ // Create a function that determines the get JSON file request.
+ // Body of function depends on the fileSrc of the NG-CHM.
+ wS += 'function jsonFileURL(name){return baseURL+';
+ if (fileSrc === MMGR.WEB_SOURCE) {
+ wS += '"GetDescriptor?map=" + mapId + "&type=" + name';
+ } else {
+ wS += 'name+".json"';
+ }
+ wS += ";}";
+
+ // The following function is stringified and sent to the web loader.
+ function loadJson (name) {
+ const req = new XMLHttpRequest();
+ req.open("GET", jsonFileURL(name), true);
+ req.responseType = "json";
+ req.onreadystatechange = function () {
+ if (req.readyState == req.DONE) {
+ if (req.status != 200) {
+ postMessage({ op: 'jsonLoadFailed', name });
+ } else {
+ // Send json to main thread.
+ postMessage({ op:'jsonLoaded', name, json: req.response });
+ }
+ }
+ };
+ req.send();
+ };
+ wS += loadJson.toString();
+
+ // This function will be stringified and sent to the web loader.
+ function handleMessage(e) {
+ if (debug) console.log({ m: 'Worker: got message', e, t: performance.now() });
+ if (e.data.op === 'loadTile') { loadTile (e.data.job); }
+ else if (e.data.op === 'loadJSON') { loadJson (e.data.name); }
+ }
+ wS += handleMessage.toString();
+
+ // This function will be stringified and sent to the web loader.
+ function getConfigAndData() {
+ // Retrieve all map configuration data.
+ loadJson('mapConfig');
+ // Retrieve all map supporting data (e.g. labels, dendros) from JSON.
+ loadJson('mapData');
+ }
+ wS += getConfigAndData.toString();
+
+ // If the map was specified by name, send the code to find the
+ // map's id by name. Otherwise just get the map's config
+ // and data.
+
+ function getMapId(url) {
+ fetch (url)
+ .then (res => {
+ if (res.status === 200) {
+ res.json().then (mapinfo => {
+ mapId = mapinfo.data.id;
+ getConfigAndData();
+ });
+ } else {
+ postMessage({ op: 'jsonLoadFailed', name: 'GetMapByName' });
+ }
+ });
+ }
+ wS += getMapId.toString();
+
+ if (UTIL.mapId === '' && UTIL.mapNameRef !== '') {
+ wS += getMapId.name + '(nameLookupURL);';
+ } else {
+ wS += getConfigAndData.name + '();';
+ }
+
+ wS += `onmessage = ${handleMessage.name};`;
+ if (debug) wS += `console.log ({ m:'TileLoader loaded', t: performance.now() });`;
+
+ // Create blob and start worker.
+ const blob = new Blob([wS], {type: 'application/javascript'});
+ if (debug) console.log({ m: 'MMGR.createWebLoader', blob, wS });
+ MMGR.webLoader = new Worker(URL.createObjectURL(blob));
+ // It is possible for the web worker to post a reply to the main thread
+ // before the message handler is defined. Stash any such messages away
+ // and play them back once it has been.
+ const pendingMessages = [];
+ MMGR.webLoader.onmessage = function(e) {
+ pendingMessages.push(e);
+ };
+ MMGR.webLoader.setMessageHandler = function (mh) {
+ // Run asychronously so that the heatmap can be defined before processing messages.
+ setTimeout(function() {
+ while (pendingMessages.length > 0) {
+ mh (pendingMessages.shift());
+ }
+ MMGR.webLoader.onmessage = mh;
+ }, 0);
+ };
+
+ // Called locally.
+ function getLoaderBaseURL (fileSrc) {
+ var URL;
+ if (fileSrc == MMGR.WEB_SOURCE) {
+ // Because a tile worker thread doesn't share our origin, we have to pass it
+ // an absolute URL, and to substitute in the CFG.api variable, we want to
+ // build the URL using the same logic as a browser for relative vs. absolute
+ // paths.
+ URL = document.location.origin;
+ if (CFG.api[0] !== '/') { // absolute
+ URL += '/' + window.location.pathname.substr(1, window.location.pathname.lastIndexOf('/'));
+ }
+ URL += CFG.api;
+ } else {
+ console.log (`getLoaderBaseURL: fileSrc==${fileSrc}`);
+ URL = MMGR.localRepository+"/"+MMGR.embeddedMapName+"/";
+ }
+ return URL;
+ }
+};
+
// Handle replies from tileio worker.
function connectWebLoader (heatMap, addMapConfig, addMapData) {