From 1b85f723b48d38cf345bb9a4f3fd01aa6039b50b Mon Sep 17 00:00:00 2001 From: Ruben Beltran del Rio Date: Tue, 2 Feb 2021 09:16:46 +0100 Subject: Initial commit --- Map/Extensions/Map+parse.swift | 106 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 Map/Extensions/Map+parse.swift (limited to 'Map/Extensions/Map+parse.swift') diff --git a/Map/Extensions/Map+parse.swift b/Map/Extensions/Map+parse.swift new file mode 100644 index 0000000..03e7993 --- /dev/null +++ b/Map/Extensions/Map+parse.swift @@ -0,0 +1,106 @@ +import CoreGraphics +import Foundation + +let VERTEX_PATTERN = "([^\\(]+?)[\\s]*\\([\\s]*([0-9]+.?[0-9]*)[\\s]*,[\\s]*([0-9]+.?[0-9]*)[\\s]*\\)" +let EDGE_PATTERN = "(.+?)[\\s]*->[\\s]*(.+)" + +struct ParsedMap { + let vertices: [Vertex] + let edges: [MapEdge] +} + +struct Vertex { + let id: Int + let label: String + let position: CGPoint +} + +struct MapEdge { + let id: Int + let origin: CGPoint + let destination: CGPoint +} + +// Extracts the vertices from the text + +func parseVertices(_ text: String) -> [String: CGPoint] { + + var result: [String: CGPoint] = [:] + let regex = try! NSRegularExpression(pattern: VERTEX_PATTERN, options: .caseInsensitive) + + let lines = text.split(whereSeparator: \.isNewline) + + for line in lines { + let range = NSRange(location: 0, length: line.utf16.count) + let matches = regex.matches(in: String(line), options: [], range: range) + + if matches.count > 0 && matches[0].numberOfRanges == 4{ + + let match = matches[0]; + let key = String(line[Range(match.range(at: 1), in: line)!]) + let xString = String(line[Range(match.range(at: 2), in: line)!]) + let yString = String(line[Range(match.range(at: 3), in: line)!]) + let x = CGFloat(truncating: NumberFormatter().number(from:xString) ?? 0.0) + let y = CGFloat(truncating: NumberFormatter().number(from:yString) ?? 0.0) + let point = CGPoint(x: x, y: y) + + result[key] = point + } + } + + return result +} + +// Extracts the edges from the text + +func parseEdges(_ text: String, vertices: [String: CGPoint]) -> [MapEdge] { + + var result: [MapEdge] = [] + let regex = try! NSRegularExpression(pattern: EDGE_PATTERN, options: .caseInsensitive) + + let lines = text.split(whereSeparator: \.isNewline) + + for (index, line) in lines.enumerated() { + let range = NSRange(location: 0, length: line.utf16.count) + let matches = regex.matches(in: String(line), options: [], range: range) + + if matches.count > 0 && matches[0].numberOfRanges == 3 { + + let match = matches[0]; + let vertexA = String(line[Range(match.range(at: 1), in: line)!]) + let vertexB = String(line[Range(match.range(at: 2), in: line)!]) + + if let origin = vertices[vertexA] { + if let destination = vertices[vertexB] { + result.append(MapEdge(id: index, origin: origin, destination: destination)) + } + } + } + } + + return result +} + +// Converts vetex dictionary to array + +func mapVertices(_ vertices: [String: CGPoint]) -> [Vertex] { + var i = 0 + return vertices.map { label, position in + i += 1; + return Vertex(id: i, label: label, position: position) + } +} + +extension Map { + func parse() -> ParsedMap { + + let text = self.content ?? "" + let vertices = parseVertices(text) + let mappedVertices = mapVertices(vertices) + let edges = parseEdges(text, vertices: vertices) + print(mappedVertices) + print(edges) + + return ParsedMap(vertices: mappedVertices, edges: edges) + } +} -- cgit