diff --git a/cmd/main.go b/cmd/main.go
index 5a48e9a..dcc1961 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -134,6 +134,7 @@ func feedifyVehicles(vehicles []*pb.VehiclePosition, header *pb.FeedHeader, rout
rows, err := scheduleDb.Query(`
SELECT
trips.route_id,
+ trips.shape_id,
trips.trip_headsign,
routes.route_type,
routes.route_color,
@@ -150,6 +151,7 @@ func feedifyVehicles(vehicles []*pb.VehiclePosition, header *pb.FeedHeader, rout
}
var route_id string
+ var shape_id string
var trip_headsign sql.NullString
var route_type int32
var route_color sql.NullString
@@ -160,7 +162,7 @@ func feedifyVehicles(vehicles []*pb.VehiclePosition, header *pb.FeedHeader, rout
continue
}
- err = rows.Scan(&route_id, &trip_headsign, &route_type, &route_color, &route_short_name, &route_long_name)
+ err = rows.Scan(&route_id, &shape_id, &trip_headsign, &route_type, &route_color, &route_short_name, &route_long_name)
if err != nil {
fmt.Println(err)
continue
@@ -195,7 +197,8 @@ func feedifyVehicles(vehicles []*pb.VehiclePosition, header *pb.FeedHeader, rout
ShortName: route_short_name.String,
LongName: route_long_name.String,
},
- TripId: *vehicle.Trip.TripId,
+ TripId: *vehicle.Trip.TripId,
+ ShapeId: shape_id,
})
}
@@ -288,6 +291,37 @@ func tripHandler(w http.ResponseWriter, r *http.Request) {
w.Write(response)
}
+func shapeHandler(w http.ResponseWriter, r *http.Request) {
+ rows, err := scheduleDb.Query(`SELECT shapes.shape_pt_lat, shapes.shape_pt_lon FROM shapes WHERE shapes.shape_id = ? ORDER BY shapes.shape_pt_sequence ASC`, r.PathValue("shape"))
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ var points [][]float64
+
+ for rows.Next() {
+ var lat float64
+ var lon float64
+ err = rows.Scan(&lat, &lon)
+ if err != nil {
+ break
+ }
+
+ points = append(points, []float64{lat, lon})
+ }
+
+ if len(points) == 0 {
+ w.WriteHeader(http.StatusNotFound)
+ return
+ }
+
+ w.Header().Add("Content-Type", "application/json")
+
+ response, _ := json.Marshal(map[string]any{"shape": points})
+ w.Write(response)
+}
+
func main() {
fmt.Println("Opening database...")
@@ -307,6 +341,7 @@ func main() {
http.HandleFunc("/api", vehicleHandler(""))
http.HandleFunc("/api.json", vehicleHandler("json"))
http.HandleFunc("/api/trips/{trip}", tripHandler)
+ http.HandleFunc("/api/shapes/{shape}", shapeHandler)
port := "3000"
if portEnv, ok := os.LookupEnv("PORT"); ok {
diff --git a/proto/schema.pb.go b/proto/schema.pb.go
index ebb1182..73a46ec 100644
--- a/proto/schema.pb.go
+++ b/proto/schema.pb.go
@@ -386,6 +386,7 @@ type VehicleFeed_Vehicle struct {
Headsign string `protobuf:"bytes,7,opt,name=headsign,proto3" json:"headsign,omitempty"`
Route *VehicleFeed_Route `protobuf:"bytes,8,opt,name=route,proto3" json:"route,omitempty"`
TripId string `protobuf:"bytes,10,opt,name=trip_id,json=tripId,proto3" json:"trip_id,omitempty"`
+ ShapeId string `protobuf:"bytes,11,opt,name=shape_id,json=shapeId,proto3" json:"shape_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -490,11 +491,18 @@ func (x *VehicleFeed_Vehicle) GetTripId() string {
return ""
}
+func (x *VehicleFeed_Vehicle) GetShapeId() string {
+ if x != nil {
+ return x.ShapeId
+ }
+ return ""
+}
+
var File_proto_schema_proto protoreflect.FileDescriptor
const file_proto_schema_proto_rawDesc = "" +
"\n" +
- "\x12proto/schema.proto\"\xe8\x06\n" +
+ "\x12proto/schema.proto\"\x83\a\n" +
"\vVehicleFeed\x120\n" +
"\bvehicles\x18\x01 \x03(\v2\x14.VehicleFeed.VehicleR\bvehicles\x12)\n" +
"\x04info\x18\x02 \x01(\v2\x15.VehicleFeed.FeedInfoR\x04info\x1a+\n" +
@@ -519,7 +527,7 @@ const file_proto_schema_proto_rawDesc = "" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
"\x04name\x18\x02 \x01(\tR\x04name\x12\x10\n" +
"\x03lat\x18\x03 \x01(\x02R\x03lat\x12\x10\n" +
- "\x03lon\x18\x04 \x01(\x02R\x03lon\x1a\xba\x02\n" +
+ "\x03lon\x18\x04 \x01(\x02R\x03lon\x1a\xd5\x02\n" +
"\aVehicle\x12\x10\n" +
"\x03lat\x18\x01 \x01(\x02R\x03lat\x12\x10\n" +
"\x03lon\x18\x02 \x01(\x02R\x03lon\x12\x18\n" +
@@ -531,7 +539,8 @@ const file_proto_schema_proto_rawDesc = "" +
"\bheadsign\x18\a \x01(\tR\bheadsign\x12(\n" +
"\x05route\x18\b \x01(\v2\x12.VehicleFeed.RouteR\x05route\x12\x17\n" +
"\atrip_id\x18\n" +
- " \x01(\tR\x06tripId\"Z\n" +
+ " \x01(\tR\x06tripId\x12\x19\n" +
+ "\bshape_id\x18\v \x01(\tR\ashapeId\"Z\n" +
"\x04Line\x12\x14\n" +
"\x10LINE_UNSPECIFIED\x10\x00\x12\t\n" +
"\x05GREEN\x10\x01\x12\a\n" +
diff --git a/proto/schema.proto b/proto/schema.proto
index c71fb73..f8cd618 100644
--- a/proto/schema.proto
+++ b/proto/schema.proto
@@ -1,4 +1,5 @@
syntax = "proto3";
+
option go_package = "github.com/cjdenio/uta-trax-api/proto";
message VehicleFeed {
@@ -49,6 +50,7 @@ message VehicleFeed {
string headsign = 7;
Route route = 8;
string trip_id = 10;
+ string shape_id = 11;
}
repeated Vehicle vehicles = 1;
diff --git a/static/index.html b/static/index.html
index 309b7e7..07bf4ad 100644
--- a/static/index.html
+++ b/static/index.html
@@ -300,6 +300,6 @@
-
+