def get_elevation(dataset_name, methods=["GET", "OPTIONS", "HEAD"]): """Calculate the elevation for the given locations. Args: dataset_name: String matching a dataset in the config file. Returns: Response. """ try: # Parse inputs. interpolation = _parse_interpolation(request.args.get("interpolation")) nodata_value = _parse_nodata_value(request.args.get("nodata_value")) lats, lons = _parse_locations( request.args.get("locations"), _load_config()["max_locations_per_request"]) # Get the z values. dataset = _get_dataset(dataset_name) elevations = backend.get_elevation(lats, lons, dataset, interpolation) elevations = utils.fill_na(elevations, nodata_value) # Build response. results = [] for z, lat, lon in zip(elevations, lats, lons): results.append({ "elevation": z, "location": { "lat": lat, "lng": lon } }) data = {"status": "OK", "results": results} return jsonify(data) except (ClientError, backend.InputError) as e: return jsonify({"status": "INVALID_REQUEST", "error": str(e)}), 400 except config.ConfigError as e: return ( jsonify({ "status": "SERVER_ERROR", "error": "Config Error: {}".format(e) }), 500, ) except Exception as e: if app.debug: raise e app.logger.error(e) msg = "Server error, please retry request." return jsonify({"status": "SERVER_ERROR", "error": msg}), 500
def _get_elevation_for_single_dataset(lats, lons, dataset, interpolation="nearest", nodata_value=None): """Read elevations from a dataset. A dataset may consist of multiple files, so need to determine which locations lies in which file, then loop over the files. Args: lats, lons: Arrays of latitudes/longitudes. dataset: config.Dataset object. interpolation: method name string. Returns: elevations: List of elevations, same length as lats/lons. """ # Which paths we need results from. lats = np.array(lats) lons = np.array(lons) paths = dataset.location_paths(lats, lons) # Store mapping of tile path to point so we can merge back together later. elevations_by_path = {} path_to_point_index = collections.defaultdict(list) for i, path in enumerate(paths): path_to_point_index[path].append(i) # Batch results by path. for path, indices in path_to_point_index.items(): if path is None: elevations_by_path[None] = [None] * len(indices) continue batch_lats = lats[path_to_point_index[path]] batch_lons = lons[path_to_point_index[path]] elevations_by_path[path] = _get_elevation_from_path( batch_lats, batch_lons, path, interpolation) # Put the results back again. elevations = [None] * len(paths) for path, path_elevations in elevations_by_path.items(): for i_path, i_original in enumerate(path_to_point_index[path]): elevations[i_original] = path_elevations[i_path] elevations = utils.fill_na(elevations, nodata_value) return elevations
def test_replacement(self): na_value = -9999 values = [np.nan, float("nan"), 0] replaced_values = [na_value, na_value, 0] assert utils.fill_na(values, na_value) == replaced_values
def test_no_replacement(self): a = [-12.5, None, 9, "string", True, False, 0, 1, "NaN"] assert a == utils.fill_na(a, "na_value")