#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.Xml;
using System.Collections;
using System.Collections.Generic;
namespace OSGeo.MapGuide.MaestroAPI
{
///
/// Interface to MapGuide coordinate system functions.
/// Only works with server > 1.2, since the coordinate mapping is not avalible through Http on older versions
///
public class HttpCoordinateSystem : OSGeo.MapGuide.MaestroAPI.ICoordinateSystem
{
private HttpServerConnection m_con;
private RequestBuilder m_req;
private Category[] m_categories;
private string m_coordLib = null;
internal HttpCoordinateSystem(HttpServerConnection con, RequestBuilder req)
{
m_con = con;
m_req = req;
}
internal HttpServerConnection Connection { get { return m_con; } }
internal RequestBuilder RequestBuilder { get { return m_req; } }
public Category[] Categories
{
get
{
if (m_categories == null)
{
string req = m_req.EnumerateCategories();
XmlDocument doc = new XmlDocument();
doc.Load(m_con.WebClient.OpenRead(req));
XmlNodeList lst = doc.SelectNodes("StringCollection/Item");
Category[] data = new Category[lst.Count];
for(int i = 0; i < lst.Count; i++)
data[i] = new Category(this, lst[i].InnerText);
m_categories = data;
}
return m_categories;
}
}
public string LibraryName
{
get
{
if (m_coordLib == null)
{
string req = m_req.GetBaseLibrary();
m_coordLib = System.Text.Encoding.UTF8.GetString(m_con.WebClient.DownloadData(req));
}
return m_coordLib;
}
}
public bool IsValid(string wkt)
{
string req = m_req.IsValidCoordSys(wkt);
return System.Text.Encoding.UTF8.GetString(m_con.WebClient.DownloadData(req)).ToLower().Trim().Equals("true");
}
public string ConvertWktToCoordinateSystemCode(string wkt)
{
string req = m_req.ConvertWktToCoordinateSystemCode(wkt);
return System.Text.Encoding.UTF8.GetString(m_con.WebClient.DownloadData(req));
}
public string ConvertCoordinateSystemCodeToWkt(string coordcode)
{
string req = m_req.ConvertCoordinateSystemCodeToWkt(coordcode);
return System.Text.Encoding.UTF8.GetString(m_con.WebClient.DownloadData(req));
}
public string ConvertWktToEpsgCode(string wkt)
{
string req = m_req.ConvertWktToEpsgCode(wkt);
return System.Text.Encoding.UTF8.GetString(m_con.WebClient.DownloadData(req));
}
public string ConvertEpsgCodeToWkt(string epsg)
{
string req = m_req.ConvertEpsgCodeToWkt(epsg);
return System.Text.Encoding.UTF8.GetString(m_con.WebClient.DownloadData(req));
}
public class Category
{
private HttpCoordinateSystem m_httpParent;
private LocalNativeCoordinateSystem m_localParent;
private string m_name;
private CoordSys[] m_items;
internal Category(HttpCoordinateSystem parent, string name)
{
m_name = name;
m_httpParent = parent;
}
internal Category(LocalNativeCoordinateSystem parent, string name)
{
m_name = name;
m_localParent = parent;
}
public string Name { get { return m_name; } }
internal HttpCoordinateSystem HttpParent { get { return m_httpParent; } }
internal LocalNativeCoordinateSystem LocalParent { get { return m_localParent; } }
internal ICoordinateSystem Parent { get { return m_httpParent == null ? (ICoordinateSystem)m_localParent : (ICoordinateSystem)m_httpParent; } }
public CoordSys[] Items
{
get
{
if (m_items == null)
{
if (m_httpParent != null)
{
string req = m_httpParent.RequestBuilder.EnumerateCoordinateSystems(m_name);
XmlDocument doc = new XmlDocument();
doc.Load(m_httpParent.Connection.WebClient.OpenRead(req));
XmlNodeList lst = doc.SelectNodes("BatchPropertyCollection/PropertyCollection");
CoordSys[] data = new CoordSys[lst.Count];
for (int i = 0; i < lst.Count; i++)
data[i] = new CoordSys(this, lst[i]);
m_items = data;
}
else
{
MgBatchPropertyCollection bp = m_localParent.m_cf.EnumerateCoordinateSystems(m_name);
List lst = new List();
for(int i = 0; i < bp.Count; i++)
lst.Add(new CoordSys(this, bp[i]));
}
}
return m_items;
}
}
public override string ToString()
{
return m_name;
}
}
public class CoordSys
{
private Category m_parent;
private string m_code;
private string m_description;
private string m_projection;
private string m_projectionDescription;
private string m_datum;
private string m_datumDescription;
private string m_ellipsoid;
private string m_ellipsoidDescription;
private string m_wkt = null;
private string m_epsg = null;
public CoordSys()
{
}
internal CoordSys(Category parent, MgPropertyCollection props)
{
m_parent = parent;
for (int i = 0; i < props.Count; i++)
switch (props[i].Name.ToLower())
{
case "code":
m_code = (props[i] as MgStringProperty).Value;
break;
case "description":
m_description = (props[i] as MgStringProperty).Value;
break;
case "projection":
m_projection = (props[i] as MgStringProperty).Value;
break;
case "projection description":
m_projectionDescription = (props[i] as MgStringProperty).Value;
break;
case "Datum":
m_datum = (props[i] as MgStringProperty).Value;
break;
case "datum description":
m_datumDescription = (props[i] as MgStringProperty).Value;
break;
case "ellipsoid":
m_ellipsoid = (props[i] as MgStringProperty).Value;
break;
case "ellipsoid description":
m_ellipsoidDescription = (props[i] as MgStringProperty).Value;
break;
}
}
internal CoordSys(Category parent, XmlNode topnode)
{
m_parent = parent;
foreach(XmlNode node in topnode.ChildNodes)
switch(node["Name"].InnerText.ToLower())
{
case "code":
m_code = node["Value"].InnerText;
break;
case "description":
m_description = node["Value"].InnerText;
break;
case "projection":
m_projection = node["Value"].InnerText;
break;
case "projection description":
m_projectionDescription = node["Value"].InnerText;
break;
case "Datum":
m_datum = node["Value"].InnerText;
break;
case "datum description":
m_datumDescription = node["Value"].InnerText;
break;
case "ellipsoid":
m_ellipsoid = node["Value"].InnerText;
break;
case "ellipsoid description":
m_ellipsoidDescription = node["Value"].InnerText;
break;
}
}
public string Code
{
get { return m_code; }
set { m_code = value; }
}
public string Description
{
get { return m_description; }
set { m_description = value; }
}
public string Projection { get { return m_projection; } }
public string ProjectionDescription { get { return m_projectionDescription; } }
public string Datum { get { return m_datum; } }
public string DatumDescription { get { return m_datumDescription; } }
public string Ellipsoid { get { return m_ellipsoid; } }
public string EllipsoidDescription { get { return m_ellipsoidDescription; } }
public string WKT
{
get
{
if (m_wkt == null)
m_wkt = m_parent.Parent.ConvertCoordinateSystemCodeToWkt(m_code);
return m_wkt;
}
set
{
m_wkt = value;
}
}
public string EPSG
{
get
{
if (m_epsg == null)
if (m_code.StartsWith("EPSG:"))
m_epsg = m_code.Substring(5);
else
m_epsg = m_parent.Parent.ConvertWktToEpsgCode(m_parent.Parent.ConvertCoordinateSystemCodeToWkt(m_code));
return m_epsg;
}
}
public override string ToString()
{
if (m_description == null && m_code == null)
return m_wkt == null ? "" : m_wkt;
else if (m_description == null)
return m_code;
else if (m_code == null)
return m_description;
else
return m_description + " (" + m_code + ")";
}
}
public CoordSys[] Coordsys
{
get
{
ArrayList items = new ArrayList();
foreach(OSGeo.MapGuide.MaestroAPI.HttpCoordinateSystem.Category cat in this.Categories)
foreach(OSGeo.MapGuide.MaestroAPI.HttpCoordinateSystem.CoordSys coord in cat.Items)
items.Add(coord);
return (CoordSys[])items.ToArray(typeof(CoordSys));
}
}
public CoordSys FindCoordSys(string coordcode)
{
try
{
foreach(OSGeo.MapGuide.MaestroAPI.HttpCoordinateSystem.Category cat in this.Categories)
foreach(OSGeo.MapGuide.MaestroAPI.HttpCoordinateSystem.CoordSys coord in cat.Items)
if (coord.Code == coordcode)
return coord;
}
catch
{
}
return null;
}
public bool IsLoaded { get { return m_categories != null; } }
}
}