From 641624d2389b6150b4b52b759307c6650c61d717 Mon Sep 17 00:00:00 2001 From: Araozu Date: Tue, 10 Sep 2024 17:40:32 -0500 Subject: [PATCH] fix edge case where a routes first way was upside down --- main.go | 64 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 5d3979c..8e8c06a 100644 --- a/main.go +++ b/main.go @@ -122,6 +122,12 @@ func main() { } log.Println("XML unmarshal finished") + // Create a map of IDs to Nodes + nodesMap := make(map[int64]*OsmNode) + for _, node := range osmDocument.Nodes { + nodesMap[node.Id] = &node + } + // Get the relation with id 17642638, // that relation hosts the SIT data var sitId int64 = 17642638 @@ -181,7 +187,7 @@ func main() { // Convert each CombiData into a CombiRoute and store it for idx, combi := range combis { - if idx > 0 { + if idx > 10 { break } @@ -189,7 +195,7 @@ func main() { returnCoord := make([][]float64, 0) combiRoute := CombiRoute{ Name: combi.Ref, - Departure: getCoordinates(&osmDocument.Ways, &osmDocument.Nodes, combi.Members), + Departure: getCoordinates(&osmDocument.Ways, nodesMap, combi.Members), Return: &returnCoord, } combiLineSlice := combiRoutesMap[combi.Id] @@ -199,7 +205,7 @@ func main() { writeOutput(combiLineMap, combiRoutesMap) } -func getCoordinates(ways *[]OsmWay, nodes *[]OsmNode, membersSlice *[]OsmMember) *[][]float64 { +func getCoordinates(ways *[]OsmWay, nodes map[int64]*OsmNode, membersSlice *[]OsmMember) *[][]float64 { coordinates := make([][]float64, 0) // The coordinate list may be reversed @@ -210,6 +216,7 @@ func getCoordinates(ways *[]OsmWay, nodes *[]OsmNode, membersSlice *[]OsmMember) // without duplicates orderedCoordinates := make([]*OsmNode, 0) var previousNodeId int64 = -1 + var previousWayId int64 = -1 // get all coordinates from each for _, member := range *membersSlice { @@ -227,11 +234,15 @@ func getCoordinates(ways *[]OsmWay, nodes *[]OsmNode, membersSlice *[]OsmMember) if previousNodeId == -1 { // just add all + secondWay := findOsmway((*membersSlice)[1].Ref, ways) + coords = findFirstCoord(way, secondWay, nodes) for _, c := range coords { orderedCoordinates = append(orderedCoordinates, c) } + // keep track of the last id previousNodeId = coords[coordsLen-1].Id + previousWayId = way.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, @@ -242,6 +253,7 @@ func getCoordinates(ways *[]OsmWay, nodes *[]OsmNode, membersSlice *[]OsmMember) // keep track of the last id previousNodeId = coords[coordsLen-1].Id + previousWayId = way.Id } else if coords[coordsLen-1].Id == previousNodeId { // if not, they are reversed // add all except the last @@ -251,8 +263,9 @@ func getCoordinates(ways *[]OsmWay, nodes *[]OsmNode, membersSlice *[]OsmMember) // keep track of the last id previousNodeId = coords[0].Id + previousWayId = way.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) + log.Fatalf("Found a way that didn't connect to the previous way. Expected to find node(%d) in way(%d), the previous way id is (%d)", previousNodeId, way.Id, previousWayId) } } @@ -267,18 +280,43 @@ func getCoordinates(ways *[]OsmWay, nodes *[]OsmNode, membersSlice *[]OsmMember) return &coordinates } -func findNode(id int64, nodes *[]OsmNode) *OsmNode { - var coordinateNode *OsmNode - for _, newNode := range *nodes { - if newNode.Id == id { - coordinateNode = &newNode - } +func findFirstCoord(firstWay, secondWay *OsmWay, nodes map[int64]*OsmNode) []*OsmNode { + // find the common point + first := make([]*OsmNode, 0) + for _, node := range firstWay.Nds { + coordinate := findNode(node.Ref, nodes) + first = append(first, coordinate) } - if coordinateNode == nil { + firstLast := len(first) - 1 + second := make([]*OsmNode, 0) + for _, node := range secondWay.Nds { + coordinate := findNode(node.Ref, nodes) + second = append(second, coordinate) + } + secondLast := len(second) - 1 + + if first[firstLast].Id == second[0].Id || first[firstLast].Id == second[secondLast].Id { + return first + } else if first[0].Id == second[0].Id || first[0].Id == second[secondLast].Id { + // reverse the slice + newFirst := make([]*OsmNode, len(first)) + for i := 0; i < len(first); i += 1 { + newFirst[i] = first[firstLast-i] + } + + return newFirst + } else { + log.Fatalf("Could not find 2 points in common between 2 ways with ids %d & %d", firstWay.Id, secondWay.Id) + panic("") + } +} + +func findNode(id int64, nodes map[int64]*OsmNode) *OsmNode { + node := nodes[id] + if node == nil { log.Fatalf("Node with id %s not found", id) } - - return coordinateNode + return node } func findOsmway(id int64, ways *[]OsmWay) *OsmWay {