SUMO - Simulation of Urban MObility
PCLoaderArcView.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // A reader of pois and polygons from shape files
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include <string>
00034 #include <utils/common/MsgHandler.h>
00035 #include <utils/common/ToString.h>
00036 #include <utils/common/StringUtils.h>
00037 #include <utils/options/OptionsCont.h>
00038 #include <utils/geom/GeomHelper.h>
00039 #include "PCLoaderArcView.h"
00040 #include <utils/geom/GeoConvHelper.h>
00041 #include <utils/common/RGBColor.h>
00042 #include <polyconvert/PCPolyContainer.h>
00043 
00044 #ifdef HAVE_GDAL
00045 #include <ogrsf_frmts.h>
00046 #endif
00047 
00048 #ifdef CHECK_MEMORY_LEAKS
00049 #include <foreign/nvwa/debug_new.h>
00050 #endif // CHECK_MEMORY_LEAKS
00051 
00052 
00053 // ===========================================================================
00054 // method definitions
00055 // ===========================================================================
00056 void
00057 PCLoaderArcView::loadIfSet(OptionsCont& oc, PCPolyContainer& toFill,
00058                            PCTypeMap& tm) {
00059     if (!oc.isSet("shapefile-prefixes")) {
00060         return;
00061     }
00062     // parse file(s)
00063     std::vector<std::string> files = oc.getStringVector("shapefile-prefixes");
00064     for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
00065         PROGRESS_BEGIN_MESSAGE("Parsing from shape-file '" + *file + "'");
00066         load(*file, oc, toFill, tm);
00067         PROGRESS_DONE_MESSAGE();
00068     }
00069 }
00070 
00071 
00072 
00073 void
00074 PCLoaderArcView::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill,
00075                       PCTypeMap&) {
00076 #ifdef HAVE_GDAL
00077     GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing();
00078     // get defaults
00079     std::string prefix = oc.getString("prefix");
00080     std::string type = oc.getString("type");
00081     RGBColor color = RGBColor::parseColor(oc.getString("color"));
00082     int layer = oc.getInt("layer");
00083     std::string idField = oc.getString("shapefile.id-column");
00084     // start parsing
00085     std::string shpName = file + ".shp";
00086     OGRRegisterAll();
00087     OGRDataSource* poDS = OGRSFDriverRegistrar::Open(shpName.c_str(), FALSE);
00088     if (poDS == NULL) {
00089         throw ProcessError("Could not open shape description '" + shpName + "'.");
00090     }
00091 
00092     // begin file parsing
00093     OGRLayer*  poLayer = poDS->GetLayer(0);
00094     poLayer->ResetReading();
00095 
00096     // build coordinate transformation
00097     OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
00098     OGRSpatialReference destTransf;
00099     // use wgs84 as destination
00100     destTransf.SetWellKnownGeogCS("WGS84");
00101     OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf);
00102     if (poCT == NULL) {
00103         if (oc.isSet("shapefile.guess-projection")) {
00104             OGRSpatialReference origTransf2;
00105             origTransf2.SetWellKnownGeogCS("WGS84");
00106             poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
00107         }
00108         if (poCT == 0) {
00109             WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed.");
00110         }
00111     }
00112 
00113     OGRFeature* poFeature;
00114     poLayer->ResetReading();
00115     while ((poFeature = poLayer->GetNextFeature()) != NULL) {
00116         // read in edge attributes
00117         std::string id = poFeature->GetFieldAsString(idField.c_str());
00118         id = StringUtils::prune(id);
00119         if (id == "") {
00120             throw ProcessError("Missing id under '" + idField + "'");
00121         }
00122         id = prefix + id;
00123         // read in the geometry
00124         OGRGeometry* poGeometry = poFeature->GetGeometryRef();
00125         if (poGeometry != 0) {
00126             // try transform to wgs84
00127             poGeometry->transform(poCT);
00128         }
00129         OGRwkbGeometryType gtype = poGeometry->getGeometryType();
00130         switch (gtype) {
00131             case wkbPoint: {
00132                 OGRPoint* cgeom = (OGRPoint*) poGeometry;
00133                 Position pos((SUMOReal) cgeom->getX(), (SUMOReal) cgeom->getY());
00134                 if (!geoConvHelper.x2cartesian(pos)) {
00135                     WRITE_ERROR("Unable to project coordinates for POI '" + id + "'.");
00136                 }
00137                 PointOfInterest* poi = new PointOfInterest(id, type, pos, color);
00138                 if (!toFill.insert(id, poi, layer)) {
00139                     WRITE_ERROR("POI '" + id + "' could not been added.");
00140                     delete poi;
00141                 }
00142             }
00143             break;
00144             case wkbLineString: {
00145                 OGRLineString* cgeom = (OGRLineString*) poGeometry;
00146                 PositionVector shape;
00147                 for (int j = 0; j < cgeom->getNumPoints(); j++) {
00148                     Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j));
00149                     if (!geoConvHelper.x2cartesian(pos)) {
00150                         WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
00151                     }
00152                     shape.push_back_noDoublePos(pos);
00153                 }
00154                 Polygon* poly = new Polygon(id, type, color, shape, false);
00155                 if (!toFill.insert(id, poly, layer)) {
00156                     WRITE_ERROR("Polygon '" + id + "' could not been added.");
00157                     delete poly;
00158                 }
00159             }
00160             break;
00161             case wkbPolygon: {
00162                 OGRLinearRing* cgeom = ((OGRPolygon*) poGeometry)->getExteriorRing();
00163                 PositionVector shape;
00164                 for (int j = 0; j < cgeom->getNumPoints(); j++) {
00165                     Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j));
00166                     if (!geoConvHelper.x2cartesian(pos)) {
00167                         WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'.");
00168                     }
00169                     shape.push_back_noDoublePos(pos);
00170                 }
00171                 Polygon* poly = new Polygon(id, type, color, shape, true);
00172                 if (!toFill.insert(id, poly, layer)) {
00173                     WRITE_ERROR("Polygon '" + id + "' could not been added.");
00174                     delete poly;
00175                 }
00176             }
00177             break;
00178             case wkbMultiPoint: {
00179                 OGRMultiPoint* cgeom = (OGRMultiPoint*) poGeometry;
00180                 for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
00181                     OGRPoint* cgeom2 = (OGRPoint*) cgeom->getGeometryRef(i);
00182                     Position pos((SUMOReal) cgeom2->getX(), (SUMOReal) cgeom2->getY());
00183                     std::string tid = id + "#" + toString(i);
00184                     if (!geoConvHelper.x2cartesian(pos)) {
00185                         WRITE_ERROR("Unable to project coordinates for POI '" + tid + "'.");
00186                     }
00187                     PointOfInterest* poi = new PointOfInterest(tid, type, pos, color);
00188                     if (!toFill.insert(tid, poi, layer)) {
00189                         WRITE_ERROR("POI '" + tid + "' could not been added.");
00190                         delete poi;
00191                     }
00192                 }
00193             }
00194             break;
00195             case wkbMultiLineString: {
00196                 OGRMultiLineString* cgeom = (OGRMultiLineString*) poGeometry;
00197                 for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
00198                     OGRLineString* cgeom2 = (OGRLineString*) cgeom->getGeometryRef(i);
00199                     PositionVector shape;
00200                     std::string tid = id + "#" + toString(i);
00201                     for (int j = 0; j < cgeom2->getNumPoints(); j++) {
00202                         Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j));
00203                         if (!geoConvHelper.x2cartesian(pos)) {
00204                             WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
00205                         }
00206                         shape.push_back_noDoublePos(pos);
00207                     }
00208                     Polygon* poly = new Polygon(tid, type, color, shape, false);
00209                     if (!toFill.insert(tid, poly, layer)) {
00210                         WRITE_ERROR("Polygon '" + tid + "' could not been added.");
00211                         delete poly;
00212                     }
00213                 }
00214             }
00215             break;
00216             case wkbMultiPolygon: {
00217                 OGRMultiPolygon* cgeom = (OGRMultiPolygon*) poGeometry;
00218                 for (int i = 0; i < cgeom->getNumGeometries(); ++i) {
00219                     OGRLinearRing* cgeom2 = ((OGRPolygon*) cgeom->getGeometryRef(i))->getExteriorRing();
00220                     PositionVector shape;
00221                     std::string tid = id + "#" + toString(i);
00222                     for (int j = 0; j < cgeom2->getNumPoints(); j++) {
00223                         Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j));
00224                         if (!geoConvHelper.x2cartesian(pos)) {
00225                             WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'.");
00226                         }
00227                         shape.push_back_noDoublePos(pos);
00228                     }
00229                     Polygon* poly = new Polygon(tid, type, color, shape, true);
00230                     if (!toFill.insert(tid, poly, layer)) {
00231                         WRITE_ERROR("Polygon '" + tid + "' could not been added.");
00232                         delete poly;
00233                     }
00234                 }
00235             }
00236             break;
00237             default:
00238                 WRITE_WARNING("Unsupported shape type occured (id='" + id + "').");
00239                 break;
00240         }
00241         OGRFeature::DestroyFeature(poFeature);
00242     }
00243     PROGRESS_DONE_MESSAGE();
00244 #else
00245     WRITE_ERROR("SUMO was compiled without GDAL support.");
00246 #endif
00247 }
00248 
00249 
00250 /****************************************************************************/
00251 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines