#region Disclaimer / License
// Copyright (C) 2010, Jackie Ng
// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Maestro.Shared.UI;
using Maestro.Editors.Common;
using OSGeo.MapGuide.ObjectModels.Common;
using OSGeo.MapGuide.ObjectModels.LayerDefinition;
using OSGeo.MapGuide.MaestroAPI;
using OSGeo.MapGuide.ObjectModels.MapDefinition;
using System.Globalization;
using OSGeo.MapGuide.MaestroAPI.CoordinateSystem;
using OSGeo.MapGuide.ObjectModels;
namespace Maestro.Editors.MapDefinition
{
//[ToolboxItem(true)]
[ToolboxItem(false)]
internal partial class MapSettingsSectionCtrl : EditorBindableCollapsiblePanel
{
public MapSettingsSectionCtrl()
{
InitializeComponent();
}
private IMapDefinition _map;
const string META_START = "";
const string META_END = "";
private IEditorService _service;
private bool _updatingExtents = false;
public override void Bind(IEditorService service)
{
cmbBackgroundColor.ResetColors();
_service = service;
_service.RegisterCustomNotifier(this);
_map = (IMapDefinition)service.GetEditedResource();
var bmeta = new Binding("Text", _map, "Metadata");
bmeta.Parse += (sender, e) =>
{
e.Value = META_START + e.Value + META_END;
};
bmeta.Format += (sender, e) =>
{
if (e.Value != null)
{
var str = e.Value.ToString();
if (str.StartsWith(META_START) && str.EndsWith(META_END))
{
e.Value = str.Substring(META_START.Length, str.Length - (META_START.Length + META_END.Length));
}
}
};
TextBoxBinder.BindText(txtDescription, bmeta);
TextBoxBinder.BindText(txtCoordinateSystem, _map, "CoordinateSystem");
//ColorComboBox requires custom databinding
cmbBackgroundColor.CurrentColor = _map.BackgroundColor;
cmbBackgroundColor.SelectedIndexChanged += (sender, e) =>
{
_map.BackgroundColor = cmbBackgroundColor.CurrentColor;
};
_map.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == "BackgroundColor")
{
cmbBackgroundColor.CurrentColor = _map.BackgroundColor;
}
else if (e.PropertyName == "Extents")
{
UpdateExtentsFromMap();
}
};
txtLowerX.Text = _map.Extents.MinX.ToString(CultureInfo.InvariantCulture);
txtLowerY.Text = _map.Extents.MinY.ToString(CultureInfo.InvariantCulture);
txtUpperX.Text = _map.Extents.MaxX.ToString(CultureInfo.InvariantCulture);
txtUpperY.Text = _map.Extents.MaxY.ToString(CultureInfo.InvariantCulture);
txtLowerX.TextChanged += (s, e) =>
{
if (_updatingExtents)
return;
if (txtLowerX.Text.EndsWith(".")) //Maybe typing in decimals atm
return;
double d;
if (double.TryParse(txtLowerX.Text, out d))
_map.Extents.MinX = d;
};
txtLowerY.TextChanged += (s, e) =>
{
if (_updatingExtents)
return;
if (txtLowerY.Text.EndsWith(".")) //Maybe typing in decimals atm
return;
double d;
if (double.TryParse(txtLowerY.Text, out d))
_map.Extents.MinY = d;
};
txtUpperX.TextChanged += (s, e) =>
{
if (_updatingExtents)
return;
if (txtUpperX.Text.EndsWith(".")) //Maybe typing in decimals atm
return;
double d;
if (double.TryParse(txtUpperX.Text, out d))
_map.Extents.MaxX = d;
};
txtUpperY.TextChanged += (s, e) =>
{
if (_updatingExtents)
return;
if (txtUpperY.Text.EndsWith(".")) //Maybe typing in decimals atm
return;
double d;
if (double.TryParse(txtUpperY.Text, out d))
_map.Extents.MaxY = d;
};
_map.Extents.PropertyChanged += (sender, e) =>
{
UpdateExtentsFromMap();
OnResourceChanged();
};
}
private void UpdateExtentsFromMap()
{
_updatingExtents = true;
try
{
txtLowerX.Text = _map.Extents.MinX.ToString(CultureInfo.InvariantCulture);
txtLowerY.Text = _map.Extents.MinY.ToString(CultureInfo.InvariantCulture);
txtUpperX.Text = _map.Extents.MaxX.ToString(CultureInfo.InvariantCulture);
txtUpperY.Text = _map.Extents.MaxY.ToString(CultureInfo.InvariantCulture);
}
finally
{
_updatingExtents = false;
}
}
private void btnPickCs_Click(object sender, EventArgs e)
{
string cs = _service.GetCoordinateSystem();
if (!string.IsNullOrEmpty(cs))
{
string oldCs = txtCoordinateSystem.Text;
txtCoordinateSystem.Text = cs;
if (_map.Extents != null && !string.IsNullOrEmpty(oldCs) && !string.IsNullOrEmpty(cs) && !oldCs.Equals(cs))
{
//NOTE: We really should be using CS-Map (MgCoordinateSystem) here as its
//transformation capabilities are more comprehensive, but we'd break mono
//compatibility by doing so. Unless of course, Linux swig'd assemblies are
//identical to the windows one, allowing for a clean swap of the DllImport'ed
//native library
//Transform current extents
try
{
var trans = new DefaultSimpleTransform(oldCs, cs);
var oldExt = _map.Extents;
double llx;
double lly;
double urx;
double ury;
trans.Transform(oldExt.MinX, oldExt.MinY, out llx, out lly);
trans.Transform(oldExt.MaxX, oldExt.MaxY, out urx, out ury);
_map.Extents.MinX = llx;
_map.Extents.MinY = lly;
_map.Extents.MaxX = urx;
_map.Extents.MaxY = ury;
}
catch (Exception ex)
{
MessageBox.Show(string.Format(Properties.Resources.CoordinateTransformationFailed, ex.Message));
}
}
}
}
private void btnSetZoom_Click(object sender, EventArgs e)
{
using (new WaitCursor(this))
{
List layers = new List();
foreach (var lyr in _map.MapLayer)
{
layers.Add((ILayerDefinition)_service.ResourceService.GetResource(lyr.ResourceId));
}
if (_map.BaseMap != null)
{
foreach (var group in _map.BaseMap.BaseMapLayerGroup)
{
foreach (var layer in group.BaseMapLayer)
{
layers.Add((ILayerDefinition)_service.ResourceService.GetResource(layer.ResourceId));
}
}
}
bool hasFailures = false;
var env = Util.GetCombinedExtents(_map, layers, out hasFailures);
if (env != null)
{
_map.SetExtents(env.MinX, env.MinY, env.MaxX, env.MaxY);
if (hasFailures)
MessageBox.Show(Properties.Resources.WarningMapExtentCalculation, Properties.Resources.TitleWarning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else
{
MessageBox.Show(Properties.Resources.ErrorMapExtentCalculationFailed, Properties.Resources.TitleError, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
internal class Util
{
public static IEnvelope GetCombinedExtents(IMapDefinition mapDef, IEnumerable layers, out bool hasFailures)
{
hasFailures = false;
Check.NotNull(layers, "layers");
IEnvelope env = null;
foreach (var layer in layers)
{
string wkt;
var e1 = layer.GetSpatialExtent(true, out wkt);
if (wkt != mapDef.CoordinateSystem)
{
//Transform if not the same, otherwise assume either arbitrary or same as the map
if (!string.IsNullOrEmpty(wkt))
e1 = Utility.TransformEnvelope(e1, wkt, mapDef.CoordinateSystem);
}
if (e1 != null)
{
if (env == null)
{
env = e1;
}
else
{
if (e1.MinX < env.MinX)
env.MinX = e1.MinX;
if (e1.MinY < env.MinY)
env.MinY = e1.MinY;
if (e1.MaxX > env.MaxX)
env.MaxX = e1.MaxX;
if (e1.MaxY > env.MaxY)
env.MaxY = e1.MaxY;
}
}
else
{
hasFailures = true;
System.Diagnostics.Trace.TraceWarning("Could not transform extent of layer " + layer.ResourceID + " to the map definition's coordinate system. Extents ignored");
}
}
return env;
}
}
}
}