예제 #1
0
        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;
        }
예제 #2
0
        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;
        }
예제 #3
0
 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;
         }
     }
 }
예제 #4
0
        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);
        }
예제 #5
0
 public XamlMapInfo(RoomInfo location, IEnumerable<ElementDescription> elements, double scale)
 {
     this.elements = elements;
     UpdateBounds(scale);
 }
예제 #6
0
 public XamlMapInfo(RoomInfo location, string svgDocContent, double scale)
 {
     elements = (List<ElementDescription>)Newtonsoft.Json.JsonConvert.DeserializeObject(svgDocContent, typeof(List<ElementDescription>));
     UpdateBounds(scale);
 }
예제 #7
0
        ///// <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);
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
 public static IEnumerable<ElementDescription> ParseVisioDoc(RoomInfo location, string content)
 {
     var _this = new VisioParser();
     return _this.parseit(location, content);
 }
예제 #10
0
        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);
        }
예제 #11
0
        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;
        }
예제 #12
0
        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);
        }