前回作成した、索引図プラグインを改良した。
1.前回からの改良点
・前回は、索引図用のパネルの下部に、泣く泣く住所検索機能をつけていたが、
これを止めて、OpenLayersのように、主題図上に表示させるようにした。
・前回は、索引図のレイヤーは、定義されたshpファイルを読み込ませていたが、
これを止めて、Dotspatialのプロジェクトファイルを読み込ませるようにした。
これにより、索引図のレイヤーに、shpだけでなく、DBや画像ファイルなど様々な
形式が利用できるようになった。
2.索引図のコントロールを作成
Map上に索引図のコントロールを登録し、常に、Map上に表示されるようにした。
また、Mapのリサイズ時、画面移動時にも、常に右上に表示されるようにした。
3.索引図用のファンクションを作成
これは前回と変わらず。
4.プラグインクラスを作成
これは、かなり変更した。主な処理は以下の通り。
・索引図プラグインの活性化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public override void Activate() { this.CreateOverviewMap(); this.App.Map.MapFrame.ViewExtentsChanged += OnMapViewExtentsChanged; this.OverviewMap.MapFunctions.Clear(); this.OverviewMap.FunctionMode = FunctionMode.None; this.OverviewMap.Projection = this.App.Map.Projection; this.OverviewMap.MapFrame.ProjectionModeDefine = ActionMode.Always; this.MoveMapAreaFunction = new MoveMapAreaFunction(this.OverviewMap); this.MoveMapAreaFunction.MainMap = this.App.Map; this.OverviewMap.MapFunctions.Add(this.MoveMapAreaFunction); this.LoadOverViewMap(); base.Activate(); } |
・索引図プラグインの非活性化
1 2 3 4 5 6 7 |
public override void Deactivate() { this.App.Map.MapFrame.ViewExtentsChanged -= OnMapViewExtentsChanged; this.App.HeaderControl.RemoveAll(); this.App.DockManager.Remove("kOvMap"); base.Deactivate(); } |
・索引図用のパネルの作成
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 |
private void CreateOverviewMap() { var map = (Map)this.App.Map; map.Resize += map_Resize; var form = (Form)map.Parent; form.LocationChanged += form_LocationChanged; form.Shown += form_Shown; var ovmap = new Map(); ovmap.AllowDrop = true; ovmap.BackColor = Drawing.Color.White; ovmap.CollectAfterDraw = false; ovmap.CollisionDetection = false; ovmap.ExtendBuffer = false; ovmap.FunctionMode = DotSpatial.Controls.FunctionMode.None; ovmap.IsBusy = false; ovmap.IsZoomedToMaxExtent = false; ovmap.Name = "map1"; ovmap.ProgressHandler = null; ovmap.ProjectionModeDefine = DotSpatial.Controls.ActionMode.Prompt; ovmap.ProjectionModeReproject = DotSpatial.Controls.ActionMode.Prompt; ovmap.RedrawLayersWhileResizing = false; ovmap.SelectionEnabled = true; ovmap.Tag = "OverviewMap"; ovmap.ZoomOutFartherThanMaxExtent = false; ovmap.Dock = DockStyle.Fill; this.OverviewMap = ovmap; this.ovmapPanel = new GroupControl(); this.ovmapPanel.Dock = DockStyle.None; this.ovmapPanel.Controls.Add(ovmap); this.ovmapPanel.Size = new Drawing.Size(150, 150); this.ovmapPanel.Location = new Drawing.Point(map.Size.Width - this.ovmapPanel.Size.Width, 0); this.ovmapPanel.Padding = new Windows.Forms.Padding(3); this.ovmapPanel.ShowCaption = false; var rc = new ResizeableControl(this.ovmapPanel); map.Controls.Add(this.ovmapPanel); } |
・索引図用のプロジェクトファイル読込と、主題図の範囲を表す矩形レイヤーを作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private void LoadOverViewMap() { var file = ConfigurationManager.AppSettings["overview_map.dspx"]; var mLayers = this.DeserializeLayers(file); this.OverviewMap.Layers.Clear(); this.OverviewMap.Layers.AddRange(mLayers); this.MapAreaLayer = this.OverviewMap.Layers.Add(new FeatureSet(FeatureType.Line)); ((LineSymbolizer)this.MapAreaLayer.Symbolizer).SetFillColor(Color.Red); ((LineSymbolizer)this.MapAreaLayer.Symbolizer).SetWidth(2); var linearRing = this.OverviewMap.Extent.ToEnvelope().ToLinearRing(); this.MapAreaLayer.DataSet.AddFeature(linearRing); this.MoveMapAreaFunction.ActiveLayer = this.MapAreaLayer; this.MoveMapAreaFunction.Activate(); this.OverviewMap.ZoomToMaxExtent(); this.OverviewMap.Resized += OnResized; } |
・索引図のリサイズ対応
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private void OnResized(object sender, EventArgs args) { const double eps = 1e-7; Envelope layerEnvelope = this.OverviewMap.ViewExtents.ToEnvelope(); if (layerEnvelope.Width > eps && layerEnvelope.Height > eps) { layerEnvelope.ExpandBy(layerEnvelope.Width / 10, layerEnvelope.Height / 10); // work item #84 } else { double zoomInFactor = 0.05; //fixed zoom-in by 10% - 5% on each side double newExtentWidth = this.OverviewMap.ViewExtents.Width * zoomInFactor; double newExtentHeight = this.OverviewMap.ViewExtents.Height * zoomInFactor; layerEnvelope.ExpandBy(newExtentWidth, newExtentHeight); } this.OverviewMap.ViewExtents = layerEnvelope.ToExtent(); } |
・主題図の表示範囲変更時の、索引図の表示対応
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private void OnMapViewExtentsChanged(object sender, ExtentArgs args) { if (this.OverviewMap.Layers.Count == 0 || this.MapAreaLayer == null) { return; } this.MapAreaLayer.DataSet.Features.Clear(); var linearRing = args.Extent.ToEnvelope().ToLinearRing(); this.MapAreaLayer.DataSet.AddFeature(linearRing); if (!this.OverviewMap.IsZoomedToMaxExtent) { var center = linearRing.Centroid.Coordinate; this.OverviewMap.ViewExtents.SetCenter(linearRing.Centroid.Coordinate); } this.OverviewMap.MapFrame.Invalidate(); } |
・読み込んだプロジェクトファイルからのレイヤーの取込
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private IMapLayerCollection DeserializeLayers(string fileName) { IMapLayerCollection layers = null; var layoutXmlDoc = new XmlDocument(); var xmlDeserializer = new XmlDeserializer(); var xml = File.ReadAllText(fileName); layoutXmlDoc.LoadXml(xml); var root = layoutXmlDoc.DocumentElement; var objs = xmlDeserializer.Deserialize<Object[]>(xml); if (objs.Length != 3) { return layers; } var map = objs[1] as Map; layers = map.Layers; return layers; } |