private void buttonSnapshot_Click(object sender, EventArgs e) { try { using (var phandle = new ProcessHandle(_pid, ProcessAccess.QueryInformation | ProcessAccess.VmRead)) { _currentHtCollection = phandle.GetHandleTraces(); if (_symbols != null) { _symbols.Dispose(); } SymbolProvider.Options |= SymbolOptions.DeferredLoads; _symbols = new SymbolProvider(phandle); WorkQueue.GlobalQueueWorkItem(new Action(() => { var symbols = _symbols; _symbols.PreloadModules = true; try { foreach (var module in phandle.GetModules()) { try { symbols.LoadModule(module.FileName, module.BaseAddress); } catch { } } } catch { } try { foreach (var module in Windows.GetKernelModules()) { try { symbols.LoadModule(module.FileName, module.BaseAddress); } catch { } } } catch { } })); } this.PopulateHandleTraceList(); } catch (Exception ex) { this.ShowException("Error getting the handle trace snapshot", ex); } }
public EventProperties(LogEvent even) { InitializeComponent(); _event = even; textSystemCall.Text = MainWindow.SysCallNames.ContainsKey(even.Event.CallNumber) ? MainWindow.SysCallNames[even.Event.CallNumber] : "(unknown)"; textTime.Text = _event.Event.Time.ToString(); textMode.Text = _event.Event.Mode == KProcessorMode.UserMode ? "User-mode" : "Kernel-mode"; for (int i = 0; i < _event.Event.Arguments.Length; i++) { ListViewItem item = new ListViewItem(); item.Text = i.ToString(); item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "0x" + _event.Event.Arguments[i].ToString("x"))); if (_event.Arguments[i] != null) { string text = ""; SsData data = _event.Arguments[i]; if (data is SsSimple) { text = (data as SsSimple).Argument.ToString(); } else if (data is SsHandle) { SsHandle handle = data as SsHandle; if (!string.IsNullOrEmpty(handle.Name)) { text = handle.TypeName + ": " + handle.Name; } else { text = handle.TypeName + ": PID: " + handle.ProcessId.ToString() + ", TID: " + handle.ThreadId.ToString(); } } else if (data is SsUnicodeString) { text = (data as SsUnicodeString).String; } else if (data is SsObjectAttributes) { SsObjectAttributes oa = data as SsObjectAttributes; text = ""; if (oa.RootDirectory != null) { text = oa.RootDirectory.Name; } if (oa.ObjectName != null) { if (!string.IsNullOrEmpty(text)) { text = text + "\\" + oa.ObjectName.String; } else { text = oa.ObjectName.String; } } } else if (data is SsClientId) { text = "PID: " + (data as SsClientId).Original.ProcessId.ToString() + ", TID: " + (data as SsClientId).Original.ThreadId.ToString(); } item.SubItems.Add(new ListViewItem.ListViewSubItem(item, text)); item.SubItems.Add(new ListViewItem.ListViewSubItem(item, _event.Arguments[i].GetType().Name.Remove(0, 2))); } else { item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "")); item.SubItems.Add(new ListViewItem.ListViewSubItem(item, "")); } listArguments.Items.Add(item); } SymbolProvider.Options = SymbolOptions.DeferredLoads | SymbolOptions.UndName; try { using (var phandle = new ProcessHandle(_event.Event.ProcessId, ProcessAccess.QueryInformation | ProcessAccess.VmRead)) { _symbols = new SymbolProvider(phandle); phandle.EnumModules((module) => { _symbols.LoadModule(module.FileName, module.BaseAddress, module.Size); return(true); }); Windows.EnumKernelModules((module) => { _symbols.LoadModule(module.FileName, module.BaseAddress); return(true); }); _symbols.PreloadModules = true; for (int i = 0; i < _event.Event.StackTrace.Length; i++) { var address = _event.Event.StackTrace[i]; string fileName; IntPtr baseAddress; fileName = _symbols.GetModuleFromAddress(address, out baseAddress); listStackTrace.Items.Add(new ListViewItem(new string[] { "0x" + address.ToString("x"), (new System.IO.FileInfo(fileName)).Name + "+0x" + address.Decrement(baseAddress).ToString("x") })); WorkQueue.GlobalQueueWorkItemTag(new Action <int, IntPtr>((i_, address_) => { string symbol = _symbols.GetSymbolFromAddress(address_.ToUInt64()); if (this.IsHandleCreated) { this.BeginInvoke(new Action(() => listStackTrace.Items[i_].SubItems[1].Text = symbol)); } }), "resolve-symbol", i, address); } } } catch { } listArguments.SetDoubleBuffered(true); listStackTrace.SetDoubleBuffered(true); }
private void ThreadWindow_FormClosing(object sender, FormClosingEventArgs e) { Settings.Instance.ThreadWindowSize = this.Size; Settings.Instance.CallStackColumns = ColumnSettings.SaveSettings(listViewCallStack); _symbols = null; }
public void TestGettingSymbolsFromModuleDeclaration() { var symbolProvider = new SymbolProvider(m_fixture.ProviderContext); var documentSymbolParams = new DocumentSymbolParams() { TextDocument = new TextDocumentIdentifier() { Uri = m_fixture.GetChildUri(@"project\project.bxt") } }; var documentSymbolsResult = symbolProvider.DocumentSymbols(documentSymbolParams, CancellationToken.None); Assert.True(documentSymbolsResult.IsSuccess); var symbols = documentSymbolsResult.SuccessValue .OrderBy(symbol => symbol.Name) .ToArray(); Assert.Equal( new SymbolInformation[] { new SymbolInformation() { Name = "A.B.C.a", Kind = SymbolKind.Constant }, new SymbolInformation() { Name = "A.B.C.b", Kind = SymbolKind.Constant }, new SymbolInformation() { Name = "callingAlias", Kind = SymbolKind.Variable }, new SymbolInformation() { Name = "callingDeployDirectly", Kind = SymbolKind.Variable }, new SymbolInformation() { Name = "completionForGenerics1", Kind = SymbolKind.Variable }, new SymbolInformation() { Name = "completionForGenerics2", Kind = SymbolKind.Variable }, new SymbolInformation() { Name = "IFoo", Kind = SymbolKind.Interface }, new SymbolInformation() { Name = "qualifier", Kind = SymbolKind.Variable }, new SymbolInformation() { Name = "value", Kind = SymbolKind.Variable }, new SymbolInformation() { Name = "value2", Kind = SymbolKind.Variable }, new SymbolInformation() { Name = "withQualifier", Kind = SymbolKind.Function }, }, symbols, s_comparer); }
private void ThreadWindow_FormClosing(object sender, FormClosingEventArgs e) { Properties.Settings.Default.ThreadWindowSize = this.Size; Properties.Settings.Default.CallStackColumns = ColumnSettings.SaveSettings(listViewCallStack); _symbols = null; }
public ThreadWindow(int PID, int TID, SymbolProvider symbols, ProcessHandle processHandle) { InitializeComponent(); this.AddEscapeToClose(); this.SetTopMost(); listViewCallStack_SelectedIndexChanged(null, null); _pid = PID; _tid = TID; _symbols = symbols; this.Text = Program.ProcessProvider.Dictionary[_pid].Name + " (PID " + _pid.ToString() + ") - Thread " + _tid.ToString(); PropertyInfo property = typeof(ListView).GetProperty("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance); property.SetValue(listViewCallStack, true, null); listViewCallStack.ContextMenu = listViewCallStack.GetCopyMenu(); try { if (processHandle != null) { _phandle = processHandle; _processHandleOwned = false; } else { try { _phandle = new ProcessHandle(_pid, ProcessAccess.QueryInformation | ProcessAccess.VmRead ); } catch { if (KProcessHacker.Instance != null) { _phandle = new ProcessHandle(_pid, Program.MinProcessReadMemoryRights); } else { throw; } } } } catch (Exception ex) { PhUtils.ShowException("Unable to open the process", ex); this.Close(); return; } try { try { _thandle = new ThreadHandle(_tid, ThreadAccess.GetContext | ThreadAccess.SuspendResume); } catch { if (KProcessHacker.Instance != null) { _thandle = new ThreadHandle(_tid, Program.MinThreadQueryRights | ThreadAccess.SuspendResume ); } else { throw; } } } catch (Exception ex) { PhUtils.ShowException("Unable to open the thread", ex); this.Close(); return; } }
public SysInfoWindow() { this.InitializeComponent(); //if (!Settings.Instance.SysInfoWindowBounds.IsEmpty) //this.DesktopBounds = Utils.FitRectangle(Settings.Instance.SysInfoWindowBounds, this); // Load the pool limit addresses. if (_mmSizeOfPagedPoolInBytes == IntPtr.Zero) { WorkQueue.GlobalQueueWorkItemTag(new Action(() => { try { using (SymbolProvider symbols = new SymbolProvider()) { symbols.LoadModule(Windows.KernelFileName, Windows.KernelBase); _mmSizeOfPagedPoolInBytes = (IntPtr)symbols.GetSymbolFromName("MmSizeOfPagedPoolInBytes").Address; _mmMaximumNonPagedPoolInBytes = (IntPtr)symbols.GetSymbolFromName("MmMaximumNonPagedPoolInBytes").Address; } } catch (Exception) { } }), "load-mm-addresses"); } this.trackerMemory.values = Program.ProcessProvider.PhysicalMemoryHistory; this.trackerMemory.DrawColor = Settings.Instance.PlotterMemoryPrivateColor; this.trackerCommit.Maximum = (int)Program.ProcessProvider.Performance.CommitLimit; this.trackerCommit.values = Program.ProcessProvider.CommitHistory; this.trackerCommit.DrawColor = Settings.Instance.PlotterMemoryWSColor; // Set indicators color this.indicatorCpu.Color1 = Settings.Instance.PlotterCPUUserColor; this.indicatorCpu.Color2 = Settings.Instance.PlotterCPUKernelColor; this.indicatorIO.Color1 = Settings.Instance.PlotterIOROColor; this.indicatorPhysical.Color1 = Settings.Instance.PlotterMemoryPrivateColor; this.plotterCPU.LineColor2 = Settings.Instance.PlotterCPUKernelColor; this.plotterCPU.LineColor1 = Settings.Instance.PlotterCPUUserColor; this.plotterIO.LineColor1 = Settings.Instance.PlotterIOROColor; this.plotterIO.LineColor2 = Settings.Instance.PlotterIOWColor; // Maximum physical memory. this.indicatorPhysical.Maximum = _pages; // Set up the plotter controls. plotterCPU.Data1 = Program.ProcessProvider.CpuKernelHistory; plotterCPU.Data2 = Program.ProcessProvider.CpuUserHistory; plotterCPU.GetToolTip = i => Program.ProcessProvider.MostCpuHistory[i] + "\n" + ((plotterCPU.Data1[i] + plotterCPU.Data2[i]) * 100).ToString("N2") + "% (K " + (plotterCPU.Data1[i] * 100).ToString("N2") + "%, U " + (plotterCPU.Data2[i] * 100).ToString("N2") + "%)" + "\n" + Program.ProcessProvider.TimeHistory[i].ToString(); plotterIO.LongData1 = Program.ProcessProvider.IoReadOtherHistory; plotterIO.LongData2 = Program.ProcessProvider.IoWriteHistory; plotterIO.GetToolTip = i => Program.ProcessProvider.MostIoHistory[i] + "\n" + "R+O: " + Utils.FormatSize(plotterIO.LongData1[i]) + "\n" + "W: " + Utils.FormatSize(plotterIO.LongData2[i]) + "\n" + Program.ProcessProvider.TimeHistory[i].ToString(); //plotterMemory.Data1 = Program.ProcessProvider.CommitHistory; //plotterMemory.Data2 = Program.ProcessProvider.PhysicalMemoryHistory; //plotterMemory.GetToolTip = i => "Commit: " + plotterMemory.Data1[i] + "\n" + // "Phys. Memory: " + plotterMemory.Data2[i] + "\n" + Program.ProcessProvider.TimeHistory[i].ToString(); // Create a plotter per CPU. _cpuPlotters = new Plotter[_noOfCPUs]; tableCPUs.ColumnCount = (int)_noOfCPUs; tableCPUs.ColumnStyles.Clear(); tableCPUs.Dock = DockStyle.Fill; for (int i = 0; i < _cpuPlotters.Length; i++) { Plotter plotter; tableCPUs.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 1.0f / _noOfCPUs)); _cpuPlotters[i] = plotter = new Plotter(); plotter.BackColor = Color.Black; plotter.Dock = DockStyle.Fill; plotter.Margin = new Padding(i == 0 ? 0 : 3, 0, 0, 0); // nice spacing plotter.UseSecondLine = true; plotter.Data1 = Program.ProcessProvider.CpusKernelHistory[i]; plotter.Data2 = Program.ProcessProvider.CpusUserHistory[i]; plotter.GetToolTip = j => Program.ProcessProvider.MostCpuHistory[j] + "\n" + ((plotter.Data1[j] + plotter.Data2[j]) * 100).ToString("N2") + "% (K " + (plotter.Data1[j] * 100).ToString("N2") + "%, U " + (plotter.Data2[j] * 100).ToString("N2") + "%)" + "\n" + Program.ProcessProvider.TimeHistory[j].ToString(); this.tableCPUs.Controls.Add(plotter, i, 0); } this.checkShowOneGraphPerCPU.Checked = Settings.Instance.ShowOneGraphPerCPU; if (_noOfCPUs == 1) { checkShowOneGraphPerCPU.Enabled = false; } Program.ProcessProvider.Updated += ProcessProvider_Updated; //We need to do this here or TopMost property gets over-rided by AlwaysOnTopCheckbox this.TopMost = Settings.Instance.AlwaysOnTop; this.UpdateGraphs(); this.UpdateInfo(); }
public ThreadProvider(int pid) : base() { this.Name = this.GetType().Name; _pid = pid; _messageQueue.AddListener( new MessageQueueListener <ResolveMessage>((message) => { if (message.Symbol != null) { this.Dictionary[message.Tid].StartAddress = message.Symbol; this.Dictionary[message.Tid].FileName = message.FileName; this.Dictionary[message.Tid].StartAddressLevel = message.ResolveLevel; this.Dictionary[message.Tid].JustResolved = true; } })); this.ProviderUpdate += new ProviderUpdateOnce(UpdateOnce); this.Disposed += ThreadProvider_Disposed; try { // Try to get a good process handle we can use the same handle for stack walking. try { _processAccess = ProcessAccess.QueryInformation | ProcessAccess.VmRead; _processHandle = new ProcessHandle(_pid, _processAccess); } catch { try { if (KProcessHacker.Instance != null) { _processAccess = Program.MinProcessReadMemoryRights; _processHandle = new ProcessHandle(_pid, _processAccess); } else { _processAccess = Program.MinProcessQueryRights; _processHandle = new ProcessHandle(_pid, _processAccess); } } catch (WindowsException ex) { Logging.Log(ex); } } // Start loading symbols; avoid the UI blocking on the dbghelp call lock. _symbolsWorkQueue.QueueWorkItemTag(new Action(() => { try { // Needed (maybe) to display the EULA Win32.SymbolServerSetOptions(SymbolServerOption.Unattended, 0); } catch (Exception ex) { Logging.Log(ex); } try { // Use the process handle if we have one, otherwise use the default ID generator. if (_processHandle != null) { _symbols = new SymbolProvider(_processHandle); } else { _symbols = new SymbolProvider(); } SymbolProvider.Options = SymbolOptions.DeferredLoads | (Properties.Settings.Default.DbgHelpUndecorate ? SymbolOptions.UndName : 0); if (Properties.Settings.Default.DbgHelpSearchPath != "") { _symbols.SearchPath = Properties.Settings.Default.DbgHelpSearchPath; } try { if (_pid != 4) { using (var phandle = new ProcessHandle(_pid, Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights)) { if (IntPtr.Size == 4 || !phandle.IsWow64()) { // Load the process' modules. try { _symbols.LoadProcessModules(phandle); } catch { } } else { // Load the process' WOW64 modules. try { _symbols.LoadProcessWow64Modules(_pid); } catch { } } // If the process is CSRSS we should load kernel modules // due to the presence of kernel-mode threads. if (phandle.GetKnownProcessType() == KnownProcess.WindowsSubsystem) { this.LoadKernelSymbols(true); } } } else { this.LoadKernelSymbols(true); } } catch (WindowsException ex) { // Did we get Access Denied? At least load // kernel32.dll and ntdll.dll. try { ProcessHandle.Current.EnumModules((module) => { if (module.BaseName == "kernel32.dll" || module.BaseName == "ntdll.dll") { _symbols.LoadModule(module.FileName, module.BaseAddress, module.Size); } return(true); }); } catch (Exception ex2) { Logging.Log(ex2); } Logging.Log(ex); } catch (Exception ex) { Logging.Log(ex); } } finally { lock (_moduleLoadCompletedEvent) { if (!_moduleLoadCompletedEvent.SafeWaitHandle.IsClosed) { _moduleLoadCompletedEvent.Set(); } } } }), "symbols-load"); } catch (Exception ex) { Logging.Log(ex); } }
private static void ScanDacFile(String file, SymbolProvider sf, List<UInt32> rvaArray, out UInt32 numGlobals) { StreamReader strm = new StreamReader(file, System.Text.Encoding.ASCII); String line; Hashtable vtables = new Hashtable(); // hashtable to guarantee uniqueness of entries // // Scan through the data access header file looking // for the globals structure. // for (;;) { line = strm.ReadLine(); if (line == null) { throw new InvalidOperationException("Invalid dac header format"); } else if (line == "typedef struct _DacGlobals") { break; } } if (strm.ReadLine() != "{") { throw new InvalidOperationException("Invalid dac header format"); } // // All the globals come first so pick up each line that // begins with ULONG. // bool fFoundVptrs = false; numGlobals = 0; for (;;) { line = strm.ReadLine().Trim(); if ( line.Equals("union {") || line.Equals("struct {") || line.Equals("};") || line.StartsWith("#line ") || line.StartsWith("# ")) { // Ignore. } else if (line.StartsWith("ULONG ")) { UInt32 rva = 0; line = line.Remove(0, 6); line = line.TrimEnd(";".ToCharArray()); string vptrSuffixSingle = "__vtAddr"; string vptrSuffixMulti = "__mvtAddr"; string vptrSuffix = null; if (line.EndsWith(vptrSuffixSingle)) { vptrSuffix = vptrSuffixSingle; } else if (line.EndsWith(vptrSuffixMulti)) { vptrSuffix = vptrSuffixMulti; } if (vptrSuffix != null) { if (!fFoundVptrs) { numGlobals = (UInt32)rvaArray.Count; fFoundVptrs = true; } line = line.Remove(line.Length - vptrSuffix.Length, vptrSuffix.Length); string keyBaseName = null; string descTail = null; if (vptrSuffix == vptrSuffixMulti) { // line now has the form <class>__<base>, so // split off the base. int basePrefix = line.LastIndexOf("__"); if (basePrefix < 0) { throw new InvalidOperationException("VPTR_MULTI_CLASS has no keyBase."); } keyBaseName = line.Substring(basePrefix + 2); line = line.Remove(basePrefix); descTail = " for " + keyBaseName; } rva = sf.GetVTableRVA(line, keyBaseName); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid vtable " + line + descTail); } else { String existing = (String)vtables[rva]; if (existing != null) { throw new InvalidOperationException(existing + " and " + line + " are at the same offsets." + " Add VPTR_UNIQUE(<a random unique number here>) to the offending classes to make their vtables unique."); } vtables[rva] = line; Console.WriteLine(" " + ToHexNB(rva) + ", // vtable " + line + descTail); } } else { SymbolProvider.SymType symType; if (fFoundVptrs) throw new InvalidOperationException("Invalid dac header format. Vtable pointers must be last."); if (line.StartsWith("dac__")) { // Global variables, use the prefix. line = line.Remove(0, 5); symType = SymbolProvider.SymType.GlobalData; } else if (line.StartsWith("fn__")) { // Global or static functions, use the prefix. line = line.Remove(0, 4); line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalFunction; } else { // Static member variable, use the full name with // namespace replacement. line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalData; } if (0 == rva) { rva = sf.GetGlobalRVA(line, symType); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid symbol " + line); } else { Console.WriteLine(" " + ToHexNB(rva) + ", // " + line); } } } rvaArray.Add(rva); } else if (line == "") { // Skip blanks. } else { // We hit a non-global so we're done. if (!line.Equals("} DacGlobals;")) { throw new InvalidOperationException("Invalid dac header format at \"" + line + "\""); } break; } } if (!fFoundVptrs) throw new InvalidOperationException("Invalid dac header format. Vtable pointers not found."); }
private void LoadSymbols() { // Ensure we only load symbols once. if (Interlocked.CompareExchange(ref _symbolsStartedLoading, 1, 0) == 1) { return; } // Start loading symbols; avoid the UI blocking on the dbghelp call lock. _symbolsWorkQueue.QueueWorkItemTag(new Action(() => { try { // Needed (maybe) to display the EULA Win32.SymbolServerSetOptions(SymbolServerOption.Unattended, 0); } catch (Exception ex) { Logging.Log(ex); } try { // Use the process handle if we have one, otherwise use the default ID generator. if (_processHandle != null) { _symbols = new SymbolProvider(_processHandle); } else { _symbols = new SymbolProvider(); } SymbolProvider.Options = SymbolOptions.DeferredLoads | (Settings.Instance.DbgHelpUndecorate ? SymbolOptions.UndName : 0); if (!string.IsNullOrEmpty(Settings.Instance.DbgHelpSearchPath)) { _symbols.SearchPath = Settings.Instance.DbgHelpSearchPath; } try { if (_pid > 4) { using (var phandle = new ProcessHandle(_pid, Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights)) { if (OSVersion.Architecture == OSArch.I386 || !phandle.IsWow64) { // Load the process' modules. try { _symbols.LoadProcessModules(phandle); } catch { } } else { // Load the process' WOW64 modules. try { _symbols.LoadProcessWow64Modules(_pid); } catch { } } // If the process is CSRSS we should load kernel modules // due to the presence of kernel-mode threads. if (phandle.KnownProcessType == KnownProcess.WindowsSubsystem) { this.LoadKernelSymbols(true); } } } else { this.LoadKernelSymbols(true); } } catch (WindowsException ex) { // Did we get Access Denied? At least load // kernel32.dll and ntdll.dll. try { ProcessHandle.Current.EnumModules(module => { if ( module.BaseName.Equals("kernel32.dll", StringComparison.OrdinalIgnoreCase) || module.BaseName.Equals("ntdll.dll", StringComparison.OrdinalIgnoreCase) ) { _symbols.LoadModule(module.FileName, module.BaseAddress, module.Size); } return(true); }); } catch (Exception ex2) { Logging.Log(ex2); } Logging.Log(ex); } catch (Exception ex) { Logging.Log(ex); } } finally { _moduleLoadCompletedEvent.Set(); } }), "symbols-load"); }
public MainWindow() { InitializeComponent(); Win32.LoadLibrary("C:\\Program Files\\Debugging Tools for Windows (x86)\\dbghelp.dll"); SymbolProvider symbols = new SymbolProvider(ProcessHandle.Current); SymbolProvider.Options |= SymbolOptions.PublicsOnly; IntPtr ntdllBase = Loader.GetDllHandle("ntdll.dll"); FileHandle ntdllFileHandle = null; Section section = null; ProcessHandle.Current.EnumModules((module) => { if (module.BaseName.Equals("ntdll.dll", StringComparison.InvariantCultureIgnoreCase)) { section = new Section( ntdllFileHandle = new FileHandle(@"\??\" + module.FileName, FileShareMode.ReadWrite, FileAccess.GenericExecute | FileAccess.GenericRead ), true, MemoryProtection.ExecuteRead ); symbols.LoadModule(module.FileName, module.BaseAddress, module.Size); return(false); } return(true); }); SectionView view = section.MapView((int)ntdllFileHandle.GetSize()); ntdllFileHandle.Dispose(); symbols.EnumSymbols("ntdll!Zw*", (symbol) => { int number = Marshal.ReadInt32( (symbol.Address.ToIntPtr().Decrement(ntdllBase)).Increment(view.Memory).Increment(1)); _sysCallNames.Add( number, "Nt" + symbol.Name.Substring(2) ); _reverseSysCallNames.Add( "Nt" + symbol.Name.Substring(2), number ); return(true); }); view.Dispose(); section.Dispose(); symbols.Dispose(); KProcessHacker.Instance = new KProcessHacker(); _logger = new SsLogger(4096, false); _logger.EventBlockReceived += new EventBlockReceivedDelegate(logger_EventBlockReceived); _logger.ArgumentBlockReceived += new ArgumentBlockReceivedDelegate(logger_ArgumentBlockReceived); _logger.AddProcessIdRule(FilterType.Exclude, ProcessHandle.GetCurrentId()); _logger.AddPreviousModeRule(FilterType.Include, KProcessorMode.UserMode); //_logger.Start(); listEvents.SetDoubleBuffered(true); }
public IList <IStyle> ConvertSymbolLayer(EvaluationContext context, StyleLayer styleLayer, Dictionary <string, Styles.Sprite> spriteAtlas, SymbolProvider symbolProvider) { string styleLabelText = string.Empty; List <IStyle> result = new List <IStyle>(); if (context.Feature.GeometryType == GeometryType.LineString) { styleLabelText = ""; } //return result; // visibility // Optional enum. One of visible, none. Defaults to visible. // The display of this layer. none hides this layer. if (styleLayer.Layout?.Visibility != null && styleLayer.Layout.Visibility.Equals("none")) { return(result); } var paint = styleLayer.Paint; var layout = styleLayer.Layout; var styleLabel = new LabelStyle { Enabled = false, Halo = new Pen { Color = Color.Transparent, Width = 0 }, CollisionDetection = true, BackColor = null, }; styleLabel.Font.Size = 16; var styleSymbol = new SymbolStyle { Enabled = false, }; // symbol-placement // Optional enum. One of point, line. Defaults to point. Interval. // Label placement relative to its geometry. line can only be used on // LineStrings and Polygons. if (layout?.SymbolPlacement != null) { switch (layout.SymbolPlacement.Evaluate(context.Zoom)) { case "point": break; case "line": // symbol-spacing // Optional number. Units in pixels. Defaults to 250. Requires symbol-placement = line. Exponential. // Distance between two symbol anchors. if (layout?.SymbolSpacing != null) { styleLabel.Spacing = layout.SymbolSpacing.Evaluate(context.Zoom); } break; } } // symbol-avoid-edges // Optional boolean. Defaults to false. Interval. // If true, the symbols will not cross tile edges to avoid mutual collisions. // Recommended in layers that don't have enough padding in the vector tile to prevent // collisions, or if it is a point symbol layer placed after a line symbol layer. // text-field // Optional string. Interval. // Value to use for a text label. Feature properties are specified using tokens like {field_name}. if (layout?.TextField != null) { styleLabelText = ReplaceFields(layout.TextField.Trim(), context.Feature.Tags); // text-transform // Optional enum. One of none, uppercase, lowercase. Defaults to none. Requires text-field. Interval. // Specifies how to capitalize text, similar to the CSS text-transform property. if (layout?.TextTransform != null) { switch (layout.TextTransform) { case "uppercase": styleLabelText = styleLabelText.ToUpper(); break; case "lowercase": styleLabelText = styleLabelText.ToLower(); break; } } styleLabel.Text = styleLabelText; // text-color // Optional color. Defaults to #000000. Requires text-field. Exponential. // The color with which the text will be drawn. if (paint?.TextColor != null) { styleLabel.ForeColor = paint.TextColor.Evaluate(context.Zoom); } // text-opacity // Optional number. Defaults to 1. Requires text-field. Exponential. // The opacity at which the text will be drawn. if (paint?.TextOpacity != null) { } // text-halo-color // Optional color. Defaults to rgba(0, 0, 0, 0). Requires text-field. Exponential. // The color of the text's halo, which helps it stand out from backgrounds. if (paint?.TextHaloColor != null) { styleLabel.Halo.Color = paint.TextHaloColor.Evaluate(context.Zoom); } //text-halo-width // Optional number. Units in pixels. Defaults to 0. Requires text-field. Exponential. // Distance of halo to the font outline. Max text halo width is 1/4 of the font-size. if (paint?.TextHaloWidth != null) { styleLabel.Halo.Width = paint.TextHaloWidth.Evaluate(context.Zoom); } // text-font // Optional array. Defaults to Open Sans Regular, Arial Unicode MS Regular. Requires text-field. Interval. // Font stack to use for displaying text. if (layout?.TextFont != null) { var fontName = string.Empty; foreach (var font in layout.TextFont) { // TODO: Check for fonts //if (font.exists) { fontName = (string)font; break; } } if (!string.IsNullOrWhiteSpace(fontName)) { styleLabel.Font.FontFamily = fontName; } } // text-size // Optional number. Units in pixels. Defaults to 16. Requires text-field. Exponential. // Font size. if (layout?.TextSize != null) { styleLabel.Font.Size = layout.TextSize.Evaluate(context.Zoom); } // text-rotation-alignment // Optional enum. One of map, viewport. Defaults to viewport. Requires text-field. Interval. // Orientation of text when map is rotated. // text-translate // Optional array. Units in pixels. Defaults to 0, 0. Requires text-field. Exponential. // Distance that the text's anchor is moved from its original placement.Positive values // indicate right and down, while negative values indicate left and up. if (paint?.TextTranslate != null) { var offset = new Offset { X = paint.TextTranslate.Count > 0 ? -paint.TextTranslate[0] : 0, Y = paint.TextTranslate.Count > 1 ? -paint.TextTranslate[1] : 0 }; styleLabel.Offset = offset; // text-translate-anchor // Optional enum. One of map, viewport. Defaults to map. Requires text-field. Requires text-translate. Interval. // Control whether the translation is relative to the map(north) or viewport(screen). // TODO: Don't know, how to do this in the moment } // text-max-width // Optional number. Units in em. Defaults to 10. Requires text-field. Exponential. // The maximum line width for text wrapping. if (layout?.TextMaxWidth != null) { styleLabel.MaxWidth = layout.TextMaxWidth.Evaluate(context.Zoom); } // text-line-height // Optional number. Units in em. Defaults to 1.2. Requires text-field. Exponential. // Text leading value for multi-line text. // text-letter-spacing // Optional number. Units in em. Defaults to 0. Requires text-field. Exponential. // Text tracking amount. // text-justify // Optional enum. One of left, center, right. Defaults to center. Requires text-field. Interval. // Text justification options. if (layout?.TextJustify != null) { switch (layout.TextJustify) { case "left": styleLabel.Justify = LabelStyle.HorizontalAlignmentEnum.Left; break; case "right": styleLabel.Justify = LabelStyle.HorizontalAlignmentEnum.Right; break; default: styleLabel.Justify = LabelStyle.HorizontalAlignmentEnum.Center; break; } } // text-anchor // Optional enum. One of center, left, right, top, bottom, top-left, top-right, bottom-left, // bottom-right. Defaults to center. Requires text-field. Interval. // Part of the text placed closest to the anchor. if (layout?.TextAnchor != null) { switch (layout.TextAnchor) { case "left": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Center; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Left; break; case "right": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Center; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Right; break; case "top": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Top; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center; break; case "bottom": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Bottom; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center; break; case "top-left": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Top; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Left; break; case "top-right": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Top; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Right; break; case "bottom-left": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Bottom; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Left; break; case "bottom-right": styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Bottom; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Right; break; default: styleLabel.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Center; styleLabel.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center; break; } } // text-max-angle // Optional number. Units in degrees. Defaults to 45. Requires text-field. // Requires symbol-placement = line. Exponential. // Maximum angle change between adjacent characters. // text-rotate // Optional number. Units in degrees. Defaults to 0. Requires text-field. Exponential. // Rotates the text clockwise. // text-padding // Optional number. Units in pixels. Defaults to 2. Requires text-field. Exponential. // Size of the additional area around the text bounding box used for detecting symbol collisions. // text-keep-upright // Optional boolean. Defaults to true. Requires text-field. Requires text-rotation-alignment = map. // Requires symbol-placement = line. Interval. // If true, the text may be flipped vertically to prevent it from being rendered upside-down. // text-offset // Optional array. Units in ems. Defaults to 0,0. Requires text-field. Exponential. // Offset distance of text from its anchor. Positive values indicate right and down, // while negative values indicate left and up. if (layout?.TextOffset != null) { var x = layout.TextOffset[0] * styleLabel.Font.Size; var y = layout.TextOffset[1] * styleLabel.Font.Size; styleLabel.Offset = new Offset(x, y, false); } // text-allow-overlap // Optional boolean. Defaults to false. Requires text-field. Interval. // If true, the text will be visible even if it collides with other previously drawn symbols. if (layout?.TextAllowOverlap != null) { // TODO layout.TextAllowOverlap.Evaluate(context.Zoom); } // text-ignore-placement // Optional boolean. Defaults to false. Requires text-field. Interval. // If true, other symbols can be visible even if they collide with the text. if (layout?.TextIgnorePlacement != null) { // TODO layout.TextIgnorePlacement.Evaluate(context.Zoom); } // text-optional // Optional boolean. Defaults to false. Requires text-field. Requires icon-image. Interval. // If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not. if (layout?.TextOptional != null) { // TODO layout.TextOptional.Evaluate(context.Zoom); } // text-halo-blur // Optional number. Units in pixels. Defaults to 0. Requires text-field. Exponential. // The halo's fadeout distance towards the outside. } // icon-image // Optional string. // A string with { tokens } replaced, referencing the data property to pull from. Interval. if (layout?.IconImage != null) { var name = ReplaceFields(layout.IconImage.Evaluate(context.Zoom), context.Feature.Tags); if (!string.IsNullOrEmpty(name) && spriteAtlas.ContainsKey(name) && spriteAtlas[name].Atlas >= 0) { styleSymbol.BitmapId = spriteAtlas[name].Atlas; } else { // No sprite found styleSymbol.BitmapId = -1; // Log information Logging.Logger.Log(Logging.LogLevel.Information, $"Sprite {name} not found"); } // icon-allow-overlap // Optional boolean. Defaults to false. Requires icon-image. Interval. // If true, the icon will be visible even if it collides with other previously drawn symbols. if (layout?.IconAllowOverlap != null) { // TODO layout.IconAllowOverlap.Evaluate(context.Zoom); } // icon-ignore-placement // Optional boolean. Defaults to false. Requires icon-image. Interval. // If true, other symbols can be visible even if they collide with the icon. if (layout?.IconIgnorePlacement != null) { // TODO layout.IconIgnorePlacement.Evaluate(context.Zoom); } // icon-optional // Optional boolean. Defaults to false. Requires icon-image. Requires text-field. Interval. // If true, text will display without their corresponding icons when the icon collides // with other symbols and the text does not. if (layout?.IconOptional != null) { // TODO layout.IconOptional.Evaluate(context.Zoom); } // icon-rotation-alignment // Optional enum. One of map, viewport. Defaults to viewport. Requires icon-image. Interval. // Orientation of icon when map is rotated. // icon-size // Optional number. Defaults to 1. Requires icon-image. Exponential. // Scale factor for icon. 1 is original size, 3 triples the size. if (layout?.IconSize != null) { styleSymbol.SymbolScale = layout.IconSize.Evaluate(context.Zoom); } // icon-rotate // Optional number. Units in degrees. Defaults to 0. Requires icon-image. Exponential. // Rotates the icon clockwise. // icon-padding // Optional number. Units in pixels. Defaults to 2. Requires icon-image. Exponential. // Size of the additional area around the icon bounding box used for detecting symbol collisions. // icon-keep-upright // Optional boolean. Defaults to false. Requires icon-image. Requires icon-rotation-alignment = map. Interval. // Requires symbol-placement = line. // If true, the icon may be flipped to prevent it from being rendered upside-down. // icon-offset // Optional array. Defaults to 0,0. Requires icon-image. Exponential. // Offset distance of icon from its anchor. Positive values indicate right and down, // while negative values indicate left and up. if (layout?.IconOffset != null) { var x = layout.IconOffset[0]; var y = layout.IconOffset[1]; styleSymbol.SymbolOffset = new Offset(x, y, false); } // icon-opacity // Optional number. Defaults to 1. Requires icon-image. Exponential. // The opacity at which the icon will be drawn. if (layout?.IconOpacity != null) { styleSymbol.Opacity = layout.IconOpacity.Evaluate(context.Zoom); } // icon-color // Optional color. Defaults to #000000. Requires icon-image. Exponential. // The color of the icon. This can only be used with sdf icons. // icon-halo-color // Optional color. Defaults to rgba(0, 0, 0, 0). Requires icon-image. Exponential. // The color of the icon's halo. Icon halos can only be used with sdf icons. // icon-halo-width // Optional number. Units in pixels. Defaults to 0. Requires icon-image. Exponential. // Distance of halo to the icon outline. // icon-halo-blur // Optional number. Units in pixels. Defaults to 0. Requires icon-image. Exponential. // Fade out the halo towards the outside. // icon-translate // Optional array. Units in pixels. Defaults to 0, 0. Requires icon-image. Exponential. // Distance that the icon's anchor is moved from its original placement. // Positive values indicate right and down, while negative values indicate left and up. // icon-translate-anchor // Optional enum. One of map, viewport. Defaults to map. Requires icon-image. Requires icon-translate. Interval. // Control whether the translation is relative to the map(north) or viewport(screen). } if (!string.IsNullOrEmpty(styleLabelText)) { styleLabel.Enabled = true; result.Add(styleLabel); } if (styleSymbol.BitmapId >= 0) { styleSymbol.Enabled = true; result.Add(styleSymbol); } if (symbolProvider != null) { symbolProvider.Symbols.Add(new Symbol { Feature = context.Feature, }); // If there is an SymbolLayer, than it handles drawing of symbols result = null; } return(result); }
/// <summary> /// Convert given context with Mapbox GL styling layer to a Mapsui Style list /// </summary> /// <param name="context">Context to use while evaluating style</param> /// <param name="styleLayer">Mapbox GL style layer</param> /// <param name="spriteAtlas">Dictionary with availible sprites</param> /// <returns>A list of Mapsui Styles</returns> public IList <IStyle> Convert(EvaluationContext context, StyleLayer styleLayer, Dictionary <string, Styles.Sprite> spriteAtlas, SymbolProvider symbolProvider) { switch (styleLayer.Type) { case "fill": return(ConvertFillLayer(context, styleLayer, spriteAtlas)); case "line": return(ConvertLineLayer(context, styleLayer, spriteAtlas)); case "symbol": return(ConvertSymbolLayer(context, styleLayer, spriteAtlas, symbolProvider)); case "circle": return(new List <IStyle>()); case "raster": // Shouldn't get here, because raster are directly handled by ConvertRasterLayer break; case "background": return(new List <IStyle>()); } return(new List <IStyle>()); }
private static void ScanDacFile(String file, SymbolProvider sf, List <UInt32> rvaArray, out UInt32 numGlobals) { StreamReader strm = new StreamReader(file, System.Text.Encoding.ASCII); String line; Hashtable vtables = new Hashtable(); // hashtable to guarantee uniqueness of entries // // Scan through the data access header file looking // for the globals structure. // for (;;) { line = strm.ReadLine(); if (line == null) { throw new InvalidOperationException("Invalid dac header format"); } else if (line == "typedef struct _DacGlobals") { break; } } if (strm.ReadLine() != "{") { throw new InvalidOperationException("Invalid dac header format"); } // // All the globals come first so pick up each line that // begins with ULONG. // bool fFoundVptrs = false; numGlobals = 0; for (;;) { line = strm.ReadLine().Trim(); if (line.Equals("union {") || line.Equals("struct {") || line.Equals("};") || line.StartsWith("#line ") || line.StartsWith("# ")) { // Ignore. } else if (line.StartsWith("ULONG ")) { UInt32 rva = 0; line = line.Remove(0, 6); line = line.TrimEnd(";".ToCharArray()); string vptrSuffixSingle = "__vtAddr"; string vptrSuffixMulti = "__mvtAddr"; string vptrSuffix = null; if (line.EndsWith(vptrSuffixSingle)) { vptrSuffix = vptrSuffixSingle; } else if (line.EndsWith(vptrSuffixMulti)) { vptrSuffix = vptrSuffixMulti; } if (vptrSuffix != null) { if (!fFoundVptrs) { numGlobals = (UInt32)rvaArray.Count; fFoundVptrs = true; } line = line.Remove(line.Length - vptrSuffix.Length, vptrSuffix.Length); string keyBaseName = null; string descTail = null; if (vptrSuffix == vptrSuffixMulti) { // line now has the form <class>__<base>, so // split off the base. int basePrefix = line.LastIndexOf("__"); if (basePrefix < 0) { throw new InvalidOperationException("VPTR_MULTI_CLASS has no keyBase."); } keyBaseName = line.Substring(basePrefix + 2); line = line.Remove(basePrefix); descTail = " for " + keyBaseName; } rva = sf.GetVTableRVA(line, keyBaseName); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid vtable " + line + descTail); } else { String existing = (String)vtables[rva]; if (existing != null) { throw new InvalidOperationException(existing + " and " + line + " are at the same offsets." + " Add VPTR_UNIQUE(<a random unique number here>) to the offending classes to make their vtables unique."); } vtables[rva] = line; Console.WriteLine(" " + ToHexNB(rva) + ", // vtable " + line + descTail); } } else { SymbolProvider.SymType symType; if (fFoundVptrs) { throw new InvalidOperationException("Invalid dac header format. Vtable pointers must be last."); } if (line.StartsWith("dac__")) { // Global variables, use the prefix. line = line.Remove(0, 5); symType = SymbolProvider.SymType.GlobalData; } else if (line.StartsWith("fn__")) { // Global or static functions, use the prefix. line = line.Remove(0, 4); line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalFunction; } else { // Static member variable, use the full name with // namespace replacement. line = line.Replace("__", "::"); symType = SymbolProvider.SymType.GlobalData; } if (0 == rva) { rva = sf.GetGlobalRVA(line, symType); if (rva == UInt32.MaxValue) { Console.WriteLine(" " + ToHexNB(rva)); Shell.Error("Invalid symbol " + line); } else { Console.WriteLine(" " + ToHexNB(rva) + ", // " + line); } } } rvaArray.Add(rva); } else if (line == "") { // Skip blanks. } else { // We hit a non-global so we're done. if (!line.Equals("} DacGlobals;")) { throw new InvalidOperationException("Invalid dac header format at \"" + line + "\""); } break; } } if (!fFoundVptrs) { throw new InvalidOperationException("Invalid dac header format. Vtable pointers not found."); } }
public MapboxGLStyler(Stream input, Map map) { using (var reader = new StreamReader(input)) styleJson = JsonConvert.DeserializeObject <MapboxGL>(reader.ReadToEnd()); Zoom = styleJson.Zoom ?? 20; // Save urls for sprite and glyphs SpriteUrl = styleJson.Sprite; GlyphsUrl = styleJson.Glyphs; var filterConverter = new FilterConverter(); var styleLayerConverter = new StyleLayerConverter(); // Create SymbolProvider, that belongs to all Styles and VectorTileLayers var symbolProvider = new SymbolProvider(map); foreach (var styleLayer in styleJson.StyleLayers) { if (styleLayer.Type.Equals("background") && styleLayer.Paint.BackgroundColor != null) { Background = styleLayer.Paint.BackgroundColor; map.BackColor = Background; } // Create filters for each style layer if (styleLayer.NativeFilter != null) { styleLayer.Filter = filterConverter.ConvertFilter(styleLayer.NativeFilter); } // Create ThemeStyles for each style layer styleLayer.Style = new MapboxGLThemeStyle(styleLayerConverter, styleLayer, SpriteAtlas, map.Viewport, symbolProvider) { MinVisible = styleLayer.MinVisible, MaxVisible = styleLayer.MaxVisible }; } // Read all tile sources foreach (var source in styleJson.Sources) { var sourceJson = source.Value; switch (source.Value.Type) { case "raster": if (!string.IsNullOrEmpty(source.Value.Url)) { // Get TileJSON from http/https url sourceJson = new Source(); } // Create new raster layer var rasterLayer = CreateRasterLayer(sourceJson); if (rasterLayer != null) { rasterLayer.Name = source.Key; rasterLayer.Style = new StyleCollection(); // Add all ThemeStyles for this layer foreach (var styleLayer in styleJson.StyleLayers) { if (!rasterLayer.Name.Equals(styleLayer.Source, StringComparison.CurrentCultureIgnoreCase)) { continue; } ((StyleCollection)rasterLayer.Style).Add(styleLayer.Style); } map.Layers.Add(rasterLayer); } break; case "vector": if (!string.IsNullOrEmpty(source.Value.Url)) { if (source.Value.Url.StartsWith("http")) { // TODO: Get TileJSON from http/https url sourceJson = JsonConvert.DeserializeObject <Source>(@"{'tiles':['https://free.tilehosting.com/data/v3/{z}/{x}/{y}.pbf.pict?key=tXiQqN3lIgskyDErJCeY'],'name':'OpenMapTiles','format':'pbf','basename':'v3.7.mbtiles','id':'openmaptiles','attribution':'<a href=\'http://www.openmaptiles.org/\' target=\'_blank\'>© OpenMapTiles</a> <a href=\'http://www.openstreetmap.org/about/\' target=\'_blank\'>© OpenStreetMap contributors</a>','description':'A tileset showcasing all layers in OpenMapTiles. http://openmaptiles.org','maxzoom':14,'minzoom':0,'pixel_scale':'256','vector_layers':[{'maxzoom':14,'fields':{'class':'String'},'minzoom':0,'id':'water','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:cy':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:hu':'String','name:ka':'String','name:fi':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:zh':'String','name:sl':'String','name:lv':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:sv':'String','name:he':'String','name:ja_rm':'String','name:ga':'String','name:br':'String','name:bs':'String','name:lb':'String','class':'String','name:ko_rm':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:be':'String','name_en':'String','name:bg':'String','name:hr':'String','name:sr':'String','name:sq':'String','name:el':'String','name:eo':'String','name:en':'String','name':'String','name:gd':'String','name:ja_kana':'String','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:nl':'String','name:es':'String'},'minzoom':0,'id':'waterway','description':''},{'maxzoom':14,'fields':{'class':'String','subclass':'String'},'minzoom':0,'id':'landcover','description':''},{'maxzoom':14,'fields':{'class':'String'},'minzoom':0,'id':'landuse','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:cy':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','rank':'Number','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:nl':'String','name:pl':'String','ele':'Number','name:ca':'String','name:hu':'String','name:ka':'String','name:fi':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:zh':'String','name:sl':'String','name:lv':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:sv':'String','name:he':'String','name:ja_rm':'String','name:ga':'String','name:br':'String','name:bs':'String','name:lb':'String','name:ko_rm':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:ru':'String','name:be':'String','name_en':'String','name:bg':'String','name:hr':'String','name:sr':'String','name:sq':'String','name:el':'String','name:eo':'String','name:en':'String','name':'String','name:gd':'String','ele_ft':'Number','name:ja_kana':'String','name:is':'String','osm_id':'Number','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'mountain_peak','description':''},{'maxzoom':14,'fields':{'class':'String'},'minzoom':0,'id':'park','description':''},{'maxzoom':14,'fields':{'admin_level':'Number','disputed':'Number','maritime':'Number'},'minzoom':0,'id':'boundary','description':''},{'maxzoom':14,'fields':{'ref':'String','class':'String'},'minzoom':0,'id':'aeroway','description':''},{'maxzoom':14,'fields':{'layer':'Number','service':'String','level':'Number','brunnel':'String','indoor':'Number','ramp':'Number','subclass':'String','oneway':'Number','class':'String'},'minzoom':0,'id':'transportation','description':''},{'maxzoom':14,'fields':{'render_min_height':'Number','render_height':'Number'},'minzoom':0,'id':'building','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:cy':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:hu':'String','name:ka':'String','name:fi':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:zh':'String','name:sl':'String','name:lv':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:sv':'String','name:he':'String','name:ja_rm':'String','name:ga':'String','name:br':'String','name:bs':'String','name:lb':'String','class':'String','name:ko_rm':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:be':'String','name_en':'String','name:bg':'String','name:hr':'String','name:sr':'String','name:sq':'String','name:el':'String','name:eo':'String','name:en':'String','name':'String','name:gd':'String','name:ja_kana':'String','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:nl':'String','name:es':'String'},'minzoom':0,'id':'water_name','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:cy':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','layer':'Number','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:hu':'String','name:ka':'String','name:fi':'String','name:da':'String','subclass':'String','name:de':'String','indoor':'Number','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:zh':'String','name:sl':'String','name:lv':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:sv':'String','name:he':'String','name:ja_rm':'String','name:ga':'String','name:br':'String','name:bs':'String','name:lb':'String','class':'String','name:ko_rm':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:be':'String','name_en':'String','name:bg':'String','name:hr':'String','name:sr':'String','name:sq':'String','network':'String','name:el':'String','name:eo':'String','name:en':'String','name':'String','name:gd':'String','ref':'String','name:ja_kana':'String','level':'Number','ref_length':'Number','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:nl':'String','name:es':'String'},'minzoom':0,'id':'transportation_name','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:cy':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','rank':'Number','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:hu':'String','name:ka':'String','name:fi':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:zh':'String','capital':'Number','name:sl':'String','name:lv':'String','name:ja':'String','name:ko_rm':'String','name:no':'String','name:kk':'String','name:sv':'String','name:he':'String','name:ja_rm':'String','name:ga':'String','name:br':'String','name:bs':'String','name:lb':'String','class':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:be':'String','name_en':'String','name:bg':'String','name:hr':'String','name:sr':'String','name:sq':'String','name:th':'String','name:el':'String','name:eo':'String','name:en':'String','name':'String','name:gd':'String','iso_a2':'String','name:ja_kana':'String','name:is':'String','name:lt':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:nl':'String','name:es':'String'},'minzoom':0,'id':'place','description':''},{'maxzoom':14,'fields':{'housenumber':'String'},'minzoom':0,'id':'housenumber','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:cy':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','rank':'Number','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:hu':'String','name:ka':'String','name:fi':'String','name:da':'String','subclass':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:zh':'String','name:sl':'String','name:lv':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:sv':'String','name:he':'String','name:ja_rm':'String','name:ga':'String','name:br':'String','name:bs':'String','name:lb':'String','class':'String','name:ko_rm':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:be':'String','name_en':'String','name:bg':'String','name:hr':'String','name:sr':'String','name:sq':'String','name:el':'String','name:eo':'String','name:en':'String','name':'String','name:gd':'String','name:ja_kana':'String','name:is':'String','name:th':'String','agg_stop':'Number','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:nl':'String','name:es':'String'},'minzoom':0,'id':'poi','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:cy':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:nl':'String','name:pl':'String','ele':'Number','name:lt':'String','name:ca':'String','name:hu':'String','name:ka':'String','name:fi':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:zh':'String','name:latin':'String','name:sl':'String','name:lv':'String','name:ja':'String','name:ko_rm':'String','name:no':'String','name:kk':'String','name:sv':'String','name:he':'String','name:ja_rm':'String','name:ga':'String','name:br':'String','name:bs':'String','name:lb':'String','class':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:ru':'String','name:be':'String','name_en':'String','name:bg':'String','name:hr':'String','name:sr':'String','name:sq':'String','name:th':'String','name:el':'String','name:eo':'String','name:en':'String','name':'String','name:gd':'String','ele_ft':'Number','name:ja_kana':'String','name:is':'String','osm_id':'Number','iata':'String','icao':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'aerodrome_label','description':''}],'center':[-12.2168,28.6135,4],'bounds':[-180,-85.0511,180,85.0511],'maskLevel':'8','planettime':'1523232000000','version':'3.7','tilejson':'2.0.0'}"); sourceJson.Name = source.Key; } else if (source.Value.Url.StartsWith("mbtiles")) { var dataSource = new MbTilesTileSource(new SQLiteConnectionString(source.Value.Url.Substring(10), false)); sourceJson = JsonConvert.DeserializeObject <Source>(@"{'vector_layers':[{'maxzoom':14,'fields':{'class':'String'},'minzoom':0,'id':'water','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:ka':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:lv':'String','name:bg':'String','name:cy':'String','name:fi':'String','name:he':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:be':'String','name:zh':'String','name:sr':'String','name:sl':'String','name:nl':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:ko_rm':'String','name:ja_rm':'String','name:br':'String','name:bs':'String','name:lb':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:sv':'String','name_en':'String','name:hu':'String','name:hr':'String','class':'String','name:sq':'String','name:el':'String','name:ga':'String','name:en':'String','name':'String','name:gd':'String','name:ja_kana':'String','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'waterway','description':''},{'maxzoom':14,'fields':{'class':'String','subclass':'String'},'minzoom':0,'id':'landcover','description':''},{'maxzoom':14,'fields':{'class':'String'},'minzoom':0,'id':'landuse','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:ka':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','rank':'Number','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:lv':'String','name:pl':'String','name:de':'String','name:ca':'String','name:bg':'String','name:cy':'String','name:fi':'String','name:he':'String','name:da':'String','ele':'Number','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:be':'String','name:zh':'String','name:sl':'String','name:nl':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:ko_rm':'String','name:ja_rm':'String','name:br':'String','name:bs':'String','name:lb':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:ru':'String','name:sv':'String','name_en':'String','name:hu':'String','name:hr':'String','name:sr':'String','name:sq':'String','name:el':'String','name:ga':'String','name:en':'String','name':'String','name:gd':'String','ele_ft':'Number','name:ja_kana':'String','name:is':'String','osm_id':'Number','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'mountain_peak','description':''},{'maxzoom':14,'fields':{'class':'String'},'minzoom':0,'id':'park','description':''},{'maxzoom':14,'fields':{'admin_level':'Number','disputed':'Number','maritime':'Number'},'minzoom':0,'id':'boundary','description':''},{'maxzoom':14,'fields':{'class':'String'},'minzoom':0,'id':'aeroway','description':''},{'maxzoom':14,'fields':{'brunnel':'String','ramp':'Number','class':'String','service':'String','oneway':'Number'},'minzoom':0,'id':'transportation','description':''},{'maxzoom':14,'fields':{'render_min_height':'Number','render_height':'Number'},'minzoom':0,'id':'building','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:ka':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:lv':'String','name:bg':'String','name:cy':'String','name:fi':'String','name:he':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:be':'String','name:zh':'String','name:sr':'String','name:sl':'String','name:nl':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:ko_rm':'String','name:ja_rm':'String','name:br':'String','name:bs':'String','name:lb':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:sv':'String','name_en':'String','name:hu':'String','name:hr':'String','class':'String','name:sq':'String','name:el':'String','name:ga':'String','name:en':'String','name':'String','name:gd':'String','name:ja_kana':'String','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'water_name','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:ka':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:lv':'String','name:bg':'String','name:cy':'String','name:fi':'String','name:he':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:be':'String','name:zh':'String','name:sr':'String','name:sl':'String','name:nl':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:ko_rm':'String','name:ja_rm':'String','name:br':'String','name:bs':'String','name:lb':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:sv':'String','name_en':'String','name:hu':'String','name:hr':'String','class':'String','name:sq':'String','network':'String','name:el':'String','name:ga':'String','name:en':'String','name':'String','name:gd':'String','ref':'String','name:ja_kana':'String','ref_length':'Number','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'transportation_name','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:ka':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','rank':'Number','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:lv':'String','name:bg':'String','name:cy':'String','name:hr':'String','name:fi':'String','name:he':'String','name:da':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:be':'String','name:zh':'String','name:sr':'String','name:sl':'String','name:nl':'String','name:ja':'String','name:ko_rm':'String','name:no':'String','name:kk':'String','capital':'Number','name:ja_rm':'String','name:br':'String','name:bs':'String','name:lb':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:sv':'String','name_en':'String','name:hu':'String','name:lt':'String','class':'String','name:sq':'String','name:el':'String','name:ga':'String','name:en':'String','name':'String','name:gd':'String','name:ja_kana':'String','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'place','description':''},{'maxzoom':14,'fields':{'housenumber':'String'},'minzoom':0,'id':'housenumber','description':''},{'maxzoom':14,'fields':{'name:mt':'String','name:pt':'String','name:az':'String','name:ka':'String','name:rm':'String','name:ko':'String','name:kn':'String','name:ar':'String','name:cs':'String','rank':'Number','name_de':'String','name:ro':'String','name:it':'String','name_int':'String','name:ru':'String','name:pl':'String','name:ca':'String','name:lv':'String','name:bg':'String','name:cy':'String','name:fi':'String','name:he':'String','name:da':'String','subclass':'String','name:de':'String','name:tr':'String','name:fr':'String','name:mk':'String','name:nonlatin':'String','name:fy':'String','name:be':'String','name:zh':'String','name:sr':'String','name:sl':'String','name:nl':'String','name:ja':'String','name:lt':'String','name:no':'String','name:kk':'String','name:ko_rm':'String','name:ja_rm':'String','name:br':'String','name:bs':'String','name:lb':'String','name:la':'String','name:sk':'String','name:uk':'String','name:hy':'String','name:sv':'String','name_en':'String','name:hu':'String','name:hr':'String','class':'String','name:sq':'String','name:el':'String','name:ga':'String','name:en':'String','name':'String','name:gd':'String','name:ja_kana':'String','name:is':'String','name:th':'String','name:latin':'String','name:sr-Latn':'String','name:et':'String','name:es':'String'},'minzoom':0,'id':'poi','description':''}]}"); //sourceJson = JsonConvert.DeserializeObject<Source>(dataSource.Json); sourceJson.Name = source.Key; sourceJson.Tiles = new List <string> { source.Value.Url }; sourceJson.Scheme = dataSource.Schema.YAxis == YAxis.TMS ? "tms" : "osm"; sourceJson.Bounds = new JValue[] { new JValue(dataSource.Schema.Extent.MinX), new JValue(dataSource.Schema.Extent.MinY), new JValue(dataSource.Schema.Extent.MaxX), new JValue(dataSource.Schema.Extent.MinX) }; } } // Create new vector layer var vectorTilelayer = CreateVectorLayer(sourceJson, symbolProvider); // Layer has a list of ThemeStyles, one for each style in style file vectorTilelayer.Style = new StyleCollection(); // Add all ThemeStyles for this layer foreach (var styleLayer in styleJson.StyleLayers) { ((StyleCollection)vectorTilelayer.Style).Add(styleLayer.Style); } // Add bounds to bounds of SymbolProvider symbolProvider.Bounds.Join(((VectorTileProvider)vectorTilelayer.DataSource).Bounds); // Only when Style avalible vectorTilelayer.Enabled = ((StyleCollection)vectorTilelayer.Style).Count > 0; // Add layer to map map.Layers.Add(vectorTilelayer); break; case "geoJson": break; case "image": break; case "video": break; default: throw new ArgumentException($"{source.Value.Type} isn't a valid source"); } } // Now add SymbolLayer at top most on map map.Layers.Add(new Layer("Symbols") { DataSource = symbolProvider, CRS = "EPSG:3857", MinVisible = 0, MaxVisible = double.PositiveInfinity, }); if (styleJson.Center != null) { Center = Projection.SphericalMercator.FromLonLat(styleJson.Center[0], styleJson.Center[1]); map.NavigateTo(Center); } map.ZoomMode = ZoomMode.None; }
private void MergeInSymbolArray(Symbol[] symbolsToAdd, out List <Symbol> createdSymbols, out List <Symbol> deletedSymbols) { int capacity = symbols.Length + symbolsToAdd.Length; //We don't know exact numbers of the new symbols, because some might get split, and some might get removed. //Thus we use a list, and chosen initial capacity makes some sense. var mergedIntervals = new List <Symbol>(capacity); var oldSymbols = new OldSymbolProvider(comparer, symbols); var newSymbols = new SymbolProvider(symbolsToAdd); createdSymbols = new List <Symbol>(); deletedSymbols = new List <Symbol>(); //While new and old symbols might interleave while (!oldSymbols.Empty && !newSymbols.Empty) { //While they do not overlap while (!oldSymbols.Empty && !newSymbols.Empty && !oldSymbols.Current.Overlaps(newSymbols.Current)) { //Symbols do not overlap here so it is sufficient to check only beginnings to find out which comes 1st. //In case of copying new symbol, we can move whole cake, because it will never be cached. if (oldSymbols.Current.Start < newSymbols.Current.Start) { mergedIntervals.Add(oldSymbols.Consume()); } else { CopyCake(mergedIntervals, newSymbols); } } if (oldSymbols.Empty || newSymbols.Empty) { break; } //Here we are sure that current old and new symbols overlap somehow // //While we are not behind the current new symbol, keep adding old symbols and hash them if needed. //Also handles zero length symbols. It is done with such an ugly condition, be cause otherwise, //Two loops would be needed, one before overlaps, and one after, for different placements of 0-length //symbols. while (!oldSymbols.Empty && ( oldSymbols.Current.Start < newSymbols.Current.End || ( newSymbols.Current.Length == 0 && oldSymbols.Current.Start == newSymbols.Current.End ))) { AddSymbolWithHashing(oldSymbols, newSymbols, mergedIntervals, createdSymbols, deletedSymbols); } //Copy in the new symbol cake CopyCake(mergedIntervals, newSymbols); } //Copy rest of the symbols. If the symbol comes from temporary list, it should be "materialized" while (!oldSymbols.Empty) { if (oldSymbols.CurrentType == OldSymbolProvider.SymbolType.Temporary) { createdSymbols.Add(oldSymbols.Current); } mergedIntervals.Add(oldSymbols.Consume()); } //Copy rest of the newSymbols CopyRest(mergedIntervals, newSymbols); symbols = mergedIntervals.ToArray(); }
public MapboxGLThemeStyle(StyleLayerConverter converter, StyleLayer styleLayer, Dictionary <string, Styles.Sprite> sprites, Viewport viewport, SymbolProvider symbolProvider) { _converter = converter; _styleLayer = styleLayer; _sprites = sprites; _viewport = viewport; _symbolProvider = symbolProvider; // Do this only once if (_viewport != null) { _viewport.ViewportChanged += (s, e) => { Zoom = FromResolution(_viewport.Resolution); ZoomLevel = (int)Math.Floor(Zoom); } } ; }