From 753652542c364a479d6863f71faffab2ebf8cc72 Mon Sep 17 00:00:00 2001 From: Araozu Date: Tue, 10 Sep 2024 17:07:23 -0500 Subject: [PATCH] Fix incorrect ways coordinates orientation --- main.go | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 4c7cdfa..5d3979c 100644 --- a/main.go +++ b/main.go @@ -83,8 +83,9 @@ type CombiData struct { // E.g.: "Combi B: Villa Santa Rosa -> Terminal Terrestre" Name string // Indentifiable name of the route - Ref string - Color string + Ref string + Color string + Members *[]OsmMember } // Type to be consumed by the client @@ -101,9 +102,9 @@ type CombiRouteContainer struct { } type CombiRoute struct { - Name string `json:"name"` - Departure []float64 `json:"departure"` - Return []float64 `json:"return"` + Name string `json:"name"` + Departure *[][]float64 `json:"departure"` + Return *[][]float64 `json:"return"` } func main() { @@ -179,11 +180,17 @@ func main() { } // Convert each CombiData into a CombiRoute and store it - for _, combi := range combis { + for idx, combi := range combis { + if idx > 0 { + break + } + + log.Printf("Processing %s %s", combi.Company, combi.Ref) + returnCoord := make([][]float64, 0) combiRoute := CombiRoute{ Name: combi.Ref, - Departure: make([]float64, 0), - Return: make([]float64, 0), + Departure: getCoordinates(&osmDocument.Ways, &osmDocument.Nodes, combi.Members), + Return: &returnCoord, } combiLineSlice := combiRoutesMap[combi.Id] combiLineSlice.Routes = append(combiLineSlice.Routes, combiRoute) @@ -192,6 +199,101 @@ func main() { writeOutput(combiLineMap, combiRoutesMap) } +func getCoordinates(ways *[]OsmWay, nodes *[]OsmNode, membersSlice *[]OsmMember) *[][]float64 { + coordinates := make([][]float64, 0) + + // The coordinate list may be reversed + // we shold check that the end of the previous set + // matches the beginning of the next set + + // stores all the osmways in order, + // without duplicates + orderedCoordinates := make([]*OsmNode, 0) + var previousNodeId int64 = -1 + + // get all coordinates from each + for _, member := range *membersSlice { + + // get the way + way := findOsmway(member.Ref, ways) + + // get all its coordinates + coords := make([]*OsmNode, 0) + for _, node := range way.Nds { + coordinate := findNode(node.Ref, nodes) + coords = append(coords, coordinate) + } + coordsLen := len(coords) + + if previousNodeId == -1 { + // just add all + for _, c := range coords { + orderedCoordinates = append(orderedCoordinates, c) + } + // keep track of the last id + previousNodeId = coords[coordsLen-1].Id + } else if coords[0].Id == previousNodeId { + // check if the first coordinate is the same as the previous stored + // if so, add them except the first one, + // and keep track of the last one + for i := 1; i < coordsLen; i += 1 { + orderedCoordinates = append(orderedCoordinates, coords[i]) + } + + // keep track of the last id + previousNodeId = coords[coordsLen-1].Id + } else if coords[coordsLen-1].Id == previousNodeId { + // if not, they are reversed + // add all except the last + for i := coordsLen - 2; i >= 0; i -= 1 { + orderedCoordinates = append(orderedCoordinates, coords[i]) + } + + // keep track of the last id + previousNodeId = coords[0].Id + } else { + log.Fatalf("Found a way whose ends didn't connect to the previous way. Expected to find %d in way with id %d", previousNodeId, way.Id) + } + } + + // Now compile all the coordinates + for _, coordinate := range orderedCoordinates { + coordsSlice := make([]float64, 2) + coordsSlice[0] = coordinate.Lat + coordsSlice[1] = coordinate.Lon + coordinates = append(coordinates, coordsSlice) + } + + return &coordinates +} + +func findNode(id int64, nodes *[]OsmNode) *OsmNode { + var coordinateNode *OsmNode + for _, newNode := range *nodes { + if newNode.Id == id { + coordinateNode = &newNode + } + } + if coordinateNode == nil { + log.Fatalf("Node with id %s not found", id) + } + + return coordinateNode +} + +func findOsmway(id int64, ways *[]OsmWay) *OsmWay { + var way *OsmWay + for _, currentWay := range *ways { + if currentWay.Id == id { + way = ¤tWay + } + } + if way == nil { + log.Fatalf("Way with id %d not found", id) + } + return way +} + func writeOutput(lines map[string]*CombiLine, routes map[int]*CombiRouteContainer) { // Create output folder os.MkdirAll("output", os.ModePerm) @@ -276,6 +378,7 @@ func parseCombiData(member OsmRelation) CombiData { Name: nameTag.V, Ref: refTag.V, Color: colorTag.V, + Members: &member.Members, } }