Code Monkey home page Code Monkey logo

Comments (6)

DzmitryFomchyn avatar DzmitryFomchyn commented on July 18, 2024 1

Hey @mtrakal,

It's reflected on public API / playground, but not in SDK.

Could you please clarify what do you mean here? Few examples will be helpful. Also, which API type you are using, v5 or SBS?

As you can see, there are 3 different types how address is formatted.

I'm not sure if this is official standard. Other sources say a slightly different formatting rules for some countries.

Anyway, I'm still not sure if this should be part of SDK unless we guarantee correct formatting. Search SDK provides address components and customers can format address in required order.

from mapbox-search-android.

kalbaxa avatar kalbaxa commented on July 18, 2024

Thank you for your suggestion @mtrakal! We will have a look, for Android specifically after 15 Dec.

cc @DzmitryFomchyn @sarochych

from mapbox-search-android.

mtrakal avatar mtrakal commented on July 18, 2024

More info what we are using and what is inconsistency between SDK and API in some old issues sample here: https://github.com/mtrakal/mapbox-issues

Search in Readme for:

Another thing is, that formatter doesn't respect the national format of address (but API respects it).
and below is description for reported issue here.

from mapbox-search-android.

mtrakal avatar mtrakal commented on July 18, 2024

API: https://docs.mapbox.com/playground/geocoding/?search_text=Bo%C5%99ivojova%2085&country=cz%2Csk%2Cpl&limit=10&types=place%2Cpostcode%2Caddress%2Cpoi&language=cs&access_token=pk.xxx used as referrence.

Any address in Czech Republic.

from mapbox-search-android.

mtrakal avatar mtrakal commented on July 18, 2024

