├── .gitattributes
├── .gitignore
├── App.config
├── ExampleDb
├── SimpleMapDb.Designer.cs
├── SimpleMapDb.cs
├── SimpleMapDb.resx
├── SimpleMapDb.xsc
├── SimpleMapDb.xsd
└── SimpleMapDb.xss
├── ExampleExe
├── Screenshot.png
├── SimpleMap.exe
└── SimpleMap.exe.config
├── ExampleForms
├── Controls
│ ├── ButtonPanelCtl.Designer.cs
│ ├── ButtonPanelCtl.cs
│ ├── ButtonPanelCtl.resx
│ ├── MapCtl.cs
│ ├── MapCtl.designer.cs
│ └── MapCtl.resx
├── FrmMapDownloader.Designer.cs
├── FrmMapDownloader.cs
├── FrmMapDownloader.resx
├── FrmOpticMap.Designer.cs
├── FrmOpticMap.cs
├── FrmOpticMap.resx
└── Miscellaneous.cs
├── Framework
├── ExternalHelpers.cs
├── GraphicLayer.cs
└── WorkerThread
│ ├── Types
│ ├── EventPriorityType.cs
│ ├── EventPriorityTypeConverter.cs
│ ├── MainThreadEventArgs.cs
│ └── WorkerEventType.cs
│ ├── WorkerEvent.cs
│ └── WorkerMessageThread.cs
├── Layers
├── MapLayer.cs
├── MapObjects
│ ├── BuildingTree.cs
│ ├── CableTree.cs
│ ├── TreeNodes
│ │ ├── BuildingNode.cs
│ │ ├── CableNode.cs
│ │ └── VertexNode.cs
│ └── VertexTree.cs
└── NetLayer.cs
├── Map
├── Coordinate.cs
├── CoordinatePoligon.cs
├── CoordinateRectangle.cs
├── EarthUtilities.cs
├── Google
│ ├── GoogleBlock.cs
│ ├── GoogleCoordinate.cs
│ ├── GoogleMapUtilities.cs
│ └── GoogleRectangle.cs
├── Indexer
│ └── CoordinateIndexer.cs
├── Spatial
│ ├── Indexer
│ │ ├── SpatialContentIndexer.cs
│ │ ├── SpatialLevelPowerIndexer.cs
│ │ └── SpatialSheetIndexer.cs
│ ├── SpatialQueryIterator.cs
│ ├── SpatialSheet.cs
│ ├── SpatialSheetBase.cs
│ ├── SpatialTree.cs
│ └── Types
│ │ ├── SpatialSheetPowerTypes.cs
│ │ ├── SpatialTreeNode.cs
│ │ └── SpatialTreeNodeTypes.cs
└── Types
│ └── InterseptResult.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
├── Settings.settings
└── app.manifest
├── README.md
├── Resources
├── centermap_24.png
├── print_24.png
├── program_24.png
├── refresh_16.png
├── save 2_16x16.png
├── vertex_16.png
├── vertex_24.png
└── vertex_8.png
├── Settings.cs
├── SimpleMap.csproj
├── SimpleMap.csproj.user
├── SimpleMap.sln
└── default.ico
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 | *.suo
49 | bin/
50 | obj/
51 |
--------------------------------------------------------------------------------
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | SimpleMap\
18 |
19 |
20 | 12
21 |
22 |
23 | 17
24 |
25 |
26 | 5
27 |
28 |
29 | 37.24468
30 |
31 |
32 | 55.9469
33 |
34 |
35 | 38.00891
36 |
37 |
38 | 55.5601
39 |
40 |
41 |
42 |
43 |
44 |
45 | http://mt1.google.com/vt/lyrs=m@146&hl=en&x={0}&y={1}&z={2}
46 |
47 |
48 | 1.3.8.5
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/ExampleDb/SimpleMapDb.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using System.Windows.Forms;
3 |
4 | namespace ProgramMain.ExampleDb
5 | {
6 |
7 | public partial class SimpleMapDb
8 | {
9 |
10 | public static BindingSource CreateDataSource(DataTable table)
11 | {
12 | var bindingSource = new BindingSource {DataSource = table.DataSet, DataMember = table.TableName};
13 |
14 | return bindingSource;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ExampleDb/SimpleMapDb.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 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | False
122 |
123 |
--------------------------------------------------------------------------------
/ExampleDb/SimpleMapDb.xsc:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ExampleDb/SimpleMapDb.xsd:
--------------------------------------------------------------------------------
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 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
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 |
79 |
--------------------------------------------------------------------------------
/ExampleDb/SimpleMapDb.xss:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ExampleExe/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/ExampleExe/Screenshot.png
--------------------------------------------------------------------------------
/ExampleExe/SimpleMap.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/ExampleExe/SimpleMap.exe
--------------------------------------------------------------------------------
/ExampleExe/SimpleMap.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | SimpleMap\
18 |
19 |
20 | 12
21 |
22 |
23 | 17
24 |
25 |
26 | 5
27 |
28 |
29 | 37.24468
30 |
31 |
32 | 55.9469
33 |
34 |
35 | 38.00891
36 |
37 |
38 | 55.5601
39 |
40 |
41 |
42 |
43 |
44 |
45 | http://mt1.google.com/vt/lyrs=m@146&hl=en&x={0}&y={1}&z={2}
46 |
47 |
48 | 1.3.8.5
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/ExampleForms/Controls/ButtonPanelCtl.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.ExampleForms.Controls
2 | {
3 | partial class ButtonPanelCtl
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Component Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | this.labelControl1 = new System.Windows.Forms.Label();
33 | this.btnRefreshMap = new System.Windows.Forms.Button();
34 | this.btnPrint = new System.Windows.Forms.Button();
35 | this.zoomLevel = new System.Windows.Forms.TrackBar();
36 | this.btnCenterMap = new System.Windows.Forms.Button();
37 | this.btnCacheAllMap = new System.Windows.Forms.Button();
38 | this.btnSaveMapAsImage = new System.Windows.Forms.Button();
39 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
40 | ((System.ComponentModel.ISupportInitialize)(this.zoomLevel)).BeginInit();
41 | this.SuspendLayout();
42 | //
43 | // labelControl1
44 | //
45 | this.labelControl1.Location = new System.Drawing.Point(105, 13);
46 | this.labelControl1.Name = "labelControl1";
47 | this.labelControl1.Size = new System.Drawing.Size(40, 13);
48 | this.labelControl1.TabIndex = 3;
49 | this.labelControl1.Text = "Zoom:";
50 | //
51 | // btnRefreshMap
52 | //
53 | this.btnRefreshMap.Image = global::ProgramMain.Properties.Resources.refresh_16;
54 | this.btnRefreshMap.Location = new System.Drawing.Point(3, 3);
55 | this.btnRefreshMap.Name = "btnRefreshMap";
56 | this.btnRefreshMap.Size = new System.Drawing.Size(33, 32);
57 | this.btnRefreshMap.TabIndex = 8;
58 | this.toolTip1.SetToolTip(this.btnRefreshMap, "Refresh Sample Tree");
59 | this.btnRefreshMap.UseCompatibleTextRendering = true;
60 | this.btnRefreshMap.UseVisualStyleBackColor = true;
61 | this.btnRefreshMap.Click += new System.EventHandler(this.btnRefreshMap_Click);
62 | //
63 | // btnPrint
64 | //
65 | this.btnPrint.Image = global::ProgramMain.Properties.Resources.print_24;
66 | this.btnPrint.Location = new System.Drawing.Point(42, 3);
67 | this.btnPrint.Name = "btnPrint";
68 | this.btnPrint.Size = new System.Drawing.Size(33, 32);
69 | this.btnPrint.TabIndex = 9;
70 | this.toolTip1.SetToolTip(this.btnPrint, "Print Map");
71 | this.btnPrint.UseVisualStyleBackColor = true;
72 | this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click);
73 | //
74 | // zoomLevel
75 | //
76 | this.zoomLevel.LargeChange = 2;
77 | this.zoomLevel.Location = new System.Drawing.Point(151, 0);
78 | this.zoomLevel.Maximum = 20;
79 | this.zoomLevel.Minimum = 10;
80 | this.zoomLevel.Name = "zoomLevel";
81 | this.zoomLevel.Size = new System.Drawing.Size(226, 45);
82 | this.zoomLevel.TabIndex = 10;
83 | this.toolTip1.SetToolTip(this.zoomLevel, "Change map zoom level");
84 | this.zoomLevel.Value = 12;
85 | this.zoomLevel.ValueChanged += new System.EventHandler(this.zoomLevel_ValueChanged);
86 | //
87 | // btnCenterMap
88 | //
89 | this.btnCenterMap.Image = global::ProgramMain.Properties.Resources.centermap_24;
90 | this.btnCenterMap.Location = new System.Drawing.Point(383, 3);
91 | this.btnCenterMap.Name = "btnCenterMap";
92 | this.btnCenterMap.Size = new System.Drawing.Size(33, 32);
93 | this.btnCenterMap.TabIndex = 11;
94 | this.toolTip1.SetToolTip(this.btnCenterMap, "Center map");
95 | this.btnCenterMap.UseVisualStyleBackColor = true;
96 | this.btnCenterMap.Click += new System.EventHandler(this.btnCenterMap_Click);
97 | //
98 | // btnCacheAllMap
99 | //
100 | this.btnCacheAllMap.Image = global::ProgramMain.Properties.Resources.save_2_16x16;
101 | this.btnCacheAllMap.Location = new System.Drawing.Point(422, 3);
102 | this.btnCacheAllMap.Name = "btnCacheAllMap";
103 | this.btnCacheAllMap.Size = new System.Drawing.Size(33, 32);
104 | this.btnCacheAllMap.TabIndex = 12;
105 | this.toolTip1.SetToolTip(this.btnCacheAllMap, "Download whole map to local disk cache");
106 | this.btnCacheAllMap.UseVisualStyleBackColor = true;
107 | this.btnCacheAllMap.Click += new System.EventHandler(this.btnCacheAllMap_Click);
108 | //
109 | // btnSaveMapAsImage
110 | //
111 | this.btnSaveMapAsImage.Image = global::ProgramMain.Properties.Resources.program_24;
112 | this.btnSaveMapAsImage.Location = new System.Drawing.Point(461, 3);
113 | this.btnSaveMapAsImage.Name = "btnSaveMapAsImage";
114 | this.btnSaveMapAsImage.Size = new System.Drawing.Size(33, 32);
115 | this.btnSaveMapAsImage.TabIndex = 13;
116 | this.toolTip1.SetToolTip(this.btnSaveMapAsImage, "Save map as image to file");
117 | this.btnSaveMapAsImage.UseVisualStyleBackColor = true;
118 | this.btnSaveMapAsImage.Click += new System.EventHandler(this.btnSaveMapAsImage_Click);
119 | //
120 | // ButtonPanelCtl
121 | //
122 | this.Controls.Add(this.btnSaveMapAsImage);
123 | this.Controls.Add(this.btnCacheAllMap);
124 | this.Controls.Add(this.btnCenterMap);
125 | this.Controls.Add(this.zoomLevel);
126 | this.Controls.Add(this.btnPrint);
127 | this.Controls.Add(this.btnRefreshMap);
128 | this.Controls.Add(this.labelControl1);
129 | this.MaximumSize = new System.Drawing.Size(20000, 38);
130 | this.MinimumSize = new System.Drawing.Size(325, 38);
131 | this.Name = "ButtonPanelCtl";
132 | this.Size = new System.Drawing.Size(600, 38);
133 | this.Load += new System.EventHandler(this.FrmDesignPanel_Load);
134 | ((System.ComponentModel.ISupportInitialize)(this.zoomLevel)).EndInit();
135 | this.ResumeLayout(false);
136 | this.PerformLayout();
137 |
138 | }
139 |
140 | #endregion
141 |
142 | private System.Windows.Forms.Label labelControl1;
143 | private System.Windows.Forms.Button btnCenterMap;
144 | private System.Windows.Forms.TrackBar zoomLevel;
145 | private System.Windows.Forms.Button btnPrint;
146 | private System.Windows.Forms.Button btnRefreshMap;
147 | private System.Windows.Forms.Button btnCacheAllMap;
148 | private System.Windows.Forms.Button btnSaveMapAsImage;
149 | private System.Windows.Forms.ToolTip toolTip1;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/ExampleForms/Controls/ButtonPanelCtl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace ProgramMain.ExampleForms.Controls
5 | {
6 | public partial class ButtonPanelCtl : UserControl
7 | {
8 | public ButtonPanelCtl()
9 | {
10 | InitializeComponent();
11 | }
12 |
13 | public int Level
14 | {
15 | get
16 | {
17 | return zoomLevel.Value;
18 | }
19 | set
20 | {
21 | zoomLevel.Value = value;
22 | }
23 | }
24 |
25 | public class LevelValueArgs : EventArgs
26 | {
27 | public int Level { get; private set; }
28 |
29 | public LevelValueArgs(int level)
30 | {
31 | Level = level;
32 | }
33 | }
34 | public event EventHandler LevelValueChanged;
35 |
36 | public event EventHandler CenterMapClicked;
37 |
38 | public event EventHandler PrintMapClicked;
39 |
40 | public event EventHandler RefreshMapClicked;
41 |
42 | public event EventHandler SaveAllMapClicked;
43 |
44 | public event EventHandler SaveMapAsImageClicked;
45 |
46 | private void FrmDesignPanel_Load(object sender, EventArgs e)
47 | {
48 | zoomLevel.Maximum = Properties.Settings.Default.MaxZoomLevel;
49 | zoomLevel.Minimum = Properties.Settings.Default.MinZoomLevel;
50 | zoomLevel.Value = Properties.Settings.Default.StartZoomLevel;
51 | }
52 |
53 | private void zoomLevel_ValueChanged(object sender, EventArgs e)
54 | {
55 | if (LevelValueChanged != null && zoomLevel.Value >= Properties.Settings.Default.MinZoomLevel
56 | && zoomLevel.Value <= Properties.Settings.Default.MaxZoomLevel)
57 | {
58 | LevelValueChanged(this, new LevelValueArgs(zoomLevel.Value));
59 | }
60 | }
61 |
62 | private void btnCenterMap_Click(object sender, EventArgs e)
63 | {
64 | if (CenterMapClicked != null) CenterMapClicked(this, e);
65 | }
66 |
67 | private void btnRefreshMap_Click(object sender, EventArgs e)
68 | {
69 | if (RefreshMapClicked != null) RefreshMapClicked(this, e);
70 | }
71 |
72 | private void btnPrint_Click(object sender, EventArgs e)
73 | {
74 | if (PrintMapClicked != null) PrintMapClicked(this, EventArgs.Empty);
75 | }
76 |
77 | private void btnCacheAllMap_Click(object sender, EventArgs e)
78 | {
79 | if (SaveAllMapClicked != null) SaveAllMapClicked(this, EventArgs.Empty);
80 | }
81 |
82 | private void btnSaveMapAsImage_Click(object sender, EventArgs e)
83 | {
84 | if (SaveMapAsImageClicked != null) SaveMapAsImageClicked(this, EventArgs.Empty);
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/ExampleForms/Controls/ButtonPanelCtl.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 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/ExampleForms/Controls/MapCtl.designer.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.ExampleForms.Controls
2 | {
3 | partial class MapCtl
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Component Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
33 | this.SuspendLayout();
34 | //
35 | // MapCtl
36 | //
37 | this.Name = "MapCtl";
38 | this.Paint += new System.Windows.Forms.PaintEventHandler(this.MapCtl_Paint);
39 | this.DoubleClick += new System.EventHandler(this.MapCtl_DoubleClick);
40 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MapCtl_KeyDown);
41 | this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MapCtl_KeyUp);
42 | this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MapCtl_MouseDown);
43 | this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MapCtl_MouseMove);
44 | this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.MapCtl_MouseUp);
45 | this.Resize += new System.EventHandler(this.MapCtl_Resize);
46 | this.ResumeLayout(false);
47 |
48 | }
49 |
50 | #endregion
51 |
52 | private System.Windows.Forms.ToolTip toolTip1;
53 |
54 |
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ExampleForms/Controls/MapCtl.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 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/ExampleForms/FrmMapDownloader.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.ExampleForms
2 | {
3 | partial class FrmMapDownloader
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.labelInfo = new System.Windows.Forms.Label();
32 | this.progressBar1 = new System.Windows.Forms.ProgressBar();
33 | this.btnCancel = new System.Windows.Forms.Button();
34 | this.label2 = new System.Windows.Forms.Label();
35 | this.labProceed = new System.Windows.Forms.Label();
36 | this.label3 = new System.Windows.Forms.Label();
37 | this.labTotal = new System.Windows.Forms.Label();
38 | this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
39 | this.SuspendLayout();
40 | //
41 | // labelInfo
42 | //
43 | this.labelInfo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
44 | | System.Windows.Forms.AnchorStyles.Right)));
45 | this.labelInfo.Location = new System.Drawing.Point(12, 13);
46 | this.labelInfo.Name = "labelInfo";
47 | this.labelInfo.Size = new System.Drawing.Size(487, 23);
48 | this.labelInfo.TabIndex = 0;
49 | this.labelInfo.Text = "Cache all map on local disk";
50 | //
51 | // progressBar1
52 | //
53 | this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
54 | | System.Windows.Forms.AnchorStyles.Right)));
55 | this.progressBar1.Location = new System.Drawing.Point(12, 39);
56 | this.progressBar1.Name = "progressBar1";
57 | this.progressBar1.Size = new System.Drawing.Size(487, 23);
58 | this.progressBar1.TabIndex = 1;
59 | this.progressBar1.Value = 20;
60 | //
61 | // btnCancel
62 | //
63 | this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
64 | | System.Windows.Forms.AnchorStyles.Right)));
65 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
66 | this.btnCancel.Location = new System.Drawing.Point(423, 102);
67 | this.btnCancel.Name = "btnCancel";
68 | this.btnCancel.Size = new System.Drawing.Size(75, 23);
69 | this.btnCancel.TabIndex = 2;
70 | this.btnCancel.Text = "Cancel";
71 | this.btnCancel.UseVisualStyleBackColor = true;
72 | //
73 | // label2
74 | //
75 | this.label2.AutoSize = true;
76 | this.label2.Location = new System.Drawing.Point(12, 69);
77 | this.label2.Name = "label2";
78 | this.label2.Size = new System.Drawing.Size(120, 13);
79 | this.label2.TabIndex = 3;
80 | this.label2.Text = "Proceed Block Number:";
81 | //
82 | // labProceed
83 | //
84 | this.labProceed.AutoSize = true;
85 | this.labProceed.Location = new System.Drawing.Point(139, 69);
86 | this.labProceed.Name = "labProceed";
87 | this.labProceed.Size = new System.Drawing.Size(14, 13);
88 | this.labProceed.TabIndex = 4;
89 | this.labProceed.Text = "~";
90 | //
91 | // label3
92 | //
93 | this.label3.AutoSize = true;
94 | this.label3.Location = new System.Drawing.Point(12, 94);
95 | this.label3.Name = "label3";
96 | this.label3.Size = new System.Drawing.Size(69, 13);
97 | this.label3.TabIndex = 5;
98 | this.label3.Text = "Total Blocks:";
99 | //
100 | // labTotal
101 | //
102 | this.labTotal.AutoSize = true;
103 | this.labTotal.Location = new System.Drawing.Point(139, 94);
104 | this.labTotal.Name = "labTotal";
105 | this.labTotal.Size = new System.Drawing.Size(14, 13);
106 | this.labTotal.TabIndex = 6;
107 | this.labTotal.Text = "~";
108 | //
109 | // saveFileDialog1
110 | //
111 | this.saveFileDialog1.DefaultExt = "PNG file (*.png)|*.png";
112 | this.saveFileDialog1.FileName = "SimpleMap.png";
113 | //
114 | // FrmMapDownloader
115 | //
116 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
117 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
118 | this.CancelButton = this.btnCancel;
119 | this.ClientSize = new System.Drawing.Size(511, 143);
120 | this.Controls.Add(this.labTotal);
121 | this.Controls.Add(this.label3);
122 | this.Controls.Add(this.labProceed);
123 | this.Controls.Add(this.label2);
124 | this.Controls.Add(this.btnCancel);
125 | this.Controls.Add(this.progressBar1);
126 | this.Controls.Add(this.labelInfo);
127 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
128 | this.MaximizeBox = false;
129 | this.MinimizeBox = false;
130 | this.Name = "FrmMapDownloader";
131 | this.Text = "Map Downloader";
132 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmMapDownloader_FormClosing);
133 | this.Load += new System.EventHandler(this.FrmMapDownloader_Load);
134 | this.ResumeLayout(false);
135 | this.PerformLayout();
136 |
137 | }
138 |
139 | #endregion
140 |
141 | private System.Windows.Forms.Label labelInfo;
142 | private System.Windows.Forms.ProgressBar progressBar1;
143 | private System.Windows.Forms.Button btnCancel;
144 | private System.Windows.Forms.Label label2;
145 | private System.Windows.Forms.Label labProceed;
146 | private System.Windows.Forms.Label label3;
147 | private System.Windows.Forms.Label labTotal;
148 | private System.Windows.Forms.SaveFileDialog saveFileDialog1;
149 | }
150 | }
--------------------------------------------------------------------------------
/ExampleForms/FrmMapDownloader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Imaging;
4 | using System.Globalization;
5 | using System.IO;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using System.Windows.Forms;
9 | using ProgramMain.Layers;
10 | using ProgramMain.Map;
11 | using ProgramMain.Map.Google;
12 | using ProgramMain.Framework;
13 | using PixelFormat = System.Drawing.Imaging.PixelFormat;
14 |
15 | namespace ProgramMain.ExampleForms
16 | {
17 | public partial class FrmMapDownloader : Form
18 | {
19 | private readonly CancellationTokenSource _tokenSource;
20 | private Task _mapTask;
21 |
22 | protected delegate void ProgressEventDelegate(int progress, int mapBlockNumber, int mapBlockCount);
23 |
24 | protected event ProgressEventDelegate ProgressEvent;
25 |
26 | protected delegate void SaveMapEventDelegate(Bitmap image);
27 |
28 | protected event SaveMapEventDelegate SaveMapEvent;
29 |
30 | private enum WorkMode
31 | {
32 | Download,
33 | SaveToImageFile
34 | };
35 |
36 | private WorkMode _workMode;
37 |
38 | private PixelFormat _mapPiFormat;
39 | private int _mapLevel;
40 |
41 | public static void DownloadMap()
42 | {
43 | var frm = new FrmMapDownloader
44 | {
45 | _workMode = WorkMode.Download,
46 | Text = @"Download Map",
47 | labelInfo = {Text = @"Cache all map on local disk"},
48 | };
49 | frm.ShowDialog();
50 | }
51 |
52 | public static void SaveMapAsImage(PixelFormat mapPiFormat, int mapLevel)
53 | {
54 | var frm = new FrmMapDownloader
55 | {
56 | _workMode = WorkMode.SaveToImageFile,
57 | _mapPiFormat = mapPiFormat,
58 | _mapLevel = mapLevel,
59 | Text = @"Save Map As Image",
60 | labelInfo = {Text = @"Save big map as one image"}
61 | };
62 |
63 | frm.ShowDialog();
64 | }
65 |
66 | private FrmMapDownloader()
67 | {
68 | InitializeComponent();
69 |
70 | _tokenSource = new CancellationTokenSource();
71 | ProgressEvent += OnProgress;
72 | SaveMapEvent += OnSaveMap;
73 | }
74 |
75 | private void FrmMapDownloader_Load(object sender, EventArgs e)
76 | {
77 | var token = _tokenSource.Token;
78 | switch (_workMode)
79 | {
80 | case WorkMode.Download:
81 | _mapTask = Task.Factory.StartNew(() => DownloadThread(token), token);
82 | break;
83 | case WorkMode.SaveToImageFile:
84 | _mapTask = Task.Factory.StartNew(() => GetFullMapThread(token), token);
85 | break;
86 | }
87 | }
88 |
89 | private void FrmMapDownloader_FormClosing(object sender, FormClosingEventArgs e)
90 | {
91 | _tokenSource.Cancel();
92 | Task.WaitAll(_mapTask);
93 | e.Cancel = false;
94 | }
95 |
96 | protected void OnProgress(int progress, int mapBlockNumber, int mapBlockCount)
97 | {
98 | if (progress > 100)
99 | {
100 | Close();
101 | return;
102 | }
103 | if (mapBlockNumber % 10 == 0 || progress >= 100)
104 | {
105 | progressBar1.Value = progress;
106 | labProceed.Text = mapBlockNumber.ToString(CultureInfo.InvariantCulture);
107 | labTotal.Text = mapBlockCount.ToString(CultureInfo.InvariantCulture);
108 | }
109 | }
110 |
111 | protected void OnSaveMap(Bitmap image)
112 | {
113 | try
114 | {
115 | if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
116 | {
117 | /*var palette = BitmapPalettes.Halftone256;
118 |
119 | var idxImage = new RenderTargetBitmap(
120 | image.Width,
121 | image.Height,
122 | Screen.PrimaryScreen.BitsPerPixel,
123 | Screen.PrimaryScreen.BitsPerPixel,
124 | PixelFormats.Indexed8);
125 | var visual = new DrawingVisual();
126 | var context = visual.RenderOpen();
127 | context.DrawImage(image, );
128 | idxImage.Render();
129 | Graphics.FromImage(idxImage);
130 |
131 | */
132 | {
133 | image.Save(saveFileDialog1.FileName, ImageFormat.Png);
134 | }
135 | }
136 | }
137 | finally
138 | {
139 | Close();
140 | }
141 | }
142 |
143 | private void DownloadThread(CancellationToken ct)
144 | {
145 | var leftBound = new Coordinate(Properties.Settings.Default.LeftMapBound, Properties.Settings.Default.TopMapBound);
146 | var rightBound = new Coordinate(Properties.Settings.Default.RightMapBound, Properties.Settings.Default.BottomMapBound);
147 |
148 | var rectBound = new CoordinateRectangle(leftBound, rightBound);
149 |
150 | var mapBlockCount = 0;
151 | for (var mapLevel = Properties.Settings.Default.MinZoomLevel; mapLevel <= Properties.Settings.Default.MaxZoomLevel; mapLevel++)
152 | {
153 | var mapWidth = Convert.ToInt32((new GoogleCoordinate(rectBound.RightTop, mapLevel)).X - (new GoogleCoordinate(rectBound.LeftTop, mapLevel)).X) + 2 * GoogleBlock.BlockSize;
154 | var mapHeight = Convert.ToInt32((new GoogleCoordinate(rectBound.LeftBottom, mapLevel)).Y - (new GoogleCoordinate(rectBound.LeftTop, mapLevel)).Y) + 2 * GoogleBlock.BlockSize;
155 |
156 | var viewBound = rectBound.LineMiddlePoint.GetScreenViewFromCenter(mapWidth, mapHeight, mapLevel);
157 | var blockView = viewBound.BlockView;
158 | mapBlockCount += (blockView.Right - blockView.Left + 1) * (blockView.Bottom - blockView.Top + 1);
159 | }
160 |
161 | var mapBlockNumber = 0;
162 | BeginInvoke(ProgressEvent, new Object[] {mapBlockNumber * 100 / mapBlockCount, mapBlockNumber, mapBlockCount});
163 |
164 | for (var mapLevel = Properties.Settings.Default.MinZoomLevel; mapLevel <= Properties.Settings.Default.MaxZoomLevel; mapLevel++)
165 | {
166 | var mapWidth = Convert.ToInt32((new GoogleCoordinate(rectBound.RightTop, mapLevel)).X - (new GoogleCoordinate(rectBound.LeftTop, mapLevel)).X) + 2 * GoogleBlock.BlockSize;
167 | var mapHeight = Convert.ToInt32((new GoogleCoordinate(rectBound.LeftBottom, mapLevel)).Y - (new GoogleCoordinate(rectBound.LeftTop, mapLevel)).Y) + 2 * GoogleBlock.BlockSize;
168 |
169 | var viewBound = rectBound.LineMiddlePoint.GetScreenViewFromCenter(mapWidth, mapHeight, mapLevel);
170 | var blockView = viewBound.BlockView;
171 |
172 | for (var x = blockView.Left; x <= blockView.Right; x++)
173 | {
174 | for (var y = blockView.Top; y <= blockView.Bottom; y++)
175 | {
176 | var block = new GoogleBlock(x, y, mapLevel);
177 |
178 | var fileName = Properties.Settings.GetMapFileName(block);
179 | if (!File.Exists(fileName))
180 | MapLayer.DownloadImageFromGoogle(block, false);
181 |
182 | mapBlockNumber++;
183 |
184 | BeginInvoke(ProgressEvent, new Object[] {mapBlockNumber * 100 / mapBlockCount, mapBlockNumber, mapBlockCount});
185 |
186 | if (ct.IsCancellationRequested)
187 | return;
188 | }
189 | }
190 | }
191 | BeginInvoke(ProgressEvent, new Object[] {101, mapBlockNumber, mapBlockCount});
192 | }
193 |
194 | private void GetFullMapThread(CancellationToken ct)
195 | {
196 | var leftBound = new Coordinate(Properties.Settings.Default.LeftMapBound, Properties.Settings.Default.TopMapBound);
197 | var rightBound = new Coordinate(Properties.Settings.Default.RightMapBound, Properties.Settings.Default.BottomMapBound);
198 |
199 | var rectBound = new CoordinateRectangle(leftBound, rightBound);
200 |
201 | try
202 | {
203 | var mapWidth = Convert.ToInt32((new GoogleCoordinate(rectBound.RightTop, _mapLevel)).X - (new GoogleCoordinate(rectBound.LeftTop, _mapLevel)).X) + 2 * GoogleBlock.BlockSize;
204 | var mapHeight = Convert.ToInt32((new GoogleCoordinate(rectBound.LeftBottom, _mapLevel)).Y - (new GoogleCoordinate(rectBound.LeftTop, _mapLevel)).Y) + 2 * GoogleBlock.BlockSize;
205 |
206 | var image = GraphicLayer.CreateCompatibleBitmap(null, mapWidth, mapHeight, _mapPiFormat);
207 | var graphics = Graphics.FromImage(image);
208 |
209 | var viewBound = rectBound.LineMiddlePoint.GetScreenViewFromCenter(mapWidth, mapHeight, _mapLevel);
210 | var blockView = viewBound.BlockView;
211 | var mapBlockCount = (blockView.Right - blockView.Left + 1) * (blockView.Bottom - blockView.Top + 1);
212 | var mapBlockNumber = 0;
213 |
214 | BeginInvoke(ProgressEvent, new Object[] {mapBlockNumber * 100 / mapBlockCount, mapBlockNumber, mapBlockCount});
215 |
216 | for (var x = blockView.Left; x <= blockView.Right; x++)
217 | {
218 | for (var y = blockView.Top; y <= blockView.Bottom; y++)
219 | {
220 | var block = new GoogleBlock(x, y, _mapLevel);
221 | var bmp = GraphicLayer.CreateCompatibleBitmap(
222 | MapLayer.DownloadImageFromFile(block) ?? MapLayer.DownloadImageFromGoogle(block, true),
223 | GoogleBlock.BlockSize, GoogleBlock.BlockSize, _mapPiFormat);
224 |
225 | var rect = ((GoogleRectangle) block).GetScreenRect(viewBound);
226 | graphics.DrawImageUnscaled(bmp, rect.Location.X, rect.Location.Y);
227 |
228 | mapBlockNumber++;
229 |
230 | BeginInvoke(ProgressEvent, new Object[]{mapBlockNumber * 100 / mapBlockCount, mapBlockNumber, mapBlockCount});
231 |
232 | if (ct.IsCancellationRequested)
233 | return;
234 | }
235 | }
236 |
237 | BeginInvoke(SaveMapEvent, new Object[] {image});
238 | }
239 | catch (Exception e)
240 | {
241 | BeginInvoke(ProgressEvent, new Object[] { 101, 0, 0 });
242 | MessageBox.Show(e.Message, @"Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
243 | }
244 | }
245 | }
246 | }
247 |
--------------------------------------------------------------------------------
/ExampleForms/FrmMapDownloader.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 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/ExampleForms/FrmOpticMap.Designer.cs:
--------------------------------------------------------------------------------
1 | using ProgramMain.ExampleForms.Controls;
2 |
3 | namespace ProgramMain.ExampleForms
4 | {
5 | partial class FrmOpticMap
6 | {
7 | ///
8 | /// Required designer variable.
9 | ///
10 | private System.ComponentModel.IContainer components = null;
11 |
12 | ///
13 | /// Clean up any resources being used.
14 | ///
15 | /// true if managed resources should be disposed; otherwise, false.
16 | protected override void Dispose(bool disposing)
17 | {
18 | if (disposing && (components != null))
19 | {
20 | components.Dispose();
21 | }
22 | base.Dispose(disposing);
23 | }
24 |
25 | #region Windows Form Designer generated code
26 |
27 | ///
28 | /// Required method for Designer support - do not modify
29 | /// the contents of this method with the code editor.
30 | ///
31 | private void InitializeComponent()
32 | {
33 | this.printDocument1 = new System.Drawing.Printing.PrintDocument();
34 | this.printDialog1 = new System.Windows.Forms.PrintDialog();
35 | this.mapCtl1 = new MapCtl();
36 | this.buttonPanelCtl1 = new ButtonPanelCtl();
37 | this.SuspendLayout();
38 | //
39 | // printDocument1
40 | //
41 | this.printDocument1.DocumentName = "Simple Map";
42 | this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.Document_PrintPage);
43 | //
44 | // printDialog1
45 | //
46 | this.printDialog1.Document = this.printDocument1;
47 | this.printDialog1.UseEXDialog = true;
48 | //
49 | // mapCtl1
50 | //
51 | this.mapCtl1.AllowDrop = true;
52 | this.mapCtl1.Dock = System.Windows.Forms.DockStyle.Fill;
53 | this.mapCtl1.Level = 13;
54 | this.mapCtl1.Location = new System.Drawing.Point(0, 38);
55 | this.mapCtl1.Name = "mapCtl1";
56 | this.mapCtl1.Size = new System.Drawing.Size(680, 426);
57 | this.mapCtl1.TabIndex = 0;
58 | this.mapCtl1.LevelValueChanged += new System.EventHandler(this.mapCtl1_LevelValueChanged);
59 | //
60 | // buttonPanelCtl1
61 | //
62 | this.buttonPanelCtl1.Dock = System.Windows.Forms.DockStyle.Top;
63 | this.buttonPanelCtl1.Level = 12;
64 | this.buttonPanelCtl1.Location = new System.Drawing.Point(0, 0);
65 | this.buttonPanelCtl1.MaximumSize = new System.Drawing.Size(2000, 38);
66 | this.buttonPanelCtl1.MinimumSize = new System.Drawing.Size(350, 38);
67 | this.buttonPanelCtl1.Name = "buttonPanelCtl1";
68 | this.buttonPanelCtl1.Size = new System.Drawing.Size(680, 38);
69 | this.buttonPanelCtl1.TabIndex = 1;
70 | this.buttonPanelCtl1.LevelValueChanged += new System.EventHandler(this.buttonPanelCtl1_LevelValueChanged);
71 | this.buttonPanelCtl1.CenterMapClicked += new System.EventHandler(this.buttonPanelCtl1_CenterMapClicked);
72 | this.buttonPanelCtl1.PrintMapClicked += new System.EventHandler(this.buttonPanelCtl1_PrintMapClicked);
73 | this.buttonPanelCtl1.RefreshMapClicked += new System.EventHandler(this.buttonPanelCtl1_RefreshMapClicked);
74 | this.buttonPanelCtl1.SaveAllMapClicked += new System.EventHandler(this.buttonPanelCtl1_SaveAllMapClicked);
75 | this.buttonPanelCtl1.SaveMapAsImageClicked += new System.EventHandler(this.buttonPanelCtl1_SaveMapAsImageClicked);
76 | //
77 | // FrmOpticMap
78 | //
79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
81 | this.ClientSize = new System.Drawing.Size(680, 464);
82 | this.Controls.Add(this.mapCtl1);
83 | this.Controls.Add(this.buttonPanelCtl1);
84 | this.DoubleBuffered = true;
85 | this.Name = "FrmOpticMap";
86 | this.Text = "Map";
87 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmOpticMap_FormClosing);
88 | this.Load += new System.EventHandler(this.FrmOpticMap_Load);
89 | this.ResumeLayout(false);
90 |
91 | }
92 |
93 | #endregion
94 |
95 | private MapCtl mapCtl1;
96 | private ButtonPanelCtl buttonPanelCtl1;
97 | private System.Drawing.Printing.PrintDocument printDocument1;
98 | private System.Windows.Forms.PrintDialog printDialog1;
99 | }
100 | }
--------------------------------------------------------------------------------
/ExampleForms/FrmOpticMap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Drawing2D;
4 | using System.Windows.Forms;
5 | using ProgramMain.ExampleForms.Controls;
6 |
7 | namespace ProgramMain.ExampleForms
8 | {
9 | public partial class FrmOpticMap : Form
10 | {
11 | public FrmOpticMap()
12 | {
13 | InitializeComponent();
14 |
15 | Icon = Miscellaneous.DefaultIcon();
16 | }
17 |
18 | //protected override CreateParams CreateParams
19 | //{
20 | // get
21 | // {
22 | // var handleParam = base.CreateParams;
23 | // handleParam.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
24 | // return handleParam;
25 | // }
26 | //}
27 |
28 | protected override void OnResizeBegin(EventArgs e)
29 | {
30 | SuspendLayout();
31 | base.OnResizeBegin(e);
32 | }
33 |
34 | protected override void OnResizeEnd(EventArgs e)
35 | {
36 | ResumeLayout();
37 | base.OnResizeEnd(e);
38 | }
39 |
40 | private void FrmOpticMap_Load(object sender, EventArgs e)
41 | {
42 | Text = Miscellaneous.GetAssemblyTitle();
43 | }
44 |
45 | private void FrmOpticMap_FormClosing(object sender, FormClosingEventArgs e)
46 | {
47 | mapCtl1.ControlClosing();
48 | }
49 |
50 | public void RefreshForm()
51 | {
52 | mapCtl1.RefreshControl();
53 | }
54 |
55 | public void SetCenterMapObject(decimal longitude, decimal latitude)
56 | {
57 | mapCtl1.MoveCenterMapObject(longitude, latitude);
58 | }
59 |
60 | private void buttonPanelCtl1_RefreshMapClicked(object sender, EventArgs e)
61 | {
62 | RefreshForm();
63 | }
64 |
65 | private void buttonPanelCtl1_LevelValueChanged(object sender, ButtonPanelCtl.LevelValueArgs e)
66 | {
67 | mapCtl1.Level = e.Level;
68 | }
69 |
70 | private void buttonPanelCtl1_CenterMapClicked(object sender, EventArgs e)
71 | {
72 | mapCtl1.SetCenterMap();
73 | }
74 |
75 | public int Level
76 | {
77 | set { buttonPanelCtl1.Level = value; }
78 | }
79 |
80 | private void mapCtl1_LevelValueChanged(object sender, ButtonPanelCtl.LevelValueArgs e)
81 | {
82 | buttonPanelCtl1.Level = e.Level;
83 | }
84 |
85 |
86 | private void buttonPanelCtl1_PrintMapClicked(object sender, EventArgs e)
87 | {
88 | if (printDialog1.ShowDialog() == DialogResult.OK)
89 | printDocument1.Print();
90 | }
91 |
92 | void Document_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
93 | {
94 | e.HasMorePages = false;
95 | e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
96 | try
97 | {
98 | var imageMap = mapCtl1.GetMapImageForPrint();
99 | var printSize = e.PageBounds.Size;
100 | var k1 = (double)imageMap.Width / printSize.Width;
101 | var k2 = (double)imageMap.Height / printSize.Height;
102 | var k = (k1 > k2) ? k1 : k2;
103 | var newSize = new Size((int)(imageMap.Size.Width / k), (int)(imageMap.Size.Height / k));
104 |
105 | var screnCenter = new Point(printSize.Width / 2, printSize.Height / 2);
106 | var mapCenter = new Point(newSize.Width / 2, newSize.Height / 2);
107 | var shift = new Size(screnCenter.X - mapCenter.X, screnCenter.Y - mapCenter.Y);
108 | var p = new Point(0, 0) + shift;
109 |
110 | var rectangle = new Rectangle(p, newSize);
111 | e.Graphics.DrawImage(imageMap, rectangle);
112 | }
113 | catch (Exception ex)
114 | {
115 | //do nothing
116 | System.Diagnostics.Trace.WriteLine(ex.Message);
117 | }
118 | }
119 |
120 | private void buttonPanelCtl1_SaveAllMapClicked(object sender, EventArgs e)
121 | {
122 | FrmMapDownloader.DownloadMap();
123 | }
124 |
125 | private void buttonPanelCtl1_SaveMapAsImageClicked(object sender, EventArgs e)
126 | {
127 | FrmMapDownloader.SaveMapAsImage(mapCtl1.PiFormat, mapCtl1.Level);
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/ExampleForms/FrmOpticMap.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 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 158, 17
125 |
126 |
--------------------------------------------------------------------------------
/ExampleForms/Miscellaneous.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | namespace ProgramMain.ExampleForms
4 | {
5 | public static class Miscellaneous
6 | {
7 | public static System.Drawing.Icon DefaultIcon()
8 | {
9 | return System.Drawing.Icon.ExtractAssociatedIcon(Application.ExecutablePath);
10 | }
11 |
12 | public static string GetAssemblyTitle()
13 | {
14 | var aTitle = @"Simple Map";
15 | var thisAssembly = Program.MainForm.GetType().Assembly;
16 | var attributes = thisAssembly.GetCustomAttributes(typeof(System.Reflection.AssemblyTitleAttribute), false);
17 | if (attributes.Length == 1)
18 | {
19 | aTitle = ((System.Reflection.AssemblyTitleAttribute) attributes[0]).Title;
20 | }
21 | return aTitle;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Framework/ExternalHelpers.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace ProgramMain.Framework
4 | {
5 | public static class ExternalHelpers
6 | {
7 |
8 | public static object Clone(this Rectangle src)
9 | {
10 | return new Rectangle(src.Location, src.Size);
11 | }
12 |
13 | public static bool Contains(this Point pt, Rectangle rect)
14 | {
15 | return pt.X >= rect.Left && pt.X <= rect.Right
16 | && pt.Y >= rect.Top && pt.Y <= rect.Bottom;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Framework/WorkerThread/Types/EventPriorityType.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.Framework.WorkerThread.Types
2 | {
3 | public enum EventPriorityType { Idle = 0, Low = 1, BelowNormal = 2, Normal = 3, AboveNormal = 4, High = 5, Critical = 6 };
4 | }
--------------------------------------------------------------------------------
/Framework/WorkerThread/Types/EventPriorityTypeConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProgramMain.Framework.WorkerThread.Types
4 | {
5 | public static class EventPriorityTypeConverter
6 | {
7 | public static Array EventPriorityValues = null;
8 | public static Array EventPriorityEnum
9 | {
10 | get
11 | {
12 | return EventPriorityValues ?? (EventPriorityValues = Enum.GetValues(typeof (EventPriorityType)));
13 | }
14 | }
15 |
16 | public static int Length
17 | {
18 | get
19 | {
20 | return EventPriorityEnum.Length;
21 | }
22 | }
23 |
24 | public static EventPriorityType ToEventPriorityType(this Int32 i)
25 | {
26 | if (i >= 0 && i < EventPriorityEnum.Length)
27 | return (EventPriorityType)Convert.ChangeType(EventPriorityEnum.GetValue(i), typeof(EventPriorityType));
28 |
29 | return EventPriorityType.Idle;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Framework/WorkerThread/Types/MainThreadEventArgs.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.Framework.WorkerThread.Types
2 | {
3 | public class MainThreadEventArgs
4 | {
5 | // Summary:
6 | // Represents an event with no event data.
7 | public static readonly MainThreadEventArgs Empty = new MainThreadEventArgs();
8 |
9 | public delegate void MainThreadEventHandler(object sender, T e) where T : MainThreadEventArgs;
10 |
11 | public delegate void DelegateToMainThread(T eventParams) where T : MainThreadEventArgs;
12 | }
13 | }
--------------------------------------------------------------------------------
/Framework/WorkerThread/Types/WorkerEventType.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.Framework.WorkerThread.Types
2 | {
3 | public enum WorkerEventType { None, RedrawLayer, DownloadImage, DrawImage, ReloadData, AddDbObject };
4 | }
--------------------------------------------------------------------------------
/Framework/WorkerThread/WorkerEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ProgramMain.Framework.WorkerThread.Types;
3 |
4 | namespace ProgramMain.Framework.WorkerThread
5 | {
6 | public class WorkerEvent : IComparable
7 | {
8 | // Summary:
9 | // Represents an event with no event data.
10 | public static readonly WorkerEvent Empty = new WorkerEvent();
11 |
12 | private readonly WorkerEventType _eventType = WorkerEventType.None;
13 | public WorkerEventType EventType
14 | {
15 | get
16 | {
17 | return _eventType;
18 | }
19 | }
20 |
21 | private readonly EventPriorityType _eventPriority = EventPriorityType.Normal;
22 | public EventPriorityType EventPriority
23 | {
24 | get
25 | {
26 | return _eventPriority;
27 | }
28 | }
29 |
30 | private readonly bool _collapsible;
31 | public bool IsCollapsible
32 | {
33 | get
34 | {
35 | return _collapsible;
36 | }
37 | }
38 |
39 | private WorkerEvent()
40 | {
41 | _collapsible = false;
42 | }
43 |
44 | public WorkerEvent(WorkerEventType pEventType)
45 | {
46 | _eventType = pEventType;
47 | _collapsible = false;
48 | _eventPriority = EventPriorityType.Normal;
49 | }
50 |
51 | public WorkerEvent(WorkerEventType pEventType, bool pIsCollapsible)
52 | {
53 | _eventType = pEventType;
54 | _collapsible = pIsCollapsible;
55 | _eventPriority = EventPriorityType.Normal;
56 | }
57 |
58 | public WorkerEvent(WorkerEventType pEventType, bool pIsCollapsible, EventPriorityType pPriorityType)
59 | {
60 | _eventType = pEventType;
61 | _collapsible = pIsCollapsible;
62 | _eventPriority = pPriorityType;
63 | }
64 |
65 | virtual public int CompareTo(object obj)
66 | {
67 | if (obj != null)
68 | {
69 | if (((WorkerEvent)obj)._eventType > EventType)
70 | return 1;
71 | if (((WorkerEvent)obj)._eventType < EventType)
72 | return -1;
73 |
74 | return 0;
75 | }
76 | return -1;
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/Framework/WorkerThread/WorkerMessageThread.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Framework/WorkerThread/WorkerMessageThread.cs
--------------------------------------------------------------------------------
/Layers/MapLayer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Net;
5 | using System.Drawing;
6 | using ProgramMain.Framework;
7 | using ProgramMain.Framework.WorkerThread;
8 | using ProgramMain.Framework.WorkerThread.Types;
9 | using ProgramMain.Map;
10 | using ProgramMain.Map.Google;
11 |
12 | namespace ProgramMain.Layers
13 | {
14 | public class MapLayer : GraphicLayer
15 | {
16 | private const int MaxCacheSize = 240;
17 |
18 | private Rectangle _blockView;
19 | private readonly Bitmap _emptyBlock;
20 |
21 | protected class MapWorkerEvent : WorkerEvent
22 | {
23 | public GoogleBlock Block;
24 |
25 | public MapWorkerEvent(WorkerEventType eventType, GoogleBlock block, EventPriorityType priorityType)
26 | : base(eventType, true, priorityType)
27 | {
28 | Block = block;
29 | }
30 |
31 | override public int CompareTo(object obj)
32 | {
33 | var res = base.CompareTo(obj);
34 | if (res == 0)
35 | {
36 | if (obj != null)
37 | {
38 | res = ((MapWorkerEvent) obj).Block.CompareTo(Block);
39 | }
40 | else
41 | {
42 | res = -1;
43 | }
44 | }
45 | return res;
46 | }
47 | }
48 |
49 | private struct MapCacheItem
50 | {
51 | public long Timestamp;
52 | public Bitmap Bmp;
53 | };
54 |
55 | private static readonly SortedDictionary MapCache = new SortedDictionary();
56 |
57 | public MapLayer(int width, int height, Coordinate centerCoordinate, int level)
58 | : base(width, height, centerCoordinate, level)
59 | {
60 | _emptyBlock = CreateCompatibleBitmap(null, GoogleBlock.BlockSize, GoogleBlock.BlockSize, PiFormat);
61 | }
62 |
63 | override protected void TranslateCoords()
64 | {
65 | base.TranslateCoords();
66 |
67 | _blockView = ScreenView.BlockView;
68 | }
69 |
70 | private void PutMapThreadEvent(WorkerEventType eventType, GoogleBlock block, EventPriorityType priorityType)
71 | {
72 | PutWorkerThreadEvent(new MapWorkerEvent(eventType, block, priorityType));
73 | }
74 |
75 | override protected void DrawLayer(Rectangle clipRectangle)
76 | {
77 | try
78 | {
79 | SwapDrawBuffer();
80 |
81 | Rectangle localBlockView;
82 | GoogleRectangle localScreenView;
83 | do
84 | {
85 | DropWorkerThreadEvents(WorkerEventType.RedrawLayer);
86 |
87 | localBlockView = (Rectangle) _blockView.Clone();
88 | localScreenView = (GoogleRectangle) ScreenView.Clone();
89 | }
90 | while (DrawImages(localBlockView, localScreenView) == false);
91 | }
92 | finally
93 | {
94 | SwapDrawBuffer();
95 | }
96 | FireIvalidateLayer(clipRectangle);
97 | }
98 |
99 | private bool DrawImages(Rectangle localBlockView, GoogleRectangle localScreenView)
100 | {
101 | for (var x = localBlockView.Left; x <= localBlockView.Right; x++)
102 | {
103 | for (var y = localBlockView.Top; y <= localBlockView.Bottom; y++)
104 | {
105 | var block = new GoogleBlock(x, y, Level);
106 | var pt = ((GoogleCoordinate)block).GetScreenPoint(localScreenView);
107 |
108 | var bmp = FindImage(block);
109 | if (bmp != null)
110 | {
111 | DrawBitmap(bmp, pt);
112 | }
113 | else
114 | {
115 | DrawBitmap(_emptyBlock, pt);
116 | PutMapThreadEvent(WorkerEventType.DownloadImage, block, EventPriorityType.Idle);
117 | }
118 |
119 | if (Terminating) return true;
120 |
121 | if (localScreenView.CompareTo(ScreenView) != 0) return false;
122 | }
123 | }
124 | return true;
125 | }
126 |
127 | private void DrawImage(GoogleBlock block)
128 | {
129 | if (Terminating) return;
130 |
131 | if (block.Level == Level && block.Pt.Contains(_blockView))
132 | {
133 | var bmp = FindImage(block);
134 | if (bmp != null)
135 | {
136 | var rect = ((GoogleRectangle)block).GetScreenRect(ScreenView);
137 | DrawBitmap(bmp, rect.Location);
138 |
139 | FireIvalidateLayer(rect);
140 | }
141 | }
142 | }
143 |
144 | private static Bitmap FindImage(GoogleBlock block)
145 | {
146 | if (MapCache.ContainsKey(block))
147 | {
148 | var dimg = MapCache[block];
149 | dimg.Timestamp = DateTime.Now.Ticks;
150 | return dimg.Bmp;
151 | }
152 | return null;
153 | }
154 |
155 | protected override bool SetCenterCoordinate(Coordinate center, int level)
156 | {
157 | var res = base.SetCenterCoordinate(center, level);
158 |
159 | if (res)
160 | DropWorkerThreadEvents(WorkerEventType.DownloadImage);
161 |
162 | return res;
163 | }
164 |
165 | protected override bool DispatchThreadEvents(WorkerEvent workerEvent)
166 | {
167 | var res = base.DispatchThreadEvents(workerEvent);
168 |
169 | if (!res && workerEvent is MapWorkerEvent)
170 | {
171 | switch (workerEvent.EventType)
172 | {
173 | case WorkerEventType.DownloadImage:
174 | {
175 | DownloadImage(((MapWorkerEvent)workerEvent).Block);
176 | return true;
177 | }
178 | case WorkerEventType.DrawImage:
179 | {
180 | DrawImage(((MapWorkerEvent)workerEvent).Block);
181 | return true;
182 | }
183 | }
184 | }
185 |
186 | return res;
187 | }
188 |
189 | private void DownloadImage(GoogleBlock block)
190 | {
191 | if (MapCache.ContainsKey(block))
192 | {
193 | var dimg = MapCache[block];
194 | if (dimg.Bmp != null) //to turn off compile warning
195 | {
196 | dimg.Timestamp = DateTime.Now.Ticks;
197 | }
198 | }
199 | else
200 | {
201 | var bmp = DownloadImageFromFile(block) ?? DownloadImageFromGoogle(block, true);
202 |
203 | if (bmp != null)
204 | {
205 | bmp = CreateCompatibleBitmap(bmp, GoogleBlock.BlockSize, GoogleBlock.BlockSize, PiFormat);
206 |
207 | var dimg = new MapCacheItem { Timestamp = DateTime.Now.Ticks, Bmp = bmp };
208 | MapCache[block] = dimg;
209 |
210 | TruncateImageCache(block);
211 |
212 | PutMapThreadEvent(WorkerEventType.DrawImage, block, EventPriorityType.Low);
213 | }
214 | }
215 | }
216 |
217 | private void TruncateImageCache(GoogleBlock newCacheItem)
218 | {
219 | while (MapCache.Count > MaxCacheSize)
220 | {
221 | var mt = GoogleBlock.Empty;
222 | var lTicks = DateTime.Now.Ticks;
223 |
224 | foreach (var lt in MapCache)
225 | {
226 | if (lt.Value.Timestamp < lTicks && lt.Key.CompareTo(newCacheItem) != 0)
227 | {
228 | mt = lt.Key;
229 | lTicks = lt.Value.Timestamp;
230 | }
231 | }
232 |
233 | if (mt != GoogleBlock.Empty)
234 | MapCache.Remove(mt);
235 | }
236 | }
237 |
238 | public static Bitmap DownloadImageFromGoogle(GoogleBlock block, bool getBitmap)
239 | {
240 | try
241 | {
242 | var oRequest = GoogleMapUtilities.CreateGoogleWebRequest(block);
243 | var oResponse = (HttpWebResponse) oRequest.GetResponse();
244 |
245 | var bmpStream = new MemoryStream();
246 | var oStream = oResponse.GetResponseStream();
247 | if (oStream != null) oStream.CopyTo(bmpStream);
248 | oResponse.Close();
249 | if (bmpStream.Length > 0)
250 | {
251 | WriteImageToFile(block, bmpStream);
252 | return getBitmap ? (Bitmap) Image.FromStream(bmpStream) : null;
253 | }
254 | }
255 | catch (Exception ex)
256 | {
257 | //do nothing
258 | System.Diagnostics.Trace.WriteLine(ex.Message);
259 | }
260 | return null;
261 | }
262 |
263 | public static Bitmap DownloadImageFromFile(GoogleBlock block)
264 | {
265 | try
266 | {
267 | var fileName = Properties.Settings.GetMapFileName(block);
268 | if (File.Exists(fileName))
269 | {
270 | var bmp = (Bitmap)Image.FromFile(fileName);
271 | return bmp;
272 | }
273 | }
274 | catch (Exception ex)
275 | {
276 | //do nothing
277 | System.Diagnostics.Trace.WriteLine(ex.Message);
278 | }
279 | return null;
280 | }
281 |
282 | private static void WriteImageToFile(GoogleBlock block, Stream bmpStream)
283 | {
284 | var fileName = Properties.Settings.GetMapFileName(block);
285 | try
286 | {
287 | if (!File.Exists(fileName))
288 | {
289 | var path = Path.GetDirectoryName(fileName) ?? "";
290 | var destdir = new DirectoryInfo(path);
291 | if (!destdir.Exists)
292 | {
293 | destdir.Create();
294 | }
295 | var fileStream = File.Create(fileName);
296 | try
297 | {
298 | bmpStream.Seek(0, SeekOrigin.Begin);
299 | bmpStream.CopyTo(fileStream);
300 | }
301 | finally
302 | {
303 | fileStream.Flush();
304 | fileStream.Close();
305 | }
306 | }
307 | }
308 | catch (Exception ex)
309 | {
310 | //do nothing
311 | System.Diagnostics.Trace.WriteLine(ex.Message);
312 | }
313 | }
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/Layers/MapObjects/BuildingTree.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using System.Threading.Tasks;
3 | using ProgramMain.ExampleDb;
4 | using ProgramMain.Layers.MapObjects.TreeNodes;
5 | using ProgramMain.Map.Spatial;
6 | using ProgramMain.Map.Spatial.Types;
7 |
8 | namespace ProgramMain.Layers.MapObjects
9 | {
10 | public class BuildingTree : SpatialTree
11 | {
12 | public SimpleMapDb.BuildingsDataTable BuildingDbRows { get; private set; }
13 |
14 | public BuildingTree()
15 | : base(SpatialSheetPowerTypes.Ultra, SpatialSheetPowerTypes.Extra, SpatialSheetPowerTypes.Medium, SpatialSheetPowerTypes.Low)
16 | {
17 | BuildingDbRows = new SimpleMapDb.BuildingsDataTable();
18 | }
19 |
20 | protected void Insert(SimpleMapDb.BuildingsRow row)
21 | {
22 | base.Insert(row);
23 | }
24 |
25 | protected void Delete(SimpleMapDb.BuildingsRow row)
26 | {
27 | base.Delete(row);
28 | }
29 |
30 | public void LoadData()
31 | {
32 | Clear();
33 |
34 | //read data from db here
35 |
36 | Parallel.ForEach(BuildingDbRows, Insert);
37 | }
38 |
39 | public void MergeData(SimpleMapDb.BuildingsDataTable buildings)
40 | {
41 | if (BuildingDbRows == null) return;
42 |
43 | BuildingDbRows.Merge(buildings, false, MissingSchemaAction.Error);
44 |
45 | Parallel.ForEach(buildings, row =>
46 | {
47 | var newRow = BuildingDbRows.FindByID(row.ID);
48 | Insert(newRow);
49 | });
50 | //apply changes to db here
51 | }
52 |
53 | public bool RemoveBuilding(int objectId)
54 | {
55 | var row = (BuildingDbRows == null) ? null : BuildingDbRows.FindByID(objectId);
56 | if (row != null)
57 | {
58 | Delete(row);
59 |
60 | BuildingDbRows.Rows.Remove(row);
61 | //apply changes to db here
62 |
63 | return true;
64 | }
65 | return false;
66 | }
67 |
68 | public SimpleMapDb.BuildingsRow GetBuilding(int objectId)
69 | {
70 | if (BuildingDbRows == null) return null;
71 |
72 | var row = BuildingDbRows.FindByID(objectId);
73 | if (row != null)
74 | {
75 | var dt = (SimpleMapDb.BuildingsDataTable)BuildingDbRows.Clone();
76 | dt.ImportRow(row);
77 | return (SimpleMapDb.BuildingsRow)dt.Rows[0];
78 | }
79 | return null;
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Layers/MapObjects/CableTree.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using System.Threading.Tasks;
3 | using ProgramMain.ExampleDb;
4 | using ProgramMain.Layers.MapObjects.TreeNodes;
5 | using ProgramMain.Map.Spatial;
6 | using ProgramMain.Map.Spatial.Types;
7 |
8 | namespace ProgramMain.Layers.MapObjects
9 | {
10 | public class CableTree : SpatialTree
11 | {
12 | public SimpleMapDb.CablesDataTable CableDbRows { get; private set; }
13 |
14 | public CableTree()
15 | : base(SpatialSheetPowerTypes.Ultra, SpatialSheetPowerTypes.High, SpatialSheetPowerTypes.Low, SpatialSheetPowerTypes.Low)
16 | {
17 | CableDbRows = new SimpleMapDb.CablesDataTable();
18 | }
19 |
20 | protected void Insert(SimpleMapDb.CablesRow row)
21 | {
22 | base.Insert(row);
23 | }
24 |
25 | protected void Delete(SimpleMapDb.CablesRow row)
26 | {
27 | base.Delete(row);
28 | }
29 |
30 | public void LoadData()
31 | {
32 | Clear();
33 |
34 | //read data from db here
35 |
36 | Parallel.ForEach(CableDbRows, Insert);
37 | }
38 |
39 | public void MergeData(SimpleMapDb.CablesDataTable cables)
40 | {
41 | if (CableDbRows == null) return;
42 |
43 | CableDbRows.Merge(cables, false, MissingSchemaAction.Error);
44 |
45 | Parallel.ForEach(cables, row =>
46 | {
47 | var newRow = CableDbRows.FindByID(row.ID);
48 | Insert(newRow);
49 | });
50 |
51 | //apply changes to db here
52 | }
53 |
54 | public bool RemoveCable(int objectId)
55 | {
56 | var row = (CableDbRows == null) ? null : CableDbRows.FindByID(objectId);
57 | if (row != null)
58 | {
59 | Delete(row);
60 |
61 | CableDbRows.Rows.Remove(row);
62 | //apply changes to db here
63 |
64 | return true;
65 | }
66 | return false;
67 | }
68 |
69 | public SimpleMapDb.CablesRow GetCable(int objectId)
70 | {
71 | if (CableDbRows == null) return null;
72 |
73 | var row = CableDbRows.FindByID(objectId);
74 | if (row != null)
75 | {
76 | var dt = (SimpleMapDb.CablesDataTable)CableDbRows.Clone();
77 | dt.ImportRow(row);
78 | return (SimpleMapDb.CablesRow)dt.Rows[0];
79 | }
80 | return null;
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Layers/MapObjects/TreeNodes/BuildingNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 | using ProgramMain.ExampleDb;
4 | using ProgramMain.Map;
5 | using ProgramMain.Map.Spatial.Types;
6 |
7 | namespace ProgramMain.Layers.MapObjects.TreeNodes
8 | {
9 | public class BuildingNode : ISpatialTreeNode
10 | {
11 | private readonly SimpleMapDb.BuildingsRow _row;
12 |
13 | public SpatialTreeNodeTypes NodeType
14 | {
15 | get { return SpatialTreeNodeTypes.Rectangle; }
16 | }
17 |
18 | public Coordinate Coordinate
19 | {
20 | get { throw new Exception(); }
21 | }
22 |
23 | public CoordinateRectangle Rectangle
24 | {
25 | get
26 | {
27 | return new CoordinateRectangle(
28 | _row.Longitude1,
29 | _row.Latitude1,
30 | _row.Longitude2,
31 | _row.Latitude2);
32 | }
33 | }
34 |
35 | public CoordinatePoligon Poligon
36 | {
37 | get { throw new Exception(); }
38 | }
39 |
40 | public int RowId
41 | {
42 | get { return _row.ID; }
43 | }
44 |
45 | internal BuildingNode(SimpleMapDb.BuildingsRow row)
46 | {
47 | _row = row;
48 | }
49 |
50 | public DataRow Row
51 | {
52 | get { return _row; }
53 | }
54 |
55 | public static implicit operator BuildingNode(SimpleMapDb.BuildingsRow row)
56 | {
57 | return new BuildingNode(row);
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/Layers/MapObjects/TreeNodes/CableNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 | using ProgramMain.ExampleDb;
4 | using ProgramMain.Map;
5 | using ProgramMain.Map.Spatial.Types;
6 |
7 | namespace ProgramMain.Layers.MapObjects.TreeNodes
8 | {
9 | public class CableNode : ISpatialTreeNode
10 | {
11 | private readonly SimpleMapDb.CablesRow _row;
12 |
13 | public SpatialTreeNodeTypes NodeType
14 | {
15 | get { return SpatialTreeNodeTypes.Line; }
16 | }
17 |
18 | public Coordinate Coordinate
19 | {
20 | get { throw new Exception(); }
21 | }
22 |
23 | public CoordinateRectangle Rectangle
24 | {
25 | get
26 | {
27 | return new CoordinateRectangle(
28 | _row.Longitude1,
29 | _row.Latitude1,
30 | _row.Longitude2,
31 | _row.Latitude2);
32 | }
33 | }
34 |
35 | public CoordinatePoligon Poligon
36 | {
37 | get { throw new Exception(); }
38 | }
39 |
40 | public int RowId
41 | {
42 | get { return _row.ID; }
43 | }
44 |
45 | internal CableNode(SimpleMapDb.CablesRow row)
46 | {
47 | _row = row;
48 | }
49 |
50 | public DataRow Row
51 | {
52 | get { return _row; }
53 | }
54 |
55 | public static implicit operator CableNode(SimpleMapDb.CablesRow row)
56 | {
57 | return new CableNode(row);
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/Layers/MapObjects/TreeNodes/VertexNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 | using ProgramMain.ExampleDb;
4 | using ProgramMain.Map;
5 | using ProgramMain.Map.Spatial.Types;
6 |
7 | namespace ProgramMain.Layers.MapObjects.TreeNodes
8 | {
9 | public class VertexNode : ISpatialTreeNode
10 | {
11 | private readonly SimpleMapDb.VertexesRow _row;
12 |
13 | public SpatialTreeNodeTypes NodeType
14 | {
15 | get { return SpatialTreeNodeTypes.Point; }
16 | }
17 |
18 | public Coordinate Coordinate
19 | {
20 | get { return new Coordinate(_row.Longitude, _row.Latitude); }
21 | }
22 |
23 | public CoordinateRectangle Rectangle
24 | {
25 | get { throw new Exception(); }
26 | }
27 |
28 | public CoordinatePoligon Poligon
29 | {
30 | get { throw new Exception(); }
31 | }
32 |
33 | public int RowId
34 | {
35 | get { return _row.ID; }
36 | }
37 |
38 | internal VertexNode(SimpleMapDb.VertexesRow row)
39 | {
40 | _row = row;
41 | }
42 |
43 | public DataRow Row
44 | {
45 | get { return _row; }
46 | }
47 |
48 | public static implicit operator VertexNode(SimpleMapDb.VertexesRow row)
49 | {
50 | return new VertexNode(row);
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/Layers/MapObjects/VertexTree.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using System.Threading.Tasks;
3 | using ProgramMain.ExampleDb;
4 | using ProgramMain.Layers.MapObjects.TreeNodes;
5 | using ProgramMain.Map.Spatial;
6 | using ProgramMain.Map.Spatial.Types;
7 |
8 | namespace ProgramMain.Layers.MapObjects
9 | {
10 | public class VertexTree : SpatialTree
11 | {
12 | public SimpleMapDb.VertexesDataTable VertexDbRows { get; private set;}
13 |
14 | public VertexTree()
15 | : base(SpatialSheetPowerTypes.Ultra, SpatialSheetPowerTypes.Extra, SpatialSheetPowerTypes.Medium, SpatialSheetPowerTypes.Low)
16 | {
17 | VertexDbRows = new SimpleMapDb.VertexesDataTable();
18 | }
19 |
20 | protected void Insert(SimpleMapDb.VertexesRow row)
21 | {
22 | base.Insert(row);
23 | }
24 |
25 | protected void Delete(SimpleMapDb.VertexesRow row)
26 | {
27 | base.Delete(row);
28 | }
29 |
30 | public void LoadData()
31 | {
32 | Clear();
33 |
34 | //read data from db here
35 |
36 | Parallel.ForEach(VertexDbRows, Insert);
37 | }
38 |
39 | public void MergeData(SimpleMapDb.VertexesDataTable vertexes)
40 | {
41 | if (VertexDbRows == null) return;
42 |
43 | VertexDbRows.Merge(vertexes, false, MissingSchemaAction.Error);
44 |
45 | Parallel.ForEach(vertexes, row =>
46 | {
47 | var newRow = VertexDbRows.FindByID(row.ID);
48 | Insert(newRow);
49 | });
50 |
51 | //apply changes to db here
52 | }
53 |
54 | public bool RemoveVertex(int objectId)
55 | {
56 | var row = (VertexDbRows == null) ? null : VertexDbRows.FindByID(objectId);
57 | if (row != null)
58 | {
59 | Delete(row);
60 |
61 | VertexDbRows.Rows.Remove(row);
62 | //apply changes to db here
63 |
64 | return true;
65 | }
66 | return false;
67 | }
68 |
69 | public SimpleMapDb.VertexesRow GetVertex(int objectId)
70 | {
71 | if (VertexDbRows == null) return null;
72 |
73 | var row = VertexDbRows.FindByID(objectId);
74 | if (row != null)
75 | {
76 | var dt = (SimpleMapDb.VertexesDataTable)VertexDbRows.Clone();
77 | dt.ImportRow(row);
78 | return (SimpleMapDb.VertexesRow)dt.Rows[0];
79 | }
80 | return null;
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Map/Coordinate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using ProgramMain.Map.Google;
4 |
5 | namespace ProgramMain.Map
6 | {
7 | public class Coordinate : IComparable, ICloneable
8 | {
9 | public static readonly Coordinate Empty = new Coordinate();
10 |
11 | public double Longitude { get; set; }
12 |
13 | public double Latitude { get; set; }
14 |
15 | private Coordinate()
16 | {
17 | Latitude = 0;
18 | Longitude = 0;
19 | }
20 |
21 | public Coordinate(double pLongitude, double pLatitude)
22 | {
23 | Longitude = pLongitude;
24 | Latitude = pLatitude;
25 | }
26 |
27 | public Coordinate(decimal pLongitude, decimal pLatitude)
28 | {
29 | Longitude = (double)pLongitude;
30 | Latitude = (double)pLatitude;
31 | }
32 |
33 | #region ICloneable Members
34 | public object Clone()
35 | {
36 | return new Coordinate(Longitude, Latitude);
37 | }
38 | #endregion
39 |
40 | #region IComparable Members
41 | public int CompareTo(Object obj)
42 | {
43 | var coords = (Coordinate)obj;
44 | if (coords.Latitude < Latitude)
45 | return -1;
46 | if (coords.Latitude > Latitude)
47 | return 1;
48 | if (coords.Longitude < Longitude)
49 | return -1;
50 | if (coords.Longitude > Longitude)
51 | return 1;
52 | return 0;
53 | }
54 | #endregion
55 |
56 |
57 | public override string ToString()
58 | {
59 | return (String.Format("E{0:F5} N{1:F5}", Longitude, Latitude));
60 | }
61 |
62 | public static Coordinate operator + (Coordinate coordinate, GoogleCoordinate addon)
63 | {
64 | return new GoogleCoordinate(coordinate, addon.Level) + addon;
65 | }
66 |
67 | private GoogleCoordinate GetLeftTopGoogle(int screenWidth, int screenHeight, int level)
68 | {
69 | return new GoogleCoordinate(
70 | GoogleMapUtilities.GetGoogleX(this, level) - ((screenWidth + 1) / 2 - 1),
71 | GoogleMapUtilities.GetGoogleY(this, level) - ((screenHeight + 1) / 2 - 1),
72 | level);
73 | }
74 |
75 | private GoogleCoordinate GetRightBottomGoogle(int screenWidth, int screenHeight, int level)
76 | {
77 | return new GoogleCoordinate(
78 | GoogleMapUtilities.GetGoogleX(this, level) + ((screenWidth - 1) / 2 + 1),
79 | GoogleMapUtilities.GetGoogleY(this, level) + ((screenHeight - 1) / 2 + 1),
80 | level);
81 | }
82 |
83 | public GoogleRectangle GetScreenViewFromCenter(int screenWidth, int screenHeight, int level)
84 | {
85 | return new GoogleRectangle(GetLeftTopGoogle(screenWidth, screenHeight, level), GetRightBottomGoogle(screenWidth, screenHeight, level));
86 | }
87 |
88 | public Point GetScreenPoint(GoogleRectangle screenView)
89 | {
90 | return new GoogleCoordinate(this, screenView.Level).GetScreenPoint(screenView);
91 | }
92 |
93 | public static Coordinate GetCoordinateFromScreen(GoogleRectangle screenView, Point point)
94 | {
95 | return screenView.LeftTop + new GoogleCoordinate(point.X, point.Y, screenView.Level);
96 | }
97 |
98 | public GoogleBlock GetGoogleBlock(int level)
99 | {
100 | return new GoogleCoordinate(this, level);
101 | }
102 |
103 | public double Distance(Coordinate coordinate)
104 | {
105 | return EarthUtilities.GetLength(this, coordinate);
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/Map/CoordinatePoligon.cs:
--------------------------------------------------------------------------------
1 | using ProgramMain.Map.Google;
2 | using ProgramMain.Map.Indexer;
3 | using ProgramMain.Map.Types;
4 |
5 | namespace ProgramMain.Map
6 | {
7 | public class CoordinatePoligon
8 | {
9 | public static readonly CoordinatePoligon Empty = new CoordinatePoligon();
10 |
11 | public readonly CoordinateIndexer Coordinates;
12 |
13 | public Coordinate First
14 | {
15 | get { return Coordinates[0]; }
16 | }
17 |
18 | public Coordinate Last
19 | {
20 | get { return Coordinates[Coordinates.Count - 1]; }
21 | }
22 |
23 | public CoordinateRectangle this[int index]
24 | {
25 | get
26 | {
27 | if (index < 0 || index > Count - 1)
28 | return null;
29 | var leftTop = Coordinates[index];
30 | var rightBottom = index == Count - 1 ? Coordinates[0] : Coordinates[index + 1];
31 | return new CoordinateRectangle(leftTop, rightBottom);
32 | }
33 | }
34 |
35 | public int Count
36 | {
37 | get { return Coordinates.Count; }
38 | }
39 |
40 | public CoordinatePoligon()
41 | {
42 | Coordinates = new CoordinateIndexer();
43 | }
44 |
45 | public bool Add(Coordinate coordinate)
46 | {
47 | if (Count > 2)
48 | {
49 | var line1 = new CoordinateRectangle(First, coordinate);
50 | var line2 = new CoordinateRectangle(Last, coordinate);
51 | for (var i = 0; i < Count - 1; i++)
52 | {
53 | if (GoogleMapUtilities.CheckLinesInterseption(this[i], line1)
54 | || GoogleMapUtilities.CheckLinesInterseption(this[i], line2))
55 | return false;
56 | }
57 | }
58 |
59 | Coordinates.Add(coordinate);
60 | return true;
61 | }
62 |
63 | public double PoligonDistance(Coordinate coordinate)
64 | {
65 | double res = 0;
66 |
67 | for (var i = 0; i < Count; i++)
68 | {
69 | var distance = this[i].LineDistance(coordinate);
70 | if (i == 0 || distance < res)
71 | res = distance;
72 | }
73 | return res;
74 | }
75 |
76 | public bool IncludeTo(CoordinateRectangle rect)
77 | {
78 | for (var i = 0; i < Coordinates.Count; i++)
79 | {
80 | if (rect.PointContains(Coordinates[i]) != InterseptResult.Contains)
81 | return false;
82 | }
83 | return true;
84 | }
85 |
86 | public InterseptResult PointContains(Coordinate coordinate)
87 | {
88 | //to do
89 |
90 | return InterseptResult.None;
91 | }
92 |
93 | public InterseptResult LineContains(CoordinateRectangle coordinate)
94 | {
95 | //to do
96 |
97 | return InterseptResult.None;
98 | }
99 |
100 | public InterseptResult RectangleContains(CoordinateRectangle coordinate)
101 | {
102 | //to do
103 |
104 | return InterseptResult.None;
105 | }
106 |
107 | public InterseptResult PoligonContains(CoordinateRectangle coordinate)
108 | {
109 | //to do
110 |
111 | return InterseptResult.None;
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/Map/CoordinateRectangle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using ProgramMain.Map.Google;
4 | using ProgramMain.Map.Types;
5 |
6 | namespace ProgramMain.Map
7 | {
8 | public class CoordinateRectangle : ICloneable
9 | {
10 | public static readonly CoordinateRectangle Empty = new CoordinateRectangle();
11 |
12 | public Coordinate LeftTop
13 | {
14 | get
15 | {
16 | return new Coordinate(Left, Top);
17 | }
18 | }
19 |
20 | public Coordinate RightBottom
21 | {
22 | get
23 | {
24 | return new Coordinate(Right, Bottom);
25 | }
26 | }
27 |
28 | public Coordinate LeftBottom
29 | {
30 | get
31 | {
32 | return new Coordinate(Left, Bottom);
33 | }
34 | }
35 |
36 | public Coordinate RightTop
37 | {
38 | get
39 | {
40 | return new Coordinate(Right, Top);
41 | }
42 | }
43 |
44 | public double Width
45 | {
46 | get { return Right - Left; }
47 | }
48 |
49 | public double Height
50 | {
51 | get { return Bottom - Top; }
52 | }
53 |
54 | public double Left { get; private set; }
55 |
56 | public double Right { get; private set; }
57 |
58 | public double Top { get; private set; }
59 |
60 | public double Bottom { get; private set; }
61 |
62 | private CoordinateRectangle()
63 | {
64 | Bottom = 0;
65 | Top = 0;
66 | Right = 0;
67 | Left = 0;
68 | }
69 |
70 | public CoordinateRectangle(double left, double top, double right, double bottom)
71 | {
72 | Left = left;
73 | Top = top;
74 | Right = right;
75 | Bottom = bottom;
76 | }
77 |
78 | public CoordinateRectangle(decimal left, decimal top, decimal right, decimal bottom)
79 | {
80 | Left = (double)left;
81 | Top = (double)top;
82 | Right = (double)right;
83 | Bottom = (double)bottom;
84 | }
85 |
86 | public CoordinateRectangle(Coordinate pLeftTop, Coordinate pRightBottom)
87 | {
88 | Left = pLeftTop.Longitude;
89 | Top = pLeftTop.Latitude;
90 | Right = pRightBottom.Longitude;
91 | Bottom = pRightBottom.Latitude;
92 | }
93 |
94 | #region ICloneable Members
95 | public object Clone()
96 | {
97 | return new CoordinateRectangle(Left, Top, Right, Bottom);
98 | }
99 | #endregion
100 |
101 |
102 | public override string ToString()
103 | {
104 | return (String.Format("E{0:F5} N{1:F5} - E{2:F5} N{3:F5} : {4:n}m", Left, Top, Right, Bottom, LineLength));
105 | }
106 |
107 | public Rectangle GetScreenRect(GoogleRectangle screenView)
108 | {
109 | return new GoogleRectangle(this, screenView.Level).GetScreenRect(screenView);
110 | }
111 |
112 | public InterseptResult PointContains(Coordinate point)
113 | {
114 | return (point.Longitude >= Left
115 | && point.Longitude <= Right
116 | && point.Latitude <= Top
117 | && point.Latitude >= Bottom) ? InterseptResult.Contains : InterseptResult.None;
118 | }
119 |
120 | public InterseptResult RectangleContains(CoordinateRectangle rectangle)
121 | {
122 | var iLeftTop = PointContains(rectangle.LeftTop) != InterseptResult.None;
123 | var iRightBottom = PointContains(rectangle.RightBottom) != InterseptResult.None;
124 |
125 | if (iLeftTop && iRightBottom)
126 | return InterseptResult.Contains;
127 | if (iLeftTop || iRightBottom)
128 | return InterseptResult.Intersepts;
129 |
130 | if (PointContains(rectangle.LeftBottom) != InterseptResult.None)
131 | return InterseptResult.Intersepts;
132 | if (PointContains(rectangle.RightTop) != InterseptResult.None)
133 | return InterseptResult.Intersepts;
134 |
135 | iLeftTop = rectangle.PointContains(LeftTop) != InterseptResult.None;
136 | iRightBottom = rectangle.PointContains(RightBottom) != InterseptResult.None;
137 |
138 | if (iLeftTop && iRightBottom)
139 | return InterseptResult.Supersets;
140 | if (iLeftTop || iRightBottom)
141 | return InterseptResult.Intersepts;
142 |
143 | if (rectangle.PointContains(LeftBottom) != InterseptResult.None)
144 | return InterseptResult.Intersepts;
145 | if (rectangle.PointContains(RightTop) != InterseptResult.None)
146 | return InterseptResult.Intersepts;
147 |
148 | if (GoogleMapUtilities.CheckLinesInterseption(new CoordinateRectangle(Left, Top, Left, Bottom),
149 | new CoordinateRectangle(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Top)))
150 | return InterseptResult.Intersepts;
151 | if (GoogleMapUtilities.CheckLinesInterseption(new CoordinateRectangle(Left, Top, Right, Top),
152 | new CoordinateRectangle(rectangle.Left, rectangle.Top, rectangle.Left, rectangle.Bottom)))
153 | return InterseptResult.Intersepts;
154 |
155 | return InterseptResult.None;
156 | }
157 |
158 | public InterseptResult LineContains(CoordinateRectangle line)
159 | {
160 | var iLeftTop = PointContains(line.LeftTop) != InterseptResult.None;
161 | var iRightBottom = PointContains(line.RightBottom) != InterseptResult.None;
162 |
163 | if (iLeftTop && iRightBottom)
164 | return InterseptResult.Contains;
165 | if (iLeftTop || iRightBottom)
166 | return InterseptResult.Intersepts;
167 | if (GoogleMapUtilities.CheckLinesInterseption(new CoordinateRectangle(Left, Top, Right, Top), line))
168 | return InterseptResult.Intersepts;
169 | if (GoogleMapUtilities.CheckLinesInterseption(new CoordinateRectangle(Right, Top, Right, Bottom), line))
170 | return InterseptResult.Intersepts;
171 | if (GoogleMapUtilities.CheckLinesInterseption(new CoordinateRectangle(Left, Bottom, Right, Bottom), line))
172 | return InterseptResult.Intersepts;
173 | if (GoogleMapUtilities.CheckLinesInterseption(new CoordinateRectangle(Left, Top, Left, Bottom), line))
174 | return InterseptResult.Intersepts;
175 | return InterseptResult.None;
176 | }
177 |
178 | public InterseptResult PoligonContains(CoordinatePoligon poligon)
179 | {
180 | if (poligon.IncludeTo(this))
181 | return InterseptResult.Contains;
182 |
183 | for (var i = 0; i < poligon.Count; i++)
184 | {
185 | if (LineContains(poligon[i]) != InterseptResult.None)
186 | return InterseptResult.Intersepts;
187 | }
188 |
189 | if (poligon.PointContains(LeftTop) != InterseptResult.None
190 | && poligon.PointContains(RightTop) != InterseptResult.None
191 | && poligon.PointContains(RightBottom) != InterseptResult.None
192 | && poligon.PointContains(LeftBottom) != InterseptResult.None)
193 | return InterseptResult.Supersets;
194 |
195 | return InterseptResult.None;
196 | }
197 |
198 | public double RectangeDistance(Coordinate coordinate)
199 | {
200 | if (PointContains(coordinate) != InterseptResult.None)
201 | return 0;
202 |
203 | var min = EarthUtilities.GetDistance(new CoordinateRectangle(Left, Top, Right, Top), coordinate);
204 | var res = EarthUtilities.GetDistance(new CoordinateRectangle(Right, Top, Right, Bottom), coordinate);
205 | if (res < min) min = res;
206 | res = EarthUtilities.GetDistance(new CoordinateRectangle(Right, Bottom, Left, Bottom), coordinate);
207 | if (res < min) min = res;
208 | res = EarthUtilities.GetDistance(new CoordinateRectangle(Left, Bottom, Left, Top), coordinate);
209 | if (res < min) min = res;
210 |
211 | return min;
212 | }
213 |
214 | public double LineDistance(Coordinate coordinate)
215 | {
216 | return EarthUtilities.GetDistance(this, coordinate);
217 | }
218 |
219 | public Coordinate LineMiddlePoint
220 | {
221 | get { return GoogleMapUtilities.GetMiddlePoint(LeftTop, RightBottom); }
222 | }
223 |
224 | public double LineLength
225 | {
226 | get { return LeftTop.Distance(RightBottom); }
227 | }
228 |
229 | public double LineAngle
230 | {
231 | get { return Math.Atan2(Width, Height); }
232 | }
233 |
234 | public void LineGrow(double meter)
235 | {
236 | var len = LineLength;
237 | var ang = LineAngle;
238 | Right = Left + (len + meter) * Math.Cos(ang);
239 | Bottom = Top + (len + meter) * Math.Sin(ang);
240 | }
241 |
242 | public Coordinate GetNearestPoint(Coordinate pt)
243 | {
244 | return EarthUtilities.GetNearestPoint(this, pt);
245 | }
246 | }
247 | }
--------------------------------------------------------------------------------
/Map/EarthUtilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ProgramMain.Map
4 | {
5 | internal class EarthUtilities
6 | {
7 | #region Вспомогательные функциии для расчета растояний для земного шара с допуском, что все объекты находятся на высоте 0 метров над уровнем моря
8 |
9 | ///
10 | /// Приблизительное растояние между двумя точками
11 | /// Передаваемые широта/долгота в градусах и сотых долях
12 | ///
13 | public static double GetLength(Coordinate c1, Coordinate c2)
14 | {
15 | // Константы, используемые для вычисления смещения и расстояния
16 | const double d2R = Math.PI / 180; // Константа для преобразования градусов в радианы
17 | const double a = 6378137.0; // Основные полуоси
18 | //const double b = 6356752.314245; // Неосновные полуоси
19 | const double e2 = 0.006739496742337; // Квадрат эксцентричности эллипсоида
20 |
21 | // Вычисляем разницу между двумя долготами и широтами и получаем среднюю широту
22 | var fdLambda = (c1.Longitude - c2.Longitude) * d2R; // Разница между двумя значениями долготы
23 | var fdPhi = (c1.Latitude - c2.Latitude) * d2R; // Разница между двумя значениями широты
24 | var fPhimean = ((c1.Latitude + c2.Latitude) / 2.0) * d2R; // Средняя широта
25 |
26 | // Меридианский радиус кривизны
27 | var fRho = (a * (1 - e2)) / Math.Pow(1 - e2 * (Math.Pow(Math.Sin(fPhimean), 2)), 1.5);
28 | // Поперечный радиус кривизны
29 | var fNu = a / (Math.Sqrt(1 - e2 * (Math.Sin(fPhimean) * Math.Sin(fPhimean))));
30 |
31 | // Вычисляем угловое расстояние от центра сфероида
32 | var fz = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(fdPhi / 2.0), 2) + Math.Cos(c2.Latitude * d2R) * Math.Cos(c1.Latitude * d2R) * Math.Pow(Math.Sin(fdLambda / 2.0), 2)));
33 |
34 | // Вычисляем смещение
35 | var fAlpha = Math.Asin(Math.Cos(c2.Latitude * d2R) * Math.Sin(fdLambda) * 1 / Math.Sin(fz));
36 | // Вычисляем радиус Земли
37 | var fR = (fRho * fNu) / ((fRho * Math.Pow(Math.Sin(fAlpha), 2)) + (fNu * Math.Pow(Math.Cos(fAlpha), 2)));
38 |
39 | // Вычисленное расстояния в метрах
40 | var distance = fz * fR;
41 |
42 | return distance;
43 | }
44 |
45 | ///
46 | /// Приблизительное растояние от точки до отрезка прямой
47 | /// Передаваемые широта/долгота в градусах и сотых долях
48 | ///
49 | public static double GetDistance(CoordinateRectangle line, Coordinate pt)
50 | {
51 | const double r2D = 180 / Math.PI; // Константа для преобразования радиан в градусы
52 |
53 | var a = GetLength(line.LeftTop, line.RightBottom);
54 |
55 | var b = GetLength(line.LeftTop, pt);
56 | var c = GetLength(line.RightBottom, pt);
57 | if (a <= 0)
58 | return (b + c) / 2;
59 |
60 | var enB = Math.Acos((Math.Pow(a, 2) + Math.Pow(b, 2) - Math.Pow(c, 2)) / (2 * a * b)) * r2D;
61 | if (enB >= 90)
62 | return b;
63 | var enC = Math.Acos((Math.Pow(a, 2) + Math.Pow(c, 2) - Math.Pow(b, 2)) / (2 * a * c)) * r2D;
64 | if (enC >= 90)
65 | return c;
66 |
67 | var s = (a + b + c) / 2;
68 | var ar = Math.Sqrt(s * (s - a) * (s - b) * (s - c));
69 |
70 | return ar * 2 / a;
71 | }
72 |
73 | public static Coordinate GetNearestPoint(CoordinateRectangle line, Coordinate pt)
74 | {
75 |
76 | const double r2D = 180 / Math.PI; // Константа для преобразования радиан в градусы
77 |
78 | var a = GetLength(line.LeftTop, line.RightBottom);
79 | if (a <= 0)
80 | return pt;
81 |
82 | var b = GetLength(line.LeftTop, pt);
83 | var c = GetLength(line.RightBottom, pt);
84 |
85 | var enB = Math.Acos((Math.Pow(a, 2) + Math.Pow(b, 2) - Math.Pow(c, 2)) / (2 * a * b)) * r2D;
86 | if (enB >= 90)
87 | return pt;
88 | var enC = Math.Acos((Math.Pow(a, 2) + Math.Pow(c, 2) - Math.Pow(b, 2)) / (2 * a * c)) * r2D;
89 | if (enC >= 90)
90 | return pt;
91 |
92 |
93 | var x = ((line.Right - line.Left) * (line.Bottom - line.Top) * (pt.Latitude - line.Top) +
94 | line.Left * Math.Pow(line.Bottom - line.Top, 2) + pt.Longitude*Math.Pow(line.Right - line.Left, 2)) /
95 | (Math.Pow(line.Bottom - line.Top, 2) + Math.Pow(line.Right - line.Left, 2));
96 | var y = (line.Bottom - line.Top) * (x - line.Left) / (line.Right - line.Left) + line.Top;
97 |
98 | return new Coordinate(x,y);
99 | }
100 |
101 | #endregion
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/Map/Google/GoogleBlock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 |
4 | namespace ProgramMain.Map.Google
5 | {
6 | public class GoogleBlock : IComparable, ICloneable
7 | {
8 | public static readonly GoogleBlock Empty = new GoogleBlock();
9 |
10 | public const int BlockSize = 256;
11 |
12 | public Point Pt
13 | {
14 | get
15 | {
16 | return new Point(X, Y);
17 | }
18 | }
19 |
20 | public int X { get; private set; }
21 |
22 | public int Y { get; private set; }
23 |
24 | public int Level { get; private set; }
25 |
26 | private GoogleBlock()
27 | {
28 | Level = 0;
29 | Y = 0;
30 | X = 0;
31 | }
32 |
33 | public GoogleBlock(int pX, int pY, int pLevel)
34 | {
35 | X = pX;
36 | Y = pY;
37 | Level = pLevel;
38 | }
39 |
40 | public GoogleBlock(Point pt, int pLevel)
41 | {
42 | X = pt.X;
43 | Y = pt.Y;
44 |
45 | Level = pLevel;
46 | }
47 |
48 | #region ICloneable Members
49 | public object Clone()
50 | {
51 | return new GoogleBlock(X, Y, Level);
52 | }
53 | #endregion
54 |
55 | #region IComparable Members
56 | public int CompareTo(Object obj)
57 | {
58 | var coords = (GoogleBlock)obj;
59 | if (coords.Level < Level)
60 | return -1;
61 | if (coords.Level > Level)
62 | return 1;
63 | if (coords.Y < Y)
64 | return -1;
65 | if (coords.Y > Y)
66 | return 1;
67 | if (coords.X < X)
68 | return -1;
69 | if (coords.X > X)
70 | return 1;
71 | return 0;
72 | }
73 | #endregion
74 |
75 | public static implicit operator GoogleCoordinate(GoogleBlock block)
76 | {
77 | return new GoogleCoordinate(block.X * BlockSize, block.Y * BlockSize, block.Level);
78 | }
79 |
80 | public static implicit operator GoogleRectangle(GoogleBlock block)
81 | {
82 | return new GoogleRectangle(
83 | block.X * BlockSize, block.Y * BlockSize,
84 | (block.X + 1) * BlockSize, (block.Y + 1) * BlockSize,
85 | block.Level);
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Map/Google/GoogleCoordinate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 |
4 | namespace ProgramMain.Map.Google
5 | {
6 | public class GoogleCoordinate : IComparable, ICloneable
7 | {
8 | public static readonly GoogleCoordinate Empty = new GoogleCoordinate();
9 |
10 | public long X { get; private set; }
11 |
12 | public long Y { get; private set; }
13 |
14 | public int Level { get; private set; }
15 |
16 | private GoogleCoordinate()
17 | {
18 | X = 0;
19 | Level = 0;
20 | Y = 0;
21 | }
22 |
23 | public GoogleCoordinate(long pX, long pY, int pLevel)
24 | {
25 | X = pX;
26 | Y = pY;
27 | Level = pLevel;
28 | }
29 |
30 | public GoogleCoordinate(Coordinate coordinate, int level)
31 | {
32 | X = GoogleMapUtilities.GetGoogleX(coordinate, level);
33 | Y = GoogleMapUtilities.GetGoogleY(coordinate, level);
34 | Level = level;
35 | }
36 |
37 | #region ICloneable Members
38 | public object Clone()
39 | {
40 | return new GoogleCoordinate(X, Y, Level);
41 | }
42 | #endregion
43 |
44 | #region IComparable Members
45 | public int CompareTo(Object obj)
46 | {
47 | var coords = (GoogleCoordinate)obj;
48 | if (coords.Level < Level)
49 | return -1;
50 | if (coords.Level > Level)
51 | return 1;
52 | if (coords.Y < Y)
53 | return -1;
54 | if (coords.Y > Y)
55 | return 1;
56 | if (coords.X < X)
57 | return -1;
58 | if (coords.X > X)
59 | return 1;
60 | return 0;
61 | }
62 | #endregion
63 |
64 | public static GoogleCoordinate operator + (GoogleCoordinate google, GoogleCoordinate addon)
65 | {
66 | if (google.Level != addon.Level)
67 | {
68 | addon = new GoogleCoordinate(addon, google.Level);
69 | }
70 | return new GoogleCoordinate(google.X + addon.X, google.Y + addon.Y, google.Level);
71 | }
72 |
73 | public static implicit operator Coordinate(GoogleCoordinate google)
74 | {
75 | return new Coordinate(GoogleMapUtilities.GetLongitude(google), GoogleMapUtilities.GetLatitude(google));
76 | }
77 |
78 | public static implicit operator GoogleBlock(GoogleCoordinate google)
79 | {
80 | return new GoogleBlock(
81 | (int)(google.X / GoogleBlock.BlockSize),
82 | (int)(google.Y / GoogleBlock.BlockSize),
83 | google.Level);
84 | }
85 |
86 | public Point GetScreenPoint(GoogleRectangle screenView)
87 | {
88 | if (Level != screenView.Level)
89 | {
90 | screenView = new GoogleRectangle(new CoordinateRectangle(screenView.LeftTop, screenView.RightBottom), Level);
91 | }
92 | return new Point((int)(X - screenView.Left), (int)(Y - screenView.Top));
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Map/Google/GoogleMapUtilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 |
4 | namespace ProgramMain.Map.Google
5 | {
6 | internal class GoogleMapUtilities
7 | {
8 | #region Helpers to work with Google Coordinate system
9 | ///
10 | /// Block count on the side of google level
11 | ///
12 | ///
13 | ///
14 | public static long NumTiles(int level)
15 | {
16 | return Convert.ToInt64(Math.Pow(2, (level - 1)));
17 | }
18 |
19 | ///
20 | /// Block count on the google level
21 | ///
22 | ///
23 | ///
24 | public static long CountTiles(int level)
25 | {
26 | var numTiles = NumTiles(level);
27 | return numTiles * numTiles;
28 | }
29 |
30 | ///
31 | /// Translate block count to google level
32 | ///
33 | ///
34 | ///
35 | public static long NumLevel(int countTiles)
36 | {
37 | return Convert.ToInt64(Math.Log(Math.Sqrt(countTiles), 2)) + 1;
38 | }
39 |
40 | ///
41 | /// Pixel count on the side of google level bitmap
42 | ///
43 | ///
44 | ///
45 | public static long BitMapSize(int level)
46 | {
47 | return NumTiles(level) * GoogleBlock.BlockSize;
48 | }
49 |
50 | ///
51 | /// Pixel count on the google level bitmap
52 | ///
53 | ///
54 | ///
55 | public static long BitmapOrigo(int level)
56 | {
57 | return BitMapSize(level) / 2;
58 | }
59 |
60 | ///
61 | /// Pixel count per degree on the google level bitmap
62 | ///
63 | ///
64 | ///
65 | public static double PixelsPerDegree(int level)
66 | {
67 | return (double)BitMapSize(level) / 360;
68 | }
69 |
70 | ///
71 | /// Pixel count per radian on the google level bitmap
72 | ///
73 | ///
74 | ///
75 | public static double PixelsPerRadian(int level)
76 | {
77 | const double p2 = 2 * Math.PI;
78 | return BitMapSize(level) / p2;
79 | }
80 |
81 | ///
82 | /// Translate longitude to X coordinate of the google level bitmap
83 | ///
84 | public static long GetGoogleX(Coordinate coordinate, int level)
85 | {
86 | return (long)(Math.Floor(BitmapOrigo(level) + coordinate.Longitude * PixelsPerDegree(level)));
87 | }
88 |
89 | ///
90 | /// Translate latitude to Y coordinate of the google level bitmap
91 | ///
92 | public static long GetGoogleY(Coordinate coordinate, int level)
93 | {
94 | const double d2R = Math.PI / 180;
95 | var z = (1 + Math.Sin(coordinate.Latitude * d2R)) / (1 - Math.Sin(coordinate.Latitude * d2R));
96 | return (long)(Math.Floor(BitmapOrigo(level) - 0.5 * Math.Log(z) * PixelsPerRadian(level)));
97 | }
98 |
99 | ///
100 | /// Translate X coordinate of the google level bitmap to longitude
101 | ///
102 | public static double GetLongitude(GoogleCoordinate google)
103 | {
104 | return Math.Round((google.X - BitmapOrigo(google.Level)) / PixelsPerDegree(google.Level), 5);
105 | }
106 |
107 | ///
108 | /// Translate Y coordinate of the google level bitmap to latitude
109 | ///
110 | public static double GetLatitude(GoogleCoordinate google)
111 | {
112 | const double r2D = 180 / Math.PI;
113 | const double p2 = Math.PI / 2;
114 | var z = (google.Y - BitmapOrigo(google.Level)) / (-1 * PixelsPerRadian(google.Level));
115 | return Math.Round((2 * Math.Atan(Math.Exp(z)) - p2) * r2D, 5);
116 | }
117 |
118 | ///
119 | /// Get google bitmap block number X by longitude
120 | ///
121 | public static long GetNumBlockX(Coordinate coordinate, int level)
122 | {
123 | return (long)Math.Floor((double)GetGoogleX(coordinate, level) / GoogleBlock.BlockSize);
124 | }
125 |
126 | ///
127 | /// Get google bitmap block number Y by latitude
128 | ///
129 | public static long GetNumBlockY(Coordinate coordinate, int level)
130 | {
131 | return (long)Math.Floor((double)GetGoogleY(coordinate, level) / GoogleBlock.BlockSize);
132 | }
133 | #endregion
134 |
135 | ///
136 | /// Line cross
137 | ///
138 | public static bool CheckLinesInterseption(CoordinateRectangle line1, CoordinateRectangle line2)
139 | {
140 | double d = (line1.Left - line1.Right) * (line2.Bottom - line2.Top) - (line1.Top - line1.Bottom) * (line2.Right - line2.Left);
141 |
142 | if (Math.Abs(d) < 0.000000001)
143 | return false;
144 |
145 | double da = (line1.Left - line2.Left) * (line2.Bottom - line2.Top) - (line1.Top - line2.Top) * (line2.Right - line2.Left);
146 | double db = (line1.Left - line1.Right) * (line1.Top - line2.Top) - (line1.Top - line1.Bottom) * (line1.Left - line2.Left);
147 |
148 | double ta = da / d;
149 | double tb = db / d;
150 |
151 | return ((0 <= ta) && (ta <= 1) && (0 <= tb) && (tb <= 1));
152 | }
153 |
154 | ///
155 | /// Line middle point
156 | ///
157 | public static Coordinate GetMiddlePoint(Coordinate c1, Coordinate c2)
158 | {
159 | const double d2R = Math.PI / 180;
160 | const double r2D = 180 / Math.PI;
161 |
162 | var dLon = d2R * (c2.Longitude - c1.Longitude);
163 | var c1Rlat = d2R * (c1.Latitude);
164 | var c2Rlat = d2R * (c2.Latitude);
165 | var bX = Math.Cos(c2Rlat) * Math.Cos(dLon);
166 | var bY = Math.Cos(c2Rlat) * Math.Sin(dLon);
167 |
168 | var longitude = Math.Round(c1.Longitude + r2D * (Math.Atan2(bY, Math.Cos(c1Rlat) + bX)), 5);
169 | var latitude = Math.Round(r2D * (Math.Atan2(Math.Sin(c1Rlat) + Math.Sin(c2Rlat), Math.Sqrt((Math.Cos(c1Rlat) + bX) * (Math.Cos(c1Rlat) + bX) + bY * bY))), 5);
170 |
171 | return new Coordinate(longitude, latitude);
172 | }
173 |
174 | ///
175 | /// Create Url to get bitmap block from google bitmap cache
176 | ///
177 | public static string CreateUrl(GoogleBlock block)
178 | {
179 | return String.Format(Properties.Settings.Default.GoogleUrl, block.X, block.Y, block.Level - 1);
180 | }
181 |
182 | ///
183 | /// Create web request to get bitmap block from google bitmap cache
184 | ///
185 | public static HttpWebRequest CreateGoogleWebRequest(GoogleBlock block)
186 | {
187 | var urlGoogle = CreateUrl(block);
188 | var oRequest = (HttpWebRequest)WebRequest.Create(urlGoogle);
189 | oRequest.UserAgent = "www.simplemap.ru"; //!!!must have to retrieve image from google
190 | return oRequest;
191 | }
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/Map/Google/GoogleRectangle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using ProgramMain.Map.Types;
4 |
5 | namespace ProgramMain.Map.Google
6 | {
7 | public class GoogleRectangle : ICloneable, IComparable
8 | {
9 | public static readonly GoogleRectangle Empty = new GoogleRectangle();
10 |
11 | public GoogleCoordinate LeftTop
12 | {
13 | get
14 | {
15 | return new GoogleCoordinate(Left, Top, Level);
16 | }
17 | }
18 |
19 | public GoogleCoordinate RightBottom
20 | {
21 | get
22 | {
23 | return new GoogleCoordinate(Right, Bottom, Level);
24 | }
25 | }
26 |
27 | public long Left { get; private set; }
28 |
29 | public long Right { get; private set; }
30 |
31 | public long Top { get; private set; }
32 |
33 | public long Bottom { get; private set; }
34 |
35 | public int Level { get; private set; }
36 |
37 | private GoogleRectangle()
38 | {
39 | Left = 0;
40 | Right = 0;
41 | Top = 0;
42 | Bottom = 0;
43 | Level = 0;
44 | }
45 |
46 | public GoogleRectangle(long left, long top, long right, long bottom, int level)
47 | {
48 | Left = left;
49 | Top = top;
50 | Right = right;
51 | Bottom = bottom;
52 | Level = level;
53 | }
54 |
55 | public GoogleRectangle(GoogleCoordinate pLeftTop, GoogleCoordinate pRightBottom)
56 | {
57 | if (pRightBottom.Level != pLeftTop.Level)
58 | {
59 | pRightBottom = new GoogleCoordinate(pRightBottom, pLeftTop.Level);
60 | }
61 | Left = pLeftTop.X;
62 | Top = pLeftTop.Y;
63 | Right = pRightBottom.X;
64 | Bottom = pRightBottom.Y;
65 | Level = pLeftTop.Level;
66 | }
67 |
68 | public GoogleRectangle(CoordinateRectangle coordinateRect, int level)
69 | {
70 | var pLeftTop = new GoogleCoordinate(coordinateRect.LeftTop, level);
71 | var pRightBottom = new GoogleCoordinate(coordinateRect.RightBottom, level);
72 | Left = pLeftTop.X;
73 | Top = pLeftTop.Y;
74 | Right = pRightBottom.X;
75 | Bottom = pRightBottom.Y;
76 | Level = level;
77 | }
78 |
79 | public GoogleRectangle(CoordinatePoligon coordinatePoligon, int level)
80 | {
81 | for (var i = 0; i < coordinatePoligon.Count; i++)
82 | {
83 | var pt = new GoogleCoordinate(coordinatePoligon.Coordinates[i], level);
84 | if (i == 0)
85 | {
86 | Left = pt.X;
87 | Right = pt.X;
88 | Top = pt.Y;
89 | Bottom = pt.Y;
90 | }
91 | else
92 | {
93 | if (pt.X < Left) Left = pt.X;
94 | if (pt.X > Right) Right = pt.X;
95 | if (pt.Y < Top) Top = pt.Y;
96 | if (pt.Y > Bottom) Bottom = pt.Y;
97 | }
98 | }
99 |
100 | Level = level;
101 | }
102 |
103 | #region ICloneable Members
104 | public object Clone()
105 | {
106 | return new GoogleRectangle(Left, Top, Right, Bottom, Level);
107 | }
108 | #endregion
109 |
110 | #region IComparable Members
111 | public int CompareTo(Object obj)
112 | {
113 | var rectangle = (GoogleRectangle)obj;
114 | var res = LeftTop.CompareTo(rectangle.LeftTop);
115 | if (res != 0) return res;
116 | return RightBottom.CompareTo(rectangle.RightBottom);
117 | }
118 | #endregion
119 |
120 | public static implicit operator CoordinateRectangle(GoogleRectangle google)
121 | {
122 | return new CoordinateRectangle(google.LeftTop, google.RightBottom);
123 | }
124 |
125 | ///
126 | /// Google bitmap block count for (X, Y)
127 | ///
128 | public Rectangle BlockView
129 | {
130 | get
131 | {
132 | return Rectangle.FromLTRB(
133 | (int) (Left / GoogleBlock.BlockSize),
134 | (int) (Top / GoogleBlock.BlockSize),
135 | (int) ((Right - GoogleBlock.BlockSize) / GoogleBlock.BlockSize) + 1,
136 | (int) ((Bottom - GoogleBlock.BlockSize) / GoogleBlock.BlockSize) + 1);
137 | }
138 | }
139 |
140 | public Rectangle GetScreenRect(GoogleRectangle screenView)
141 | {
142 | if (Level != screenView.Level)
143 | {
144 | screenView = new GoogleRectangle(
145 | new CoordinateRectangle(screenView.LeftTop, screenView.RightBottom), Level);
146 | }
147 |
148 | var pt1 = LeftTop.GetScreenPoint(screenView);
149 | var pt2 = RightBottom.GetScreenPoint(screenView);
150 |
151 | return Rectangle.FromLTRB(pt1.X, pt1.Y, pt2.X, pt2.Y);
152 | }
153 |
154 | public InterseptResult PointContains(Coordinate point)
155 | {
156 | return ((CoordinateRectangle)this).PointContains(point);
157 | }
158 |
159 | public InterseptResult RectangleContains(CoordinateRectangle rectangle)
160 | {
161 | return ((CoordinateRectangle)this).RectangleContains(rectangle);
162 | }
163 |
164 | public InterseptResult LineContains(CoordinateRectangle line)
165 | {
166 | return ((CoordinateRectangle)this).LineContains(line);
167 | }
168 |
169 | public InterseptResult PoligonContains(CoordinatePoligon poligon)
170 | {
171 | return ((CoordinateRectangle)this).PoligonContains(poligon);
172 | }
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/Map/Indexer/CoordinateIndexer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace ProgramMain.Map.Indexer
4 | {
5 | public class CoordinateIndexer
6 | {
7 | private List _values;
8 |
9 | public Coordinate this[int index]
10 | {
11 | get { return index >= 0 && index < _values.Count ? _values[index] : null; }
12 | }
13 |
14 | public int Count {get { return _values != null ? _values.Count : 0; }}
15 |
16 | public void Add(Coordinate coordinate)
17 | {
18 | if (_values == null)
19 | _values = new List();
20 | _values.Add(coordinate);
21 | }
22 |
23 | public void Remove(Coordinate coordinate)
24 | {
25 | if (_values != null)
26 | {
27 | _values.Remove(coordinate);
28 | }
29 | }
30 |
31 | public void Destroy()
32 | {
33 | if (_values != null)
34 | {
35 | _values.Clear();
36 | _values = null;
37 | }
38 | }
39 |
40 | public bool HasChilds
41 | {
42 | get { return _values != null && _values.Count > 0; }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Map/Spatial/Indexer/SpatialContentIndexer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using ProgramMain.Map.Spatial.Types;
3 |
4 | namespace ProgramMain.Map.Spatial.Indexer
5 | {
6 | internal class SpatialContentIndexer where TNode : ISpatialTreeNode
7 | {
8 | private SortedDictionary _content;
9 |
10 | public void Add(TNode node)
11 | {
12 | if (_content == null)
13 | _content = new SortedDictionary();
14 | _content[node.RowId] = node;
15 | }
16 |
17 | public void Remove(TNode node)
18 | {
19 | if (_content != null)
20 | {
21 | _content.Remove(node.RowId);
22 | }
23 | }
24 |
25 | public SortedDictionary.ValueCollection Values
26 | {
27 | get { return _content != null ? _content.Values : null; }
28 | }
29 |
30 | public void Destroy()
31 | {
32 | if (_content != null)
33 | {
34 | _content.Clear();
35 | _content = null;
36 | }
37 | }
38 |
39 | public bool HasChilds
40 | {
41 | get { return _content != null && _content.Count > 0; }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Map/Spatial/Indexer/SpatialLevelPowerIndexer.cs:
--------------------------------------------------------------------------------
1 | using ProgramMain.Map.Spatial.Types;
2 |
3 | namespace ProgramMain.Map.Spatial.Indexer
4 | {
5 | public class SpatialLevelPowerIndexer where TNode : ISpatialTreeNode
6 | {
7 | private readonly SpatialSheetPowerTypes[] _power;
8 | private readonly SpatialTree _tree;
9 |
10 | internal SpatialLevelPowerIndexer(SpatialTree tree)
11 | {
12 | _tree = tree;
13 | _power = new SpatialSheetPowerTypes[_tree.SpatialDepth];
14 | }
15 |
16 | public SpatialSheetPowerTypes this[int level]
17 | {
18 | get
19 | {
20 | if (level > 0 && level <= _power.Length)
21 | return _power[level - 1];
22 | return SpatialSheetPowerTypes.None;
23 | }
24 | set
25 | {
26 | if (_tree.NodeCount > 0) return;
27 |
28 | if (level > 0 && level <= _power.Length)
29 | _power[level - 1] = value;
30 | }
31 | }
32 |
33 | //Zero level is virtual and always "None"
34 | public int Length
35 | {
36 | get { return _power.Length + 1; }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Map/Spatial/Indexer/SpatialSheetIndexer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Map/Spatial/Indexer/SpatialSheetIndexer.cs
--------------------------------------------------------------------------------
/Map/Spatial/SpatialQueryIterator.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 |
3 | namespace ProgramMain.Map.Spatial
4 | {
5 | internal class SpatialQueryIterator
6 | {
7 | public int Value { get; private set; }
8 |
9 | private SpatialQueryIterator()
10 | {
11 | Value = 0;
12 | }
13 |
14 | public static SpatialQueryIterator Start()
15 | {
16 | return new SpatialQueryIterator();
17 | }
18 |
19 | public void Next()
20 | {
21 | lock (this)
22 | {
23 | Value++;
24 | }
25 | }
26 |
27 | public override string ToString()
28 | {
29 | return Value.ToString(CultureInfo.InvariantCulture);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Map/Spatial/SpatialSheet.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using ProgramMain.Map.Google;
3 | using ProgramMain.Map.Spatial.Types;
4 | using ProgramMain.Map.Types;
5 |
6 | namespace ProgramMain.Map.Spatial
7 | {
8 | internal class SpatialSheet : SpatialSheetBase where TNode : ISpatialTreeNode
9 | {
10 | public CoordinateRectangle Rectangle { get; private set; }
11 |
12 | public SpatialSheet(SpatialTree tree, int level, int googleLevel, CoordinateRectangle rectangle)
13 | : base(tree, level, googleLevel)
14 | {
15 | Rectangle = rectangle;
16 | }
17 |
18 | public enum SheetActionType { Insert, Delete };
19 |
20 | internal void SheetAction(TNode node, SheetActionType actionType)
21 | {
22 | //Insert node to spatial index or remove node from spatial index
23 | if (!IsBottomSheet)
24 | {
25 | switch (node.NodeType)
26 | {
27 | case SpatialTreeNodeTypes.Point:
28 | PointSheetAction(node, actionType);
29 | break;
30 | case SpatialTreeNodeTypes.Line:
31 | LineSheetAction(node, actionType);
32 | break;
33 | case SpatialTreeNodeTypes.Rectangle:
34 | RectangleSheetAction(node, actionType);
35 | break;
36 | case SpatialTreeNodeTypes.Poligon:
37 | PoligonSheetAction(node, actionType);
38 | break;
39 | }
40 | }
41 | else
42 | {
43 | //Just do it on bottom level
44 | lock (this)
45 | {
46 | switch (actionType)
47 | {
48 | case SheetActionType.Insert:
49 | Content.Add(node);
50 | break;
51 | case SheetActionType.Delete:
52 | Content.Remove(node);
53 | break;
54 | }
55 | }
56 | }
57 | }
58 |
59 | private void PointSheetAction(TNode node, SheetActionType actionType)
60 | {
61 | var block = node.Coordinate.GetGoogleBlock(NextGoogleLevel);
62 | lock (this)
63 | {
64 | //point search in daughter sheet
65 | var sheet = Sheets[block];
66 |
67 | sheet.SheetAction(node, actionType);
68 |
69 | PostSheetAction(block, sheet, actionType);
70 | }
71 | }
72 |
73 | private void LineSheetAction(TNode node, SheetActionType actionType)
74 | {
75 | var blockViewLevel = NextGoogleLevel;
76 |
77 | var line = node.Rectangle;
78 | var rect = new GoogleRectangle(line, blockViewLevel).BlockView;
79 |
80 | var deltaX = (rect.Left <= rect.Right) ? 1 : -1;
81 | var deltaY = (rect.Top <= rect.Bottom) ? 1 : -1;
82 |
83 | //line search in daughter sheet
84 | for (var x = rect.Left; (deltaX == 1 && x <= rect.Right) || (deltaX == -1 && x >= rect.Right); x += deltaX)
85 | {
86 | for (var y = rect.Top; (deltaY == 1 && y <= rect.Bottom) || (deltaY == -1 && y >= rect.Bottom); y += deltaY)
87 | {
88 | var block = new GoogleBlock(x, y, blockViewLevel);
89 | var googleRect = (GoogleRectangle)block;
90 |
91 | if (googleRect.LineContains(line) != InterseptResult.None)
92 | {
93 | lock (this)
94 | {
95 | var sheet = Sheets[block];
96 |
97 | sheet.SheetAction(node, actionType);
98 |
99 | PostSheetAction(block, sheet, actionType);
100 | }
101 | }
102 | }
103 | }
104 | }
105 |
106 | private void RectangleSheetAction(TNode node, SheetActionType actionType)
107 | {
108 | var blockViewLevel = NextGoogleLevel;
109 |
110 | var rect = new GoogleRectangle(node.Rectangle, blockViewLevel).BlockView;
111 |
112 | var deltaX = (rect.Left <= rect.Right) ? 1 : -1;
113 | var deltaY = (rect.Top <= rect.Bottom) ? 1 : -1;
114 |
115 | //rectangle search in daughter sheet
116 | for (var x = rect.Left; (deltaX == 1 && x <= rect.Right) || (deltaX == -1 && x >= rect.Right); x += deltaX)
117 | {
118 | for (var y = rect.Top; (deltaY == 1 && y <= rect.Bottom) || (deltaY == -1 && y >= rect.Bottom); y += deltaY)
119 | {
120 | var block = new GoogleBlock(x, y, blockViewLevel);
121 | lock (this)
122 | {
123 | var sheet = Sheets[block];
124 |
125 | sheet.SheetAction(node, actionType);
126 |
127 | PostSheetAction(block, sheet, actionType);
128 | }
129 | }
130 | }
131 | }
132 |
133 | private void PoligonSheetAction(TNode node, SheetActionType actionType)
134 | {
135 | var blockViewLevel = NextGoogleLevel;
136 |
137 | var poligon = node.Poligon;
138 | var rect = new GoogleRectangle(poligon, blockViewLevel).BlockView;
139 |
140 | var deltaX = (rect.Left <= rect.Right) ? 1 : -1;
141 | var deltaY = (rect.Top <= rect.Bottom) ? 1 : -1;
142 |
143 | //poligon search in daughter sheet
144 | for (var x = rect.Left; (deltaX == 1 && x <= rect.Right) || (deltaX == -1 && x >= rect.Right); x += deltaX)
145 | {
146 | for (var y = rect.Top; (deltaY == 1 && y <= rect.Bottom) || (deltaY == -1 && y >= rect.Bottom); y += deltaY)
147 | {
148 | var block = new GoogleBlock(x, y, blockViewLevel);
149 | var googleRect = (GoogleRectangle)block;
150 |
151 | if (googleRect.PoligonContains(poligon) != InterseptResult.None)
152 | {
153 | lock (this)
154 | {
155 | var sheet = Sheets[block];
156 |
157 | sheet.SheetAction(node, actionType);
158 |
159 | PostSheetAction(block, sheet, actionType);
160 | }
161 | }
162 | }
163 | }
164 | }
165 |
166 | private void PostSheetAction(GoogleBlock block, SpatialSheet sheet, SheetActionType actionType)
167 | {
168 | switch (actionType)
169 | {
170 | case SheetActionType.Delete:
171 | {
172 | //delete sheet from index without elements
173 | if (sheet.IsEmpty)
174 | Sheets.Remove(block);
175 | } break;
176 | }
177 | }
178 |
179 | public void Query(HashSet hashSet, CoordinateRectangle rectangle, InterseptResult parentResult, SpatialQueryIterator i)
180 | {
181 | //Query elements on the map by coordinate ractengle(indexed search)
182 | lock (this)
183 | {
184 | if (!IsBottomSheet)
185 | {
186 | if (Sheets.HasChilds)
187 | {
188 | foreach (var sheet in Sheets.Values)
189 | {
190 | var res = parentResult == InterseptResult.Supersets ? InterseptResult.Supersets : InterseptResult.None;
191 |
192 | if (res != InterseptResult.Supersets)
193 | {
194 | i.Next();
195 |
196 | res = sheet.Rectangle.RectangleContains(rectangle);
197 | }
198 | if (res != InterseptResult.None)
199 | {
200 | sheet.Query(hashSet, rectangle, res, i);
201 | }
202 | if (res == InterseptResult.Contains) break;
203 | }
204 | }
205 | }
206 | else if (Content.HasChilds)
207 | {
208 | foreach (var node in Content.Values)
209 | {
210 | var res = parentResult == InterseptResult.Supersets ? InterseptResult.Supersets : InterseptResult.None;
211 | if (res != InterseptResult.Supersets)
212 | {
213 | i.Next();
214 |
215 | switch (node.NodeType)
216 | {
217 | case SpatialTreeNodeTypes.Point:
218 | res = rectangle.PointContains(node.Coordinate);
219 | break;
220 | case SpatialTreeNodeTypes.Line:
221 | res = rectangle.LineContains(node.Rectangle);
222 | break;
223 | case SpatialTreeNodeTypes.Rectangle:
224 | res = rectangle.RectangleContains(node.Rectangle);
225 | break;
226 | case SpatialTreeNodeTypes.Poligon:
227 | res = rectangle.PoligonContains(node.Poligon);
228 | break;
229 | }
230 | }
231 | if (res != InterseptResult.None)
232 | {
233 | hashSet.Add(node);
234 | }
235 | }
236 | }
237 | }
238 | }
239 |
240 | public void Distance(HashSet hashSet, Coordinate coordinate, double variance, SpatialQueryIterator i)
241 | {
242 | //Query elements on the map close to coordinate (indexed search)
243 | lock (this)
244 | {
245 | if (!IsBottomSheet)
246 | {
247 | if (Sheets.HasChilds)
248 | {
249 | foreach (var sheet in Sheets.Values)
250 | {
251 | i.Next();
252 |
253 | if (sheet.Rectangle.RectangeDistance(coordinate) <= variance)
254 | {
255 | sheet.Distance(hashSet, coordinate, variance, i);
256 | }
257 | }
258 | }
259 | }
260 | else if (Content.HasChilds)
261 | {
262 | foreach (var node in Content.Values)
263 | {
264 | i.Next();
265 |
266 | double distance = -1;
267 | switch (node.NodeType)
268 | {
269 | case SpatialTreeNodeTypes.Point:
270 | distance = node.Coordinate.Distance(coordinate);
271 | break;
272 | case SpatialTreeNodeTypes.Line:
273 | distance = node.Rectangle.LineDistance(coordinate);
274 | break;
275 | case SpatialTreeNodeTypes.Rectangle:
276 | distance = node.Rectangle.RectangeDistance(coordinate);
277 | break;
278 | case SpatialTreeNodeTypes.Poligon:
279 | distance = node.Poligon.PoligonDistance(coordinate);
280 | break;
281 | }
282 |
283 | if (distance >= 0 && distance <= variance)
284 | {
285 | hashSet.Add(node);
286 | }
287 | }
288 | }
289 | }
290 | }
291 | }
292 | }
--------------------------------------------------------------------------------
/Map/Spatial/SpatialSheetBase.cs:
--------------------------------------------------------------------------------
1 | using ProgramMain.Map.Google;
2 | using ProgramMain.Map.Spatial.Indexer;
3 | using ProgramMain.Map.Spatial.Types;
4 |
5 | namespace ProgramMain.Map.Spatial
6 | {
7 | internal class SpatialSheetBase where TNode : ISpatialTreeNode
8 | {
9 | public int Level { get; private set; }
10 | public int GoogleLevel { get; private set; }
11 |
12 | //Daughter index sheets
13 | public readonly SpatialSheetIndexer Sheets;
14 |
15 | //Content array of index elemets on bottom index sheets
16 | public readonly SpatialContentIndexer Content;
17 |
18 | public bool IsEmpty
19 | {
20 | get
21 | {
22 | return !Sheets.HasChilds && !Content.HasChilds;
23 | }
24 | }
25 |
26 | public bool IsBottomSheet
27 | {
28 | get { return Level >= Sheets.PowerLength; }
29 | }
30 |
31 | public SpatialSheetBase(SpatialTree tree, int level, int googleLevel)
32 | {
33 | Level = level;
34 | GoogleLevel = googleLevel;
35 |
36 | Sheets = new SpatialSheetIndexer(this, tree);
37 | Content = new SpatialContentIndexer();
38 | }
39 |
40 | private int GoogleNumLevel(int level)
41 | {
42 | return (int)GoogleMapUtilities.NumLevel((int)Sheets.Power(level));
43 | }
44 |
45 | private int GoogleNextLevelAddon()
46 | {
47 | return GoogleNumLevel(Level) - 1;
48 | }
49 |
50 | public int NextGoogleLevel
51 | {
52 | get { return GoogleLevel + GoogleNextLevelAddon(); }
53 | }
54 |
55 | public void Clear()
56 | {
57 | lock (this)
58 | {
59 | if (!IsBottomSheet)
60 | {
61 | if (Sheets.HasChilds)
62 | {
63 | foreach (var sheet in Sheets.Values)
64 | {
65 | sheet.Clear();
66 | }
67 | Sheets.Destroy();
68 | }
69 | }
70 | else
71 | {
72 | Content.Destroy();
73 | }
74 | }
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/Map/Spatial/SpatialTree.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using ProgramMain.Map.Spatial.Indexer;
3 | using ProgramMain.Map.Spatial.Types;
4 | using ProgramMain.Map.Types;
5 |
6 | namespace ProgramMain.Map.Spatial
7 | {
8 | public class SpatialTree where TNode : ISpatialTreeNode
9 | {
10 | //Spatial index depth count, can be > 4
11 | internal readonly int SpatialDepth = 4;
12 |
13 | //Root spatial index sheet includes all daughter indexed sheets
14 | private SpatialSheet _root;
15 | public int NodeCount { get; private set; }
16 | public readonly SpatialLevelPowerIndexer Power;
17 |
18 | internal int[] NodeDimension = null;
19 |
20 | public SpatialTree()
21 | {
22 | NodeCount = 0;
23 | Power = new SpatialLevelPowerIndexer(this);
24 |
25 | SetLevels(
26 | SpatialSheetPowerTypes.Medium,
27 | SpatialSheetPowerTypes.Medium,
28 | SpatialSheetPowerTypes.Medium,
29 | SpatialSheetPowerTypes.Medium);
30 | }
31 |
32 | public SpatialTree(SpatialSheetPowerTypes level1, SpatialSheetPowerTypes level2, SpatialSheetPowerTypes level3, SpatialSheetPowerTypes level4)
33 | {
34 | NodeCount = 0;
35 | Power = new SpatialLevelPowerIndexer(this);
36 |
37 | SetLevels(level1, level2, level3, level4);
38 | }
39 |
40 | protected void SetLevels(SpatialSheetPowerTypes level1, SpatialSheetPowerTypes level2, SpatialSheetPowerTypes level3, SpatialSheetPowerTypes level4)
41 | {
42 | if (NodeCount > 0) return;
43 |
44 | Power[1] = level1;
45 | if (Power.Length > 2) Power[2] = level2;
46 | if (Power.Length > 3) Power[3] = level3;
47 | if (Power.Length > 4) Power[4] = level4;
48 |
49 | for (var i = 5; i < Power.Length; i++)
50 | {
51 | Power[i] = SpatialSheetPowerTypes.Low;
52 | }
53 | //Root spatial index sheet includes whole world
54 | _root = new SpatialSheet(this, 1, 1, CoordinateRectangle.Empty);
55 |
56 | //Array to grab index stats for tuning
57 | NodeDimension = new int[Power.Length - 1];
58 | }
59 |
60 | protected void Insert(TNode value)
61 | {
62 | lock (this)
63 | {
64 | NodeCount++;
65 | }
66 |
67 | _root.SheetAction(value, SpatialSheet.SheetActionType.Insert);
68 | }
69 |
70 | protected void Delete(TNode value)
71 | {
72 | lock (this)
73 | {
74 | NodeCount--;
75 | }
76 |
77 | _root.SheetAction(value, SpatialSheet.SheetActionType.Delete);
78 | }
79 |
80 | public HashSet Query(CoordinateRectangle rectangle)
81 | {
82 | //for debug to see how many iterations used for a search
83 | var i = SpatialQueryIterator.Start();
84 |
85 | var res = new HashSet();
86 | _root.Query(res, rectangle, InterseptResult.None, i);
87 |
88 | //index turning
89 | System.Diagnostics.Trace.WriteLine(string.Format("{5} Level nodes {1} {2} {3} {4}, Query iterations - {0:d}",
90 | i.Value, NodeDimension[0], NodeDimension[1], NodeDimension[2], NodeDimension[3], typeof(TNode).Name));
91 |
92 | return res;
93 | }
94 |
95 | public HashSet Distance(Coordinate coordinate, double variance)
96 | {
97 | //for debug to see how many iterations used for a search
98 | var i = SpatialQueryIterator.Start();
99 |
100 | var res = new HashSet();
101 | _root.Distance(res, coordinate, variance, i);
102 |
103 | //index turning
104 | System.Diagnostics.Trace.WriteLine(string.Format("{5} Level nodes {1} {2} {3} {4}, Distance iterations - {0:d}",
105 | i.Value, NodeDimension[0], NodeDimension[1], NodeDimension[2], NodeDimension[3], typeof(TNode).Name));
106 |
107 | return res;
108 | }
109 |
110 | public void Clear()
111 | {
112 | NodeCount = 0;
113 | _root.Clear();
114 |
115 | NodeDimension = new int[Power.Length - 1];
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/Map/Spatial/Types/SpatialSheetPowerTypes.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.Map.Spatial.Types
2 | {
3 | public enum SpatialSheetPowerTypes
4 | {
5 | None = 1,
6 | Few = 4,
7 | Low = 16,
8 | Medium = 64,
9 | High = 256,
10 | Extra = 1024,
11 | Ultra = 4096,
12 | Micro = 16384,
13 | Nano = 262144,
14 | Pico = 1048576
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Map/Spatial/Types/SpatialTreeNode.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 |
3 | namespace ProgramMain.Map.Spatial.Types
4 | {
5 | public interface ISpatialTreeNode
6 | {
7 | SpatialTreeNodeTypes NodeType { get; }
8 | Coordinate Coordinate { get; }
9 | CoordinateRectangle Rectangle { get; }
10 | CoordinatePoligon Poligon { get; }
11 | int RowId { get; }
12 | DataRow Row { get; } //!!!absolute
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Map/Spatial/Types/SpatialTreeNodeTypes.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.Map.Spatial.Types
2 | {
3 | public enum SpatialTreeNodeTypes {Point, Line, Rectangle, Poligon}
4 | }
5 |
--------------------------------------------------------------------------------
/Map/Types/InterseptResult.cs:
--------------------------------------------------------------------------------
1 | namespace ProgramMain.Map.Types
2 | {
3 | public enum InterseptResult { None, Intersepts, Contains, Supersets };
4 | }
5 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 | using ProgramMain.ExampleForms;
4 |
5 |
6 | namespace ProgramMain
7 | {
8 | static class Program
9 | {
10 | static Program()
11 | {
12 | MainForm = null;
13 | }
14 |
15 | public static FrmOpticMap MainForm { get; private set; }
16 |
17 | [STAThread]
18 | static void Main()
19 | {
20 | Application.EnableVisualStyles();
21 |
22 | MainForm = new FrmOpticMap();
23 | Application.Run(MainForm);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | using System.Resources;
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("Simple Map")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Agafonoff")]
12 | [assembly: AssemblyProduct("Simple Map")]
13 | [assembly: AssemblyCopyright("Copyright © None 2010")]
14 | [assembly: AssemblyTrademark("Simple Map")]
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 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 |
24 | [assembly: Guid("381aef28-6284-4d3f-bcdd-87cfc27deaaa")]
25 |
26 | // Version information for an assembly consists of the following four values:
27 | //
28 | // Major Version
29 | // Minor Version
30 | // Build Number
31 | // Revision
32 | //
33 | [assembly: AssemblyVersion("1.3.8.5")]
34 | [assembly: AssemblyFileVersion("1.3.8.5")]
35 | [assembly: NeutralResourcesLanguageAttribute("ru-RU")]
36 |
--------------------------------------------------------------------------------
/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 ProgramMain.Properties {
12 | using System;
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 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProgramMain.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap centermap_24 {
67 | get {
68 | object obj = ResourceManager.GetObject("centermap_24", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Bitmap.
75 | ///
76 | internal static System.Drawing.Bitmap print_24 {
77 | get {
78 | object obj = ResourceManager.GetObject("print_24", resourceCulture);
79 | return ((System.Drawing.Bitmap)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// Looks up a localized resource of type System.Drawing.Bitmap.
85 | ///
86 | internal static System.Drawing.Bitmap program_24 {
87 | get {
88 | object obj = ResourceManager.GetObject("program_24", resourceCulture);
89 | return ((System.Drawing.Bitmap)(obj));
90 | }
91 | }
92 |
93 | ///
94 | /// Looks up a localized resource of type System.Drawing.Bitmap.
95 | ///
96 | internal static System.Drawing.Bitmap refresh_16 {
97 | get {
98 | object obj = ResourceManager.GetObject("refresh_16", resourceCulture);
99 | return ((System.Drawing.Bitmap)(obj));
100 | }
101 | }
102 |
103 | ///
104 | /// Looks up a localized resource of type System.Drawing.Bitmap.
105 | ///
106 | internal static System.Drawing.Bitmap save_2_16x16 {
107 | get {
108 | object obj = ResourceManager.GetObject("save_2_16x16", resourceCulture);
109 | return ((System.Drawing.Bitmap)(obj));
110 | }
111 | }
112 |
113 | ///
114 | /// Looks up a localized resource of type System.Drawing.Bitmap.
115 | ///
116 | internal static System.Drawing.Bitmap vertex_16 {
117 | get {
118 | object obj = ResourceManager.GetObject("vertex_16", resourceCulture);
119 | return ((System.Drawing.Bitmap)(obj));
120 | }
121 | }
122 |
123 | ///
124 | /// Looks up a localized resource of type System.Drawing.Bitmap.
125 | ///
126 | internal static System.Drawing.Bitmap vertex_24 {
127 | get {
128 | object obj = ResourceManager.GetObject("vertex_24", resourceCulture);
129 | return ((System.Drawing.Bitmap)(obj));
130 | }
131 | }
132 |
133 | ///
134 | /// Looks up a localized resource of type System.Drawing.Bitmap.
135 | ///
136 | internal static System.Drawing.Bitmap vertex_8 {
137 | get {
138 | object obj = ResourceManager.GetObject("vertex_8", resourceCulture);
139 | return ((System.Drawing.Bitmap)(obj));
140 | }
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/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 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\refresh_16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Resources\print_24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Resources\vertex_16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | ..\Resources\vertex_8.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
134 | ..\Resources\centermap_24.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
135 |
136 |
137 | ..\Resources\vertex_24.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
138 |
139 |
140 | ..\Resources\program_24.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
141 |
142 |
143 | ..\Resources\save 2_16x16.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
144 |
145 |
--------------------------------------------------------------------------------
/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 ProgramMain.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("SimpleMap\\")]
29 | public string MapCacheLocalPath {
30 | get {
31 | return ((string)(this["MapCacheLocalPath"]));
32 | }
33 | set {
34 | this["MapCacheLocalPath"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("12")]
41 | public int StartZoomLevel {
42 | get {
43 | return ((int)(this["StartZoomLevel"]));
44 | }
45 | set {
46 | this["StartZoomLevel"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("http://mt1.google.com/vt/lyrs=m@146&hl=en&x={0}&y={1}&z={2}")]
53 | public string GoogleUrl {
54 | get {
55 | return ((string)(this["GoogleUrl"]));
56 | }
57 | }
58 |
59 | [global::System.Configuration.ApplicationScopedSettingAttribute()]
60 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
61 | [global::System.Configuration.DefaultSettingValueAttribute("1.3.8.5")]
62 | public string AppVersion {
63 | get {
64 | return ((string)(this["AppVersion"]));
65 | }
66 | }
67 |
68 | [global::System.Configuration.UserScopedSettingAttribute()]
69 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
70 | [global::System.Configuration.DefaultSettingValueAttribute("17")]
71 | public int MaxZoomLevel {
72 | get {
73 | return ((int)(this["MaxZoomLevel"]));
74 | }
75 | set {
76 | this["MaxZoomLevel"] = value;
77 | }
78 | }
79 |
80 | [global::System.Configuration.UserScopedSettingAttribute()]
81 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
82 | [global::System.Configuration.DefaultSettingValueAttribute("5")]
83 | public int MinZoomLevel {
84 | get {
85 | return ((int)(this["MinZoomLevel"]));
86 | }
87 | set {
88 | this["MinZoomLevel"] = value;
89 | }
90 | }
91 |
92 | [global::System.Configuration.UserScopedSettingAttribute()]
93 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
94 | [global::System.Configuration.DefaultSettingValueAttribute("37.24468")]
95 | public double LeftMapBound {
96 | get {
97 | return ((double)(this["LeftMapBound"]));
98 | }
99 | set {
100 | this["LeftMapBound"] = value;
101 | }
102 | }
103 |
104 | [global::System.Configuration.UserScopedSettingAttribute()]
105 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
106 | [global::System.Configuration.DefaultSettingValueAttribute("55.9469")]
107 | public double TopMapBound {
108 | get {
109 | return ((double)(this["TopMapBound"]));
110 | }
111 | set {
112 | this["TopMapBound"] = value;
113 | }
114 | }
115 |
116 | [global::System.Configuration.UserScopedSettingAttribute()]
117 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
118 | [global::System.Configuration.DefaultSettingValueAttribute("38.00891")]
119 | public double RightMapBound {
120 | get {
121 | return ((double)(this["RightMapBound"]));
122 | }
123 | set {
124 | this["RightMapBound"] = value;
125 | }
126 | }
127 |
128 | [global::System.Configuration.UserScopedSettingAttribute()]
129 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
130 | [global::System.Configuration.DefaultSettingValueAttribute("55.5601")]
131 | public double BottomMapBound {
132 | get {
133 | return ((double)(this["BottomMapBound"]));
134 | }
135 | set {
136 | this["BottomMapBound"] = value;
137 | }
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SimpleMap\
7 |
8 |
9 | 12
10 |
11 |
12 | http://mt1.google.com/vt/lyrs=m@146&hl=en&x={0}&y={1}&z={2}
13 |
14 |
15 | 1.3.8.5
16 |
17 |
18 | 17
19 |
20 |
21 | 5
22 |
23 |
24 | 37.24468
25 |
26 |
27 | 55.9469
28 |
29 |
30 | 38.00891
31 |
32 |
33 | 55.5601
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SimpleMap
2 |
3 | This is fully workable sample project on C# for Visual Studio 2012 or above.
4 | You can download and run SimpleMap.exe. Or download and compile the source code.
5 |
6 | SimpleMap/ExampleForms/FrmMapDownloader.cs demonstrates how to download google map area as single image (GetFullMapThread function) or how to cache google map on local disk (DownloadThread function).
7 |
8 | SimpleMap/ExampleForms/Controls/MapCtl.cs demostrates how to draw cached google map images to screen with custom objects as lines, bitmaps etc.
9 |
10 | The problem, project solve:
11 |
12 | Fast image(gif,png,jpg) draw to screen trhough GDI+ written pure on C# without any direct mapping to WinApi.
13 | Double buffering technology, all image changes draw into memory buffer and then changes apply to the screen.
14 | Download map images from google.
15 | Support google map coordinate system through sub classes and operators. Translate google coordinates to longitude and latitude. Translate longitude and latitude to google coordinates. Math operators support to work with coordinates.
16 | Cache google map files on disk.
17 | Download google image file cache to local storage.
18 | Save google map as one image.
19 | Base classes to draw any map layers.
20 | Spatial in-memory index with fast search by coordinates based on google map coordinate system.
21 | Spatial index tuning.
22 | Spatial index supported objects are: Point, Line, Rectangle, Poligon(patially suppoted).
23 | Sample demonstrates how You can use maps in your projects. It is absolutely free for use.
24 |
25 | Thanx.
26 |
--------------------------------------------------------------------------------
/Resources/centermap_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/centermap_24.png
--------------------------------------------------------------------------------
/Resources/print_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/print_24.png
--------------------------------------------------------------------------------
/Resources/program_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/program_24.png
--------------------------------------------------------------------------------
/Resources/refresh_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/refresh_16.png
--------------------------------------------------------------------------------
/Resources/save 2_16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/save 2_16x16.png
--------------------------------------------------------------------------------
/Resources/vertex_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/vertex_16.png
--------------------------------------------------------------------------------
/Resources/vertex_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/vertex_24.png
--------------------------------------------------------------------------------
/Resources/vertex_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/Resources/vertex_8.png
--------------------------------------------------------------------------------
/Settings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using ProgramMain.Map;
4 | using ProgramMain.Map.Google;
5 |
6 | // ReSharper disable CheckNamespace
7 | namespace ProgramMain.Properties {
8 | // ReSharper restore CheckNamespace
9 |
10 |
11 | // This class allows you to handle specific events on the settings class:
12 | // The SettingChanging event is raised before a setting's value is changed.
13 | // The PropertyChanged event is raised after a setting's value is changed.
14 | // The SettingsLoaded event is raised after the setting values are loaded.
15 | // The SettingsSaving event is raised before the setting values are saved.
16 | internal sealed partial class Settings {
17 |
18 | // ReSharper disable EmptyConstructor
19 | public Settings() {
20 | // ReSharper restore EmptyConstructor
21 | // // To add event handlers for saving and changing settings, uncomment the lines below:
22 | //
23 | // this.SettingChanging += this.SettingChangingEventHandler;
24 | //
25 | // this.SettingsSaving += this.SettingsSavingEventHandler;
26 | //
27 | }
28 |
29 | // ReSharper disable UnusedMember.Local
30 | private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
31 | // Add code to handle the SettingChangingEvent event here.
32 | if (sender != null && e != null)
33 | {
34 |
35 | }
36 | }
37 |
38 | private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
39 | // Add code to handle the SettingsSaving event here.
40 | if (sender != null && e != null)
41 | {
42 |
43 | }
44 | }
45 | // ReSharper restore UnusedMember.Local
46 |
47 | public static string GetMapFileName(GoogleBlock block)
48 | {
49 | var mapPath = Default.MapCacheLocalPath;
50 | if (!Path.IsPathRooted(mapPath))
51 | {
52 | mapPath = Path.Combine(
53 | Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
54 | mapPath);
55 | }
56 | var fileName = Path.Combine(mapPath, block.Level + "\\" + (block.X / 100) + "_" + (block.Y / 100) + "\\" + block.Level + "_" + block.X + "_" + block.Y + ".png");
57 |
58 | return fileName;
59 | }
60 |
61 | private static Coordinate _centerMapBound;
62 |
63 | public static Coordinate CenterMapBound
64 | {
65 | get
66 | {
67 | if (_centerMapBound == null)
68 | {
69 | var rectBound = new CoordinateRectangle(Default.LeftMapBound, Default.TopMapBound, Default.RightMapBound, Default.BottomMapBound);
70 | _centerMapBound = rectBound.LineMiddlePoint;
71 | }
72 | return _centerMapBound;
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/SimpleMap.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Publish\
5 | http://install.simplemap.ru/
6 |
7 |
8 |
9 |
10 | en-US
11 | false
12 |
13 |
--------------------------------------------------------------------------------
/SimpleMap.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleMap", "SimpleMap.csproj", "{FE54D43D-1518-478D-94C1-42656E024E1D}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {FE54D43D-1518-478D-94C1-42656E024E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {FE54D43D-1518-478D-94C1-42656E024E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {FE54D43D-1518-478D-94C1-42656E024E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {FE54D43D-1518-478D-94C1-42656E024E1D}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/default.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agafonoff2000/SimpleMap/7893f78f2ac8a5c070a7b98c993dd168aff16b83/default.ico
--------------------------------------------------------------------------------