From 57868f38ef0cbbe342fabe5e5ab5e8d1a38f95a1 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Tue, 13 Dec 2011 10:13:48 +0100 Subject: [PATCH] First working version of SRTM lookup --- Util/SRTMImport/NASAGridSquare.cpp | 218 +++++++++++++++++++++++++++++ Util/SRTMImport/NASAGridSquare.h | 92 ++++++++++++ Util/SRTMImport/SRTMLookup.h | 104 ++++++++++++++ Util/SRTMImport/utils.cpp | 137 ++++++++++++++++++ Util/SRTMImport/utils.h | 83 +++++++++++ 5 files changed, 634 insertions(+) create mode 100644 Util/SRTMImport/NASAGridSquare.cpp create mode 100644 Util/SRTMImport/NASAGridSquare.h create mode 100644 Util/SRTMImport/SRTMLookup.h create mode 100644 Util/SRTMImport/utils.cpp create mode 100644 Util/SRTMImport/utils.h diff --git a/Util/SRTMImport/NASAGridSquare.cpp b/Util/SRTMImport/NASAGridSquare.cpp new file mode 100644 index 000000000..0149e1eb0 --- /dev/null +++ b/Util/SRTMImport/NASAGridSquare.cpp @@ -0,0 +1,218 @@ +/* +Copyright (c) 2006 Alex Tingle + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "NASAGridSquare.h" + +NasaGridSquare::~NasaGridSquare() { + if(data) + unload(); +} + +std::string NasaGridSquare::make_filename(const char* ext) const +{ + using namespace std; + char EW =(longitude>=0?'E':'W'); + char NS =(latitude>=0?'N':'S'); + stringstream ss; +#ifdef ROOT_PATH + static const char* root_path =ROOT_PATH; +#else + static const char* root_path =FloodUtils::getenvz("ROOT_PATH","."); +#endif + ss<>8 | datum<<8); + INFO("493093: " << result); + } + + + + zip_close(test); + + while(true) { + fd=::open(filename,O_RDONLY); + if(fd>=0) + break; + DEBUG_ONLY(int saved_errno =errno;) + if(ENOENT!=errno || triedZipped || !FloodUtils::exists(gzipfile.c_str())) { + DB("Failed to open file "< "<=num_cols || row>=num_rows) + return NO_DATA; + unsigned int i=( col + row * num_cols ); +// unsigned short datum=((unsigned short*)data)[i]; +// short result=(datum>>8 | datum<<8); + unsigned short datum2=((unsigned short*)data2)[i]; + short result2=(datum2>>8 | datum2<<8); + +// INFO("[" << i << "] result: " << result << ", result2: " << (int)result2); + return result2; +} + diff --git a/Util/SRTMImport/NASAGridSquare.h b/Util/SRTMImport/NASAGridSquare.h new file mode 100644 index 000000000..3fff42b52 --- /dev/null +++ b/Util/SRTMImport/NASAGridSquare.h @@ -0,0 +1,92 @@ +/* +Copyright (c) 2006 Alex Tingle + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NASA_GRID_SQUARE_H +#define NASA_GRID_SQUARE_H + +#include +#include + +#include "utils.h" + +#include +#include +#include +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../typedefs.h" + +class NasaGridSquare { +public: + NasaGridSquare(const char* filename); + NasaGridSquare(int lng, int lat); + ~NasaGridSquare(); + short height(float lng_fraction, float lat_fraction) const; + const static short NO_DATA =-32768; ///< NASA's magic number for no data. + + /** Formula for grid squares' unique keys. */ + static int key(int lng, int lat) { + return 1000*lat + lng; + } + + /** Calculate unique key for this object. */ + int key() const {return key(longitude,latitude);} + unsigned int cols() const {return num_cols;} + unsigned int rows() const {return num_rows;} + bool has_data() const {return bool(data);} + +private: + void* data; ///< mmap'd data file. + char * data2; + int longitude; + int latitude; + int fd; ///< File ID for mmap'd data file. + unsigned int num_bytes; ///< Length of data. + unsigned int num_rows; + unsigned int num_cols; + + std::string make_filename(const char* ext) const; + void parse_filename(const char* filename, int& lng, int& lat); + + /** Loads the file into memory, pointed to by 'data'. Sets num_bytes. */ + void load(const char* filename); + void unload(); + /** Converts lng,lat floats to col,row ints. Returns TRUE if result valid. */ + bool lngLat_to_colRow( + float lng_fraction, float lat_fraction, + unsigned int& col, unsigned int& row + ) const; + short getHeight(unsigned int col, unsigned int row) const; + + friend class ReducedGridSquare; + +}; // end class NasaGridSquare + +#endif // NASA_GRID_SQUARE_H diff --git a/Util/SRTMImport/SRTMLookup.h b/Util/SRTMImport/SRTMLookup.h new file mode 100644 index 000000000..0258fc8e3 --- /dev/null +++ b/Util/SRTMImport/SRTMLookup.h @@ -0,0 +1,104 @@ +/* +Copyright (c) 2006 Alex Tingle + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef GRID_H +#define GRID_H + +#include "NASAGridSquare.h" + +#include +#include + +/** Interface to the GridSquares. Template parameter determines which kind of + * raw data is used (NASA, or reduced). GridSquare data is globally cached, so + * that many queries can be answered without having to constantly mmap & unmmap + * the data files. + * + * Typical usage: + * + * Grid g(); + * cout << g.height(lng,lat) << endl; + * + */ +template +class Grid { + static boost::unordered_map cache; + static typename boost::unordered_map::size_type cache_size; + +public: + /** The cache_limit defaults to 360. Adjust it to set the number of + * grid squares to store in memory. */ + static typename boost::unordered_map::size_type cache_limit; + + Grid(short sea_level_rise_ = 0 ) : sea_level_rise(sea_level_rise_) { + // Double check that this compiler truncates towards zero. + assert(-1 == int(float(-1.9))); + } + + /** Returns the height above sea level for the given lat/lng. */ + short height(float longitude, float latitude) const { + int lng,lat; + float lng_fraction,lat_fraction; + split(longitude,lng,lng_fraction); + split(latitude ,lat,lat_fraction); + + int k =T::key(lng,lat); + typename boost::unordered_map::iterator pos =cache.find(k); + if(pos==cache.end()) + { + if(cache_size>=cache_limit) + clear_cache(); + pos = cache.insert(std::make_pair(k,new T(lng,lat))).first; + if(pos->second->has_data()) + ++cache_size; + } + return pos->second->height(lng_fraction,lat_fraction); + } + + /** Returns TRUE if the given lng/lat is underwater. */ + bool underwater(float longitude, float latitude) const + { + short h =height(longitude,latitude); + return( h!=NasaGridSquare::NO_DATA && h<=sea_level_rise ); + } + +private: + + /** Clears the cache of non-null GridSquares. */ + void clear_cache() const { + cache.clear(); + } + + /** Split a floating point number (num) into integer (i) & fraction (f) + * components. */ + void split(float num, int& i, float& f) const { + if(num>=0.0) + i=int(num); + else + i=int(num)-1; + f=num-float(i); + } + + short sea_level_rise; +}; + +template boost::unordered_map Grid::cache; +template typename boost::unordered_map::size_type Grid::cache_size =0; +template typename boost::unordered_map::size_type Grid::cache_limit=360; + +#endif // GRID_H diff --git a/Util/SRTMImport/utils.cpp b/Util/SRTMImport/utils.cpp new file mode 100644 index 000000000..b3803da0d --- /dev/null +++ b/Util/SRTMImport/utils.cpp @@ -0,0 +1,137 @@ +/* +Copyright (c) 2006 Alex Tingle + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace FloodUtils { + +unsigned short sqrt(unsigned long a) { + return std::sqrt(a); +} + + +std::list split(const std::string& s, char token) { + std::list result; + std::string::size_type pos=0; + while(true) + { + pos=s.find_first_not_of(token,pos); + if(pos==std::string::npos) break; + std::string::size_type token_pos=s.find_first_of(token,pos); + result.push_back( s.substr(pos,token_pos-pos) ); + pos=token_pos; + } + return result; +} + + +void googleXY_to_latlng( + double x, double y, int zoom, + double& lng, double& lat +) +{ + googleX_to_lng(zoom,x,lng); + googleY_to_lat(zoom,y,lat); +} +void googleX_to_lng(int zoom, double x, double& lng) +{ + long tilesAtThisZoom =googleMaxTiles(zoom); + lng = -180.0 + (x * 360.0 / double(tilesAtThisZoom)); +} +void googleY_to_lat(int zoom, double y, double& lat) +{ + // This function is the inverse Mercator projection. + // Look up 'Mercator projection' on Wikipedia for details. + long pixels = googleMaxTiles(zoom) * 256L; + double pixelsPerLonRadian = pixels / (2.0 * M_PI); + double bitmapOrigo = pixels / 2; + + double Y = (bitmapOrigo - y*256) / pixelsPerLonRadian; + + double latRad = 2.0 * ::atan( ::exp(Y) ) - M_PI_2; + lat = latRad * 180.0 / M_PI; +} + + +/* + * Implementation copyright (C) 2004, Alex Tingle. + */ + +size_t strlcpy(char* dst, const char* src, size_t bufsize) +{ + size_t srclen =strlen(src); + size_t result =srclen; /* Result is always the length of the src string */ + if(bufsize>0) + { + if(srclen>=bufsize) + srclen=bufsize-1; + if(srclen>0) + memcpy(dst,src,srclen); + dst[srclen]='\0'; + } + return result; +} + +size_t strlcat(char* dst, const char* src, size_t bufsize) +{ + size_t dstlen =strlen(dst); + size_t srclen =strlen(src); + size_t result =dstlen+srclen; + /* truncate srclen to the buffer */ + if(result>=bufsize) + srclen=bufsize-dstlen-1; + if(srclen>0) /* if there is anything left to copy. */ + { + dst+=dstlen; + memcpy(dst,src,srclen); + dst[srclen]='\0'; + } + return result; +} + + +int getpid() +{ + return int(::getpid()); +} + + +const char* getenvz(const char* name, const char* dflt) +{ + const char* result =::getenv(name); + if(!result) + result=dflt; + return result; +} + + +bool exists(const char* path) { + std::ifstream ifile(path); + return ifile; +} + + +} // end namespace FloodUtils diff --git a/Util/SRTMImport/utils.h b/Util/SRTMImport/utils.h new file mode 100644 index 000000000..8119a4540 --- /dev/null +++ b/Util/SRTMImport/utils.h @@ -0,0 +1,83 @@ +/* +Copyright (c) 2006 Alex Tingle + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef FLOOD_UTILS_H +#define FLOOD_UTILS_H + +#include +#include +#include +#include +#include + +/* +#define ERR(x) { \ + std::stringstream s; \ + s< split(const std::string& s, char token=','); + + void googleXY_to_latlng( + double x, double y, int zoom, + double& lng, double& lat + ); + void googleX_to_lng(int zoom, double x, double& lng); + void googleY_to_lat(int zoom, double y, double& lat); + + /** Calculate the number of tiles in x or y dimensions at a zoom level. */ + inline long googleMaxTiles(int zoom) { return( 1L << (17 - zoom) ); } + + /* Specs. & semantics from: + * http://www.courtesan.com/todd/papers/strlcpy.html + */ + size_t strlcpy(char* dst, const char* src, size_t bufsize); + size_t strlcat(char* dst, const char* src, size_t bufsize); + + /** Convenience function for debug output */ + int getpid(); + + /** Convenience function for getting env vars as strings. */ + const char* getenvz(const char* name, const char* dflt =""); + + /** Check for the existence of the names file. */ + bool exists(const char* path); +} + + +#endif // FLOOD_UTILS_H