Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
80a2229
1849-show-more-trajectory-information: make string as resource
sandradeng20 Dec 3, 2024
bf90357
1849-show-more-trajectory-information: update mapbox secret token set…
sandradeng20 Jan 23, 2025
6001ead
1849-show-more-trajectory-information: fix empty trajectory processing
sandradeng20 Jan 31, 2025
c56a4bc
1849-show-more-trajectory-information: refactor code
sandradeng20 Jan 31, 2025
62ff6d4
1849-show-more-trajectory-information: reformat code
sandradeng20 Jan 31, 2025
a6d0653
Merge branch 'main' into 1849-show-more-trajectory-information
abbybernstein Feb 7, 2025
0c76715
add postgres logic to create layer by activity
abbybernstein Feb 11, 2025
f6591ba
connect trajectory by activity layer to timeline app
abbybernstein Feb 11, 2025
30b4b96
change colors by activity type
abbybernstein Feb 11, 2025
1cadf91
add activity summary functionality
abbybernstein Feb 12, 2025
3d98c44
fix postgres activity type assignment
abbybernstein Feb 18, 2025
4b21e40
add trajectory summary colorcoded
abbybernstein Feb 20, 2025
a5f395c
fix summary updating error
abbybernstein Feb 20, 2025
b4f3f42
fix colors
abbybernstein Feb 20, 2025
d795199
Print trajectory info by session
abbybernstein Feb 26, 2025
5fabc91
add summary to bottom sheet
abbybernstein Feb 27, 2025
c46519b
fix page switch loaidng behavior
abbybernstein Mar 4, 2025
880728f
fix centering trajectory
abbybernstein Mar 4, 2025
3a37197
refactor files
abbybernstein Mar 4, 2025
e8d375a
resolve comments
abbybernstein Mar 6, 2025
1cc4285
resolve comments
abbybernstein Mar 10, 2025
bbe55ea
simplifying sql
abbybernstein Mar 10, 2025
7f06941
interactable trajectoryline
abbybernstein Mar 11, 2025
407e686
fix sql script for layer creation
abbybernstein Mar 13, 2025
935da95
fix sql script
abbybernstein Mar 13, 2025
205fd14
fix trajectory interactability
abbybernstein Mar 13, 2025
f8b3eed
resolve comments
abbybernstein Mar 17, 2025
773669c
update user agent
abbybernstein Mar 17, 2025
dda320e
upate trajectoryqueryagent image
abbybernstein Mar 17, 2025
59a1fa1
Merge branch 'main' into 1849-show-more-trajectory-information
abbybernstein Mar 17, 2025
62242c6
fix errors
abbybernstein Mar 18, 2025
f1b2bff
1849-show-more-trajectory-information: resolve comments
sandradeng20 Mar 19, 2025
b64c5cd
redesign trajectory classes
abbybernstein Mar 24, 2025
f064269
fix xml
abbybernstein Mar 26, 2025
59a9842
clickability fixed
abbybernstein Mar 26, 2025
6a73793
fix trajectory line clicking
abbybernstein Apr 1, 2025
c65834b
resolve comments
abbybernstein Apr 1, 2025
e9ef455
resolve comments
abbybernstein Apr 2, 2025
a6a2ffd
resolve comments
abbybernstein Apr 2, 2025
f1a34ce
fix error
abbybernstein Apr 2, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,17 @@ BEGIN
RETURN CONCAT('https://www.theworldavatar.com/kg/sensorloggerapp/sessionID_', device_id);
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION get_activity_type_iri(device_id VARCHAR)
RETURNS VARCHAR AS $$
BEGIN
RETURN CONCAT('https://www.theworldavatar.com/kg/sensorloggerapp/activity_type_', device_id);
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION get_confidence_level_iri(device_id VARCHAR)
RETURNS VARCHAR AS $$
BEGIN
RETURN CONCAT('https://www.theworldavatar.com/kg/sensorloggerapp/confidence_level_', device_id);
END;
$$ LANGUAGE plpgsql;
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,17 @@ target sensorloggerapp:smartphone_{device_id} ontodevice:hasScreenBrightnes
om:hasValue sensorloggerapp:brightness_measure_{device_id} .
sensorloggerapp:brightness_measure_{device_id} a om:Measure .
source SELECT device_id, sensor_class FROM devices WHERE sensor_class='RelativeBrightness'

mappingId activitytype
target sensorloggerapp:activity_type_{device_id} rdf:type sensorloggerapp:ActivityType ;
sensorloggerapp:hasActivityType "{activity_type}"^^xsd:string .
source SELECT device_id, activity_type FROM your_table WHERE activity_type IS NOT NULL;

