From ee101bced89943f673aa2c276042b08b850746b8 Mon Sep 17 00:00:00 2001 From: mossroy Date: Wed, 12 Mar 2014 19:46:45 +0100 Subject: [PATCH] Several fixes for the nearby article search algorithm + some more unit tests + some debug logs in the console (to be removed afterwards) --- tests/tests.js | 35 +++++++++++++-- www/js/lib/archive.js | 98 ++++++++++++++++++++++++++++++------------ www/js/lib/geometry.js | 15 ++++++- 3 files changed, 116 insertions(+), 32 deletions(-) diff --git a/tests/tests.js b/tests/tests.js index 07465f0a..6e365d56 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -207,6 +207,9 @@ define(function(require) { ok(rect6.intersect(rect2), "rect6 intersects rect2"); ok(rect6.intersect(rect3), "rect6 intersects rect3"); ok(!rect6.intersect(rect5), "rect6 intersects rect5"); + var rect7 = new geometry.rect(0,0,45.5,90,5); + var rect8 = new geometry.rect(0,40,10,10); + ok(rect8.intersect(rect7), "rect8 intersects rect7"); }); test("check rectangle contains a point", function() { var rect1 = new geometry.rect(2,3,4,5); @@ -321,7 +324,7 @@ define(function(require) { start(); }; - var rectFranceGermany = new geometry.rect(0,40,10,10); + var rectFranceGermany = new geometry.rect(40,0,10,10); localArchive.getTitlesInCoords(rectFranceGermany, 10, callbackTitlesNearbyFound); }); @@ -329,7 +332,7 @@ define(function(require) { expect(3); var callbackTitlesNearbyLondonFound = function(titleList) { ok(titleList !== null, "Some titles should be found"); - ok(titleList.length > 0, "At least one title should be found"); + equal(titleList.length, 1, "1 title should be found"); var titleLondon = null; for (var i=0; i 0) { + alert("The last nearby search did not seem to end well : please try again"); + callbackCounterForTitlesInCoordsSearch = 0; + return; + } var normalizedRectangle = rect.normalized(); - var i = 0; - LocalArchive.getTitlesInCoordsInt(this, i, 0, normalizedRectangle, GLOBE_RECTANGLE, maxTitles, new Array(), callbackFunction, LocalArchive.callbackGetTitlesInCoordsInt); + var titlePositionsFound = new Array(); + for (var i = 0; i < this.coordinateFiles.length; i++) { + callbackCounterForTitlesInCoordsSearch++; + LocalArchive.getTitlesInCoordsInt(this, i, 0, normalizedRectangle, GLOBE_RECTANGLE, maxTitles, titlePositionsFound, callbackFunction, LocalArchive.callbackGetTitlesInCoordsInt); + } }; /** @@ -666,20 +677,15 @@ define(function(require) { * @param {type} normalizedRectangle * @param {type} callbackFunction */ - LocalArchive.callbackGetTitlesInCoordsInt = function(localArchive, titlePositionsFound, i, maxTitles, normalizedRectangle, callbackFunction) { - i++; - if (titlePositionsFound.length < maxTitles && i < localArchive.coordinateFiles.length) { - LocalArchive.getTitlesInCoordsInt(localArchive, i, 0, normalizedRectangle, GLOBE_RECTANGLE, maxTitles, titlePositionsFound, callbackFunction, LocalArchive.callbackGetTitlesInCoordsInt); + LocalArchive.callbackGetTitlesInCoordsInt = function(localArchive, titlePositionsFound, maxTitles, callbackFunction) { + // Search is over : now let's convert the title positions into Title instances + if (titlePositionsFound && titlePositionsFound.length > 0) { + LocalArchive.readTitlesFromTitleCoordsInTitleFile(localArchive, titlePositionsFound, 0, new Array(), callbackFunction); } else { - // Search is over : now let's convert the title positions into Title instances - if (titlePositionsFound && titlePositionsFound.length > 0) { - LocalArchive.readTitlesFromTitleCoordsInTitleFile(localArchive, titlePositionsFound, 0, new Array(), callbackFunction); - } - else { - callbackFunction(titlePositionsFound); - } + callbackFunction(titlePositionsFound); } + }; /** @@ -722,7 +728,7 @@ define(function(require) { readCoordinates = function(byteArray, startIndex) { var lat = util.readFloatFrom4Bytes(byteArray, startIndex, true); var long = util.readFloatFrom4Bytes(byteArray, startIndex + 4, true); - var point = new geometry.point(long, lat); + var point = new geometry.point(lat, long); return point; }; @@ -740,6 +746,7 @@ define(function(require) { * @param {type} callbackGetTitlesInCoordsInt */ LocalArchive.getTitlesInCoordsInt = function(localArchive, coordinateFileIndex, coordFilePos, targetRect, thisRect, maxTitles, titlePositionsFound, callbackFunction, callbackGetTitlesInCoordsInt) { + console.log("getTitlesInCoordsInt called : coord file number=" + coordinateFileIndex + " coordFilepos=" + coordFilePos + " x=" + thisRect.x + " y=" + thisRect.y + " w=" + thisRect.width + " h=" + thisRect.height + " callbackCounterForTitlesInCoordsSearch=" + callbackCounterForTitlesInCoordsSearch); var reader = new FileReader(); reader.onerror = errorHandler; reader.onabort = function(e) { @@ -747,10 +754,12 @@ define(function(require) { }; reader.onload = function(e) { + callbackCounterForTitlesInCoordsSearch--; var binaryTitleFile = e.target.result; var byteArray = new Uint8Array(binaryTitleFile); // Compute selector var selector = util.readIntegerFrom2Bytes(byteArray, 0); + console.log("selector=" + selector); // 0xFFFF = 65535 in decimal if (selector === 65535) { @@ -765,23 +774,49 @@ define(function(require) { var pos2 = pos1 + lense; var pos3 = pos2 + lennw; // Compute the 4 rectangles around - var rectSW = new geometry.rect(thisRect.origin(), center); - var rectSE = (new geometry.rect(thisRect.topRight(), center)).normalized(); - var rectNW = (new geometry.rect(thisRect.bottomLeft(), center)).normalized(); - var rectNE = (new geometry.rect(thisRect.corner(), center)).normalized(); + var rectSW = (new geometry.rect(thisRect.sw(), center)).normalized(); + var rectNE = (new geometry.rect(thisRect.ne(), center)).normalized(); + var rectSE = (new geometry.rect(thisRect.se(), center)).normalized(); + var rectNW = (new geometry.rect(thisRect.nw(), center)).normalized(); + console.log("center=" + center); + console.log("pos0=" + pos0); + console.log("pos1=" + pos1); + console.log("pos2=" + pos2); + console.log("pos3=" + pos3); + console.log("rectSW=" + rectSW); + console.log("rectNW=" + rectNW); + console.log("rectSE=" + rectSE); + console.log("rectNE=" + rectNE); // Recursively call this function for each rectangle around + console.log("Does the target rectangle intersect SW?"); if (targetRect.intersect(rectSW)) { + console.log("Target rectangle intersects SW : looking for archives in it"); + callbackCounterForTitlesInCoordsSearch++; LocalArchive.getTitlesInCoordsInt(localArchive, coordinateFileIndex, pos0, targetRect, rectSW, maxTitles, titlePositionsFound, callbackFunction, callbackGetTitlesInCoordsInt); } - if (targetRect.intersect(rectSE)) { - LocalArchive.getTitlesInCoordsInt(localArchive, coordinateFileIndex, pos1, targetRect, rectSE, maxTitles, titlePositionsFound, callbackFunction, callbackGetTitlesInCoordsInt); - } + console.log("Does the target rectangle intersect NW?"); if (targetRect.intersect(rectNW)) { - LocalArchive.getTitlesInCoordsInt(localArchive, coordinateFileIndex, pos2, targetRect, rectNW, maxTitles, titlePositionsFound, callbackFunction, callbackGetTitlesInCoordsInt); + console.log("Target rectangle intersects NW : looking for archives in it"); + callbackCounterForTitlesInCoordsSearch++; + LocalArchive.getTitlesInCoordsInt(localArchive, coordinateFileIndex, pos1, targetRect, rectNW, maxTitles, titlePositionsFound, callbackFunction, callbackGetTitlesInCoordsInt); } + console.log("Does the target rectangle intersect SE?"); + if (targetRect.intersect(rectSE)) { + console.log("Target rectangle intersects SE : looking for archives in it"); + callbackCounterForTitlesInCoordsSearch++; + LocalArchive.getTitlesInCoordsInt(localArchive, coordinateFileIndex, pos2, targetRect, rectSE, maxTitles, titlePositionsFound, callbackFunction, callbackGetTitlesInCoordsInt); + } + console.log("Does the target rectangle intersect NE?"); if (targetRect.intersect(rectNE)) { + console.log("Target rectangle intersects NE : looking for archives in it"); + callbackCounterForTitlesInCoordsSearch++; LocalArchive.getTitlesInCoordsInt(localArchive, coordinateFileIndex, pos3, targetRect, rectNE, maxTitles, titlePositionsFound, callbackFunction, callbackGetTitlesInCoordsInt); } + console.log("end"); + if (callbackCounterForTitlesInCoordsSearch === 0) { + console.log("callbackCounterForTitlesInCoordsSearch reached 0 : return the titles found") + callbackGetTitlesInCoordsInt(localArchive, titlePositionsFound, maxTitles, callbackFunction); + } } else { // This is a leaf node : let's see if its articles are in the @@ -790,21 +825,28 @@ define(function(require) { var indexInByteArray = 2 + i * 12; var articleCoordinates = readCoordinates(byteArray, indexInByteArray); + console.log("articleCoordinates=" + articleCoordinates); // Read position (in title file) of title var title_pos = util.readIntegerFrom4Bytes(byteArray, indexInByteArray + 8); if (!targetRect.containsPoint(articleCoordinates)) { + console.log("target rectangle does not contain this point"); continue; } // We currently do not use the article coordinates // so it's no use putting it in the result list : we only put // the position in title list + console.log("target rectangle contains this point : adding to the list"); titlePositionsFound.push(title_pos); - if (maxTitles >= 0 && titlePositionsFound.length >= maxTitles) { - callbackGetTitlesInCoordsInt(localArchive, titlePositionsFound, coordinateFileIndex, maxTitles, targetRect, callbackFunction); - return; - } + console.log("maxTitles="+maxTitles+" titlePositionsFound.length="+titlePositionsFound.length); + // TODO : reactivate to enforce the maximum titles to be searched +// if (maxTitles >= 0 && titlePositionsFound.length >= maxTitles) { +// return; +// } + } + if (callbackCounterForTitlesInCoordsSearch === 0) { + console.log("callbackCounter reached 0 : return the titles found") + callbackGetTitlesInCoordsInt(localArchive, titlePositionsFound, maxTitles, callbackFunction); } - callbackGetTitlesInCoordsInt(localArchive, titlePositionsFound, coordinateFileIndex, maxTitles, targetRect, callbackFunction); } }; diff --git a/www/js/lib/geometry.js b/www/js/lib/geometry.js index 4099d5be..bd3eafa9 100644 --- a/www/js/lib/geometry.js +++ b/www/js/lib/geometry.js @@ -278,8 +278,21 @@ define(function(require) { rect.prototype = { toString: function() { - return this.origin().toString() + ' ' + this.corner().toString(); + return 'x=' + this.x + ' y=' + this.y + ' w=' + this.width + ' h=' + this.height; }, + sw : function() { + return point(this.x, this.y); + }, + nw : function() { + return point(this.x, this.y + this.height); + }, + se : function() { + return point(this.x + this.width, this.y); + }, + ne : function() { + return point(this.x + this.width, this.y + this.height); + }, + // TODO : rename all this right/left/top/bottom terms because they are misleading (and wrong) in the Evopedia context : replace with N/S/E/W origin: function() { return point(this.x, this.y); },