using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using MapsDb; using MapsDb.Models; using Newtonsoft.Json; namespace MapConsole { class OsmImport { protected PostgresDbContext _context; public OsmImport() { _context = new PostgresDbContext(); } public async void Index() { Curl curl = new Curl(); string result = await curl.SendRequest(); XmlDocument xDoc = new XmlDocument(); xDoc.LoadXml(result); XmlElement xRoot = xDoc.DocumentElement; if (xRoot.Name != "osm") { return; } int nodes, ways, relations; nodes = ways = relations = 0; foreach (XmlNode child in xRoot) { switch(child.Name) { case "node": nodes++; break; case "way": ways++; break; case "relation": relations++; break; } } string answer = ""; answer += "Nodes count: " + nodes + "\n"; answer += "Ways count: " + ways + "\n"; answer += "Relations count: " + relations; Console.WriteLine(answer); } public async void Create() { string filename = "base.xml"; int trackId = 1; XDocument doc = new XDocument( new XElement("library", new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Rap"), new XAttribute("time", "3:24"), new XElement("name", "Who We Be RMX (feat. 2Pac)"), new XElement("artist", "DMX"), new XElement("album", "The Dogz Mixtape: Who's Next?!") ), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Rap"), new XAttribute("time", "5:06"), new XElement("name", "Angel (ft. Regina Bell)"), new XElement("artist", "DMX"), new XElement("album", "...And Then There Was X") ), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Break Beat"), new XAttribute("time", "6:16"), new XElement("name", "Dreaming Your Dreams"), new XElement("artist", "Hybrid"), new XElement("album", "Wide Angle") ), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Break Beat"), new XAttribute("time", "9:38"), new XElement("name", "Finished Symphony"), new XElement("artist", "Hybrid"), new XElement("album", "Wide Angle") ) ) ); FileStream stream = new FileStream(filename, FileMode.Append); doc.Save(stream); Console.WriteLine(doc.ToString()); } public async void Update() { string filename = "base.xml"; FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite); XDocument xDoc = XDocument.Load(stream); stream.Dispose(); stream = new FileStream(filename, FileMode.Truncate, FileAccess.ReadWrite); foreach (XElement el in xDoc.Root.Elements("track")) { int id = Int32.Parse(el.Attribute("id").Value); el.SetAttributeValue("id", id + 5); } xDoc.Save(stream); Console.WriteLine(xDoc.ToString()); } public async void Add() { string filename = "base.xml"; FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite); XDocument doc = XDocument.Load(stream); stream.Dispose(); stream = new FileStream(filename, FileMode.Truncate, FileAccess.ReadWrite); int maxId = doc.Root.Elements("track").Max(t => Int32.Parse(t.Attribute("id").Value)); XElement track = new XElement("track", new XAttribute("id", ++maxId), new XAttribute("genre", "Break Beat"), new XAttribute("time", "5:35"), new XElement("name", "Higher Than A Skyscraper"), new XElement("artist", "Hybrid"), new XElement("album", "Morning Sci-Fi") ); doc.Root.Add(track); doc.Save(stream); Console.WriteLine(doc.ToString()); } public async void Delete() { string filename = "base.xml"; FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite); XDocument doc = XDocument.Load(stream); stream.Dispose(); stream = new FileStream(filename, FileMode.Truncate, FileAccess.ReadWrite); // IEnumerable tracks = doc.Root.Descendants("track").Where( // t => t.Element("artist").Value == "Hybrid" // ).ToList(); // foreach (XElement t in tracks) // { // t.Remove(); // } doc.Root.Descendants("track").Where( t => t.Element("artist").Value == "Hybrid" ).Remove(); doc.Save(stream); Console.WriteLine(doc.ToString()); } public async Task Relation(int Id) { await Task.Run(async () => { Curl curl = new Curl(); string result = await curl.GetRelation(Id); this.SaveRelation(result); }); } public async Task Relation() { await Task.Run(async () => { Curl curl = new Curl(); string result = await curl.GetRelation(2143112); XDocument doc = XDocument.Parse(result); IEnumerable relations = doc.Root.Elements("relation"); List relation_ids = new List(); foreach (XElement relation in relations) { XElement tag = (from t in relation.Elements("tag") where t.Attribute("k").Value == "ref" select t).SingleOrDefault(); if (tag != null) { string name = tag.Attribute("v").Value; if (name.Length == 4) { relation_ids.Add(Int32.Parse(relation.Attribute("id").Value)); } } } foreach (int relation_id in relation_ids) { string relationXml = await curl.GetRelation(relation_id); this.SaveRelation(relationXml); } }); } protected void SaveRelation(string relation) { XDocument doc = XDocument.Parse(relation); XElement relationEl = doc.Root.Element("relation"); string relationRemoteId = relationEl.Attribute("id").Value; string[] inserted = { }; if (inserted.Contains(relationRemoteId)) { Console.WriteLine("Skipped relation " + relationRemoteId); return; } XElement tag = (from t in relationEl.Elements("tag") where t.Attribute("k").Value == "ref" select t).Single(); int index = Int32.Parse(tag.Attribute("v").Value.Substring(2)); Road road = _context.Road.SingleOrDefault(t => t.RoadTypeId == 1 && t.Index == index); if (road == null) { return ; } Relation relationDb = _context.Relation.SingleOrDefault(t => t.RemoteId == relationEl.Attribute("id").Value); if (relationDb == null) { relationDb = new Relation() { RemoteId = relationEl.Attribute("id").Value }; _context.Relation.Add(relationDb); Console.WriteLine("Relation " + relationDb.RemoteId + " Created for Road M-" + road.Index); } else { Console.WriteLine("Relation " + relationDb.RemoteId + " Found for Road M-" + road.Index); } _context.SaveChanges(); RelationToRoad relationToRoad = _context.RelationToRoad.SingleOrDefault(t => t.RoadId == road.Id && t.RelationId == relationDb.Id); if (relationToRoad == null) { relationToRoad = new RelationToRoad() { RoadId = road.Id, RelationId = relationDb.Id }; _context.RelationToRoad.Add(relationToRoad); } _context.SaveChanges(); Console.WriteLine("Relation " + relationDb.RemoteId + " linked to Road M-" + road.Index); this.SaveWays(doc, relationDb.Id); Console.WriteLine("Relation " + relationDb.RemoteId +" insertion completed for Road M-" + road.Index); } protected void SaveWays(XDocument doc, int relationId) { XElement relation = doc.Root.Element("relation"); IEnumerable wayIds = from t in relation.Elements("member") where t.Attribute("type").Value == "way" select t.Attribute("ref").Value; int index = 1; foreach (string wayId in wayIds) { XElement wayXml = doc.Root.Elements("way").Where(t => t.Attribute("id").Value == wayId).SingleOrDefault(); if (wayXml == null) { continue; } Way way = _context.Way.Where(t => t.RemoteId == wayId).SingleOrDefault(); if (way == null) { way = new Way() { RemoteId = wayId }; _context.Way.Add(way); Console.WriteLine("Way " + wayId + " Created for Relation " + relationId); } else { Console.WriteLine("Way " + wayId + " Found for Relation " + relationId); } _context.SaveChanges(); WayToRelation wayToRelation = _context.WayToRelation.Where(t => t.RelationId == relationId && t.WayId == way.Id).SingleOrDefault(); if (wayToRelation == null) { wayToRelation = new WayToRelation() { RelationId = relationId, WayId = way.Id, Index = index }; _context.WayToRelation.Add(wayToRelation); Console.WriteLine("Way " + way.Id + " to Relation " + relationId + " link was created with Index " + index); } else { wayToRelation.Index = index; Console.WriteLine("Way " + way.Id + " to Relation " + relationId + " link was updated with Index " + index); } _context.SaveChanges(); this.SavePoints(doc, wayId, way.Id); Console.WriteLine("Way " + wayId +" insertion completed"); index++; } } protected void SavePoints(XDocument doc, string wayRemoteId, int wayId) { XElement wayXml = (from t in doc.Root.Elements("way") where t.Attribute("id").Value == wayRemoteId select t) .SingleOrDefault(); if (wayXml == null) { return; } int index = 1; foreach (XElement pointXml in wayXml.Elements("nd")) { string pointId = pointXml.Attribute("ref").Value; XElement nodeXml = doc.Root.Elements("node").Where(t => t.Attribute("id").Value == pointId).SingleOrDefault(); if(nodeXml == null) { continue; } decimal lat, lon; lat = decimal.Parse(nodeXml.Attribute("lat").Value); lon = decimal.Parse(nodeXml.Attribute("lon").Value); Node node = _context.Node.Where(t => t.RemoteId == pointId).SingleOrDefault(); if (node == null) { node = new Node() { RemoteId = pointId, Lat = lat, Lon = lon, }; _context.Node.Add(node); Console.WriteLine("Point " + pointId + " created for Way " + wayId + " at Lat:" + lat + " Lon:" + lon); } else { node.Lat = lat; node.Lon = lon; Console.WriteLine("Point " + pointId + " updated for Way " + wayId + " at Lat:" + lat + " Lon:" + lon); } _context.SaveChanges(); NodeToWay nodeToWay = _context.NodeToWay.Where(t => t.WayId == wayId && t.NodeId == node.Id).SingleOrDefault(); if (nodeToWay == null) { nodeToWay = new NodeToWay() { NodeId = node.Id, WayId = wayId, Index = index }; _context.NodeToWay.Add(nodeToWay); } else { nodeToWay.Index = index; } _context.SaveChanges(); Console.WriteLine("Point " + pointId + " linked to Way " + wayId); index++; } } } }