mappingId confidencelevel
target sensorloggerapp:confidence_level_{device_id} rdf:type sensorloggerapp:ConfidenceLevel ;
sensorloggerapp:hasConfidenceLevel "{confidence_level}"^^xsd:string .
source SELECT device_id, confidence_level FROM your_table WHERE confidence_level IS NOT NULL;



]]
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public JSONObject getDatesWithData(String timezone, String userId) {
response.put("message", "Succeed");
response.put("result", result);
} else {
response.put("message", "Faile");
response.put("message", "Failed");
}

return response;
Expand Down Expand Up @@ -236,6 +236,32 @@ private void createGeoserver() {
geoServerClient.createPostGISLayer(workspaceName, dbName, "trajectoryUserIdLineSegments",
geoServerVectorSettings);
}


String lineLayerUserIdByActivity = null;
try (InputStream is = new ClassPathResource("line_layer_user_id_by_activity.sql").getInputStream()) {
lineLayerUserIdByActivity = IOUtils.toString(is, StandardCharsets.UTF_8);
} catch (IOException e) {
LOGGER.error("failed to read line_layer_user_id_by_activity.sql");
LOGGER.error(e.getMessage());
}

if (lineLayerUserIdByActivity != null) {
geoServerClient.createWorkspace(workspaceName);
UpdatedGSVirtualTableEncoder virtualTable = new UpdatedGSVirtualTableEncoder();
GeoServerVectorSettings geoServerVectorSettings = new GeoServerVectorSettings();
virtualTable.setSql(lineLayerUserIdByActivity);
virtualTable.setEscapeSql(true);
virtualTable.setName("line_layer_user_id_by_activity_table");
virtualTable.addVirtualTableGeometry("geom", "Geometry", "4326");
virtualTable.addVirtualTableParameter("user_id", "null", ".*");
virtualTable.addVirtualTableParameter("upperbound", "0", "^(0|[1-9][0-9]*)$");
virtualTable.addVirtualTableParameter("lowerbound", "0", "^(0|[1-9][0-9]*)$");
geoServerVectorSettings.setVirtualTable(virtualTable);
geoServerClient.createPostGISDataStore(workspaceName, "trajectory", dbName, schema);
geoServerClient.createPostGISLayer(workspaceName, dbName, "trajectoryUserIdByActivity", geoServerVectorSettings);
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,103 @@ BEGIN
RETURN QUERY EXECUTE query;
END $$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION get_activity_table(
device_id_array TEXT[]
)
RETURNS TABLE (
"time" bigint,
"activity_type" VARCHAR,
"confidence_level" smallint,
"session_id" character varying,
"device_id" TEXT,
"user_id" TEXT
) AS $$
DECLARE
query TEXT := '';
device_id TEXT;
BEGIN
DROP TABLE IF EXISTS temp_activity_data;
CREATE TEMP TABLE temp_activity_data (
time bigint,
activity_type VARCHAR,
confidence_level smallint,
session_id character varying,
device_id TEXT,
user_id TEXT,
index INT
);


FOR i IN 1..array_length(device_id_array, 1) LOOP
IF i > 1 THEN
query := query || ' UNION ALL ';
END IF;

device_id := device_id_array[i];


query := query || format(
'SELECT time, %I AS activity_type, %I AS confidence_level, %I AS session_id, %L AS device_id, %L AS user_id FROM %I WHERE time_series_iri = %L',
get_column_name(get_activity_type_iri(device_id)),
get_column_name(get_confidence_level_iri(device_id)),
get_column_name(get_session_iri(device_id)),
device_id,
get_user_id(device_id),
get_table_name(get_activity_type_iri(device_id)),
get_time_series(get_activity_type_iri(device_id))
);
END LOOP;


EXECUTE 'INSERT INTO temp_activity_data
WITH activity_data AS (' || query || ')
SELECT time, activity_type, confidence_level, session_id, device_id, user_id,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY time) AS index
FROM activity_data;';


EXECUTE '
WITH filled_backward AS (
SELECT *,
COALESCE(NULLIF(activity_type, ''others''),
LAG(activity_type) OVER (PARTITION BY user_id ORDER BY index)) AS activity_type_filled
FROM temp_activity_data
)
UPDATE temp_activity_data t
SET activity_type = f.activity_type_filled
FROM filled_backward f
WHERE t.index = f.index;';


EXECUTE '
WITH filled_forward AS (
SELECT *,
COALESCE(NULLIF(activity_type, ''others''),
FIRST_VALUE(activity_type) OVER (PARTITION BY user_id ORDER BY index ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)) AS activity_type_filled
FROM temp_activity_data
)
UPDATE temp_activity_data t
SET activity_type = f.activity_type_filled
FROM filled_forward f
WHERE t.index = f.index;';


