diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml new file mode 100644 index 00000000..6de7c320 --- /dev/null +++ b/.github/workflows/dotnetcore.yml @@ -0,0 +1,50 @@ +name: .NET Core + +on: [push] + +jobs: + build: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 2.2.401 + - name: Setup Nuget + uses: nuget/setup-nuget@v1 + - name: Setup MSBuild.exe + uses: warrenbuckley/Setup-MSBuild@v1 + + - name: Install packages into packages folder 1/2 + run: nuget restore SharpMap.Extensions/packages.config -OutputDirectory packages + - name: Install packages into packages folder 2/2 + run: nuget restore SharpMap.SqlServerSpatialObjects/packages.config -OutputDirectory packages + - name: MSBuild SharedAssemblyVersion + run: msbuild SharpMap.targets /t:Version + + - name: Build with dotnet + env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + run: dotnet build SharpMap.sln --configuration ReleaseDotNet + + - name: Setup NUnit TestRunner + run: nuget install NUnit.Console -Version 3.10.0 -OutputDirectory testrunner + - name: Perform tests + run: ../../../../testrunner/NUnit.ConsoleRunner.3.10.0/tools/nunit3-console.exe UnitTests.dll + working-directory: + ./UnitTests/bin/Release/net472 + +# - name: Publish packages +# if: success() +# env: +# MYGET_API_KEY: ${{ secrets.MYGET_API_KEY }} +# run: dotnet nuget push SharpMap.Packages/SharpMap.*.nupkg --api-key $MYGET_API_KEY --source https://www.myget.org/F/sharpmap/api/v2/package --skip-duplicate + + - name: Upload + uses: actions/upload-artifact@v1 + with: + name: NuGet Package Files + path: SharpMap.Packages diff --git a/.gitignore b/.gitignore index b45580a6..d6861a8c 100644 --- a/.gitignore +++ b/.gitignore @@ -208,4 +208,10 @@ I[V|v][V|v]*.* **/SqlServerTypes/readme.htm # Testrunner -testrunner/** \ No newline at end of file +testrunner/** +/SharpMap/LastMajorVersionBinary +*.snupkg +testrunner/** + +# Generated packages +/SharpMap.*Packages/** diff --git a/.travis.yml b/.travis.yml index 271d6163..4fdbc2c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_install: install: - nuget install NUnit.Console -Version 3.10.0 -OutputDirectory testrunner script: -- nuget restore SharpMap.sln +- nuget restore SharpMap.Extensions/packages.config -o packages - dotnet msbuild SharpMap.targets /t:Version /p:UseTools35=false /v:minimal - dotnet msbuild SharpMap.sln /m "/t:Restore;Build" /p:Configuration=ReleaseLinux "/p:Platform=Any CPU" /p:UseTools35=false "/p:FrameworkPathOverride=$(dirname $(which mono))/../lib/mono/4.5/" /v:minimal /p:WarningLevel=3 - pushd UnitTests/bin/ReleaseLinux/net472 diff --git a/BuildTools/BuildTools/MSBuild.Community.Tasks.dll b/BuildTools/BuildTools/MSBuild.Community.Tasks.dll new file mode 100644 index 00000000..1423bfeb Binary files /dev/null and b/BuildTools/BuildTools/MSBuild.Community.Tasks.dll differ diff --git a/BuildTools/BuildTools/MSBuild.Community.Tasks.targets b/BuildTools/BuildTools/MSBuild.Community.Tasks.targets new file mode 100644 index 00000000..a1c91893 --- /dev/null +++ b/BuildTools/BuildTools/MSBuild.Community.Tasks.targets @@ -0,0 +1,148 @@ + + + + + + $(MSBuildExtensionsPath)\MSBuildCommunityTasks + $(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/DemoWinForm/app.config b/Examples/DemoWinForm/app.config deleted file mode 100644 index 48db5df4..00000000 --- a/Examples/DemoWinForm/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Examples/ExampleCodeSnippets/app.config b/Examples/ExampleCodeSnippets/app.config index 2ba4be27..4913f2e5 100644 --- a/Examples/ExampleCodeSnippets/app.config +++ b/Examples/ExampleCodeSnippets/app.config @@ -5,7 +5,6 @@
- diff --git a/Examples/ExampleCodeSnipplets.VB/app.config b/Examples/ExampleCodeSnipplets.VB/app.config deleted file mode 100644 index 312bb3f2..00000000 --- a/Examples/ExampleCodeSnipplets.VB/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Examples/SharpMap.Demo.Wms/Controllers/BuildingsController.cs b/Examples/SharpMap.Demo.Wms/Controllers/BuildingsController.cs index 946f11fd..0934fbc6 100644 --- a/Examples/SharpMap.Demo.Wms/Controllers/BuildingsController.cs +++ b/Examples/SharpMap.Demo.Wms/Controllers/BuildingsController.cs @@ -23,7 +23,7 @@ public class BuildingsController : Controller public BuildingsController() { - GeometryServiceProvider.Instance = new NtsGeometryServices(); + GeometryServiceProvider.SetInstanceIfNotAlreadySetDirectly(new NtsGeometryServices()); } private Point GeoToPixel(double lat, double lon, int zoom) @@ -90,4 +90,4 @@ public JsonResult GetData(float w, float n, float e, float s, int z) return this.Json(new { meta, data }, JsonRequestBehavior.AllowGet); } } -} \ No newline at end of file +} diff --git a/Examples/SharpMap.Demo.Wms/Global.asax.cs b/Examples/SharpMap.Demo.Wms/Global.asax.cs index 0ff97729..c88bfce2 100644 --- a/Examples/SharpMap.Demo.Wms/Global.asax.cs +++ b/Examples/SharpMap.Demo.Wms/Global.asax.cs @@ -15,8 +15,14 @@ public static void RegisterRoutes(RouteCollection routes) protected void Application_Start() { + SharpMap.Session.Instance + .SetGeometryServices(NetTopologySuite.NtsGeometryServices.Instance) + .SetCoordinateSystemServices(CoordinateSystems.CoordinateSystemServices + .FromSpatialRefSys(new ProjNet.CoordinateSystems.CoordinateSystemFactory(), + new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory())); + AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); } } -} \ No newline at end of file +} diff --git a/Examples/SharpMap.Demo.Wms/Handlers/AbstractStdMapHandler.cs b/Examples/SharpMap.Demo.Wms/Handlers/AbstractStdMapHandler.cs index 4b157f00..db07b875 100644 --- a/Examples/SharpMap.Demo.Wms/Handlers/AbstractStdMapHandler.cs +++ b/Examples/SharpMap.Demo.Wms/Handlers/AbstractStdMapHandler.cs @@ -15,10 +15,7 @@ public abstract class AbstractStdMapHandler : IHttpHandler static AbstractStdMapHandler() { - lock (SyncLock) - { - GeometryServiceProvider.Instance = new NtsGeometryServices(); - } + GeometryServiceProvider.SetInstanceIfNotAlreadySetDirectly(NtsGeometryServices.Instance); } public abstract void ProcessRequest(HttpContext context); @@ -63,4 +60,4 @@ public bool IsReusable get { return false; } } } -} \ No newline at end of file +} diff --git a/Examples/SharpMap.Demo.Wms/Helpers/ShapefileHelper.cs b/Examples/SharpMap.Demo.Wms/Helpers/ShapefileHelper.cs index 7b937721..47cd69d9 100644 --- a/Examples/SharpMap.Demo.Wms/Helpers/ShapefileHelper.cs +++ b/Examples/SharpMap.Demo.Wms/Helpers/ShapefileHelper.cs @@ -1,3 +1,5 @@ +using ProjNet.CoordinateSystems; + namespace SharpMap.Demo.Wms.Helpers { using System; @@ -48,6 +50,7 @@ static ShapefileHelper() PointSize = 10 } }; + Nyc = new Dictionary { { "nyc/poly_landmarks.shp", landmarks }, @@ -58,11 +61,15 @@ static ShapefileHelper() public static Map Spherical() { - ICoordinateTransformation transformation = ProjHelper.LatLonToGoogle(); + //ICoordinateTransformation transformation = ProjHelper.LatLonToGoogle(); HttpContext context = HttpContext.Current; Map map = new Map(new Size(1, 1)); IDictionary dict = Nyc; + var ctFac = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory(); + var pos = ctFac.CreateFromCoordinateSystems(GeographicCoordinateSystem.WGS84, ProjectedCoordinateSystem.WebMercator); + var neg = ctFac.CreateFromCoordinateSystems(ProjectedCoordinateSystem.WebMercator, GeographicCoordinateSystem.WGS84); + foreach (string layer in dict.Keys) { string format = String.Format("~/App_Data/{0}", layer); @@ -75,11 +82,13 @@ public static Map Spherical() ShapeFile source = new ShapeFile(path, true); VectorLayer item = new VectorLayer(name, source) { - SRID = 4326, - TargetSRID = 900913, - CoordinateTransformation = transformation, + //SRID = 4326, + //TargetSRID = 900913, + CoordinateTransformation = pos, + ReverseCoordinateTransformation = neg, Style = (VectorStyle)data.Style, - SmoothingMode = SmoothingMode.AntiAlias + SmoothingMode = SmoothingMode.AntiAlias, + IsQueryEnabled = true }; map.Layers.Add(item); } @@ -113,4 +122,4 @@ public static Map Default() return map; } } -} \ No newline at end of file +} diff --git a/Examples/WinFormSamples/DlgSamplesMenu.Designer.cs b/Examples/WinFormSamples/DlgSamplesMenu.Designer.cs index 3d0bf895..d1bd1ebb 100644 --- a/Examples/WinFormSamples/DlgSamplesMenu.Designer.cs +++ b/Examples/WinFormSamples/DlgSamplesMenu.Designer.cs @@ -29,6 +29,7 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); this.button2 = new System.Windows.Forms.Button(); this.textBox2 = new System.Windows.Forms.TextBox(); this.textBox1 = new System.Windows.Forms.TextBox(); @@ -41,7 +42,8 @@ private void InitializeComponent() this.button6 = new System.Windows.Forms.Button(); this.textBox6 = new System.Windows.Forms.TextBox(); this.button3 = new System.Windows.Forms.Button(); - this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.textBox7 = new System.Windows.Forms.TextBox(); + this.button7 = new System.Windows.Forms.Button(); this.tableLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // @@ -50,6 +52,7 @@ private void InitializeComponent() this.tableLayoutPanel1.ColumnCount = 2; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 70F)); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 30F)); + this.tableLayoutPanel1.Controls.Add(this.checkBox1, 0, 7); this.tableLayoutPanel1.Controls.Add(this.button2, 1, 0); this.tableLayoutPanel1.Controls.Add(this.textBox2, 0, 0); this.tableLayoutPanel1.Controls.Add(this.textBox1, 0, 4); @@ -62,11 +65,13 @@ private void InitializeComponent() this.tableLayoutPanel1.Controls.Add(this.button6, 1, 3); this.tableLayoutPanel1.Controls.Add(this.textBox6, 0, 5); this.tableLayoutPanel1.Controls.Add(this.button3, 1, 5); - this.tableLayoutPanel1.Controls.Add(this.checkBox1, 0, 6); + this.tableLayoutPanel1.Controls.Add(this.textBox7, 0, 6); + this.tableLayoutPanel1.Controls.Add(this.button7, 1, 6); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top; this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 10); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 7; + this.tableLayoutPanel1.RowCount = 8; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); @@ -74,9 +79,21 @@ private void InitializeComponent() this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(264, 348); + this.tableLayoutPanel1.Size = new System.Drawing.Size(264, 403); this.tableLayoutPanel1.TabIndex = 0; // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.checkBox1.Location = new System.Drawing.Point(3, 353); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(178, 47); + this.checkBox1.TabIndex = 8; + this.checkBox1.Text = "MapBox rendering using LegacyMapImageRenderer"; + this.checkBox1.UseVisualStyleBackColor = true; + this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); + // // button2 // this.button2.Location = new System.Drawing.Point(187, 3); @@ -94,7 +111,7 @@ private void InitializeComponent() this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(178, 36); this.textBox2.TabIndex = 2; - this.textBox2.Text = "Different kind of layers which [MapBox]"; + this.textBox2.Text = "Different kind of layers supported by [MapBox]"; // // textBox1 // @@ -140,7 +157,7 @@ private void InitializeComponent() this.textBox5.Name = "textBox5"; this.textBox5.Size = new System.Drawing.Size(178, 36); this.textBox5.TabIndex = 2; - this.textBox5.Text = "Shows Shows how to save a set of images [MapBox]"; + this.textBox5.Text = "Shows how to save a set of images [MapBox]"; // // button4 // @@ -179,7 +196,7 @@ private void InitializeComponent() this.textBox6.Name = "textBox6"; this.textBox6.Size = new System.Drawing.Size(178, 36); this.textBox6.TabIndex = 4; - this.textBox6.Text = "Different kind of layers which [MapBox using DotSpatial]"; + this.textBox6.Text = "Different kind of layers supported by [MapBox using DotSpatial]"; // // button3 // @@ -191,23 +208,30 @@ private void InitializeComponent() this.button3.UseVisualStyleBackColor = true; this.button3.Click += new System.EventHandler(this.button2_Click); // - // checkBox1 + // textBox7 // - this.checkBox1.AutoSize = true; - this.checkBox1.Dock = System.Windows.Forms.DockStyle.Fill; - this.checkBox1.Location = new System.Drawing.Point(3, 303); - this.checkBox1.Name = "checkBox1"; - this.checkBox1.Size = new System.Drawing.Size(178, 44); - this.checkBox1.TabIndex = 7; - this.checkBox1.Text = "MapBox rendering using LegacyMapImageRenderer"; - this.checkBox1.UseVisualStyleBackColor = true; - this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); + this.textBox7.Location = new System.Drawing.Point(3, 303); + this.textBox7.Multiline = true; + this.textBox7.Name = "textBox7"; + this.textBox7.Size = new System.Drawing.Size(178, 36); + this.textBox7.TabIndex = 9; + this.textBox7.Text = "[MapBox] with interactive layers for image generation validation"; + // + // button7 + // + this.button7.Location = new System.Drawing.Point(187, 303); + this.button7.Name = "button7"; + this.button7.Size = new System.Drawing.Size(74, 23); + this.button7.TabIndex = 10; + this.button7.Text = "Start"; + this.button7.UseVisualStyleBackColor = true; + this.button7.Click += new System.EventHandler(this.button7_Click); // // DlgSamplesMenu // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(284, 368); + this.ClientSize = new System.Drawing.Size(284, 419); this.Controls.Add(this.tableLayoutPanel1); this.MaximizeBox = false; this.MinimizeBox = false; @@ -237,5 +261,7 @@ private void InitializeComponent() private System.Windows.Forms.TextBox textBox6; private System.Windows.Forms.Button button3; private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.TextBox textBox7; + private System.Windows.Forms.Button button7; } -} \ No newline at end of file +} diff --git a/Examples/WinFormSamples/DlgSamplesMenu.cs b/Examples/WinFormSamples/DlgSamplesMenu.cs index 0130eb55..ad43a3ab 100644 --- a/Examples/WinFormSamples/DlgSamplesMenu.cs +++ b/Examples/WinFormSamples/DlgSamplesMenu.cs @@ -1,61 +1,68 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; -using SharpMap.Forms; - -namespace WinFormSamples -{ - public partial class DlgSamplesMenu : Form - { - public DlgSamplesMenu() - { - InitializeComponent(); - checkBox1.Checked = true; - button2.Focus(); - } - - private void button2_Click(object sender, EventArgs e) - { - var ds = sender == button3; - FormMapBox.UseDotSpatial = ds; - using (var f = new FormMapBox()) - f.ShowDialog(); - } - - private void button4_Click(object sender, EventArgs e) - { - using(var f = new DockAreaForm()) - f.ShowDialog(); - } - - private void button5_Click(object sender, EventArgs e) - { - using(var f = new FormDemoDrawGeometries()) - f.ShowDialog(); - } - - private void button6_Click(object sender, EventArgs e) - { - using(var f = new FormAnimation()) - f.ShowDialog(); - } - - private void button1_Click(object sender, EventArgs e) - { - using(var f = new FormMovingObjectOverTileLayer()) - f.ShowDialog(); - } - - private void checkBox1_CheckedChanged(object sender, EventArgs e) - { - if (checkBox1.Checked) - MapBox.MapImageGeneratorFunction = null; - else - MapBox.MapImageGeneratorFunction = MapBox.LayerListImageGenerator; - } - } -} +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using SharpMap.Forms; + +namespace WinFormSamples +{ + public partial class DlgSamplesMenu : Form + { + public DlgSamplesMenu() + { + InitializeComponent(); + checkBox1.Checked = true; + button2.Focus(); + } + + private void button2_Click(object sender, EventArgs e) + { + var ds = sender == button3; + FormMapBox.UseDotSpatial = ds; + using (var f = new FormMapBox()) + f.ShowDialog(); + } + + private void button4_Click(object sender, EventArgs e) + { + using(var f = new DockAreaForm()) + f.ShowDialog(); + } + + private void button5_Click(object sender, EventArgs e) + { + using(var f = new FormDemoDrawGeometries()) + f.ShowDialog(); + } + + private void button6_Click(object sender, EventArgs e) + { + using(var f = new FormAnimation()) + f.ShowDialog(); + } + + private void button1_Click(object sender, EventArgs e) + { + using(var f = new FormMovingObjectOverTileLayer()) + f.ShowDialog(); + } + + private void button7_Click(object sender, EventArgs e) + { + using (var f = new FormLayerListImageGenerator()) + f.ShowDialog(); + } + private void checkBox1_CheckedChanged(object sender, EventArgs e) + { + if (checkBox1.Checked) + MapBox.MapImageGeneratorFunction = null; + else + MapBox.MapImageGeneratorFunction = MapBox.LayerListImageGenerator; + } + + + } +} diff --git a/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.Designer.cs b/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.Designer.cs new file mode 100644 index 00000000..919dfd52 --- /dev/null +++ b/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.Designer.cs @@ -0,0 +1,227 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; + +namespace WinFormSamples +{ + partial class FormLayerListImageGenerator + { + /// + /// Required designer variable. + /// + private IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.tv = new System.Windows.Forms.TreeView(); + this.mapZoomToolStrip1 = new SharpMap.Forms.ToolBar.MapZoomToolStrip(this.components); + this.mb = new SharpMap.Forms.MapBox(); + this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.panel2 = new System.Windows.Forms.Panel(); + this.label1 = new System.Windows.Forms.Label(); + this.ddlRotation = new System.Windows.Forms.ComboBox(); + this.txtImgGeneration = new System.Windows.Forms.TextBox(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.toolStripContainer1.ContentPanel.SuspendLayout(); + this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); + this.toolStripContainer1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); + this.SuspendLayout(); + // + // tv + // + this.tv.CheckBoxes = true; + this.tv.Dock = System.Windows.Forms.DockStyle.Fill; + this.tv.Location = new System.Drawing.Point(0, 43); + this.tv.Name = "tv"; + this.tv.Size = new System.Drawing.Size(233, 600); + this.tv.TabIndex = 0; + this.tv.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.tv_AfterCheck); + this.tv.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tv_NodeMouseClick); + // + // mapZoomToolStrip1 + // + this.mapZoomToolStrip1.Dock = System.Windows.Forms.DockStyle.None; + this.mapZoomToolStrip1.Enabled = false; + this.mapZoomToolStrip1.Location = new System.Drawing.Point(3, 0); + this.mapZoomToolStrip1.MapControl = this.mb; + this.mapZoomToolStrip1.Name = "mapZoomToolStrip1"; + this.mapZoomToolStrip1.Size = new System.Drawing.Size(409, 25); + this.mapZoomToolStrip1.TabIndex = 4; + this.mapZoomToolStrip1.Text = "mapZoomToolStrip1"; + // + // mb + // + this.mb.ActiveTool = SharpMap.Forms.MapBox.Tools.Pan; + this.mb.Cursor = System.Windows.Forms.Cursors.Hand; + this.mb.CustomTool = null; + this.mb.Dock = System.Windows.Forms.DockStyle.Fill; + this.mb.FineZoomFactor = 10D; + this.mb.Location = new System.Drawing.Point(0, 0); + this.mb.MapQueryMode = SharpMap.Forms.MapBox.MapQueryType.LayerByIndex; + this.mb.Name = "mb"; + this.mb.QueryGrowFactor = 5F; + this.mb.QueryLayerIndex = 0; + this.mb.SelectionBackColor = System.Drawing.Color.FromArgb(((int) (((byte) (210)))), + ((int) (((byte) (244)))), ((int) (((byte) (244)))), ((int) (((byte) (244))))); + this.mb.SelectionForeColor = System.Drawing.Color.FromArgb(((int) (((byte) (244)))), + ((int) (((byte) (244)))), ((int) (((byte) (244))))); + this.mb.ShowProgressUpdate = false; + this.mb.Size = new System.Drawing.Size(789, 673); + this.mb.TabIndex = 6; + this.mb.Text = "mb"; + this.mb.WheelZoomMagnitude = -2D; + // + // toolStripContainer1 + // + // + // toolStripContainer1.ContentPanel + // + this.toolStripContainer1.ContentPanel.Controls.Add(this.mb); + this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(789, 673); + this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.toolStripContainer1.Location = new System.Drawing.Point(233, 0); + this.toolStripContainer1.Name = "toolStripContainer1"; + this.toolStripContainer1.Size = new System.Drawing.Size(789, 698); + this.toolStripContainer1.TabIndex = 7; + this.toolStripContainer1.Text = "toolStripContainer1"; + // + // toolStripContainer1.TopToolStripPanel + // + this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.mapZoomToolStrip1); + // + // textBox1 + // + this.textBox1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.textBox1.Location = new System.Drawing.Point(0, 643); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(233, 55); + this.textBox1.TabIndex = 8; + this.textBox1.Text = "NB: Tree view has layer-sensitive context menu to interact with Variable Layers a" + + "nd Map Point Layers"; + // + // panel1 + // + this.panel1.Controls.Add(this.panel2); + this.panel1.Controls.Add(this.tv); + this.panel1.Controls.Add(this.txtImgGeneration); + this.panel1.Controls.Add(this.textBox1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Left; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(233, 698); + this.panel1.TabIndex = 9; + // + // panel2 + // + this.panel2.Controls.Add(this.label1); + this.panel2.Controls.Add(this.ddlRotation); + this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel2.Location = new System.Drawing.Point(0, 591); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(233, 52); + this.panel2.TabIndex = 10; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(7, 15); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(55, 15); + this.label1.TabIndex = 1; + this.label1.Text = "Rotation:"; + // + // ddlRotation + // + this.ddlRotation.FormattingEnabled = true; + this.ddlRotation.Location = new System.Drawing.Point(80, 12); + this.ddlRotation.Margin = new System.Windows.Forms.Padding(12, 12, 12, 12); + this.ddlRotation.Name = "ddlRotation"; + this.ddlRotation.Size = new System.Drawing.Size(140, 23); + this.ddlRotation.TabIndex = 0; + this.ddlRotation.SelectedIndexChanged += new System.EventHandler(this.ddlRotation_SelectedIndexChanged); + // + // txtImgGeneration + // + this.txtImgGeneration.Dock = System.Windows.Forms.DockStyle.Top; + this.txtImgGeneration.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, + System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte) (0))); + this.txtImgGeneration.ForeColor = System.Drawing.SystemColors.MenuHighlight; + this.txtImgGeneration.Location = new System.Drawing.Point(0, 0); + this.txtImgGeneration.Multiline = true; + this.txtImgGeneration.Name = "txtImgGeneration"; + this.txtImgGeneration.Size = new System.Drawing.Size(233, 43); + this.txtImgGeneration.TabIndex = 9; + this.txtImgGeneration.Text = "Image generation mode:"; + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); + // + // FormLayerListImageGenerator + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1022, 698); + this.Controls.Add(this.toolStripContainer1); + this.Controls.Add(this.panel1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FormLayerListImageGenerator"; + this.Text = "LayerListImageGenerator Validation"; + this.Closing += new System.ComponentModel.CancelEventHandler(this.FormLayerListImageGenerator_Closing); + this.Load += new System.EventHandler(this.FormLayerListImageGenerator_Load); + this.toolStripContainer1.ContentPanel.ResumeLayout(false); + this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false); + this.toolStripContainer1.TopToolStripPanel.PerformLayout(); + this.toolStripContainer1.ResumeLayout(false); + this.toolStripContainer1.PerformLayout(); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.panel2.ResumeLayout(false); + this.panel2.PerformLayout(); + this.ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.TreeView tv; + private SharpMap.Forms.ToolBar.MapZoomToolStrip mapZoomToolStrip1; + private SharpMap.Forms.MapBox mb; + private System.Windows.Forms.ToolStripContainer toolStripContainer1; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.TextBox txtImgGeneration; + private System.Windows.Forms.ComboBox ddlRotation; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Panel panel2; + } +} + diff --git a/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.cs b/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.cs new file mode 100644 index 00000000..9630e9c7 --- /dev/null +++ b/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.cs @@ -0,0 +1,803 @@ +using BruTile.Predefined; +using GeoAPI.CoordinateSystems.Transformations; +using GeoAPI.Geometries; +using NetTopologySuite.Geometries; +using SharpMap; +using SharpMap.Data; +using SharpMap.Data.Providers; +using SharpMap.Layers; +using SharpMap.Rendering.Decoration; +using SharpMap.Rendering.Symbolizer; +using SharpMap.Styles; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.Remoting.Channels; +using System.Windows.Forms; +using WinFormSamples.Properties; +using Point = NetTopologySuite.Geometries.Point; + +namespace WinFormSamples +{ + public partial class FormLayerListImageGenerator : Form + { + private MovingObjects _fastBoats; + private MovingObjects _mediumBoats; + private MovingObjects _slowBoats; + private static Image _boat; + + private Layer _contextLayer; + + // Context Menu actions + private enum enumMenuItem + { + Refresh, // MapBox.Refresh + IncrementLabelSize, // Label Layers + DecrementLabelSize, // Label Layers + StartMoving, // Variable Layer moving object + StopMoving, // Variable Layer moving object + RegularSymbolizer, // Variable Layer and Map Point layer + ThematicSymbolizer, // Variable Layer and Map Point layer + IncreaseSymbolSize, // Basic Vector Style Point Size + DecreaseSymbolSize, // Basic Vector Style Point Size + SymbolOffsetTL, // Basic Vector Style Point Size + SymbolOffsetTR, // Basic Vector Style Point Size + SymbolOffsetNone, // Basic Vector Style Point Size + SymbolOffsetBL, // Basic Vector Style Point Size + SymbolOffsetBR, // Basic Vector Style Point Size + AlignHz, // Regenerate Map Point layer data + AlignVt, // Regenerate Map Point layer data + AlignDiagonal , // Regenerate Map Point layer data + IncrementLineWidth, // Rectangle layers + DecrementLineWidth // Rectangle layers + } + + public FormLayerListImageGenerator() + { + InitializeComponent(); + } + + private void FormLayerListImageGenerator_Load(object sender, System.EventArgs e) + { + this.SizeChanged += Form_SizeChanged; + + _boat = Resources.vessel_01; + + InitMap(); + InitBackground(); + InitLayers(); + InitVariableLayers(); + InitTreeView(); + InitRotations(); + + using (var renderer = SharpMap.Forms.MapBox.MapImageGeneratorFunction(new SharpMap.Forms.MapBox(), null)) + { + if (renderer is SharpMap.Forms.ImageGenerator.LegacyMapBoxImageGenerator) + this.txtImgGeneration.Text = (this.txtImgGeneration.Text + "\n. LegacyMapImageRenderer"); + else + this.txtImgGeneration.Text = (this.txtImgGeneration.Text + "\n. LayerListImageGenerator"); + }; + + this.mb.Refresh(); + + //_slowBoats?.Start(); + _mediumBoats?.Start(); + //_fastBoats?.Start(); + } + + + + private void FormLayerListImageGenerator_Closing(object sender, EventArgs e) + { + this.SizeChanged -= Form_SizeChanged; + _fastBoats?.Dispose(); + _mediumBoats?.Dispose(); + _slowBoats?.Dispose(); + } + + private void Form_SizeChanged(object sender, EventArgs e) + { + this.mb.Refresh(); + } + + private void tv_AfterCheck(object sender, TreeViewEventArgs e) + { + if (e.Node.Tag != null) + { + var lyr = (Layer)e.Node.Tag; + lyr.Enabled = e.Node.Checked; + this.mb.Refresh(); + } + } + + #region Context Menu Stuff + private void tv_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) + { + if (e.Button != MouseButtons.Right) return; + + var cm = new ContextMenu(); + var vlyr = e.Node.Tag as VectorLayer; + _contextLayer = e.Node.Tag as Layer; + + if (vlyr != null && (e.Node.FullPath.StartsWith("Variable Layers", StringComparison.OrdinalIgnoreCase))) + { + if (cm.MenuItems.Count > 0) cm.MenuItems.Add(new MenuItem("-")); + + if (_contextLayer.LayerName.StartsWith("Fast")) + cm.MenuItems.Add(_fastBoats.IsRunning ? + CreateMenuItem(enumMenuItem.StopMoving, "Stop") : + CreateMenuItem(enumMenuItem.StartMoving, "Start")); + else if (_contextLayer.LayerName.StartsWith("Slow")) + cm.MenuItems.Add(_slowBoats.IsRunning ? + CreateMenuItem(enumMenuItem.StopMoving, "Stop") : + CreateMenuItem(enumMenuItem.StartMoving, "Start")); + else + cm.MenuItems.Add(_mediumBoats.IsRunning ? + CreateMenuItem(enumMenuItem.StopMoving, "Stop") : + CreateMenuItem(enumMenuItem.StartMoving, "Start")); + + //cm.MenuItems.Add(CreateMenuItem(enumMenuItem.StartMoving, "Start")); + //cm.MenuItems.Add(CreateMenuItem(enumMenuItem.StopMoving, "Stop")); + cm.MenuItems.Add(new MenuItem("-")); + + if (vlyr.Theme == null) + { + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.ThematicSymbolizer, "Thematic Symbolizer")); + cm.MenuItems.Add(new MenuItem("-")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.IncreaseSymbolSize, "Increment symbol size")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.DecreaseSymbolSize, "Decrement symbol size")); + } + else + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.RegularSymbolizer, "Basic Symbolizer")); + } + else if (vlyr != null && (e.Node.FullPath.StartsWith("Map Layers", StringComparison.OrdinalIgnoreCase))) + { + if (vlyr.LayerName.StartsWith("Point", StringComparison.OrdinalIgnoreCase) ) + { + if (vlyr.Theme == null) + { + // default point style + if (cm.MenuItems.Count > 0) cm.MenuItems.Add(new MenuItem("-")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.IncreaseSymbolSize, "Increment symbol size")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.DecreaseSymbolSize, "Decrement symbol size")); + cm.MenuItems.Add(new MenuItem("-")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.SymbolOffsetNone, "Remove symbol offset")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.SymbolOffsetTL, "Offset step upper left")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.SymbolOffsetTR, "Offset step upper right")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.SymbolOffsetBL, "Offset Step lower left")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.SymbolOffsetBR, "Offset step lower right")); + } + if (cm.MenuItems.Count > 0) cm.MenuItems.Add(new MenuItem("-")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.AlignHz, "Align Pts Horizontal")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.AlignVt, "Align Pts Vertical")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.AlignDiagonal, "Align Pts Diagonal")); + } + + if (vlyr.LayerName.Contains("Rect")) + { + if (cm.MenuItems.Count > 0) cm.MenuItems.Add(new MenuItem("-")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.IncrementLineWidth, "Increment line width")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.DecrementLineWidth, "Decrement line width")); + } + } + + if (e.Node.Tag is LabelLayer) + { + if (cm.MenuItems.Count > 0) cm.MenuItems.Add(new MenuItem("-")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.IncrementLabelSize, "Increment Label Size")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.DecrementLabelSize, "Decrement Label Size")); + } + + if (cm.MenuItems.Count > 0) cm.MenuItems.Add(new MenuItem("-")); + cm.MenuItems.Add(CreateMenuItem(enumMenuItem.Refresh, "Refresh [clear cache]")); + + cm.Show(tv, new System.Drawing.Point(e.X, e.Y)); + } + + private MenuItem CreateMenuItem(enumMenuItem eMenuItem, string text) + { + var mi = new MenuItem(text) + { + Tag = eMenuItem, + }; + mi.Click += MenuItemClick; + return mi; + } + + private void MenuItemClick (Object sender, EventArgs e) + { + var mi = sender as MenuItem; + if (mi == null) return; + + var vectorLyr = _contextLayer as VectorLayer; + var lblLyr = _contextLayer as LabelLayer; + + switch ((enumMenuItem)mi.Tag) + { + //case enumMenuItem.Refresh: + // this.mb.Refresh(); + // break; + case enumMenuItem.StartMoving: + if (_contextLayer.LayerName.StartsWith("Fast")) + _fastBoats?.Start(); + else if (_contextLayer.LayerName.StartsWith("Slow")) + _slowBoats?.Start(); + else + _mediumBoats?.Start(); + break; + + case enumMenuItem.StopMoving: + if (_contextLayer.LayerName.StartsWith("Fast")) + _fastBoats?.Stop(); + else if (_contextLayer.LayerName.StartsWith("Slow")) + _slowBoats?.Stop(); + else + _mediumBoats?.Stop(); + break; + + case enumMenuItem.IncrementLabelSize: + lblLyr.Style.Font = new Font(lblLyr.Style.Font.FontFamily, lblLyr.Style.Font.Size + 2); + break; + case enumMenuItem.DecrementLabelSize: + lblLyr.Style.Font = new Font(lblLyr.Style.Font.FontFamily, lblLyr.Style.Font.Size - 2); + break; + case enumMenuItem.RegularSymbolizer: + InitRasterPointSymbolizer(vectorLyr, 0); + break; + case enumMenuItem.ThematicSymbolizer: + InitRasterPointSymbolizer(vectorLyr, 1); + break; + case enumMenuItem.IncreaseSymbolSize: + vectorLyr.Style.PointSize += 2; + break; + case enumMenuItem.DecreaseSymbolSize: + vectorLyr.Style.PointSize-= 2; + break; + case enumMenuItem.SymbolOffsetTL: + vectorLyr.Style.SymbolOffset = new PointF(vectorLyr.Style.SymbolOffset.X - 10f, vectorLyr.Style.SymbolOffset.Y - 10f); + break; + case enumMenuItem.SymbolOffsetTR: + vectorLyr.Style.SymbolOffset = new PointF(vectorLyr.Style.SymbolOffset.X + 10f, vectorLyr.Style.SymbolOffset.Y - 10f); + break; + case enumMenuItem.SymbolOffsetNone: + vectorLyr.Style.SymbolOffset = new PointF(0, 0); + break; + case enumMenuItem.SymbolOffsetBL: + vectorLyr.Style.SymbolOffset = new PointF(vectorLyr.Style.SymbolOffset.X - 10f, vectorLyr.Style.SymbolOffset.Y + 10f); + break; + case enumMenuItem.SymbolOffsetBR: + vectorLyr.Style.SymbolOffset = new PointF(vectorLyr.Style.SymbolOffset.X + 10f, vectorLyr.Style.SymbolOffset.Y + 10f); + break; + case enumMenuItem.AlignHz: + if (vectorLyr.Theme == null) + PopulateGeomFeatureLayer(vectorLyr, 0); + else + PopulateCharacterPointSymbolizerLayer((GeometryFeatureProvider)vectorLyr.DataSource, 0); + break; + case enumMenuItem.AlignVt: + if (vectorLyr.Theme == null) + PopulateGeomFeatureLayer(vectorLyr, 1); + else + PopulateCharacterPointSymbolizerLayer((GeometryFeatureProvider)vectorLyr.DataSource, 1); + break; + case enumMenuItem.AlignDiagonal: + if (vectorLyr.Theme == null) + PopulateGeomFeatureLayer(vectorLyr, 2); + else + PopulateCharacterPointSymbolizerLayer((GeometryFeatureProvider)vectorLyr.DataSource, 2); + break; + case enumMenuItem.IncrementLineWidth: + vectorLyr.Style.Line.Width += 1; + break; + case enumMenuItem.DecrementLineWidth: + vectorLyr.Style.Line.Width -= vectorLyr.Style.Line.Width <= 1 ? 0 : 1; + break; + + default: + break; + } + + this.mb.Refresh(); + + } + #endregion + + private void InitTreeView() + { + var font = new System.Drawing.Font(tv.Font.FontFamily, tv.Font.Size, System.Drawing.FontStyle.Bold); + + tv.Nodes.Add(new TreeNode("Variable Layers") {NodeFont = font}); + tv.Nodes.Add(new TreeNode("Map Layers") { NodeFont = font }); + tv.Nodes.Add(new TreeNode("Background Layers") { NodeFont = font }); + + // Populate Tree View + TreeViewAddLayerNode(tv.Nodes[0], this.mb.Map.VariableLayers); + TreeViewAddLayerNode(tv.Nodes[1], this.mb.Map.Layers); + TreeViewAddLayerNode(tv.Nodes[2], this.mb.Map.BackgroundLayer); + + this.tv.CheckBoxes = true; + this.tv.ShowRootLines = false; + this.tv.ExpandAll(); + } + + private void TreeViewAddLayerNode(TreeNode parentNode, LayerCollection collection) + { + foreach (var lyr in collection) + TreeViewAddLayerNode(parentNode, lyr); + } + + private void TreeViewAddLayerNode(TreeNode parentNode, ILayer layer) + { + var node = new TreeNode(layer.LayerName) { Tag = layer, Checked = layer.Enabled }; + parentNode.Nodes.Add(node); + + var lyrGrp = layer as LayerGroup; + if (lyrGrp != null) + foreach (var lyr in lyrGrp.Layers) + TreeViewAddLayerNode(node, lyr); + } + + private void InitRotations() + { + ddlRotation.Items.Clear(); + ddlRotation.DisplayMember = "Text"; + ddlRotation.ValueMember = "Value"; + + ddlRotation.Items.Add(new {Text = "North up", Value = 0f}); + ddlRotation.Items.Add(new {Text = "30°", Value = 30f}); + ddlRotation.Items.Add(new {Text = "60°", Value = 60f}); + ddlRotation.Items.Add(new {Text = "90°", Value = 90f}); + ddlRotation.Items.Add(new {Text = "120°", Value = 120f}); + ddlRotation.Items.Add(new {Text = "150°", Value = 150f}); + ddlRotation.Items.Add(new {Text = "180°", Value = 180f}); + ddlRotation.Items.Add(new {Text = "210°", Value = 210f}); + ddlRotation.Items.Add(new {Text = "240°", Value = 240f}); + ddlRotation.Items.Add(new {Text = "270°", Value = 270f}); + ddlRotation.Items.Add(new {Text = "300°", Value = 300f}); + ddlRotation.Items.Add(new {Text = "330°", Value = 330f}); + + ddlRotation.SelectedIndex = 0; + } + + private void ddlRotation_SelectedIndexChanged(object sender, EventArgs e) + { + var deg = (ddlRotation.SelectedItem as dynamic).Value; + var matrix = new System.Drawing.Drawing2D.Matrix(); + if (deg != 0f) + matrix.RotateAt((float) deg, new PointF(this.mb.Width / 2f, this.mb.Height / 2f)); + this.mb.Map.MapTransform = matrix; + this.mb.Refresh(); + } + + private void InitMap() + { + this.mb.Map = new SharpMap.Map() + { + SRID = 3857, + BackColor = System.Drawing.Color.AliceBlue, + }; + + //Lisbon... + var mathTransform = LayerTools.Wgs84toGoogleMercator.MathTransform; + var geom = GeometryTransform.TransformBox( + new Envelope(-9.205626, -9.123736, 38.690993, 38.740837), + mathTransform); + //geom.ExpandBy(2500); + this.mb.Map.ZoomToBox(geom); + + this.mb.Map.Decorations.Add(new NorthArrow() {ForeColor = Color.DarkSlateBlue}); + } + + private void InitVariableLayers() + { + LayerGroup lyrGrp = null; + VectorLayer lyr = null; + + // group layer with single target + labels + lyrGrp = new LayerGroup("Fast Boats Group"); + lyr = CreateGeometryFeatureProviderLayer("Fast Boats", new[] { + new System.Data.DataColumn("Name",typeof(string)), + new System.Data.DataColumn("Heading",typeof(float)), + new System.Data.DataColumn("Scale",typeof(float)), + new System.Data.DataColumn("ARGB",typeof(int)) + }); + lyr.Style.PointColor = new SolidBrush(Color.Green); + _fastBoats = new MovingObjects(50, 50, lyr, this.mb.Map, 0.8f, Color.Green); + _fastBoats.AddObject("Fast 1", GetRectangleCenter(MapDecorationAnchor.LeftTop)); + InitRasterPointSymbolizer(lyr, 0); + lyrGrp.Layers.Add(lyr); + lyrGrp.Layers.Add(CreateLabelLayer(lyr, "Name", false)); + this.mb.Map.VariableLayers.Add(lyrGrp); + + // group layer with multiple targets + labels + lyrGrp = new LayerGroup("Medium Boats Group"); + lyr = CreateGeometryFeatureProviderLayer("Medium Boats", new[] { + new System.Data.DataColumn("Name",typeof(string)), + new System.Data.DataColumn("Heading",typeof(float)), + new System.Data.DataColumn("Scale",typeof(float)), + new System.Data.DataColumn("ARGB",typeof(int)) + }); + lyr.Style.PointColor = new SolidBrush(Color.Yellow); + _mediumBoats = new MovingObjects(500, 100, lyr, this.mb.Map, 1, Color.Yellow); + _mediumBoats.AddObject("Boat 1", GetRectangleCenter(MapDecorationAnchor.RightTop)); + _mediumBoats.AddObject("Boat 2", GetRectangleCenter(MapDecorationAnchor.RightCenter)); + InitRasterPointSymbolizer(lyr, 1); + lyrGrp.Layers.Add(lyr); + lyrGrp.Layers.Add(CreateLabelLayer(lyr, "Name", false)); + this.mb.Map.VariableLayers.Add(lyrGrp); + + // group layer with multiple targets + labels + lyrGrp = new LayerGroup("Slow Boats Group"); + lyr = CreateGeometryFeatureProviderLayer("Slow Boats", new[] { + new System.Data.DataColumn("Name",typeof(string)), + new System.Data.DataColumn("Heading",typeof(float)), + new System.Data.DataColumn("Scale",typeof(float)), + new System.Data.DataColumn("ARGB",typeof(int)) + }); + // raster point symbolizer + lyr.Style.PointColor = new SolidBrush(Color.Red); + _slowBoats = new MovingObjects(2000, 100, lyr, this.mb.Map, 1.2f, Color.Red); + _slowBoats.AddObject("Slow 1", GetRectangleCenter(MapDecorationAnchor.LeftBottom)); + _slowBoats.AddObject("Slow 2", GetRectangleCenter(MapDecorationAnchor.CenterBottom)); + _slowBoats.AddObject("Slow 3", GetRectangleCenter(MapDecorationAnchor.RightBottom)); + InitRasterPointSymbolizer(lyr, 1); + lyrGrp.Layers.Add(lyr); + lyrGrp.Layers.Add(CreateLabelLayer(lyr, "Name", true)); + this.mb.Map.VariableLayers.Add(lyrGrp); + } + + private ILayer CreateLabelLayer(VectorLayer lyr, string column, bool enabled) + { + var lblLayer = new LabelLayer( lyr.LayerName + " Labels"); + lblLayer.DataSource = lyr.DataSource; + lblLayer.LabelColumn = column; + //lblLayer.Style.BackColor = Brushes.LightPink; + lblLayer.SRID = lblLayer.SRID; + lblLayer.Enabled = enabled; + return lblLayer; + } + + private void InitLayers() + { + LayerGroup lyrGrp = null; + VectorLayer lyr = null; + Geometry[] geoms = null; + + // group layer with 2 child layers (Blue Rect, Red Rect) + lyrGrp = new LayerGroup("Layer Group 1"); + + geoms = new Geometry[] { new LineString(GetRectanglePoints(MapDecorationAnchor.LeftTop)) }; + lyrGrp.Layers.Add(CreateGeomLayer("Blue Rectangle", geoms, System.Drawing.Color.DodgerBlue)); + + geoms = new Geometry[] { new LineString(GetRectanglePoints(MapDecorationAnchor.CenterTop)) }; + lyrGrp.Layers.Add(CreateGeomLayer("Red Rectangle", geoms, System.Drawing.Color.Red)); + this.mb.Map.Layers.Add(lyrGrp); + + // layer with Green Rect + geoms = new Geometry[] { new LineString(GetRectanglePoints(MapDecorationAnchor.RightTop)) }; + lyr = CreateGeomLayer("Green Rectangle", geoms, System.Drawing.Color.Green); + this.mb.Map.Layers.Add(lyr); + + // Point layer with basic Vector Style + geoms = new Geometry[] { + GetRectangleCenter(MapDecorationAnchor.LeftTop), + GetRectangleCenter(MapDecorationAnchor.Center), + GetRectangleCenter(MapDecorationAnchor.CenterBottom), + }; + lyr = CreateGeomLayer("Points with Vector Style", geoms, System.Drawing.Color.Transparent); + //lyr.Style.SymbolOffset = new System.Drawing.PointF(20,20); + lyr.Enabled = false; + this.mb.Map.Layers.Add(lyr); + + // Char Symbol Layer with Thematic rendering + lyr = CreateGeometryFeatureProviderLayer("Points with thematic CPS", new [] { + new System.Data.DataColumn("CharIndex",typeof(int)), + new System.Data.DataColumn("CharSize",typeof(float)), + new System.Data.DataColumn("OffsetX",typeof(float)), + new System.Data.DataColumn("OffsetY", typeof(float)) + }); + PopulateCharacterPointSymbolizerLayer((GeometryFeatureProvider)lyr.DataSource, 0); + lyr.Theme = new SharpMap.Rendering.Thematics.CustomTheme(GetCharacterPointStyle); + lyr.Enabled = false; + this.mb.Map.Layers.Add(lyr); + } + + private void InitBackground() + { + var lyr = new TileAsyncLayer(KnownTileSources.Create(KnownTileSource.BingRoads), "Async TileLayer [Bing]"); + lyr.SRID = 3857; + this.mb.Map.BackgroundLayer.Add(lyr); + } + + private void InitRasterPointSymbolizer(VectorLayer lyr, int style) + { + if (style == 1) + lyr.Theme = new SharpMap.Rendering.Thematics.CustomTheme(GetRasterPointSymbolizerStyle); + else + lyr.Theme = null; + } + + public static VectorStyle GetRasterPointSymbolizerStyle(FeatureDataRow row) + { + // NB - this is for testing only. + var rps = new RasterPointSymbolizer() + { + Symbol = (Image)_boat.Clone(), + Rotation = (float)row[2], + RemapColor = Color.White, + Scale = (float) row[3], + SymbolColor = Color.FromArgb((int) row[4]) + }; + return new VectorStyle() {PointSymbolizer = rps}; + } + + private void PopulateGeomFeatureLayer(VectorLayer lyr, int direction) + { + var geoms = new Geometry[] { + GetRectangleCenter(MapDecorationAnchor.LeftTop), + GetRectangleCenter(direction == 0 ? MapDecorationAnchor.CenterTop : direction == 1 ? MapDecorationAnchor.LeftCenter : MapDecorationAnchor.Center), + GetRectangleCenter(direction == 0 ? MapDecorationAnchor.RightTop : direction == 1 ? MapDecorationAnchor.LeftBottom : MapDecorationAnchor.RightBottom) + }; + + var gp = (GeometryProvider)lyr.DataSource; + gp.Geometries.Clear(); + foreach (var geom in geoms) + gp.Geometries.Add(geom); + + } + private void PopulateCharacterPointSymbolizerLayer(GeometryFeatureProvider fp, int direction) + { + FeatureDataRow fdr = null; + + fp.Features.Clear(); + + fdr = fp.Features.NewRow(); + fdr["CharIndex"] = 171; + fdr["CharSize"] = 15f; + fdr["OffsetX"] = -10f; + fdr["OffsetY"] = 5f; + fdr.Geometry = GetRectangleCenter(direction == 0 ? MapDecorationAnchor.LeftBottom : direction == 1 ? MapDecorationAnchor.RightBottom : MapDecorationAnchor.LeftBottom); + fp.Features.AddRow(fdr); + + fdr = fp.Features.NewRow(); + fdr["CharIndex"] = 176; + fdr["CharSize"] = 20f; + fdr["OffsetX"] = -10f; + fdr["OffsetY"] = 5f; + fdr.Geometry = GetRectangleCenter(direction == 0 ? MapDecorationAnchor.CenterBottom : direction == 1 ? MapDecorationAnchor.RightCenter : MapDecorationAnchor.Center); + fp.Features.AddRow(fdr); + + fdr = fp.Features.NewRow(); + fdr["CharIndex"] = 181; + fdr["CharSize"] = 25f; + fdr["OffsetX"] = -15f; + fdr["OffsetY"] = -10f; + fdr.Geometry = GetRectangleCenter(direction == 0 ? MapDecorationAnchor.RightBottom : MapDecorationAnchor.RightTop); + fp.Features.AddRow(fdr); + + fp.Features.AcceptChanges(); + } + private VectorLayer CreateGeometryFeatureProviderLayer(string name, System.Data.DataColumn[] columns) + { + var fdt = new FeatureDataTable(); + fdt.Columns.Add("Oid", typeof(uint)); + var con = new System.Data.UniqueConstraint(fdt.Columns[0]); + con.Columns[0].AutoIncrement = true; + con.Columns[0].AutoIncrementSeed = 1000; + fdt.Constraints.Add(con); + fdt.PrimaryKey = new System.Data.DataColumn[]{fdt.Columns[0]}; + + fdt.Columns.AddRange(columns); + + return new VectorLayer(name, new GeometryFeatureProvider(fdt)); + } + + private VectorLayer CreateGeomLayer(string name, IGeometry[] geometries, System.Drawing.Color lineColor) + { + var lyr = new VectorLayer(name) + { + DataSource = new GeometryProvider(geometries), + SRID = 3857 + }; + lyr.Style.Line.Color = lineColor; + lyr.Style.Line.Width = 2f; + + return lyr; + } + + private Coordinate[] GetRectanglePoints(MapDecorationAnchor anchor) + { + var env = this.mb.Map.Envelope; + env.ExpandBy(-env.Width * 0.05); + + var coords = new Coordinate[5]; + + Coordinate tl = null; + switch (anchor) + { + case MapDecorationAnchor.LeftTop: + tl = env.TopLeft(); + break; + case MapDecorationAnchor.LeftCenter: + tl = new Coordinate(env.MinX, env.MaxY - env.Height * 0.375); + break; + case MapDecorationAnchor.LeftBottom: + tl = new Coordinate(env.MinX, env.MinY + env.Height * 0.25); + break; + case MapDecorationAnchor.CenterTop: + tl = new Coordinate(env.Centre.X - env.Width * 0.125, env.MaxY); + break; + case MapDecorationAnchor.CenterBottom: + tl = new Coordinate(env.Centre.X - env.Width * 0.125, env.MinY + env.Height * 0.25); + break; + case MapDecorationAnchor.RightTop: + tl = new Coordinate(env.MaxX - env.Width * 0.25, env.MaxY); + break; + case MapDecorationAnchor.RightCenter: + tl = new Coordinate(env.MaxX - env.Width * 0.25, env.MaxY - env.Height * 0.375); + break; + case MapDecorationAnchor.RightBottom: + tl = new Coordinate(env.MaxX - env.Width * 0.25, env.MinY + env.Height * 0.25); + break; + default: + tl = new Coordinate(env.Centre.X - env.Width * 0.125, env.Centre.Y + env.Height * 0.125); + break; + } + + coords[0] = tl; + coords[1] = new Coordinate(tl.X + env.Width * 0.25, coords[0].Y); + coords[2] = new Coordinate(coords[1].X, tl.Y - env.Height * 0.25); + coords[3] = new Coordinate(coords[0].X, coords[2].Y); + coords[4] = tl; + + return coords; + } + + private Point GetRectangleCenter(MapDecorationAnchor anchor) + { + var coords = GetRectanglePoints(anchor); + return new Point((coords[0].X + coords[1].X) / 2.0, + (coords[0].Y + coords[2].Y) / 2.0); + } + + public static VectorStyle GetCharacterPointStyle(FeatureDataRow row) + { + var cps = new CharacterPointSymbolizer(); + cps.CharacterIndex = (int)row[1]; + cps.Font = new System.Drawing.Font("Wingdings", (float)row[2]); + cps.Offset = new System.Drawing.PointF((float)row[3], (float)row[4]); + return new VectorStyle() {PointSymbolizer = cps}; + } + + } + + public class MovingObjects : IDisposable + { + private List _movingObjects = new List(); + + private readonly Timer _timer; + private readonly VectorLayer _lyr; + private readonly Map _map; + public int StepSize { get; set; } + private float _scale; + private Color _color; + + public MovingObjects(int interval, int stepSize, VectorLayer lyr, Map map, float scale, Color color) + { + _timer = new Timer(); + _timer.Tick += new EventHandler(Timer_Tick); + _timer.Interval = interval; + + StepSize = stepSize; + _lyr = lyr; + _map = map; + _scale = scale; + _color = color; + } + + public void Start() => _timer.Enabled = true; + public void Stop() => _timer.Enabled = false; + public bool IsRunning => _timer.Enabled; + + public void AddObject(string name, Point startAt) + { + lock (((ICollection) _movingObjects).SyncRoot) + { + var fp = (GeometryFeatureProvider) _lyr.DataSource; + var fdr = fp.Features.NewRow(); + fdr[1] = name; + fdr[2] = 0; + fdr[3] = _scale; + fdr[4] = _color.ToArgb(); + fdr.Geometry = startAt; + fp.Features.AddRow(fdr); + fp.Features.AcceptChanges(); + + var obj = new MovingObject(Convert.ToUInt32(fdr[0]), startAt); + _movingObjects.Add(obj); + } + } + + public bool DeleteObject(uint oid) + { + lock (((ICollection) _movingObjects).SyncRoot) + { + var obj = _movingObjects.Find(p => p.Oid == oid); + if (obj == null) return false; + + var fp = (GeometryFeatureProvider) _lyr.DataSource; + var fdr = fp.Features.Rows.Find(oid); + fp.Features.Rows.Remove(fdr); + fp.Features.AcceptChanges(); + + _movingObjects.Remove(obj); + return true; + } + } + + private void Timer_Tick(object sender, EventArgs e) + { + lock (((ICollection)_movingObjects).SyncRoot) + { + foreach (var obj in _movingObjects) + { + obj.Step(_map.Envelope, StepSize); + var fp = (GeometryFeatureProvider) _lyr.DataSource; + var fdr = (FeatureDataRow) fp.Features.Rows.Find(obj.Oid); +// //fdr.Geometry = obj.Position; + fdr[2] = obj.Heading; + fdr.AcceptChanges(); + } + } + if (_lyr.Enabled) _map.VariableLayers.TouchTimer(); + } + + public void Dispose() + { + _timer.Tick -= new EventHandler(Timer_Tick); + _timer?.Dispose(); + } + } + + public class MovingObject + { + public uint Oid { get; } + private bool _movingLeft; + private bool _movingUp; + public Point Position { get; private set; } + public float Heading { get; private set; } + + public MovingObject(uint oid, Point startAt) + { + Oid = oid; + Position = startAt; + _movingUp = true; + } + + public void Step(Envelope currentExtent, double stepSize) + { + var dx = _movingLeft ? -stepSize : stepSize; + var dy = _movingUp ? stepSize : -stepSize; + + Position.X += dx; + Position.Y += dy; + Position.GeometryChanged(); + + if (Position.X < currentExtent.MinX) + _movingLeft = false; + else if (Position.X > currentExtent.MaxX) + _movingLeft = true; + + if (Position.Y < currentExtent.MinY) + _movingUp = true; + else if (Position.Y > currentExtent.MaxY) + _movingUp = false; + + var deg = 90 - Math.Atan2(dy, dx) * 180 / Math.PI; + Heading = (float)(deg + 360) % 360; + } + } +} + diff --git a/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.resx b/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.resx new file mode 100644 index 00000000..5ab3f9af --- /dev/null +++ b/Examples/WinFormSamples/FormInteractiveVectorLayerRendering.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 181, 17 + + \ No newline at end of file diff --git a/Examples/WinFormSamples/Properties/Resources.Designer.cs b/Examples/WinFormSamples/Properties/Resources.Designer.cs index ef66e5d8..d304440d 100644 --- a/Examples/WinFormSamples/Properties/Resources.Designer.cs +++ b/Examples/WinFormSamples/Properties/Resources.Designer.cs @@ -1,113 +1,125 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace WinFormSamples.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WinFormSamples.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap OutfallSmall { - get { - object obj = ResourceManager.GetObject("OutfallSmall", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap PumpSmall { - get { - object obj = ResourceManager.GetObject("PumpSmall", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap view_left_right { - get { - object obj = ResourceManager.GetObject("view_left_right", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap view_top_bottom { - get { - object obj = ResourceManager.GetObject("view_top_bottom", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - internal static System.Drawing.Bitmap ZoomToExtents1 { - get { - object obj = ResourceManager.GetObject("ZoomToExtents1", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace WinFormSamples.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WinFormSamples.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap OutfallSmall { + get { + object obj = ResourceManager.GetObject("OutfallSmall", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap PumpSmall { + get { + object obj = ResourceManager.GetObject("PumpSmall", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap vessel_01 + { + get + { + object obj = ResourceManager.GetObject("vessel_01", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap view_left_right { + get { + object obj = ResourceManager.GetObject("view_left_right", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap view_top_bottom { + get { + object obj = ResourceManager.GetObject("view_top_bottom", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ZoomToExtents1 { + get { + object obj = ResourceManager.GetObject("ZoomToExtents1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Examples/WinFormSamples/Properties/Resources.resx b/Examples/WinFormSamples/Properties/Resources.resx index 488a065e..48cf9e6c 100644 --- a/Examples/WinFormSamples/Properties/Resources.resx +++ b/Examples/WinFormSamples/Properties/Resources.resx @@ -1,136 +1,139 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Resources\view_left_right.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\view_top_bottom.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\ZoomToExtents1.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\OutfallSmall.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\PumpSmall.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\view_left_right.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\view_top_bottom.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\ZoomToExtents1.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\OutfallSmall.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\PumpSmall.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\vessel_01.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Examples/WinFormSamples/Resources/vessel_01.png b/Examples/WinFormSamples/Resources/vessel_01.png new file mode 100644 index 00000000..dd484829 Binary files /dev/null and b/Examples/WinFormSamples/Resources/vessel_01.png differ diff --git a/Examples/WinFormSamples/Samples/ShapefileSample.cs b/Examples/WinFormSamples/Samples/ShapefileSample.cs index af019312..e9cd3fbc 100644 --- a/Examples/WinFormSamples/Samples/ShapefileSample.cs +++ b/Examples/WinFormSamples/Samples/ShapefileSample.cs @@ -82,6 +82,7 @@ private static Map InitializeMapWithSymbolizerLayers(float angle) DataSource = layCountries.DataSource, Enabled = true, LabelColumn = "Name", + LabelFilter = LabelCollisionDetection.QuickAccurateCollisionDetectionMethod, Style = new LabelStyle { @@ -94,7 +95,7 @@ private static Map InitializeMapWithSymbolizerLayers(float angle) MinVisible = 30, SRID = 4326, MultipartGeometryBehaviour = LabelLayer.MultipartGeometryBehaviourEnum.Largest, - + }; //Set up a city label layer @@ -106,7 +107,7 @@ private static Map InitializeMapWithSymbolizerLayers(float angle) TextRenderingHint = TextRenderingHint.AntiAlias, SmoothingMode = SmoothingMode.AntiAlias, SRID = 4326, - LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection, + LabelFilter = LabelCollisionDetection.QuickAccurateCollisionDetectionMethod, Style = new LabelStyle { @@ -130,7 +131,7 @@ private static Map InitializeMapWithSymbolizerLayers(float angle) TextRenderingHint = TextRenderingHint.AntiAlias, SmoothingMode = SmoothingMode.AntiAlias, SRID = 4326, - LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection, + LabelFilter = LabelCollisionDetection.QuickAccurateCollisionDetectionMethod, MultipartGeometryBehaviour = LabelLayer.MultipartGeometryBehaviourEnum.All, Style = new LabelStyle @@ -139,7 +140,7 @@ private static Map InitializeMapWithSymbolizerLayers(float angle) Font = new Font(FontFamily.GenericSansSerif, 11), HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center, VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Middle, - //CollisionDetection = true, + CollisionDetection = true, Halo = new Pen(Color.Azure, 2), IgnoreLength = true @@ -270,7 +271,7 @@ private static Map InitializeMapOrig(float angle) TextRenderingHint = TextRenderingHint.AntiAlias, SmoothingMode = SmoothingMode.AntiAlias, SRID = 4326, - LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection, + LabelFilter = LabelCollisionDetection.QuickAccurateCollisionDetectionMethod, MultipartGeometryBehaviour = LabelLayer.MultipartGeometryBehaviourEnum.CommonCenter, Style = new LabelStyle @@ -279,7 +280,7 @@ private static Map InitializeMapOrig(float angle) Font = new Font(FontFamily.GenericSansSerif, 11), HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center, VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Middle, - //CollisionDetection = true, + CollisionDetection = true, Halo = new Pen(Color.Azure, 2), IgnoreLength = ignoreLength, Offset = new PointF(0, -10) diff --git a/Examples/WinFormSamples/WinFormSamples.csproj b/Examples/WinFormSamples/WinFormSamples.csproj index be256d79..98a60157 100644 --- a/Examples/WinFormSamples/WinFormSamples.csproj +++ b/Examples/WinFormSamples/WinFormSamples.csproj @@ -14,6 +14,7 @@ WinExe WinFormSamples.Program false + true diff --git a/Examples/WinFormSamples/app.config b/Examples/WinFormSamples/app.config index fdbe0461..d3fb667e 100644 --- a/Examples/WinFormSamples/app.config +++ b/Examples/WinFormSamples/app.config @@ -57,22 +57,11 @@ - - - - - - - - - - - - - + + diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 00000000..08598b21 --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/SharpMap.Common.props b/SharpMap.Common.props index a42735bb..cf9404da 100644 --- a/SharpMap.Common.props +++ b/SharpMap.Common.props @@ -6,14 +6,81 @@ v4.0 + + true + 0 + + + + + ci.github.$(GITHUB_ACTION) + $(GITHUB_ACTION) + + + + ci.travis.$(TRAVIS_BUILD_NUMBER) + $(TRAVIS_BUILD_NUMBER) + + + + ci.teamcity.$(BUILD_NUMBER) + $(BUILD_NUMBER) + + + + ci.appveyor.$(APPVEYOR_BUILD_NUMBER) + $(APPVEYOR_BUILD_NUMBER) + + + + local + + + + + + + + + + + + + $([System.DateTime]::op_Addition( + $([System.DateTime]::new($([MSBuild]::Multiply($(BuildTimeLinux), $([System.TimeSpan]::TicksPerSecond))))), + $([System.TimeSpan]::FromTicks(621355968000000000))).Ticks) + + + + + + $(BuildTimeUtcTicks) + + + + + $([System.DateTime]::UtcNow.Ticks) + + + + - 1 - 2 - 0 - 0 + + 1 + 2 + 0 + + $([System.DateTime]::op_Subtraction($([System.DateTime]::new($(SmBuildTimestamp)).Date),$([System.DateTime]::new(621355968000000000))).TotalDays.ToString("00000")) + + $([System.DateTime]::new($(SmBuildTimestamp)).TimeOfDay.TotalMinutes.ToString("0000")) + + $(SmMajor).$(SmMinor).$(SmPatch) + pre.$(SmDaysSinceEpoch)$(SmMinutesSinceStartOfUtcDay)+$(SmBuildMetadata) + + SharpMap - Team @@ -33,13 +101,34 @@ SharpMap.Logo.png LGPL-2.1-or-later true - $(Major).$(Minor).$(Build) - $(Major).$(Minor).$(Build).$(Revision) - $(Major).$(Minor).$(Build)-pre1 + $(SmMajor).$(SmMinor).0.0 + $(VersionPrefix).$(SmBuildNo) + $(VersionPrefix)-$(VersionSuffix) + $(VersionPrefix)-$(VersionSuffix) + + + + $(SolutionDir)SharpMap.Debug.Packages + + + + $(SolutionDir)SharpMap.Packages + + true + true + true + snupkg + + + + + + + diff --git a/SharpMap.Data.Providers.FileGdb/SharpMap.Data.Providers.FileGdb.csproj b/SharpMap.Data.Providers.FileGdb/SharpMap.Data.Providers.FileGdb.csproj index 9fb64c47..df22f910 100644 --- a/SharpMap.Data.Providers.FileGdb/SharpMap.Data.Providers.FileGdb.csproj +++ b/SharpMap.Data.Providers.FileGdb/SharpMap.Data.Providers.FileGdb.csproj @@ -16,7 +16,7 @@ - + Libraries\bin\Esri.FileGDBAPI.dll diff --git a/SharpMap.Data.Providers.Kml/KmlProvider.cs b/SharpMap.Data.Providers.Kml/KmlProvider.cs index f56d7d33..7b55b288 100644 --- a/SharpMap.Data.Providers.Kml/KmlProvider.cs +++ b/SharpMap.Data.Providers.Kml/KmlProvider.cs @@ -1,767 +1,955 @@ -// Copyright 2014 - Robert Smart (www.cnl-software.com) -// -// This file is part of SharpMap.Data.Providers.Kml. -// SharpMap.Data.Providers.Kml is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// SharpMap.Data.Providers.Kml is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with SharpMap; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Drawing; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using GeoAPI.Geometries; -using SharpKml.Dom; -using SharpKml.Engine; -using SharpMap.Rendering.Thematics; -using SharpMap.Styles; -using LinearRing = SharpKml.Dom.LinearRing; -using LineString = SharpKml.Dom.LineString; -using Point = SharpKml.Dom.Point; -using Polygon = SharpKml.Dom.Polygon; -using Style = SharpKml.Dom.Style; - -namespace SharpMap.Data.Providers -{ - /// - /// Kml/Kmz provider - /// - public class KmlProvider : IProvider - { - #region Static factory methods - - /// - /// Creates a KmlProvider from a file - /// - /// The path to the file - /// A Kml provider - /// - /// - public static KmlProvider FromKml(string filename) - { - if (string.IsNullOrEmpty(filename)) - throw new ArgumentNullException("filename"); - if (!File.Exists(filename)) - throw new FileNotFoundException("File not found", "filename"); - - using (var s = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return FromKml(s); - } - } - - /// - /// Creates a KmlProvider from a Kml stream - /// - /// The stream to read from - /// - public static KmlProvider FromKml(Stream stream) - { - if (stream == null) - throw new ArgumentNullException("stream"); - - return new KmlProvider(KmlFile.Load(stream)); - } - - /// - /// Creates a KmlProvider from a file - /// - /// The path to the file - /// The internal file to read - /// A Kml provider - /// - /// - public static KmlProvider FromKmz(string filename, string internalFile = null) - { - if (string.IsNullOrEmpty(filename)) - throw new ArgumentNullException("filename"); - if (!File.Exists(filename)) - throw new FileNotFoundException("File not found", "filename"); - - using (var s = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return FromKmz(s, internalFile); - } - } - - /// - /// Creates a KmlProvider from a Kmz stream - /// - /// The stream to read from - /// The internal file to read - /// - public static KmlProvider FromKmz(Stream stream, string internalFile = null) - { - var kmz = KmzFile.Open(stream); - if (string.IsNullOrEmpty(internalFile)) - return new KmlProvider(kmz.GetDefaultKmlFile()); - - //NOTE:DON'T KNOW IF THIS IS CORRECT! - using (var ms = new MemoryStream(kmz.ReadFile(internalFile))) - { - return new KmlProvider(KmlFile.Load(ms)); - } - } - #endregion - - #region static constructor and fields - - private static readonly FeatureDataTable _schemaTable; - - static KmlProvider() - { - _schemaTable = new FeatureDataTable(); - AddColumnsToFeatureDataTable(_schemaTable); - } - - #endregion - - #region private fields and constants - private IGeometryFactory _geometryFactory; - private Dictionary> _geometrys; - private Dictionary _kmlStyles; - private List _styleMaps; - - private const string DefaultStyleId = "{6787C5B3-6482-4B96-9C2D-2C6236D2AC50}"; - private const string DefaultPointStyleId = "{E2892545-7CF4-48A1-B8F0-5A0BF06EF0E1}"; - - #endregion - - /// - /// Method to create a theme for the Layer - /// - /// A theme - /// - /// - /// - /// - public ITheme GetKmlTheme() - { - //todo layer will need to do this - //Layer.Theme = assetTheme; - return new CustomTheme(GetKmlStyle); - } - - /// - /// Gets or sets a value indicating that are to be treated as polygons - /// - public bool RingsArePolygons { get; set; } - - /// - /// Creates an instance of this class using the provided KmlFile - /// - /// The KmlFile - public KmlProvider(KmlFile kmlFile) - { - ParseKml(kmlFile); - } - - /// - /// Method to parse the KmlFile - /// - /// The file to parse - private void ParseKml(KmlFile kmlFile) - { - var kml = kmlFile.Root as Kml; - if (kml == null) - { - throw new Exception("Kml file is null! Please check that the file conforms to http://www.opengis.net/kml/2.2 standards"); - } - - var doc = kml.Feature as Document; - if (doc == null) - { - throw new Exception("Kml file does not have a document node! please check that the file conforms to http://www.opengis.net/kml/2.2 standards"); - } - - _geometryFactory = GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory(4326); - ConnectionID = doc.Name; - if (doc.Description != null && !string.IsNullOrEmpty(doc.Description.Text)) - ConnectionID += " (" + doc.Description.Text + ")"; - - ExtractStyles(kml); - ExtractStyleMaps(kml); - ExtractGeometries(kml); - - } - - private void ExtractStyleMaps(Element kml) - { - _styleMaps = new List(); - foreach (var style in kml.Flatten().OfType()) - { - var styleMap = new StyleMap { Id = style.Id }; - _styleMaps.Add(styleMap); - style.ToList().ForEach(x => - { - if (x.State != null) - - switch (x.State.Value) - { - case StyleState.Normal: - styleMap.NormalStyleUrl = x.StyleUrl.ToString().Replace("#", ""); - break; - case StyleState.Highlight: - styleMap.HighlightStyleUrl = x.StyleUrl.ToString().Replace("#", ""); - break; - } - - }); - } - } - - /// - /// Style map class - /// - private class StyleMap - { - public string Id { get; set; } - public string NormalStyleUrl { get; set; } - public string HighlightStyleUrl { get; set; } - } - - //todo needs buffing up - private void ExtractStyles(Element kml) - { - _kmlStyles = new Dictionary(); - - _kmlStyles.Add(DefaultStyleId, DefaultVectorStyle()); - _kmlStyles.Add(DefaultPointStyleId, DefaultPointStyle()); - - var symbolDict = new Dictionary(); - - foreach (var style in kml.Flatten().OfType + + 1 + + 14.76679054044666,8.647733316197623,0 14.99402575335166,8.762810855977225,0 15.13946004407134,8.539054532876513,0 + + + + + Polygon 1 with StyleUrl + KML_styles.kml#polygonsymbology + + 1 + + + + 15.45930089777413,8.649774762626734,0 15.78812145713398,8.826902630484089,0 15.56553132250632,9.117659207419846,0 15.28843281990799,8.916977130845003,0 15.45930089777413,8.649774762626734,0 + + + + + + + Polygon 2 with Style overrides + KML_styles.kml#polygonsymbology + + + 1 + + + + 15.99240773337751,8.791408965716004,0 16.2407273758592,8.921982810633205,0 15.97838555087566,9.197063754094813,0 15.75799832823521,9.060468835708274,0 15.99240773337751,8.791408965716004,0 + + + + + + + Polygon 3 inline style fill only + + + 1 + + + + 16.45141663527584,8.99085343604397,0 16.62822777773094,9.105369181051785,0 16.3836231863226,9.367059726191357,0 16.22294327719263,9.238531882204896,0 16.45141663527584,8.99085343604397,0 + + + + + + + Polygon 4 inline style outline only + + + 1 + + + + 16.75311822571322,9.148653889350184,0 16.91888588059678,9.219599002061271,0 16.70384488661618,9.49955818101844,0 16.55253261598985,9.408508348830811,0 16.75311822571322,9.148653889350184,0 + + + + + + + Polygon 5 with island + KML_styles.kml#polygonsymbology + + 1 + + + + 17.156109304262,9.251432883064757,0 17.32967734249761,9.340659686674064,0 17.15439083960273,9.617539674318666,0 16.97897194415396,9.494094316822185,0 17.156109304262,9.251432883064757,0 + + + + + + + 17.18499558552173,9.330908287399483,0 17.24428094114781,9.374604608036631,0 17.17390026104265,9.5020304960033,0 17.10654405342015,9.460253752017769,0 17.18499558552173,9.330908287399483,0 + + + + + + + diff --git a/UnitTests/TestData/KML_geom_external_styleurl_http.kml b/UnitTests/TestData/KML_geom_external_styleurl_http.kml new file mode 100644 index 00000000..b0e19adf --- /dev/null +++ b/UnitTests/TestData/KML_geom_external_styleurl_http.kml @@ -0,0 +1,20 @@ + + + + Style Map Tests + + Africa 1 + https://developers.google.com/kml/documentation/KML_Samples.kml#globeIcon + + 14.56324920473027,8.823766947866202,0 + + + + Africa 2 + https://developers.google.com/kml/documentation/KML_Samples.kml#downArrowIcon + + 17.40955322880677,9.619815130815919,0 + + + + diff --git a/UnitTests/TestData/KML_geom_external_styleurl_invalid.kml b/UnitTests/TestData/KML_geom_external_styleurl_invalid.kml new file mode 100644 index 00000000..3ace5b06 --- /dev/null +++ b/UnitTests/TestData/KML_geom_external_styleurl_invalid.kml @@ -0,0 +1,146 @@ + + + + Style Map Tests + Placemarks using invalid styles. Placemarks will be rendered using default symbology. + + Africa 1 + bollocks#sm_square + + 1 + 14.56324920473027,8.823766947866202,0 + + + + Africa 2 + bollocks#sm_circle + + 1 + 17.40955322880677,9.619815130815919,0 + + + + Line 1 with StyleUrl + bollocks#linesymbology + + + 14.7322444643474,8.741122422265486,0 14.98189150254889,8.876022509822219,0 15.1636208882102,8.614709363012477,0 + + + + + Line 2 with StyleUrl and overrides + bollocks#linesymbology + + + 1 + + 14.76679054044666,8.647733316197623,0 14.99402575335166,8.762810855977225,0 15.13946004407134,8.539054532876513,0 + + + + + Polygon 1 with StyleUrl + bollocks#polygonsymbology + + 1 + + + + 15.45930089777413,8.649774762626734,0 15.78812145713398,8.826902630484089,0 15.56553132250632,9.117659207419846,0 15.28843281990799,8.916977130845003,0 15.45930089777413,8.649774762626734,0 + + + + + + + Polygon 2 with Style overrides + bollocks#polygonsymbology + + + 1 + + + + 15.99240773337751,8.791408965716004,0 16.2407273758592,8.921982810633205,0 15.97838555087566,9.197063754094813,0 15.75799832823521,9.060468835708274,0 15.99240773337751,8.791408965716004,0 + + + + + + + Polygon 3 inline style fill only + + + 1 + + + + 16.45141663527584,8.99085343604397,0 16.62822777773094,9.105369181051785,0 16.3836231863226,9.367059726191357,0 16.22294327719263,9.238531882204896,0 16.45141663527584,8.99085343604397,0 + + + + + + + Polygon 4 inline style outline only + + + 1 + + + + 16.75311822571322,9.148653889350184,0 16.91888588059678,9.219599002061271,0 16.70384488661618,9.49955818101844,0 16.55253261598985,9.408508348830811,0 16.75311822571322,9.148653889350184,0 + + + + + + + Polygon 5 with island + bollocks#polygonsymbology + + 1 + + + + 17.156109304262,9.251432883064757,0 17.32967734249761,9.340659686674064,0 17.15439083960273,9.617539674318666,0 16.97897194415396,9.494094316822185,0 17.156109304262,9.251432883064757,0 + + + + + + + 17.18499558552173,9.330908287399483,0 17.24428094114781,9.374604608036631,0 17.17390026104265,9.5020304960033,0 17.10654405342015,9.460253752017769,0 17.18499558552173,9.330908287399483,0 + + + + + + + diff --git a/UnitTests/TestData/KML_geom_internal_styleurl.kml b/UnitTests/TestData/KML_geom_internal_styleurl.kml new file mode 100644 index 00000000..ffb596dc --- /dev/null +++ b/UnitTests/TestData/KML_geom_internal_styleurl.kml @@ -0,0 +1,213 @@ + + + + Style Map Tests + Placemarks using Styles defined in the same document + + + + + + + + + normal + #sym_circle + + + highlight + #sym_circle_highlight + + + + + normal + #sym_square + + + highlight + #sym_square_highlight + + + + Africa 1 + #sm_square + + 1 + 14.56324920473027,8.823766947866202,0 + + + + Africa 2 + #sm_circle + + 1 + 17.40955322880677,9.619815130815919,0 + + + + Line 1 with StyleUrl + #linesymbology + + + 14.7322444643474,8.741122422265486,0 14.98189150254889,8.876022509822219,0 15.1636208882102,8.614709363012477,0 + + + + + Line 2 with StyleUrl and overrides + #linesymbology + + + 1 + + 14.76679054044666,8.647733316197623,0 14.99402575335166,8.762810855977225,0 15.13946004407134,8.539054532876513,0 + + + + + Polygon 1 with StyleUrl + #polygonsymbology + + 1 + + + + 15.45930089777413,8.649774762626734,0 15.78812145713398,8.826902630484089,0 15.56553132250632,9.117659207419846,0 15.28843281990799,8.916977130845003,0 15.45930089777413,8.649774762626734,0 + + + + + + + Polygon 2 with Style overrides + #polygonsymbology + + + 1 + + + + 15.99240773337751,8.791408965716004,0 16.2407273758592,8.921982810633205,0 15.97838555087566,9.197063754094813,0 15.75799832823521,9.060468835708274,0 15.99240773337751,8.791408965716004,0 + + + + + + + Polygon 3 inline style fill only + + + 1 + + + + 16.45141663527584,8.99085343604397,0 16.62822777773094,9.105369181051785,0 16.3836231863226,9.367059726191357,0 16.22294327719263,9.238531882204896,0 16.45141663527584,8.99085343604397,0 + + + + + + + Polygon 4 inline style outline only + + + 1 + + + + 16.75311822571322,9.148653889350184,0 16.91888588059678,9.219599002061271,0 16.70384488661618,9.49955818101844,0 16.55253261598985,9.408508348830811,0 16.75311822571322,9.148653889350184,0 + + + + + + + Polygon 5 with island + #polygonsymbology + + 1 + + + + 17.156109304262,9.251432883064757,0 17.32967734249761,9.340659686674064,0 17.15439083960273,9.617539674318666,0 16.97897194415396,9.494094316822185,0 17.156109304262,9.251432883064757,0 + + + + + + + 17.18499558552173,9.330908287399483,0 17.24428094114781,9.374604608036631,0 17.17390026104265,9.5020304960033,0 17.10654405342015,9.460253752017769,0 17.18499558552173,9.330908287399483,0 + + + + + + + diff --git a/UnitTests/TestData/KML_styles.kml b/UnitTests/TestData/KML_styles.kml new file mode 100644 index 00000000..09bbbfce --- /dev/null +++ b/UnitTests/TestData/KML_styles.kml @@ -0,0 +1,74 @@ + + + + Style Map Tests + Styles and Style Maps referenced by other KML files + + + + + + + + + normal + #sym_circle + + + highlight + #sym_circle_highlight + + + + + normal + #sym_square + + + highlight + #sym_square_highlight + + + + diff --git a/UnitTests/TestData/KMZ_geom_external_styleurl_file.kmz b/UnitTests/TestData/KMZ_geom_external_styleurl_file.kmz new file mode 100644 index 00000000..75a231a5 Binary files /dev/null and b/UnitTests/TestData/KMZ_geom_external_styleurl_file.kmz differ diff --git a/UnitTests/TestData/KMZ_geom_internal_styleurl.kmz b/UnitTests/TestData/KMZ_geom_internal_styleurl.kmz new file mode 100644 index 00000000..3124d220 Binary files /dev/null and b/UnitTests/TestData/KMZ_geom_internal_styleurl.kmz differ diff --git a/UnitTests/TestData/KMZ_styles.kmz b/UnitTests/TestData/KMZ_styles.kmz new file mode 100644 index 00000000..c698fa9a Binary files /dev/null and b/UnitTests/TestData/KMZ_styles.kmz differ diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index e3edc592..f744c474 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -19,16 +19,24 @@ $(DefineConstants);LINUX + + 1701;1702;1591 + + + - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -91,13 +99,13 @@ - - + + - - + + - + diff --git a/UnitTests/app.config b/UnitTests/app.config index 8ce0b5e0..71cd046a 100644 --- a/UnitTests/app.config +++ b/UnitTests/app.config @@ -32,24 +32,16 @@ --> - - - - - - + + - - - -