def detection_features_to_geojson()

in src/mapillary/utils/format.py [0:0]


def detection_features_to_geojson(feature_list: list) -> dict:
    """
    Converts a preprocessed list (i.e, features from the detections of either images or
    map_features from multiple segments) into a fully featured GeoJSON

    :param feature_list: A list of processed features merged from different segments within a
        detection
    :type feature_list: list

    :return: GeoJSON formatted as expected in a detection format
    :rtype: dict

    Example::

        >>> # From
        >>> [{'created_at': '2021-05-20T17:49:01+0000', 'geometry':
        ... 'GjUKBm1weS1vchIVEgIAABgDIg0JhiekKBoqAABKKQAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==',
        ... 'image': {'geometry': {'type': 'Point', 'coordinates': [-97.743279722222,
        ... 30.270651388889]}, 'id': '1933525276802129'}, 'value': 'regulatory--no-parking--g2',
        ... 'id': '1942105415944115'}, ... ]
        >>> # To
        >>> {'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'geometry':
        ... {'type': 'Point', 'coordinates': [-97.743279722222, 30.270651388889]}, 'properties': {
        ... 'image_id': '1933525276802129', 'created_at': '2021-05-20T17:49:01+0000',
        ... 'pixel_geometry':
        ... 'GjUKBm1weS1vchIVEgIAABgDIg0JhiekKBoqAABKKQAPGgR0eXBlIgkKB3BvbHlnb24ogCB4AQ==',
        ... 'value': 'regulatory--no-parking--g2', 'id': '1942105415944115' } }, ... ]}
    """

    resulting_geojson = {
        # FeatureCollection type
        "type": "FeatureCollection",
        # List of features
        "features": [
            # Feature generation from feature_list
            {
                # Type is 'Feature'
                "type": "Feature",
                # Let 'geometry' be the `image` key, defaults to {} is `image` not in feature
                "geometry": {
                    "type": "Point",
                    "coordinates": feature["image"]["geometry"]["coordinates"],
                }
                if "image" in feature
                else {},
                # Property list
                "possible_none_properties": {
                    # Only if "image" was specified in the `fields` of the endpoint, else None
                    "image_id": feature["image"]["id"]
                    if "image" in "feature"
                    else None,
                    # Only if "created_at" was specified in the `fields` of the endpoint, else None
                    "created_at": feature["created_at"]
                    if "created_at" in feature
                    else None,
                    # Only if "geometry" was specified in the `fields` of the endpoint, else None
                    "pixel_geometry": feature["geometry"]
                    if "geometry" in feature
                    else None,
                    # Only if "value" was specified in the `fields` of the endpoint, else None
                    "value": feature["value"] if "value" in feature else None,
                    # "id" is always available in the response
                    "id": feature["id"],
                },
                "properties": {},
            }
            # Going through the given of features
            for feature in feature_list
        ],
    }

    # The next logic below removes features that defaulted to None

    # Through each feature in the resulting features
    for _feature in resulting_geojson["features"]:

        # Going through each property in the feature
        for key, value in _feature["possible_none_properties"].items():

            # If the _property is not None
            if value is not None:

                # Add that property to the _feature
                _feature["properties"][key] = value

    for _feature in resulting_geojson["features"]:

        del _feature["possible_none_properties"]

    # Finally return the output
    return resulting_geojson