github.com/LdDl/ch@v1.7.8/import.go (about) 1 package ch 2 3 import ( 4 "encoding/csv" 5 "fmt" 6 "io" 7 "os" 8 "strconv" 9 10 "github.com/pkg/errors" 11 ) 12 13 // ImportFromFile Imports graph (prepared by ExportToFile(fname string) function) from file of CSV-format 14 // Header of CSV-file containing information about edges: 15 // from_vertex_id - int64, ID of source vertex 16 // to_vertex_id - int64, ID of arget vertex 17 // weight - float64, Weight of an edge 18 // Header of CSV-file containing information about vertices: 19 // vertex_id - int64, ID of vertex 20 // order_pos - int, Position of vertex in hierarchies (evaluted by library) 21 // importance - int, Importance of vertex in graph (evaluted by library) 22 // Header of CSV-file containing information about shortcuts between vertices: 23 // from_vertex_id - int64, ID of source vertex 24 // to_vertex_id - int64, ID of target vertex 25 // weight - float64, Weight of an shortcut 26 // via_vertex_id - int64, ID of vertex through which the shortcut exists 27 func ImportFromFile(edgesFname, verticesFname, contractionsFname string) (*Graph, error) { 28 // Read edges first 29 file, err := os.Open(edgesFname) 30 if err != nil { 31 return nil, err 32 } 33 defer file.Close() 34 reader := csv.NewReader(file) 35 reader.Comma = ';' 36 37 graph := Graph{} 38 39 // Fill graph with edges informations 40 // Skip header of CSV-file 41 _, err = reader.Read() 42 if err != nil { 43 return nil, err 44 } 45 // Read file line by line 46 for { 47 record, err := reader.Read() 48 if err == io.EOF { 49 break 50 } 51 sourceExternal, err := strconv.ParseInt(record[0], 10, 64) 52 if err != nil { 53 return nil, err 54 } 55 targetExternal, err := strconv.ParseInt(record[1], 10, 64) 56 if err != nil { 57 return nil, err 58 } 59 60 weight, err := strconv.ParseFloat(record[2], 64) 61 if err != nil { 62 return nil, err 63 } 64 65 err = graph.CreateVertex(sourceExternal) 66 if err != nil { 67 return nil, errors.Wrap(err, fmt.Sprintf("Can't add source vertex with external_ID = '%d'", sourceExternal)) 68 } 69 err = graph.CreateVertex(targetExternal) 70 if err != nil { 71 return nil, errors.Wrap(err, fmt.Sprintf("Can't add target vertex with external_ID = '%d'", targetExternal)) 72 } 73 74 err = graph.AddEdge(sourceExternal, targetExternal, weight) 75 if err != nil { 76 return nil, errors.Wrap(err, fmt.Sprintf("Can't add edge with source_internal_ID = '%d' and target_internal_ID = '%d'", sourceExternal, targetExternal)) 77 } 78 } 79 80 // Read vertices 81 fileVertices, err := os.Open(verticesFname) 82 if err != nil { 83 return nil, err 84 } 85 defer fileVertices.Close() 86 readerVertices := csv.NewReader(fileVertices) 87 readerVertices.Comma = ';' 88 89 // Skip header of CSV-file 90 _, err = readerVertices.Read() 91 if err != nil { 92 return nil, err 93 } 94 // Read file line by line 95 for { 96 record, err := readerVertices.Read() 97 if err == io.EOF { 98 break 99 } 100 101 vertexExternal, err := strconv.ParseInt(record[0], 10, 64) 102 if err != nil { 103 return nil, err 104 } 105 vertexOrderPos, err := strconv.ParseInt(record[1], 10, 64) 106 if err != nil { 107 return nil, err 108 } 109 vertexImportance, err := strconv.Atoi(record[2]) 110 if err != nil { 111 return nil, err 112 } 113 114 vertexInternal, vertexFound := graph.FindVertex(vertexExternal) 115 if !vertexFound { 116 return nil, fmt.Errorf("Vertex with Label = %d is not found in graph", vertexExternal) 117 } 118 graph.Vertices[vertexInternal].SetOrderPos(vertexOrderPos) 119 graph.Vertices[vertexInternal].SetImportance(vertexImportance) 120 } 121 122 // Read contractions 123 fileShortcuts, err := os.Open(contractionsFname) 124 if err != nil { 125 return nil, err 126 } 127 defer fileShortcuts.Close() 128 readerShortcuts := csv.NewReader(fileShortcuts) 129 readerShortcuts.Comma = ';' 130 // Skip header of CSV-file 131 _, err = readerShortcuts.Read() 132 if err != nil { 133 return nil, err 134 } 135 // Read file line by line 136 for { 137 record, err := readerShortcuts.Read() 138 if err == io.EOF { 139 break 140 } 141 sourceExternal, err := strconv.ParseInt(record[0], 10, 64) 142 if err != nil { 143 return nil, err 144 } 145 targetExternal, err := strconv.ParseInt(record[1], 10, 64) 146 if err != nil { 147 return nil, err 148 } 149 150 weight, err := strconv.ParseFloat(record[2], 64) 151 if err != nil { 152 return nil, err 153 } 154 contractionExternal, err := strconv.ParseInt(record[3], 10, 64) 155 if err != nil { 156 return nil, err 157 } 158 159 err = graph.AddEdge(sourceExternal, targetExternal, weight) 160 if err != nil { 161 return nil, errors.Wrap(err, fmt.Sprintf("Can't add shortcut with source_internal_ID = '%d' and target_internal_ID = '%d'", sourceExternal, targetExternal)) 162 } 163 164 err = graph.AddShortcut(sourceExternal, targetExternal, contractionExternal, weight) 165 if err != nil { 166 return nil, errors.Wrap(err, fmt.Sprintf("Can't add shortcut with source_internal_ID = '%d' and target_internal_ID = '%d' to internal map", sourceExternal, targetExternal)) 167 } 168 } 169 return &graph, nil 170 } 171 172 // ImportRestrictionsFromFile Imports turn restrictions from file of CSV-format into graph 173 // 174 // Header of CSV-file: 175 // from_vertex_id;via_vertex_id;to_vertex_id; 176 // int;int;int 177 // 178 func (graph *Graph) ImportRestrictionsFromFile(fname string) error { 179 file, err := os.Open(fname) 180 if err != nil { 181 return err 182 } 183 reader := csv.NewReader(file) 184 reader.Comma = ';' 185 186 // skip header 187 _, err = reader.Read() 188 if err != nil { 189 return err 190 } 191 // read lines 192 for { 193 record, err := reader.Read() 194 if err == io.EOF { 195 break 196 } 197 sourceExternal, err := strconv.ParseInt(record[0], 10, 64) 198 if err != nil { 199 return err 200 } 201 viaExternal, err := strconv.ParseInt(record[1], 10, 64) 202 if err != nil { 203 return err 204 } 205 targetExternal, err := strconv.ParseInt(record[2], 10, 64) 206 if err != nil { 207 return err 208 } 209 210 err = graph.AddTurnRestriction(sourceExternal, viaExternal, targetExternal) 211 if err != nil { 212 return errors.Wrap(err, fmt.Sprintf("Can't add restriction between source_external_ID = '%d' and target_external_ID = '%d' via via_external_id = '%d'", sourceExternal, targetExternal, viaExternal)) 213 } 214 } 215 return nil 216 }