|
| 1 | +// ==++== |
| 2 | +// |
| 3 | +// Copyright (c) Microsoft Corporation. All rights reserved. |
| 4 | +// |
| 5 | +// ==--== |
| 6 | +/*============================================================================= |
| 7 | +** |
| 8 | +** Class: CivicAddress |
| 9 | +** |
| 10 | +** Purpose: Represents a CivicAddress object |
| 11 | +** |
| 12 | +=============================================================================*/ |
| 13 | + |
| 14 | +using System; |
| 15 | +using System.ComponentModel; |
| 16 | +using System.Globalization; |
| 17 | +using System.Collections.Generic; |
| 18 | +using System.Threading; |
| 19 | +using System.Diagnostics.CodeAnalysis; |
| 20 | + |
| 21 | +namespace System.Device.Location |
| 22 | +{ |
| 23 | + public class CivicAddress |
| 24 | + { |
| 25 | + public static readonly CivicAddress Unknown = new CivicAddress(); |
| 26 | + |
| 27 | + // |
| 28 | + // private construcotr for creating single instance of CivicAddress.Unknown |
| 29 | + // |
| 30 | + public CivicAddress() |
| 31 | + { |
| 32 | + AddressLine1 = String.Empty; |
| 33 | + AddressLine2 = String.Empty; |
| 34 | + Building = String.Empty; |
| 35 | + City = String.Empty; |
| 36 | + CountryRegion = String.Empty; |
| 37 | + FloorLevel = String.Empty; |
| 38 | + PostalCode = String.Empty; |
| 39 | + StateProvince = String.Empty; |
| 40 | + } |
| 41 | + |
| 42 | + public CivicAddress(String addressLine1, String addressLine2, String building, String city, String countryRegion, String floorLevel, String postalCode, String stateProvince) |
| 43 | + : this() |
| 44 | + { |
| 45 | + bool hasField = false; |
| 46 | + |
| 47 | + if (addressLine1 != null && addressLine1 != String.Empty) |
| 48 | + { |
| 49 | + hasField = true; |
| 50 | + AddressLine1 = addressLine1; |
| 51 | + } |
| 52 | + if (addressLine2 != null && addressLine2 != String.Empty) |
| 53 | + { |
| 54 | + hasField = true; |
| 55 | + AddressLine2 = addressLine2; |
| 56 | + } |
| 57 | + if (building != null && building != String.Empty) |
| 58 | + { |
| 59 | + hasField = true; |
| 60 | + Building = building; |
| 61 | + } |
| 62 | + if (city != null && city != String.Empty) |
| 63 | + { |
| 64 | + hasField = true; |
| 65 | + City = city; |
| 66 | + } |
| 67 | + if (countryRegion != null && countryRegion != String.Empty) |
| 68 | + { |
| 69 | + hasField = true; |
| 70 | + CountryRegion = countryRegion; |
| 71 | + } |
| 72 | + if (floorLevel != null && floorLevel != String.Empty) |
| 73 | + { |
| 74 | + hasField = true; |
| 75 | + FloorLevel = floorLevel; |
| 76 | + } |
| 77 | + if (postalCode != null && postalCode != String.Empty) |
| 78 | + { |
| 79 | + hasField = true; |
| 80 | + PostalCode = postalCode; |
| 81 | + } |
| 82 | + |
| 83 | + if (stateProvince != null && stateProvince != String.Empty) |
| 84 | + { |
| 85 | + hasField = true; |
| 86 | + StateProvince = stateProvince; |
| 87 | + } |
| 88 | + |
| 89 | + if (!hasField) |
| 90 | + { |
| 91 | + throw new ArgumentException(SR.GetString(SR.Argument_RequiresAtLeastOneNonEmptyStringParameter)); |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + public String AddressLine1 { get; set; } |
| 96 | + public String AddressLine2 { get; set; } |
| 97 | + public String Building { get; set; } |
| 98 | + public String City { get; set; } |
| 99 | + public String CountryRegion { get; set; } |
| 100 | + public String FloorLevel { get; set; } |
| 101 | + public String PostalCode { get; set; } |
| 102 | + public String StateProvince { get; set; } |
| 103 | + |
| 104 | + public Boolean IsUnknown |
| 105 | + { |
| 106 | + get |
| 107 | + { |
| 108 | + return (String.IsNullOrEmpty(AddressLine1) && String.IsNullOrEmpty(AddressLine2) && |
| 109 | + String.IsNullOrEmpty(Building) && String.IsNullOrEmpty(City) && String.IsNullOrEmpty(CountryRegion) && String.IsNullOrEmpty(FloorLevel) && String.IsNullOrEmpty(PostalCode) && String.IsNullOrEmpty(StateProvince)); |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + } |
| 114 | + |
| 115 | + public interface ICivicAddressResolver |
| 116 | + { |
| 117 | + CivicAddress ResolveAddress(GeoCoordinate coordinate); |
| 118 | + void ResolveAddressAsync(GeoCoordinate coordinate); |
| 119 | + event EventHandler<ResolveAddressCompletedEventArgs> ResolveAddressCompleted; |
| 120 | + } |
| 121 | + |
| 122 | + public class ResolveAddressCompletedEventArgs : AsyncCompletedEventArgs |
| 123 | + { |
| 124 | + public ResolveAddressCompletedEventArgs(CivicAddress address, Exception error, Boolean cancelled, Object userState) |
| 125 | + : base(error, cancelled, userState) |
| 126 | + { |
| 127 | + Address = address; |
| 128 | + } |
| 129 | + |
| 130 | + public CivicAddress Address { get; private set;} |
| 131 | + } |
| 132 | + |
| 133 | + public sealed class CivicAddressResolver : ICivicAddressResolver |
| 134 | + { |
| 135 | + private SynchronizationContext m_synchronizationContext; |
| 136 | + |
| 137 | + public CivicAddressResolver() |
| 138 | + { |
| 139 | + if (SynchronizationContext.Current == null) |
| 140 | + { |
| 141 | + // |
| 142 | + // Create a SynchronizationContext if there isn't one on calling thread |
| 143 | + // |
| 144 | + m_synchronizationContext = new SynchronizationContext(); |
| 145 | + } |
| 146 | + else |
| 147 | + { |
| 148 | + m_synchronizationContext = SynchronizationContext.Current; |
| 149 | + } |
| 150 | + } |
| 151 | + |
| 152 | + public CivicAddress ResolveAddress(GeoCoordinate coordinate) |
| 153 | + { |
| 154 | + if (coordinate == null) |
| 155 | + { |
| 156 | + throw new ArgumentNullException("coordinate"); |
| 157 | + } |
| 158 | + |
| 159 | + if (coordinate.IsUnknown) |
| 160 | + { |
| 161 | + throw new ArgumentException("coordinate"); |
| 162 | + } |
| 163 | + |
| 164 | + return coordinate.m_address; |
| 165 | + } |
| 166 | + |
| 167 | + public void ResolveAddressAsync(GeoCoordinate coordinate) |
| 168 | + { |
| 169 | + if (coordinate == null) |
| 170 | + { |
| 171 | + throw new ArgumentNullException("coordinate"); |
| 172 | + } |
| 173 | + |
| 174 | + if (Double.IsNaN(coordinate.Latitude) || Double.IsNaN(coordinate.Longitude)) |
| 175 | + { |
| 176 | + throw new ArgumentException("coordinate"); |
| 177 | + } |
| 178 | + |
| 179 | + ThreadPool.QueueUserWorkItem(new WaitCallback(this.ResolveAddress), coordinate); |
| 180 | + } |
| 181 | + |
| 182 | + public event EventHandler<ResolveAddressCompletedEventArgs> ResolveAddressCompleted; |
| 183 | + |
| 184 | + private void OnResolveAddressCompleted(ResolveAddressCompletedEventArgs e) |
| 185 | + { |
| 186 | + EventHandler<ResolveAddressCompletedEventArgs> t = ResolveAddressCompleted; |
| 187 | + if (t != null) t(this, e); |
| 188 | + } |
| 189 | + |
| 190 | + /// <summary>Represents a callback to a protected virtual method that raises an event.</summary> |
| 191 | + /// <typeparam name="T">The <see cref="T:System.EventArgs"/> type identifying the type of object that gets raised with the event"/></typeparam> |
| 192 | + /// <param name="e">The <see cref="T:System.EventArgs"/> object that should be passed to a protected virtual method that raises the event.</param> |
| 193 | + private delegate void EventRaiser<T>(T e) where T : EventArgs; |
| 194 | + |
| 195 | + /// <summary>A helper method used by derived types that asynchronously raises an event on the application's desired thread.</summary> |
| 196 | + /// <typeparam name="T">The <see cref="T:System.EventArgs"/> type identifying the type of object that gets raised with the event"/></typeparam> |
| 197 | + /// <param name="callback">The protected virtual method that will raise the event.</param> |
| 198 | + /// <param name="e">The <see cref="T:System.EventArgs"/> object that should be passed to the protected virtual method raising the event.</param> |
| 199 | + private void PostEvent<T>(EventRaiser<T> callback, T e) where T : EventArgs |
| 200 | + { |
| 201 | + if (m_synchronizationContext != null) |
| 202 | + { |
| 203 | + m_synchronizationContext.Post(delegate(Object state) { callback((T)state); }, e); |
| 204 | + } |
| 205 | + } |
| 206 | + |
| 207 | + // |
| 208 | + // Thread pool thread used to resolve civic address |
| 209 | + // |
| 210 | + private void ResolveAddress(object state) |
| 211 | + { |
| 212 | + GeoCoordinate coordinate = state as GeoCoordinate; |
| 213 | + if (coordinate != null) |
| 214 | + { |
| 215 | + PostEvent(OnResolveAddressCompleted, new ResolveAddressCompletedEventArgs(coordinate.m_address, null, false, null)); |
| 216 | + } |
| 217 | + } |
| 218 | + } |
| 219 | +} |
0 commit comments