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