public static List<ElementDescription> ParseSvgDoc(RoomInfo location, string svgDocContent) { var elements = new List<ElementDescription>(); XElement doc = null; try { doc = XDocument.Parse(svgDocContent).Root; } catch (Exception e) { throw new Exception("Could not load the map for " + "building '" + location.Building + "', " + "floor'" + location.Floor + "'\n" + e.Message); } foreach (XElement node in doc.Nodes().OfType<XElement>()) { foreach (XElement node2 in node.Nodes().OfType<XElement>()) { elements.Add(ParseSvgElement(node2, node.Attribute("id").Value)); } } elements = elements.Where(p => p != null).ToList(); return elements; }
public static List<ElementDescription> ParseSvgDoc(RoomInfo location, string rawContent) { int ind = rawContent.IndexOf(" id='thesvg'"); if (ind > 0) { rawContent = "<svg " + rawContent.Substring(ind); } ind = rawContent.IndexOf(" id=\"thesvg\""); if (ind > 0) { rawContent = "<svg " + rawContent.Substring(ind); } // Now do some hacky junk string svgDocContent = FixClosingTags(rawContent); var elements = new List<ElementDescription>(); XElement doc = null; try { doc = XDocument.Parse(svgDocContent).Root; } catch (Exception e) { throw new Exception("Could not load the map for " + "building '" + location.Building + "', " + "floor'" + location.Floor + "'\n" + e.Message); } foreach (XElement node in doc.Nodes().OfType<XElement>()) { foreach (XElement node2 in node.Nodes().OfType<XElement>()) { elements.Add(ParseSvgElement(node2, node.Attribute("id").Value)); } } elements = elements.Where(p => p != null).ToList(); return elements; }
public XamlMapInfo(RoomInfo location, string svgDocContent) { elements = SvgParser.ParseSvgDoc(location, svgDocContent); foreach (var description in elements) { switch (description.Type) { case ElementType.Circle: buildingBounds.UpdateBounds(description.CenterX, description.CenterY); break; case ElementType.Text: buildingBounds.UpdateBounds(description.CenterX, description.CenterY); int roomNumber; if (int.TryParse(description.Text, out roomNumber)) { RoomLocations.Add(roomNumber, new Point(description.CenterX, description.CenterY)); } break; case ElementType.Path: default: break; } } }
public void Render(Canvas funky, Canvas parent, Canvas window, CompositeTransform textRotation, Action<Action> dispatcher, RoomInfo location) { dispatcher(() => { CompositeTransform c = (CompositeTransform)funky.RenderTransform; c.CenterX = buildingBounds.CenterX; c.CenterY = buildingBounds.CenterY; funky.Width = buildingBounds.Width; funky.Height = buildingBounds.Height; c.TranslateX = -buildingBounds.CenterX + window.ActualWidth / 2; c.TranslateY = -buildingBounds.CenterY + window.ActualHeight / 2; }); foreach (var description in elements.Where(p => p.Parent == ParentType.Labels || p.Parent == ParentType.Rooms)) { this.checkRunActions(50, () => RenderElement(parent, textRotation, description), dispatcher); } // Highlight the correct room this.checkRunActions(1, () => { var roomElement = parent.Children.OfType<Path>().FirstOrDefault(p => ToInt(p.Tag as string) == location.Room); if (roomElement != null) { roomElement.Fill = new SolidColorBrush(Colors.Magenta); } }, dispatcher); foreach (var description in elements.Where(p => p.Parent == ParentType.Background)) { // Fewer because these paths are more complex this.checkRunActions(5, () => RenderElement(parent, textRotation, description), dispatcher); } this.checkRunActions(0, () => { }, dispatcher); }
public XamlMapInfo(RoomInfo location, IEnumerable<ElementDescription> elements, double scale) { this.elements = elements; UpdateBounds(scale); }
public XamlMapInfo(RoomInfo location, string svgDocContent, double scale) { elements = (List<ElementDescription>)Newtonsoft.Json.JsonConvert.DeserializeObject(svgDocContent, typeof(List<ElementDescription>)); UpdateBounds(scale); }
///// <summary> ///// If the point is in a hall, just return it. Else, move the point so that it is ///// inside the nearest hall. ///// </summary> ///// <param name="p"></param> ///// <returns></returns> //public Point RebasePointToHall(Point testPoint) //{ // // We have the hall outlines, // Tuple<Point, double> prevNearestWall = null; // foreach (var x in elements.Where(p => p.IsHall.Value)) // { // var nearestWall = x.GetClosestWallIntersection(testPoint); // if (nearestWall.Item2 <= 0) // { // return testPoint; // } // else if (prevNearestWall == null || nearestWall.Item2 < prevNearestWall.Item2) // { // prevNearestWall = nearestWall; // } // } // return prevNearestWall.Item1; //} //public Point? GetRoomLocation(int room) //{ // Point loc; // return (RoomLocations.TryGetValue(room, out loc) ? (Point?)loc : null); //} public async Task Render(UIElementCollection childCollection, Transform textRotation, Action<BoundingRectangle, double, double> mapBounds, Func<Action, Task> dispatcher, RoomInfo location, FrameworkElement overlay) { // Use the whole object to allow the overlay to render in the meantime. if (overlay.ActualWidth == 0 || overlay.ActualHeight == 0) { #if NETFX_CORE EventHandler<object> foo = null; foo = (object sender, object e) => #else EventHandler foo = null; foo = (object sender, EventArgs e) => #endif { mapBounds(buildingBounds, overlay.ActualWidth, overlay.ActualHeight); overlay.LayoutUpdated -= foo; }; overlay.LayoutUpdated += foo; } else { await dispatcher(() => mapBounds(buildingBounds, overlay.ActualWidth, overlay.ActualHeight)); } // Do the rooms first foreach (var description in elements .Where(p => p.Parent == ParentType.Labels || p.Parent == ParentType.Rooms) .Where(p => p.Type != ElementType.Text)) { await this.checkRunActions(50, () => RenderElement(childCollection, textRotation, description), dispatcher); } // Then the text on top foreach (var description in elements .Where(p => p.Parent == ParentType.Labels || p.Parent == ParentType.Rooms) .Where(p => p.Type == ElementType.Text)) { await this.checkRunActions(50, () => RenderElement(childCollection, textRotation, description), dispatcher); } // Highlight the correct room await this.checkRunActions(1, () => { var roomElement = childCollection.OfType<Path>().FirstOrDefault(p => ToInt(p.Tag as string) == location.Room); if (roomElement != null) { roomElement.Fill = new SolidColorBrush(Colors.Magenta); } }, dispatcher); foreach (var description in elements.Where(p => p.Parent == ParentType.Background)) { // Fewer because these paths are more complex // await this.checkRunActions(50, () => RenderElement(childCollection, textRotation, description), dispatcher); } await this.checkRunActions(0, () => { }, dispatcher); }
async static public Task<string> LoadMapSvg(RoomInfo location, Action<bool> waiter) { // Check cache waiter(true); try { string filename = "Maps/" + location.Building + "-" + location.Floor + ".svg"; IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication(); if (store.FileExists(filename)) { // TODO: Add app-wide support for clearing cache var content = store.OpenFile(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read); string svgDocContent = new System.IO.StreamReader(content).ReadToEnd(); return svgDocContent; } // Not in cache, so need to access files on server. if (!await TryLogin()) { return null; } // OK, user has permission so lets try to get the data from the server. var mapTable = service.GetTable<Map>(); List<Map> maps = null; try { maps = await mapTable.Where(p => p.Building == location.Building && p.Floor == location.Floor).ToListAsync(); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } if (maps == null || maps.Count() == 0) { MessageBox.Show("Server does not have a map for: " + location.ToString()); #if !NETFX_CORE return null; #else // Upload mode StreamResourceInfo resource = Application.GetResourceStream(new Uri(filename, UriKind.Relative)); string content0 = new StreamReader(resource.Stream).ReadToEnd(); var chunks = Chunker(content0, 1024 * 128); for (int i = 0; i < chunks.Length; i++) { var newMap = new Map() { Floor = location.Floor, Building = location.Building, Part = i, SVG = chunks[i] }; Debug.WriteLine("inserting " + i + " of " + chunks.Length); await mapTable.InsertAsync(newMap); } maps = await mapTable.Where(p => p.Building == location.Building && p.Floor == location.Floor).ToListAsync(); if (maps.Count() == 0) { MessageBox.Show("Still wrong!"); return null; } #endif } // Map is on the server string svg = string.Join("", maps.OrderBy(p => p.Part).Select(p => p.SVG)); if (!store.DirectoryExists("Maps")) { store.CreateDirectory("Maps"); } var content2 = store.OpenFile(filename, FileMode.OpenOrCreate, FileAccess.Write); byte[] bytes = Encoding.UTF8.GetBytes(svg); content2.Write(bytes, 0, bytes.Length); content2.Flush(); content2.Close(); return svg; } finally { waiter(false); } }
public static IEnumerable<ElementDescription> ParseVisioDoc(RoomInfo location, string content) { var _this = new VisioParser(); return _this.parseit(location, content); }
private IEnumerable<ElementDescription> parseit(RoomInfo location, string content) { var ret = new List<ElementDescription>(); try { var xd = XDocument.Parse(content); layerDescriptions = xd.Root.Descendants(ns + "Layer").Select(p => p.Value).ToArray(); double pageWidthInch = double.Parse(xd.Root.Descendants(ns + "PageWidth").First().Value); double pageHeightInch = double.Parse(xd.Root.Descendants(ns + "PageHeight").First().Value); pageWidth = pageWidthInch * ptsMultiplier; pageHeight = pageHeightInch * ptsMultiplier; var xx = xd.Root.Descendants(ns + "Shape"); foreach (var x in xx) { if (x.Attribute("LineStyle") == null || x.Attribute("LineStyle").Value != "2") Debug.WriteLine("A: " + x.ToString()); if (x.Attribute("TextStyle") == null || x.Attribute("TextStyle").Value != "3") Debug.WriteLine("B: " + x.ToString()); if (x.Attribute("Type") == null || x.Attribute("Type").Value != "Shape") { Debug.WriteLine("C: " + x.ToString()); continue; } Line l = new Line(); foreach (var xxx in x.Elements()) { Parse(xxx, l); } foreach (var el in ConvertToElements(l)) { ret.Add(el); } } } catch (Exception e) { throw new Exception("Could not load the map for " + "building '" + location.Building + "', " + "floor'" + location.Floor + "'\n" + e.Message); } return ret.Where(p => p != null); }
private async Task<object> ShowMap(RoomInfo location) { if (location == null) return null; string svgDocContent = await CloudAccesser.LoadMapSvg(location, Waiter); UpdateLoginLogoutUI(); if (svgDocContent == null) return null; ResetMap(); this.roomDisplay.Text = location.ToString(); roomDisplay.Visibility = Visibility.Visible; ContentPanel.Visibility = Visibility.Collapsed; funky.Visibility = Visibility.Visible; Foo.Visibility = Visibility.Visible; funkyKids.Children.Clear(); var f = this.funky; var fk = this.funkyKids; var resources = this.Resources; var textRotation = (CompositeTransform)this.Resources["antiRotation"]; var dispatcher = this.Dispatcher; var tcs = new TaskCompletionSource<object>(); System.Threading.Thread t = new System.Threading.Thread(() => { map = new XamlMapInfo(location, svgDocContent); map.Render(f, fk, Foo, textRotation, (x) => dispatcher.BeginInvoke(x), location); tcs.SetResult(null); }); t.Start(); return tcs.Task; }
private async Task ShowMap(RoomInfo location, GeoCoord? loc = null) { if (location == null) return; string content = await CloudAccesser.LoadMapSvg(location, Waiter); MapMetadata mapMetadata = await CloudAccesser.LoadMapMetadata(location); #if NETFX_CORE || WINDOWS_PHONE UpdateLoginLogoutUI(); #endif if (content == null) return; this.roomDisplay.Text = ""; view.ResetMap(); this.roomDisplay.Text = location.ToString(); roomDisplay.Visibility = Visibility.Visible; ContentPanel.Visibility = Visibility.Collapsed; view.Visibility = Visibility.Visible; overlay.Visibility = Visibility.Visible; var resources = this.Resources; var dispatcher = this.Dispatcher; var map = new XamlMapInfo(location, content, mapScaleFactor); this.view.MapMetadata = mapMetadata; await map.Render(view.LiveChildCollection, view.TextRotation, (a, b, c) => { this.view.SetViewForMap(a, b, c); if (loc.HasValue) { view.ShowScanLoc(loc.Value); } }, RunOnUIThread, location, overlay); }