Reputation: 349
how to get street number from google map in swift?
my code:
let geocoder = GMSGeocoder()
geocoder.reverseGeocodeCoordinate(place.coordinate) { response, error in
if let address = response?.firstResult() {
print(address)
}
})
and i get this:
GMSAddress {
coordinate: (56.966157, 24.054405)
lines: Buļļu iela 21, Kurzeme District, Rīga, LV-1055, Latvia
thoroughfare: 21 Buļļu iela
locality: Rīga
administrativeArea: Rīgas pilsēta
postalCode: LV-1055
country: Latvia
}
So... how to get street number?
Upvotes: 2
Views: 3022
Reputation: 36
It works fine for me:
func splitStreetNumber(in streetAddress: String) -> (streetNumber: String?, street: String?) {
let words = streetAddress.split(separator: " ")
var lastIndex: Int?
for (index, word) in words.enumerated() where word.rangeOfCharacter(from: .decimalDigits) != nil {
lastIndex = index
}
guard let lindex = lastIndex else { return (nil, streetAddress) }
var nChars: [String] = []
var sChars: [String] = []
for (index, word) in words.enumerated() {
if index <= lindex {
nChars.append(String(word))
} else {
sChars.append(String(word))
}
}
let number = nChars.joined(separator: " ")
let street = sChars.joined(separator: " ")
return (number.isEmpty ? nil : number, street.isEmpty ? nil : street)
}
Upvotes: 0
Reputation: 91
Using a regular expression you can get both the street number and street from the thoroughfare
in one go. This makes your address parsing code much more flexible because you will only have to make minimal changes in the splitStreetNumber(in:) method if you decide to tweak it later. Also the substrings method is extremely reusable.
extension NSRegularExpression {
func substrings(in string: String, options: MatchingOptions = [], range rangeOrNil: NSRange? = nil) -> [[String?]] {
// search the full range of the string by default
let range = rangeOrNil ?? NSRange(location: 0, length: string.count)
let matches = self.matches(in: string, options: options, range: range)
// parse each match's ranges into strings
return matches.map{ match -> [String?] in
return (0..<match.numberOfRanges)
// map each index to a range
.map{ match.range(at: $0) }
// map each range to a substring of the given string if the range is valid
.map{ matchRange -> String? in
if let validRange = range.intersection(matchRange) {
return (string as NSString).substring(with: validRange)
}
return nil
}
}
}
}
func splitStreetNumber(in streetAddress: String) -> (streetNumber: String?, street: String?) {
// regex matches digits at the beginning and any text after without capturing any extra spaces
let regex = try! NSRegularExpression(pattern: "^ *(\\d+)? *(.*?) *$", options: .caseInsensitive)
// because the regex is anchored to the beginning and end of the string there will
// only ever be one match unless the string does not match the regex at all
if let strings = regex.substrings(in: streetAddress).first, strings.count > 2 {
return (strings[1], strings[2])
}
return (nil, nil)
}
Result
' 1234 Address Dr ' -> ('1234', 'Address Dr')
'1234 Address Dr' -> ('1234', 'Address Dr')
'Address Dr' -> (nil, 'Address Dr')
'1234' -> ('1234', nil)
Upvotes: 2
Reputation: 38833
The thoroughfare
returns the street and street number. Check the GMSAddress documentation.
If you want to get the street number from the thoroughfare
result string
, you can the method below.
func getStreetNumber(street : String){
let str = street
let streetNumber = str.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
print(streetNumber)
}
UPDATE
To get the number only
I have called getStreetNumber("531 W 217th St, New York")
and the method below prints out 531.
var number = ""
var hasValue = false
// Loops thorugh the street
for i in street.characters {
let str = String(i)
// Checks if the char is a number
if (Int(str) != nil){
// If it is it appends it to number
number+=str
// Here we set the hasValue to true, beacause the street number will come in one order
// 531 in this case
hasValue = true
}
else{
// Lets say that we have runned through 531 and are at the blank char now, that means we have looped through the street number and can end the for iteration
if(hasValue){
break
}
}
}
print(number)
To get the address only
func getStreetNumber(street : String){
let str = street
let streetNumber = str.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
print(streetNumber)
var address = street
var hasValue = false
// Loops thorugh the street
for i in street.characters {
let str = String(i)
// Checks if the char is a number
if (Int(str) != nil){
// If it is it appends it to number
address = address.stringByReplacingOccurrencesOfString(str, withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
// Here we set the hasValue to true, beacause the street number will come in one order
// 531 in this case
hasValue = true
}
else{
// Lets say that we have runned through 531 and are at the blank char now, that means we have looped through the street number and can end the for iteration
if(hasValue){
break
}
}
}
print(address)
}
Upvotes: 1