Just provide consistent data (and preferred same data as API - like place_name_cs / place_name - a complete name with address and all will be fine. If it will return proper address in selected locale.

For now I must do this mess in code just to show proper / nice address name:

import com.mapbox.search.result.SearchAddress
import com.mapbox.search.result.SearchResult
import com.mapbox.search.result.SearchResultType
import com.mapbox.search.result.SearchSuggestion
import com.mapbox.search.result.SearchSuggestionType

val SearchResult.fullAddress: String
    get() = when (types.firstByType()) {
        SearchResultType.COUNTRY -> withName(address?.countryAddress) // usa
        SearchResultType.REGION -> withName(address?.regionAddress) // Liberecký kraj
        SearchResultType.POSTCODE,
        SearchResultType.BLOCK -> withName(address?.postcodeAddress) // 468 22
        SearchResultType.DISTRICT -> address?.districtAddress //
        SearchResultType.PLACE -> withName(address?.placeAddress) // Praha
        SearchResultType.LOCALITY -> withName(address?.localityAddress) // Manhattan / Písek Líšťany
        SearchResultType.NEIGHBORHOOD -> address?.neighborhoodAddress // ?
        SearchResultType.STREET -> address?.streetAddress // never used, SDK return error, if try to use STREET 🤦‍
        SearchResultType.ADDRESS -> address?.houseAddress // any czech street is returned as address 🤷‍
        SearchResultType.POI -> withName(address?.poiAddress) // Cross club
        null -> null
    }.orEmpty()
        .distinct()
        .filter { it.isNotBlank() }
        .joinToString(", ")
        .trim()

/**
 * Add name of suggestion, because address don't contains this info in some cases...
 */
private fun SearchResult.withName(address: List<String>?) = listOfNotNull(name) + address.orEmpty()

val SearchSuggestion.fullAddress: String
    get() = when (this.type.getSearchSuggestionType()) {
        SearchResultType.COUNTRY -> withName(address?.countryAddress) // usa
        SearchResultType.REGION -> withName(address?.regionAddress) // Liberecký kraj
        SearchResultType.POSTCODE,
        SearchResultType.BLOCK -> withName(address?.postcodeAddress) // 468 22
        SearchResultType.DISTRICT -> address?.districtAddress //
        SearchResultType.PLACE -> withName(address?.placeAddress) // Praha
        SearchResultType.LOCALITY -> withName(address?.localityAddress) // Manhattan / Písek Líšťany
        SearchResultType.NEIGHBORHOOD -> address?.neighborhoodAddress // ?
        SearchResultType.STREET -> address?.streetAddress // never used, SDK return error, if try to use STREET 🤦‍
        SearchResultType.ADDRESS -> address?.houseAddress // any czech street is returned as address 🤷‍
        SearchResultType.POI -> withName(address?.poiAddress) // Cross club
        null -> null
    }.orEmpty()
        .distinct()
        .filter { it.isNotBlank() }
        .joinToString(", ")
        .trim()

/**
 * Add name of suggestion, because address don't contains this info in some cases...
 */
private fun SearchSuggestion.withName(address: List<String>?) = listOfNotNull(name) + address.orEmpty()

/**
 * Generally recognized countries or, in some cases like Hong Kong, an area of quasi-national
 * administrative status that has been given a designated country code under ISO 3166-1.
 */
private val SearchAddress.countryAddress: List<String>
    get() = listOfNotNull(country)

/**
 * Top-level sub-national administrative features, such as states in the United States
 * or provinces in Canada or China.
 */
private val SearchAddress.regionAddress: List<String>
    get() = listOfNotNull(region, country)

/**
 * Postal codes used in country-specific national addressing systems.
 */
private val SearchAddress.postcodeAddress: List<String>
    get() = listOfNotNull(postcode, place, region)

/**
 * Features that are smaller than top-level administrative features but typically larger than cities,
 * in countries that use such an additional layer in postal addressing (for example, prefectures in China).
 */
private val SearchAddress.districtAddress: List<String>
    get() = listOfNotNull(district, postcode, region)

/**
 * Typically these are cities, villages, municipalities, etc.
 * They’re usually features used in postal addressing, and are suitable for display in ambient
 * end-user applications where current-location context is needed (for example, in weather displays).
 */
private val SearchAddress.placeAddress: List<String>
    get() = listOfNotNull(place, district, postcode, region)

/**
 * Official sub-city features present in countries where such an additional administrative layer
 * is used in postal addressing, or where such features are commonly referred to in local parlance.
 * Examples include city districts in Brazil and Chile and arrondissements in France.
 */
private val SearchAddress.localityAddress: List<String>
    get() = listOfNotNull(locality, place, district, postcode, region)

/**
 * Colloquial sub-city features often referred to in local parlance.
 * Unlike locality features, these typically lack official status and may lack universally agreed-upon boundaries.
 */
private val SearchAddress.neighborhoodAddress: List<String>
    get() = listOfNotNull(neighborhood, locality, place, district, postcode, region)

/**
 * Features that are smaller than places and that correspond to streets in cities, villages, etc.
 */
private val SearchAddress.streetAddress: List<String>
    get() = listOfNotNull(street, neighborhood, locality, place, district, postcode, region)

/**
 * Individual residential or business addresses.
 */
private val SearchAddress.houseAddress: List<String>
    get() = listOfNotNull(
        streetWithHouseNumber,
        neighborhood,
        locality,
        place,
        district,
        postcode,
        region
    )

/**
 * Points of interest.
 * These include restaurants, stores, concert venues, parks, museums, etc.
 */
private val SearchAddress.poiAddress: List<String>
    get() = listOfNotNull(
        streetWithHouseNumber,
        neighborhood,
        locality,
        place,
        district,
        postcode
    )

private fun SearchSuggestionType.getSearchSuggestionType(): SearchResultType? = when (this) {
    is SearchSuggestionType.SearchResultSuggestion -> this.types.firstByType()
    is SearchSuggestionType.Category, is SearchSuggestionType.Query -> null
    else -> error("Unknown SearchSuggestionType type: $this.")
}

/**
 * Get most weighted type from list of [SearchResultType].
 */
private fun List<SearchResultType>.firstByType(): SearchResultType? = this.maxByOrNull { it.weight }

/**
 * Ordering weight by priority (most precise address has highest weight).
 */
private val SearchResultType.weight: Int
    get() = when (this) {
        SearchResultType.COUNTRY -> 0
        SearchResultType.REGION -> 1
        SearchResultType.POSTCODE -> 2
        SearchResultType.BLOCK -> 3
        SearchResultType.PLACE -> 4
        SearchResultType.DISTRICT -> 5
        SearchResultType.LOCALITY -> 6
        SearchResultType.NEIGHBORHOOD -> 7
        SearchResultType.STREET -> 8
        SearchResultType.ADDRESS -> 9
        SearchResultType.POI -> 10
    }

/**
 * Format House number and Street name to most used European format (not at all EU countries).
 * https://qph.cf2.quoracdn.net/main-qimg-fed2c12535f9552efa214450c4c87881
 * Created issue on MapBox: https://github.com/mapbox/mapbox-search-android/issues/112
 */
private val SearchAddress.streetWithHouseNumber: String
    get() = "${street.orEmpty()} ${houseNumber.orEmpty()}".trim()

How it works:

  • check what type of address result is (POI, Address, City, etc)
  • add name for addresses, which don’t have all fields filled in SearchAddress object. In that case is used SearchResult.name or SearchSuggestion.name
  • add proper fields of address for the specified type (not show all fields for full address etc.
    We don’t want to show Bořivojova 11, Praha 3 (Locality), Praha (place), 1300, Praha (region), Czech Republic (country)
  • use European house/street convention (Street HouseNumber - with space as divider) for full address

from mapbox-search-android.

DzmitryFomchyn avatar DzmitryFomchyn commented on July 18, 2024

@mtrakal thanks for the details!
We've fixed this issue in the 1.0.0-beta.46. Now SearchSuggestion.name/SearchResult.name return house number and street in a correct order. Besides that we've added a new field SearchSuggestion.fullAddress/SearchResult.fullAddress that returns full formatted address from the backend.

I'll close this issue for now. Feel free to reopen it or create an ew one if you have more questions.

from mapbox-search-android.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.