def _create_overpass_features_query(  # noqa: PLR0912
    polygon_coord_str: str,
    tags: dict[str, bool | str | list[str]],
) -> str:
    """
    Create an Overpass features query string based on tags.

    Parameters
    ----------
    polygon_coord_str
        The lat lon coordinates.
    tags
        Tags used for finding elements in the search area.

    Returns
    -------
    query
        The Overpass features query.
    """
    # create overpass settings string
    overpass_settings = _make_overpass_settings()

    # make sure every value in dict is bool, str, or list of str
    err_msg = "`tags` must be a dict with values of bool, str, or list of str."
    if not isinstance(tags, dict):  # pragma: no cover
        raise TypeError(err_msg)

    tags_dict: dict[str, bool | str | list[str]] = {}
    for key, value in tags.items():
        if isinstance(value, bool):
            tags_dict[key] = value

        elif isinstance(value, str):
            tags_dict[key] = [value]

        elif isinstance(value, list):
            if not all(isinstance(s, str) for s in value):  # pragma: no cover
                raise TypeError(err_msg)
            tags_dict[key] = value

        else:  # pragma: no cover
            raise TypeError(err_msg)

    # convert the tags dict into a list of {tag:value} dicts
    tags_list: list[dict[str, bool | str | list[str]]] = []
    for key, value in tags_dict.items():
        if isinstance(value, bool):
            tags_list.append({key: value})
        else:
            for value_item in value:
                tags_list.append({key: value_item})  # noqa: PERF401

    # add node/way/relation query components one at a time
    components = []
    for d in tags_list:
        for key, value in d.items():
            if isinstance(value, bool):
                # if bool (ie, True) just pass the key, no value
                tag_str = f"[{key!r}](poly:{polygon_coord_str!r});(._;>;);"
            else:
                # otherwise, pass "key"="value"
                tag_str = f"[{key!r}={value!r}](poly:{polygon_coord_str!r});(._;>;);"

            for kind in ("node", "way", "relation"):
                components.append(f"({kind}{tag_str});")  # noqa: PERF401

    # finalize query and return
    components_str = "".join(components)
    return f"{overpass_settings};({components_str});out;"

    Create an Overpass features query string based on tags.

    Parameters
    ----------
    polygon_coord_str
        The lat lon coordinates.
    tags
        Tags used for finding elements in the search area.

    Returns
    -------
    query
        The Overpass features query.
    
osmnx/_overpass.py