RETURN QUERY
SELECT
t.time,
t.activity_type,
t.confidence_level,
t.session_id,
t.device_id,
t.user_id
FROM
temp_activity_data AS t
ORDER BY
t.user_id, t.time;

END $$ LANGUAGE plpgsql;


-- used by timeline app only
CREATE OR REPLACE FUNCTION get_device_ids(id VARCHAR)
RETURNS TEXT AS
Expand All @@ -144,4 +241,5 @@ BEGIN
RETURN phone_id_list;
END;
$$
LANGUAGE plpgsql;
LANGUAGE plpgsql

Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
WITH distinct_devices AS (
SELECT
array_agg(device_id::text) AS device_list
FROM
(SELECT DISTINCT device_id
FROM devices
WHERE sensor_class = 'Activity') AS distinct_devices
),

timeseries AS (
SELECT
timeseries.time AS time,
timeseries.speed AS speed,
timeseries.altitude AS altitude,
timeseries.geom AS geom,
timeseries.bearing AS bearing,
timeseries.session_id AS session_id,
timeseries.user_id AS user_id
FROM
public.get_location_table((SELECT device_list FROM distinct_devices)) AS timeseries
ORDER BY time
),

activity_data AS (
SELECT
activity_data.time AS time,
activity_data.user_id AS user_id,
activity_data.activity_type AS activity_type,
activity_data.confidence_level AS confidence_level
FROM
public.get_activity_table((SELECT device_list FROM distinct_devices)) AS activity_data
ORDER BY time
),

joined_data AS (
SELECT
t.time,
t.speed,
t.altitude,
t.geom,
t.bearing,
t.session_id,
t.user_id,
a.activity_type,
a.confidence_level
FROM
timeseries t
JOIN
activity_data a
ON
t.user_id = a.user_id
AND ABS(t.time - a.time) <= 5000 -- Allow a 5-second difference
ORDER BY t.time
),

fixed_activity_data AS (
SELECT
time,
speed,
altitude,
geom,
bearing,
session_id,
user_id,
activity_type,
confidence_level
FROM (
SELECT
time,
speed,
altitude,
geom,
bearing,
session_id,
user_id,
activity_type,
confidence_level,
LAG(time) OVER (PARTITION BY user_id ORDER BY time) AS prev_time
FROM joined_data
) AS subquery
WHERE time <> prev_time
),

change_marked AS (
SELECT
*,
CASE
WHEN
LAG(activity_type) OVER (PARTITION BY user_id ORDER BY time) IS NULL
THEN 0
WHEN
LAG(activity_type) OVER (PARTITION BY user_id ORDER BY time) IS DISTINCT FROM activity_type
THEN 1
ELSE 0
END AS change_flag
FROM fixed_activity_data
),

change_marked_union AS (
SELECT
time,
speed,
altitude,
geom,
bearing,
session_id,
user_id,
activity_type,
confidence_level,
change_flag
FROM change_marked

UNION ALL
SELECT
time,
speed,
altitude,
geom,
bearing,
session_id,
user_id,
COALESCE(LAG(activity_type) OVER (PARTITION BY user_id ORDER BY time), 'others') as activity_type,
confidence_level,
0 AS change_flag
FROM change_marked
WHERE change_flag = 1
ORDER BY time, change_flag
),

numbered_activity_data AS (
SELECT
*,
SUM(change_flag) OVER (PARTITION BY user_id ORDER BY time ROWS UNBOUNDED PRECEDING) + 1 AS id
FROM change_marked_union cm
ORDER BY cm.time, cm.change_flag
),

filled_activity_data AS (
SELECT
*,
COALESCE(
NULLIF(activity_type, 'others'),
LAG(activity_type) OVER (PARTITION BY user_id ORDER BY time),
FIRST_VALUE(activity_type) OVER (PARTITION BY user_id ORDER BY time ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
) AS filled_activity_type
FROM numbered_activity_data
)

SELECT
MIN(na.time) AS start_time,
MAX(na.time) AS end_time,
na.id,
na.filled_activity_type AS activity_type,
na.session_id,
ST_MakeLine(ARRAY_AGG(na.geom ORDER BY na.time)) AS geom,
ST_Length(ST_Transform(ST_MakeLine(ARRAY_AGG(na.geom ORDER BY na.time)), 3857))::INTEGER AS distance_traveled,
CONCAT('https://w3id.org/MON/person.owl#person_', na.user_id) AS iri
FROM
filled_activity_data AS na
WHERE
('%user_id%' = '' OR na.user_id = '%user_id%')
AND ('%lowerbound%' = '0' OR na.time > '%lowerbound%'::BIGINT)
AND ('%upperbound%' = '0' OR na.time < '%upperbound%'::BIGINT)
GROUP BY
na.id, na.filled_activity_type, na.user_id, na.session_id
Loading