Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions data/observational/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from enum import Enum
from typing import Callable, Dict, List, Optional, Tuple

from sqlalchemy import and_, func
from sqlalchemy import and_, func, select
from sqlalchemy.orm import Session, joinedload

from . import DataType, Platform, PlatformMetadata, Sample, Station, engine
Expand Down Expand Up @@ -134,7 +134,7 @@ def get_platform_tracks(
the optional query filters.
"""
funcs = __db_funcs()
query = session.query(
query = select(
Platform.id,
Platform.type,
func.avg(Station.longitude),
Expand All @@ -160,9 +160,11 @@ def get_platform_tracks(
endtime=endtime,
)

query = query.group_by(Platform.id, funcs[quantum](Station.time))
query = query.group_by(Platform.id, funcs[quantum](Station.time)).order_by(
Platform.id, funcs[quantum](Station.time)
)

return query.order_by(Platform.id, funcs[quantum](Station.time)).all()
return session.execute(query).all()


def get_platform_track(
Expand Down Expand Up @@ -326,7 +328,13 @@ def __build_station_query(
meta_key=None,
meta_value=None,
):
query = session.query(Station)
query = select(
Platform.type,
Station.id,
Station.name,
Station.latitude,
Station.longitude,
).join(Station)

# Use index hint
query = query.with_hint(Station, "USE INDEX (idx_stations_time)")
Expand Down Expand Up @@ -378,7 +386,7 @@ def get_stations(
"""
Queries for stations, given the optional query filters.
"""
return __build_station_query(
query = __build_station_query(
session=session,
variable=variable,
mindepth=mindepth,
Expand All @@ -392,7 +400,9 @@ def get_stations(
platform_types=platform_types,
meta_key=meta_key,
meta_value=meta_value,
).all()
)

return session.execute(query).all()


def get_station_time_range(session: Session):
Expand Down
13 changes: 13 additions & 0 deletions oceannavigator/frontend/src/components/Map/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -827,14 +827,27 @@ const Map = forwardRef((props, ref) => {
let url = "";
let extent = mapView.calculateExtent(map0.getSize());
let resolution = mapView.getResolution();
let prevFeatures;
switch (featureType) {
case "observation_points":
prevFeatures = featureVectorSource.getFeatures();
prevFeatures = prevFeatures.filter((feature) => feature.get("class") === "observation")
featureVectorSource.removeFeatures(prevFeatures)

url = `/api/v2.0/observation/point/` + `${featureId}.json`;
break;
case "observation_tracks":
prevFeatures = featureVectorSource.getFeatures();
prevFeatures = prevFeatures.filter((feature) => feature.get("class") === "observation")
featureVectorSource.removeFeatures(prevFeatures)

url = `/api/v2.0/observation/track/` + `${featureId}.json`;
break;
case "class4":
prevFeatures = featureVectorSource.getFeatures();
prevFeatures = prevFeatures.filter((feature) => feature.get("type") === "class4")
featureVectorSource.removeFeatures(prevFeatures)

url =
`/api/v2.0/class4` +
`/${props.class4Type}` +
Expand Down
69 changes: 40 additions & 29 deletions oceannavigator/frontend/src/components/Map/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,17 @@ const I9 = require("../../images/s111/I9.svg").default;

const arrowImages = [I0, I1, I2, I3, I4, I5, I6, I7, I8, I9];

const OBS_COLORS = {
argo: [255, 0, 0],
mission: [255, 255, 0],
drifter: [0, 255, 0],
glider: [0, 255, 255],
animal: [0, 0, 255],
};

const COLORS = [
[0, 0, 255],
[0, 128, 0],
[255, 0, 0],
[0, 255, 255],
[255, 0, 255],
[255, 255, 0],
[0, 0, 0],
[255, 255, 255],
];
Expand All @@ -78,7 +82,7 @@ export const getBasemap = (
source,
projection,
attribution,
topoShadedRelief
topoShadedRelief,
) => {
switch (source) {
case "topo":
Expand Down Expand Up @@ -129,13 +133,13 @@ export const createMap = (
layerFeatureVector,
obsDrawSource,
maxZoom,
mapRef
mapRef,
) => {
const newLayerBasemap = getBasemap(
mapSettings.basemap,
mapSettings.projection,
mapSettings.basemap_attribution,
mapSettings.topoShadedRelief
mapSettings.topoShadedRelief,
);

const vectorTileGrid = new olTilegrid.createXYZ({
Expand Down Expand Up @@ -260,7 +264,7 @@ export const createMap = (
mapObject.getEventPixel(e.originalEvent),
function (feature, layer) {
return feature;
}
},
);
if (feature && feature.get("name")) {
overlay.setPosition(e.coordinate);
Expand All @@ -286,7 +290,7 @@ export const createMap = (
<td>{bearing}</td>
</tr>
)}
</table>
</table>,
);
} else {
popupElement.current.innerHTML = feature.get("name");
Expand All @@ -313,8 +317,8 @@ export const createMap = (
olProj.transform(
f.get("centroid"),
"EPSG:4326",
mapSettings.projection
)
mapSettings.projection,
),
),
text: new Text({
text: f.get("name"),
Expand Down Expand Up @@ -355,8 +359,8 @@ export const createMap = (
<td>{response.data[key]}</td>
</tr>
))}
</table>
)
</table>,
),
);
popupElement.current.innerHTML = feature.get("meta");
})
Expand Down Expand Up @@ -416,7 +420,7 @@ export const createFeatureVectorLayer = (source, mapSettings) => {
style: function (feat, res) {
if (feat.get("class") == "observation") {
if (feat.getGeometry() instanceof olgeom.LineString) {
let color = drifter_color[feat.get("id")];
let color = OBS_COLORS[feat.get("type")];

if (color === undefined) {
color = COLORS[Object.keys(drifter_color).length % COLORS.length];
Expand All @@ -429,6 +433,12 @@ export const createFeatureVectorLayer = (source, mapSettings) => {
width: 8,
}),
}),
new Style({
stroke: new Stroke({
color: "#555555",
width: isMobile ? 6 : 4,
}),
}),
new Style({
stroke: new Stroke({
color: color,
Expand All @@ -452,43 +462,44 @@ export const createFeatureVectorLayer = (source, mapSettings) => {
});
let stroke = new Stroke({ color: "#000000", width: 1 });
let radius = isMobile ? 9 : 6;
switch (feat.get("type")) {
let featureType = feat.get("type");
switch (featureType) {
case "argo":
image = new Circle({
radius: isMobile ? 6 : 4,
fill: new Fill({ color: "#ff0000" }),
fill: new Fill({ color: OBS_COLORS[featureType] }),
stroke: stroke,
});
break;
case "mission":
image = new RegularShape({
points: 3,
radius: radius,
fill: new Fill({ color: "#ffff00" }),
fill: new Fill({ color: OBS_COLORS[featureType] }),
stroke: stroke,
});
break;
case "drifter":
image = new RegularShape({
points: 4,
radius: radius,
fill: new Fill({ color: "#00ff00" }),
fill: new Fill({ color: OBS_COLORS[featureType] }),
stroke: stroke,
});
break;
case "glider":
image = new RegularShape({
points: 5,
radius: radius,
fill: new Fill({ color: "#00ffff" }),
fill: new Fill({ color: OBS_COLORS[featureType] }),
stroke: stroke,
});
break;
case "animal":
image = new RegularShape({
points: 6,
radius: radius,
fill: new Fill({ color: "#0000ff" }),
fill: new Fill({ color: OBS_COLORS[featureType] }),
stroke: stroke,
});
break;
Expand Down Expand Up @@ -520,7 +531,7 @@ export const createFeatureVectorLayer = (source, mapSettings) => {
feat,
"#000",
"#ffffff",
mapSettings
mapSettings,
);
if (textStyle) styles.push(textStyle);

Expand All @@ -544,7 +555,7 @@ export const createFeatureVectorLayer = (source, mapSettings) => {
feat,
"#000",
"#ffffff",
mapSettings
mapSettings,
);
if (textStyle) styles.push(textStyle);
return styles;
Expand All @@ -568,7 +579,7 @@ export const createFeatureVectorLayer = (source, mapSettings) => {
feat,
"#000",
"#ffffff",
mapSettings
mapSettings,
);
if (textStyle) styles.push(textStyle);
return styles;
Expand Down Expand Up @@ -654,7 +665,7 @@ export const createFeatureVectorLayer = (source, mapSettings) => {
const red = Math.min(255, 255 * (feat.get("error_norm") / 0.5));
const green = Math.min(
255,
(255 * (1 - feat.get("error_norm"))) / 0.5
(255 * (1 - feat.get("error_norm"))) / 0.5,
);

return new Style({
Expand All @@ -680,7 +691,7 @@ export const createFeatureTextStyle = (
feature,
textColor = "#000",
strokeColor = "#ffffff",
mapSettings = null
mapSettings = null,
) => {
if (!feature.get("name")) return null;

Expand All @@ -702,8 +713,8 @@ export const createFeatureTextStyle = (
olProj.transform(
feature.get("centroid"),
"EPSG:4326",
mapSettings.projection
)
mapSettings.projection,
),
);
}

Expand Down Expand Up @@ -821,7 +832,7 @@ export const createPlotData = (selected, projection) => {
let id = selected[0].getId();
let name = selected.map((f) => f.get("name"));
let coordinates = selected.map((feature) =>
feature.getGeometry().getCoordinates()
feature.getGeometry().getCoordinates(),
);
// Observations
if (selected[0].get("class") === "observation") {
Expand Down Expand Up @@ -853,7 +864,7 @@ export const createPlotData = (selected, projection) => {
title = selected.map((feature, idx) =>
feature.get("name")
? feature.get("name")
: `${formatLatLon(coordinates[idx][0], coordinates[idx][1])}`
: `${formatLatLon(coordinates[idx][0], coordinates[idx][1])}`,
);
title = "Point - " + title.join(", ");
} else if (type === "LineString") {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import React, {
useState,
useEffect,
useRef,
useMemo,
memo,
} from "react";
import React, { useState, useEffect, useRef, useMemo, memo } from "react";
import Button from "react-bootstrap/Button";
import OverlayTrigger from "react-bootstrap/OverlayTrigger";
import Tooltip from "react-bootstrap/Tooltip";
Expand Down Expand Up @@ -88,16 +82,6 @@ function TimeSlider({ id, dataset, timestamps, selected, onChange }) {
return () => clearInterval(interval);
}, [scrollSpeed]);

useEffect(() => {
document.addEventListener("mousemove", handleThumbMousemove);
document.addEventListener("mouseup", handleThumbMouseup);
document.addEventListener("mouseleave", handleThumbMouseup);
return () => {
document.removeEventListener("mousemove", handleThumbMousemove);
document.removeEventListener("mouseup", handleThumbMouseup);
document.removeEventListener("mouseleave", handleThumbMouseup);
};
}, [timestamps, tickWidth]);

useEffect(() => {
if (contentRef.current && scrollTrackRef.current) {
Expand Down Expand Up @@ -158,7 +142,7 @@ function TimeSlider({ id, dataset, timestamps, selected, onChange }) {
const updateTickContainerWidth = () => {
if (!scrollTrackRef.current || timestamps.length === 0) return;

let minTickWidth = 70;
let minTickWidth = 105;
if (dataset.quantum === "hour" && dataset.id !== "giops_day") {
minTickWidth = 35;
}
Expand Down Expand Up @@ -427,7 +411,12 @@ function TimeSlider({ id, dataset, timestamps, selected, onChange }) {
));

return (
<div className="time-slider">
<div
className="time-slider"
onMouseMove={handleThumbMousemove}
onMouseDown={handleThumbMousedown}
onMouseUp={handleThumbMouseup}
>
<div className="nav-button-container">{leftButtons}</div>
<div className="time-slider-container">
<div
Expand Down
2 changes: 0 additions & 2 deletions oceannavigator/frontend/src/components/lib/ComboBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import Icon from "./Icon.jsx";
import PropTypes from "prop-types";
import { withTranslation } from "react-i18next";

import { useGetComboBoxQuery } from "../../remote/queries.js";

function ComboBox({
id,
label,
Expand Down
Loading
Loading