void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature) { OGRLinearRing* exterior = geom->getExteriorRing(); int num_points = exterior->getNumPoints(); int num_interior = geom->getNumInteriorRings(); int capacity = 0; for (int r = 0; r < num_interior; r++) { OGRLinearRing* interior = geom->getInteriorRing(r); capacity += interior->getNumPoints(); } geometry_type* poly = new geometry_type(mapnik::Polygon); poly->move_to(exterior->getX(0), exterior->getY(0)); for (int i = 1; i < num_points; ++i) { poly->line_to(exterior->getX(i), exterior->getY(i)); } for (int r = 0; r < num_interior; r++) { OGRLinearRing* interior = geom->getInteriorRing(r); num_points = interior->getNumPoints(); poly->move_to(interior->getX(0), interior->getY(0)); for (int i = 1; i < num_points; ++i) { poly->line_to(interior->getX(i), interior->getY(i)); } } feature->add_geometry(poly); }
Polygon GeomToPoly(OGRGeometry* geometry){ OGRLinearRing *ring = dynamic_cast<OGRLinearRing *>(dynamic_cast<OGRPolygon *>(geometry)->getExteriorRing()); Polygon skeleton; for(int i=0; i < ring->getNumPoints() - 1; i++) if(CGAL::is_finite(ring->getX(i)) && CGAL::is_finite(ring->getY(i))) skeleton.push_back(Point(ring->getX(i), ring->getY(i))); return skeleton; }
void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature) { OGRLinearRing* exterior = geom->getExteriorRing(); int num_points = exterior->getNumPoints(); int num_interior = geom->getNumInteriorRings(); int capacity = 0; for (int r = 0; r < num_interior; ++r) { OGRLinearRing* interior = geom->getInteriorRing(r); capacity += interior->getNumPoints(); } std::auto_ptr<geometry_type> poly(new geometry_type(mapnik::Polygon)); poly->move_to(exterior->getX(0), exterior->getY(0)); for (int i = 1; i < num_points - 1; ++i) { poly->line_to(exterior->getX(i), exterior->getY(i)); } poly->close(exterior->getX(num_points-1), exterior->getY(num_points-1)); for (int r = 0; r < num_interior; ++r) { OGRLinearRing* interior = geom->getInteriorRing(r); num_points = interior->getNumPoints(); poly->move_to(interior->getX(0), interior->getY(0)); for (int i = 1; i < num_points - 1; ++i) { poly->line_to(interior->getX(i), interior->getY(i)); } poly->close(interior->getX(num_points-1), interior->getY(num_points-1)); } feature->paths().push_back(poly); }
int OGRGetCentroid(OGRPolygon *poPoly, OGRPoint *poCentroid) { int i,j; double cent_weight_x=0.0, cent_weight_y=0.0; double len, total_len=0; for(i=0; i<OGR_NUM_RINGS(poPoly); i++) { double x1, y1, x2, y2; OGRLinearRing *poRing = OGR_GET_RING(poPoly, i); x2 = poRing->getX(0); y2 = poRing->getY(0); for(j=1; j<poRing->getNumPoints(); j++) { x1 = x2; y1 = y2; x2 = poRing->getX(j); y2 = poRing->getY(j); len = sqrt( pow((x2-x1),2) + pow((y2-y1),2) ); cent_weight_x += len * ((x1 + x2)/2.0); cent_weight_y += len * ((y1 + y2)/2.0); total_len += len; } } if(total_len == 0) return(OGRERR_FAILURE); poCentroid->setX( cent_weight_x / total_len ); poCentroid->setY( cent_weight_y / total_len ); return OGRERR_NONE; }
std::vector<Polygon::Ring> Polygon::interiorRings() const { std::vector<Ring> rings; OGRwkbGeometryType t = m_geom->getGeometryType(); if (t != wkbPolygon && t != wkbPolygon25D) throw pdal_error("Request for exterior ring on non-polygon."); // OGRPolygon *poly = m_geom->toPolygon(); OGRPolygon *poly = static_cast<OGRPolygon *>(m_geom.get()); for (int i = 0; i < poly->getNumInteriorRings(); ++i) { OGRLinearRing *er = poly->getInteriorRing(i); Ring r; for (int j = 0; j < er->getNumPoints(); ++j) r.push_back({er->getX(j), er->getY(j)}); rings.push_back(r); } return rings; }
Polygon::Ring Polygon::exteriorRing() const { Ring r; OGRwkbGeometryType t = m_geom->getGeometryType(); if (t != wkbPolygon && t != wkbPolygon25D) throw pdal_error("Request for exterior ring on non-polygon."); // Not until GDAL 2.3 /** OGRLinearRing *er = m_geom->toPolygon()->getExteriorRing(); // For some reason there's no operator -> on an iterator. for (auto it = er->begin(); it != er->end(); ++it) r.push_back({(*it).getX(), (*it).getY()}); **/ OGRLinearRing *er = static_cast<OGRPolygon *>(m_geom.get())->getExteriorRing(); for (int i = 0; i < er->getNumPoints(); ++i) r.push_back({er->getX(i), er->getY(i)}); return r; }
MultiPolygonGraphics::MultiPolygonGraphics(OGRMultiPolygon* OGRMultiPoly, const QPen& Pen, const QBrush& Brush): SurfacicGraphics(Brush.color()) { QPainterPath Path; for (int i=0; i<OGRMultiPoly->getNumGeometries();i++) { OGRLinearRing* LinearRing = dynamic_cast<OGRPolygon*>(OGRMultiPoly->getGeometryRef(i))->getExteriorRing(); QPolygonF Poly; for (int i=0; i < LinearRing->getNumPoints(); i++) Poly << QPointF(LinearRing->getX(i),LinearRing->getY(i)); Path.addPolygon(Poly); } setPen(Pen); setBrush(Brush); setPath(Path); }
Surface* Building::extrude_envelope() const { Surface* envelope = new Surface(SurfaceType::Envelope,0,_length,_width,_height); OGRLinearRing* ringFt = _footprint->getExteriorRing(); if(ringFt->isClockwise()) adjust_winding_ccw(ringFt); envelope->addChild(new Surface(SurfaceType::Footprint,_footprint,_length,_width,0.)); //extrude roof OGRLinearRing* ringRoof = new OGRLinearRing; for(int i=0; i<ringFt->getNumPoints(); i++) ringRoof->addPoint(ringFt->getX(i),ringFt->getY(i),_height); OGRPolygon plyRoof; plyRoof.addRingDirectly(ringRoof); envelope->addChild(new Surface(SurfaceType::Roof,&plyRoof,_length,_width,0.)); //extrude walls for(int i=0; i<ringFt->getNumPoints()-1; i++) { OGRLinearRing* ringWall = new OGRLinearRing; ringWall->addPoint(ringFt->getX(i),ringFt->getY(i),0); ringWall->addPoint(ringFt->getX(i+1),ringFt->getY(i+1),0); ringWall->addPoint(ringFt->getX(i+1),ringFt->getY(i+1),_height); ringWall->addPoint(ringFt->getX(i),ringFt->getY(i),_height); ringWall->addPoint(ringFt->getX(i),ringFt->getY(i),0); OGRPolygon plyWall; plyWall.addRingDirectly(ringWall); OGRPoint pt1(ringFt->getX(i),ringFt->getY(i),0); OGRPoint pt2(ringFt->getX(i+1),ringFt->getY(i+1),0); envelope->addChild(new Wall(&plyWall,pt1.Distance(&pt2),_height,&pt1,&pt2)); } return envelope; }
void PCLoaderArcView::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill, PCTypeMap&) { #ifdef HAVE_GDAL GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing(); // get defaults std::string prefix = oc.getString("prefix"); std::string type = oc.getString("type"); RGBColor color = RGBColor::parseColor(oc.getString("color")); int layer = oc.getInt("layer"); std::string idField = oc.getString("shapefile.id-column"); bool useRunningID = oc.getBool("shapefile.use-running-id"); // start parsing std::string shpName = file + ".shp"; OGRRegisterAll(); OGRDataSource* poDS = OGRSFDriverRegistrar::Open(shpName.c_str(), FALSE); if (poDS == NULL) { throw ProcessError("Could not open shape description '" + shpName + "'."); } // begin file parsing OGRLayer* poLayer = poDS->GetLayer(0); poLayer->ResetReading(); // build coordinate transformation OGRSpatialReference* origTransf = poLayer->GetSpatialRef(); OGRSpatialReference destTransf; // use wgs84 as destination destTransf.SetWellKnownGeogCS("WGS84"); OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf); if (poCT == NULL) { if (oc.isSet("shapefile.guess-projection")) { OGRSpatialReference origTransf2; origTransf2.SetWellKnownGeogCS("WGS84"); poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf); } if (poCT == 0) { WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed."); } } OGRFeature* poFeature; poLayer->ResetReading(); unsigned int runningID = 0; while ((poFeature = poLayer->GetNextFeature()) != NULL) { // read in edge attributes std::string id = useRunningID ? toString(runningID) : poFeature->GetFieldAsString(idField.c_str()); ++runningID; id = StringUtils::prune(id); if (id == "") { throw ProcessError("Missing id under '" + idField + "'"); } id = prefix + id; // read in the geometry OGRGeometry* poGeometry = poFeature->GetGeometryRef(); if (poGeometry == 0) { OGRFeature::DestroyFeature(poFeature); continue; } // try transform to wgs84 poGeometry->transform(poCT); OGRwkbGeometryType gtype = poGeometry->getGeometryType(); switch (gtype) { case wkbPoint: { OGRPoint* cgeom = (OGRPoint*) poGeometry; Position pos((SUMOReal) cgeom->getX(), (SUMOReal) cgeom->getY()); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for POI '" + id + "'."); } PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer); if (!toFill.insert(id, poi, layer)) { WRITE_ERROR("POI '" + id + "' could not be added."); delete poi; } } break; case wkbLineString: { OGRLineString* cgeom = (OGRLineString*) poGeometry; PositionVector shape; for (int j = 0; j < cgeom->getNumPoints(); j++) { Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(id, type, color, shape, false, (SUMOReal)layer); if (!toFill.insert(id, poly, layer)) { WRITE_ERROR("Polygon '" + id + "' could not be added."); delete poly; } } break; case wkbPolygon: { OGRLinearRing* cgeom = ((OGRPolygon*) poGeometry)->getExteriorRing(); PositionVector shape; for (int j = 0; j < cgeom->getNumPoints(); j++) { Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(id, type, color, shape, true, (SUMOReal)layer); if (!toFill.insert(id, poly, layer)) { WRITE_ERROR("Polygon '" + id + "' could not be added."); delete poly; } } break; case wkbMultiPoint: { OGRMultiPoint* cgeom = (OGRMultiPoint*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRPoint* cgeom2 = (OGRPoint*) cgeom->getGeometryRef(i); Position pos((SUMOReal) cgeom2->getX(), (SUMOReal) cgeom2->getY()); std::string tid = id + "#" + toString(i); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for POI '" + tid + "'."); } PointOfInterest* poi = new PointOfInterest(tid, type, color, pos, (SUMOReal)layer); if (!toFill.insert(tid, poi, layer)) { WRITE_ERROR("POI '" + tid + "' could not be added."); delete poi; } } } break; case wkbMultiLineString: { OGRMultiLineString* cgeom = (OGRMultiLineString*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRLineString* cgeom2 = (OGRLineString*) cgeom->getGeometryRef(i); PositionVector shape; std::string tid = id + "#" + toString(i); for (int j = 0; j < cgeom2->getNumPoints(); j++) { Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(tid, type, color, shape, false, (SUMOReal)layer); if (!toFill.insert(tid, poly, layer)) { WRITE_ERROR("Polygon '" + tid + "' could not be added."); delete poly; } } } break; case wkbMultiPolygon: { OGRMultiPolygon* cgeom = (OGRMultiPolygon*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRLinearRing* cgeom2 = ((OGRPolygon*) cgeom->getGeometryRef(i))->getExteriorRing(); PositionVector shape; std::string tid = id + "#" + toString(i); for (int j = 0; j < cgeom2->getNumPoints(); j++) { Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(tid, type, color, shape, true, (SUMOReal)layer); if (!toFill.insert(tid, poly, layer)) { WRITE_ERROR("Polygon '" + tid + "' could not be added."); delete poly; } } } break; default: WRITE_WARNING("Unsupported shape type occured (id='" + id + "')."); break; } OGRFeature::DestroyFeature(poFeature); } PROGRESS_DONE_MESSAGE(); #else WRITE_ERROR("SUMO was compiled without GDAL support."); #endif }
OGRFeature *OGROpenAirLayer::GetNextRawFeature() { const char* pszLine; CPLString osCLASS, osNAME, osFLOOR, osCEILING; OGRLinearRing oLR; double dfLastLat = 0, dfLastLon = 0; int bFirst = TRUE; int bClockWise = TRUE; double dfCenterLat = 0, dfCenterLon = 0; int bHasCenter = FALSE; OpenAirStyle sStyle; sStyle.penStyle = -1; sStyle.penWidth = -1; sStyle.penR = sStyle.penG = sStyle.penB = -1; sStyle.fillR = sStyle.fillG = sStyle.fillB = -1; if (bEOF) return NULL; while(TRUE) { if (bFirst && bHasLastLine) { pszLine = osLastLine.c_str(); bFirst = FALSE; } else { pszLine = CPLReadLine2L(fpOpenAir, 1024, NULL); if (pszLine == NULL) { bEOF = TRUE; if (oLR.getNumPoints() == 0) return NULL; if (osCLASS.size() != 0 && oStyleMap.find(osCLASS) != oStyleMap.end()) { memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle)); } break; } osLastLine = pszLine; bHasLastLine = TRUE; } if (pszLine[0] == '*' || pszLine[0] == '\0') continue; if (EQUALN(pszLine, "AC ", 3) || EQUALN(pszLine, "AC,", 3)) { if (osCLASS.size() != 0) { if (sStyle.penStyle != -1 || sStyle.fillR != -1) { if (oLR.getNumPoints() == 0) { OpenAirStyle* psStyle; if (oStyleMap.find(osCLASS) == oStyleMap.end()) { psStyle = (OpenAirStyle*)CPLMalloc( sizeof(OpenAirStyle)); oStyleMap[osCLASS] = psStyle; } else psStyle = oStyleMap[osCLASS]; memcpy(psStyle, &sStyle, sizeof(sStyle)); } else break; } else if (oStyleMap.find(osCLASS) != oStyleMap.end()) { memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle)); break; } else break; } sStyle.penStyle = -1; sStyle.penWidth = -1; sStyle.penR = sStyle.penG = sStyle.penB = -1; sStyle.fillR = sStyle.fillG = sStyle.fillB = -1; osCLASS = pszLine + 3; bClockWise = TRUE; bHasCenter = FALSE; } else if (EQUALN(pszLine, "AN ", 3)) { if (osNAME.size() != 0) break; osNAME = pszLine + 3; } else if (EQUALN(pszLine, "AH ", 3)) osCEILING = pszLine + 3; else if (EQUALN(pszLine, "AL ", 3)) osFLOOR = pszLine + 3; else if (EQUALN(pszLine, "AT ", 3)) { /* Ignored for that layer*/ } else if (EQUALN(pszLine, "SP ", 3)) { if (osCLASS.size() != 0) { char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0); if (CSLCount(papszTokens) == 5) { sStyle.penStyle = atoi(papszTokens[0]); sStyle.penWidth = atoi(papszTokens[1]); sStyle.penR = atoi(papszTokens[2]); sStyle.penG = atoi(papszTokens[3]); sStyle.penB = atoi(papszTokens[4]); } CSLDestroy(papszTokens); } } else if (EQUALN(pszLine, "SB ", 3)) { if (osCLASS.size() != 0) { char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0); if (CSLCount(papszTokens) == 3) { sStyle.fillR = atoi(papszTokens[0]); sStyle.fillG = atoi(papszTokens[1]); sStyle.fillB = atoi(papszTokens[2]); } CSLDestroy(papszTokens); } } else if (EQUALN(pszLine, "DP ", 3)) { pszLine += 3; double dfLat, dfLon; if (!OGROpenAirGetLatLon(pszLine, dfLat, dfLon)) continue; oLR.addPoint(dfLon, dfLat); dfLastLat = dfLat; dfLastLon = dfLon; } else if (EQUALN(pszLine, "DA ", 3)) { pszLine += 3; char* pszStar = strchr((char*)pszLine, '*'); if (pszStar) *pszStar = 0; char** papszTokens = CSLTokenizeString2(pszLine, ",", 0); if (bHasCenter && CSLCount(papszTokens) == 3) { double dfRadius = atof(papszTokens[0]) * 1852; double dfStartAngle = atof(papszTokens[1]); double dfEndAngle = atof(papszTokens[2]); if (bClockWise && dfEndAngle < dfStartAngle) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; double dfStartDistance = dfRadius; double dfEndDistance = dfRadius; int nSign = (bClockWise) ? 1 : -1; double dfAngle; double dfLat, dfLon; for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign) { double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfEndDistance, dfEndAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } CSLDestroy(papszTokens); } else if (EQUALN(pszLine, "DB ", 3)) { pszLine += 3; char* pszStar = strchr((char*)pszLine, '*'); if (pszStar) *pszStar = 0; char** papszTokens = CSLTokenizeString2(pszLine, ",", 0); double dfFirstLat, dfFirstLon; double dfSecondLat, dfSecondLon; if (bHasCenter && CSLCount(papszTokens) == 2 && OGROpenAirGetLatLon(papszTokens[0], dfFirstLat, dfFirstLon) && OGROpenAirGetLatLon(papszTokens[1], dfSecondLat, dfSecondLon)) { double dfStartDistance =OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfFirstLat, dfFirstLon); double dfEndDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfSecondLat, dfSecondLon); double dfStartAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfFirstLat, dfFirstLon); double dfEndAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfSecondLat, dfSecondLon); if (bClockWise && dfEndAngle < dfStartAngle) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; int nSign = (bClockWise) ? 1 : -1; double dfAngle; for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign) { double dfLat, dfLon; double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } oLR.addPoint(dfSecondLon, dfSecondLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } CSLDestroy(papszTokens); } else if ((EQUALN(pszLine, "DC ", 3) || EQUALN(pszLine, "DC=", 3)) && (bHasCenter || strstr(pszLine, "V X=") != NULL)) { if (!bHasCenter) { const char* pszVX = strstr(pszLine, "V X="); bHasCenter = OGROpenAirGetLatLon(pszVX, dfCenterLat, dfCenterLon); } if (bHasCenter) { pszLine += 3; double dfRADIUS = atof(pszLine) * 1852; double dfAngle; double dfLat, dfLon; for(dfAngle = 0; dfAngle < 360; dfAngle += 1) { OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } } else if (EQUALN(pszLine, "V X=", 4)) { bHasCenter = OGROpenAirGetLatLon(pszLine + 4, dfCenterLat, dfCenterLon); } else if (EQUALN(pszLine, "V D=-", 5)) { bClockWise = FALSE; } else if (EQUALN(pszLine, "V D=+", 5)) { bClockWise = TRUE; } else { //CPLDebug("OpenAir", "Unexpected content : %s", pszLine); } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, osCLASS.c_str()); poFeature->SetField(1, osNAME.c_str()); poFeature->SetField(2, osFLOOR.c_str()); poFeature->SetField(3, osCEILING.c_str()); if (sStyle.penStyle != -1 || sStyle.fillR != -1) { CPLString osStyle; if (sStyle.penStyle != -1) { osStyle += CPLString().Printf("PEN(c:#%02X%02X%02X,w:%dpt", sStyle.penR, sStyle.penG, sStyle.penB, sStyle.penWidth); if (sStyle.penStyle == 1) osStyle += ",p:\"5px 5px\""; osStyle += ")"; } if (sStyle.fillR != -1) { if (osStyle.size() != 0) osStyle += ";"; osStyle += CPLString().Printf("BRUSH(fc:#%02X%02X%02X)", sStyle.fillR, sStyle.fillG, sStyle.fillB); } else { if (osStyle.size() != 0) osStyle += ";"; osStyle += "BRUSH(fc:#00000000,id:\"ogr-brush-1\")"; } if (osStyle.size() != 0) poFeature->SetStyleString(osStyle); } OGRPolygon* poPoly = new OGRPolygon(); oLR.closeRings(); poPoly->addRing(&oLR); poPoly->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
OGRErr OGROCIWritableLayer::TranslateElementGroup( OGRGeometry *poGeometry ) { switch( wkbFlatten(poGeometry->getGeometryType()) ) { case wkbPoint: { OGRPoint *poPoint = (OGRPoint *) poGeometry; PushElemInfo( nOrdinalCount+1, 1, 1 ); PushOrdinal( poPoint->getX() ); PushOrdinal( poPoint->getY() ); if( nDimension == 3 ) PushOrdinal( poPoint->getZ() ); return OGRERR_NONE; } case wkbLineString: { OGRLineString *poLine = (OGRLineString *) poGeometry; int iVert; PushElemInfo( nOrdinalCount+1, 2, 1 ); for( iVert = 0; iVert < poLine->getNumPoints(); iVert++ ) { PushOrdinal( poLine->getX(iVert) ); PushOrdinal( poLine->getY(iVert) ); if( nDimension == 3 ) PushOrdinal( poLine->getZ(iVert) ); } return OGRERR_NONE; } case wkbPolygon: { OGRPolygon *poPoly = (OGRPolygon *) poGeometry; int iRing; for( iRing = -1; iRing < poPoly->getNumInteriorRings(); iRing++ ) { OGRLinearRing *poRing; int iVert; if( iRing == -1 ) poRing = poPoly->getExteriorRing(); else poRing = poPoly->getInteriorRing(iRing); if( iRing == -1 ) PushElemInfo( nOrdinalCount+1, 1003, 1 ); else PushElemInfo( nOrdinalCount+1, 2003, 1 ); if( (iRing == -1 && poRing->isClockwise()) || (iRing != -1 && !poRing->isClockwise()) ) { for( iVert = poRing->getNumPoints()-1; iVert >= 0; iVert-- ) { PushOrdinal( poRing->getX(iVert) ); PushOrdinal( poRing->getY(iVert) ); if( nDimension == 3 ) PushOrdinal( poRing->getZ(iVert) ); } } else { for( iVert = 0; iVert < poRing->getNumPoints(); iVert++ ) { PushOrdinal( poRing->getX(iVert) ); PushOrdinal( poRing->getY(iVert) ); if( nDimension == 3 ) PushOrdinal( poRing->getZ(iVert) ); } } } return OGRERR_NONE; } default: { return OGRERR_FAILURE; } } }
OGRErr OGRDXFWriterLayer::WriteHATCH( OGRFeature *poFeature, OGRGeometry *poGeom ) { /* -------------------------------------------------------------------- */ /* For now we handle multipolygons by writing a series of */ /* entities. */ /* -------------------------------------------------------------------- */ if( poGeom == NULL ) poGeom = poFeature->GetGeometryRef(); if ( poGeom->IsEmpty() ) { return OGRERR_NONE; } if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) { OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom; int iGeom; OGRErr eErr = OGRERR_NONE; for( iGeom = 0; eErr == OGRERR_NONE && iGeom < poGC->getNumGeometries(); iGeom++ ) { eErr = WriteHATCH( poFeature, poGC->getGeometryRef( iGeom ) ); } return eErr; } /* -------------------------------------------------------------------- */ /* Do we now have a geometry we can work with? */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) != wkbPolygon ) return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; /* -------------------------------------------------------------------- */ /* Write as a hatch. */ /* -------------------------------------------------------------------- */ WriteValue( 0, "HATCH" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbHatch" ); WriteValue( 10, 0 ); // elevation point X. 0 for DXF WriteValue( 20, 0 ); // elevation point Y WriteValue( 30, 0 ); // elevation point Z WriteValue(210, 0 ); // extrusion direction X WriteValue(220, 0 ); // extrusion direction Y WriteValue(230,1.0); // extrusion direction Z WriteValue( 2, "SOLID" ); // fill pattern WriteValue( 70, 1 ); // solid fill WriteValue( 71, 0 ); // associativity /* -------------------------------------------------------------------- */ /* Do we have styling information? */ /* -------------------------------------------------------------------- */ OGRStyleTool *poTool = NULL; OGRStyleMgr oSM; if( poFeature->GetStyleString() != NULL ) { oSM.InitFromFeature( poFeature ); if( oSM.GetPartCount() > 0 ) poTool = oSM.GetPart(0); } // Write style brush fore color if( poTool && poTool->GetType() == OGRSTCBrush ) { OGRStyleBrush *poBrush = (OGRStyleBrush *) poTool; GBool bDefault; if( poBrush->ForeColor(bDefault) != NULL && !bDefault ) WriteValue( 62, ColorStringToDXFColor( poBrush->ForeColor(bDefault) ) ); } delete poTool; /* -------------------------------------------------------------------- */ /* Handle a PEN tool to control drawing color and width. */ /* Perhaps one day also dottedness, etc. */ /* -------------------------------------------------------------------- */ #ifdef notdef if( poTool && poTool->GetType() == OGRSTCPen ) { OGRStylePen *poPen = (OGRStylePen *) poTool; GBool bDefault; if( poPen->Color(bDefault) != NULL && !bDefault ) WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) ); double dfWidthInMM = poPen->Width(bDefault); if( !bDefault ) WriteValue( 370, (int) floor(dfWidthInMM * 100 + 0.5) ); } /* -------------------------------------------------------------------- */ /* Do we have a Linetype for the feature? */ /* -------------------------------------------------------------------- */ CPLString osLineType = poFeature->GetFieldAsString( "Linetype" ); if( osLineType.size() > 0 && (poDS->oHeaderDS.LookupLineType( osLineType ) != NULL || oNewLineTypes.count(osLineType) > 0 ) ) { // Already define -> just reference it. WriteValue( 6, osLineType ); } else if( poTool != NULL && poTool->GetType() == OGRSTCPen ) { CPLString osDefinition = PrepareLineTypeDefinition( poFeature, poTool ); if( osDefinition != "" && osLineType == "" ) { // Is this definition already created and named? std::map<CPLString,CPLString>::iterator it; for( it = oNewLineTypes.begin(); it != oNewLineTypes.end(); it++ ) { if( (*it).second == osDefinition ) { osLineType = (*it).first; break; } } // create an automatic name for it. if( osLineType == "" ) { do { osLineType.Printf( "AutoLineType-%d", nNextAutoID++ ); } while( poDS->oHeaderDS.LookupLineType(osLineType) != NULL ); } } // If it isn't already defined, add it now. if( osDefinition != "" && oNewLineTypes.count(osLineType) == 0 ) { oNewLineTypes[osLineType] = osDefinition; WriteValue( 6, osLineType ); } } delete poTool; #endif /* -------------------------------------------------------------------- */ /* Process the loops (rings). */ /* -------------------------------------------------------------------- */ OGRPolygon *poPoly = (OGRPolygon *) poGeom; WriteValue( 91, poPoly->getNumInteriorRings() + 1 ); for( int iRing = -1; iRing < poPoly->getNumInteriorRings(); iRing++ ) { OGRLinearRing *poLR; if( iRing == -1 ) poLR = poPoly->getExteriorRing(); else poLR = poPoly->getInteriorRing( iRing ); WriteValue( 92, 2 ); // Polyline WriteValue( 72, 0 ); // has bulge WriteValue( 73, 1 ); // is closed WriteValue( 93, poLR->getNumPoints() ); for( int iVert = 0; iVert < poLR->getNumPoints(); iVert++ ) { WriteValue( 10, poLR->getX(iVert) ); WriteValue( 20, poLR->getY(iVert) ); } WriteValue( 97, 0 ); // 0 source boundary objects } WriteValue( 75, 0 ); // hatch style = Hatch "odd parity" area (Normal style) WriteValue( 76, 1 ); // hatch pattern type = predefined WriteValue( 98, 0 ); // 0 seed points return OGRERR_NONE; #ifdef notdef /* -------------------------------------------------------------------- */ /* Alternate unmaintained implementation as a polyline entity. */ /* -------------------------------------------------------------------- */ WriteValue( 0, "POLYLINE" ); WriteCore( poFeature ); WriteValue( 100, "AcDbEntity" ); WriteValue( 100, "AcDbPolyline" ); if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) ) WriteValue( 70, 1 ); else WriteValue( 70, 0 ); WriteValue( 66, "1" ); int iVert; for( iVert = 0; iVert < poLS->getNumPoints(); iVert++ ) { WriteValue( 0, "VERTEX" ); WriteValue( 8, "0" ); WriteValue( 10, poLS->getX(iVert) ); if( !WriteValue( 20, poLS->getY(iVert) ) ) return OGRERR_FAILURE; if( poLS->getGeometryType() == wkbLineString25D ) { if( !WriteValue( 30, poLS->getZ(iVert) ) ) return OGRERR_FAILURE; } } WriteValue( 0, "SEQEND" ); WriteValue( 8, "0" ); return OGRERR_NONE; #endif }
void DrawShape::paintMap(WPaintDevice *paintDevice) { WPainter painter(paintDevice); painter.setRenderHint(WPainter::LowQualityShadows); painter.save(); if(!sfile.empty()) { vector<LABELS> label_list; OGRDataSource *poDS,*PointDS; string dfile = sfile + ".shp"; string shp = "g_4326/" + sfile + ".shp"; poDS = OGRSFDriverRegistrar::Open(shp.c_str(), FALSE ); //comment till here if(poDS==NULL) { printf( "Open failed.\n" ); exit( 1 ); } OGRLayer *poLayer; poLayer = poDS->GetLayerByName( sfile.c_str() ); // comment here OGRFeature *poFeature; OGREnvelope * psExtent = new OGREnvelope(); poLayer->GetExtent(psExtent); double xMin = psExtent->MinX; double yMin = psExtent->MinY; double xMax = psExtent->MaxX; double yMax = psExtent->MaxY; stringstream strm; strm << xMin; string exp; double scaleFactor; string bound_string = strm.str(); int size = bound_string.size(); size_t found=bound_string.find("+"); if (found!=string::npos) { exp = bound_string.substr(found+1,size); } if(exp.empty()) { stringstream strExtent; strExtent << yMin; bound_string = strExtent.str(); size = bound_string.size(); found = bound_string.find("+"); if(found!=string::npos) { exp = bound_string.substr(found+1,size); } } if(exp.empty()) { stringstream strExtent; strExtent << xMax; bound_string = strExtent.str(); size = bound_string.size(); found = bound_string.find("+"); if(found!=string::npos) { exp = bound_string.substr(found+1,size); } } if(exp.empty()) { stringstream strExtent; strExtent << yMax; bound_string = strExtent.str(); size = bound_string.size(); found = bound_string.find("+"); if(found!=string::npos) { exp = bound_string.substr(found+1,size); } } //cout << "EXXP: " << exp << endl; if(!exp.empty()) { int exponent = boost::lexical_cast<int>(exp); exponent-=3; scaleFactor = pow (10,exponent); } else { //cout << "EXXP is empty " << exp << endl; scaleFactor = 1; } xMin/=scaleFactor; xMax/=scaleFactor; yMin/=scaleFactor; yMax/=scaleFactor; double gWidth = xMax - xMin; double gHeight = yMax - yMin; double widthFactor = 1; double pwidth = abs(gWidth-gHeight); double s = gWidth - gHeight; if(s<0.16) gWidth = gHeight + 0.16; double ratio=gWidth/gHeight; //for zoom n pan if(increase_width<100 && increase_height<100){ painter.setWindow(xMin +(-x_pos_shift+increase_width/2)/100*gWidth* widthFactor, yMax+(y_pos_shift-increase_height/2)/100*gHeight * widthFactor, gWidth* widthFactor*(100-increase_width)/100, gHeight * widthFactor*(-1+increase_height/100)); brush.setStyle(SolidPattern); brush.setColor(backcolor); painter.setBrush(brush); painter.drawRect(xMin +(-x_pos_shift+increase_width/2)/100*gWidth* widthFactor, yMax+(y_pos_shift-increase_height/2)/100*gHeight * widthFactor, gWidth* widthFactor*(100-increase_width)/100, gHeight * widthFactor*(-1+increase_height/100)); } else{ painter.setWindow(xMin +x_pos_shift, yMax-y_pos_shift, 0, 0); } // for normal picture //painter.setWindow(xMin , yMax, gWidth* widthFactor, -gHeight * widthFactor); pwidth/=480; pwidth*=4; //if(iwidth<0.06) // iwidth=0.06; if(iwidth == 0.0015){ pen.setWidth(pwidth); } else { pen.setWidth(iwidth); } //std::cerr<<pwidth<<" "<<iwidth<<"\n"; pen.setColor(bordercolor); brush.setStyle(SolidPattern); brush.setColor(fillcolor); font= new WFont(); font->setSize(WLength(labelpercentage*gWidth*widthFactor)); painter.setFont(*font); painter.setPen(pen); painter.setBrush(brush); WPainterPath path; poLayer->ResetReading(); OGRPoint *centroid = new OGRPoint(); char label[100]; while( (poFeature = poLayer->GetNextFeature()) != NULL ) { centroid->empty(); label[0]=0; if(labelindex>0) { OGRFeatureDefn *PointFDefn = poLayer->GetLayerDefn(); OGRFieldDefn *PointFieldDefn = PointFDefn->GetFieldDefn(labelindex-1); if( PointFieldDefn->GetType() == OFTInteger ) sprintf(label, "%d", poFeature->GetFieldAsInteger(labelindex-1) ); else if( PointFieldDefn->GetType() == OFTReal ) sprintf(label, "%.3f", poFeature->GetFieldAsDouble(labelindex-1) ); else if( PointFieldDefn->GetType() == OFTString ) sprintf(label, "%s", poFeature->GetFieldAsString(labelindex-1) ); else sprintf(label, "%s", poFeature->GetFieldAsString(labelindex-1) ); } OGRGeometry *poGeometry; poGeometry = poFeature->GetGeometryRef(); if( poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbPoint ) { OGRPoint *poPoint = (OGRPoint *) poGeometry; double x = poPoint->getX(); double y = poPoint->getY(); //painter.drawPoint(x/scaleFactor,y/scaleFactor); painter.drawEllipse(x/scaleFactor-0.005*gWidth*widthFactor,y/scaleFactor-0.005*gWidth*widthFactor,0.01*gWidth*widthFactor,0.01*gWidth*widthFactor); poGeometry->Centroid(centroid); } //end wkbpoint else if( poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbLineString ) { OGRLineString *poPoint = (OGRLineString *) poGeometry; for(int i=0;i<poPoint->getNumPoints();i++) { double x=poPoint->getX(i) ; double y = poPoint->getY(i); x/=scaleFactor; y/=scaleFactor; if(i==0) path = WPainterPath( WPointF(x, y)); else path.lineTo( x , y); } painter.drawPath(path); poGeometry->Centroid(centroid); } else if( (poGeometry != NULL) && wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon) { OGRPolygon *poPoint = (OGRPolygon *) poGeometry; OGRLinearRing *extring = poPoint->getExteriorRing(); int n = extring->getNumPoints(); double x, y; for(int i=0;i<n;i++) { x = extring->getX(i); y = extring->getY(i); x/=scaleFactor; y/=scaleFactor; if(i==0) path = WPainterPath( WPointF(x , y)); else path.lineTo( x , y); } painter.drawPath(path); poGeometry->Centroid(centroid); } else if( (poGeometry != NULL) && wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon) { double x, y; OGRMultiPolygon *poPoint = (OGRMultiPolygon *) poGeometry; int p = poPoint->getNumGeometries(); for(int k=0;k<p;k++) { OGRGeometry* geom = poPoint->getGeometryRef(k); OGRPolygon *poly = (OGRPolygon *) geom; OGRLinearRing *ring = poly->getExteriorRing(); for(int i=0;i<ring->getNumPoints();i++) { x = ring->getX(i); y = ring->getY(i); x/=scaleFactor; y/=scaleFactor; if(i==0) path = WPainterPath( WPointF(x , y)); else path.lineTo( x , y); } painter.drawPath(path); poGeometry->Centroid(centroid); } } if(labelindex>0 && !centroid->IsEmpty()){ LABELS l={centroid->getX(),centroid->getY(),label}; label_list.push_back(l); } } painter.restore(); //labelling the contents if(increase_width<100 && increase_height<100){ painter.setWindow(0.0, 0.0, (paintDevice->width()).value(),(paintDevice->height()).value()); font= new WFont(WFont::SansSerif); font->setSize(WLength(10*labelpercentage)); painter.setFont(*font); pen.setColor(labelcolor); painter.setPen(pen); std::vector<LABELS>::iterator the_iterator = label_list.begin(); double x, y, minx=(xMin+(-x_pos_shift+increase_width/2)/100*gWidth* widthFactor),miny=(yMax+(y_pos_shift-increase_height/2)/100*gHeight*widthFactor); double multx=(paintDevice->width().value())/(gWidth* widthFactor*(100-increase_width)/100); double multy=(paintDevice->height().value())/(gHeight*widthFactor*(-1+increase_height/100)); while( the_iterator != label_list.end() ) { x=((*the_iterator).x/scaleFactor-minx)*multx; y=((*the_iterator).y/scaleFactor-miny)*multy; painter.drawText(WRectF( x-(*the_iterator).label.size()*5*labelpercentage, y-5*labelpercentage, (*the_iterator).label.size() *10*labelpercentage,10*labelpercentage),AlignCenter,(*the_iterator).label); ++the_iterator; } pen.setColor(red); painter.setPen(pen); painter.setFont(*font); //painter.drawText(WRectF(paintDevice->width().value()-dfile.size()*10*labelpercentage,paintDevice->height().value()-10*labelpercentage*(paintDevice->height()).value(), dfile.size()*10*labelpercentage,10*labelpercentage ),AlignCenter,dfile); //this text is not seen in the picture when painted. } } }
OGRMultiPolygon* Building::extrude_box() const { OGRMultiPolygon* block = new OGRMultiPolygon; //extrude roof OGRPolygon roof; { roof.addRing(_footprint->getExteriorRing()); OGRLinearRing* ring = roof.getExteriorRing(); for(int i=0; i<ring->getNumPoints(); i++) ring->setPoint(i,ring->getX(i),ring->getY(i),_height); } if(int n = _footprint->getNumInteriorRings()) { for (int j=0; j<n; j++) { roof.addRing(_footprint->getInteriorRing(j)); OGRLinearRing* ring = roof.getInteriorRing(j); for(int i=0; i<ring->getNumPoints(); i++) ring->setPoint(i,ring->getX(i),ring->getY(i),_height); } } block->addGeometry(&roof); //extrude exter walls OGRLinearRing* ringEx = _footprint->getExteriorRing(); for(int i=0; i<ringEx->getNumPoints()-1; i++) { OGRPolygon wall; OGRLinearRing ring; ring.addPoint(ringEx->getX(i),ringEx->getY(i),0); ring.addPoint(ringEx->getX(i+1),ringEx->getY(i+1),0); ring.addPoint(ringEx->getX(i+1),ringEx->getY(i+1),_height); ring.addPoint(ringEx->getX(i),ringEx->getY(i),_height); ring.addPoint(ringEx->getX(i),ringEx->getY(i),0); wall.addRing(&ring); block->addGeometry(&wall); } //extrude inner walls if exist if(int n = _footprint->getNumInteriorRings()) { for (int i=0; i<n; i++) { OGRLinearRing* ringIn = _footprint->getInteriorRing(i); for(int j=0; j<ringIn->getNumPoints()-1; j++) { OGRPolygon wall; OGRLinearRing ring; ring.addPoint(ringIn->getX(j),ringIn->getY(j),0); ring.addPoint(ringIn->getX(j+1),ringIn->getY(j+1),0); ring.addPoint(ringIn->getX(j+1),ringIn->getY(j+1),_height); ring.addPoint(ringIn->getX(j),ringIn->getY(j),_height); ring.addPoint(ringIn->getX(j),ringIn->getY(j),0); wall.addRing(&ring); block->addGeometry(&wall); } } } return block; }
OGRErr OGRIngresTableLayer::PrepareOldStyleGeometry( OGRGeometry *poGeom, CPLString &osRetGeomText ) { osRetGeomText = ""; if( poGeom == NULL ) return OGRERR_FAILURE; /* -------------------------------------------------------------------- */ /* Point */ /* -------------------------------------------------------------------- */ if( EQUAL(osIngresGeomType,"POINT") && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) { OGRPoint *poPoint = (OGRPoint *) poGeom; osRetGeomText.Printf( "(%.15g,%.15g)", poPoint->getX(), poPoint->getY() ); return OGRERR_NONE; } if( EQUAL(osIngresGeomType,"IPOINT") && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) { OGRPoint *poPoint = (OGRPoint *) poGeom; osRetGeomText.Printf( "(%d,%d)", (int) floor(poPoint->getX()), (int) floor(poPoint->getY()) ); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Line */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) { OGRLineString *poLS = (OGRLineString *) poGeom; CPLString osLastPoint; int i; if( (EQUAL(osIngresGeomType,"LSEG") || EQUAL(osIngresGeomType,"ILSEG")) && poLS->getNumPoints() != 2 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to place %d vertex linestring in %s field.", poLS->getNumPoints(), osIngresGeomType.c_str() ); return OGRERR_FAILURE; } else if( EQUAL(osIngresGeomType,"LINESTRING") && poLS->getNumPoints() > 124 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to place %d vertex linestring in %s field.", poLS->getNumPoints(), osIngresGeomType.c_str() ); return OGRERR_FAILURE; } else if( EQUAL(osIngresGeomType,"ILINESTRING") && poLS->getNumPoints() > 248 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to place %d vertex linestring in %s field.", poLS->getNumPoints(), osIngresGeomType.c_str() ); return OGRERR_FAILURE; } osRetGeomText = "("; for( i = 0; i < poLS->getNumPoints(); i++ ) { CPLString osPoint; if( i > 0 && poLS->getX(i) == poLS->getX(i-1) && poLS->getY(i) == poLS->getY(i-1) ) { CPLDebug( "INGRES", "Dropping duplicate point in linestring."); continue; } if( EQUALN(osIngresGeomType,"I",1) ) osPoint.Printf( "(%d,%d)", (int) floor(poLS->getX(i)), (int) floor(poLS->getY(i)) ); else osPoint.Printf( "(%.15g,%.15g)", poLS->getX(i), poLS->getY(i) ); if( osPoint == osLastPoint ) { CPLDebug( "INGRES", "Dropping duplicate point in linestring(2)."); continue; } osLastPoint = osPoint; if( osRetGeomText.size() > 1 ) osRetGeomText += "," + osPoint; else osRetGeomText += osPoint; } osRetGeomText += ")"; return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon ) { OGRPolygon *poPoly = (OGRPolygon *) poGeom; OGRLinearRing *poLS = poPoly->getExteriorRing(); int i, nPoints; if( poLS == NULL ) return OGRERR_FAILURE; if( poPoly->getNumInteriorRings() > 0 ) { CPLError( CE_Warning, CPLE_AppDefined, "%d inner rings discarded from polygon being converted\n" "to old ingres spatial data type '%s'.", poPoly->getNumInteriorRings(), osIngresGeomType.c_str() ); } if( EQUAL(osIngresGeomType,"POLYGON") && poLS->getNumPoints() > 124 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to place %d vertex linestring in %s field.", poLS->getNumPoints(), osIngresGeomType.c_str() ); return OGRERR_FAILURE; } else if( EQUAL(osIngresGeomType,"IPOLYGON") && poLS->getNumPoints() > 248 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to place %d vertex linestring in %s field.", poLS->getNumPoints(), osIngresGeomType.c_str() ); return OGRERR_FAILURE; } // INGRES geometries use *implied* closure of rings. nPoints = poLS->getNumPoints(); if( poLS->getX(0) == poLS->getX(nPoints-1) && poLS->getY(0) == poLS->getY(nPoints-1) && nPoints > 1 ) nPoints--; osRetGeomText = "("; for( i = 0; i < nPoints; i++ ) { CPLString osPoint; if( i > 0 && poLS->getX(i) == poLS->getX(i-1) && poLS->getY(i) == poLS->getY(i-1) ) { CPLDebug( "INGRES", "Dropping duplicate point in linestring."); continue; } if( EQUALN(osIngresGeomType,"I",1) ) osPoint.Printf( "(%d,%d)", (int) floor(poLS->getX(i)), (int) floor(poLS->getY(i)) ); else osPoint.Printf( "(%.15g,%.15g)", poLS->getX(i), poLS->getY(i) ); if( osRetGeomText.size() > 1 ) osRetGeomText += "," + osPoint; else osRetGeomText += osPoint; } osRetGeomText += ")"; return OGRERR_NONE; } return OGRERR_FAILURE; }
int OGRLayer::InstallFilter( OGRGeometry * poFilter ) { if( m_poFilterGeom == NULL && poFilter == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Replace the existing filter. */ /* -------------------------------------------------------------------- */ if( m_poFilterGeom != NULL ) { delete m_poFilterGeom; m_poFilterGeom = NULL; } if( poFilter != NULL ) m_poFilterGeom = poFilter->clone(); m_bFilterIsEnvelope = FALSE; if( m_poFilterGeom == NULL ) return TRUE; if( m_poFilterGeom != NULL ) m_poFilterGeom->getEnvelope( &m_sFilterEnvelope ); /* -------------------------------------------------------------------- */ /* Now try to determine if the filter is really a rectangle. */ /* -------------------------------------------------------------------- */ if( wkbFlatten(m_poFilterGeom->getGeometryType()) != wkbPolygon ) return TRUE; OGRPolygon *poPoly = (OGRPolygon *) m_poFilterGeom; if( poPoly->getNumInteriorRings() != 0 ) return TRUE; OGRLinearRing *poRing = poPoly->getExteriorRing(); if (poRing == NULL) return TRUE; if( poRing->getNumPoints() > 5 || poRing->getNumPoints() < 4 ) return TRUE; // If the ring has 5 points, the last should be the first. if( poRing->getNumPoints() == 5 && ( poRing->getX(0) != poRing->getX(4) || poRing->getY(0) != poRing->getY(4) ) ) return TRUE; // Polygon with first segment in "y" direction. if( poRing->getX(0) == poRing->getX(1) && poRing->getY(1) == poRing->getY(2) && poRing->getX(2) == poRing->getX(3) && poRing->getY(3) == poRing->getY(0) ) m_bFilterIsEnvelope = TRUE; // Polygon with first segment in "x" direction. if( poRing->getY(0) == poRing->getY(1) && poRing->getX(1) == poRing->getX(2) && poRing->getY(2) == poRing->getY(3) && poRing->getX(3) == poRing->getX(0) ) m_bFilterIsEnvelope = TRUE; return TRUE; }
bool MapWidget::loadCountyShapes() { OGRRegisterAll(); std::string filename = g_dataDirectory + "/counties/tl_2009_48_county00.shp"; OGRDataSource * dataSource = OGRSFDriverRegistrar::Open(filename.c_str(), false); if(dataSource == NULL) { put_flog(LOG_ERROR, "could not open %s", filename.c_str()); return false; } OGRLayer * layer = dataSource->GetLayerByName("tl_2009_48_county00"); layer->ResetReading(); OGRFeature * feature; while((feature = layer->GetNextFeature()) != NULL) { // get county FIPS code int nodeId = feature->GetFieldAsInteger("COUNTYFP00"); if(nodeId == 0) { put_flog(LOG_WARN, "invalid county"); } // add a new county to the counties map corresponding to this nodeId boost::shared_ptr<MapShape> county(new MapShape()); counties_[nodeId] = county; OGRGeometry * geometry = feature->GetGeometryRef(); if(geometry != NULL && geometry->getGeometryType() == wkbPolygon) { OGRPolygon * polygon = (OGRPolygon *)geometry; OGRLinearRing * ring = polygon->getExteriorRing(); for(int i=0; i<ring->getNumPoints(); i++) { // x is longitude, y latitude county->addVertex(ring->getY(i), ring->getX(i)); } // set the centroid OGRPoint centroidPoint; if(polygon->Centroid(¢roidPoint) == OGRERR_NONE) { county->setCentroid(centroidPoint.getY(), centroidPoint.getX()); } else { put_flog(LOG_WARN, "no polygon centroid"); } } else { put_flog(LOG_WARN, "no polygon geometry"); } OGRFeature::DestroyFeature(feature); } OGRDataSource::DestroyDataSource(dataSource); return true; }
int NBHeightMapper::loadShapeFile(const std::string& file) { #ifdef HAVE_GDAL #if GDAL_VERSION_MAJOR < 2 OGRRegisterAll(); OGRDataSource* ds = OGRSFDriverRegistrar::Open(file.c_str(), FALSE); #else GDALAllRegister(); GDALDataset* ds = (GDALDataset*)GDALOpenEx(file.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL); #endif if (ds == NULL) { throw ProcessError("Could not open shape file '" + file + "'."); } // begin file parsing OGRLayer* layer = ds->GetLayer(0); layer->ResetReading(); // triangle coordinates are stored in WGS84 and later matched with network coordinates in WGS84 // build coordinate transformation OGRSpatialReference* sr_src = layer->GetSpatialRef(); OGRSpatialReference sr_dest; sr_dest.SetWellKnownGeogCS("WGS84"); OGRCoordinateTransformation* toWGS84 = OGRCreateCoordinateTransformation(sr_src, &sr_dest); if (toWGS84 == 0) { WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed."); } int numFeatures = 0; OGRFeature* feature; layer->ResetReading(); while ((feature = layer->GetNextFeature()) != NULL) { OGRGeometry* geom = feature->GetGeometryRef(); assert(geom != 0); // @todo gracefull handling of shapefiles with unexpected contents or any error handling for that matter assert(std::string(geom->getGeometryName()) == std::string("POLYGON")); // try transform to wgs84 geom->transform(toWGS84); OGRLinearRing* cgeom = ((OGRPolygon*) geom)->getExteriorRing(); // assume TIN with with 4 points and point0 == point3 assert(cgeom->getNumPoints() == 4); PositionVector corners; for (int j = 0; j < 3; j++) { Position pos((double) cgeom->getX(j), (double) cgeom->getY(j), (double) cgeom->getZ(j)); corners.push_back(pos); myBoundary.add(pos); } addTriangle(corners); numFeatures++; /* OGRwkbGeometryType gtype = geom->getGeometryType(); switch (gtype) { case wkbPolygon: { break; } case wkbPoint: { WRITE_WARNING("got wkbPoint"); break; } case wkbLineString: { WRITE_WARNING("got wkbLineString"); break; } case wkbMultiPoint: { WRITE_WARNING("got wkbMultiPoint"); break; } case wkbMultiLineString: { WRITE_WARNING("got wkbMultiLineString"); break; } case wkbMultiPolygon: { WRITE_WARNING("got wkbMultiPolygon"); break; } default: WRITE_WARNING("Unsupported shape type occurred"); break; } */ OGRFeature::DestroyFeature(feature); } #if GDAL_VERSION_MAJOR < 2 OGRDataSource::DestroyDataSource(ds); #else GDALClose(ds); #endif OCTDestroyCoordinateTransformation(toWGS84); OGRCleanupAll(); return numFeatures; #else UNUSED_PARAMETER(file); WRITE_ERROR("Cannot load shape file since SUMO was compiled without GDAL support."); return 0; #endif }
OGRGeometry *OGRIngresLayer::TranslateGeometry( const char *pszGeom ) { OGRGeometry *poGeom = NULL; /* -------------------------------------------------------------------- */ /* Parse the tuple list into an array of x/y vertices. The */ /* input may look like "(2,3)" or "((2,3),(4,5),...)". Extra */ /* spaces may occur between tokens. */ /* -------------------------------------------------------------------- */ double *padfXY = NULL; int nVertMax = 0; int nVertCount = 0; int nDepth = 0; const char *pszNext = pszGeom; while( *pszNext != '\0' ) { while( *pszNext == ' ' ) pszNext++; if( *pszNext == '(' ) { pszNext++; nDepth++; continue; } if( *pszNext == ')' ) { pszNext++; CPLAssert( nDepth == 1 ); nDepth--; break; } if( *pszNext == ',' ) { pszNext++; CPLAssert( nDepth == 1 ); continue; } if( nVertCount == nVertMax ) { nVertMax = nVertMax * 2 + 1; padfXY = (double *) CPLRealloc(padfXY, sizeof(double) * nVertMax * 2 ); } if( !ParseXY( &pszNext, padfXY + nVertCount*2 ) ) { CPLDebug( "INGRES", "Error parsing geometry: %s", pszGeom ); CPLFree( padfXY ); return NULL; } CPLAssert( *pszNext == ')' ); nVertCount++; pszNext++; nDepth--; while( *pszNext == ' ' ) pszNext++; } CPLAssert( nDepth == 0 ); /* -------------------------------------------------------------------- */ /* Handle Box/IBox. */ /* -------------------------------------------------------------------- */ if( EQUAL(osIngresGeomType,"BOX") || EQUAL(osIngresGeomType,"IBOX") ) { CPLAssert( nVertCount == 2 ); OGRLinearRing *poRing = new OGRLinearRing(); poRing->addPoint( padfXY[0], padfXY[1] ); poRing->addPoint( padfXY[2], padfXY[1] ); poRing->addPoint( padfXY[2], padfXY[3] ); poRing->addPoint( padfXY[0], padfXY[3] ); poRing->addPoint( padfXY[0], padfXY[1] ); OGRPolygon *poPolygon = new OGRPolygon(); poPolygon->addRingDirectly( poRing ); poGeom = poPolygon; } /* -------------------------------------------------------------------- */ /* Handle Point/IPoint */ /* -------------------------------------------------------------------- */ else if( EQUAL(osIngresGeomType,"POINT") || EQUAL(osIngresGeomType,"IPOINT") ) { CPLAssert( nVertCount == 1 ); poGeom = new OGRPoint( padfXY[0], padfXY[1] ); } /* -------------------------------------------------------------------- */ /* Handle various linestring types. */ /* -------------------------------------------------------------------- */ else if( EQUAL(osIngresGeomType,"LSEG") || EQUAL(osIngresGeomType,"ILSEG") || EQUAL(osIngresGeomType,"LINE") || EQUAL(osIngresGeomType,"LONG LINE") || EQUAL(osIngresGeomType,"ILINE") ) { OGRLineString *poLine = new OGRLineString(); int iVert; poLine->setNumPoints( nVertCount ); for( iVert = 0; iVert < nVertCount; iVert++ ) poLine->setPoint( iVert, padfXY[iVert*2+0], padfXY[iVert*2+1] ); poGeom = poLine; } /* -------------------------------------------------------------------- */ /* Handle Polygon/IPolygon/LongPolygon. */ /* -------------------------------------------------------------------- */ else if( EQUAL(osIngresGeomType,"POLYGON") || EQUAL(osIngresGeomType,"IPOLYGON") || EQUAL(osIngresGeomType,"LONG POLYGON") ) { OGRLinearRing *poLine = new OGRLinearRing(); int iVert; poLine->setNumPoints( nVertCount ); for( iVert = 0; iVert < nVertCount; iVert++ ) poLine->setPoint( iVert, padfXY[iVert*2+0], padfXY[iVert*2+1] ); // INGRES polygons are implicitly closed, but OGR expects explicit if( poLine->getX(nVertCount-1) != poLine->getX(0) || poLine->getY(nVertCount-1) != poLine->getY(0) ) poLine->addPoint( poLine->getX(0), poLine->getY(0) ); OGRPolygon *poPolygon = new OGRPolygon(); poPolygon->addRingDirectly( poLine ); poGeom = poPolygon; } return poGeom; }
OGRGeometryH OGRBuildPolygonFromEdges( OGRGeometryH hLines, int bBestEffort, int bAutoClose, double dfTolerance, OGRErr * peErr ) { int bSuccess = TRUE; OGRGeometryCollection *poLines = (OGRGeometryCollection *) hLines; OGRPolygon *poPolygon = new OGRPolygon(); (void) bBestEffort; /* -------------------------------------------------------------------- */ /* Setup array of line markers indicating if they have been */ /* added to a ring yet. */ /* -------------------------------------------------------------------- */ int nEdges = poLines->getNumGeometries(); int *panEdgeConsumed, nRemainingEdges = nEdges; panEdgeConsumed = (int *) CPLCalloc(sizeof(int),nEdges); /* ==================================================================== */ /* Loop generating rings. */ /* ==================================================================== */ while( nRemainingEdges > 0 ) { int iEdge; OGRLineString *poLine; /* -------------------------------------------------------------------- */ /* Find the first unconsumed edge. */ /* -------------------------------------------------------------------- */ for( iEdge = 0; panEdgeConsumed[iEdge]; iEdge++ ) {} poLine = (OGRLineString *) poLines->getGeometryRef(iEdge); /* -------------------------------------------------------------------- */ /* Start a new ring, copying in the current line directly */ /* -------------------------------------------------------------------- */ OGRLinearRing *poRing = new OGRLinearRing(); AddEdgeToRing( poRing, poLine, FALSE ); panEdgeConsumed[iEdge] = TRUE; nRemainingEdges--; /* ==================================================================== */ /* Loop adding edges to this ring until we make a whole pass */ /* within finding anything to add. */ /* ==================================================================== */ int bWorkDone = TRUE; double dfBestDist = dfTolerance; while( !CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1,NULL) && nRemainingEdges > 0 && bWorkDone ) { int iBestEdge = -1, bReverse = FALSE; bWorkDone = FALSE; dfBestDist = dfTolerance; // We consider linking the end to the beginning. If this is // closer than any other option we will just close the loop. //CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1,&dfBestDist); // Find unused edge with end point closest to our loose end. for( iEdge = 0; iEdge < nEdges; iEdge++ ) { if( panEdgeConsumed[iEdge] ) continue; poLine = (OGRLineString *) poLines->getGeometryRef(iEdge); if( CheckPoints(poLine,0,poRing,poRing->getNumPoints()-1, &dfBestDist) ) { iBestEdge = iEdge; bReverse = FALSE; } if( CheckPoints(poLine,poLine->getNumPoints()-1, poRing,poRing->getNumPoints()-1, &dfBestDist) ) { iBestEdge = iEdge; bReverse = TRUE; } } // We found one within tolerance - add it. if( iBestEdge != -1 ) { poLine = (OGRLineString *) poLines->getGeometryRef(iBestEdge); AddEdgeToRing( poRing, poLine, bReverse ); panEdgeConsumed[iBestEdge] = TRUE; nRemainingEdges--; bWorkDone = TRUE; } } /* -------------------------------------------------------------------- */ /* Did we fail to complete the ring? */ /* -------------------------------------------------------------------- */ dfBestDist = dfTolerance; if( !CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1, &dfBestDist) ) { CPLDebug( "OGR", "Failed to close ring %d.\n" "End Points are: (%.8f,%.7f) and (%.7f,%.7f)\n", poPolygon->getNumInteriorRings()+1, poRing->getX(0), poRing->getY(0), poRing->getX(poRing->getNumPoints()-1), poRing->getY(poRing->getNumPoints()-1) ); bSuccess = FALSE; } /* -------------------------------------------------------------------- */ /* Do we need to auto-close this ring? */ /* -------------------------------------------------------------------- */ if( bAutoClose && !CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1,NULL) ) { poRing->addPoint( poRing->getX(0), poRing->getY(0), poRing->getZ(0)); } poPolygon->addRingDirectly( poRing ); } /* next ring */ /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ CPLFree( panEdgeConsumed ); // Eventually we should at least identify the external ring properly, // perhaps even ordering the direction of rings, though this isn't // required by the OGC geometry model. if( peErr != NULL ) { if( bSuccess ) *peErr = OGRERR_NONE; else *peErr = OGRERR_FAILURE; } return (OGRGeometryH) poPolygon; }
OGRErr OGRBNALayer::CreateFeature( OGRFeature *poFeature ) { int i,j,k,n; OGRGeometry *poGeom = poFeature->GetGeometryRef(); char eol[3]; const char* partialEol = (poDS->GetMultiLine()) ? eol : poDS->GetCoordinateSeparator(); if (poGeom == NULL || poGeom->IsEmpty() ) { CPLError(CE_Failure, CPLE_AppDefined, "OGR BNA driver cannot write features with empty geometries."); return OGRERR_FAILURE; } if (poDS->GetUseCRLF()) { eol[0] = 13; eol[1] = 10; eol[2] = 0; } else { eol[0] = 10; eol[1] = 0; } if ( ! bWriter ) { return OGRERR_FAILURE; } if( poFeature->GetFID() == OGRNullFID ) poFeature->SetFID( nFeatures++ ); VSILFILE* fp = poDS->GetOutputFP(); int nbPairPerLine = poDS->GetNbPairPerLine(); switch( poGeom->getGeometryType() ) { case wkbPoint: case wkbPoint25D: { OGRPoint* point = (OGRPoint*)poGeom; WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "1"); VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, point->getX(), point->getY()); VSIFPrintfL( fp, "%s", eol); break; } case wkbPolygon: case wkbPolygon25D: { OGRPolygon* polygon = (OGRPolygon*)poGeom; OGRLinearRing* ring = polygon->getExteriorRing(); if (ring == NULL) { return OGRERR_FAILURE; } double firstX = ring->getX(0); double firstY = ring->getY(0); int nBNAPoints = ring->getNumPoints(); int is_ellipse = FALSE; /* This code tries to detect an ellipse in a polygon geometry */ /* This will only work presumably on ellipses already read from a BNA file */ /* Mostly a BNA to BNA feature... */ if (poDS->GetEllipsesAsEllipses() && polygon->getNumInteriorRings() == 0 && nBNAPoints == 361) { double oppositeX = ring->getX(180); double oppositeY = ring->getY(180); double quarterX = ring->getX(90); double quarterY = ring->getY(90); double antiquarterX = ring->getX(270); double antiquarterY = ring->getY(270); double center1X = 0.5*(firstX + oppositeX); double center1Y = 0.5*(firstY + oppositeY); double center2X = 0.5*(quarterX + antiquarterX); double center2Y = 0.5*(quarterY + antiquarterY); if (fabs(center1X - center2X) < 1e-5 && fabs(center1Y - center2Y) < 1e-5 && fabs(oppositeY - firstY) < 1e-5 && fabs(quarterX - antiquarterX) < 1e-5) { double major_radius = fabs(firstX - center1X); double minor_radius = fabs(quarterY - center1Y); is_ellipse = TRUE; for(i=0;i<360;i++) { if (!(fabs(center1X + major_radius * cos(i * (M_PI / 180)) - ring->getX(i)) < 1e-5 && fabs(center1Y + minor_radius * sin(i * (M_PI / 180)) - ring->getY(i)) < 1e-5)) { is_ellipse = FALSE; break; } } if ( is_ellipse == TRUE ) { WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "2"); VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, center1X, center1Y); VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, major_radius, minor_radius); VSIFPrintfL( fp, "%s", eol); } } } if ( is_ellipse == FALSE) { int nInteriorRings = polygon->getNumInteriorRings(); for(i=0;i<nInteriorRings;i++) { nBNAPoints += polygon->getInteriorRing(i)->getNumPoints() + 1; } if (nBNAPoints <= 3) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); return OGRERR_FAILURE; } WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "%d", nBNAPoints); n = ring->getNumPoints(); int nbPair = 0; for(i=0;i<n;i++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(i), ring->getY(i)); nbPair++; } for(i=0;i<nInteriorRings;i++) { ring = polygon->getInteriorRing(i); n = ring->getNumPoints(); for(j=0;j<n;j++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(j), ring->getY(j)); nbPair++; } VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, firstX, firstY); nbPair++; } VSIFPrintfL( fp, "%s", eol); } break; } case wkbMultiPolygon: case wkbMultiPolygon25D: { OGRMultiPolygon* multipolygon = (OGRMultiPolygon*)poGeom; int N = multipolygon->getNumGeometries(); int nBNAPoints = 0; double firstX = 0, firstY = 0; for(i=0;i<N;i++) { OGRPolygon* polygon = (OGRPolygon*)multipolygon->getGeometryRef(i); OGRLinearRing* ring = polygon->getExteriorRing(); if (ring == NULL) continue; if (nBNAPoints) nBNAPoints ++; else { firstX = ring->getX(0); firstY = ring->getY(0); } nBNAPoints += ring->getNumPoints(); int nInteriorRings = polygon->getNumInteriorRings(); for(j=0;j<nInteriorRings;j++) { nBNAPoints += polygon->getInteriorRing(j)->getNumPoints() + 1; } } if (nBNAPoints <= 3) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); return OGRERR_FAILURE; } WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "%d", nBNAPoints); int nbPair = 0; for(i=0;i<N;i++) { OGRPolygon* polygon = (OGRPolygon*)multipolygon->getGeometryRef(i); OGRLinearRing* ring = polygon->getExteriorRing(); if (ring == NULL) continue; n = ring->getNumPoints(); int nInteriorRings = polygon->getNumInteriorRings(); for(j=0;j<n;j++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(j), ring->getY(j)); nbPair++; } if (i != 0) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, firstX, firstY); nbPair++; } for(j=0;j<nInteriorRings;j++) { ring = polygon->getInteriorRing(j); n = ring->getNumPoints(); for(k=0;k<n;k++) { VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, ring->getX(k), ring->getY(k)); nbPair++; } VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " "); WriteCoord(fp, firstX, firstY); nbPair++; } } VSIFPrintfL( fp, "%s", eol); break; } case wkbLineString: case wkbLineString25D: { OGRLineString* line = (OGRLineString*)poGeom; int n = line->getNumPoints(); int i; if (n < 2) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" ); return OGRERR_FAILURE; } WriteFeatureAttributes(fp, poFeature); VSIFPrintfL( fp, "-%d", n); int nbPair = 0; for(i=0;i<n;i++) { VSIFPrintfL( fp, "%s", partialEol); WriteCoord(fp, line->getX(i), line->getY(i)); nbPair++; } VSIFPrintfL( fp, "%s", eol); break; } default: { CPLError( CE_Failure, CPLE_AppDefined, "Unsupported geometry type : %s.", poGeom->getGeometryName() ); return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } } return OGRERR_NONE; }
static void GDALCollectRingsFromGeometry( OGRGeometry *poShape, std::vector<double> &aPointX, std::vector<double> &aPointY, std::vector<double> &aPointVariant, std::vector<int> &aPartSize, GDALBurnValueSrc eBurnValueSrc) { if( poShape == NULL ) return; OGRwkbGeometryType eFlatType = wkbFlatten(poShape->getGeometryType()); int i; if ( eFlatType == wkbPoint ) { OGRPoint *poPoint = (OGRPoint *) poShape; int nNewCount = aPointX.size() + 1; aPointX.reserve( nNewCount ); aPointY.reserve( nNewCount ); aPointX.push_back( poPoint->getX() ); aPointY.push_back( poPoint->getY() ); aPartSize.push_back( 1 ); if( eBurnValueSrc != GBV_UserBurnValue ) { /*switch( eBurnValueSrc ) { case GBV_Z:*/ aPointVariant.reserve( nNewCount ); aPointVariant.push_back( poPoint->getZ() ); /*break; case GBV_M: aPointVariant.reserve( nNewCount ); aPointVariant.push_back( poPoint->getM() ); }*/ } } else if ( eFlatType == wkbLineString ) { OGRLineString *poLine = (OGRLineString *) poShape; int nCount = poLine->getNumPoints(); int nNewCount = aPointX.size() + nCount; aPointX.reserve( nNewCount ); aPointY.reserve( nNewCount ); if( eBurnValueSrc != GBV_UserBurnValue ) aPointVariant.reserve( nNewCount ); for ( i = nCount - 1; i >= 0; i-- ) { aPointX.push_back( poLine->getX(i) ); aPointY.push_back( poLine->getY(i) ); if( eBurnValueSrc != GBV_UserBurnValue ) { /*switch( eBurnValueSrc ) { case GBV_Z:*/ aPointVariant.push_back( poLine->getZ(i) ); /*break; case GBV_M: aPointVariant.push_back( poLine->getM(i) ); }*/ } } aPartSize.push_back( nCount ); } else if ( EQUAL(poShape->getGeometryName(),"LINEARRING") ) { OGRLinearRing *poRing = (OGRLinearRing *) poShape; int nCount = poRing->getNumPoints(); int nNewCount = aPointX.size() + nCount; aPointX.reserve( nNewCount ); aPointY.reserve( nNewCount ); if( eBurnValueSrc != GBV_UserBurnValue ) aPointVariant.reserve( nNewCount ); for ( i = nCount - 1; i >= 0; i-- ) { aPointX.push_back( poRing->getX(i) ); aPointY.push_back( poRing->getY(i) ); } if( eBurnValueSrc != GBV_UserBurnValue ) { /*switch( eBurnValueSrc ) { case GBV_Z:*/ aPointVariant.push_back( poRing->getZ(i) ); /*break; case GBV_M: aPointVariant.push_back( poRing->getM(i) ); }*/ } aPartSize.push_back( nCount ); } else if( eFlatType == wkbPolygon ) { OGRPolygon *poPolygon = (OGRPolygon *) poShape; GDALCollectRingsFromGeometry( poPolygon->getExteriorRing(), aPointX, aPointY, aPointVariant, aPartSize, eBurnValueSrc ); for( i = 0; i < poPolygon->getNumInteriorRings(); i++ ) GDALCollectRingsFromGeometry( poPolygon->getInteriorRing(i), aPointX, aPointY, aPointVariant, aPartSize, eBurnValueSrc ); } else if( eFlatType == wkbMultiPoint || eFlatType == wkbMultiLineString || eFlatType == wkbMultiPolygon || eFlatType == wkbGeometryCollection ) { OGRGeometryCollection *poGC = (OGRGeometryCollection *) poShape; for( i = 0; i < poGC->getNumGeometries(); i++ ) GDALCollectRingsFromGeometry( poGC->getGeometryRef(i), aPointX, aPointY, aPointVariant, aPartSize, eBurnValueSrc ); } else { CPLDebug( "GDAL", "Rasterizer ignoring non-polygonal geometry." ); } }
bool ShpReader::Open(std::wstring fullPath, StudyControllerPtr studyController, VectorMapControllerPtr vectorMapController, ProgressDlgPtr progressDlg) { // Registers all format drivers built into GDAL/OGR. OGRRegisterAll(); OGRDataSource *OGRDataset; // Open vector file path std::string tempStr( fullPath.begin(), fullPath.end() ); OGRDataset = OGRSFDriverRegistrar::Open( tempStr.c_str(), FALSE ); // Return if no vector files are found if( OGRDataset == NULL ) { Log::Inst().Warning("(Warning) Failed to open file at " + tempStr + "."); return false; } if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() >0 ) MapControllerPtr mapController= App::Inst().GetLayerTreeController()->GetLayerTreeModel()->GetStudy(0)->GetMapLayer(0)->GetMapController(); // It appears that shapefiles (*.SHP) only support up to one layer per file // This will need to be further investigated for other vector filetypes (e.g., KML) // For now just grab layer at position 0 OGRLayer *poLayer = OGRDataset->GetLayer( 0 ); // Determine the XY boundaries for the entire vector dataset OGREnvelope psEnvelope; VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel(); poLayer->GetExtent( &psEnvelope ); vectorMapModel->SetVectorBoundary(psEnvelope); if(!SetupVectorProjection(OGRDataset,studyController,poLayer,vectorMapController )) { OGRDataset->DestroyDataSource(OGRDataset); return false; } if(progressDlg) { if(!progressDlg->Update(0, _T("Reading Vector Map Information..."))) { OGRDataset->DestroyDataSource(OGRDataset); return false; } } GLdouble minX, minY, maxX, maxY; minX = minY = std::numeric_limits<float>::max(); maxX = maxY = -std::numeric_limits<float>::max(); // Retrieve features from the dataset OGRFeature *poFeature; poLayer->ResetReading(); int numFeatures = poLayer->GetFeatureCount(); int count=0; //Log::Inst().Write("Loading shapefile with the following meta data:"); while ( ( poFeature = poLayer->GetNextFeature() ) != NULL ) { ///////////////////////////////////////////////// // PHASE 1: Retrieve METADATA from the dataset // ///////////////////////////////////////////////// OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn(); int iField; for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField ); //if( poFieldDefn->GetType() == OFTInteger ) // printf( "%d,", poFeature->GetFieldAsInteger( iField ) ); //else if( poFieldDefn->GetType() == OFTReal ) // printf( "%.3f,", poFeature->GetFieldAsDouble(iField) ); //else if( poFieldDefn->GetType() == OFTString ) // printf( "%s,", poFeature->GetFieldAsString(iField) ); //else // printf( "%s,", poFeature->GetFieldAsString(iField) ); //ofs << poFeature->GetFieldAsString(iField) << ","; std::string metaData = poFeature->GetFieldAsString(iField); // do something with the meta data... //Log::Inst().Write(metaData); } count++; if(progressDlg) { if(!progressDlg->Update(int(50 + (float(count)/numFeatures)*50))) return false; } /////////////////////////////////////////////////// // PHASE 2: Retrieve GEOMETRIES from the dataset // /////////////////////////////////////////////////// OGRGeometry *poGeometry; poGeometry = poFeature->GetGeometryRef(); // Move to the next feature in the set if no geometry present if( poGeometry == NULL ) { OGRFeature::DestroyFeature( poFeature ); continue; } OGRwkbGeometryType whatisit = poGeometry->getGeometryType(); // Handle POINTS if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPoint ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = (OGRPoint *) poGeometry; geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } //Handle MultiPoint else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPoint ) { OGRMultiPoint *poMultiPoint = (OGRMultiPoint *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPoint->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = ( OGRPoint* )poMultiPoint->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } //Handle Polylines else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbLineString ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = (OGRLineString *) poGeometry; geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); // Convert and store the points for ( int currentPoint = 0; currentPoint < poLine->getNumPoints(); currentPoint++ ) { // Convert and store the points if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MultiPolyLine else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiLineString ) { OGRMultiLineString *poMultiLine = (OGRMultiLineString *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiLine->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = ( OGRLineString* )poMultiLine->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLine ->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } // Handle POLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPolygon ) { GeoVector* geoVector = new GeoVector(); OGRPolygon *poPolygon = ( OGRPolygon* )poGeometry; OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MULTIPOLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPolygon ) { OGRMultiPolygon *poMultiPolygon = (OGRMultiPolygon *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPolygon->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); // OGRPolygon http://www.gdal.org/ogr/classOGRPolygon.html OGRPolygon *poPolygon = ( OGRPolygon* )poMultiPolygon->getGeometryRef( currGeometry ); // Retrieve the EXTERNAL ring of the multipolygon OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); // Retrieve all the INTERNAL rings of the multipolygon for ( int currentRing = 0; currentRing < poPolygon->getNumInteriorRings(); currentRing++ ) { GeoVector* geoVector2 = new GeoVector(); poLinearRing = poPolygon->getInteriorRing( currentRing ); geoVector2->SetGeometryType( wkbLinearRing ); geoVector2->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector2->pointX[currentPoint] = x; geoVector2->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector2->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector2->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector2 ); } } } // Report a warning message for unhandled geometries else { Log::Inst().Warning("(Warning) Could not load vector data: unsupported geometry."); } OGRFeature::DestroyFeature( poFeature ); } if (float(minX) == float(maxX) && float(minY) == float(maxY)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } if(needProjection) { vectorMapModel->SetVectorBoundary_MinX(minX); vectorMapModel->SetVectorBoundary_MaxX(maxX); vectorMapModel->SetVectorBoundary_MinY(minY); vectorMapModel->SetVectorBoundary_MaxY(maxY); } if(!SetupVectorScaling(vectorMapModel,progressDlg)) { OGRDataset->DestroyDataSource(OGRDataset); return false; } VectorMetaDataInfo(OGRDataset, studyController, vectorMapController); OGRDataSource::DestroyDataSource( OGRDataset ); return true; }
OGRFeature *OGRSUALayer::GetNextRawFeature() { if( bEOF ) return nullptr; CPLString osTYPE; CPLString osCLASS; CPLString osTITLE; CPLString osTOPS; CPLString osBASE; OGRLinearRing oLR; double dfLastLat = 0.0; double dfLastLon = 0.0; bool bFirst = true; while( true ) { const char* pszLine = nullptr; if( bFirst && bHasLastLine ) { pszLine = osLastLine.c_str(); bFirst = false; } else { pszLine = CPLReadLine2L(fpSUA, 1024, nullptr); if (pszLine == nullptr) { bEOF = true; if (oLR.getNumPoints() == 0) return nullptr; break; } osLastLine = pszLine; bHasLastLine = true; } if (pszLine[0] == '#' || pszLine[0] == '\0') continue; if (STARTS_WITH_CI(pszLine, "TYPE=")) { if (!osTYPE.empty()) break; osTYPE = pszLine + 5; } else if (STARTS_WITH_CI(pszLine, "CLASS=")) { if (!osCLASS.empty()) break; osCLASS = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TITLE=")) { if (!osTITLE.empty()) break; osTITLE = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TOPS=")) osTOPS = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "BASE=")) osBASE = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "POINT=")) { pszLine += 6; if (strlen(pszLine) != 16) continue; double dfLat = 0.0; double dfLon = 0.0; if (!GetLatLon(pszLine, dfLat, dfLon)) continue; oLR.addPoint(dfLon, dfLat); dfLastLat = dfLat; dfLastLon = dfLon; } else if (STARTS_WITH_CI(pszLine, "CLOCKWISE") || STARTS_WITH_CI(pszLine, "ANTI-CLOCKWISE")) { if (oLR.getNumPoints() == 0) continue; int bClockWise = STARTS_WITH_CI(pszLine, "CLOCKWISE"); /*const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == NULL) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852;*/ const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == nullptr) continue; pszCENTRE += 7; if (strlen(pszCENTRE) < 17 || pszCENTRE[16] != ' ') continue; double dfCenterLat = 0.0; double dfCenterLon = 0.0; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; const char* pszTO = strstr(pszLine, "TO="); if (pszTO == nullptr) continue; pszTO += 3; if (strlen(pszTO) != 16) continue; double dfToLat = 0.0; double dfToLon = 0.0; if (!GetLatLon(pszTO, dfToLat, dfToLon)) continue; const double dfStartDistance = OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); const double dfEndDistance = OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfToLat, dfToLon); const double dfStartAngle = OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); double dfEndAngle = OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfToLat, dfToLon); if( bClockWise && dfEndAngle < dfStartAngle ) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; int nSign = (bClockWise) ? 1 : -1; for( double dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign ) { const double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); const double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; double dfLat = 0.0; double dfLon = 0.0; OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } oLR.addPoint(dfToLon, dfToLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "CIRCLE")) { const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == nullptr) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852; const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == nullptr) continue; pszCENTRE += 7; if (strlen(pszCENTRE) != 16) continue; double dfCenterLat = 0.0; double dfCenterLon = 0.0; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; double dfLat = 0.0; double dfLon = 0.0; for( double dfAngle = 0; dfAngle < 360; dfAngle += 1 ) { OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "INCLUDE") || STARTS_WITH_CI(pszLine, "END")) { } else { CPLDebug("SUA", "Unexpected content : %s", pszLine); } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, osTYPE.c_str()); poFeature->SetField(1, osCLASS.c_str()); poFeature->SetField(2, osTITLE.c_str()); poFeature->SetField(3, osTOPS.c_str()); poFeature->SetField(4, osBASE.c_str()); OGRPolygon* poPoly = new OGRPolygon(); poPoly->assignSpatialReference(poSRS); oLR.closeRings(); poPoly->addRing(&oLR); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
int OGRPolygonLabelPoint(OGRPolygon *poPoly, OGRPoint *poLabelPoint) { double slope; OGRRawPoint point1, point2; int i, j, k, nfound; double x, y, *xintersect, temp; double hi_y, lo_y; int wrong_order, n; double len, max_len=0; double skip; OGREnvelope oEnv; if (poPoly == NULL) return OGRERR_FAILURE; poPoly->getEnvelope(&oEnv); poLabelPoint->setX((oEnv.MaxX + oEnv.MinX)/2.0); poLabelPoint->setY((oEnv.MaxY + oEnv.MinY)/2.0); //if(get_centroid(p, lp, &miny, &maxy) == -1) return(-1); if(OGRIntersectPointPolygon(poLabelPoint, poPoly) == TRUE) /* cool, done */ return OGRERR_NONE; /* do it the hard way - scanline */ skip = (oEnv.MaxY - oEnv.MinY)/NUM_SCANLINES; n=0; for(j=0; j<OGR_NUM_RINGS(poPoly); j++) { /* count total number of points */ n += OGR_GET_RING(poPoly, j)->getNumPoints(); } xintersect = (double *)calloc(n, sizeof(double)); if (xintersect == NULL) return OGRERR_FAILURE; for(k=1; k<=NUM_SCANLINES; k++) { /* sample the shape in the y direction */ y = oEnv.MaxY - k*skip; /* need to find a y that won't intersect any vertices exactly */ hi_y = y - 1; /* first initializing lo_y, hi_y to be any 2 pnts on either side of lp->y */ lo_y = y + 1; for(j=0; j<OGR_NUM_RINGS(poPoly); j++) { OGRLinearRing *poRing = OGR_GET_RING(poPoly,j); if((lo_y < y) && (hi_y >= y)) break; /* already initialized */ for(i=0; i < poRing->getNumPoints(); i++) { if((lo_y < y) && (hi_y >= y)) break; /* already initialized */ if(poRing->getY(i) < y) lo_y = poRing->getY(i); if(poRing->getY(i) >= y) hi_y = poRing->getY(i); } } n=0; for(j=0; j<OGR_NUM_RINGS(poPoly); j++) { OGRLinearRing *poRing = OGR_GET_RING(poPoly,j); for(i=0; i < poRing->getNumPoints(); i++) { if((poRing->getY(i) < y) && ((y - poRing->getY(i)) < (y - lo_y))) lo_y = poRing->getY(i); if((poRing->getY(i) >= y) && ((poRing->getY(i) - y) < (hi_y - y))) hi_y = poRing->getY(i); } } if(lo_y == hi_y) return OGRERR_FAILURE; else y = (hi_y + lo_y)/2.0; nfound = 0; for(j=0; j<OGR_NUM_RINGS(poPoly); j++) /* for each line */ { OGRLinearRing *poRing = OGR_GET_RING(poPoly,j); point1.x = poRing->getX(poRing->getNumPoints()-1); point1.y = poRing->getY(poRing->getNumPoints()-1); for(i=0; i < poRing->getNumPoints(); i++) { point2.x = poRing->getX(i); point2.y = poRing->getY(i); if(EDGE_CHECK(point1.y, y, point2.y) == CLIP_MIDDLE) { if(point1.y == point2.y) continue; /* ignore horizontal edges */ else slope = (point2.x - point1.x) / (point2.y - point1.y); x = point1.x + (y - point1.y)*slope; xintersect[nfound++] = x; } /* End of checking this edge */ point1 = point2; /* Go on to next edge */ } } /* Finished the scanline */ /* First, sort the intersections */ do { wrong_order = 0; for(i=0; i < nfound-1; i++) { if(xintersect[i] > xintersect[i+1]) { wrong_order = 1; SWAP(xintersect[i], xintersect[i+1], temp); } } } while(wrong_order); /* Great, now find longest span */ point1.y = point2.y = y; for(i=0; i < nfound; i += 2) { point1.x = xintersect[i]; point2.x = xintersect[i+1]; /* len = length(point1, point2); */ len = ABS((point2.x - point1.x)); if(len > max_len) { max_len = len; poLabelPoint->setX( (point1.x + point2.x)/2 ); poLabelPoint->setY( y ); } } } free(xintersect); /* __TODO__ Bug 673 * There seem to be some polygons for which the label is returned * completely outside of the polygon's MBR and this messes the * file bounds, etc. * Until we find the source of the problem, we'll at least validate * the label point to make sure that it overlaps the polygon MBR. */ if( poLabelPoint->getX() < oEnv.MinX || poLabelPoint->getY() < oEnv.MinY || poLabelPoint->getX() > oEnv.MaxX || poLabelPoint->getY() > oEnv.MaxY ) { // Reset label coordinates to center of MBR, just in case poLabelPoint->setX((oEnv.MaxX + oEnv.MinX)/2.0); poLabelPoint->setY((oEnv.MaxY + oEnv.MinY)/2.0); // And return an error return OGRERR_FAILURE; } if(max_len > 0) return OGRERR_NONE; else return OGRERR_FAILURE; }
void SavePolygons( const std::vector< std::string > InFilenames, const char *OutFilename, const cv::Mat klabels, const std::vector< cv::Mat > raster, const std::vector< u_int32_t > labelpixels, const std::vector< std::vector <double> > sumCH, const std::vector< std::vector <double> > avgCH, const std::vector< std::vector <double> > stdCH, std::vector< std::vector< LINE > >& linelists ) { CPLLocaleC oLocaleCForcer(); CPLErrorReset(); const char *pszDriverName = "ESRI Shapefile"; GDALDriver *liDriver; liDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName ); if( liDriver == NULL ) { printf( "\nERROR: %s driver not available.\n", pszDriverName ); exit( 1 ); } const size_t m_bands = raster.size(); const size_t m_labels = labelpixels.size(); GDALDataset *liDS; liDS = liDriver->Create( OutFilename, 0, 0, 0, GDT_Unknown, NULL ); if( liDS == NULL ) { printf( "\nERROR: Creation of output file failed.\n" ); exit( 1 ); } // dataset GDALDataset* piDataset; piDataset = (GDALDataset*) GDALOpen(InFilenames[0].c_str(), GA_ReadOnly); // spatialref OGRSpatialReference oSRS; oSRS.SetProjCS( piDataset->GetProjectionRef() ); OGRLayer *liLayer; liLayer = liDS->CreateLayer( "segments", &oSRS, wkbPolygon, NULL ); if( liLayer == NULL ) { printf( "\nERROR: Layer creation failed.\n" ); exit( 1 ); } // spatial transform double adfGeoTransform[6]; double oX = 0.0f; double oY = 0.0f; double mX = 1.0f; double mY = -1.0f; if( piDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { oX = adfGeoTransform[0]; oY = adfGeoTransform[3]; mX = adfGeoTransform[1]; mY = adfGeoTransform[5]; } GDALClose( (GDALDatasetH) piDataset ); OGRFieldDefn *clsIdField = new OGRFieldDefn( "CLASS", OFTInteger ); liLayer->CreateField( clsIdField ); OGRFieldDefn *pixArField = new OGRFieldDefn( "AREA", OFTInteger ); liLayer->CreateField( pixArField ); for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_AVERAGE"; OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal ); liLayer->CreateField( lavrgField ); } for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_STDDEV"; OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal ); liLayer->CreateField( lavrgField ); } int multiring = 0; printf ("Write File: %s (polygon)\n", OutFilename); for (size_t k = 0; k < m_labels; k++) { if (multiring == 1) { k = k - 1; multiring = 0; } if (linelists[k].size() == 0) continue; // insert field data OGRFeature *liFeature; liFeature = OGRFeature::CreateFeature( liLayer->GetLayerDefn() ); liFeature->SetField( "CLASS", (int) k ); liFeature->SetField( "AREA", (int) labelpixels.at(k) ); for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_AVERAGE"; liFeature->SetField( FieldName.c_str(), (double) avgCH[b].at(k) ); } for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_STDDEV"; liFeature->SetField( FieldName.c_str(), stdCH[b].at(k) ); } // initiate polygon start OGRLinearRing linestring; linestring.setCoordinateDimension(2); linestring.addPoint( oX + (double) linelists[k][0].sX * mX, oY + mY * (double) linelists[k][0].sY ); linestring.addPoint( oX + (double) linelists[k][0].eX * mX, oY + mY * (double) linelists[k][0].eY ); linelists[k].erase( linelists[k].begin() ); // construct polygon from lines while ( linelists[k].size() > 0 ) { if (multiring == 1) break; vector<LINE>::iterator it = linelists[k].begin(); for (; it != linelists[k].end(); ++it) { double ltX = linestring.getX(linestring.getNumPoints()-1); double ltY = linestring.getY(linestring.getNumPoints()-1); double csX = oX + (double) it->sX * mX; double csY = oY + mY * (double) it->sY; double ceX = oX + (double) it->eX * mX; double ceY = oY + mY * (double) it->eY; if ( ( csX == ltX ) && ( csY == ltY ) ) { linestring.addPoint(ceX, ceY); linelists[k].erase(it); break; } if ( ( ceX == ltX ) && ( ceY == ltY ) ) { linestring.addPoint(csX, csY); linelists[k].erase(it); break; } if (it == linelists[k].end()-1) { multiring = 1; break; } } } OGRPolygon polygon; linestring.closeRings(); // simplify poligons // remove colinear vertices OGRLinearRing linesimple; float pointPrevX = 0, pointPrevY = 0; for (int i = 0; i < linestring.getNumPoints(); i++) { OGRPoint point; linestring.getPoint(i, &point); // start if ( i == 0) { linesimple.addPoint( &point ); pointPrevX = point.getX(); pointPrevY = point.getY(); continue; } // end vertex if ( i == linestring.getNumPoints() - 1 ) { linesimple.addPoint( &point ); continue; } OGRPoint pointNext; linestring.getPoint(i+1, &pointNext); // | x1 y1 1 | // det | x2 y2 1 | = 0 => p1,p2,p3 are colinear // | x3 y3 1 | // x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2) == 0 // only if not colinear with previous and next if ( pointPrevX*(point.getY()-pointNext.getY()) + point.getX()*(pointNext.getY()-pointPrevY) + pointNext.getX()*(pointPrevY-point.getY()) != 0 ) { linesimple.addPoint( &point ); pointPrevX = point.getX(); pointPrevY = point.getY(); } } // as polygon geometry polygon.addRing( &linesimple ); liFeature->SetGeometry( &polygon ); if( liLayer->CreateFeature( liFeature ) != OGRERR_NONE ) { printf( "\nERROR: Failed to create feature in shapefile.\n" ); exit( 1 ); } OGRFeature::DestroyFeature( liFeature ); GDALTermProgress( (float)(k+1) / (float)(m_labels), NULL, NULL ); } GDALTermProgress( 1.0f, NULL, NULL ); GDALClose( liDS ); }