#region Disclaimer / License
// Copyright (C) 2009, Kenneth Skovhede
// http://www.hexad.dk, opensource@hexad.dk
//
// 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;
using System.Collections.Generic;
namespace OSGeo.MapGuide.MaestroAPI {
///
/// Defines a Map, in either the library or session repository
///
[System.Xml.Serialization.XmlRootAttribute("MapDefinition", Namespace="", IsNullable=false)]
public class MapDefinition
{
protected ServerConnectionI m_serverConnection;
///
/// Gets or sets the connection used in various operations performed on this object
///
[System.Xml.Serialization.XmlIgnore()]
public ServerConnectionI CurrentConnection
{
get { return m_serverConnection; }
set
{
m_serverConnection = value;
foreach(MapLayerType layer in this.Layers)
layer.Parent = this;
}
}
protected string m_resourceId;
[System.Xml.Serialization.XmlIgnore()]
public string ResourceId
{
get { return m_resourceId; }
set { m_resourceId = value; }
}
public static readonly string SchemaName = "MapDefinition-1.0.0.xsd";
[System.Xml.Serialization.XmlAttribute("noNamespaceSchemaLocation", Namespace="http://www.w3.org/2001/XMLSchema-instance")]
public string XsdSchema
{
get { return SchemaName; }
set { if (value != SchemaName) throw new System.Exception("Cannot set the schema name"); }
}
protected string m_name;
protected string m_coordinateSystem;
protected Box2DType m_extents;
protected System.Drawing.Color m_backgroundColor;
protected string m_metadata;
protected MapLayerTypeCollection m_mapLayer;
protected MapLayerGroupTypeCollection m_mapLayerGroup;
protected MapDefinitionTypeBaseMapDefinition m_baseMapDefinition;
public MapDefinition()
{
m_name = "";
m_coordinateSystem = "";
m_extents = new Box2DType();
m_backgroundColor = System.Drawing.Color.FromArgb(0,0,0);
m_metadata = "";
m_mapLayer = new MapLayerTypeCollection();
m_mapLayerGroup = new MapLayerGroupTypeCollection();
m_baseMapDefinition = new MapDefinitionTypeBaseMapDefinition();
}
///
public string Name
{
get
{
return this.m_name;
}
set
{
this.m_name = value;
}
}
///
public string CoordinateSystem
{
get
{
return this.m_coordinateSystem;
}
set
{
this.m_coordinateSystem = value;
}
}
///
public Box2DType Extents
{
get
{
return this.m_extents;
}
set
{
this.m_extents = value;
}
}
[System.Xml.Serialization.XmlElementAttribute("BackgroundColor")]
public string BackGroundColorAsHTML
{
get
{
return Utility.SerializeHTMLColor(m_backgroundColor, true);
/*return new byte[]
{
m_backgroundColor.A,
m_backgroundColor.R,
m_backgroundColor.G,
m_backgroundColor.B
};*/
}
set
{
if (value == null)
m_backgroundColor = System.Drawing.Color.White;
else
m_backgroundColor = Utility.ParseHTMLColor(value); //System.Drawing.Color.FromArgb(value[0], value[1], value[2], value[3]);
}
}
///
[System.Xml.Serialization.XmlIgnore()]
public System.Drawing.Color BackgroundColor
{
get
{
return this.m_backgroundColor;
}
set
{
this.m_backgroundColor = value;
}
}
///
/// Gets or sets the Metadata for the map
///
public string Metadata
{
get
{
return this.m_metadata;
}
set
{
this.m_metadata = value;
}
}
///
/// Gets or sets the layers associated with this map
///
[System.Xml.Serialization.XmlElementAttribute("MapLayer")]
public MapLayerTypeCollection Layers
{
get { return this.m_mapLayer; }
set { this.m_mapLayer = value; }
}
///
/// Gets or sets the groups defined in this map
///
[System.Xml.Serialization.XmlElementAttribute("MapLayerGroup")]
public MapLayerGroupTypeCollection LayerGroups
{
get { return this.m_mapLayerGroup; }
set { this.m_mapLayerGroup = value; }
}
///
public MapDefinitionTypeBaseMapDefinition BaseMapDefinition
{
get
{
return this.m_baseMapDefinition;
}
set
{
this.m_baseMapDefinition = value;
}
}
///
/// Sorts the group list so parent groups are listed before child groups
///
public void SortGroupList()
{
if (m_mapLayerGroup == null || m_mapLayerGroup.Count < 2)
return;
List remaining = new List();
List mapped = new List();
Dictionary mappedElements = new Dictionary();
foreach (MapLayerGroupType g in m_mapLayerGroup)
if (string.IsNullOrEmpty(g.Group))
{
mapped.Add(g);
if (mappedElements.ContainsKey(g.Name))
throw new Exception(string.Format("The group {0} exists more than once", g.Name));
mappedElements.Add(g.Name, g);
}
else
remaining.Add(g);
bool anyRemoved = true;
while (remaining.Count > 0 && anyRemoved)
{
anyRemoved = false;
for (int i = 0; i < remaining.Count; i++)
{
if (mappedElements.ContainsKey(remaining[i].Group))
{
anyRemoved = true;
mapped.Add(remaining[i]);
if (mappedElements.ContainsKey(remaining[i].Name))
throw new Exception(string.Format("The group {0} exists more than once", remaining[i].Name));
mappedElements.Add(remaining[i].Name, remaining[i]);
remaining.RemoveAt(i);
i--;
}
}
}
if (remaining.Count > 0)
{
List names = new List();
foreach (MapLayerGroupType g in remaining)
names.Add(g.Name);
throw new Exception(string.Format("Found orphan groups: {0}", string.Join(",", names.ToArray())));
}
if (m_mapLayerGroup == null)
m_mapLayerGroup = new MapLayerGroupTypeCollection();
m_mapLayerGroup.Clear();
foreach (MapLayerGroupType g in mapped)
m_mapLayerGroup.Add(g);
}
}
public class Change
{
public enum ChangeType
{
removed,
added,
visibilityChanged,
displayInLegendChanged,
legendLabelChanged,
parentChanged,
selectabilityChanged,
definitionChanged
};
private ChangeType m_type;
private string m_params;
public ChangeType Type { get { return m_type; } }
public string Params { get { return m_params; } }
public Change()
{
}
public Change(ChangeType type, string param)
{
m_type = type;
m_params = param;
}
}
public class ChangeList
{
private string m_objectId;
private bool m_isLayer;
private ArrayList m_changes;
public string ObjectId { get { return m_objectId; } }
public bool IsLayer { get { return m_isLayer; } }
public ArrayList Changes { get { return m_changes; } }
public ChangeList()
{
m_changes = new ArrayList();
}
public ChangeList(string objectId, bool isLayer)
: this()
{
m_objectId = objectId;
m_isLayer = isLayer;
}
}
///
public class Box2DType
//: BinarySerializer.IBinarySerializeable
{
private System.Double m_minX;
private System.Double m_maxX;
private System.Double m_minY;
private System.Double m_maxY;
///
public System.Double MinX
{
get {
return this.m_minX;
}
set {
this.m_minX = value;
}
}
///
public System.Double MaxX {
get {
return this.m_maxX;
}
set {
this.m_maxX = value;
}
}
///
public System.Double MinY {
get {
return this.m_minY;
}
set {
this.m_minY = value;
}
}
///
public System.Double MaxY {
get {
return this.m_maxY;
}
set {
this.m_maxY = value;
}
}
internal void Deserialize(BinarySerializer.MgBinaryDeserializer d)
{
int classid = d.ReadClassId();
if (d.SiteVersion <= SiteVersions.GetVersion(KnownSiteVersions.MapGuideEP1_1) && classid != 18001)
throw new Exception("Invalid class identifier, expected Box2D");
if (d.SiteVersion > SiteVersions.GetVersion(KnownSiteVersions.MapGuideEP1_1) && classid != 20001)
throw new Exception("Invalid class identifier, expected Box2D");
int dimensions = d.ReadInt32();
if (dimensions != 2 && dimensions != 0)
throw new Exception("Bounding box for map had " + dimensions.ToString() + " dimensions, 2 was expected");
double x1 = d.ReadDouble();
double y1 = d.ReadDouble();
double x2 = d.ReadDouble();
double y2 = d.ReadDouble();
m_minX = Math.Min(x1, x2);
m_minY = Math.Min(y1, y2);
m_maxX = Math.Max(x1, x2);
m_maxY = Math.Max(y1, y2);
}
internal void Serialize(BinarySerializer.MgBinarySerializer s)
{
if (s.SiteVersion <= SiteVersions.GetVersion(KnownSiteVersions.MapGuideEP1_1))
s.WriteClassId(18001);
else
s.WriteClassId(20001);
s.Write((int)0);
s.Write(m_minX);
s.Write(m_minY);
s.Write(m_maxX);
s.Write(m_maxY);
}
}
///
public class MapDefinitionTypeBaseMapDefinition {
private DoubleCollection m_finiteDisplayScale;
private BaseMapLayerGroupCommonTypeCollection m_baseMapLayerGroup;
///
[System.Xml.Serialization.XmlElementAttribute("FiniteDisplayScale")]
public DoubleCollection FiniteDisplayScale {
get {
return this.m_finiteDisplayScale;
}
set {
this.m_finiteDisplayScale = value;
}
}
///
[System.Xml.Serialization.XmlElementAttribute("BaseMapLayerGroup")]
public BaseMapLayerGroupCommonTypeCollection BaseMapLayerGroup {
get {
return this.m_baseMapLayerGroup;
}
set {
this.m_baseMapLayerGroup = value;
}
}
}
///
public class BaseMapLayerGroupCommonType : MapLayerGroupCommonType {
private BaseMapLayerTypeCollection m_baseMapLayer;
///
[System.Xml.Serialization.XmlElementAttribute("BaseMapLayer")]
public BaseMapLayerTypeCollection BaseMapLayer {
get {
return this.m_baseMapLayer;
}
set {
this.m_baseMapLayer = value;
}
}
}
///
[System.Xml.Serialization.XmlIncludeAttribute(typeof(MapLayerType))]
public class BaseMapLayerType {
protected string m_name;
protected string m_resourceId;
protected bool m_selectable;
protected bool m_showInLegend;
protected string m_legendLabel;
protected bool m_expandInLegend;
[System.Xml.Serialization.XmlIgnore()]
public MapDefinition Parent { get { return m_parent; } set { m_parent = value; } }
protected MapDefinition m_parent = null;
///
public string Name
{
get {
return this.m_name;
}
set {
this.m_name = value;
}
}
///
public string ResourceId {
get {
return this.m_resourceId;
}
set {
this.m_resourceId = value;
}
}
///
public virtual bool Selectable {
get {
return this.m_selectable;
}
set {
this.m_selectable = value;
}
}
///
public bool ShowInLegend {
get {
return this.m_showInLegend;
}
set {
this.m_showInLegend = value;
}
}
///
public string LegendLabel {
get {
return this.m_legendLabel;
}
set {
this.m_legendLabel = value;
}
}
///
public bool ExpandInLegend {
get {
return this.m_expandInLegend;
}
set {
this.m_expandInLegend = value;
}
}
}
///
public class MapLayerType
: BaseMapLayerType
{
protected bool m_visible;
protected string m_group = "";
public MapLayerType()
: base()
{
}
///
/// Gets or sets the layer visibility, this attribute is combined with the layers DisplayScale, to determine actual visibility.
///
public virtual bool Visible {
get { return this.m_visible; }
set { this.m_visible = value; }
}
///
/// Gets or sets the Group that this layer belongs to
///
public string Group {
get { return this.m_group; }
set { this.m_group = value; }
}
///
/// Gets the full path of the group
///
/// The string used to separate the individual levels
/// The parent mapdefinition, use null for the current parent
/// The full path or null if no such group is found
public string GetFullPath(string separator, MapDefinition parent)
{
//TODO: Protect against infinite recursion
if (parent == null)
parent = m_parent;
if (parent == null)
throw new Exception("Cannot determine full path on group that is not attached to a map");
if (m_group == null || m_group.Length == 0)
return m_name;
else
{
MapLayerGroupType mlg = null;
if (parent.LayerGroups != null)
foreach(MapLayerGroupType g in parent.LayerGroups)
if (g.Name == m_group)
{
mlg = g;
break;
}
if (mlg == null)
return null;
return mlg.GetFullPath(separator, parent) + separator + m_name;
}
}
///
/// Returns a list of layers present in the current group. This method does NOT run in O(n).
///
[System.Xml.Serialization.XmlIgnore()]
public MapLayerTypeCollection Layers
{
get
{
if (m_parent == null)
return null;
string s = this.GetFullPath("/", m_parent);
MapLayerTypeCollection layers = new MapLayerTypeCollection();
foreach(MapLayerType ml in m_parent.Layers)
if (ml.GetFullPath("/", m_parent).StartsWith(s))
layers.Add(ml);
return layers;
}
}
}
///
[System.Xml.Serialization.XmlIncludeAttribute(typeof(BaseMapLayerGroupCommonType))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(MapLayerGroupType))]
public class MapLayerGroupCommonType {
protected string m_name;
protected bool m_visible;
protected bool m_showInLegend;
protected bool m_expandInLegend;
protected string m_legendLabel;
///
/// Gets or sets the name of the group
///
public string Name {
get {
return this.m_name;
}
set {
this.m_name = value;
}
}
///
/// Gets or set the group visibility
///
public bool Visible {
get {
return this.m_visible;
}
set {
this.m_visible = value;
}
}
///
/// Gets or sets a value indicating if this group is displayed in the map legend
///
public bool ShowInLegend {
get {
return this.m_showInLegend;
}
set {
this.m_showInLegend = value;
}
}
///
/// Gets or sets a value indicating if this groups layers are displayed in the map legend
///
public bool ExpandInLegend {
get {
return this.m_expandInLegend;
}
set {
this.m_expandInLegend = value;
}
}
///
/// Gets or sets the label to use for this group
///
public string LegendLabel {
get {
return this.m_legendLabel;
}
set {
this.m_legendLabel = value;
}
}
}
///
public class MapLayerGroupType : MapLayerGroupCommonType {
private string m_group;
///
public string Group {
get {
return this.m_group;
}
set {
this.m_group = value;
}
}
protected MapDefinition m_parent = null;
internal MapDefinition Parent
{
get { return m_parent; }
set { m_parent = value; }
}
///
/// Gets the full path of the group
///
/// The string used to separate the individual levels
/// The parent mapdefinition, use null for the current parent
///
public string GetFullPath(string separator, MapDefinition parent)
{
//TODO: Protect against infinite recursion
if (parent == null)
parent = m_parent;
if (parent == null)
throw new Exception("Cannot determine full path on group that is not attached to a map");
if (m_group == null || m_group.Length == 0)
return m_name;
else
{
MapLayerGroupType mlg = null;
if (parent.LayerGroups != null)
foreach(MapLayerGroupType g in parent.LayerGroups)
if (g.Name == m_group)
{
mlg = g;
break;
}
if (mlg == null)
return null;
return mlg.GetFullPath(separator, parent) + separator + m_name;
}
}
}
public class MapLayerTypeCollection : System.Collections.CollectionBase {
///
/// Gets or sets the index of a layer, given the layer name.
/// Is case sensitive but will search case insensitive if no layer matches with case sensitive.
///
/// The name of the layer
/// The index of the layer, or -1 if no such layer could be found
public int IndexOf(string name)
{
int rml = -1;
for (int i = 0; i < this.Count; i++)
if (this[i].Name == name)
return i;
else if (rml == -1 && this[i].Name.ToLower() == name.ToLower())
rml = i;
return rml;
}
///
/// Gets a value indicating if the layer exists in the map.
/// Is case sensitive but will search case insensitive if no layer matches with case sensitive.
///
/// The name of the layer
/// True if the layer was found, false otherwise
public bool Contains(string name)
{
return IndexOf(name) != -1;
}
///
/// Gets or sets a layer based on the layers name.
/// Is case sensitive but will search case insensitive if no layer matches with case sensitive.
///
public MapLayerType this[string name]
{
get
{
int ix = IndexOf(name);
if (ix == -1)
throw new IndexOutOfRangeException("The layer named: " + name + " was not found in the map");
else
return this[ix];
}
set
{
int ix = IndexOf(name);
if (ix == -1)
throw new IndexOutOfRangeException("The layer named: " + name + " was not found");
else
this[ix] = value;
}
}
public MapLayerType this[int idx]
{
get {
return ((MapLayerType)(base.InnerList[idx]));
}
set {
base.InnerList[idx] = value;
}
}
public int Add(MapLayerType value) {
return base.InnerList.Add(value);
}
public int IndexOf(MapLayerType value)
{
return base.InnerList.IndexOf(value);
}
public void Insert(int index, MapLayerType value)
{
base.InnerList.Insert(index, value);
}
}
public class MapLayerGroupTypeCollection : System.Collections.CollectionBase {
///
/// Gets or sets the index of a layer, given the layer name.
/// Is case sensitive but will search case insensitive if no layer matches with case sensitive.
///
/// The name of the layer
/// The index of the layer, or -1 if no such layer could be found
public int IndexOf(string name)
{
int rml = -1;
for (int i = 0; i < this.Count; i++)
if (this[i].Name == name)
return i;
else if (rml == -1 && this[i].Name.ToLower() == name.ToLower())
rml = i;
return rml;
}
///
/// Gets a value indicating if the layer exists in the map.
/// Is case sensitive but will search case insensitive if no layer matches with case sensitive.
///
/// The name of the layer
/// True if the layer was found, false otherwise
public bool Contains(string name)
{
return IndexOf(name) != -1;
}
///
/// Gets or sets a layer based on the layers name.
/// Is case sensitive but will search case insensitive if no layer matches with case sensitive.
///
public MapLayerGroupType this[string name]
{
get
{
int ix = IndexOf(name);
if (ix == -1)
throw new IndexOutOfRangeException("The layer named: " + name + " was not found in the map");
else
return this[ix];
}
set
{
int ix = IndexOf(name);
if (ix == -1)
throw new IndexOutOfRangeException("The layer named: " + name + " was not found");
else
this[ix] = value;
}
}
public MapLayerGroupType this[int idx]
{
get {
return ((MapLayerGroupType)(base.InnerList[idx]));
}
set {
base.InnerList[idx] = value;
}
}
public int Add(MapLayerGroupType value) {
return base.InnerList.Add(value);
}
public int IndexOf(MapLayerGroupType value)
{
return base.InnerList.IndexOf(value);
}
}
public class DoubleCollection : System.Collections.CollectionBase {
public double this[int idx] {
get {
return ((double)(base.InnerList[idx]));
}
set {
base.InnerList[idx] = value;
}
}
public int Add(System.Double value) {
return base.InnerList.Add(value);
}
}
public class BaseMapLayerGroupCommonTypeCollection : System.Collections.CollectionBase {
public BaseMapLayerGroupCommonType this[int idx] {
get {
return ((BaseMapLayerGroupCommonType)(base.InnerList[idx]));
}
set {
base.InnerList[idx] = value;
}
}
public int Add(BaseMapLayerGroupCommonType value) {
return base.InnerList.Add(value);
}
public void Insert(int index, BaseMapLayerGroupCommonType value)
{
base.InnerList.Insert(index, value);
}
public int IndexOf(BaseMapLayerGroupCommonType value)
{
return base.InnerList.IndexOf(value);
}
}
public class BaseMapLayerTypeCollection : System.Collections.CollectionBase {
public BaseMapLayerType this[int idx] {
get {
return ((BaseMapLayerType)(base.InnerList[idx]));
}
set {
base.InnerList[idx] = value;
}
}
public int Add(BaseMapLayerType value) {
return base.InnerList.Add(value);
}
public void Insert(int index, BaseMapLayerType value)
{
base.InnerList.Insert(index, value);
}
public int IndexOf(BaseMapLayerType value)
{
return base.InnerList.IndexOf(value);
}
}
}