22using System . Globalization ;
33using System . Runtime . Serialization ;
44using System . Collections . Generic ;
5+ using System . Linq ;
56using GoogleMapsApi . Entities . Common ;
67
78namespace GoogleMapsApi . Entities . PlacesDetails . Response
@@ -13,6 +14,11 @@ public class Result
1314 /// name contains the human-readable name for the returned result. For establishment results, this is usually the canonicalized business name.
1415 /// </summary>
1516
17+ /// <summary>
18+ /// address_components is an array containing the separate address components.
19+ /// Use the helper methods on this Result class to easily extract street address, state, postal code, etc.
20+ /// Example: result.GetStreetAddress(), result.GetState(), result.GetPostalCode()
21+ /// </summary>
1622 [ DataMember ( Name = "address_components" ) ]
1723 public IEnumerable < GoogleMapsApi . Entities . Geocoding . Response . AddressComponent > AddressComponent { get ; set ; }
1824
@@ -228,6 +234,164 @@ internal string string_PriceLevel
228234
229235 [ DataMember ( Name = "place_id" ) ]
230236 public string PlaceId { get ; set ; }
237+
238+ #region Address Component Helper Methods
239+
240+ /// <summary>
241+ /// Gets the street address (street number + route) from address components
242+ /// </summary>
243+ /// <returns>Street address or null if not found</returns>
244+ public string GetStreetAddress ( )
245+ {
246+ if ( AddressComponent == null )
247+ return null ;
248+
249+ var streetNumber = GetAddressComponentByType ( "street_number" ) ? . LongName ;
250+ var route = GetAddressComponentByType ( "route" ) ? . LongName ;
251+
252+ if ( string . IsNullOrEmpty ( streetNumber ) && string . IsNullOrEmpty ( route ) )
253+ return null ;
254+
255+ if ( string . IsNullOrEmpty ( streetNumber ) )
256+ return route ;
257+
258+ if ( string . IsNullOrEmpty ( route ) )
259+ return streetNumber ;
260+
261+ return $ "{ streetNumber } { route } ";
262+ }
263+
264+ /// <summary>
265+ /// Gets the state/province from address components
266+ /// </summary>
267+ /// <param name="useShortName">If true, returns short name (e.g., "NY"), otherwise long name (e.g., "New York")</param>
268+ /// <returns>State/province or null if not found</returns>
269+ public string GetState ( bool useShortName = false )
270+ {
271+ if ( AddressComponent == null )
272+ return null ;
273+
274+ var component = GetAddressComponentByType ( "administrative_area_level_1" ) ;
275+ return component == null ? null : ( useShortName ? component . ShortName : component . LongName ) ;
276+ }
277+
278+ /// <summary>
279+ /// Gets the postal code from address components
280+ /// </summary>
281+ /// <returns>Postal code or null if not found</returns>
282+ public string GetPostalCode ( )
283+ {
284+ if ( AddressComponent == null )
285+ return null ;
286+
287+ return GetAddressComponentByType ( "postal_code" ) ? . LongName ;
288+ }
289+
290+ /// <summary>
291+ /// Gets the city/locality from address components
292+ /// </summary>
293+ /// <param name="useShortName">If true, returns short name, otherwise long name</param>
294+ /// <returns>City/locality or null if not found</returns>
295+ public string GetCity ( bool useShortName = false )
296+ {
297+ if ( AddressComponent == null )
298+ return null ;
299+
300+ // Try locality first, then sublocality
301+ var component = GetAddressComponentByType ( "locality" )
302+ ?? GetAddressComponentByType ( "sublocality" ) ;
303+
304+ return component == null ? null : ( useShortName ? component . ShortName : component . LongName ) ;
305+ }
306+
307+ /// <summary>
308+ /// Gets the country from address components
309+ /// </summary>
310+ /// <param name="useShortName">If true, returns short name (e.g., "US"), otherwise long name (e.g., "United States")</param>
311+ /// <returns>Country or null if not found</returns>
312+ public string GetCountry ( bool useShortName = false )
313+ {
314+ if ( AddressComponent == null )
315+ return null ;
316+
317+ var component = GetAddressComponentByType ( "country" ) ;
318+ return component == null ? null : ( useShortName ? component . ShortName : component . LongName ) ;
319+ }
320+
321+ /// <summary>
322+ /// Gets a complete address breakdown from address components
323+ /// </summary>
324+ /// <returns>Address breakdown object</returns>
325+ public AddressBreakdown GetAddressBreakdown ( )
326+ {
327+ if ( AddressComponent == null )
328+ return new AddressBreakdown ( ) ;
329+
330+ return new AddressBreakdown
331+ {
332+ StreetAddress = GetStreetAddress ( ) ,
333+ City = GetCity ( ) ,
334+ State = GetState ( ) ,
335+ PostalCode = GetPostalCode ( ) ,
336+ Country = GetCountry ( )
337+ } ;
338+ }
339+
340+ /// <summary>
341+ /// Helper method to find an address component by type
342+ /// </summary>
343+ /// <param name="type">The type to search for</param>
344+ /// <returns>Address component or null if not found</returns>
345+ private GoogleMapsApi . Entities . Geocoding . Response . AddressComponent GetAddressComponentByType ( string type )
346+ {
347+ return AddressComponent ? . FirstOrDefault ( ac => ac . Types ? . Contains ( type ) == true ) ;
348+ }
349+
350+ #endregion
351+ }
352+
353+ /// <summary>
354+ /// Represents a complete address breakdown with individual components
355+ /// </summary>
356+ public class AddressBreakdown
357+ {
358+ /// <summary>
359+ /// Street address (street number + route)
360+ /// </summary>
361+ public string StreetAddress { get ; set ; }
362+
363+ /// <summary>
364+ /// City/locality
365+ /// </summary>
366+ public string City { get ; set ; }
367+
368+ /// <summary>
369+ /// State/province
370+ /// </summary>
371+ public string State { get ; set ; }
372+
373+ /// <summary>
374+ /// Postal code
375+ /// </summary>
376+ public string PostalCode { get ; set ; }
377+
378+ /// <summary>
379+ /// Country
380+ /// </summary>
381+ public string Country { get ; set ; }
382+
383+ /// <summary>
384+ /// Returns a formatted address string
385+ /// </summary>
386+ /// <returns>Formatted address</returns>
387+ public override string ToString ( )
388+ {
389+ var parts = new [ ] { StreetAddress , City , State , PostalCode , Country }
390+ . Where ( part => ! string . IsNullOrEmpty ( part ) )
391+ . ToArray ( ) ;
392+
393+ return string . Join ( ", " , parts ) ;
394+ }
231395 }
232396
233397 public enum PriceLevel
0 commit comments