├── .gitattributes
├── .gitignore
├── README.md
├── VectorTileToBitmapRenderer.sln
├── VectorTileToBitmapRenderer.sln.DotSettings
├── docs
└── psychedelic-tiles.png
├── samples
└── VectorTileSample
│ ├── App.config
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── FetchStrategy.cs
│ ├── LayerList.xaml
│ ├── LayerList.xaml.cs
│ ├── LayerListItem.xaml
│ ├── LayerListItem.xaml.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ ├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
│ ├── VectorTileLayer.cs
│ ├── VectorTileSample.csproj
│ └── packages.config
└── src
└── VectorTileToBitmapRenderer
├── GDI
└── GeoJsonToGdiRenderer.cs
├── HttpVectorTileSource.cs
├── IGeoJSONRenderer.cs
├── OpenTK.dll.config
├── OpenTK
├── FrameBufferObjectHelper.cs
├── GeoJsonToOpenTKRenderer.cs
└── GraphicsContextToBitmapConverter.cs
├── Properties
└── AssemblyInfo.cs
├── SphericalMercator.cs
├── VectorTileToBitmapRenderer.csproj
├── VectorTileToBitmapRenderer.csproj.DotSettings
├── app.config
└── packages.config
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 |
28 | # MSTest test Results
29 | [Tt]est[Rr]esult*/
30 | [Bb]uild[Ll]og.*
31 |
32 | # NUNIT
33 | *.VisualState.xml
34 | TestResult.xml
35 |
36 | # Build Results of an ATL Project
37 | [Dd]ebugPS/
38 | [Rr]eleasePS/
39 | dlldata.c
40 |
41 | # DNX
42 | project.lock.json
43 | artifacts/
44 |
45 | *_i.c
46 | *_p.c
47 | *_i.h
48 | *.ilk
49 | *.meta
50 | *.obj
51 | *.pch
52 | *.pdb
53 | *.pgc
54 | *.pgd
55 | *.rsp
56 | *.sbr
57 | *.tlb
58 | *.tli
59 | *.tlh
60 | *.tmp
61 | *.tmp_proj
62 | *.log
63 | *.vspscc
64 | *.vssscc
65 | .builds
66 | *.pidb
67 | *.svclog
68 | *.scc
69 |
70 | # Chutzpah Test files
71 | _Chutzpah*
72 |
73 | # Visual C++ cache files
74 | ipch/
75 | *.aps
76 | *.ncb
77 | *.opensdf
78 | *.sdf
79 | *.cachefile
80 |
81 | # Visual Studio profiler
82 | *.psess
83 | *.vsp
84 | *.vspx
85 |
86 | # TFS 2012 Local Workspace
87 | $tf/
88 |
89 | # Guidance Automation Toolkit
90 | *.gpState
91 |
92 | # ReSharper is a .NET coding add-in
93 | _ReSharper*/
94 | *.[Rr]e[Ss]harper
95 | *.DotSettings.user
96 |
97 | # JustCode is a .NET coding add-in
98 | .JustCode
99 |
100 | # TeamCity is a build add-in
101 | _TeamCity*
102 |
103 | # DotCover is a Code Coverage Tool
104 | *.dotCover
105 |
106 | # NCrunch
107 | _NCrunch_*
108 | .*crunch*.local.xml
109 |
110 | # MightyMoose
111 | *.mm.*
112 | AutoTest.Net/
113 |
114 | # Web workbench (sass)
115 | .sass-cache/
116 |
117 | # Installshield output folder
118 | [Ee]xpress/
119 |
120 | # DocProject is a documentation generator add-in
121 | DocProject/buildhelp/
122 | DocProject/Help/*.HxT
123 | DocProject/Help/*.HxC
124 | DocProject/Help/*.hhc
125 | DocProject/Help/*.hhk
126 | DocProject/Help/*.hhp
127 | DocProject/Help/Html2
128 | DocProject/Help/html
129 |
130 | # Click-Once directory
131 | publish/
132 |
133 | # Publish Web Output
134 | *.[Pp]ublish.xml
135 | *.azurePubxml
136 | ## TODO: Comment the next line if you want to checkin your
137 | ## web deploy settings but do note that will include unencrypted
138 | ## passwords
139 | #*.pubxml
140 |
141 | *.publishproj
142 |
143 | # NuGet Packages
144 | *.nupkg
145 | # The packages folder can be ignored because of Package Restore
146 | **/packages/*
147 | # except build/, which is used as an MSBuild target.
148 | !**/packages/build/
149 | # Uncomment if necessary however generally it will be regenerated when needed
150 | #!**/packages/repositories.config
151 |
152 | # Windows Azure Build Output
153 | csx/
154 | *.build.csdef
155 |
156 | # Windows Store app package directory
157 | AppPackages/
158 |
159 | # Visual Studio cache files
160 | # files ending in .cache can be ignored
161 | *.[Cc]ache
162 | # but keep track of directories ending in .cache
163 | !*.[Cc]ache/
164 |
165 | # Others
166 | ClientBin/
167 | [Ss]tyle[Cc]op.*
168 | ~$*
169 | *~
170 | *.dbmdl
171 | *.dbproj.schemaview
172 | *.pfx
173 | *.publishsettings
174 | node_modules/
175 | orleans.codegen.cs
176 |
177 | # RIA/Silverlight projects
178 | Generated_Code/
179 |
180 | # Backup & report files from converting an old project file
181 | # to a newer Visual Studio version. Backup files are not needed,
182 | # because we have git ;-)
183 | _UpgradeReport_Files/
184 | Backup*/
185 | UpgradeLog*.XML
186 | UpgradeLog*.htm
187 |
188 | # SQL Server files
189 | *.mdf
190 | *.ldf
191 |
192 | # Business Intelligence projects
193 | *.rdl.data
194 | *.bim.layout
195 | *.bim_*.settings
196 |
197 | # Microsoft Fakes
198 | FakesAssemblies/
199 |
200 | # Node.js Tools for Visual Studio
201 | .ntvs_analysis.dat
202 |
203 | # Visual Studio 6 build log
204 | *.plg
205 |
206 | # Visual Studio 6 workspace options file
207 | *.opt
208 |
209 | # LightSwitch generated files
210 | GeneratedArtifacts/
211 | _Pvt_Extensions/
212 | ModelManifest.xml
213 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VectorTileToBitmapRenderer
2 | Renders vector tiles to PNGs. This makes it easy to render a vector tile in a client that is capable of bitmap rendering. It is not possible to draw the vectors directly on your clients canvas which will reduce quality in some cases. It is however still possible to choose the styling used to render to bitmap.
3 |
4 | It uses [mapbox-vector-tile-cs](https://github.com/bertt/mapbox-vector-tile-cs) to parse vector tiles. This turns is into [GeoJSON.NET](https://github.com/GeoJSON-Net/GeoJSON.Net) objects.
5 |
6 | ## Roadmap
7 | * Do nothing unless a real need arises
8 | * Wait a little more
9 | * Use SkiaSharp rendering, remove GDI and OpenTK
10 | * Add configurable styling
11 | * Use vector tile style
12 |
13 | ## Sample
14 | The repo contains a sample of the awesome psychedelic tile renderer which has value all of its own :)
15 |
16 | 
17 |
--------------------------------------------------------------------------------
/VectorTileToBitmapRenderer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectorTileToBitmapRenderer", "src\VectorTileToBitmapRenderer\VectorTileToBitmapRenderer.csproj", "{CD32D7AD-2B89-4E3A-B204-B9D2B179F3F5}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EE5731D0-11F9-4A36-867F-6AD1260048FF}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{80B98CD5-CFD0-4BA7-A11F-96A9CAED5DAE}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectorTileSample", "samples\VectorTileSample\VectorTileSample.csproj", "{57D747AA-79C3-4F05-A165-33CCA6158C16}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {CD32D7AD-2B89-4E3A-B204-B9D2B179F3F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {CD32D7AD-2B89-4E3A-B204-B9D2B179F3F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {CD32D7AD-2B89-4E3A-B204-B9D2B179F3F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {CD32D7AD-2B89-4E3A-B204-B9D2B179F3F5}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {57D747AA-79C3-4F05-A165-33CCA6158C16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {57D747AA-79C3-4F05-A165-33CCA6158C16}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {57D747AA-79C3-4F05-A165-33CCA6158C16}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {57D747AA-79C3-4F05-A165-33CCA6158C16}.Release|Any CPU.Build.0 = Release|Any CPU
28 | EndGlobalSection
29 | GlobalSection(SolutionProperties) = preSolution
30 | HideSolutionNode = FALSE
31 | EndGlobalSection
32 | GlobalSection(NestedProjects) = preSolution
33 | {CD32D7AD-2B89-4E3A-B204-B9D2B179F3F5} = {EE5731D0-11F9-4A36-867F-6AD1260048FF}
34 | {57D747AA-79C3-4F05-A165-33CCA6158C16} = {80B98CD5-CFD0-4BA7-A11F-96A9CAED5DAE}
35 | EndGlobalSection
36 | EndGlobal
37 |
--------------------------------------------------------------------------------
/VectorTileToBitmapRenderer.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | JSON
--------------------------------------------------------------------------------
/docs/psychedelic-tiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsmSharp/VectorTileToBitmapRenderer/836badf784c49f917334c5a587d41d9637ab2495/docs/psychedelic-tiles.png
--------------------------------------------------------------------------------
/samples/VectorTileSample/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace VectorTileSample
2 | {
3 | ///
4 | /// Interaction logic for App.xaml
5 | ///
6 | public partial class App
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/FetchStrategy.cs:
--------------------------------------------------------------------------------
1 | // Copyright 2009 - Paul den Dulk (Geodan)
2 | //
3 | // This file is part of SharpMap.
4 | // Mapsui is free software; you can redistribute it and/or modify
5 | // it under the terms of the GNU Lesser General Public License as published by
6 | // the Free Software Foundation; either version 2 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // SharpMap is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU Lesser General Public License for more details.
13 |
14 | // You should have received a copy of the GNU Lesser General Public License
15 | // along with SharpMap; if not, write to the Free Software
16 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | using System.Collections.Generic;
19 | using System.Linq;
20 | using BruTile;
21 | using Mapsui.Fetcher;
22 | using Mapsui.Geometries.Utilities;
23 | using Mapsui.Utilities;
24 |
25 | namespace VectorTileSample
26 | {
27 | public class FetchStrategy : IFetchStrategy
28 | {
29 | public IList GetTilesWanted(ITileSchema schema, Extent extent, string levelId)
30 | {
31 | var infos = new List();
32 | // Iterating through all levels from current to zero. If lower levels are
33 | // not available the renderer can fall back on higher level tiles.
34 | var resolution = schema.Resolutions[levelId].UnitsPerPixel;
35 | var levels = schema.Resolutions.Where(k => k.Value.UnitsPerPixel >= resolution).OrderBy(x => x.Value.UnitsPerPixel).ToList();
36 |
37 | foreach (var level in levels)
38 | {
39 | var tileInfos = schema.GetTileInfos(extent, level.Key).OrderBy(
40 | t => Algorithms.Distance(extent.CenterX, extent.CenterY, t.Extent.CenterX, t.Extent.CenterY));
41 |
42 | foreach (TileInfo info in tileInfos.Where(info => (info.Index.Row >= 0) && (info.Index.Col >= 0)))
43 | {
44 | infos.Add(info);
45 | }
46 | }
47 |
48 | return infos;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/LayerList.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/LayerList.xaml.cs:
--------------------------------------------------------------------------------
1 | using Mapsui;
2 | using Mapsui.Layers;
3 |
4 | namespace VectorTileSample
5 | {
6 | ///
7 | /// Interaction logic for LayerList.xaml
8 | ///
9 | public partial class LayerList
10 | {
11 | public LayerList()
12 | {
13 | InitializeComponent();
14 | }
15 |
16 | public void Initialize(LayerCollection layers)
17 | {
18 | Items.Children.Clear();
19 |
20 | foreach (var layer in layers)
21 | {
22 | var item = new LayerListItem {LayerName = layer.Name};
23 | item.Enabled = layer.Enabled;
24 | item.LayerOpacity = layer.Opacity;
25 | item.Layer = layer;
26 | Items.Children.Add(item);
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/LayerListItem.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 | Text
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/LayerListItem.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 | using Mapsui.Layers;
4 |
5 | namespace VectorTileSample
6 | {
7 | public partial class LayerListItem
8 | {
9 | public ILayer Layer { private get; set; }
10 |
11 | public string LayerName
12 | {
13 | set { TextBlock.Text = value; }
14 | }
15 |
16 | public double LayerOpacity
17 | {
18 | set { OpacitySlider.Value = value; }
19 | }
20 |
21 | public bool? Enabled
22 | {
23 | set { EnabledCheckBox.IsChecked = value; }
24 | }
25 |
26 | public LayerListItem()
27 | {
28 | InitializeComponent();
29 | OpacitySlider.IsMoveToPointEnabled = true; // mouse click moves slider to that specific position (otherwise only 0 or 1 is selected)
30 | }
31 |
32 | private void OpacitySliderValueChanged(object sender, RoutedPropertyChangedEventArgs e)
33 | {
34 | var tempLayer = Layer;
35 | if (tempLayer != null)
36 | {
37 | tempLayer.Opacity = e.NewValue;
38 | }
39 | }
40 |
41 | private void EnabledCheckBoxClick(object sender, RoutedEventArgs e)
42 | {
43 | var tempLayer = Layer;
44 | if (tempLayer != null)
45 | {
46 | tempLayer.Enabled = ((CheckBox)e.Source).IsChecked != false;
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using BruTile.Predefined;
3 | using Mapsui.Layers;
4 | using VectorTileToBitmapRenderer;
5 |
6 | namespace VectorTileSample
7 | {
8 | ///
9 | /// Interaction logic for MainWindow.xaml
10 | ///
11 | public partial class MainWindow
12 | {
13 | readonly HttpVectorTileSource _httpVectorTileSource;
14 | readonly ILayer _vectorTileLayer;
15 | public MainWindow()
16 | {
17 | InitializeComponent();
18 |
19 | MapControl.Map.Layers.Add(new TileLayer(KnownTileSources.Create()) { Name = "OpenStreetMap"});
20 |
21 | _httpVectorTileSource = CreateVectorTileTileSource();
22 | // FUTURE_httpVectorTileSource = new HttpTileSource (new GlobalSphericalMercator(), "https://tile.mapzen.com/mapzen/vector/v1/all/{z}/{x}/{y}.mvt?api_key=mapzen-tnjqimH");
23 |
24 | _vectorTileLayer = new TileLayer(_httpVectorTileSource) { Opacity = 0.5, Name = "Mapzen vector tiles"};
25 | // FUTURE: _vectorTileLayer = new VectorTileLayer(_httpVectorTileSource);
26 |
27 | MapControl.Map.Layers.Add(_vectorTileLayer);
28 |
29 | MapsuiLayerList.Initialize(MapControl.Map.Layers);
30 | }
31 |
32 | public HttpVectorTileSource CreateVectorTileTileSource()
33 | {
34 | return new HttpVectorTileSource(
35 | new GlobalSphericalMercator(),
36 | "http://tile.mapzen.com/mapzen/vector/v1/all/{z}/{x}/{y}.mvt?api_key=mapzen-tnjqimH",
37 | name: "vector tile");
38 | }
39 |
40 | private void GDI_OnClick(object sender, RoutedEventArgs e)
41 | {
42 | _httpVectorTileSource.UseGdi = true;
43 | _vectorTileLayer.ClearCache();
44 | MapControl.Refresh();
45 | }
46 |
47 | private void OpenTK_OnClick(object sender, RoutedEventArgs e)
48 | {
49 | _httpVectorTileSource.UseGdi = false;
50 | _vectorTileLayer.ClearCache();
51 | MapControl.Refresh();
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("VectorTileSample")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("VectorTileSample")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | //In order to begin building localizable applications, set
23 | //CultureYouAreCodingWith in your .csproj file
24 | //inside a . For example, if you are using US english
25 | //in your source files, set the to en-US. Then uncomment
26 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
27 | //the line below to match the UICulture setting in the project file.
28 |
29 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
30 |
31 |
32 | [assembly: ThemeInfo(
33 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
34 | //(used if a resource is not found in the page,
35 | // or application resource dictionaries)
36 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
37 | //(used if a resource is not found in the page,
38 | // app, or any theme specific resource dictionaries)
39 | )]
40 |
41 |
42 | // Version information for an assembly consists of the following four values:
43 | //
44 | // Major Version
45 | // Minor Version
46 | // Build Number
47 | // Revision
48 | //
49 | // You can specify all the values or you can default the Build and Revision Numbers
50 | // by using the '*' as shown below:
51 | // [assembly: AssemblyVersion("1.0.*")]
52 | [assembly: AssemblyVersion("1.0.0.0")]
53 | [assembly: AssemblyFileVersion("1.0.0.0")]
54 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace VectorTileSample.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VectorTileSample.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace VectorTileSample.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/VectorTileLayer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using BruTile;
6 | using BruTile.Cache;
7 | using Mapsui.Fetcher;
8 | using Mapsui.Geometries;
9 | using Mapsui.Layers;
10 | using Mapsui.Providers;
11 | using Mapsui.Rendering;
12 |
13 | namespace VectorTileSample
14 | {
15 | public class VectorTileLayer : BaseLayer
16 | {
17 | private readonly ITileSource _tileSource;
18 | private readonly MemoryCache _tileCache = new MemoryCache();
19 | private readonly IRenderGetStrategy _renderStrategy;
20 | private readonly IFetchStrategy _fetchStrategy = new FetchStrategy();
21 | private readonly TileFetcher _tileFetcher;
22 | private List _vectorCache = new List();
23 |
24 | public VectorTileLayer(ITileSource tileSource, RenderGetStrategy renderStrategy = null)
25 | {
26 | _tileSource = tileSource;
27 | _tileFetcher = new TileFetcher(_tileSource, _tileCache, 1, 4, _fetchStrategy);
28 | _tileFetcher.DataChanged += TileFetcherOnDataChanged;
29 | _tileFetcher.PropertyChanged += TileFetcherOnPropertyChanged;
30 | _renderStrategy = renderStrategy ?? new RenderGetStrategy();
31 | }
32 |
33 | private void TileFetcherOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
34 | {
35 | if (propertyChangedEventArgs.PropertyName != nameof(Busy)) return;
36 | if (_tileFetcher != null) Busy = _tileFetcher.Busy;
37 | }
38 |
39 | private void TileFetcherOnDataChanged(object sender, DataChangedEventArgs dataChangedEventArgs)
40 | {
41 |
42 | }
43 |
44 | public override IEnumerable GetFeaturesInView(BoundingBox box, double resolution)
45 | {
46 | if (_tileSource?.Schema == null) return Enumerable.Empty();
47 |
48 | return _renderStrategy.GetFeatures(box, resolution, _tileSource?.Schema, _tileCache);
49 | }
50 |
51 | public override BoundingBox Envelope => _tileSource?.Schema?.Extent.ToBoundingBox();
52 |
53 | public override void AbortFetch()
54 | {
55 | // method should be removed
56 | }
57 |
58 | public override void ViewChanged(bool majorChange, BoundingBox extent, double resolution)
59 | {
60 | if (Enabled && extent.GetArea() > 0 && _tileFetcher != null && MaxVisible > resolution && MinVisible < resolution)
61 | {
62 | _tileFetcher.ViewChanged(extent, resolution);
63 | }
64 | }
65 |
66 | public override void ClearCache()
67 | {
68 | _tileCache.Clear();
69 | _vectorCache.Clear();
70 | }
71 |
72 | public override bool? IsCrsSupported(string crs)
73 | {
74 | return string.Equals(ToSimpleEpsgCode(), crs, StringComparison.CurrentCultureIgnoreCase);
75 | }
76 |
77 | string ToSimpleEpsgCode()
78 | {
79 | var startEpsgCode = _tileSource.Schema.Srs.IndexOf("EPSG:", StringComparison.Ordinal);
80 | if (startEpsgCode < 0) return _tileSource.Schema.Srs;
81 | return _tileSource.Schema.Srs.Substring(startEpsgCode).Replace("::", ":").Trim();
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/VectorTileSample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {57D747AA-79C3-4F05-A165-33CCA6158C16}
8 | WinExe
9 | Properties
10 | VectorTileSample
11 | VectorTileSample
12 | v4.5.2
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | true
17 |
18 |
19 |
20 |
21 | AnyCPU
22 | true
23 | full
24 | false
25 | bin\Debug\
26 | DEBUG;TRACE
27 | prompt
28 | 4
29 |
30 |
31 | AnyCPU
32 | pdbonly
33 | true
34 | bin\Release\
35 | TRACE
36 | prompt
37 | 4
38 |
39 |
40 |
41 | ..\..\packages\BruTile.0.22.1\lib\portable-net45+win+WindowsPhoneApp81+Xamarin.iOS10+MonoAndroid10+MonoTouch10\BruTile.dll
42 |
43 |
44 | ..\..\packages\ConcurrentHashSet.1.0.2\lib\netstandard1.0\ConcurrentCollections.dll
45 |
46 |
47 | ..\..\packages\Mapsui.1.1.1\lib\net45\Mapsui.dll
48 |
49 |
50 | ..\..\packages\Mapsui.1.1.1\lib\net45\Mapsui.Geometries.dll
51 |
52 |
53 | ..\..\packages\Mapsui.1.1.1\lib\net45\Mapsui.Rendering.Skia.dll
54 |
55 |
56 | ..\..\packages\Mapsui.1.1.1\lib\net45\Mapsui.Rendering.Xaml.dll
57 |
58 |
59 | ..\..\packages\Mapsui.1.1.1\lib\net45\Mapsui.UI.Wpf.dll
60 |
61 |
62 | ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
63 |
64 |
65 | ..\..\packages\SkiaSharp.1.59.1\lib\net45\SkiaSharp.dll
66 |
67 |
68 | ..\..\packages\SkiaSharp.Views.1.59.1.1\lib\net45\SkiaSharp.Views.Desktop.dll
69 |
70 |
71 | ..\..\packages\SkiaSharp.Views.1.59.1.1\lib\net45\SkiaSharp.Views.WPF.dll
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | 4.0
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | MSBuild:Compile
91 | Designer
92 |
93 |
94 |
95 |
96 | MSBuild:Compile
97 | Designer
98 |
99 |
100 | MSBuild:Compile
101 | Designer
102 |
103 |
104 | MSBuild:Compile
105 | Designer
106 |
107 |
108 | App.xaml
109 | Code
110 |
111 |
112 | LayerList.xaml
113 |
114 |
115 | LayerListItem.xaml
116 |
117 |
118 | MainWindow.xaml
119 | Code
120 |
121 |
122 |
123 |
124 | Code
125 |
126 |
127 | True
128 | True
129 | Resources.resx
130 |
131 |
132 | True
133 | Settings.settings
134 | True
135 |
136 |
137 | ResXFileCodeGenerator
138 | Resources.Designer.cs
139 |
140 |
141 |
142 | SettingsSingleFileGenerator
143 | Settings.Designer.cs
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | {cd32d7ad-2b89-4e3a-b204-b9d2b179f3f5}
153 | VectorTileToBitmapRenderer
154 |
155 |
156 |
157 |
158 |
159 |
160 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
161 |
162 |
163 |
164 |
171 |
--------------------------------------------------------------------------------
/samples/VectorTileSample/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/GDI/GeoJsonToGdiRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Drawing.Drawing2D;
5 | using System.IO;
6 | using GeoJSON.Net;
7 | using GeoJSON.Net.Feature;
8 | using GeoJSON.Net.Geometry;
9 |
10 | namespace VectorTileToBitmapRenderer
11 | {
12 | public class GeoJsonToGdiRenderer : IGeoJsonRenderer
13 | {
14 | private readonly int _canvasWidth;
15 | private readonly int _canvasHeight;
16 | private readonly float _extentMinX;
17 | private readonly float _extentMinY;
18 | private readonly float _extentWidth;
19 | private readonly float _extentHeight;
20 |
21 | public GeoJsonToGdiRenderer(int canvasWidth, int canvasHeight, double[] boundingBox)
22 | {
23 | _canvasWidth = canvasWidth;
24 | _canvasHeight = canvasHeight;
25 | _extentMinX = (float)boundingBox[0];
26 | _extentMinY = (float) boundingBox[1];
27 | _extentWidth = (float)boundingBox[2] -_extentMinX;
28 | _extentHeight = (float)boundingBox[3] - _extentMinY;
29 | }
30 |
31 | public byte[] Render(IEnumerable featureCollections)
32 | {
33 | var random = new Random();
34 |
35 | using (var bitmap = new Bitmap(_canvasWidth, _canvasHeight))
36 | using (var canvas = Graphics.FromImage(bitmap))
37 | {
38 | foreach (var featureCollection in featureCollections)
39 | {
40 | foreach (var feature in featureCollection.Features)
41 | {
42 | if (feature.Geometry.Type == GeoJSONObjectType.Polygon)
43 | {
44 | var polygon = (Polygon) feature.Geometry;
45 |
46 | foreach (var lineString in polygon.Coordinates)
47 | {
48 | canvas.Transform = CreateTransformMatrix(_canvasWidth, _canvasHeight, _extentMinX, _extentMinY, _extentWidth, _extentHeight);
49 | using (var brush = new SolidBrush(
50 | Color.FromArgb(random.Next(256), random.Next(256), random.Next(256))))
51 | {
52 | canvas.FillPolygon(brush, ToGdi(lineString));
53 |
54 | }
55 | }
56 | }
57 | }
58 | }
59 | return ToBytes(bitmap);
60 | }
61 | }
62 |
63 | private static Matrix CreateTransformMatrix(int canvasWidth, int canvasHeight, float minX, float minY, float width, float height)
64 | {
65 | // The code below needs no comments, it is fully intuitive.
66 | // I wrote in in one go and it ran correctly right away.
67 | var matrix = new Matrix();
68 | var flipMatrix = new Matrix(1, 0, 0, -1, 0, 0);
69 | matrix.Multiply(flipMatrix);
70 | matrix.Scale(canvasWidth/width, canvasHeight/height);
71 | var maxY = minY + height;
72 | matrix.Translate(-minX, -maxY);
73 | return matrix;
74 | }
75 |
76 | private static PointF[] ToGdi(LineString lineString)
77 | {
78 | var result = new List();
79 |
80 | foreach (var coordinate in lineString.Coordinates)
81 | {
82 | var position = (GeographicPosition)coordinate;
83 | result.Add(SphericalMercator.FromLonLat(position.Longitude, position.Latitude));
84 | }
85 | return result.ToArray();
86 | }
87 |
88 | private static byte[] ToBytes(Image img)
89 | {
90 | using (var stream = new MemoryStream())
91 | {
92 | img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
93 | return stream.ToArray();
94 | }
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/HttpVectorTileSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Net.Http;
7 | using BruTile;
8 | using BruTile.Cache;
9 | using BruTile.Web;
10 | using Mapbox.Vector.Tile;
11 |
12 | namespace VectorTileToBitmapRenderer
13 | {
14 | public class HttpVectorTileSource : HttpTileSource
15 | {
16 | public HttpVectorTileSource(ITileSchema tileSchema, string urlFormatter, IEnumerable serverNodes = null, string apiKey = null, string name = null, IPersistentCache persistentCache = null)
17 | : base(tileSchema, urlFormatter, serverNodes, apiKey, name, persistentCache, FetchTile)
18 | {
19 | }
20 |
21 | private static byte[] FetchTile(Uri url)
22 | {
23 | var gzipWebClient = new HttpClient(new HttpClientHandler()
24 | {
25 | AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
26 | });
27 | return gzipWebClient.GetByteArrayAsync(url).Result;
28 | }
29 |
30 | public override byte[] GetTile(TileInfo tileInfo)
31 | {
32 | var bytes = base.GetTile(tileInfo);
33 | var index = tileInfo.Index;
34 | var layerInfos = VectorTileParser.Parse(new MemoryStream(bytes));
35 | var tileWidth = Schema.GetTileWidth(tileInfo.Index.Level);
36 | var tileHeight = Schema.GetTileHeight(tileInfo.Index.Level);
37 | var geoJSONRenderer = GetGeoJsonRenderer(tileInfo, tileWidth, tileHeight);
38 | return geoJSONRenderer.Render(layerInfos.Select(i => i.ToGeoJSON(index.Col, index.Row, int.Parse(index.Level))));
39 | }
40 |
41 | private IGeoJsonRenderer GetGeoJsonRenderer(TileInfo tileInfo, int tileWidth, int tileHeight)
42 | {
43 | if (UseGdi)
44 | return new GeoJsonToGdiRenderer(tileWidth, tileHeight, ToGeoJSONArray(tileInfo.Extent));
45 | return new GeoJsonToOpenTKRenderer(tileWidth, tileHeight, ToGeoJSONArray(tileInfo.Extent));
46 | }
47 |
48 | public bool UseGdi { private get; set; } = true;
49 |
50 | private static double[] ToGeoJSONArray(Extent extent)
51 | {
52 | // GeoJSON.NET has no class for bounding boxes. It just holds them in a double array.
53 | // The spec says it should first the lowest and then all the highest values for all axes:
54 | // http://geojson.org/geojson-spec.html#bounding-boxes
55 | return new [] {extent.MinX, extent.MinY, extent.MaxX, extent.MaxY };
56 |
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/IGeoJSONRenderer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using GeoJSON.Net.Feature;
3 |
4 | namespace VectorTileToBitmapRenderer
5 | {
6 | public interface IGeoJsonRenderer
7 | {
8 | byte[] Render(IEnumerable featureCollections);
9 | }
10 | }
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/OpenTK.dll.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/OpenTK/FrameBufferObjectHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using OpenTK.Graphics.ES20;
3 | #pragma warning disable 618 // Not obsolte for Android. It needs to cross compile
4 |
5 | namespace VectorTileToBitmapRenderer
6 | {
7 | internal static class FrameBufferObjectHelper
8 | {
9 | public static void StopFrameBufferObject()
10 | {
11 | GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); // disable rendering into the FBO
12 | GL.Enable(EnableCap.Texture2D); // enable Texture Mapping
13 | GL.BindTexture(TextureTarget.Texture2D, 0); // bind default texture
14 | }
15 |
16 | public static void StartFrameBufferObject(int width, int height)
17 | {
18 | uint colorTexture;
19 | uint depthTexture;
20 | uint fboHandle;
21 |
22 | // Create Color Tex
23 | GL.GenTextures(1, out colorTexture);
24 | GL.BindTexture(TextureTarget.Texture2D, colorTexture);
25 | GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba,
26 | PixelType.UnsignedByte, IntPtr.Zero);
27 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
28 | (int) TextureMinFilter.Linear);
29 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
30 | (int) TextureMagFilter.Linear);
31 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
32 | (int) TextureWrapMode.ClampToEdge);
33 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
34 | (int) TextureWrapMode.ClampToEdge);
35 | // GL.Ext.GenerateMipmap( GenerateMipmapTarget.Texture2D );
36 |
37 | // Create Depth Tex
38 | GL.GenTextures(1, out depthTexture);
39 | GL.BindTexture(TextureTarget.Texture2D, depthTexture);
40 | GL.TexImage2D(TextureTarget.Texture2D, 0, (PixelInternalFormat) All.DepthComponent32Oes, width, height, 0,
41 | PixelFormat.DepthComponent, PixelType.UnsignedByte, IntPtr.Zero);
42 | // things go horribly wrong if DepthComponent's Bitcount does not match the main Framebuffer's Depth
43 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
44 | (int) TextureMinFilter.Linear);
45 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
46 | (int) TextureMagFilter.Linear);
47 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
48 | (int) TextureWrapMode.ClampToEdge);
49 | GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
50 | (int) TextureWrapMode.ClampToEdge);
51 |
52 | // Create a FBO and attach the textures
53 | GL.GenFramebuffers(1, out fboHandle);
54 | GL.BindFramebuffer(All.Framebuffer, fboHandle);
55 | GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0,
56 | TextureTarget.Texture2D,
57 | (int) colorTexture, 0);
58 | GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.DepthAttachment,
59 | TextureTarget.Texture2D,
60 | (int) depthTexture, 0);
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/OpenTK/GeoJsonToOpenTKRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using GeoJSON.Net;
4 | using GeoJSON.Net.Feature;
5 | using GeoJSON.Net.Geometry;
6 | using OpenTK;
7 | using OpenTK.Graphics;
8 | using All = OpenTK.Graphics.ES11.All;
9 | using ClearBufferMask = OpenTK.Graphics.ES20.ClearBufferMask;
10 | using GL = OpenTK.Graphics.ES11.GL;
11 | using MatrixMode = OpenTK.Graphics.ES11.MatrixMode;
12 | using StringName = OpenTK.Graphics.ES11.StringName;
13 | #pragma warning disable 618 // Not obsolte for Android. It needs to cross compile
14 |
15 | namespace VectorTileToBitmapRenderer
16 | {
17 | public class GeoJsonToOpenTKRenderer : IGeoJsonRenderer
18 | {
19 | private readonly int _pixelWidth;
20 | private readonly int _pixelHeight;
21 | private readonly float _extentMinX;
22 | private readonly float _extentMinY;
23 | private readonly float _extentWidth;
24 | private readonly float _extentHeight;
25 | private readonly object _syncRoot = new object();
26 |
27 | public GeoJsonToOpenTKRenderer(int pixelWidth, int pixelHeight, double[] boundingBox)
28 | {
29 | _pixelWidth = pixelWidth;
30 | _pixelHeight = pixelHeight;
31 | _extentMinX = (float)boundingBox[0];
32 | _extentMinY = (float)boundingBox[1];
33 | _extentWidth = (float)boundingBox[2] - _extentMinX;
34 | _extentHeight = (float)boundingBox[3] - _extentMinY;
35 | }
36 |
37 | public byte[] Render(IEnumerable featureCollections)
38 | {
39 | lock (_syncRoot)
40 | {
41 | // There needs to be a gamewindow even though we don't write to screen. It is created but not used explicitly in our code.
42 | // ReSharper disable once UnusedVariable
43 | using (var gameWindow = new GameWindow(_pixelWidth, _pixelHeight))
44 | {
45 | if (!GL.GetString(StringName.Extensions).Contains("GL_EXT_framebuffer_object"))
46 | {
47 | throw new NotSupportedException(
48 | "GL_EXT_framebuffer_object extension is required. Please update your drivers.");
49 | }
50 |
51 | FrameBufferObjectHelper.StartFrameBufferObject(_pixelWidth, _pixelHeight);
52 |
53 | OpenTK.Graphics.ES20.GL.ClearColor(Color4.White);
54 | OpenTK.Graphics.ES20.GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
55 |
56 | Set2DViewport(_pixelWidth, _pixelHeight);
57 |
58 | GL.PushMatrix();
59 |
60 | GL.Scale(_pixelWidth / _extentWidth, _pixelHeight / _extentHeight, 1);
61 | GL.Translate(-_extentMinX, -_extentMinY, 0);
62 |
63 | PolygonRenderer(featureCollections);
64 | var byteArray = GraphicsContextToBitmapConverter.ToBitmap(_pixelWidth, _pixelHeight);
65 |
66 | GL.PopMatrix();
67 |
68 | FrameBufferObjectHelper.StopFrameBufferObject();
69 |
70 | return byteArray;
71 | }
72 | }
73 | }
74 |
75 | private static void Set2DViewport(int pixelWidth, int pixelHeight)
76 | {
77 | GL.Viewport(0, 0, pixelWidth, pixelHeight);
78 |
79 | GL.MatrixMode(MatrixMode.Projection);
80 | GL.LoadIdentity();
81 |
82 | OpenTK.Graphics.OpenGL.GL.Ortho(0, pixelWidth, pixelHeight, 0, -1, 1); // This has no effect: OpenTK.Graphics.ES11.GL.Ortho(0, width, height, 0, 0, 1);
83 | }
84 |
85 | private void PolygonRenderer(IEnumerable featureCollections)
86 | {
87 | foreach (var featureCollection in featureCollections)
88 | {
89 | foreach (var feature in featureCollection.Features)
90 | {
91 | if (feature.Geometry.Type == GeoJSONObjectType.Polygon)
92 | {
93 | var polygon = (Polygon)feature.Geometry;
94 |
95 | foreach (var lineString in polygon.Coordinates)
96 | {
97 | RenderPolygon(lineString);
98 | }
99 | }
100 | }
101 | }
102 | }
103 |
104 | private void RenderPolygon(LineString lineString)
105 | {
106 | float lineWidth = 0;
107 |
108 | float[] points = ToOpenTK(lineString);
109 |
110 | GL.LineWidth(lineWidth);
111 | GL.Color4(0, 0, 0, 255);
112 | GL.EnableClientState(All.VertexArray);
113 | GL.VertexPointer(2, All.Float, 0, points);
114 | GL.DrawArrays(All.LineLoop, 0, points.Length / 2);
115 | GL.DisableClientState(All.VertexArray);
116 | }
117 |
118 | private static float[] ToOpenTK(LineString lineString)
119 | {
120 | const int dimensions = 2; // x and y are both in one array
121 | var points = new float[lineString.Coordinates.Count * dimensions];
122 |
123 | var counter = 0;
124 | foreach (var coordinate in lineString.Coordinates)
125 | {
126 | var position = (GeographicPosition)coordinate;
127 | var point = SphericalMercator.FromLonLat(position.Longitude, position.Latitude);
128 | points[counter * 2 + 0] = point.X;
129 | points[counter * 2 + 1] = point.Y;
130 | counter++;
131 | }
132 |
133 | return points;
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/OpenTK/GraphicsContextToBitmapConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Drawing.Imaging;
3 | using System.IO;
4 | using OpenTK.Graphics;
5 | using OpenTK.Graphics.OpenGL;
6 | using PixelFormat = OpenTK.Graphics.OpenGL.PixelFormat;
7 |
8 | namespace VectorTileToBitmapRenderer
9 | {
10 | static class GraphicsContextToBitmapConverter
11 | {
12 | public static byte[] ToBitmap(int width, int height)
13 | {
14 | var bitmap = GrabScreenshot(width, height);
15 | var byteArray = BitmapToByteArray(bitmap);
16 | return byteArray;
17 | }
18 |
19 | private static byte[] BitmapToByteArray(Bitmap bitmap)
20 | {
21 | var memoryStream = new MemoryStream();
22 | bitmap.Save(memoryStream, ImageFormat.Png);
23 | memoryStream.Position = 0;
24 | return memoryStream.ToArray();
25 | }
26 |
27 | private static Bitmap GrabScreenshot(int width, int height)
28 | {
29 | if (GraphicsContext.CurrentContext == null)
30 | throw new GraphicsContextMissingException();
31 |
32 | var bitmap = new Bitmap(width, height);
33 | BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
34 | GL.ReadPixels(0, 0, width, height, PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0);
35 |
36 | bitmap.UnlockBits(data);
37 | //bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
38 | return bitmap;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("VectorTileToBitmapRenderer")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("VectorTileToBitmapRenderer")]
12 | [assembly: AssemblyCopyright("Copyright © 2016")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("cd32d7ad-2b89-4e3a-b204-b9d2b179f3f5")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/SphericalMercator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 |
4 | namespace VectorTileToBitmapRenderer
5 | {
6 | public class SphericalMercator
7 | {
8 | private const double Radius = 6378137;
9 | private const double D2R = Math.PI / 180;
10 | private const double HalfPi = Math.PI / 2;
11 |
12 | public static PointF FromLonLat(double lon, double lat)
13 | {
14 | var lonRadians = (D2R * lon);
15 | var latRadians = (D2R * lat);
16 |
17 | var x = Radius * lonRadians;
18 | var y = Radius * Math.Log(Math.Tan(Math.PI * 0.25 + latRadians * 0.5));
19 |
20 | return new PointF((float)x, (float)y);
21 | }
22 |
23 | public static PointF ToLonLat(double x, double y)
24 | {
25 | var ts = Math.Exp(-y / (Radius));
26 | var latRadians = HalfPi - 2 * Math.Atan(ts);
27 |
28 | var lonRadians = x / (Radius);
29 |
30 | var lon = (lonRadians / D2R);
31 | var lat = (latRadians / D2R);
32 |
33 | return new PointF((float)lon, (float)lat);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/VectorTileToBitmapRenderer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {CD32D7AD-2B89-4E3A-B204-B9D2B179F3F5}
8 | Library
9 | Properties
10 | VectorTileToBitmapRenderer
11 | VectorTileToBitmapRenderer
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\..\packages\BruTile.0.22.1\lib\portable-net45+win+WindowsPhoneApp81+Xamarin.iOS10+MonoAndroid10+MonoTouch10\BruTile.dll
35 |
36 |
37 | ..\..\packages\GeoJSON.Net.0.1.47\lib\portable-net40+sl5+wp80+win8+wpa81\GeoJSON.Net.dll
38 |
39 |
40 | ..\..\packages\mapbox-vector-tile.3.1.4\lib\portable-net4+sl5+wp8+win8\Mapbox.Vector.Tile.dll
41 |
42 |
43 | ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
44 |
45 |
46 | ..\..\packages\OpenTK.3.0.0-pre\lib\net20\OpenTK.dll
47 |
48 |
49 | ..\..\packages\protobuf-net.2.3.2\lib\net40\protobuf-net.dll
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
85 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/VectorTileToBitmapRenderer.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/VectorTileToBitmapRenderer/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------