def search(dataset, node,
    lat=None, lng=None,
    distance=100,
    ll=None, ur=None,
    start_date=None, end_date=None,
    where=None,
    max_results=50000,
    starting_number=1,
    sort_order="DESC",
    api_key=None):
    """
    :param dataset:
    
    :param node:
    
    :param lat:
    
    :param lng:
    
    :param ll:
    
    :param distance:
    
    :param ur:
    
    :param start_date:
    
    :param end_date:
    
    :param where:
        Specify additional search criteria
    
    :param max_results:
    
    :param starting_number:
    
    :param sort_order:
    
    :param api_key:
        API key is not required.
    """

    payload = {
        "datasetName": dataset,
        "node": node,
        "apiKey": api_key,
    }

    # Latitude and longitude take precedence over ll and ur
    if lat and lng:

        lats, lngs = great_circle_dist(lat, lng, distance / 2.0)

        ll = { "longitude": min(*lngs), "latitude": min(*lats) }
        ur = { "longitude": max(*lngs), "latitude": max(*lats) }

    if ll and ur:
        payload["spatialFilter"] = {
            "filterType": "mbr",
            "lowerLeft": ll,
            "upperRight": ur
        }

    if start_date or end_date:
        payload["temporalFilter"] = {
            "dateField": "search_date"
        }

        if start_date:
            payload["temporalFilter"]["startDate"] = start_date
        if end_date:
            payload["temporalFilter"]["endDate"] = end_date

    if where:

        # TODO: Support more than AND key/value equality queries
        # usgs search --node EE LANDSAT_8_C1 --start-date 20170410 --end-date 20170411 --where wrs-row 032 | jq ""
        # LC81810322017101LGN00
        payload["additionalCriteria"] = {
            "filterType": "and",
            "childFilters": [
                {
                    "filterType": "value",
                    "fieldId": field_id,
                    "value": value,
                    "operand": "="
                }
                for field_id, value in iter(where.items())
            ]
        }

    if max_results:
        payload["maxResults"] = max_results

    if starting_number:
        payload["startingNumber"] = starting_number

    if sort_order:
        payload["sortOrder"] = sort_order

    return json.dumps(payload)