diff --git a/package.json b/package.json
index 66d5af2..ce6206b 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"eslint-plugin-react-hooks": "^2.3.0",
"leaflet": "^1.6.0",
"lodash": "^4.17.15",
+ "object-hash": "^2.0.1",
"prop-types": "^15.6.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
diff --git a/src/database.js b/src/database.js
index a9a1135..340d3fc 100644
--- a/src/database.js
+++ b/src/database.js
@@ -1,17 +1,19 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, useContext } from 'react';
import NodeEnvironment from 'jest-environment-node';
+import { add_polygon_to_store, get_polygon_from_store } from './polygons.js';
+
export async function sqljs_async_queries(sqljs_object, queries) {
//var t0 = performance.now();
for (let i = 0; i < (queries.length - 1); i++) {
- console.log("Query: ", queries[i]);
+ //console.log("Query: ", queries[i]);
try {
sqljs_object.exec(queries[i]);
} catch (e) {
throw e;
}
}
- console.log("Query: ", queries[queries.length - 1]);
+ //console.log("Query: ", queries[queries.length - 1]);
try {
var r = sqljs_object.exec(queries[queries.length - 1]);
} catch (e) {
@@ -47,13 +49,13 @@ export function regexp_match(string, regex) {
return string.match(regex) != null;
}
-export function is_in_geo_polygon(lat, long, polyid) {
- return true;
+export function is_in_polygon(x, y, poly) {
+ return false;
}
-export function add_custom_functions(db) {
- db.create_function("REGEXP", regexp_match);
- db.create_function("IS_IN_GEO_POLYGON", is_in_geo_polygon);
+export function is_in_geo_polygon_from_store(lat, long, polygon_hash) {
+ const poly = get_polygon_from_store(polygon_hash);
+ return is_in_polygon(lat, long, poly);
}
// Digikam stores its tree of tags as individual tags,
@@ -102,8 +104,6 @@ export async function add_full_tag_info(db) {
db.exec(query);
});
- console.log(db.exec("PRAGMA table_info([Tags]);"));
-
return db;
}
@@ -116,7 +116,8 @@ export function ProvideDB(props) {
fetch_sqljs_db_from_sqlite(db_url)
.then(db => {
add_full_tag_info(db).then((newdb) => {
- add_custom_functions(newdb);
+ db.create_function("REGEXP", regexp_match);
+ db.create_function("IS_IN_GEO_POLYGON", is_in_geo_polygon_from_store);
setError(false);
setDb(newdb);
})
@@ -129,9 +130,5 @@ export function ProvideDB(props) {
db_error: error,
};
- if (db != null) {
- console.log("Provided DB tags schema:", db.exec("PRAGMA table_info([Tags]);"));
- }
-
return children({ ...child_props });
}
\ No newline at end of file
diff --git a/src/gridgallery.js b/src/gridgallery.js
index a03b360..01c80ec 100644
--- a/src/gridgallery.js
+++ b/src/gridgallery.js
@@ -3,6 +3,8 @@ import Gallery from 'react-grid-gallery';
import { makeStyles } from '@material-ui/core/styles';
+// TODO: some nice options: ModuloBox,
+
const useStyles = makeStyles(theme => ({
root: {
width: "100%",
diff --git a/src/main.js b/src/main.js
index ccf78c3..10a1704 100644
--- a/src/main.js
+++ b/src/main.js
@@ -12,7 +12,6 @@ import { UserQuery, user_query_from_search_string, maybe_image_query, do_image_q
import { Browser } from './browser.js';
import { UserQueryWidget } from './userquerywidget.js';
import { ResultsView } from './resultsview.js';
-import { PolygonStoreProvider } from './polygons.js';
const useStyles = makeStyles(theme => ({
root: {
@@ -126,18 +125,16 @@ export function LoadedMainPage(props) {
return (
<>
-
-
-
- {albums && }
-
-
-
-
- {photos && }
-
+
+
+ {albums && }
-
+
+
+
+ {photos && }
+
+
>
);
}
diff --git a/src/map.js b/src/map.js
index 67e9b22..0874132 100644
--- a/src/map.js
+++ b/src/map.js
@@ -58,7 +58,7 @@ export function MapView(props) {
fetch("http://nominatim.openstreetmap.org/search?polygon_geojson=1&polygon_threshold=0.001&format=json&limit=5&q=" + query)
.then(res => res.json())
.then(jsonres => {
- console.log(jsonres);
+ //console.log("Nominatim result: ", jsonres);
if (Array.isArray(jsonres) && jsonres.length > 0) {
showNominatimResult(jsonres[0]);
}
diff --git a/src/polygons.js b/src/polygons.js
index 2462584..476433c 100644
--- a/src/polygons.js
+++ b/src/polygons.js
@@ -1,21 +1,22 @@
-import React, { createContext, useReducer } from 'react';
+var g_PolygonStore = {};
-const polygonStore = createContext({});
-const { Provider } = polygonStore;
+export function hash_polygon(polygon) {
+ var hash = require('object-hash');
+ return hash(polygon);
+}
-const PolygonStoreProvider = ({ children }) => {
- const [state, dispatch] = useReducer((state, action) => {
- switch (action.type) {
- case 'add polygon':
- const newstate = state;
- newstate[action.payload.id] = action.payload.data;
- return newstate;
- default:
- throw new Error();
- };
- }, {});
+export function add_polygon_to_store(polygon) {
+ var h = hash_polygon(polygon);
+ if(!(h in g_PolygonStore)) {
+ g_PolygonStore[h] = polygon;
+ }
- return {children};
-};
+ return h;
+}
-export { polygonStore, PolygonStoreProvider }
\ No newline at end of file
+export function get_polygon_from_store(polygon_hash) {
+ if(polygon_hash in g_PolygonStore) {
+ return g_PolygonStore[polygon_hash];
+ }
+ throw new Error("Requested non-existent polygon from store.");
+}
\ No newline at end of file
diff --git a/src/queries.js b/src/queries.js
index 70ec079..d0a8bd3 100644
--- a/src/queries.js
+++ b/src/queries.js
@@ -2,6 +2,7 @@
import { create_photo, create_album, create_tag } from './media.js';
import { sqljs_async_queries } from './database.js';
import { format } from 'date-fns';
+import { add_polygon_to_store } from './polygons.js';
export function escape_regex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
@@ -12,7 +13,7 @@ export function do_image_query(query, database, collection_path, collection_thum
var queries = [];
queries.push(query);
sqljs_async_queries(database, queries).then(res => {
- console.log("response: ", res);
+ //console.log("Query result: ", res);
var photos = [];
if (res && Array.isArray(res) && res.length > 0) {
var cols = res[0].columns;
@@ -61,7 +62,6 @@ export function do_tag_query(query, database) {
return new Promise(function (resolve, reject) {
var queries = [];
queries.push(query);
- console.log("Provided DB tags schema before query:", database.exec("PRAGMA table_info([Tags]);"));
sqljs_async_queries(database, queries).then(res => {
var tags = [];
if (res && Array.isArray(res) && res.length > 0) {
@@ -136,7 +136,6 @@ export class NegationFilter extends ResultFilter {
simplify() {
var f = this.body.simplify();
- console.log("NOT body:", f);
if (f.is_true()) {
return new ConstFilter(this.result_type, false);
}
@@ -248,7 +247,6 @@ export class MatchingFilter extends ResultFilter {
+ '(\/[^\/]+)*"))';
}
- console.log(this);
throw new Error("Unsupported matching filter for SQL generation.");
}
simplify() { return this; }
@@ -306,10 +304,9 @@ export class LogicalOperatorFilter extends ResultFilter {
export class LocationFilter extends ResultFilter {
// The location filter always compares object locations (points)
// to a location polygon and filters objects outside said polygon.
- constructor(rtype, polygon, polygon_store_dispatch) {
+ constructor(rtype, polygon) {
super(rtype);
this.polygon = polygon;
- this.polygon_store_dispatch = polygon_store_dispatch;
}
to_sql_where() {
@@ -319,13 +316,8 @@ export class LocationFilter extends ResultFilter {
// by the custom comparison function invoked by SQL.js.
// We need to store our polygon in said state and then return the query to guarantee that
// it will have access to said polygon.
- const _ = require('lodash');
- const poly = {
- id: _.uniqueId('polygon_'),
- data: this.polygon
- }
- this.polygon_store_dispatch({ type: 'add polygon', payload: poly });
- return 'IS_IN_GEO_POLYGON(ImagePositions.latitude, ImagePositions.longitude, "' + poly.id + '")';
+ const hash = add_polygon_to_store(this.polygon);
+ return 'IS_IN_GEO_POLYGON(ImagePositions.latitude, ImagePositions.longitude, "' + hash + '")';
}
simplify() { return this; }
diff --git a/src/userquerywidget.js b/src/userquerywidget.js
index 5303eef..5688206 100644
--- a/src/userquerywidget.js
+++ b/src/userquerywidget.js
@@ -24,8 +24,6 @@ import { format } from 'date-fns';
import { makeStyles } from '@material-ui/core/styles';
-import { polygonStore } from './polygons.js';
-
import {
filter_is_const_false, ConstFilter, LogicalOperatorFilter, MatchingFilter,
ResultTypeEnum, LogicalOperatorEnum, MatchTypeEnum, NegationFilter, TimeFilterTypeEnum,
@@ -239,8 +237,6 @@ export function EditFilterExpressionDialog(props) {
const { onClose, startingFilter, open } = props;
const [filter, setFilter] = React.useState(startingFilter);
- const polygons_dispatch = useContext(polygonStore).dispatch;
-
const FilterTypeEnum = {
CONST: 0,
NEGATION: 1,
@@ -270,7 +266,7 @@ export function EditFilterExpressionDialog(props) {
} else if (val == FilterTypeEnum.IMAGETYPE) {
setFilter(new ImageTypeFilter(filter.result_type, ImageTypeEnum.PHOTO));
} else if (val == FilterTypeEnum.LOCATION) {
- setFilter(new LocationFilter(filter.result_type, [[0.0, 0.0]], polygons_dispatch));
+ setFilter(new LocationFilter(filter.result_type, [[0.0, 0.0]]));
} else {
throw new Error('Unsupported filter type: ' + val);
}
@@ -483,12 +479,12 @@ export function LogicalOperatorFilterExpressionControl(props) {
-
+
-
+
@@ -532,13 +528,16 @@ export function NegationExpressionControl(props) {
onChange(new_filter);
}
+ // Only nodes which are transformation nodes may normally be removed.
+ const may_be_removed = expr instanceof NegationFilter;
+
return (
<>
-
+
@@ -624,7 +623,7 @@ export function LocationFilterExpressionControl(props) {
}
export function FilterExpressionControl(props) {
- const { expr, onChange, isRoot } = props;
+ const { expr, onChange, mayBeRemoved } = props;
const [anchorEl, setAnchorEl] = React.useState(null);
const [editDialogOpen, setEditDialogOpen] = React.useState(false);
const [combineDialogOpen, setCombineDialogOpen] = React.useState(false);
@@ -718,11 +717,6 @@ export function FilterExpressionControl(props) {
throw new Error('Unsupported filter expression');
}
- // If this is the root node, removing it is not allowed.
- // Other nodes may be removed.
- // The only exception is a negation node: removing that will replace it by its child.
- var allowRemove = !isRoot || (expr instanceof NegationFilter);
-
return (
<>
{filter_elem}
@@ -737,7 +731,7 @@ export function FilterExpressionControl(props) {
- {allowRemove && }
+ {mayBeRemoved && }
@@ -781,7 +779,7 @@ export function FilterControl(props) {
}
label={resultTypeString + ':'}
/>
-
+
>
);
diff --git a/yarn.lock b/yarn.lock
index 3728018..0acfb3f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7252,6 +7252,11 @@ object-hash@^1.3.1:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
+object-hash@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.1.tgz#cef18a0c940cc60aa27965ecf49b782cbf101d96"
+ integrity sha512-HgcGMooY4JC2PBt9sdUdJ6PMzpin+YtY3r/7wg0uTifP+HJWW8rammseSEHuyt0UeShI183UGssCJqm1bJR7QA==
+
object-inspect@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"