<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def iter_features(geojsonfile, func=None):
 """Extract GeoJSON features from a text file object. Given a file-like object containing a single GeoJSON feature collection text or a sequence of GeoJSON features, iter_features() iterates over lines of the file and yields GeoJSON features. Parameters geojsonfile: a file-like object The geojsonfile implements the iterator protocol and yields lines of JSON text. func: function, optional A function that will be applied to each extracted feature. It takes a feature object and may return a replacement feature or None -- in which case iter_features does not yield. """

    func = func or (lambda x: x)
    first_line = next(geojsonfile)

    # Does the geojsonfile contain RS-delimited JSON sequences?
    if first_line.startswith(u'\x1e'):
        text_buffer = first_line.strip(u'\x1e')
        for line in geojsonfile:
            if line.startswith(u'\x1e'):
                if text_buffer:
                    obj = json.loads(text_buffer)
                    if 'coordinates' in obj:
                        obj = to_feature(obj)
                    newfeat = func(obj)
                    if newfeat:
                        yield newfeat
                text_buffer = line.strip(u'\x1e')
            else:
                text_buffer += line
        # complete our parsing with a for-else clause.
        else:
            obj = json.loads(text_buffer)
            if 'coordinates' in obj:
                obj = to_feature(obj)
            newfeat = func(obj)
            if newfeat:
                yield newfeat

    # If not, it may contains LF-delimited GeoJSON objects or a single
    # multi-line pretty-printed GeoJSON object.
    else:
        # Try to parse LF-delimited sequences of features or feature
        # collections produced by, e.g., `jq -c ...`.
        try:
            obj = json.loads(first_line)
            if obj['type'] == 'Feature':
                newfeat = func(obj)
                if newfeat:
                    yield newfeat
                for line in geojsonfile:
                    newfeat = func(json.loads(line))
                    if newfeat:
                        yield newfeat
            elif obj['type'] == 'FeatureCollection':
                for feat in obj['features']:
                    newfeat = func(feat)
                    if newfeat:
                        yield newfeat
            elif 'coordinates' in obj:
                newfeat = func(to_feature(obj))
                if newfeat:
                    yield newfeat
                for line in geojsonfile:
                    newfeat = func(to_feature(json.loads(line)))
                    if newfeat:
                        yield newfeat

        # Indented or pretty-printed GeoJSON features or feature
        # collections will fail out of the try clause above since
        # they'll have no complete JSON object on their first line.
        # To handle these, we slurp in the entire file and parse its
        # text.
        except ValueError:
            text = "".join(chain([first_line], geojsonfile))
            obj = json.loads(text)
            if obj['type'] == 'Feature':
                newfeat = func(obj)
                if newfeat:
                    yield newfeat
            elif obj['type'] == 'FeatureCollection':
                for feat in obj['features']:
                    newfeat = func(feat)
                    if newfeat:
                        yield newfeat
            elif 'coordinates' in obj:
                newfeat = func(to_feature(obj))
                if newfeat:
                    yield newfeat