From c75f6a34dfdf6aee63b918d610cdb9536d801532 Mon Sep 17 00:00:00 2001 From: Andrew Carlile Date: Tue, 9 Sep 2025 15:56:31 -0400 Subject: [PATCH 1/6] need more data --- src/clj/collect_earth_online/db/plots.clj | 111 +++++++++------------- src/js/collection.jsx | 14 +-- 2 files changed, 52 insertions(+), 73 deletions(-) diff --git a/src/clj/collect_earth_online/db/plots.clj b/src/clj/collect_earth_online/db/plots.clj index d47b16d18..c432d0c41 100644 --- a/src/clj/collect_earth_online/db/plots.clj +++ b/src/clj/collect_earth_online/db/plots.clj @@ -39,15 +39,18 @@ - if no datum of coll matches pred, or if no datum exists in dir, (ie, the first datum when dir = :prev or the last when dir = :next returns nil." - [pred coll dir] - (let [loop-coll (into [nil] coll)] - (loop [[prev this & foll] loop-coll] - (if (pred this) - (case dir - :prev prev - :next (first foll)) - (when (seq foll) - (recur (into [this] foll))))))) + ([pred coll] + (pred-idx-nav pred nil coll)) + ([pred dir coll] + (let [loop-coll (into [nil] coll)] + (loop [[prev this & foll] loop-coll] + (if (pred this) + (case dir + :prev prev + :next (first foll) + this) + (when (seq foll) + (recur (into [this] foll)))))))) (defn filter-pred-idx [pred coll] @@ -242,8 +245,7 @@ (take 1 (filter (fn [s] (= 1 (:visibleId s))) samples)) samples) :userId user_id - :email email - :navigation [nil nil 1]})) + :email email})) (defn get-correct-plot-navigation [project-id user-id current-user-id review-mode? navigation-mode project-type threshold reference-plot-id] @@ -261,7 +263,6 @@ "qaqc" (call-sql "select_qaqc_plots" project-id) "similar" (call-sql "select_plots_by_similarity" project-id reference-plot-id) []))) - (require '[clojure.pprint :refer [pprint]]) (defn get-collection-plot "Gets plot information needed for the collections page. The plot @@ -280,11 +281,10 @@ " [{:keys [params session]}] - (pprint params) (let [navigation-mode (:navigationMode params "unanalyzed") direction (:direction params "next") project-id (tc/val->int (:projectId params)) - old-visible-id (tc/val->int (:visibleId params)) + visible-id (tc/val->int (:visibleId params)) threshold (tc/val->int (:threshold params)) ref-plot-id (tc/val->int (:referencePlotId params)) project-type (:projectType params "regular") @@ -292,6 +292,7 @@ current-user-id (tc/val->int (:currentUserId params -1)) review-mode? (and (tc/val->bool (:inReviewMode params)) (is-proj-admin? user-id project-id nil)) + proj-plots (get-correct-plot-navigation project-id user-id current-user-id @@ -300,68 +301,46 @@ project-type threshold ref-plot-id) - grouped-plots (group-by :visible_id proj-plots) - sorted-plots (case navigation-mode - "qaqc" (sort-by first (filter-plot-disagreement project-id grouped-plots threshold)) - "similar" - (if (some #(= (:visible_id %) old-visible-id) proj-plots) - (filter-pred-idx #(= (:visible_id %) old-visible-id) proj-plots) - (take 3 (into [nil nil] proj-plots))) - (sort-by first grouped-plots)) - plots-info (case direction - "next" (case navigation-mode "similar" - (->> sorted-plots - (take-last 1) - (remove nil?) - seq) - (or - (->> sorted-plots - (some (fn [[visible-id plots]] - (and (> visible-id old-visible-id) - plots)))) - (-> sorted-plots first second))) - "previous" (case navigation-mode "similar" - (->> sorted-plots - (take 1) - (remove nil?) - seq) - (or - (->> sorted-plots - (sort-by first #(compare %2 %1)) - (some (fn [[visible-id plots]] - (and (< visible-id old-visible-id) - plots)))) - (->> sorted-plots - (last) - (second)))) - "id" (case navigation-mode "similar" - (->> sorted-plots - (take-last 2) - (remove nil?) - seq) - (if (> 0 old-visible-id) - (-> sorted-plots first second) - (some - - (fn [[visible-id plots]] - (and (= visible-id old-visible-id) - plots)) - sorted-plots)) - - ))] - (if plots-info + ;; grouped-plots (group-by :visible_id proj-plots) + + #_sorted-plots #_(case navigation-mode + "qaqc" (sort-by first (filter-plot-disagreement project-id grouped-plots threshold)) + "similar" + (if (some #(= (:visible_id %) old-visible-id) proj-plots) + (filter-pred-idx #(= (:visible_id %) old-visible-id) proj-plots) + (take 3 (into [nil nil] proj-plots))) + (sort-by first grouped-plots)) + sorted-plots (sort-by :visible_id proj-plots) + [next-plot this-plot previous-plot + :as nav-plots] (if (> 0 visible-id) + (into [nil] (take 2 sorted-plots)) + (filter-pred-idx #(= (:visible_id %) visible-id) sorted-plots)) + plot-info (case direction + "previous" previous-plot + "next" next-plot + this-plot)] + (-> plot-info + (build-collection-plot user-id review-mode? project-type) + (assoc :navigation (mapv :visible_id nav-plots))) + #_(if plot-info (try (when (not= project-type "simplified") (unlock-plots user-id) (call-sql "lock_plot" - (:plot_id (first plots-info)) + (:plot_id plot-info) user-id (time-plus-five-min))) - (data-response (map #(build-collection-plot % user-id review-mode? project-type) plots-info)) + + (-> plot-info + (build-collection-plot user-id review-mode? project-type) + (assoc :navigation (mapv :visible_id nav-plots)) + #_(data-response)) (catch Exception _e (data-response "Unable to get the requested plot. Please try again."))) (data-response "not-found")))) + + ;;; ;;; Saving Plots ;;; diff --git a/src/js/collection.jsx b/src/js/collection.jsx index b20e55a35..d992a65a6 100644 --- a/src/js/collection.jsx +++ b/src/js/collection.jsx @@ -251,15 +251,15 @@ export const Collection = ({ projectId, acceptedTerms, plotId }) => { console.log("got plot for collection", data); setState (prev=> ({ ... prev, - plotNavigation: data[0].navigation, - userPlotList: data, - remainingPlotters: data, - currentPlot: data[0], - currentUserId: data[0].userId, - ...newPlotValues(data[0]), + plotNavigation: data.navigation, + userPlotList: [data], + remainingPlotters: [data], + currentPlot: data, + currentUserId: data.userId, + ...newPlotValues(data), answerMode: "question", inReviewMode: reviewMode || state.inReviewMode, - newPlotId: data[0].visibleId, + newPlotId: data.visibleId, })); } }) From 9beddadeee4888d3bce6202af91133d791e2cc45 Mon Sep 17 00:00:00 2001 From: Andrew Carlile Date: Wed, 10 Sep 2025 15:02:59 -0400 Subject: [PATCH 2/6] handles all but qaqc, plot locks --- src/clj/collect_earth_online/api.clj | 4 +- src/clj/collect_earth_online/db/plots.clj | 52 +++++++++-------------- src/js/project/PlotDesign.jsx | 5 ++- src/js/project/ReviewForm.jsx | 3 +- src/sql/functions/project.sql | 2 +- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/clj/collect_earth_online/api.clj b/src/clj/collect_earth_online/api.clj index 16d923176..ec3531e9b 100644 --- a/src/clj/collect_earth_online/api.clj +++ b/src/clj/collect_earth_online/api.clj @@ -7,8 +7,7 @@ [triangulum.response :refer [data-response]] [triangulum.type-conversion :as tc] [triangulum.config :refer [get-config]] - [malli.error :as me] - [clojure.pprint :refer [pprint]])) + [malli.error :as me])) (def Int @@ -350,6 +349,7 @@ (data-response (me/humanize (m/explain schema# args#)) {:status 403}))))) (comment + (require '[clojure.pprint :refer [pprint]]) (-> (->> ~(keyword (str query)) (get validation-map) diff --git a/src/clj/collect_earth_online/db/plots.clj b/src/clj/collect_earth_online/db/plots.clj index c432d0c41..acf1c59fa 100644 --- a/src/clj/collect_earth_online/db/plots.clj +++ b/src/clj/collect_earth_online/db/plots.clj @@ -61,8 +61,6 @@ (when (seq foll) (recur (into [this] foll))))))) - - ;;; ;;; Project Level ;;; @@ -263,7 +261,7 @@ "qaqc" (call-sql "select_qaqc_plots" project-id) "similar" (call-sql "select_plots_by_similarity" project-id reference-plot-id) []))) -(require '[clojure.pprint :refer [pprint]]) + (defn get-collection-plot "Gets plot information needed for the collections page. The plot returned is based off of the navigation mode and direction. Valid @@ -277,10 +275,8 @@ :projectType :string? :currentUserId :int-str? :inReviewMode :bool?} - :session {:userId :int-str?}} - -" - [{:keys [params session]}] + :session {:userId :int-str?}}" + [{:keys [params session] :as this}] (let [navigation-mode (:navigationMode params "unanalyzed") direction (:direction params "next") project-id (tc/val->int (:projectId params)) @@ -301,40 +297,34 @@ project-type threshold ref-plot-id) - ;; grouped-plots (group-by :visible_id proj-plots) - - #_sorted-plots #_(case navigation-mode - "qaqc" (sort-by first (filter-plot-disagreement project-id grouped-plots threshold)) - "similar" - (if (some #(= (:visible_id %) old-visible-id) proj-plots) - (filter-pred-idx #(= (:visible_id %) old-visible-id) proj-plots) - (take 3 (into [nil nil] proj-plots))) - (sort-by first grouped-plots)) - sorted-plots (sort-by :visible_id proj-plots) - [next-plot this-plot previous-plot - :as nav-plots] (if (> 0 visible-id) - (into [nil] (take 2 sorted-plots)) - (filter-pred-idx #(= (:visible_id %) visible-id) sorted-plots)) + sorted-plots (case navigation-mode + "similar" proj-plots + "qaqc" (flatten (map second (sort-by first (filter-plot-disagreement project-id (group-by :visible_id proj-plots) threshold)))) + (sort-by :visible_id proj-plots)) + [previous-plot this-plot next-plot + :as nav-plots] (or (filter-pred-idx #(= (:visible_id %) visible-id) sorted-plots) + (into [nil] (take 2 sorted-plots))) plot-info (case direction "previous" previous-plot "next" next-plot - this-plot)] - (-> plot-info - (build-collection-plot user-id review-mode? project-type) - (assoc :navigation (mapv :visible_id nav-plots))) - #_(if plot-info + this-plot) + plot-nav (case direction + "previous" (mapv :visible_id (filter-pred-idx #(= (:visible_id %) (:visible_id previous-plot)) sorted-plots)) + "next" (mapv :visible_id (filter-pred-idx #(= (:visible_id %) (:visible_id next-plot)) sorted-plots) ) + (mapv :visible_id nav-plots))] + + (if plot-info (try (when (not= project-type "simplified") - (unlock-plots user-id) - (call-sql "lock_plot" + #_(unlock-plots user-id) + #_(call-sql "lock_plot" (:plot_id plot-info) user-id (time-plus-five-min))) - (-> plot-info (build-collection-plot user-id review-mode? project-type) - (assoc :navigation (mapv :visible_id nav-plots)) - #_(data-response)) + (assoc :navigation plot-nav) + (data-response)) (catch Exception _e (data-response "Unable to get the requested plot. Please try again."))) (data-response "not-found")))) diff --git a/src/js/project/PlotDesign.jsx b/src/js/project/PlotDesign.jsx index 41f728aad..efb71842c 100644 --- a/src/js/project/PlotDesign.jsx +++ b/src/js/project/PlotDesign.jsx @@ -841,7 +841,7 @@ export class PlotDesign extends React.Component { PlotDesign.contextType = ProjectContext; export function PlotDesignReview() { - const { institutionImagery } = useContext(ProjectContext); + const { institutionImagery } = useContext(ProjectContext); return (
@@ -936,7 +936,8 @@ export function PlotReview() { } export function AOIReview() { - const { aoiFeatures, aoiFileName } = useContext(ProjectContext); + const context = useContext(ProjectContext); + const { aoiFeatures, aoiFileName } = context; const boundaryExtent = mercator.parseGeoJson(aoiFeatures[0], false).getExtent(); return (
diff --git a/src/js/project/ReviewForm.jsx b/src/js/project/ReviewForm.jsx index 06fa69d37..3b950b598 100644 --- a/src/js/project/ReviewForm.jsx +++ b/src/js/project/ReviewForm.jsx @@ -46,8 +46,7 @@ export default function ReviewForm() { ) : null}
- ); - + ); return (
diff --git a/src/sql/functions/project.sql b/src/sql/functions/project.sql index 198e18c68..27e149f68 100644 --- a/src/sql/functions/project.sql +++ b/src/sql/functions/project.sql @@ -606,7 +606,7 @@ CREATE OR REPLACE FUNCTION select_project_by_id(_project_id integer) FROM projects LEFT JOIN project_widgets ON project_rid = project_uid - JOIN geoai_cache gc + LEFT JOIN geoai_cache gc ON gc.project_rid = project_uid WHERE project_uid = _project_id AND availability <> 'archived' From ef3ee29e508b9e4b110069c0b7a12240faed8581 Mon Sep 17 00:00:00 2001 From: Andrew Carlile Date: Tue, 16 Sep 2025 10:18:34 -0400 Subject: [PATCH 3/6] get ids then get plots --- src/clj/collect_earth_online/db/geoai.clj | 2 +- src/clj/collect_earth_online/db/plots.clj | 9 +- src/js/collection.jsx | 13 +- src/js/components/CollectionSidebar.jsx | 113 ++++++++--------- src/js/reviewInstitution.jsx | 6 +- src/sql/functions/plots.sql | 142 ++++++++++++++++++++++ 6 files changed, 217 insertions(+), 68 deletions(-) diff --git a/src/clj/collect_earth_online/db/geoai.clj b/src/clj/collect_earth_online/db/geoai.clj index 37b0a2486..7c6c329dd 100644 --- a/src/clj/collect_earth_online/db/geoai.clj +++ b/src/clj/collect_earth_online/db/geoai.clj @@ -9,7 +9,7 @@ (defonce gcs-resource (st/init - {:project-id (get-config :gcs-integration :project-name) + #_{:project-id (get-config :gcs-integration :project-name) :credentials (get-config :gcs-integration :credentials)})) (defn generate-geojson [project-id] diff --git a/src/clj/collect_earth_online/db/plots.clj b/src/clj/collect_earth_online/db/plots.clj index 41317d58c..bc73f84ae 100644 --- a/src/clj/collect_earth_online/db/plots.clj +++ b/src/clj/collect_earth_online/db/plots.clj @@ -251,7 +251,7 @@ (call-sql "select_simplified_project_plot" project-id) (case navigation-mode "unanalyzed" (call-sql "select_unanalyzed_plots" project-id user-id review-mode?) - "analyzed" (call-sql "select_analyzed_plots" project-id user-id review-mode?) + "analyzed" (call-sfl "select_analyzed_plots" project-id user-id review-mode?) "flagged" (call-sql "select_flagged_plots" project-id user-id review-mode?) "confidence" (call-sql "select_confidence_plots" project-id user-id review-mode? threshold) "natural" (concat (call-sql "select_analyzed_plots" project-id user-id false) @@ -260,7 +260,7 @@ "qaqc" (call-sql "select_qaqc_plots" project-id) "similar" (call-sql "select_plots_by_similarity" project-id reference-plot-id) []))) - +(require '[clojure.pprint :refer [pprint]]) (defn get-collection-plot "Gets plot information needed for the collections page. The plot returned is based off of the navigation mode and direction. Valid @@ -278,6 +278,7 @@ " [{:keys [params session]}] + (pprint {:params params :session session}) (let [navigation-mode (:navigationMode params "unanalyzed") direction (:direction params "next") project-id (tc/val->int (:projectId params)) @@ -302,8 +303,8 @@ "qaqc" (sort-by first (filter-plot-disagreement project-id grouped-plots threshold)) "similar" (if (some #(= (:visible_id %) old-visible-id) proj-plots) - (filter-pred-idx #(= (:visible_id %) old-visible-id) proj-plots) - (take 3 (into [nil nil] proj-plots))) + (filter-pred-idx #(= (:visible_id %) old-visible-id) proj-plots) + (take 3 (into [nil nil] proj-plots))) (sort-by first grouped-plots)) plots-info (case direction "next" (case navigation-mode "similar" diff --git a/src/js/collection.jsx b/src/js/collection.jsx index 191223c02..071fbc652 100644 --- a/src/js/collection.jsx +++ b/src/js/collection.jsx @@ -224,7 +224,18 @@ export const Collection = ({ projectId, acceptedTerms, plotId }) => { }, [state.navigationMode]); // API CALLS - const getPlotData = (visibleId=1, direction, forcedNavMode = null, reviewMode = null) => { + const getPlotData = (visibleId=1, direction, forcedNavMode = null, reviewMode = null) => { + console.log('getting plot', { + visibleId, + projectId, + navigationMode: forcedNavMode || state.navigationMode, + direction, + inReviewMode: reviewMode || state.inReviewMode, + threshold: state.threshold, + currentUserId: state.currentUserId, + projectType: state.currentProject.type, + referencePlotId: state.referencePlotId || 0 + }); processModal("Getting plot", () => { return fetch( "/get-collection-plot?" + diff --git a/src/js/components/CollectionSidebar.jsx b/src/js/components/CollectionSidebar.jsx index 7fb69dce1..b87d5c51c 100644 --- a/src/js/components/CollectionSidebar.jsx +++ b/src/js/components/CollectionSidebar.jsx @@ -36,7 +36,7 @@ export const CollectionSidebar = ({ processModal }) => { ) : null - } + }
@@ -106,12 +106,12 @@ export const NewPlotNavigation = () => { + + + + + {currentProject.referencePlotId && } +
+ Admin Review {navigationMode === "similar" && Reference Plot: {currentProject.referencePlotId}} @@ -129,7 +129,7 @@ export const NewPlotNavigation = () => { { let urlParams=""; if(currentPlot?.plotGeom){ urlParams = currentPlot?.plotGeom?.includes("Point") - ? currentProject?.plotShape === "circle" - ? "center=[" + - mercator.parseGeoJson(currentPlot?.plotGeom).getCoordinates() + - "];radius=" + - currentProject?.plotSize / 2 - : "geoJson=" + - mercator.geometryToGeoJSON( - mercator.getPlotPolygon( - currentPlot?.plotGeom, - currentProject?.plotSize, - currentProject?.plotShape - ), - "EPSG:4326", - "EPSG:3857", - 5 - ) - : "geoJson=" + currentPlot?.plotGeom; + ? currentProject?.plotShape === "circle" + ? "center=[" + + mercator.parseGeoJson(currentPlot?.plotGeom).getCoordinates() + + "];radius=" + + currentProject?.plotSize / 2 + : "geoJson=" + + mercator.geometryToGeoJSON( + mercator.getPlotPolygon( + currentPlot?.plotGeom, + currentProject?.plotSize, + currentProject?.plotShape + ), + "EPSG:4326", + "EPSG:3857", + 5 + ) + : "geoJson=" + currentPlot?.plotGeom; } if (auxWindow) auxWindow.close(); const win = window.open( @@ -349,8 +349,7 @@ export const SidebarFooter = ({ processModal }) => { } else { alert("Answers saved successfully!"); } - } else { - console.log(response); + } else { setAppState(s => ({...s, modal: {alert: {alertType: "Assignment Error", alertMessage: "Error saving your assignments to the database. See console for details."}}})); } }) @@ -377,7 +376,6 @@ export const SidebarFooter = ({ processModal }) => { if (response.ok) { return navToNextPlot(); } else { - console.log(response); setAppState(s => ({...s, modal: {alert: {alertType: "Plot Flagging Error", alertMessage: "Error flagging plot as bad. See console for details."}}})); } }) @@ -423,14 +421,7 @@ export const ImageryOptions = () => { const setAppState = useSetAtom(stateAtom); const [open, setOpen] = useState(true); - const [enableGrid, setEnableGrid] = useState(false); - - useEffect(() => { - console.log(imageryList); - console.log(imagery); - console.log(currentPlot); - }, [currentPlot]); - + const [enableGrid, setEnableGrid] = useState(false); const setBaseMapSource = (id) => { const img = imageryList.find((i) => Number(i.id) === Number(id)) || null; @@ -518,30 +509,30 @@ export const ImageryOptions = () => { {currentImagery.id && imageryList.map((imagery) => { - const visible = currentImagery.id === imagery.id && open; - if (!imagery.sourceConfig) return null; - - const propsForMenu = { - ...commonProps, - key: imagery.id, - thisImageryId: imagery.id, - sourceConfig: imagery.sourceConfig, - visible, - }; - - const byType = { - Planet: , - PlanetDaily: , - PlanetTFO: , - SecureWatch: , - Sentinel1: , - Sentinel2: , - GEEImage: , - GEEImageCollection: , - }; - - return byType[imagery.sourceConfig.type] || null; - })} + const visible = currentImagery.id === imagery.id && open; + if (!imagery.sourceConfig) return null; + + const propsForMenu = { + ...commonProps, + key: imagery.id, + thisImageryId: imagery.id, + sourceConfig: imagery.sourceConfig, + visible, + }; + + const byType = { + Planet: , + PlanetDaily: , + PlanetTFO: , + SecureWatch: , + Sentinel1: , + Sentinel2: , + GEEImage: , + GEEImageCollection: , + }; + + return byType[imagery.sourceConfig.type] || null; + })}