2014-11-12 14 views
6

Ho tentato in due modi diversi di provare ad ottenere il nome della città e l'abbreviazione dello stato solo dalla classe Indirizzo, senza fortuna. Il primo sta restituendo lo stato come "CA 92055" con il codice postale e il secondo tentativo restituisce il nome completo dello stato. Qualche modo veloce intorno a questo?Ottenere l'abbreviazione di stato da getAdminArea();

Primo tentativo, che lo Stato finisce per tornare "CA 92055" (Zip seguita dopo l'abbrev)

Geocoder geoCoder = new Geocoder(getActivity(), Locale.getDefault()); 
       List<Address> addresses; 
       try { 
        addresses = geoCoder.getFromLocation(mLatitude, mLongitude, 10); 
        int i=1; 
        for(Address addObj:addresses) 
        { 
         // Looping once 
         if(i==1) 
         { 

          String add_line1_extract; 

          add_line1_extract=addObj.getAddressLine(1); 

          String string = add_line1_extract; 
          String[] parts = string.split(","); 

          //Setting city 
          mCity = parts[0]; 

          //setting state 
          mState = parts[1]; 

          // Final Output 
          String cityAndState = mCity + ", " + mState; 
          i++; 

         } 
        } 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 

Secondo tentativo, avvicinandosi senza zip ora ... ma ... (Restituisce lo stato completo nome):

Geocoder geoCoder = new Geocoder(getActivity(), Locale.getDefault()); 
       List<Address> addresses; 
       try { 
        addresses = geoCoder.getFromLocation(mLatitude, mLongitude, 10); 
        int i=1; 
        for(Address addObj:addresses) 
        { 
         // Looping once 
         if(i==1) 
         { 

          //Setting city 
          mCity = addObj.getSubLocality();        
          //setting state 
          mState = addObj.getAdminArea(); 

          i++; 
         } 
        } 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 

risposta

5

io non credo che si possa ottenere una sigla dello stato direttamente da getAdminArea() nonostante quello che dice la documentazione. Tuttavia, quando si tratta di Stati Uniti e Canada, è possibile impostare una mappa di hash che mapperà lo stato/province alle abbreviazioni in riferimento.

usare qualcosa di simile a questo:

Map<String, String> states = new HashMap<String, String>(); 
states.put("Alabama","AL"); 
states.put("Alaska","AK"); 
states.put("Alberta","AB"); 
states.put("American Samoa","AS"); 
states.put("Arizona","AZ"); 
states.put("Arkansas","AR"); 
states.put("Armed Forces (AE)","AE"); 
states.put("Armed Forces Americas","AA"); 
states.put("Armed Forces Pacific","AP"); 
states.put("British Columbia","BC"); 
states.put("California","CA"); 
states.put("Colorado","CO"); 
states.put("Connecticut","CT"); 
states.put("Delaware","DE"); 
states.put("District Of Columbia","DC"); 
states.put("Florida","FL"); 
states.put("Georgia","GA"); 
states.put("Guam","GU"); 
states.put("Hawaii","HI"); 
states.put("Idaho","ID"); 
states.put("Illinois","IL"); 
states.put("Indiana","IN"); 
states.put("Iowa","IA"); 
states.put("Kansas","KS"); 
states.put("Kentucky","KY"); 
states.put("Louisiana","LA"); 
states.put("Maine","ME"); 
states.put("Manitoba","MB"); 
states.put("Maryland","MD"); 
states.put("Massachusetts","MA"); 
states.put("Michigan","MI"); 
states.put("Minnesota","MN"); 
states.put("Mississippi","MS"); 
states.put("Missouri","MO"); 
states.put("Montana","MT"); 
states.put("Nebraska","NE"); 
states.put("Nevada","NV"); 
states.put("New Brunswick","NB"); 
states.put("New Hampshire","NH"); 
states.put("New Jersey","NJ"); 
states.put("New Mexico","NM"); 
states.put("New York","NY"); 
states.put("Newfoundland","NF"); 
states.put("North Carolina","NC"); 
states.put("North Dakota","ND"); 
states.put("Northwest Territories","NT"); 
states.put("Nova Scotia","NS"); 
states.put("Nunavut","NU"); 
states.put("Ohio","OH"); 
states.put("Oklahoma","OK"); 
states.put("Ontario","ON"); 
states.put("Oregon","OR"); 
states.put("Pennsylvania","PA"); 
states.put("Prince Edward Island","PE"); 
states.put("Puerto Rico","PR"); 
states.put("Quebec","PQ"); 
states.put("Rhode Island","RI"); 
states.put("Saskatchewan","SK"); 
states.put("South Carolina","SC"); 
states.put("South Dakota","SD"); 
states.put("Tennessee","TN"); 
states.put("Texas","TX"); 
states.put("Utah","UT"); 
states.put("Vermont","VT"); 
states.put("Virgin Islands","VI"); 
states.put("Virginia","VA"); 
states.put("Washington","WA"); 
states.put("West Virginia","WV"); 
states.put("Wisconsin","WI"); 
states.put("Wyoming","WY"); 
states.put("Yukon Territory","YT"); 
+2

il problema che vedo con questa soluzione è il nome dello stato per lingue diverse dall'inglese. – pellyadolfo

+0

Un buon punto @pellyadolfo - non ha ancora affrontato l'internazionalizzazione per i nomi degli Stati Uniti ancora, ma non è possibile aggiungere qualche logica per le lingue aggiuntive e quindi basta scambiare una hashmap basata sulla lingua desiderata? – Bourne

+0

Ciao @Bourme, certo che potresti, ma lo considero un compito impegnativo. Ad esempio, New York in inglese verrebbe restituita come Nueva York in spagnolo da geocoder. Quindi avresti bisogno di una nuova mappa per lingua considerata che ritengo sia un compito lungo e potenzialmente incline all'errore. Ma, tecnicamente, è fattibile, sono d'accordo. – pellyadolfo

3

ho lavorato intorno ad esso trovando l'ultima parola 2 lettere l'indirizzo completo (assumendo un indirizzo negli Stati Uniti fornito da Google Maps geocoder Android). Funziona per tutti i casi che ho trovato:

private String getUSStateCode(Address USAddress){ 
    String fullAddress = ""; 
    for(int j = 0; j <= USAddress.getMaxAddressLineIndex(); j++) 
     if (USAddress.getAddressLine(j) != null) 
      fullAddress = fullAddress + " " + USAddress.getAddressLine(j); 

    String stateCode = null; 
    Pattern pattern = Pattern.compile(" [A-Z]{2} "); 
    String helper = fullAddress.toUpperCase().substring(0, fullAddress.toUpperCase().indexOf("USA")); 
    Matcher matcher = pattern.matcher(helper); 
    while (matcher.find()) 
     stateCode = matcher.group().trim(); 

    return stateCode; 
} 
+0

Grazie @pellyadolfo, funziona perfettamente :) –

+1

bug: la città USA può contenere sottostringa "usa": Thousand Oaks – user1269737

1

Ecco una versione combinata e modificata delle risposte di Bourne e Pellyadolfo. Cerca dapprima di mappare il nome completo dello stato in un codice di stato (funziona anche per le province canadesi, ed è meno incline all'errore rispetto alla regex), e se ciò non funziona, ricade sulla soluzione regex (che ha il potenziale per errore, quindi perché lo preferisco come soluzione di backup, ma posso lavorare con lingue o paesi diversi).

La soluzione regex è stata migliorata per includere un controllo di integrità all'inizio e ha una regex più avanzata per eliminare la necessità di filtrare manualmente "USA" (questo consente agli indirizzi canadesi di funzionare). Rimuove anche la chiamata "toupper()" che ha un effetto collaterale della conversione di "St" (abbreviazione di "street") in "ST" che può causare una falsa corrispondenza.

import android.location.Address; 
import android.util.Log; 

import java.util.HashMap; 
import java.util.Map; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class StateNameAbbreviator { 
    private static final String TAG = "StateNameAbbreviator"; 

    static private Map<String, String> mStateMap = null; 

    static public String getStateAbbreviation(Address address) { 
     if (address == null) { 
      return null; 
     } 

     populateStates(); 

     String stateCode = mStateMap.get(address.getAdminArea()); 
     if (stateCode == null) { 
      Log.d(TAG, "State mapping failed, parsing from address"); 
      stateCode = parseStateCodeFromFullAddress(address); 
      if (stateCode == null) { 
       Log.d(TAG, "Could not parse state from address"); 
      } 
     } 
     else { 
      Log.d(TAG, "Successfully mapped " + address.getAdminArea() + " to " + stateCode); 
     } 

     return stateCode; 
    } 

    static private String parseStateCodeFromFullAddress(Address address) { 
     if ((address == null) || address.getMaxAddressLineIndex() < 0) { 
      return null; 
     } 

     String fullAddress = ""; 
     for(int j = 0; j <= address.getMaxAddressLineIndex(); j++) { 
      if (address.getAddressLine(j) != null) { 
       fullAddress += " " + address.getAddressLine(j); 
      } 
     } 

     Log.d(TAG, "Full address: " + fullAddress); 

     Pattern pattern = Pattern.compile("(?<![A-Za-z0-9])([A-Z]{2})(?![A-Za-z0-9])"); 
     Matcher matcher = pattern.matcher(fullAddress); 

     String stateCode = null; 
     while (matcher.find()) { 
      stateCode = matcher.group().trim(); 
     } 

     Log.d(TAG, "Parsed statecode: " + stateCode); 

     return stateCode; 
    } 

    private static void populateStates() { 
     if (mStateMap == null) { 
      mStateMap = new HashMap<String, String>(); 
      mStateMap.put("Alabama", "AL"); 
      mStateMap.put("Alaska", "AK"); 
      mStateMap.put("Alberta", "AB"); 
      mStateMap.put("American Samoa", "AS"); 
      mStateMap.put("Arizona", "AZ"); 
      mStateMap.put("Arkansas", "AR"); 
      mStateMap.put("Armed Forces (AE)", "AE"); 
      mStateMap.put("Armed Forces Americas", "AA"); 
      mStateMap.put("Armed Forces Pacific", "AP"); 
      mStateMap.put("British Columbia", "BC"); 
      mStateMap.put("California", "CA"); 
      mStateMap.put("Colorado", "CO"); 
      mStateMap.put("Connecticut", "CT"); 
      mStateMap.put("Delaware", "DE"); 
      mStateMap.put("District Of Columbia", "DC"); 
      mStateMap.put("Florida", "FL"); 
      mStateMap.put("Georgia", "GA"); 
      mStateMap.put("Guam", "GU"); 
      mStateMap.put("Hawaii", "HI"); 
      mStateMap.put("Idaho", "ID"); 
      mStateMap.put("Illinois", "IL"); 
      mStateMap.put("Indiana", "IN"); 
      mStateMap.put("Iowa", "IA"); 
      mStateMap.put("Kansas", "KS"); 
      mStateMap.put("Kentucky", "KY"); 
      mStateMap.put("Louisiana", "LA"); 
      mStateMap.put("Maine", "ME"); 
      mStateMap.put("Manitoba", "MB"); 
      mStateMap.put("Maryland", "MD"); 
      mStateMap.put("Massachusetts", "MA"); 
      mStateMap.put("Michigan", "MI"); 
      mStateMap.put("Minnesota", "MN"); 
      mStateMap.put("Mississippi", "MS"); 
      mStateMap.put("Missouri", "MO"); 
      mStateMap.put("Montana", "MT"); 
      mStateMap.put("Nebraska", "NE"); 
      mStateMap.put("Nevada", "NV"); 
      mStateMap.put("New Brunswick", "NB"); 
      mStateMap.put("New Hampshire", "NH"); 
      mStateMap.put("New Jersey", "NJ"); 
      mStateMap.put("New Mexico", "NM"); 
      mStateMap.put("New York", "NY"); 
      mStateMap.put("Newfoundland", "NF"); 
      mStateMap.put("North Carolina", "NC"); 
      mStateMap.put("North Dakota", "ND"); 
      mStateMap.put("Northwest Territories", "NT"); 
      mStateMap.put("Nova Scotia", "NS"); 
      mStateMap.put("Nunavut", "NU"); 
      mStateMap.put("Ohio", "OH"); 
      mStateMap.put("Oklahoma", "OK"); 
      mStateMap.put("Ontario", "ON"); 
      mStateMap.put("Oregon", "OR"); 
      mStateMap.put("Pennsylvania", "PA"); 
      mStateMap.put("Prince Edward Island", "PE"); 
      mStateMap.put("Puerto Rico", "PR"); 
      mStateMap.put("Quebec", "PQ"); 
      mStateMap.put("Rhode Island", "RI"); 
      mStateMap.put("Saskatchewan", "SK"); 
      mStateMap.put("South Carolina", "SC"); 
      mStateMap.put("South Dakota", "SD"); 
      mStateMap.put("Tennessee", "TN"); 
      mStateMap.put("Texas", "TX"); 
      mStateMap.put("Utah", "UT"); 
      mStateMap.put("Vermont", "VT"); 
      mStateMap.put("Virgin Islands", "VI"); 
      mStateMap.put("Virginia", "VA"); 
      mStateMap.put("Washington", "WA"); 
      mStateMap.put("West Virginia", "WV"); 
      mStateMap.put("Wisconsin", "WI"); 
      mStateMap.put("Wyoming", "WY"); 
      mStateMap.put("Yukon Territory", "YT"); 
     } 
    } 
} 

L'espressione regolare corrisponderà due qualsiasi parola lettera maiuscola:

(?<![A-Za-z0-9])([A-Z]{2})(?![A-Za-z0-9]) 

La sfida qui è "Stati Uniti d'America" ​​sarà effettivamente corrispondere "US" con una semplice due lettere maiuscole di ricerca. Quindi abbiamo bisogno di un lookahead e lookbehind:

?<! 

lookbehind partita

(?<![A-Za-z0-9]) 

sguardo dietro le partita, e assicurarsi che non v'è un carattere alfanumerico lì (cioè, deve essere un "inizio di linea ", spazio bianco, virgola, ecc.prima della partita)

([A-Z]{2}) 

Partita due lettere maiuscole

?! 

lookahead della partita

(?![A-Za-z0-9]) 

guardare avanti della partita, e assicurarsi che non v'è un carattere alfanumerico lì (cioè, deve essere un "fine riga" o uno spazio bianco, una virgola, ecc. dopo la corrispondenza)

0

Questo lavora per me negli indirizzi statunitensi:

String[] spState = addressInformation.get(0).getAddressLine(1).split(" "); 
String state = spState[1]; 
Problemi correlati