From 6dee30cf6c8ca1a780d0ab38ab403bd4d5d92ece Mon Sep 17 00:00:00 2001 From: Wenbo Tao Date: Sun, 20 Sep 2020 13:18:51 -0700 Subject: [PATCH] bug fixes (#156) --- back-end/src/main/java/index/Indexer.java | 27 +++++++++++++++++++ .../main/java/index/SSVInMemoryIndexer.java | 18 ++++++++----- .../src/main/java/server/IndexHandler.java | 1 + compiler/src/index.js | 2 ++ compiler/src/template-api/SSV.js | 16 ++++++----- front-end/js/jump.js | 6 +++-- front-end/js/jumpAnimation.js | 6 ++++- 7 files changed, 59 insertions(+), 17 deletions(-) diff --git a/back-end/src/main/java/index/Indexer.java b/back-end/src/main/java/index/Indexer.java index a0bb905c..060326d4 100644 --- a/back-end/src/main/java/index/Indexer.java +++ b/back-end/src/main/java/index/Indexer.java @@ -7,6 +7,7 @@ import java.io.Serializable; import java.lang.reflect.Method; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -15,10 +16,12 @@ import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.api.scripting.NashornScriptEngine; import main.Config; +import main.DbConnector; import main.Main; import project.Canvas; import project.Layer; import project.Placement; +import project.SSV; /** Created by wenbo on 12/30/18. */ public abstract class Indexer implements Serializable { @@ -91,6 +94,30 @@ else if (Config.indexingScheme == Config.indexingScheme.TILE_INDEX) l.setIndexer(indexer); l.setIndexerType(indexer.getClass().getSimpleName()); + // for geo ssv layers, add kyrix_geo_x/kyrix_geo_y columns first + // so that getTransform().getColumnNames() below can find them + if (!l.getSSVId().isEmpty()) { + int ssvIndex = + Integer.valueOf(l.getSSVId().substring(0, l.getSSVId().indexOf("_"))); + SSV curSSV = Main.getProject().getSsvs().get(ssvIndex); + // check if geo component is specified + if (curSSV.getGeoInitialLevel() >= 0) { + String rawTable = curSSV.getRawTable(); + String db = curSSV.getDb(); + Statement rawDbStmt = DbConnector.getStmtByDbName(db); + String sql = + "ALTER TABLE " + + rawTable + + " ADD COLUMN IF NOT EXISTS kyrix_geo_x float;"; + rawDbStmt.executeUpdate(sql); + sql = + "ALTER TABLE " + + rawTable + + " ADD COLUMN IF NOT EXISTS kyrix_geo_y float;"; + rawDbStmt.executeUpdate(sql); + } + } + // pre-run getColumnNames, see issue #84: github.com/tracyhenry/kyrix/issues/84 l.getTransform().getColumnNames(); } diff --git a/back-end/src/main/java/index/SSVInMemoryIndexer.java b/back-end/src/main/java/index/SSVInMemoryIndexer.java index 0498c600..b9e98145 100644 --- a/back-end/src/main/java/index/SSVInMemoryIndexer.java +++ b/back-end/src/main/java/index/SSVInMemoryIndexer.java @@ -161,9 +161,6 @@ public void createMV(Canvas c, int layerId) throws Exception { // set common variables setCommonVariables(); - // transform geo to screen coordinates if needed - if (!ssv.getGeoLatCol().isEmpty()) getGeoCoords(); - // compute cluster aggregations long st = System.nanoTime(); computeClusterAggs(); @@ -198,6 +195,9 @@ private void setCommonVariables() throws Exception { overlappingThreshold = Math.max(overlappingThreshold, ssv.getOverlap()); System.out.println("Overlapping threshold: " + overlappingThreshold); + // transform geo to screen coordinates if needed + if (!ssv.getGeoLatCol().isEmpty()) getGeoCoords(); + // store raw query results into memory rawRows = DbConnector.getQueryResult(ssv.getDb(), ssv.getQuery()); for (int i = 0; i < rawRows.size(); i++) @@ -220,7 +220,7 @@ private void getGeoCoords() throws Exception { System.out.println(sql); rawDbStmt.executeUpdate(sql); - sql = "DROP FUNCTION get_coord"; + sql = "DROP FUNCTION IF EXISTS get_coord;"; System.out.println(sql); rawDbStmt.executeUpdate(sql); @@ -249,7 +249,11 @@ private void getGeoCoords() throws Exception { sql = "UPDATE " + ssv.getRawTable() - + " SET kyrix_geo_x = ((get_coord(latitude::float, longitude::float)->>'x')::float)," + + " SET kyrix_geo_x = ((get_coord(" + + ssv.getGeoLatCol() + + "::float, " + + ssv.getGeoLonCol() + + "::float)->>'x')::float)," + " kyrix_geo_y = ((get_coord(latitude::float, longitude::float)->>'y')::float);"; System.out.println(sql); rawDbStmt.executeUpdate(sql); @@ -479,8 +483,8 @@ private void calculateBGRP(RTreeData[] rds, int level) private void cleanUp() throws SQLException { // commit & close connections - rawDbStmt.close(); - bboxStmt.close(); + if (rawDbStmt != null) rawDbStmt.close(); + if (bboxStmt != null) bboxStmt.close(); DbConnector.closeConnection(ssv.getDb()); DbConnector.closeConnection(Config.databaseName); diff --git a/back-end/src/main/java/server/IndexHandler.java b/back-end/src/main/java/server/IndexHandler.java index 377d611b..ea0be0d2 100644 --- a/back-end/src/main/java/server/IndexHandler.java +++ b/back-end/src/main/java/server/IndexHandler.java @@ -51,6 +51,7 @@ else if (path.contains(".jpg")) e.printStackTrace(); System.out.println("\n\n" + e.getMessage() + "\n"); Server.printServingErrorMessage(); + Server.sendResponse(httpExchange, HttpsURLConnection.HTTP_NO_CONTENT, ""); } } } diff --git a/compiler/src/index.js b/compiler/src/index.js index b3f4fd1b..53aa716d 100644 --- a/compiler/src/index.js +++ b/compiler/src/index.js @@ -593,6 +593,8 @@ function saveProject() { throw new Error( "Auto drill down for MySQL is not supported right now." ); + if (this.views.length == 0) + throw new Error("No view object specified in the project."); for (var i = 0; i < this.canvases.length; i++) { // a canvas should have at least one layer if (this.canvases[i].layers.length == 0) diff --git a/compiler/src/template-api/SSV.js b/compiler/src/template-api/SSV.js index f84a0109..28b2b671 100644 --- a/compiler/src/template-api/SSV.js +++ b/compiler/src/template-api/SSV.js @@ -1662,7 +1662,9 @@ function getMapRenderer() { var vy = args["viewportY"]; var vw = args["viewportW"]; var vh = args["viewportH"]; - var level = args["pyramidLevel"]; + var topLevelWidth = params.hiX - params.loX; + var topLevelHeight = params.hiY - params.loY; + var level = +args.ssvId.substring(args.ssvId.indexOf("_") + 1); var initialLon = params.geoInitialCenterLon; var initialLat = params.geoInitialCenterLat; var initialLevel = params.geoInitialLevel; @@ -1672,16 +1674,16 @@ function getMapRenderer() { // note: vw/3 because dynamic boxes fetch a box slightly larger than viewport var minTileX = Math.floor( - (cx - (vw * (1 << level)) / 2 + vx - vw / 3) / 256 + (cx - (topLevelWidth * (1 << level)) / 2 + vx - vw / 3) / 256 ); var maxTileX = Math.floor( - (cx - (vw * (1 << level)) / 2 + vx + vw + vw / 3) / 256 + (cx - (topLevelWidth * (1 << level)) / 2 + vx + vw + vw / 3) / 256 ); var minTileY = Math.floor( - (cy - (vh * (1 << level)) / 2 + vy - vh / 3) / 256 + (cy - (topLevelHeight * (1 << level)) / 2 + vy - vh / 3) / 256 ); var maxTileY = Math.floor( - (cy - (vh * (1 << level)) / 2 + vy + vh + vh / 3) / 256 + (cy - (topLevelHeight * (1 << level)) / 2 + vy + vh + vh / 3) / 256 ); var tiles = []; for (var i = minTileX; i <= maxTileX; i++) @@ -1712,10 +1714,10 @@ function getMapRenderer() { ); }) .attr("x", function(d) { - return d[0] * 256 - (cx - (vw * (1 << level)) / 2); + return d[0] * 256 - (cx - (topLevelWidth * (1 << level)) / 2); }) .attr("y", function(d) { - return d[1] * 256 - (cy - (vh * (1 << level)) / 2); + return d[1] * 256 - (cy - (topLevelHeight * (1 << level)) / 2); }) .attr("width", 256) .attr("height", 256); diff --git a/front-end/js/jump.js b/front-end/js/jump.js index bfb24aad..d286d9e8 100644 --- a/front-end/js/jump.js +++ b/front-end/js/jump.js @@ -1,12 +1,14 @@ function removePopovers(viewId) { - var selector = ".popover,.kyrixtooltip"; + var selector = ".popover"; if (viewId != null) selector += ".view_" + viewId; + selector += ",.kyrixtooltip"; d3.selectAll(selector).remove(); } function removePopoversSmooth(viewId) { - var selector = ".popover,.kyrixtooltip"; + var selector = ".popover"; if (viewId != null) selector += ".view_" + viewId; + selector += ",.kyrixtooltip"; d3.selectAll(selector) .transition() .duration(param.popoverOutDuration) diff --git a/front-end/js/jumpAnimation.js b/front-end/js/jumpAnimation.js index 970fe80c..45ca9217 100644 --- a/front-end/js/jumpAnimation.js +++ b/front-end/js/jumpAnimation.js @@ -42,7 +42,11 @@ function animateSemanticZoom(viewId, jump, newVpX, newVpY, tuple) { // get client dx & dy var thisBox = this.getBoundingClientRect(); - var ancestorBox = ancestor.getBoundingClientRect(); + var ancestorBox = d3 + .select(ancestor) + .select("rect") + .node() + .getBoundingClientRect(); var dx = thisBox.x - ancestorBox.x; var dy = thisBox.y - ancestorBox.y;