Skip to content

Commit 230f914

Browse files
committed
[branches/1.0]
+ WFS client can now download and cache all the geometries returned from server in order to speed up things. Set UseCache to true to enable; + WFS.GetExtents() now correctly returns coordinates in the SRS of the layer; + Added FeatureTypeInfo.Elements to store all the feature's elements. This has been tested with GeoServer, and works only for sequence schemas; + With the new UseCache set to true, queries always works as expected and returns all the feature elements; + Added ICoordinateSystemServices, this comes from GeoAPI 1.7.4.0 pre-release, this avoids the update of all the references; + Added CoordinateSystemServicesProvider to get/set the global ICoordinateSystemServices and CoordinateSystemServices, an implementation.
1 parent 35a6de6 commit 230f914

12 files changed

Lines changed: 882 additions & 182 deletions

Branches/1.0/SharpMap/Converters/WellKnownText/SpatialReference.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,36 @@ public static string SridToProj4(int srid)
6363
return SridToDefinition(srid, _proj4s, "PROJ4");
6464
}
6565

66+
/// <summary>
67+
/// Returns an IEnumerable with all the SRID/WKT pairs known.
68+
/// </summary>
69+
/// <returns></returns>
70+
public static IEnumerable<KeyValuePair<int, string>> GetAllReferenceSystems()
71+
{
72+
var xmldoc = new XmlDocument();
73+
74+
var uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
75+
var file = Path.GetDirectoryName(uri.LocalPath) + "\\SpatialRefSys.xml";
76+
try
77+
{
78+
xmldoc.Load(file);
79+
}
80+
catch
81+
{
82+
yield break;
83+
}
84+
85+
var nodes = xmldoc.DocumentElement.SelectNodes("/SpatialReference/*");
86+
foreach (XmlNode referenceNode in nodes)
87+
{
88+
var srid = int.Parse(referenceNode.SelectSingleNode("SRID").InnerText);
89+
90+
var wkt = referenceNode.LastChild.InnerText;
91+
92+
yield return new KeyValuePair<int, string>(srid, wkt);
93+
}
94+
}
95+
6696
private static string SridToDefinition(int srid, IDictionary<int, string> cache, string nodeName = null)
6797
{
6898

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Globalization;
5+
using GeoAPI;
6+
using GeoAPI.CoordinateSystems;
7+
using GeoAPI.CoordinateSystems.Transformations;
8+
using SharpMap.Converters.WellKnownText;
9+
10+
namespace SharpMap.CoordinateSystems
11+
{
12+
/// <summary>
13+
/// A coordinate system services class
14+
/// </summary>
15+
public class CoordinateSystemServices : ICoordinateSystemServices
16+
{
17+
private readonly Dictionary<int, ICoordinateSystem> _csBySrid;
18+
private readonly Dictionary<IInfo, int> _sridByCs;
19+
20+
private readonly ICoordinateSystemFactory _coordinateSystemFactory;
21+
private readonly ICoordinateTransformationFactory _ctFactory;
22+
23+
#region CsEqualityComparer class
24+
private class CsEqualityComparer : EqualityComparer<IInfo>
25+
{
26+
public override bool Equals(IInfo x, IInfo y)
27+
{
28+
return x.AuthorityCode == y.AuthorityCode &&
29+
#if PCL
30+
string.Compare(x.Authority, y.Authority, CultureInfo.InvariantCulture, CompareOptions.OrdinalIgnoreCase) == 0;
31+
#else
32+
string.Compare(x.Authority, y.Authority, true, CultureInfo.InvariantCulture) == 0;
33+
#endif
34+
}
35+
36+
public override int GetHashCode(IInfo obj)
37+
{
38+
if (obj == null) return 0;
39+
return Convert.ToInt32(obj.AuthorityCode) + (obj.Authority != null ? obj.Authority.GetHashCode() : 0);
40+
}
41+
}
42+
#endregion
43+
44+
#region CoordinateSystemKey class
45+
46+
private class CoordinateSystemKey : IInfo
47+
{
48+
public CoordinateSystemKey(string authority, long authorityCode)
49+
{
50+
Authority = authority;
51+
AuthorityCode = authorityCode;
52+
}
53+
54+
public bool EqualParams(object obj)
55+
{
56+
throw new NotSupportedException();
57+
}
58+
59+
public string Name { get { return null; } }
60+
public string Authority { get; private set; }
61+
public long AuthorityCode { get; private set; }
62+
public string Alias { get { return null; } }
63+
public string Abbreviation { get { return null; } }
64+
public string Remarks { get { return null; } }
65+
public string WKT { get { return null; } }
66+
public string XML { get { return null; } }
67+
}
68+
69+
#endregion
70+
71+
#region ctors
72+
private CoordinateSystemServices(ICoordinateSystemFactory coordinateSystemFactory,
73+
ICoordinateTransformationFactory coordinateTransformationFactory)
74+
{
75+
if (coordinateSystemFactory == null)
76+
throw new ArgumentNullException("coordinateSystemFactory");
77+
78+
if (coordinateTransformationFactory == null)
79+
throw new ArgumentNullException("coordinateTransformationFactory");
80+
81+
_coordinateSystemFactory = coordinateSystemFactory;
82+
_ctFactory = coordinateTransformationFactory;
83+
84+
_csBySrid = new Dictionary<int, ICoordinateSystem>();
85+
_sridByCs = new Dictionary<IInfo, int>(new CsEqualityComparer());
86+
}
87+
88+
public CoordinateSystemServices(ICoordinateSystemFactory coordinateSystemFactory,
89+
ICoordinateTransformationFactory coordinateTransformationFactory,
90+
IEnumerable<KeyValuePair<int, string>> enumeration)
91+
: this(coordinateSystemFactory, coordinateTransformationFactory)
92+
{
93+
FromEnumeration(this, enumeration);
94+
}
95+
#endregion
96+
97+
#region private members
98+
private static ICoordinateSystem CreateCoordinateSystem(ICoordinateSystemFactory coordinateSystemFactory, string wkt)
99+
{
100+
try
101+
{
102+
return coordinateSystemFactory.CreateFromWkt(wkt.Replace("ELLIPSOID", "SPHEROID"));
103+
}
104+
catch (Exception)
105+
{
106+
// as a fallback we ignore projections not supported
107+
return null;
108+
}
109+
}
110+
111+
private static void FromEnumeration(CoordinateSystemServices css,
112+
IEnumerable<KeyValuePair<int, ICoordinateSystem>> enumeration)
113+
{
114+
foreach (var sridCs in enumeration)
115+
{
116+
css.AddCoordinateSystem(sridCs.Key, sridCs.Value);
117+
}
118+
}
119+
120+
private static IEnumerable<KeyValuePair<int, ICoordinateSystem>> CreateCoordinateSystems(
121+
ICoordinateSystemFactory factory,
122+
IEnumerable<KeyValuePair<int, string>> enumeration)
123+
{
124+
foreach (var sridWkt in enumeration)
125+
{
126+
var cs = CreateCoordinateSystem(factory, sridWkt.Value);
127+
if (cs != null)
128+
yield return new KeyValuePair<int, ICoordinateSystem>(sridWkt.Key, cs);
129+
}
130+
}
131+
132+
private static void FromEnumeration(CoordinateSystemServices css,
133+
IEnumerable<KeyValuePair<int, string>> enumeration)
134+
{
135+
FromEnumeration(css, CreateCoordinateSystems(css._coordinateSystemFactory, enumeration));
136+
}
137+
138+
#endregion
139+
140+
#region public members
141+
142+
public ICoordinateSystem GetCoordinateSystem(int srid)
143+
{
144+
ICoordinateSystem cs;
145+
return _csBySrid.TryGetValue(srid, out cs) ? cs : null;
146+
}
147+
148+
public ICoordinateSystem GetCoordinateSystem(string authority, long code)
149+
{
150+
var srid = GetSRID(authority, code);
151+
return srid.HasValue ? GetCoordinateSystem(srid.Value) : null;
152+
}
153+
154+
public int? GetSRID(string authority, long authorityCode)
155+
{
156+
var key = new CoordinateSystemKey(authority, authorityCode);
157+
int srid;
158+
if (_sridByCs.TryGetValue(key, out srid))
159+
return srid;
160+
161+
return null;
162+
}
163+
164+
public ICoordinateTransformation CreateTransformation(int sourceSrid, int targetSrid)
165+
{
166+
return CreateTransformation(GetCoordinateSystem(sourceSrid),
167+
GetCoordinateSystem(targetSrid));
168+
}
169+
170+
public ICoordinateTransformation CreateTransformation(ICoordinateSystem src, ICoordinateSystem tgt)
171+
{
172+
return _ctFactory.CreateFromCoordinateSystems(src, tgt);
173+
}
174+
175+
public IEnumerator<KeyValuePair<int, ICoordinateSystem>> GetEnumerator()
176+
{
177+
return _csBySrid.GetEnumerator();
178+
}
179+
180+
#region obsolete members
181+
[Obsolete]
182+
public string GetCoordinateSystemInitializationString(int srid)
183+
{
184+
ICoordinateSystem cs;
185+
if (_csBySrid.TryGetValue(srid, out cs))
186+
return cs.WKT;
187+
throw new ArgumentOutOfRangeException("srid");
188+
}
189+
190+
[Obsolete]
191+
public ICoordinateSystemFactory CoordinateSystemFactory
192+
{
193+
get { return _coordinateSystemFactory; }
194+
}
195+
196+
[Obsolete]
197+
public ICoordinateTransformationFactory CoordinateTransformationFactory
198+
{
199+
get { return _ctFactory; }
200+
}
201+
202+
#endregion
203+
204+
#endregion
205+
206+
#region protected members
207+
208+
protected void AddCoordinateSystem(int srid, ICoordinateSystem coordinateSystem)
209+
{
210+
lock (((IDictionary)_csBySrid).SyncRoot)
211+
{
212+
lock (((IDictionary)_sridByCs).SyncRoot)
213+
{
214+
if (_csBySrid.ContainsKey(srid))
215+
{
216+
if (ReferenceEquals(coordinateSystem, _csBySrid[srid]))
217+
return;
218+
219+
_sridByCs.Remove(_csBySrid[srid]);
220+
_csBySrid[srid] = coordinateSystem;
221+
_sridByCs.Add(coordinateSystem, srid);
222+
}
223+
else
224+
{
225+
_csBySrid.Add(srid, coordinateSystem);
226+
_sridByCs.Add(coordinateSystem, srid);
227+
}
228+
}
229+
}
230+
}
231+
232+
protected virtual int AddCoordinateSystem(ICoordinateSystem coordinateSystem)
233+
{
234+
var srid = (int)coordinateSystem.AuthorityCode;
235+
AddCoordinateSystem(srid, coordinateSystem);
236+
237+
return srid;
238+
}
239+
240+
protected virtual void Clear()
241+
{
242+
_csBySrid.Clear();
243+
_sridByCs.Clear();
244+
}
245+
246+
protected int Count
247+
{
248+
get
249+
{
250+
return _sridByCs.Count;
251+
}
252+
}
253+
254+
#endregion
255+
256+
public virtual bool RemoveCoordinateSystem(int srid)
257+
{
258+
throw new NotSupportedException();
259+
}
260+
261+
/// <summary>
262+
/// Creates a CoordinateSystemServices built with all the values coming from the SpatialRefSys.xml
263+
/// </summary>
264+
/// <param name="coordinateSystemFactory"></param>
265+
/// <param name="coordinateTransformationFactory"></param>
266+
/// <returns></returns>
267+
public static CoordinateSystemServices FromSpatialRefSys(ICoordinateSystemFactory coordinateSystemFactory, ICoordinateTransformationFactory coordinateTransformationFactory)
268+
{
269+
if (coordinateSystemFactory == null)
270+
throw new ArgumentNullException("coordinateSystemFactory");
271+
272+
if (coordinateTransformationFactory == null)
273+
throw new ArgumentNullException("coordinateTransformationFactory");
274+
275+
return new CoordinateSystemServices(coordinateSystemFactory, coordinateTransformationFactory, SpatialReference.GetAllReferenceSystems());
276+
}
277+
}
278+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using GeoAPI;
3+
4+
namespace SharpMap.CoordinateSystems
5+
{
6+
public static class CoordinateSystemServicesProvider
7+
{
8+
private static class InstanceHolder
9+
{
10+
public volatile static Func<ICoordinateSystemServices> GetInstance;
11+
12+
static InstanceHolder()
13+
{
14+
GetInstance = () => { throw new InvalidOperationException("ICoordinateSystemServices not initialized, please use CoordinateSystemServiceProvider.Instance to set an implementation"); };
15+
}
16+
}
17+
18+
/// <summary>
19+
/// Gets or sets the ICoordinateSystemService instance.
20+
/// </summary>
21+
public static ICoordinateSystemServices Instance
22+
{
23+
get
24+
{
25+
return InstanceHolder.GetInstance();
26+
}
27+
set
28+
{
29+
if (value == null)
30+
throw new ArgumentNullException("value");
31+
32+
33+
InstanceHolder.GetInstance = () => value;
34+
}
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)