45 #include <ogrsf_frmts.h>
47 #include <gdal_priv.h>
50 #ifdef CHECK_MEMORY_LEAKS
52 #endif // CHECK_MEMORY_LEAKS
65 myRTree(&
Triangle::addSelf), myRaster(0)
89 WRITE_WARNING(
"Cannot supply height since no height data was loaded");
100 if (result > -1e5 && result < 1e5) {
107 minB[0] = (float)geo.
x() - 0.00001f;
108 minB[1] = (float)geo.
y() - 0.00001f;
109 maxB[0] = (float)geo.
x() + 0.00001f;
110 maxB[1] = (float)geo.
y() + 0.00001f;
112 int hits =
myRTree.Search(minB, maxB, queryResult);
114 assert(hits == (
int)result.size());
117 for (Triangles::iterator it = result.begin(); it != result.end(); it++) {
120 return triangle->
getZ(geo);
133 const float cmin[2] = {(float) b.
xmin(), (float) b.
ymin()};
134 const float cmax[2] = {(float) b.
xmax(), (float) b.
ymax()};
135 myRTree.Insert(cmin, cmax, triangle);
141 if (oc.
isSet(
"heightmap.geotiff")) {
143 std::vector<std::string> files = oc.
getStringVector(
"heightmap.geotiff");
144 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
148 " done (parsed " +
toString(numFeatures) +
152 if (oc.
isSet(
"heightmap.shapefiles")) {
154 std::vector<std::string> files = oc.
getStringVector(
"heightmap.shapefiles");
155 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
159 " done (parsed " +
toString(numFeatures) +
170 OGRDataSource* ds = OGRSFDriverRegistrar::Open(file.c_str(), FALSE);
172 throw ProcessError(
"Could not open shape file '" + file +
"'.");
176 OGRLayer* layer = ds->GetLayer(0);
177 layer->ResetReading();
181 OGRSpatialReference* sr_src = layer->GetSpatialRef();
182 OGRSpatialReference sr_dest;
183 sr_dest.SetWellKnownGeogCS(
"WGS84");
184 OGRCoordinateTransformation* toWGS84 = OGRCreateCoordinateTransformation(sr_src, &sr_dest);
186 WRITE_WARNING(
"Could not create geocoordinates converter; check whether proj.4 is installed.");
191 layer->ResetReading();
192 while ((feature = layer->GetNextFeature()) != NULL) {
193 OGRGeometry* geom = feature->GetGeometryRef();
197 assert(std::string(geom->getGeometryName()) == std::string(
"POLYGON"));
199 geom->transform(toWGS84);
200 OGRLinearRing* cgeom = ((OGRPolygon*) geom)->getExteriorRing();
202 assert(cgeom->getNumPoints() == 4);
204 for (
int j = 0; j < 3; j++) {
206 corners.push_back(pos);
243 OGRFeature::DestroyFeature(feature);
245 OGRDataSource::DestroyDataSource(ds);
246 OCTDestroyCoordinateTransformation(toWGS84);
250 WRITE_ERROR(
"Cannot load shape file since SUMO was compiled without GDAL support.");
260 GDALDataset* poDataset = (GDALDataset*)GDALOpen(file.c_str(), GA_ReadOnly);
261 if (poDataset == 0) {
265 const int xSize = poDataset->GetRasterXSize();
266 const int ySize = poDataset->GetRasterYSize();
267 double adfGeoTransform[6];
268 if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None) {
269 Position topLeft(adfGeoTransform[0], adfGeoTransform[3]);
274 myBoundary.
add(topLeft.
x() + horizontalSize, topLeft.
y() + verticalSize);
276 WRITE_ERROR(
"Could not parse geo information from " + file +
".");
279 const int picSize = xSize * ySize;
280 myRaster = (int16_t*)CPLMalloc(
sizeof(int16_t) * picSize);
281 for (
int i = 1; i <= poDataset->GetRasterCount(); i++) {
282 GDALRasterBand* poBand = poDataset->GetRasterBand(i);
283 if (poBand->GetColorInterpretation() != GCI_GrayIndex) {
284 WRITE_ERROR(
"Unknown color band in " + file +
".");
288 if (poBand->GetRasterDataType() != GDT_Int16) {
293 assert(xSize == poBand->GetXSize() && ySize == poBand->GetYSize());
294 if (poBand->RasterIO(GF_Read, 0, 0, xSize, ySize,
myRaster, xSize, ySize, GDT_Int16, 0, 0) == CE_Failure) {
300 GDALClose(poDataset);
303 WRITE_ERROR(
"Cannot load GeoTIFF file since SUMO was compiled without GDAL support.");
343 return myCorners.around(pos);
361 Position side1 = myCorners[1] - myCorners[0];
362 Position side2 = myCorners[2] - myCorners[0];
void sub(SUMOReal dx, SUMOReal dy)
Substracts the given position from this one.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
SUMOReal getZ(const Position &geo) const
returns the projection of the give geoCoordinate (WGS84) onto triangle plane
bool ready() const
returns whether the NBHeightMapper has data
bool around(const Position &p, SUMOReal offset=0) const
Returns whether the boundary contains the given coordinate.
Position normalVector() const
returns the normal vector for this triangles plane
int loadShapeFile(const std::string &file)
load height data from Arcgis-shape file and returns the number of parsed features ...
SUMOReal getZ(const Position &geo) const
returns height for the given geo coordinate (WGS84)
SUMOReal ymin() const
Returns minimum y-coordinate.
SUMOReal xmin() const
Returns minimum x-coordinate.
Triangle(const PositionVector &corners)
void addTriangle(PositionVector corners)
adds one triangles worth of height data
void clearData()
clears loaded data
static NBHeightMapper Singleton
the singleton instance
NBHeightMapper()
private constructor and destructor (Singleton)
SUMOReal x() const
Returns the x-position.
#define UNUSED_PARAMETER(x)
SUMOReal xmax() const
Returns maximum x-coordinate.
A class that stores a 2D geometrical boundary.
#define WRITE_WARNING(msg)
int loadTiff(const std::string &file)
load height data from GeoTIFF file and returns the number of non void pixels
static const NBHeightMapper & get()
return the singleton instance (maybe 0)
class for cirumventing the const-restriction of RTree::Search-context
static void loadIfSet(OptionsCont &oc)
loads heigh map data if any loading options are set
TRIANGLE_RTREE_QUAL myRTree
The RTree for spatial queries.
Position crossProduct(const Position &pos)
returns the cross product between this point and the second one
A point in 2D or 3D with translation and scaling methods.
std::vector< const Triangle * > Triangles
#define PROGRESS_BEGIN_MESSAGE(msg)
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
int16_t * myRaster
raster height information in m
bool contains(const Position &pos) const
checks whether pos lies within triangle (only checks x,y)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Position mySizeOfPixel
dimensions of one pixel in raster data
Boundary myBoundary
convex boundary of all known triangles;
void add(SUMOReal x, SUMOReal y)
Makes the boundary include the given coordinate.
void reset()
Resets the boundary.
SUMOReal dotProduct(const Position &pos)
returns the dot product (scalar product) between this point and the second one
SUMOReal y() const
Returns the y-position.
PositionVector myCorners
the corners of the triangle
A storage for options typed value containers)
void set(SUMOReal x, SUMOReal y)
void addSelf(const QueryResult &queryResult) const
callback for RTree search
SUMOReal ymax() const
Returns maximum y-coordinate.
const Boundary & getBoundary()
returns the convex boundary of all known triangles
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
Set z-values for all network positions based on data from a height map.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void endProcessMsg(std::string msg)
Ends a process information.