Skip to content

Commit

Permalink
Merge pull request #24 from olincollege/SAN-92-vehicle-dir
Browse files Browse the repository at this point in the history
SAN-92 Vehicle Direction
  • Loading branch information
cory0417 authored Feb 5, 2025
2 parents 4572177 + 9742908 commit 93ebb86
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 5 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ pytest~=8.3.3
sphinx~=8.1.3
pygris~=0.1.6
aiohttp~=3.10.10
duckdb~=1.1.3
5 changes: 5 additions & 0 deletions src/night_light/GIS_predictor/crosswalk_center.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ def find_crosswalk_centers(con: duckdb.DuckDBPyConnection):
ped_edge_mid AS (
SELECT
crosswalk_id,
street_segment_id,
geometry as ped_edge_geom,
ST_Point(
(
ST_X(ST_PointN(ST_GeomFromText(geometry), 1)) +
Expand All @@ -77,6 +79,9 @@ def find_crosswalk_centers(con: duckdb.DuckDBPyConnection):
centers AS (
SELECT
e.crosswalk_id,
e.street_segment_id,
e.ped_edge_geom,
ST_AsText(i.intersection_center) AS street_center_point,
ST_AsText(
ST_Point(
(ST_X(e.edge_mid) + ST_X(i.intersection_center)) / 2.0,
Expand Down
30 changes: 25 additions & 5 deletions src/night_light/GIS_predictor/edge_classifier/edge_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,34 @@ def classify_edges_by_intersection(con: duckdb.DuckDBPyConnection):
-- 1. Add a new boolean column
ALTER TABLE crosswalk_segments
ADD COLUMN is_vehicle_edge BOOLEAN;
ALTER TABLE crosswalk_segments
ADD COLUMN street_segment_id INT;
-- 2. Update is_vehicle_edge = TRUE if there's any intersection, otherwise FALSE
UPDATE crosswalk_segments
SET is_vehicle_edge = (
SELECT COUNT(*) > 0
FROM street_segments s
WHERE ST_Intersects(ST_GeomFromText(crosswalk_segments.geometry), ST_GeomFromText(s.geometry))
);
SET
is_vehicle_edge = (
SELECT COUNT(*) > 0
FROM street_segments s
WHERE ST_Intersects(ST_GeomFromText(crosswalk_segments.geometry), ST_GeomFromText(s.geometry))
),
street_segment_id = (
SELECT MAX(t.street_segment_id)
FROM (
SELECT cs2.crosswalk_id,
-- For each crosswalk segment of this crosswalk, get one street segment id
(SELECT s.OBJECTID
FROM street_segments s
WHERE ST_Intersects(
ST_GeomFromText(cs2.geometry),
ST_GeomFromText(s.geometry)
)
LIMIT 1
) AS street_segment_id
FROM crosswalk_segments cs2
WHERE cs2.crosswalk_id = crosswalk_segments.crosswalk_id
) t
);
"""
)

Expand Down
129 changes: 129 additions & 0 deletions src/night_light/GIS_predictor/vehicle_direction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import duckdb

from night_light.bronze_db import util


def identify_vehicle_direction(con: duckdb.DuckDBPyConnection):
"""
Identify the direction of the vehicle for each side of the road segment.
- Case 1: If the crosswalk center’s X value is greater than the street center
point’s X value, we assume the vehicle is moving from “y_smaller” to “y_larger.”
– For the from_coord, choose the vertex of the pedestrian edge with the smaller
Y value.
– For the to_coord, choose the vertex with the larger Y value.
- Case 2: If the crosswalk center’s X is less than the street center point’s X
value, we assume the reverse:
– For from_coord, choose the vertex with the larger Y.
– For to_coord, choose the vertex with the smaller Y.
- Case 3: If the crosswalk center’s Y is greater than the street center point’s Y
value, we assume the vehicle is moving from “x_larger” to “x_smaller.”
– For from_coord, choose the vertex with the larger X value.
– For to_coord, choose the vertex with the smaller X value.
- Case 4: If the crosswalk center’s Y is less than the street center point’s Y
value, then:
– For from_coord, choose the vertex with the smaller X value.
– For to_coord, choose the vertex with the larger X value.
"""
con.execute(
"""
-- Add columns to store the from/to direction
ALTER TABLE crosswalk_centers DROP COLUMN IF EXISTS from_coord;
ALTER TABLE crosswalk_centers DROP COLUMN IF EXISTS to_coord;
ALTER TABLE crosswalk_centers ADD COLUMN from_coord VARCHAR;
ALTER TABLE crosswalk_centers ADD COLUMN to_coord VARCHAR;
-- Update them based on the comparison result
UPDATE crosswalk_centers
SET
from_coord = CASE
WHEN ST_X(ST_GeomFromText(geometry)) > ST_X(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
< ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
WHEN ST_X(ST_GeomFromText(geometry)) < ST_X(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
> ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
WHEN ST_Y(ST_GeomFromText(geometry)) > ST_Y(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
> ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
WHEN ST_Y(ST_GeomFromText(geometry)) < ST_Y(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
< ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
ELSE 'undefined'
END,
to_coord = CASE
WHEN ST_X(ST_GeomFromText(geometry)) > ST_X(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
> ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
WHEN ST_X(ST_GeomFromText(geometry)) < ST_X(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
< ST_Y(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
WHEN ST_Y(ST_GeomFromText(geometry)) > ST_Y(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
< ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
WHEN ST_Y(ST_GeomFromText(geometry)) < ST_Y(ST_GeomFromText(street_center_point))
THEN (
CASE
WHEN ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
> ST_X(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
THEN ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 1))
ELSE ST_AsText(ST_PointN(ST_GeomFromText(ped_edge_geom), 2))
END
)
ELSE 'undefined'
END;
"""
)


if __name__ == "__main__":
con = util.connect_to_duckdb("edge_classifier/edge_classifier.db")
identify_vehicle_direction(con)
util.save_table_to_geojson(
con,
"crosswalk_centers",
"crosswalk_centers.geojson",
)

0 comments on commit 93ebb86

Please sign in to comment.