OGRGeometry* BuildOgrPolygon(Polygon* poly, OGRCoordinateTransformation* transform) { OGRPolygon* result = new OGRPolygon(); list<Point*>* pOuter = poly->outerRing; list<Point*>::iterator ringIter; OGRLinearRing* ring = new OGRLinearRing(); for (ringIter = pOuter->begin(); ringIter != pOuter->end(); ringIter++) { double x = (*ringIter)->X; double y = (*ringIter)->Y; if (transform != NULL) transform->Transform(1, &x, &y); ring->addPoint(x, y); } result->addRingDirectly(ring); list<list<Point *>*>* innerRings = poly->innerRings; list<list<Point *>*>::iterator ringsIter; for (ringsIter = innerRings->begin(); ringsIter != innerRings->end(); ringsIter++) { ring = new OGRLinearRing(); list<Point*>* currRing = *ringsIter; for (ringIter = currRing->begin(); ringIter != currRing->end(); ringIter++) { double x = (*ringIter)->X; double y = (*ringIter)->Y; if (transform != NULL) transform->Transform(1, &x, &y); ring->addPoint(x, y); } result->addRingDirectly(ring); } result->closeRings(); return result; }
int ICLayerLineString::isSelected(double x, double y, double scale) { OGRPolygon* Poly = static_cast<OGRPolygon*> (OGRGeometryFactory::createGeometry(wkbPolygon)); OGRLinearRing* Ring = static_cast<OGRLinearRing*> (OGRGeometryFactory::createGeometry( wkbLinearRing)); Ring->setPoint(0, new OGRPoint(x - 3 / scale, y - 3 / scale)); Ring->setPoint(1, new OGRPoint(x + 3 / scale, y - 3 / scale)); Ring->setPoint(2, new OGRPoint(x + 3 / scale, y + 3 / scale)); Ring->setPoint(3, new OGRPoint(x - 3 / scale, y + 3 / scale)); Ring->closeRings(); Poly->addRingDirectly(Ring); std::map<int, ICLayerObject*>::iterator it; for (it = m_ICLayerObject.begin(); it != m_ICLayerObject.end(); it++) { if (Poly->Intersects( static_cast<OGRGeometry*> ((*it).second->getOGRGeometryObject()))) { return (*it).first; } } return -1; }
OGRPolygon* OGRMSSQLGeometryParser::ReadPolygon(int iShape) { int iFigure, iPoint, iNextPoint, i; int iNextFigure = NextFigureOffset(iShape); OGRPolygon* poPoly = new OGRPolygon(); for (iFigure = FigureOffset(iShape); iFigure < iNextFigure; iFigure++) { OGRLinearRing* poRing = new OGRLinearRing(); iPoint = PointOffset(iFigure); iNextPoint = NextPointOffset(iFigure); poRing->setNumPoints(iNextPoint - iPoint); i = 0; while (iPoint < iNextPoint) { if ( chProps & SP_HASZVALUES ) poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) ); else poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint) ); ++iPoint; ++i; } poPoly->addRingDirectly( poRing ); } return poPoly; }
OGRPolygon* make() { OGRPolygon* poPolygon = new OGRPolygon(); poPolygon->addRingDirectly(make<OGRLinearRing>()); poPolygon->addRingDirectly(make<OGRLinearRing>()); return poPolygon; }
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; }
Polygon::Polygon(const BOX3D& box) { OGRPolygon *poly = new OGRPolygon(); m_geom.reset(poly); OGRLinearRing *lr = new OGRLinearRing(); lr->addPoint(box.minx, box.miny, box.minz); lr->addPoint(box.minx, box.maxy, box.minz); lr->addPoint(box.maxx, box.maxy, box.maxz); lr->addPoint(box.maxx, box.miny, box.maxz); lr->addPoint(box.minx, box.miny, box.minz); poly->addRingDirectly(lr); }
OGRPolygon* OGRCurvePolygon::CurvePolyToPoly(double dfMaxAngleStepSizeDegrees, const char* const* papszOptions) const { OGRPolygon* poPoly = new OGRPolygon(); poPoly->assignSpatialReference(getSpatialReference()); for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { OGRLineString* poLS = oCC.papoCurves[iRing]->CurveToLine(dfMaxAngleStepSizeDegrees, papszOptions); poPoly->addRingDirectly(OGRCurve::CastToLinearRing(poLS)); } return poPoly; }
OGRPolygon *getPolygon(DOMElement *elem) { OGRPolygon *pg = new OGRPolygon(); DOMElement *boundaryElem = (DOMElement *)elem->getFirstChild(); // outer boundary while (boundaryElem != NULL) { char* pszTagName = XMLString::transcode(boundaryElem->getTagName()); if (cmpStr(ILI2_BOUNDARY, pszTagName) == 0) pg->addRingDirectly(getBoundary(boundaryElem)); XMLString::release(&pszTagName); boundaryElem = (DOMElement *)boundaryElem->getNextSibling(); // inner boundaries } return pg; }
void OGRPLScenesLayer::SetMainFilterRect(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY) { delete poMainFilter; if( dfMinX == dfMaxX && dfMinY == dfMaxY ) poMainFilter = new OGRPoint(dfMinX, dfMinY); else { OGRPolygon* poPolygon = new OGRPolygon(); poMainFilter = poPolygon; OGRLinearRing* poLR = new OGRLinearRing; poPolygon->addRingDirectly(poLR); poLR->addPoint(dfMinX, dfMinY); poLR->addPoint(dfMinX, dfMaxY); poLR->addPoint(dfMaxX, dfMaxY); poLR->addPoint(dfMaxX, dfMinY); poLR->addPoint(dfMinX, dfMinY); } ResetReading(); }
void ILI1Reader::ReadGeom(char **stgeom, OGRwkbGeometryType eType, OGRFeature *feature) { char **tokens = NULL; const char *firsttok = NULL; int end = FALSE; int isArc = FALSE; OGRLineString *ogrLine = NULL; //current line OGRLinearRing *ogrRing = NULL; //current ring OGRPolygon *ogrPoly = NULL; //current polygon OGRPoint ogrPoint, arcPoint, endPoint; //points for arc interpolation OGRMultiLineString *ogrMultiLine = NULL; //current multi line //tokens = ["STPT", "1111", "22222"] ogrPoint.setX(atof(stgeom[1])); ogrPoint.setY(atof(stgeom[2])); ogrLine = (eType == wkbPolygon) ? new OGRLinearRing() : new OGRLineString(); ogrLine->addPoint(&ogrPoint); //Set feature geometry if (eType == wkbMultiLineString) { ogrMultiLine = new OGRMultiLineString(); feature->SetGeometryDirectly(ogrMultiLine); } else if (eType == wkbGeometryCollection) //AREA { if (feature->GetGeometryRef()) ogrMultiLine = (OGRMultiLineString *)feature->GetGeometryRef(); else { ogrMultiLine = new OGRMultiLineString(); feature->SetGeometryDirectly(ogrMultiLine); } } else if (eType == wkbPolygon) { if (feature->GetGeometryRef()) { ogrPoly = (OGRPolygon *)feature->GetGeometryRef(); if (ogrPoly->getNumInteriorRings() > 0) ogrRing = ogrPoly->getInteriorRing(ogrPoly->getNumInteriorRings()-1); else ogrRing = ogrPoly->getExteriorRing(); if (ogrRing && !ogrRing->get_IsClosed()) ogrLine = ogrRing; //SURFACE polygon spread over multiple OBJECTs } else { ogrPoly = new OGRPolygon(); feature->SetGeometryDirectly(ogrPoly); } } else { feature->SetGeometryDirectly(ogrLine); } //Parse geometry while (!end && (tokens = ReadParseLine())) { firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "LIPT")) { if (isArc) { endPoint.setX(atof(tokens[1])); endPoint.setY(atof(tokens[2])); interpolateArc(ogrLine, &ogrPoint, &arcPoint, &endPoint, arcIncr); } ogrPoint.setX(atof(tokens[1])); ogrPoint.setY(atof(tokens[2])); isArc = FALSE; ogrLine->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ARCP")) { isArc = TRUE; arcPoint.setX(atof(tokens[1])); arcPoint.setY(atof(tokens[2])); } else if (EQUAL(firsttok, "ELIN")) { if (ogrMultiLine) { ogrMultiLine->addGeometryDirectly(ogrLine); } if (ogrPoly && ogrLine != ogrRing) { ogrPoly->addRingDirectly((OGRLinearRing *)ogrLine); } end = TRUE; } else if (EQUAL(firsttok, "EEDG")) { end = TRUE; } else if (EQUAL(firsttok, "LATT")) { //Line Attributes (ignored) } else if (EQUAL(firsttok, "EFLA")) { end = TRUE; } else if (EQUAL(firsttok, "ETAB")) { end = TRUE; } else { CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } }
OGRFeature * OGRBNALayer::BuildFeatureFromBNARecord (BNARecord* record, long fid) { OGRFeature *poFeature; int i; poFeature = new OGRFeature( poFeatureDefn ); for(i=0;i<nIDs;i++) { poFeature->SetField( i, record->ids[i] ? record->ids[i] : ""); } poFeature->SetFID( fid ); if (bnaFeatureType == BNA_POINT) { poFeature->SetGeometryDirectly( new OGRPoint( record->tabCoords[0][0], record->tabCoords[0][1] ) ); } else if (bnaFeatureType == BNA_POLYLINE) { OGRLineString* lineString = new OGRLineString (); lineString->setCoordinateDimension(2); lineString->setNumPoints(record->nCoords); for(i=0;i<record->nCoords;i++) { lineString->setPoint(i, record->tabCoords[i][0], record->tabCoords[i][1] ); } poFeature->SetGeometryDirectly(lineString); } else if (bnaFeatureType == BNA_POLYGON) { double firstX = record->tabCoords[0][0]; double firstY = record->tabCoords[0][1]; int isFirstPolygon = 1; double secondaryFirstX = 0, secondaryFirstY = 0; OGRLinearRing* ring = new OGRLinearRing (); ring->setCoordinateDimension(2); ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] ); /* record->nCoords is really a safe upper bound */ int nbPolygons = 0; OGRPolygon** tabPolygons = (OGRPolygon**)CPLMalloc(record->nCoords * sizeof(OGRPolygon*)); for(i=1;i<record->nCoords;i++) { ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); if (isFirstPolygon == 1 && record->tabCoords[i][0] == firstX && record->tabCoords[i][1] == firstY) { OGRPolygon* polygon = new OGRPolygon (); polygon->addRingDirectly(ring); tabPolygons[nbPolygons] = polygon; nbPolygons++; if (i == record->nCoords - 1) { break; } isFirstPolygon = 0; i ++; secondaryFirstX = record->tabCoords[i][0]; secondaryFirstY = record->tabCoords[i][1]; ring = new OGRLinearRing (); ring->setCoordinateDimension(2); ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); } else if (isFirstPolygon == 0 && record->tabCoords[i][0] == secondaryFirstX && record->tabCoords[i][1] == secondaryFirstY) { OGRPolygon* polygon = new OGRPolygon (); polygon->addRingDirectly(ring); tabPolygons[nbPolygons] = polygon; nbPolygons++; if (i < record->nCoords - 1) { /* After the closing of a subpolygon, the first coordinates of the first polygon */ /* should be recalled... in theory */ if (record->tabCoords[i+1][0] == firstX && record->tabCoords[i+1][1] == firstY) { if (i + 1 == record->nCoords - 1) break; i ++; } else { #if 0 CPLError(CE_Warning, CPLE_AppDefined, "Geometry of polygon of fid %d starting at line %d is not strictly conformant. " "Trying to go on...\n", fid, offsetAndLineFeaturesTable[fid].line + 1); #endif } i ++; secondaryFirstX = record->tabCoords[i][0]; secondaryFirstY = record->tabCoords[i][1]; ring = new OGRLinearRing (); ring->setCoordinateDimension(2); ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] ); } else { #if 0 CPLError(CE_Warning, CPLE_AppDefined, "Geometry of polygon of fid %d starting at line %d is not strictly conformant. Trying to go on...\n", fid, offsetAndLineFeaturesTable[fid].line + 1); #endif } } } if (i == record->nCoords) { /* Let's be a bit tolerant abount non closing polygons */ if (isFirstPolygon) { ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] ); OGRPolygon* polygon = new OGRPolygon (); polygon->addRingDirectly(ring); tabPolygons[nbPolygons] = polygon; nbPolygons++; } } if (nbPolygons == 1) { /* Special optimization here : we directly put the polygon into the multipolygon. */ /* This should save quite a few useless copies */ OGRMultiPolygon* multipolygon = new OGRMultiPolygon(); multipolygon->addGeometryDirectly(tabPolygons[0]); poFeature->SetGeometryDirectly(multipolygon); } else { int isValidGeometry; poFeature->SetGeometryDirectly( OGRGeometryFactory::organizePolygons((OGRGeometry**)tabPolygons, nbPolygons, &isValidGeometry, NULL)); if (!isValidGeometry) { CPLError(CE_Warning, CPLE_AppDefined, "Geometry of polygon of fid %ld starting at line %d cannot be translated to Simple Geometry. " "All polygons will be contained in a multipolygon.\n", fid, offsetAndLineFeaturesTable[fid].line + 1); } } CPLFree(tabPolygons); } else { /* Circle or ellipses are not part of the OGR Simple Geometry, so we discretize them into polygons by 1 degree step */ OGRPolygon* polygon = new OGRPolygon (); OGRLinearRing* ring = new OGRLinearRing (); ring->setCoordinateDimension(2); double center_x = record->tabCoords[0][0]; double center_y = record->tabCoords[0][1]; double major_radius = record->tabCoords[1][0]; double minor_radius = record->tabCoords[1][1]; if (minor_radius == 0) minor_radius = major_radius; for(i=0;i<360;i++) { ring->addPoint(center_x + major_radius * cos(i * (M_PI / 180)), center_y + minor_radius * sin(i * (M_PI / 180)) ); } ring->addPoint(center_x + major_radius, center_y); polygon->addRingDirectly ( ring ); poFeature->SetGeometryDirectly(polygon); poFeature->SetField( nIDs, major_radius); poFeature->SetField( nIDs+1, minor_radius); } return poFeature; }
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; }
OGRErr OGRCreateFromGeomedia( GByte *pabyGeom, OGRGeometry **ppoGeom, int nBytes ) { *ppoGeom = NULL; if( nBytes < 16 ) return OGRERR_FAILURE; if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) ) return OGRERR_FAILURE; int nGeomType = pabyGeom[0]; pabyGeom += 16; nBytes -= 16; if( nGeomType == GEOMEDIA_POINT || nGeomType == GEOMEDIA_ORIENTED_POINT ) { if (nBytes < 3 * 8) return OGRERR_FAILURE; double dfX, dfY, dfZ; memcpy(&dfX, pabyGeom, 8); CPL_LSBPTR64(&dfX); memcpy(&dfY, pabyGeom + 8, 8); CPL_LSBPTR64(&dfY); memcpy(&dfZ, pabyGeom + 16, 8); CPL_LSBPTR64(&dfZ); *ppoGeom = new OGRPoint( dfX, dfY, dfZ ); return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_POLYLINE ) { if (nBytes < 4) return OGRERR_FAILURE; int nPoints; memcpy(&nPoints, pabyGeom, 4); CPL_LSBPTR32(&nPoints); pabyGeom += 4; nBytes -= 4; if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24) return OGRERR_FAILURE; OGRLineString* poLS = new OGRLineString(); poLS->setNumPoints(nPoints); int i; for(i=0;i<nPoints;i++) { double dfX, dfY, dfZ; memcpy(&dfX, pabyGeom, 8); CPL_LSBPTR64(&dfX); memcpy(&dfY, pabyGeom + 8, 8); CPL_LSBPTR64(&dfY); memcpy(&dfZ, pabyGeom + 16, 8); CPL_LSBPTR64(&dfZ); poLS->setPoint(i, dfX, dfY, dfZ); pabyGeom += 24; } *ppoGeom = poLS; return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_POLYGON ) { if (nBytes < 4) return OGRERR_FAILURE; int nPoints; memcpy(&nPoints, pabyGeom, 4); CPL_LSBPTR32(&nPoints); pabyGeom += 4; nBytes -= 4; if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24) return OGRERR_FAILURE; OGRLinearRing* poRing = new OGRLinearRing(); poRing->setNumPoints(nPoints); int i; for(i=0;i<nPoints;i++) { double dfX, dfY, dfZ; memcpy(&dfX, pabyGeom, 8); CPL_LSBPTR64(&dfX); memcpy(&dfY, pabyGeom + 8, 8); CPL_LSBPTR64(&dfY); memcpy(&dfZ, pabyGeom + 16, 8); CPL_LSBPTR64(&dfZ); poRing->setPoint(i, dfX, dfY, dfZ); pabyGeom += 24; } OGRPolygon* poPoly = new OGRPolygon(); poPoly->addRingDirectly(poRing); *ppoGeom = poPoly; return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_BOUNDARY ) { if (nBytes < 4) return OGRERR_FAILURE; int nExteriorSize; memcpy(&nExteriorSize, pabyGeom, 4); CPL_LSBPTR32(&nExteriorSize); pabyGeom += 4; nBytes -= 4; if (nBytes < nExteriorSize) return OGRERR_FAILURE; OGRGeometry* poExteriorGeom = NULL; if (OGRCreateFromGeomedia( pabyGeom, &poExteriorGeom, nExteriorSize ) != OGRERR_NONE) return OGRERR_FAILURE; if ( wkbFlatten( poExteriorGeom->getGeometryType() ) != wkbPolygon ) { delete poExteriorGeom; return OGRERR_FAILURE; } pabyGeom += nExteriorSize; nBytes -= nExteriorSize; if (nBytes < 4) { delete poExteriorGeom; return OGRERR_FAILURE; } int nInteriorSize; memcpy(&nInteriorSize, pabyGeom, 4); CPL_LSBPTR32(&nInteriorSize); pabyGeom += 4; nBytes -= 4; if (nBytes < nInteriorSize) { delete poExteriorGeom; return OGRERR_FAILURE; } OGRGeometry* poInteriorGeom = NULL; if (OGRCreateFromGeomedia( pabyGeom, &poInteriorGeom, nInteriorSize ) != OGRERR_NONE) { delete poExteriorGeom; return OGRERR_FAILURE; } OGRwkbGeometryType interiorGeomType = wkbFlatten( poInteriorGeom->getGeometryType() ); if ( interiorGeomType == wkbPolygon ) { ((OGRPolygon*)poExteriorGeom)->addRing(((OGRPolygon*)poInteriorGeom)->getExteriorRing()); } else if ( interiorGeomType == wkbMultiPolygon ) { int numGeom = ((OGRMultiPolygon*)poInteriorGeom)->getNumGeometries(); for ( int i = 0; i < numGeom; ++i ) { OGRPolygon* poInteriorPolygon = (OGRPolygon*)((OGRMultiPolygon*)poInteriorGeom)->getGeometryRef(i); ((OGRPolygon*)poExteriorGeom)->addRing( poInteriorPolygon->getExteriorRing() ); } } else { delete poExteriorGeom; delete poInteriorGeom; return OGRERR_FAILURE; } delete poInteriorGeom; *ppoGeom = poExteriorGeom; return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_COLLECTION || nGeomType == GEOMEDIA_MULTILINE || nGeomType == GEOMEDIA_MULTIPOLYGON ) { if (nBytes < 4) return OGRERR_FAILURE; int i; int nParts; memcpy(&nParts, pabyGeom, 4); CPL_LSBPTR32(&nParts); pabyGeom += 4; nBytes -= 4; if (nParts < 0 || nParts > INT_MAX / (4 + 16) || nBytes < nParts * (4 + 16)) return OGRERR_FAILURE; /* Can this collection be considered as a multipolyline or multipolygon ? */ if ( nGeomType == GEOMEDIA_COLLECTION ) { GByte* pabyGeomBackup = pabyGeom; int nBytesBackup = nBytes; int bAllPolyline = TRUE; int bAllPolygon = TRUE; for(i=0;i<nParts;i++) { if (nBytes < 4) return OGRERR_FAILURE; int nSubBytes; memcpy(&nSubBytes, pabyGeom, 4); CPL_LSBPTR32(&nSubBytes); if (nSubBytes < 0) { return OGRERR_FAILURE; } pabyGeom += 4; nBytes -= 4; if (nBytes < nSubBytes) { return OGRERR_FAILURE; } if( nSubBytes < 16 ) return OGRERR_FAILURE; if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) ) return OGRERR_FAILURE; int nSubGeomType = pabyGeom[0]; if ( nSubGeomType != GEOMEDIA_POLYLINE ) bAllPolyline = FALSE; if ( nSubGeomType != GEOMEDIA_POLYGON ) bAllPolygon = FALSE; pabyGeom += nSubBytes; nBytes -= nSubBytes; } pabyGeom = pabyGeomBackup; nBytes = nBytesBackup; if (bAllPolyline) nGeomType = GEOMEDIA_MULTILINE; else if (bAllPolygon) nGeomType = GEOMEDIA_MULTIPOLYGON; } OGRGeometryCollection* poColl = (nGeomType == GEOMEDIA_MULTILINE) ? new OGRMultiLineString() : (nGeomType == GEOMEDIA_MULTIPOLYGON) ? new OGRMultiPolygon() : new OGRGeometryCollection(); for(i=0;i<nParts;i++) { if (nBytes < 4) return OGRERR_FAILURE; int nSubBytes; memcpy(&nSubBytes, pabyGeom, 4); CPL_LSBPTR32(&nSubBytes); if (nSubBytes < 0) { delete poColl; return OGRERR_FAILURE; } pabyGeom += 4; nBytes -= 4; if (nBytes < nSubBytes) { delete poColl; return OGRERR_FAILURE; } OGRGeometry* poSubGeom = NULL; if (OGRCreateFromGeomedia( pabyGeom, &poSubGeom, nSubBytes ) == OGRERR_NONE) { if (wkbFlatten(poColl->getGeometryType()) == wkbMultiPolygon && wkbFlatten(poSubGeom->getGeometryType()) == wkbLineString) { OGRPolygon* poPoly = new OGRPolygon(); OGRLinearRing* poRing = new OGRLinearRing(); poRing->addSubLineString((OGRLineString*)poSubGeom); poPoly->addRingDirectly(poRing); delete poSubGeom; poSubGeom = poPoly; } if (poColl->addGeometryDirectly(poSubGeom) != OGRERR_NONE) { //printf("%d %d\n", poColl->getGeometryType() & ~wkb25DBit, poSubGeom->getGeometryType() & ~wkb25DBit); delete poSubGeom; } } pabyGeom += nSubBytes; nBytes -= nSubBytes; } *ppoGeom = poColl; return OGRERR_NONE; } else { CPLDebug("GEOMEDIA", "Unhandled type %d", nGeomType); } return OGRERR_FAILURE; }
OGRFeature *OGRSOSILayer::GetNextFeature() { short nName, nNumLines; long nNumCoo; unsigned short nInfo; /* iterate through the SOSI groups*/ while (LC_NextBgr(poNextSerial,LC_FRAMGR)) { nName = LC_RxGr(&oNextSerial, LES_OPTIMALT, &nNumLines, &nNumCoo, &nInfo); S2S oHeaders; S2S::iterator iHeaders; /* extract reference strings from group header */ CPLString osKey, osValue; for (short i=1; i<=nNumLines; i++) { char *pszLine = LC_GetGi(i); if (pszLine[0] == '!') continue; /* If we have a comment line, skip it. */ if ((pszLine[0] == ':')||(pszLine[0] == '(')) { /* if we have a continued REF line... */ osValue.append(CPLString(pszLine)); /* append to previous line. */ oHeaders.insert(std::pair<CPLString,CPLString>(osKey,osValue)); continue; } while (pszLine[0] == '.') pszLine++; /* skipping the dots at the beginning of a SOSI line */ char *pszUTFLine = CPLRecode(pszLine, poParent->pszEncoding, CPL_ENC_UTF8); /* switch to UTF encoding here */ char *pszPos = strstr(pszUTFLine, " "); if (pszPos != NULL) { osKey = CPLString(std::string(pszUTFLine,pszPos)); osValue = CPLString(pszPos+1); oHeaders.insert(std::pair<CPLString,CPLString>(osKey,osValue)); } CPLFree(pszUTFLine); } /* get Feature from fyba, according to feature definition */ OGRGeometry *poGeom = NULL; OGRwkbGeometryType oGType = wkbUnknown; switch (nName) { case INGEN_GRUPPE: { /* No group */ CPLDebug( "[GetNextFeature]", "Could not load further groups - FYBA reported INGEN_GRUPPE."); break; } case L_FLATE: { /* Area */ oGType = wkbPolygon; OGRLinearRing *poOuter = new OGRLinearRing(); /* Initialize a new closed polygon */ long nRefNr; unsigned char nRefStatus; long nRefCount; bool correct = true; LC_GRF_STATUS oGrfStat; // Iterate through all objects that constitute this area. LC_InitGetRefFlate(&oGrfStat); nRefCount = LC_GetRefFlate(&oGrfStat, GRF_YTRE, &nRefNr, &nRefStatus, 1); while (nRefCount > 0) { if (poParent->papoBuiltGeometries[nRefNr] == NULL) { // This should not happen under normal operation. CPLError( CE_Warning, CPLE_AppDefined, "Feature %li referenced by %li, but it was not initialized. Geometry may be broken.", nRefNr, oNextSerial.lNr); correct = false; //return NULL; break; } OGRGeometry *geom = poParent->papoBuiltGeometries[nRefNr]; if (geom->getGeometryType() == wkbLineString) { OGRLineString *poCurve = (OGRLineString*)geom; if (nRefStatus == LC_MED_DIG) { /* clockwise */ poOuter->addSubLineString(poCurve); } else if (nRefStatus == LC_MOT_DIG) { /* counter-clockwise */ poOuter->addSubLineString(poCurve,poCurve->getNumPoints()-1,0); } else { CPLError( CE_Failure, CPLE_OpenFailed, "Internal error: GRF_*_OY encountered."); return NULL; } } else { CPLError( CE_Warning, CPLE_AppDefined, "Element %li composed of non-linestrings (REF %li of type %i). Ignored.", oNextSerial.lNr, nRefNr, geom->getGeometryType()); } nRefCount = LC_GetRefFlate(&oGrfStat, GRF_YTRE, &nRefNr, &nRefStatus, 1); } if (correct) { OGRPolygon *poLy = new OGRPolygon(); poOuter->closeRings(); poLy->addRingDirectly(poOuter); OGRLinearRing *poInner = 0; nRefCount = LC_GetRefFlate(&oGrfStat, GRF_INDRE, &nRefNr, &nRefStatus, 1); while (nRefCount > 0) { if (nRefNr == -1) { if (poInner && (poInner->getNumPoints()>2)) { /* If this is not the first polygon, terminate and add the last */ poInner->closeRings(); poLy->addRingDirectly(poInner); } poInner = new OGRLinearRing(); /* Initialize a new closed polygon */ } else { if (poParent->papoBuiltGeometries[nRefNr] == NULL) { /* this shouldn't happen under normal operation */ CPLError( CE_Fatal, CPLE_AppDefined, "Feature %li referenced by %li, but it was not initialized.", nRefNr, oNextSerial.lNr); return NULL; } OGRGeometry *geom = poParent->papoBuiltGeometries[nRefNr]; if (geom->getGeometryType() == wkbLineString) { OGRLineString *poCurve = (OGRLineString*)geom; if (nRefStatus == LC_MED_DIG) { /* clockwise */ poInner->addSubLineString(poCurve); } else if (nRefStatus == LC_MOT_DIG) { /* counter-clockwise */ poInner->addSubLineString(poCurve,poCurve->getNumPoints()-1,0); } else { CPLError( CE_Failure, CPLE_OpenFailed, "Internal error: GRF_*_OY encountered."); return NULL; } } else { CPLError( CE_Warning, CPLE_AppDefined, "Element %li composed of non-linestrings (REF %li of type %i). Ignored.", oNextSerial.lNr, nRefNr, geom->getGeometryType()); } } nRefCount = LC_GetRefFlate(&oGrfStat, GRF_INDRE, &nRefNr, &nRefStatus, 1); } poGeom = poLy; } break; } case L_KURVE: /* curve */ case L_LINJE: /* curve, not simplifyable */ case L_BUEP: { /* curve, interpolated from circular arc */ oGType = wkbLineString; OGRLineString *poCurve = (OGRLineString*)(poParent->papoBuiltGeometries[oNextSerial.lNr]); if (poCurve == NULL) { CPLError( CE_Fatal, CPLE_AppDefined, "Curve %li was not initialized.", oNextSerial.lNr); return NULL; } poGeom = poCurve->clone(); break; } case L_TEKST: { /* text */ oGType = wkbMultiPoint; OGRMultiPoint *poMP = (OGRMultiPoint*)(poParent->papoBuiltGeometries[oNextSerial.lNr]); if (poMP == NULL) { CPLError( CE_Fatal, CPLE_AppDefined, "Tekst %li was not initialized.", oNextSerial.lNr); return NULL; } poGeom = poMP->clone(); break; } case L_SYMBOL: { //CPLError( CE_Warning, CPLE_OpenFailed, "Geometry of type SYMBOL treated as point (PUNKT)."); } case L_PUNKT: { /* point */ oGType = wkbPoint; OGRPoint *poPoint = (OGRPoint*)(poParent->papoBuiltGeometries[oNextSerial.lNr]); if (poPoint == NULL) { CPLError( CE_Fatal, CPLE_AppDefined, "Point %li was not initialized.", oNextSerial.lNr); return NULL; } poGeom = poPoint->clone(); break; } case L_DEF: /* skip user definitions and headers here */ case L_HODE: { break; } default: { /* complain a bit about anything else that is not implemented */ CPLError( CE_Failure, CPLE_OpenFailed, "Unrecognized geometry of type %i.", nName); break; } } if (poGeom == NULL) continue; /* skipping L_HODE and unrecognized groups */ if (oGType != poFeatureDefn->GetGeomType()) { if (poGeom != NULL) delete poGeom; continue; /* skipping features that are not the correct geometry */ } OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); /* set all headers found in this group - we export everything, just in case */ for (iHeaders = oHeaders.begin(); iHeaders != oHeaders.end(); iHeaders++) { OGRSOSIDataType *poType = SOSIGetType(iHeaders->first); OGRSOSISimpleDataType *poElements = poType->getElements(); const char *pszLine = iHeaders->second.c_str(); char** tokens = CSLTokenizeString(iHeaders->second.c_str()); for (int k=0; k<poType->getElementCount(); k++) { if (tokens[k] == 0) break; if (strcmp(poElements[k].GetName(),"")==0) continue; int iHNr = poHeaderDefn->find(poElements[k].GetName())->second; if (iHNr == -1) { CPLError( CE_Warning, CPLE_AppDefined, "Could not find field definition for %s.", poElements[k].GetName()); continue; } OGRFieldType nType = poElements[k].GetType(); switch (nType) { case OFTInteger: { poFeature->SetField( iHNr, SOSITypeToInt(tokens[k])); break; } case OFTDate: { int date[3]; SOSITypeToDate(tokens[k], date); poFeature->SetField( iHNr, date[0], date[1], date[2]); break; } case OFTDateTime: { int date[6]; SOSITypeToDateTime(tokens[k], date); if (date[0]>0) poFeature->SetField( iHNr, date[0], date[1], date[2], date[3], date[4], static_cast<float>(date[5]), 1); break; } case OFTReal: { poFeature->SetField( iHNr, SOSITypeToReal(tokens[k])); break; } default: { if ((k==0)&&((pszLine[0] == '\'')||(pszLine[0] == '\"'))) { /* If the value is quoted, ignore these */ int nLen = static_cast<int>(strlen(pszLine)); char *pszNline = (char*)CPLMalloc(nLen-1); strncpy(pszNline, pszLine+1, nLen-2); pszNline[nLen-2] = '\0'; poFeature->SetField( iHNr, pszNline); CPLFree(pszNline); } else { poFeature->SetField( iHNr, tokens[k]); } break; } } } CSLDestroy(tokens); } if( poGeom != NULL ) poGeom->assignSpatialReference(poParent->poSRS); poFeature->SetGeometryDirectly( poGeom ); poFeature->SetFID( nNextFID++ ); /* Loop until we have a feature that matches the definition */ if ( (m_poFilterGeom == NULL || FilterGeometry( poFeature->GetGeometryRef() ) ) && (m_poAttrQuery == NULL || m_poAttrQuery->Evaluate( poFeature )) ) return poFeature; delete poFeature; } return NULL; }
OGRFeature *OGRARCGENLayer::GetNextRawFeature() { if (bEOF) return NULL; const char* pszLine; OGRwkbGeometryType eType = poFeatureDefn->GetGeomType(); if (wkbFlatten(eType) == wkbPoint) { while(TRUE) { pszLine = CPLReadLine2L(fp,256,NULL); if (pszLine == NULL || EQUAL(pszLine, "END")) { bEOF = TRUE; return NULL; } char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); if (nTokens == 3 || nTokens == 4) { OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID ++); poFeature->SetField(0, papszTokens[0]); if (nTokens == 3) poFeature->SetGeometryDirectly( new OGRPoint(CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2]))); else poFeature->SetGeometryDirectly( new OGRPoint(CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2]), CPLAtof(papszTokens[3]))); CSLDestroy(papszTokens); return poFeature; } else CSLDestroy(papszTokens); } } CPLString osID; OGRLinearRing* poLR = (wkbFlatten(eType) == wkbPolygon) ? new OGRLinearRing() : NULL; OGRLineString* poLS = (wkbFlatten(eType) == wkbLineString) ? new OGRLineString() : poLR; while(TRUE) { pszLine = CPLReadLine2L(fp,256,NULL); if (pszLine == NULL) break; if (EQUAL(pszLine, "END")) { if (osID.size() == 0) break; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID ++); poFeature->SetField(0, osID.c_str()); if (wkbFlatten(eType) == wkbPolygon) { OGRPolygon* poPoly = new OGRPolygon(); poPoly->addRingDirectly(poLR); poFeature->SetGeometryDirectly(poPoly); } else poFeature->SetGeometryDirectly(poLS); return poFeature; } char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); if (osID.size() == 0) { if (nTokens >= 1) osID = papszTokens[0]; else { CSLDestroy(papszTokens); break; } } else { if (nTokens == 2) { poLS->addPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1])); } else if (nTokens == 3) { poLS->addPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2])); } else { CSLDestroy(papszTokens); break; } } CSLDestroy(papszTokens); } bEOF = TRUE; delete poLS; return NULL; }
GDAL_GCP * PrepareGCP(const CPLString& sFileName, OGRPoint *pt1, OGRPoint *pt2, OGRPoint *pt3, OGRPoint *pt4, OGRPoint *ptCenter, const OGRSpatialReference &oDstOGRSpatialReference, const int nRasterSizeX, const int nRasterSizeY, int &nGCPCount, OGREnvelope &DstEnv) { // to meters double dfFocusM = dfFocus / 100; double dfFilmHalfHeightM = dfFilmHeight / 200; double dfRatio = dfFilmHalfHeightM / dfFocusM; //create center point and line of scene OGRPoint ptShortSideBeg = GetCenterOfLine(pt1, pt4); OGRPoint ptShortSideEnd = GetCenterOfLine(pt2, pt3); OGRLineString lnTmp; lnTmp.addPoint(&ptShortSideBeg); lnTmp.addPoint(&ptShortSideEnd); lnTmp.Value(lnTmp.Project(pt1), &ptShortSideBeg); lnTmp.Value(lnTmp.Project(pt2), &ptShortSideEnd); double dfDist1 = pt1->Distance(pt2); double dfDist2 = pt2->Distance(pt3); double dfDist3 = pt3->Distance(pt4); double dfDist4 = pt4->Distance(pt1); double dfHalfWidth = (dfDist2 + dfDist4) / 4; double dfHalfHeight = (dfDist1 + dfDist3) / 4; double dfAltitudeAtSide = (dfHalfWidth * dfFocusM) / dfFilmHalfHeightM; double dfAltitudeAtSceneCenter = sqrt( dfAltitudeAtSide * dfAltitudeAtSide - dfHalfHeight * dfHalfHeight); double dfAltitude = dfAltitudeAtSceneCenter * cos(dfMountAngleRad); // 145 - 220 km double dfDistCenter = dfAltitudeAtSceneCenter * sin(dfMountAngleRad); OGRLineString lnCenterLeft; lnCenterLeft.addPoint(&ptShortSideBeg); lnCenterLeft.addPoint(ptCenter); OGRPoint ptSatCenter = GetTangetPoint(lnCenterLeft, dfDistCenter); std::vector<OGRPoint> aPt1, aPt2; int nTotalGCPCount = ((SEGMENT_STEPS + 1) * 2); GDAL_GCP *paGSPs = (GDAL_GCP *) CPLMalloc (nTotalGCPCount * sizeof(GDAL_GCP)); GDALInitGCPs(nTotalGCPCount, paGSPs); double dfImageStepLen = double(nRasterSizeX) / SEGMENT_STEPS; double dfImageCenterX = 0; OGRLineString lnCenter; lnCenter.addPoint(&ptShortSideBeg); lnCenter.addPoint(ptCenter); lnCenter.addPoint(&ptShortSideEnd); double dfCenterLineLen = lnCenter.get_Length(); double dfStepLen = dfCenterLineLen / SEGMENT_STEPS; double dfCenterLineHalfLen = dfCenterLineLen / 2; for(double i = 0; i <= dfCenterLineLen; i += dfStepLen) { OGRPoint ptTmp; lnCenter.Value(i, &ptTmp); double dfDist = fabs(dfCenterLineHalfLen - i); double dfWidthTmp = GetWidthForHeight(dfAltitudeAtSceneCenter, dfDist, dfRatio); OGRLineString lnTmpLine; lnTmpLine.addPoint(ptCenter); lnTmpLine.addPoint(&ptTmp); int direction = 1; if(dfCenterLineHalfLen < i) direction = -1; OGRPoint ptUp = GetTangetPoint(lnTmpLine, dfWidthTmp * direction); OGRPoint ptDown = GetTangetPoint(lnTmpLine, -dfWidthTmp * direction); //OGRPoint ptUp = GetValue(dfWidthTmp, lnTmpLine); //OGRPoint ptDown = GetValue(-dfWidthTmp, lnTmpLine); aPt1.push_back(ptUp); aPt2.push_back(ptDown); paGSPs[nGCPCount].dfGCPLine = 0; paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX; paGSPs[nGCPCount].dfGCPX = ptDown.getX(); paGSPs[nGCPCount].dfGCPY = ptDown.getY(); paGSPs[nGCPCount].dfGCPZ = dfMeanHeight; paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount)); nGCPCount++; paGSPs[nGCPCount].dfGCPLine = nRasterSizeY; paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX; paGSPs[nGCPCount].dfGCPX = ptUp.getX(); paGSPs[nGCPCount].dfGCPY = ptUp.getY(); paGSPs[nGCPCount].dfGCPZ = dfMeanHeight; paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount)); nGCPCount++; dfImageCenterX += dfImageStepLen; } // add points to polygon OGRLinearRing Ring; for(int i = 0; i < aPt1.size(); ++i) Ring.addPoint(aPt1[i].getX(), aPt1[i].getY()); for(int i = aPt2.size() - 1; i >= 0; --i) Ring.addPoint(aPt2[i].getX(), aPt2[i].getY()); Ring.closeRings(); OGRPolygon Rgn; Rgn.addRingDirectly((OGRCurve*)Ring.clone()); Rgn.assignSpatialReference(oDstOGRSpatialReference.Clone()); Rgn.flattenTo2D(); Rgn.getEnvelope(&DstEnv); SaveGeometry(CPLResetExtension(sFileName, "shp"), Rgn, oDstOGRSpatialReference); return paGSPs; }
OGRFeature *OGRIdrisiLayer::GetNextRawFeature() { while(TRUE) { if (eGeomType == wkbPoint) { double dfId; double dfX, dfY; if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfX, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfY, sizeof(double), 1, fp) != 1) { return NULL; } CPL_LSBPTR64(&dfId); CPL_LSBPTR64(&dfX); CPL_LSBPTR64(&dfY); if (m_poFilterGeom != NULL && (dfX < m_sFilterEnvelope.MinX || dfX > m_sFilterEnvelope.MaxX || dfY < m_sFilterEnvelope.MinY || dfY > m_sFilterEnvelope.MaxY)) { nNextFID ++; continue; } OGRPoint* poGeom = new OGRPoint(dfX, dfY); if (poSRS) poGeom->assignSpatialReference(poSRS); OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, dfId); poFeature->SetFID(nNextFID ++); poFeature->SetGeometryDirectly(poGeom); ReadAVLLine(poFeature); return poFeature; } else if (eGeomType == wkbLineString) { double dfId; double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape; unsigned int nNodes; if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1) { return NULL; } CPL_LSBPTR64(&dfId); CPL_LSBPTR64(&dfMinXShape); CPL_LSBPTR64(&dfMaxXShape); CPL_LSBPTR64(&dfMinYShape); CPL_LSBPTR64(&dfMaxYShape); if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1) { return NULL; } CPL_LSBPTR32(&nNodes); if (nNodes > 100 * 1000 * 1000) return NULL; if (m_poFilterGeom != NULL && (dfMaxXShape < m_sFilterEnvelope.MinX || dfMinXShape > m_sFilterEnvelope.MaxX || dfMaxYShape < m_sFilterEnvelope.MinY || dfMinYShape > m_sFilterEnvelope.MaxY)) { nNextFID ++; VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR); continue; } OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nNodes); if (poRawPoints == NULL) { return NULL; } if ((unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes) { VSIFree(poRawPoints); return NULL; } #if defined(CPL_MSB) for(unsigned int iNode=0; iNode<nNodes; iNode++) { CPL_LSBPTR64(&poRawPoints[iNode].x); CPL_LSBPTR64(&poRawPoints[iNode].y); } #endif OGRLineString* poGeom = new OGRLineString(); poGeom->setPoints(nNodes, poRawPoints, NULL); VSIFree(poRawPoints); if (poSRS) poGeom->assignSpatialReference(poSRS); OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, dfId); poFeature->SetFID(nNextFID ++); poFeature->SetGeometryDirectly(poGeom); ReadAVLLine(poFeature); return poFeature; } else /* if (eGeomType == wkbPolygon) */ { double dfId; double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape; unsigned int nParts; unsigned int nTotalNodes; if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 || VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1) { return NULL; } CPL_LSBPTR64(&dfId); CPL_LSBPTR64(&dfMinXShape); CPL_LSBPTR64(&dfMaxXShape); CPL_LSBPTR64(&dfMinYShape); CPL_LSBPTR64(&dfMaxYShape); if (VSIFReadL(&nParts, sizeof(unsigned int), 1, fp) != 1 || VSIFReadL(&nTotalNodes, sizeof(unsigned int), 1, fp) != 1) { return NULL; } CPL_LSBPTR32(&nParts); CPL_LSBPTR32(&nTotalNodes); if (nParts > 100000 || nTotalNodes > 100 * 1000 * 1000) return NULL; if (m_poFilterGeom != NULL && (dfMaxXShape < m_sFilterEnvelope.MinX || dfMinXShape > m_sFilterEnvelope.MaxX || dfMaxYShape < m_sFilterEnvelope.MinY || dfMinYShape > m_sFilterEnvelope.MaxY)) { VSIFSeekL(fp, sizeof(unsigned int) * nParts + sizeof(OGRRawPoint) * nTotalNodes, SEEK_CUR); nNextFID ++; continue; } OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nTotalNodes); if (poRawPoints == NULL) { return NULL; } unsigned int* panNodesCount = NULL; if( nParts > 1 ) { panNodesCount = (unsigned int *)CPLMalloc(sizeof(unsigned int) * nParts); if (VSIFReadL(panNodesCount, sizeof(unsigned int) * nParts, 1, fp) != 1) { VSIFree(poRawPoints); VSIFree(panNodesCount); return NULL; } #if defined(CPL_MSB) for(unsigned int iPart=0; iPart < nParts; iPart ++) { CPL_LSBPTR32(&panNodesCount[iPart]); } #endif } else { unsigned int nNodes; if (VSIFReadL(&nNodes, sizeof(unsigned int) * nParts, 1, fp) != 1) { VSIFree(poRawPoints); return NULL; } CPL_LSBPTR32(&nNodes); if( nNodes != nTotalNodes ) { VSIFree(poRawPoints); return NULL; } } unsigned int iPart; OGRPolygon* poGeom = new OGRPolygon(); for(iPart = 0; iPart < nParts; iPart ++) { unsigned int nNodes = (nParts > 1) ? panNodesCount[iPart] : nTotalNodes; if (nNodes > nTotalNodes || (unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes) { VSIFree(poRawPoints); VSIFree(panNodesCount); delete poGeom; return NULL; } #if defined(CPL_MSB) for(unsigned int iNode=0; iNode<nNodes; iNode++) { CPL_LSBPTR64(&poRawPoints[iNode].x); CPL_LSBPTR64(&poRawPoints[iNode].y); } #endif OGRLinearRing* poLR = new OGRLinearRing(); poGeom->addRingDirectly(poLR); poLR->setPoints(nNodes, poRawPoints, NULL); } VSIFree(poRawPoints); VSIFree(panNodesCount); if (poSRS) poGeom->assignSpatialReference(poSRS); OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, dfId); poFeature->SetFID(nNextFID ++); poFeature->SetGeometryDirectly(poGeom); ReadAVLLine(poFeature); return poFeature; } } }
static OGRGeometry *GML2OGRGeometry_XMLNode( CPLXMLNode *psNode ) { const char *pszBaseGeometry = BareGMLElement( psNode->pszValue ); /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"Polygon") ) { CPLXMLNode *psChild; OGRPolygon *poPolygon = new OGRPolygon(); OGRLinearRing *poRing; // Find outer ring. psChild = FindBareXMLChild( psNode, "outerBoundaryIs" ); if( psChild == NULL || psChild->psChild == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing outerBoundaryIs property on Polygon." ); delete poPolygon; return NULL; } // Translate outer ring and add to polygon. poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poRing == NULL ) { delete poPolygon; return NULL; } if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as outerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"innerBoundaryIs") ) { poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as innerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); } } return poPolygon; } /* -------------------------------------------------------------------- */ /* LinearRing */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LinearRing") ) { OGRLinearRing *poLinearRing = new OGRLinearRing(); if( !ParseGMLCoordinates( psNode, poLinearRing ) ) { delete poLinearRing; return NULL; } return poLinearRing; } /* -------------------------------------------------------------------- */ /* LineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LineString") ) { OGRLineString *poLine = new OGRLineString(); if( !ParseGMLCoordinates( psNode, poLine ) ) { delete poLine; return NULL; } return poLine; } /* -------------------------------------------------------------------- */ /* PointType */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"PointType") || EQUAL(pszBaseGeometry,"Point") ) { OGRPoint *poPoint = new OGRPoint(); if( !ParseGMLCoordinates( psNode, poPoint ) ) { delete poPoint; return NULL; } return poPoint; } /* -------------------------------------------------------------------- */ /* Box */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"BoxType") || EQUAL(pszBaseGeometry,"Box") ) { OGRLineString oPoints; if( !ParseGMLCoordinates( psNode, &oPoints ) ) return NULL; if( oPoints.getNumPoints() < 2 ) return NULL; OGRLinearRing *poBoxRing = new OGRLinearRing(); OGRPolygon *poBoxPoly = new OGRPolygon(); poBoxRing->setNumPoints( 5 ); poBoxRing->setPoint( 0, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 1, oPoints.getX(1), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 2, oPoints.getX(1), oPoints.getY(1), oPoints.getZ(1) ); poBoxRing->setPoint( 3, oPoints.getX(0), oPoints.getY(1), oPoints.getZ(0) ); poBoxRing->setPoint( 4, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxPoly->addRingDirectly( poBoxRing ); return poBoxPoly; } /* -------------------------------------------------------------------- */ /* MultiPolygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPolygon") ) { CPLXMLNode *psChild; OGRMultiPolygon *poMPoly = new OGRMultiPolygon(); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"polygonMember") ) { OGRPolygon *poPolygon; poPolygon = (OGRPolygon *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPolygon == NULL ) { delete poMPoly; return NULL; } if( !EQUAL(poPolygon->getGeometryName(),"POLYGON") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as polygonMember instead of MULTIPOLYGON.", poPolygon->getGeometryName() ); delete poPolygon; delete poMPoly; return NULL; } poMPoly->addGeometryDirectly( poPolygon ); } } return poMPoly; } /* -------------------------------------------------------------------- */ /* MultiPoint */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPoint") ) { CPLXMLNode *psChild; OGRMultiPoint *poMP = new OGRMultiPoint(); // collect points. for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"pointMember") ) { OGRPoint *poPoint; poPoint = (OGRPoint *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPoint == NULL || wkbFlatten(poPoint->getGeometryType()) != wkbPoint ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as pointMember instead of MULTIPOINT", poPoint ? poPoint->getGeometryName() : "NULL" ); delete poPoint; delete poMP; return NULL; } poMP->addGeometryDirectly( poPoint ); } } return poMP; } /* -------------------------------------------------------------------- */ /* MultiLineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiLineString") ) { CPLXMLNode *psChild; OGRMultiLineString *poMP = new OGRMultiLineString(); // collect lines for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"lineStringMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL || wkbFlatten(poGeom->getGeometryType()) != wkbLineString ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as Member instead of LINESTRING.", poGeom ? poGeom->getGeometryName() : "NULL" ); delete poGeom; delete poMP; return NULL; } poMP->addGeometryDirectly( poGeom ); } } return poMP; } /* -------------------------------------------------------------------- */ /* GeometryCollection */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"GeometryCollection") ) { CPLXMLNode *psChild; OGRGeometryCollection *poGC = new OGRGeometryCollection(); // collect geoms for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"geometryMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to get geometry in geometryMember" ); delete poGeom; delete poGC; return NULL; } poGC->addGeometryDirectly( poGeom ); } } return poGC; } CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised geometry type <%.500s>.", pszBaseGeometry ); return NULL; }
OGRFeature *OGRARCGENLayer::GetNextRawFeature() { if (bEOF) return nullptr; OGRwkbGeometryType eType = poFeatureDefn->GetGeomType(); if (wkbFlatten(eType) == wkbPoint) { while( true ) { const char* pszLine = CPLReadLine2L(fp,256,nullptr); if (pszLine == nullptr || EQUAL(pszLine, "END")) { bEOF = true; return nullptr; } char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); if (nTokens == 3 || nTokens == 4) { OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID ++); poFeature->SetField(0, papszTokens[0]); if (nTokens == 3) poFeature->SetGeometryDirectly( new OGRPoint(CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2]))); else poFeature->SetGeometryDirectly( new OGRPoint(CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2]), CPLAtof(papszTokens[3]))); CSLDestroy(papszTokens); return poFeature; } CSLDestroy(papszTokens); } } CPLString osID; const bool bIsPoly = (wkbFlatten(eType) == wkbPolygon); OGRwkbGeometryType eRingType = (bIsPoly) ? wkbLinearRing : wkbLineString; OGRLineString* poLS = OGRGeometryFactory::createGeometry(eRingType)->toLineString(); while( true ) { const char* pszLine = CPLReadLine2L(fp,256,nullptr); if (pszLine == nullptr) break; if (EQUAL(pszLine, "END")) { if (osID.empty()) break; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID ++); poFeature->SetField(0, osID.c_str()); if( bIsPoly ) { OGRPolygon* poPoly = new OGRPolygon(); poPoly->addRingDirectly(poLS->toLinearRing()); poFeature->SetGeometryDirectly(poPoly); } else poFeature->SetGeometryDirectly(poLS); return poFeature; } char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); if (osID.empty()) { if (nTokens >= 1) osID = papszTokens[0]; else { CSLDestroy(papszTokens); break; } } else { if (nTokens == 2) { poLS->addPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1])); } else if (nTokens == 3) { poLS->addPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2])); } else { CSLDestroy(papszTokens); break; } } CSLDestroy(papszTokens); } bEOF = true; delete poLS; return nullptr; }
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; }
OGRGeometry * cvct2gdal::CVCT2GDALGeometry ( VCTGeometry & oVCTGeometry ) { OGRGeometry * poOGRGeometry = NULL; Geometry * poGeometry = NULL; if ( oVCTGeometry.geotype == GT_POINT ) { PointParser oParser ( poVCTFile, poVCTDataSource ); poGeometry = oParser.Parse ( oVCTGeometry ); Geometry & cGeometry = *poGeometry; OGRGeometry * poPoint = new OGRPoint (cGeometry[0]->operator[](0).X, cGeometry[0]->operator[](0).Y); poOGRGeometry = poPoint; } else if ( oVCTGeometry.geotype == GT_LINE ) { LineParser oParser ( poVCTFile, poVCTDataSource ); poGeometry = oParser.Parse ( oVCTGeometry ); Geometry & cGeometry = *poGeometry; OGRLineString * poLine = new OGRLineString(); for ( auto iter = cGeometry[0]->begin(); iter != cGeometry[0]->end(); ++iter ) { poLine->addPoint ( iter->X, iter->Y ); } poOGRGeometry = poLine; } else if ( oVCTGeometry.geotype == GT_POLYGON ) { PolyParser oParser ( poVCTFile, poVCTDataSource ); poGeometry = oParser.Parse ( oVCTGeometry ); Geometry & cGeometry = *poGeometry; int nParts = cGeometry.size(); if (nParts == 1) { OGRPolygon * poOGRPoly = NULL; OGRLinearRing * poRing = NULL; poOGRGeometry = poOGRPoly = new OGRPolygon(); poRing = CreateLinearRing(*cGeometry[0]); poOGRPoly->addRingDirectly(poRing); } else { OGRPolygon ** tabPolygons = new OGRPolygon*[nParts]; for ( int iRing = 0; iRing != nParts; ++iRing ) { tabPolygons[iRing] = new OGRPolygon(); tabPolygons[iRing]->addRingDirectly ( CreateLinearRing ( *cGeometry[iRing] ) ); } int isValidGeometry; const char * papszOptions[] = { "METHOD=ONLY_CCW", NULL }; poOGRGeometry = OGRGeometryFactory::organizePolygons ( ( OGRGeometry ** ) tabPolygons, nParts, &isValidGeometry, papszOptions ); delete[] tabPolygons; } } DestroyGeometry(poGeometry); return poOGRGeometry; }
OGRErr OGRMultiPolygon::importFromWkt( char ** ppszInput ) { char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; OGRErr eErr = OGRERR_NONE; /* -------------------------------------------------------------------- */ /* Clear existing rings. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Read and verify the MULTIPOLYGON keyword token. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* The next character should be a ( indicating the start of the */ /* list of polygons. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszInput; return OGRERR_NONE; } if( szToken[0] != '(' ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* If the next token is EMPTY, then verify that we have proper */ /* EMPTY format will a trailing closing bracket. */ /* -------------------------------------------------------------------- */ OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszInput, szToken ); pszInput = OGRWktReadToken( pszInput, szToken ); *ppszInput = (char *) pszInput; if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else return OGRERR_NONE; } /* ==================================================================== */ /* Read each polygon in turn. Note that we try to reuse the same */ /* point list buffer from ring to ring to cut down on */ /* allocate/deallocate overhead. */ /* ==================================================================== */ OGRRawPoint *paoPoints = NULL; int nMaxPoints = 0; double *padfZ = NULL; do { OGRPolygon *poPolygon = new OGRPolygon(); /* -------------------------------------------------------------------- */ /* The next character should be a ( indicating the start of the */ /* list of polygons. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( szToken[0] != '(' ) { eErr = OGRERR_CORRUPT_DATA; delete poPolygon; break; } /* -------------------------------------------------------------------- */ /* Loop over each ring in this polygon. */ /* -------------------------------------------------------------------- */ do { int nPoints = 0; /* -------------------------------------------------------------------- */ /* Read points for one line from input. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoints, &nPoints ); if( pszInput == NULL ) { eErr = OGRERR_CORRUPT_DATA; break; } /* -------------------------------------------------------------------- */ /* Create the new line, and add to collection. */ /* -------------------------------------------------------------------- */ OGRLinearRing *poLine; poLine = new OGRLinearRing(); poLine->setPoints( nPoints, paoPoints, padfZ ); poPolygon->addRingDirectly( poLine ); /* -------------------------------------------------------------------- */ /* Read the delimeter following the ring. */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); } while( szToken[0] == ',' && eErr == OGRERR_NONE ); /* -------------------------------------------------------------------- */ /* Verify that we have a closing bracket. */ /* -------------------------------------------------------------------- */ if( eErr == OGRERR_NONE ) { if( szToken[0] != ')' ) eErr = OGRERR_CORRUPT_DATA; else pszInput = OGRWktReadToken( pszInput, szToken ); } /* -------------------------------------------------------------------- */ /* Add the polygon to the MULTIPOLYGON. */ /* -------------------------------------------------------------------- */ if( eErr == OGRERR_NONE ) eErr = addGeometryDirectly( poPolygon ); else delete poPolygon; } while( szToken[0] == ',' && eErr == OGRERR_NONE ); /* -------------------------------------------------------------------- */ /* freak if we don't get a closing bracket. */ /* -------------------------------------------------------------------- */ CPLFree( paoPoints ); CPLFree( padfZ ); if( eErr != OGRERR_NONE ) return eErr; if( szToken[0] != ')' ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE; }
OGRFeature *OGRDGNLayer::ElementToFeature( DGNElemCore *psElement ) { OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( psElement->element_id ); poFeature->SetField( "Type", psElement->type ); poFeature->SetField( "Level", psElement->level ); poFeature->SetField( "GraphicGroup", psElement->graphic_group ); poFeature->SetField( "ColorIndex", psElement->color ); poFeature->SetField( "Weight", psElement->weight ); poFeature->SetField( "Style", psElement->style ); m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Collect linkage information */ /* -------------------------------------------------------------------- */ #define MAX_LINK 100 int anEntityNum[MAX_LINK], anMSLink[MAX_LINK]; unsigned char *pabyData; int iLink=0, nLinkCount=0; anEntityNum[0] = 0; anMSLink[0] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+iLink, anMSLink+iLink, NULL ); while( pabyData && nLinkCount < MAX_LINK ) { iLink++; if( anEntityNum[nLinkCount] != 0 || anMSLink[nLinkCount] != 0 ) nLinkCount++; anEntityNum[nLinkCount] = 0; anMSLink[nLinkCount] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+nLinkCount, anMSLink+nLinkCount, NULL ); } /* -------------------------------------------------------------------- */ /* Apply attribute linkage to feature. */ /* -------------------------------------------------------------------- */ if( nLinkCount > 0 ) { if( EQUAL(pszLinkFormat,"FIRST") ) { poFeature->SetField( "EntityNum", anEntityNum[0] ); poFeature->SetField( "MSLink", anMSLink[0] ); } else if( EQUAL(pszLinkFormat,"LIST") ) { poFeature->SetField( "EntityNum", nLinkCount, anEntityNum ); poFeature->SetField( "MSLink", nLinkCount, anMSLink ); } else if( EQUAL(pszLinkFormat,"STRING") ) { char szEntityList[MAX_LINK*9], szMSLinkList[MAX_LINK*9]; int nEntityLen = 0, nMSLinkLen = 0; for( iLink = 0; iLink < nLinkCount; iLink++ ) { if( iLink != 0 ) { szEntityList[nEntityLen++] = ','; szMSLinkList[nMSLinkLen++] = ','; } sprintf( szEntityList + nEntityLen, "%d", anEntityNum[iLink]); sprintf( szMSLinkList + nMSLinkLen, "%d", anMSLink[iLink] ); nEntityLen += strlen(szEntityList + nEntityLen ); nMSLinkLen += strlen(szMSLinkList + nMSLinkLen ); } poFeature->SetField( "EntityNum", szEntityList ); poFeature->SetField( "MSLink", szMSLinkList ); } } /* -------------------------------------------------------------------- */ /* Lookup color. */ /* -------------------------------------------------------------------- */ char gv_color[128]; int gv_red, gv_green, gv_blue; char szFSColor[128], szPen[256]; szFSColor[0] = '\0'; if( DGNLookupColor( hDGN, psElement->color, &gv_red, &gv_green, &gv_blue ) ) { sprintf( gv_color, "%f %f %f 1.0", gv_red / 255.0, gv_green / 255.0, gv_blue / 255.0 ); sprintf( szFSColor, "c:#%02x%02x%02x", gv_red, gv_green, gv_blue ); } /* -------------------------------------------------------------------- */ /* Generate corresponding PEN style. */ /* -------------------------------------------------------------------- */ if( psElement->style == DGNS_SOLID ) sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); else if( psElement->style == DGNS_DOTTED ) sprintf( szPen, "PEN(id:\"ogr-pen-5\"" ); else if( psElement->style == DGNS_MEDIUM_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-2\"" ); else if( psElement->style == DGNS_LONG_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-4\"" ); else if( psElement->style == DGNS_DOT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-6\"" ); else if( psElement->style == DGNS_SHORT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-3\"" ); else if( psElement->style == DGNS_DASH_DOUBLE_DOT ) sprintf( szPen, "PEN(id:\"ogr-pen-7\"" ); else if( psElement->style == DGNS_LONG_DASH_SHORT_DASH ) sprintf( szPen, "PEN(p:\"10px 5px 4px 5px\"" ); else sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); if( strlen(szFSColor) > 0 ) sprintf( szPen+strlen(szPen), ",%s", szFSColor ); if( psElement->weight > 1 ) sprintf( szPen+strlen(szPen), ",w:%dpx", psElement->weight ); strcat( szPen, ")" ); switch( psElement->stype ) { case DGNST_MULTIPOINT: if( psElement->type == DGNT_SHAPE ) { OGRLinearRing *poLine = new OGRLinearRing(); OGRPolygon *poPolygon = new OGRPolygon(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poPolygon->addRingDirectly( poLine ); poFeature->SetGeometryDirectly( poPolygon ); ConsiderBrush( psElement, szPen, poFeature ); } else if( psElement->type == DGNT_CURVE ) { DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; OGRLineString *poLine = new OGRLineString(); DGNPoint *pasPoints; int nPoints; nPoints = 5 * psEMP->num_vertices; pasPoints = (DGNPoint *) CPLMalloc(sizeof(DGNPoint) * nPoints); DGNStrokeCurve( hDGN, psEMP, nPoints, pasPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, pasPoints[i].x, pasPoints[i].y, pasPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); CPLFree( pasPoints ); poFeature->SetStyleString( szPen ); } else { OGRLineString *poLine = new OGRLineString(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; if( psEMP->num_vertices > 0 ) { poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poFeature->SetGeometryDirectly( poLine ); } poFeature->SetStyleString( szPen ); } break; case DGNST_ARC: { OGRLineString *poLine = new OGRLineString(); DGNElemArc *psArc = (DGNElemArc *) psElement; DGNPoint asPoints[90]; int nPoints; nPoints = (int) (MAX(1,ABS(psArc->sweepang) / 5) + 1); DGNStrokeArc( hDGN, psArc, nPoints, asPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, asPoints[i].x, asPoints[i].y, asPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); poFeature->SetStyleString( szPen ); } break; case DGNST_TEXT: { OGRPoint *poPoint = new OGRPoint(); DGNElemText *psText = (DGNElemText *) psElement; char *pszOgrFS; poPoint->setX( psText->origin.x ); poPoint->setY( psText->origin.y ); poPoint->setZ( psText->origin.z ); poFeature->SetGeometryDirectly( poPoint ); pszOgrFS = (char *) CPLMalloc(strlen(psText->string) + 150); // setup the basic label. sprintf( pszOgrFS, "LABEL(t:\"%s\"", psText->string ); // set the color if we have it. if( strlen(szFSColor) > 0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",%s", szFSColor ); // Add the size info in ground units. if( ABS(psText->height_mult) >= 6.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%dg", (int) psText->height_mult ); else if( ABS(psText->height_mult) > 0.1 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.3fg", psText->height_mult ); else sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.12fg", psText->height_mult ); // Add the font name. Name it MstnFont<FONTNUMBER> if not available // in the font list. #3392 static const char *papszFontList[] = { "STANDARD", "WORKING", "FANCY", "ENGINEERING", "NEWZERO", "STENCEL", //0-5 "USTN_FANCY", "COMPRESSED", "STENCEQ", NULL, "hand", "ARCH", //6-11 "ARCHB", NULL, NULL, "IGES1001", "IGES1002", "IGES1003", //12-17 "CENTB", "MICROS", NULL, NULL, "ISOFRACTIONS", "ITALICS", //18-23 "ISO30", NULL, "GREEK", "ISOREC", "Isoeq", NULL, //24-29 "ISO_FONTLEFT", "ISO_FONTRIGHT", "INTL_ENGINEERING", "INTL_WORKING", "ISOITEQ", NULL, //30-35 "USTN FONT 26", NULL, NULL, NULL, NULL, "ARCHITECTURAL", //36-41 "BLOCK_OUTLINE", "LOW_RES_FILLED", NULL, NULL, NULL, NULL, //42-47 NULL, NULL, "UPPERCASE", NULL, NULL, NULL, //48-53 NULL, NULL, NULL, NULL, NULL, NULL, //54-49 "FONT060", "din", "dinit", "helvl", "HELVLIT", "helv", //60-65 "HELVIT", "cent", "CENTIT", "SCRIPT", NULL, NULL, //66-71 NULL, NULL, NULL, NULL, "MICROQ", "dotfont", //72-77 "DOTIT", NULL, NULL, NULL, NULL, NULL, //78-83 NULL, NULL, NULL, NULL, NULL, NULL, //84-89 NULL, NULL, "FONT092", NULL, "FONT094", NULL, //90-95 NULL, NULL, NULL, NULL, "ANSI_SYMBOLS", "FEATURE_CONTROL_SYSMBOLS", //96-101 "SYMB_FAST", NULL, NULL, "INTL_ISO", "INTL_ISO_EQUAL", "INTL_ISO_ITALIC", //102-107 "INTL_ISO_ITALIC_EQUAL" }; //108 if(psText->font_id <= 108 && papszFontList[psText->font_id] != NULL ) { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:%s", papszFontList[psText->font_id] ); } else { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:MstnFont%d", psText->font_id ); } // Add the angle, if not horizontal if( psText->rotation != 0.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",a:%d", (int) (psText->rotation+0.5) ); strcat( pszOgrFS, ")" ); poFeature->SetStyleString( pszOgrFS ); CPLFree( pszOgrFS ); poFeature->SetField( "Text", psText->string ); } break; case DGNST_COMPLEX_HEADER: { DGNElemComplexHeader *psHdr = (DGNElemComplexHeader *) psElement; int iChild; OGRMultiLineString oChildren; /* collect subsequent child geometries. */ // we should disable the spatial filter ... add later. for( iChild = 0; iChild < psHdr->numelems; iChild++ ) { OGRFeature *poChildFeature = NULL; DGNElemCore *psChildElement; psChildElement = DGNReadElement( hDGN ); // should verify complex bit set, not another header. if( psChildElement != NULL ) { poChildFeature = ElementToFeature( psChildElement ); DGNFreeElement( hDGN, psChildElement ); } if( poChildFeature != NULL && poChildFeature->GetGeometryRef() != NULL ) { OGRGeometry *poGeom; poGeom = poChildFeature->GetGeometryRef(); if( wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) oChildren.addGeometry( poGeom ); } if( poChildFeature != NULL ) delete poChildFeature; } // Try to assemble into polygon geometry. OGRGeometry *poGeom; if( psElement->type == DGNT_COMPLEX_SHAPE_HEADER ) poGeom = (OGRPolygon *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oChildren, TRUE, TRUE, 100000, NULL ); else poGeom = oChildren.clone(); if( poGeom != NULL ) poFeature->SetGeometryDirectly( poGeom ); ConsiderBrush( psElement, szPen, poFeature ); } break; default: break; } /* -------------------------------------------------------------------- */ /* Fixup geometry dimension. */ /* -------------------------------------------------------------------- */ if( poFeature->GetGeometryRef() != NULL ) poFeature->GetGeometryRef()->setCoordinateDimension( DGNGetDimension( hDGN ) ); return poFeature; }
OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat ) { CPLDebug ( "GRASS", "OGRGRASSLayer::GetFeatureGeometry nFeatureId = %d", nFeatureId ); int cidx = paFeatureIndex[(int)nFeatureId]; int type, id; Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, cat, &type, &id ); //CPLDebug ( "GRASS", "cat = %d type = %d id = %d", *cat, type, id ); OGRGeometry *poOGR = NULL; int bIs3D = Vect_is_3d(poMap); switch ( type ) { case GV_POINT: { Vect_read_line ( poMap, poPoints, poCats, id); if (bIs3D) poOGR = new OGRPoint( poPoints->x[0], poPoints->y[0], poPoints->z[0] ); else poOGR = new OGRPoint( poPoints->x[0], poPoints->y[0] ); } break; case GV_LINE: case GV_BOUNDARY: { Vect_read_line ( poMap, poPoints, poCats, id); OGRLineString *poOGRLine = new OGRLineString(); if (bIs3D) poOGRLine->setPoints( poPoints->n_points, poPoints->x, poPoints->y, poPoints->z ); else poOGRLine->setPoints( poPoints->n_points, poPoints->x, poPoints->y ); poOGR = poOGRLine; } break; case GV_AREA: { Vect_get_area_points ( poMap, id, poPoints ); OGRPolygon *poOGRPoly; poOGRPoly = new OGRPolygon(); OGRLinearRing *poRing; poRing = new OGRLinearRing(); if (bIs3D) poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y, poPoints->z ); else poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y ); poOGRPoly->addRingDirectly( poRing ); // Islands int nisles = Vect_get_area_num_isles ( poMap, id ); for ( int i = 0; i < nisles; i++ ) { int isle = Vect_get_area_isle ( poMap, id, i ); Vect_get_isle_points ( poMap, isle, poPoints ); poRing = new OGRLinearRing(); if (bIs3D) poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y, poPoints->z ); else poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y ); poOGRPoly->addRingDirectly( poRing ); } poOGR = poOGRPoly; } break; default: // Should not happen { CPLError( CE_Failure, CPLE_AppDefined, "Unknown GRASS feature type."); return NULL; } } return poOGR; }
static CPLErr OGRPolygonContourWriter( double dfLevelMin, double dfLevelMax, const OGRMultiPolygon& multipoly, void *pInfo ) { OGRContourWriterInfo *poInfo = static_cast<OGRContourWriterInfo *>(pInfo); OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn( static_cast<OGRLayerH>(poInfo->hLayer) ); OGRFeatureH hFeat = OGR_F_Create( hFDefn ); if( poInfo->nIDField != -1 ) OGR_F_SetFieldInteger( hFeat, poInfo->nIDField, poInfo->nNextID++ ); if( poInfo->nElevFieldMin != -1 ) OGR_F_SetFieldDouble( hFeat, poInfo->nElevFieldMin, dfLevelMin ); if( poInfo->nElevFieldMax != -1 ) OGR_F_SetFieldDouble( hFeat, poInfo->nElevFieldMax, dfLevelMax ); const bool bHasZ = wkbHasZ(OGR_FD_GetGeomType(hFDefn)); OGRGeometryH hGeom = OGR_G_CreateGeometry( bHasZ ? wkbMultiPolygon25D : wkbMultiPolygon ); for ( int iPart = 0; iPart < multipoly.getNumGeometries(); iPart++ ) { OGRPolygon* poNewPoly = new OGRPolygon(); const OGRPolygon* poPolygon = static_cast<const OGRPolygon*>(multipoly.getGeometryRef(iPart)); for ( int iRing = 0; iRing < poPolygon->getNumInteriorRings() + 1; iRing++ ) { const OGRLinearRing* poRing = iRing == 0 ? poPolygon->getExteriorRing() : poPolygon->getInteriorRing(iRing - 1); OGRLinearRing* poNewRing = new OGRLinearRing(); for ( int iPoint = 0; iPoint < poRing->getNumPoints(); iPoint++ ) { const double dfX = poInfo->adfGeoTransform[0] + poInfo->adfGeoTransform[1] * poRing->getX(iPoint) + poInfo->adfGeoTransform[2] * poRing->getY(iPoint); const double dfY = poInfo->adfGeoTransform[3] + poInfo->adfGeoTransform[4] * poRing->getX(iPoint) + poInfo->adfGeoTransform[5] * poRing->getY(iPoint); if( bHasZ ) OGR_G_SetPoint( OGRGeometry::ToHandle( poNewRing ), iPoint, dfX, dfY, dfLevelMax ); else OGR_G_SetPoint_2D( OGRGeometry::ToHandle( poNewRing ), iPoint, dfX, dfY ); } poNewPoly->addRingDirectly( poNewRing ); } OGR_G_AddGeometryDirectly( hGeom, OGRGeometry::ToHandle( poNewPoly ) ); } OGR_F_SetGeometryDirectly( hFeat, hGeom ); const OGRErr eErr = OGR_L_CreateFeature(static_cast<OGRLayerH>(poInfo->hLayer), hFeat); OGR_F_Destroy( hFeat ); return eErr == OGRERR_NONE ? CE_None : CE_Failure; }
OGRFeature * OGRSDTSLayer::GetNextUnfilteredFeature() { /* -------------------------------------------------------------------- */ /* If not done before we need to assemble the geometry for a */ /* polygon layer. */ /* -------------------------------------------------------------------- */ if( poTransfer->GetLayerType(iLayer) == SLTPoly ) { ((SDTSPolygonReader *) poReader)->AssembleRings(poTransfer,iLayer); } /* -------------------------------------------------------------------- */ /* Fetch the next sdts style feature object from the reader. */ /* -------------------------------------------------------------------- */ SDTSFeature *poSDTSFeature = poReader->GetNextFeature(); OGRFeature *poFeature; if( poSDTSFeature == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Create the OGR feature. */ /* -------------------------------------------------------------------- */ poFeature = new OGRFeature( poFeatureDefn ); m_nFeaturesRead++; switch( poTransfer->GetLayerType(iLayer) ) { /* -------------------------------------------------------------------- */ /* Translate point feature specific information and geometry. */ /* -------------------------------------------------------------------- */ case SLTPoint: { SDTSRawPoint *poPoint = (SDTSRawPoint *) poSDTSFeature; poFeature->SetGeometryDirectly( new OGRPoint( poPoint->dfX, poPoint->dfY, poPoint->dfZ ) ); } break; /* -------------------------------------------------------------------- */ /* Translate line feature specific information and geometry. */ /* -------------------------------------------------------------------- */ case SLTLine: { SDTSRawLine *poLine = (SDTSRawLine *) poSDTSFeature; OGRLineString *poOGRLine = new OGRLineString(); poOGRLine->setPoints( poLine->nVertices, poLine->padfX, poLine->padfY, poLine->padfZ ); poFeature->SetGeometryDirectly( poOGRLine ); poFeature->SetField( "SNID", (int) poLine->oStartNode.nRecord ); poFeature->SetField( "ENID", (int) poLine->oEndNode.nRecord ); } break; /* -------------------------------------------------------------------- */ /* Translate polygon feature specific information and geometry. */ /* -------------------------------------------------------------------- */ case SLTPoly: { SDTSRawPolygon *poPoly = (SDTSRawPolygon *) poSDTSFeature; OGRPolygon *poOGRPoly = new OGRPolygon(); for( int iRing = 0; iRing < poPoly->nRings; iRing++ ) { OGRLinearRing *poRing = new OGRLinearRing(); int nVertices; if( iRing == poPoly->nRings - 1 ) nVertices = poPoly->nVertices - poPoly->panRingStart[iRing]; else nVertices = poPoly->panRingStart[iRing+1] - poPoly->panRingStart[iRing]; poRing->setPoints( nVertices, poPoly->padfX + poPoly->panRingStart[iRing], poPoly->padfY + poPoly->panRingStart[iRing], poPoly->padfZ + poPoly->panRingStart[iRing] ); poOGRPoly->addRingDirectly( poRing ); } poFeature->SetGeometryDirectly( poOGRPoly ); } break; default: break; } /* -------------------------------------------------------------------- */ /* Set attributes for any indicated attribute records. */ /* -------------------------------------------------------------------- */ int iAttrRecord; for( iAttrRecord = 0; iAttrRecord < poSDTSFeature->nAttributes; iAttrRecord++) { DDFField *poSR; poSR = poTransfer->GetAttr( poSDTSFeature->paoATID+iAttrRecord ); if( poSR != NULL ) AssignAttrRecordToFeature( poFeature, poTransfer, poSR ); } /* -------------------------------------------------------------------- */ /* If this record is an attribute record, attach the local */ /* attributes. */ /* -------------------------------------------------------------------- */ if( poTransfer->GetLayerType(iLayer) == SLTAttr ) { AssignAttrRecordToFeature( poFeature, poTransfer, ((SDTSAttrRecord *) poSDTSFeature)->poATTR); } /* -------------------------------------------------------------------- */ /* Translate the record id. */ /* -------------------------------------------------------------------- */ poFeature->SetFID( poSDTSFeature->oModId.nRecord ); poFeature->SetField( 0, (int) poSDTSFeature->oModId.nRecord ); if( poFeature->GetGeometryRef() != NULL ) poFeature->GetGeometryRef()->assignSpatialReference( poDS->GetSpatialRef() ); if( !poReader->IsIndexed() ) delete poSDTSFeature; return poFeature; }
OGRFeature *OGRPCIDSKLayer::GetFeature( GIntBig nFID ) { /* -------------------------------------------------------------------- */ /* Create the OGR feature. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeature; poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( (int) nFID ); /* -------------------------------------------------------------------- */ /* Set attributes for any indicated attribute records. */ /* -------------------------------------------------------------------- */ try { std::vector<PCIDSK::ShapeField> aoFields; unsigned int i; poVecSeg->GetFields( (int) nFID, aoFields ); for( i=0; i < aoFields.size(); i++ ) { if( (int) i == iRingStartField ) continue; switch( aoFields[i].GetType() ) { case PCIDSK::FieldTypeNone: // null field value. break; case PCIDSK::FieldTypeInteger: poFeature->SetField( i, aoFields[i].GetValueInteger() ); break; case PCIDSK::FieldTypeFloat: poFeature->SetField( i, aoFields[i].GetValueFloat() ); break; case PCIDSK::FieldTypeDouble: poFeature->SetField( i, aoFields[i].GetValueDouble() ); break; case PCIDSK::FieldTypeString: poFeature->SetField( i, aoFields[i].GetValueString().c_str() ); break; case PCIDSK::FieldTypeCountedInt: std::vector<PCIDSK::int32> list = aoFields[i].GetValueCountedInt(); poFeature->SetField( i, list.size(), &(list[0]) ); break; } } /* -------------------------------------------------------------------- */ /* Translate the geometry. */ /* -------------------------------------------------------------------- */ std::vector<PCIDSK::ShapeVertex> aoVertices; poVecSeg->GetVertices( (int) nFID, aoVertices ); /* -------------------------------------------------------------------- */ /* Point */ /* -------------------------------------------------------------------- */ if( poFeatureDefn->GetGeomType() == wkbPoint25D || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown && aoVertices.size() == 1) ) { if( aoVertices.size() == 1 ) { OGRPoint* poPoint = new OGRPoint( aoVertices[0].x, aoVertices[0].y, aoVertices[0].z ); if (poSRS) poPoint->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poPoint); } else { // report issue? } } /* -------------------------------------------------------------------- */ /* LineString */ /* -------------------------------------------------------------------- */ else if( poFeatureDefn->GetGeomType() == wkbLineString25D || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown && aoVertices.size() > 1) ) { // We should likely be applying ringstart to break things into // a multilinestring in some cases. if( aoVertices.size() > 1 ) { OGRLineString *poLS = new OGRLineString(); poLS->setNumPoints( aoVertices.size() ); for( i = 0; i < aoVertices.size(); i++ ) poLS->setPoint( i, aoVertices[i].x, aoVertices[i].y, aoVertices[i].z ); if (poSRS) poLS->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poLS ); } else { // report issue? } } /* -------------------------------------------------------------------- */ /* Polygon - Currently we have no way to recognise if we are */ /* dealing with a multipolygon when we have more than one */ /* ring. Also, PCIDSK allows the rings to be in arbitrary */ /* order, not necessarily outside first which we are not yet */ /* ready to address in the following code. */ /* -------------------------------------------------------------------- */ else if( poFeatureDefn->GetGeomType() == wkbPolygon25D ) { std::vector<PCIDSK::int32> anRingStart; OGRPolygon *poPoly = new OGRPolygon(); unsigned int iRing; if( iRingStartField != -1 ) anRingStart = aoFields[iRingStartField].GetValueCountedInt(); for( iRing = 0; iRing < anRingStart.size()+1; iRing++ ) { int iStartVertex, iEndVertex, iVertex; OGRLinearRing *poRing = new OGRLinearRing(); if( iRing == 0 ) iStartVertex = 0; else iStartVertex = anRingStart[iRing-1]; if( iRing == anRingStart.size() ) iEndVertex = aoVertices.size() - 1; else iEndVertex = anRingStart[iRing] - 1; poRing->setNumPoints( iEndVertex - iStartVertex + 1 ); for( iVertex = iStartVertex; iVertex <= iEndVertex; iVertex++ ) { poRing->setPoint( iVertex - iStartVertex, aoVertices[iVertex].x, aoVertices[iVertex].y, aoVertices[iVertex].z ); } poPoly->addRingDirectly( poRing ); } if (poSRS) poPoly->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poPoly ); } } /* -------------------------------------------------------------------- */ /* Trap exceptions and report as CPL errors. */ /* -------------------------------------------------------------------- */ catch( PCIDSK::PCIDSKException ex ) { delete poFeature; CPLError( CE_Failure, CPLE_AppDefined, "%s", ex.what() ); return NULL; } catch(...) { delete poFeature; CPLError( CE_Failure, CPLE_AppDefined, "Non-PCIDSK exception trapped." ); return NULL; } m_nFeaturesRead++; return poFeature; }
OGRErr OGRPGeoLayer::createFromShapeBin( GByte *pabyShape, OGRGeometry **ppoGeom, int nBytes ) { *ppoGeom = NULL; if( nBytes < 1 ) return OGRERR_FAILURE; int nSHPType = pabyShape[0]; // CPLDebug( "PGeo", // "Shape type read from PGeo data is nSHPType = %d", // nSHPType ); /* -------------------------------------------------------------------- */ /* type 50 appears to just be an alias for normal line */ /* strings. (#1484) */ /* Type 51 appears to just be an alias for normal polygon. (#3100) */ /* TODO: These types include additional attributes including */ /* non-linear segments and such. They should be handled. */ /* -------------------------------------------------------------------- */ switch( nSHPType ) { case 50: nSHPType = SHPT_ARC; break; case 51: nSHPType = SHPT_POLYGON; break; case 52: nSHPType = SHPT_POINT; break; case 53: nSHPType = SHPT_MULTIPOINT; break; case 54: nSHPType = SHPT_MULTIPATCH; } /* ==================================================================== */ /* Extract vertices for a Polygon or Arc. */ /* ==================================================================== */ if( nSHPType == SHPT_ARC || nSHPType == SHPT_ARCZ || nSHPType == SHPT_ARCM || nSHPType == SHPT_ARCZM || nSHPType == SHPT_POLYGON || nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_POLYGONZM || nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM) { GInt32 nPoints, nParts; int i, nOffset; GInt32 *panPartStart; if (nBytes < 44) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Extract part/point count, and build vertex and part arrays */ /* to proper size. */ /* -------------------------------------------------------------------- */ memcpy( &nPoints, pabyShape + 40, 4 ); memcpy( &nParts, pabyShape + 36, 4 ); CPL_LSBPTR32( &nPoints ); CPL_LSBPTR32( &nParts ); if (nPoints < 0 || nParts < 0 || nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nPoints=%d, nParts=%d.", nPoints, nParts); return OGRERR_FAILURE; } int bHasZ = ( nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_POLYGONZM || nSHPType == SHPT_ARCZ || nSHPType == SHPT_ARCZM || nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM ); int bIsMultiPatch = ( nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM ); /* With the previous checks on nPoints and nParts, */ /* we should not overflow here and after */ /* since 50 M * (16 + 8 + 8) = 1 600 MB */ int nRequiredSize = 44 + 4 * nParts + 16 * nPoints; if ( bHasZ ) { nRequiredSize += 16 + 8 * nPoints; } if( bIsMultiPatch ) { nRequiredSize += 4 * nParts; } if (nRequiredSize > nBytes) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nPoints=%d, nParts=%d, nBytes=%d, nSHPType=%d", nPoints, nParts, nBytes, nSHPType); return OGRERR_FAILURE; } panPartStart = (GInt32 *) VSICalloc(nParts,sizeof(GInt32)); if (panPartStart == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Copy out the part array from the record. */ /* -------------------------------------------------------------------- */ memcpy( panPartStart, pabyShape + 44, 4 * nParts ); for( i = 0; i < nParts; i++ ) { CPL_LSBPTR32( panPartStart + i ); /* We check that the offset is inside the vertex array */ if (panPartStart[i] < 0 || panPartStart[i] >= nPoints) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : panPartStart[%d] = %d, nPoints = %d", i, panPartStart[i], nPoints); CPLFree(panPartStart); return OGRERR_FAILURE; } if (i > 0 && panPartStart[i] <= panPartStart[i-1]) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : panPartStart[%d] = %d, panPartStart[%d] = %d", i, panPartStart[i], i - 1, panPartStart[i - 1]); CPLFree(panPartStart); return OGRERR_FAILURE; } } nOffset = 44 + 4*nParts; /* -------------------------------------------------------------------- */ /* If this is a multipatch, we will also have parts types. For */ /* now we ignore and skip past them. */ /* -------------------------------------------------------------------- */ if( bIsMultiPatch ) nOffset += 4*nParts; /* -------------------------------------------------------------------- */ /* Copy out the vertices from the record. */ /* -------------------------------------------------------------------- */ double *padfX = (double *) VSIMalloc(sizeof(double)*nPoints); double *padfY = (double *) VSIMalloc(sizeof(double)*nPoints); double *padfZ = (double *) VSICalloc(sizeof(double),nPoints); if (padfX == NULL || padfY == NULL || padfZ == NULL) { CPLFree( panPartStart ); CPLFree( padfX ); CPLFree( padfY ); CPLFree( padfZ ); CPLError(CE_Failure, CPLE_OutOfMemory, "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts); return OGRERR_FAILURE; } for( i = 0; i < nPoints; i++ ) { memcpy(padfX + i, pabyShape + nOffset + i * 16, 8 ); memcpy(padfY + i, pabyShape + nOffset + i * 16 + 8, 8 ); CPL_LSBPTR64( padfX + i ); CPL_LSBPTR64( padfY + i ); } nOffset += 16*nPoints; /* -------------------------------------------------------------------- */ /* If we have a Z coordinate, collect that now. */ /* -------------------------------------------------------------------- */ if( bHasZ ) { for( i = 0; i < nPoints; i++ ) { memcpy( padfZ + i, pabyShape + nOffset + 16 + i*8, 8 ); CPL_LSBPTR64( padfZ + i ); } nOffset += 16 + 8*nPoints; } /* -------------------------------------------------------------------- */ /* Build corresponding OGR objects. */ /* -------------------------------------------------------------------- */ if( nSHPType == SHPT_ARC || nSHPType == SHPT_ARCZ || nSHPType == SHPT_ARCM || nSHPType == SHPT_ARCZM ) { /* -------------------------------------------------------------------- */ /* Arc - As LineString */ /* -------------------------------------------------------------------- */ if( nParts == 1 ) { OGRLineString *poLine = new OGRLineString(); *ppoGeom = poLine; poLine->setPoints( nPoints, padfX, padfY, padfZ ); } /* -------------------------------------------------------------------- */ /* Arc - As MultiLineString */ /* -------------------------------------------------------------------- */ else { OGRMultiLineString *poMulti = new OGRMultiLineString; *ppoGeom = poMulti; for( i = 0; i < nParts; i++ ) { OGRLineString *poLine = new OGRLineString; int nVerticesInThisPart; if( i == nParts-1 ) nVerticesInThisPart = nPoints - panPartStart[i]; else nVerticesInThisPart = panPartStart[i+1] - panPartStart[i]; poLine->setPoints( nVerticesInThisPart, padfX + panPartStart[i], padfY + panPartStart[i], padfZ + panPartStart[i] ); poMulti->addGeometryDirectly( poLine ); } } } /* ARC */ /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ else if( nSHPType == SHPT_POLYGON || nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_POLYGONZM ) { OGRPolygon *poMulti = new OGRPolygon; *ppoGeom = poMulti; for( i = 0; i < nParts; i++ ) { OGRLinearRing *poRing = new OGRLinearRing; int nVerticesInThisPart; if( i == nParts-1 ) nVerticesInThisPart = nPoints - panPartStart[i]; else nVerticesInThisPart = panPartStart[i+1] - panPartStart[i]; poRing->setPoints( nVerticesInThisPart, padfX + panPartStart[i], padfY + panPartStart[i], padfZ + panPartStart[i] ); poMulti->addRingDirectly( poRing ); } } /* polygon */ /* -------------------------------------------------------------------- */ /* Multipatch */ /* -------------------------------------------------------------------- */ else if( bIsMultiPatch ) { /* return to this later */ } CPLFree( panPartStart ); CPLFree( padfX ); CPLFree( padfY ); CPLFree( padfZ ); if( !bHasZ ) (*ppoGeom)->setCoordinateDimension( 2 ); return OGRERR_NONE; } /* ==================================================================== */ /* Extract vertices for a MultiPoint. */ /* ==================================================================== */ else if( nSHPType == SHPT_MULTIPOINT || nSHPType == SHPT_MULTIPOINTM || nSHPType == SHPT_MULTIPOINTZ || nSHPType == SHPT_MULTIPOINTZM ) { #ifdef notdef int32 nPoints; int i, nOffset; memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); if( bBigEndian ) SwapWord( 4, &nPoints ); psShape->nVertices = nPoints; psShape->padfX = (double *) calloc(nPoints,sizeof(double)); psShape->padfY = (double *) calloc(nPoints,sizeof(double)); psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); psShape->padfM = (double *) calloc(nPoints,sizeof(double)); for( i = 0; i < nPoints; i++ ) { memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); } nOffset = 48 + 16*nPoints; /* -------------------------------------------------------------------- */ /* Get the X/Y bounds. */ /* -------------------------------------------------------------------- */ memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); /* -------------------------------------------------------------------- */ /* If we have a Z coordinate, collect that now. */ /* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_MULTIPOINTZ || psShape->nSHPType == SHPT_MULTIPOINTZM ) { memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); } nOffset += 16 + 8*nPoints; } /* -------------------------------------------------------------------- */ /* If we have a M measure value, then read it now. We assume */ /* that the measure can be present for any shape if the size is */ /* big enough, but really it will only occur for the Z shapes */ /* (options), and the M shapes. */ /* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); } } #endif } /* ==================================================================== */ /* Extract vertices for a point. */ /* ==================================================================== */ else if( nSHPType == SHPT_POINT || nSHPType == SHPT_POINTM || nSHPType == SHPT_POINTZ || nSHPType == SHPT_POINTZM ) { int nOffset; double dfX, dfY, dfZ = 0; int bHasZ = (nSHPType == SHPT_POINTZ || nSHPType == SHPT_POINTZM); if (nBytes < 4 + 8 + 8 + ((nSHPType == SHPT_POINTZ) ? 8 : 0)) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType); return OGRERR_FAILURE; } memcpy( &dfX, pabyShape + 4, 8 ); memcpy( &dfY, pabyShape + 4 + 8, 8 ); CPL_LSBPTR64( &dfX ); CPL_LSBPTR64( &dfY ); nOffset = 20 + 8; if( bHasZ ) { memcpy( &dfZ, pabyShape + 4 + 16, 8 ); CPL_LSBPTR64( &dfZ ); } *ppoGeom = new OGRPoint( dfX, dfY, dfZ ); if( !bHasZ ) (*ppoGeom)->setCoordinateDimension( 2 ); return OGRERR_NONE; } char* pszHex = CPLBinaryToHex( nBytes, pabyShape ); CPLDebug( "PGEO", "Unsupported geometry type:%d\nnBytes=%d, hex=%s", nSHPType, nBytes, pszHex ); CPLFree(pszHex); return OGRERR_FAILURE; }
OGRFeature *OGROGDILayer::GetNextRawFeature() { ecs_Result *psResult; int i; OGRFeature *poFeature; /* -------------------------------------------------------------------- */ /* Retrieve object from OGDI server and create new feature */ /* -------------------------------------------------------------------- */ psResult = cln_GetNextObject(m_nClientID); if (! ECSSUCCESS(psResult)) { // We probably reached EOF... keep track of shape count. m_nTotalShapeCount = m_iNextShapeId - m_nFilteredOutShapes; return NULL; } poFeature = new OGRFeature(m_poFeatureDefn); poFeature->SetFID( m_iNextShapeId++ ); m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Process geometry */ /* -------------------------------------------------------------------- */ if (m_eFamily == Point) { ecs_Point *psPoint = &(ECSGEOM(psResult).point); OGRPoint *poOGRPoint = new OGRPoint(psPoint->c.x, psPoint->c.y); poOGRPoint->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRPoint); } else if (m_eFamily == Line) { ecs_Line *psLine = &(ECSGEOM(psResult).line); OGRLineString *poOGRLine = new OGRLineString(); poOGRLine->setNumPoints( psLine->c.c_len ); for( i=0; i < (int) psLine->c.c_len; i++ ) { poOGRLine->setPoint(i, psLine->c.c_val[i].x, psLine->c.c_val[i].y); } poOGRLine->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRLine); } else if (m_eFamily == Area) { ecs_Area *psArea = &(ECSGEOM(psResult).area); OGRPolygon *poOGRPolygon = new OGRPolygon(); for(int iRing=0; iRing < (int) psArea->ring.ring_len; iRing++) { ecs_FeatureRing *psRing = &(psArea->ring.ring_val[iRing]); OGRLinearRing *poOGRRing = new OGRLinearRing(); poOGRRing->setNumPoints( psRing->c.c_len ); for( i=0; i < (int) psRing->c.c_len; i++ ) { poOGRRing->setPoint(i, psRing->c.c_val[i].x, psRing->c.c_val[i].y); } poOGRPolygon->addRingDirectly(poOGRRing); } // __TODO__ // When OGR supports polygon centroids then we should carry them here poOGRPolygon->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRPolygon); } else if (m_eFamily == Text) { // __TODO__ // For now text is treated as a point and string is lost // ecs_Text *psText = &(ECSGEOM(psResult).text); OGRPoint *poOGRPoint = new OGRPoint(psText->c.x, psText->c.y); poOGRPoint->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRPoint); } else { CPLAssert(FALSE); } /* -------------------------------------------------------------------- */ /* Set attributes */ /* -------------------------------------------------------------------- */ char *pszAttrList = ECSOBJECTATTR(psResult); for( int iField = 0; iField < m_poFeatureDefn->GetFieldCount(); iField++ ) { char *pszFieldStart; int nNameLen; char chSavedChar; /* parse out the next attribute value */ if( !ecs_FindElement( pszAttrList, &pszFieldStart, &pszAttrList, &nNameLen, NULL ) ) { nNameLen = 0; pszFieldStart = pszAttrList; } /* Skip any trailing white space (for string constants). */ if( nNameLen > 0 && pszFieldStart[nNameLen-1] == ' ' ) nNameLen--; /* skip leading white space */ while( pszFieldStart[0] == ' ' && nNameLen > 0 ) { pszFieldStart++; nNameLen--; } /* zero terminate the single field value, but save the */ /* character we overwrote, so we can restore it when done. */ chSavedChar = pszFieldStart[nNameLen]; pszFieldStart[nNameLen] = '\0'; /* OGR takes care of all field type conversions for us! */ poFeature->SetField(iField, pszFieldStart); pszFieldStart[nNameLen] = chSavedChar; } /* -------------------------------------------------------------------- */ /* Apply the text associated with text features if appropriate. */ /* -------------------------------------------------------------------- */ if( m_eFamily == Text ) { poFeature->SetField( "text", ECSGEOM(psResult).text.desc ); } return poFeature; }
static OGRGeometry* ParseKMLGeometry(/* const */ CPLXMLNode* psXML) { OGRGeometry* poGeom = nullptr; const char* pszGeomType = psXML->pszValue; if (strcmp(pszGeomType, "Point") == 0) { const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr); if (pszCoordinates) { char** papszTokens = CSLTokenizeString2(pszCoordinates, ",", 0); if (CSLCount(papszTokens) == 2) poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1])); else if (CSLCount(papszTokens) == 3) poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2])); CSLDestroy(papszTokens); } } else if (strcmp(pszGeomType, "LineString") == 0) { const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr); if (pszCoordinates) { OGRLineString* poLS = new OGRLineString(); ParseLineString(poLS, pszCoordinates); poGeom = poLS; } } else if (strcmp(pszGeomType, "Polygon") == 0) { OGRPolygon* poPoly = nullptr; CPLXMLNode* psOuterBoundary = CPLGetXMLNode(psXML, "outerBoundaryIs"); if (psOuterBoundary) { CPLXMLNode* psLinearRing = CPLGetXMLNode(psOuterBoundary, "LinearRing"); const char* pszCoordinates = CPLGetXMLValue( psLinearRing ? psLinearRing : psOuterBoundary, "coordinates", nullptr); if (pszCoordinates) { OGRLinearRing* poLS = new OGRLinearRing(); ParseLineString(poLS, pszCoordinates); poPoly = new OGRPolygon(); poPoly->addRingDirectly(poLS); poGeom = poPoly; } if (poPoly) { CPLXMLNode* psIter = psXML->psChild; while(psIter) { if (psIter->eType == CXT_Element && strcmp(psIter->pszValue, "innerBoundaryIs") == 0) { psLinearRing = CPLGetXMLNode(psIter, "LinearRing"); pszCoordinates = CPLGetXMLValue( psLinearRing ? psLinearRing : psIter, "coordinates", nullptr); if (pszCoordinates) { OGRLinearRing* poLS = new OGRLinearRing(); ParseLineString(poLS, pszCoordinates); poPoly->addRingDirectly(poLS); } } psIter = psIter->psNext; } } } } else if (strcmp(pszGeomType, "MultiGeometry") == 0) { CPLXMLNode* psIter = nullptr; OGRwkbGeometryType eType = wkbUnknown; for(psIter = psXML->psChild; psIter; psIter = psIter->psNext) { if (psIter->eType == CXT_Element) { OGRwkbGeometryType eNewType = wkbUnknown; if (strcmp(psIter->pszValue, "Point") == 0) { eNewType = wkbPoint; } else if (strcmp(psIter->pszValue, "LineString") == 0) { eNewType = wkbLineString; } else if (strcmp(psIter->pszValue, "Polygon") == 0) { eNewType = wkbPolygon; } else break; if (eType == wkbUnknown) eType = eNewType; else if (eType != eNewType) break; } } OGRGeometryCollection* poColl = nullptr; if (psIter != nullptr) poColl = new OGRGeometryCollection(); else if (eType == wkbPoint) poColl = new OGRMultiPoint(); else if (eType == wkbLineString) poColl = new OGRMultiLineString(); else if (eType == wkbPolygon) poColl = new OGRMultiPolygon(); else { CPLAssert(false); } for(psIter = psXML->psChild; psIter; psIter = psIter->psNext) { if (psIter->eType == CXT_Element) { OGRGeometry* poSubGeom = ParseKMLGeometry(psIter); if (poSubGeom) poColl->addGeometryDirectly(poSubGeom); } } poGeom = poColl; } return poGeom; }