Пример #1
0
bool triangulateandtag_yz(OGRGeometry* geometry, Triangulationyz &triangulation) {
  OGRPolygon *polygon = (OGRPolygon *)geometry;
  for (int currentPoint = 0; currentPoint < polygon->getExteriorRing()->getNumPoints(); ++currentPoint) {
    triangulation.insert_constraint(Point(polygon->getExteriorRing()->getX(currentPoint), 
                                          polygon->getExteriorRing()->getY(currentPoint),
                                          polygon->getExteriorRing()->getZ(currentPoint)),
                                    Point(polygon->getExteriorRing()->getX((currentPoint+1)%polygon->getExteriorRing()->getNumPoints()), 
                                          polygon->getExteriorRing()->getY((currentPoint+1)%polygon->getExteriorRing()->getNumPoints()),
                                          polygon->getExteriorRing()->getZ((currentPoint+1)%polygon->getExteriorRing()->getNumPoints())));
  } 
  for (int currentRing = 0; currentRing < polygon->getNumInteriorRings(); ++currentRing) {
    for (int currentPoint = 0; currentPoint < polygon->getInteriorRing(currentRing)->getNumPoints(); ++currentPoint)
      triangulation.insert_constraint(Point(polygon->getInteriorRing(currentRing)->getX(currentPoint), 
                                            polygon->getInteriorRing(currentRing)->getY(currentPoint),
                                            polygon->getInteriorRing(currentRing)->getZ(currentPoint)),
                                      Point(polygon->getInteriorRing(currentRing)->getX((currentPoint+1)%polygon->getInteriorRing(currentRing)->getNumPoints()), 
                                            polygon->getInteriorRing(currentRing)->getY((currentPoint+1)%polygon->getInteriorRing(currentRing)->getNumPoints()),
                                            polygon->getInteriorRing(currentRing)->getZ((currentPoint+1)%polygon->getInteriorRing(currentRing)->getNumPoints())));
  }
  
  std::cout << "Triangulation: " << triangulation.number_of_faces() << " faces, " << triangulation.number_of_vertices() << " vertices." << std::endl;
  if (triangulation.number_of_faces() < 1) {
    return NULL;
  }
  
  // Tag
  void *interior = malloc(sizeof(void *));
  void *exterior = malloc(sizeof(void *));
  tag_yz(triangulation, interior, exterior);
  
  return true;
}
Пример #2
0
PFB::PolygonFeature::PolygonFeature(const std::string & label, const PlaceFileColor & color, 
  const OGRPolygon & polygon, int displayThresh, int lineWidth)
  :Feature(label, color, displayThresh, lineWidth)
{
  int numLines = polygon.getNumInteriorRings() + 1; // +1 for exterior ring.

  // Get numPoints in exterior ring
  int numPoints = polygon.getExteriorRing()->getNumPoints();
  if (!_isOGRLinearRingClosed(*polygon.getExteriorRing())) ++numPoints;

  // Get numPoints in interior rings
  for (int i = 1; i != numLines; ++i)
  {
    numPoints += polygon.getInteriorRing(i - 1)->getNumPoints();
    if (!_isOGRLinearRingClosed(*polygon.getInteriorRing(i - 1))) ++numPoints;
  }

  // Reserve space for our points.
  _coords.reserve(numPoints);

  // Copy the points to our local data type
  for (int l = 0; l != numLines; ++l)
  {
    const OGRLineString* ls = nullptr;
    if (l == 0)
    {
      ls = polygon.getExteriorRing();
    }
    else
    {
      ls = polygon.getInteriorRing(l - 1);
    }

    int numPntsInRing = ls->getNumPoints();
    int increment = 1;
    while (numPntsInRing / increment > 5000) {
      increment++;
    }

    for (int i = 0; i < numPntsInRing; i += increment)
    {
      _coords.push_back(point(ls->getY(i), ls->getX(i)));
    }
    
    // Close the loop
    _coords.push_back(point(ls->getY(0), ls->getX(0)));
  }
}
Пример #3
0
OGRBoolean OGRPolygon::Equal( OGRGeometry * poOther )

{
    OGRPolygon *poOPoly = (OGRPolygon *) poOther;

    if( poOther == this )
        return TRUE;
    
    if( poOther->getGeometryType() != getGeometryType() )
        return FALSE;

    if( getNumInteriorRings() != poOPoly->getNumInteriorRings() )
        return FALSE;

    if( !getExteriorRing()->Equal( poOPoly->getExteriorRing() ) )
        return FALSE;
    
    // we should eventually test the SRS.

    for( int iRing = 0; iRing < getNumInteriorRings(); iRing++ )
    {
        if( !getInteriorRing(iRing)->Equal(poOPoly->getInteriorRing(iRing)) )
            return FALSE;
    }

    return TRUE;
}
Пример #4
0
OGRGeometry *OGRGeometryFactory::forceToPolygon( OGRGeometry *poGeom )

{
    if( poGeom == NULL )
        return NULL;

    if( wkbFlatten(poGeom->getGeometryType()) != wkbGeometryCollection
        || wkbFlatten(poGeom->getGeometryType()) != wkbMultiPolygon )
        return poGeom;

    // build an aggregated polygon from all the polygon rings in the container.
    OGRPolygon *poPolygon = new OGRPolygon();
    OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom;
    int iGeom;

    for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ )
    {
        if( wkbFlatten(poGC->getGeometryRef(iGeom)->getGeometryType()) 
            != wkbPolygon )
            continue;

        OGRPolygon *poOldPoly = (OGRPolygon *) poGC->getGeometryRef(iGeom);
        int   iRing;

        poPolygon->addRing( poOldPoly->getExteriorRing() );

        for( iRing = 0; iRing < poOldPoly->getNumInteriorRings(); iRing++ )
            poPolygon->addRing( poOldPoly->getInteriorRing( iRing ) );
    }
    
    delete poGC;

    return poPolygon;
}
Пример #5
0
void Polygon::simplify(double distance_tolerance, double area_tolerance)
{
    throwNoGeos();

    auto deleteSmallRings = [area_tolerance](OGRGeometry *geom)
    {
// Missing until GDAL 2.3.
//        OGRPolygon *poly = geom->toPolygon();
        OGRPolygon *poly = static_cast<OGRPolygon *>(geom);

        std::vector<int> deleteRings;
        for (int i = 0; i < poly->getNumInteriorRings(); ++i)
        {
            OGRLinearRing *lr = poly->getInteriorRing(i);
            if (lr->get_Area() < area_tolerance)
                deleteRings.push_back(i + 1);
        }
        // Note that interior rings are in a list with the exterior ring,
        // which is why the ring numbers are offset by one when used in
        // this context (what a mess).
        for (auto i : deleteRings)
// Missing until 2.3
//            poly->removeRing(i, true);
            OGR_G_RemoveGeometry(gdal::toHandle(poly), i, true);
    };

    OGRGeometry *g = m_geom->SimplifyPreserveTopology(distance_tolerance);
    m_geom.reset(g);

    OGRwkbGeometryType t = m_geom->getGeometryType();
    if (t == wkbPolygon || t == wkbPolygon25D)
        deleteSmallRings(m_geom.get());
    else if (t == wkbMultiPolygon || t == wkbMultiPolygon25D)
    {
// Missing until 2.3
/**
        OGRMultiPolygon *mpoly = m_geom->toMultiPolygon();
        for (auto it = mpoly->begin(); it != mpoly->end(); ++it)
            deleteSmallRings(*it);
**/
        OGRMultiPolygon *mpoly = static_cast<OGRMultiPolygon *>(m_geom.get());
        for (int i = 0; i < mpoly->getNumGeometries(); ++i)
            deleteSmallRings(mpoly->getGeometryRef(i));
    }
}
Пример #6
0
std::vector<Polygon::Ring> Polygon::interiorRings() const
{
    std::vector<Ring> rings;

    OGRwkbGeometryType t = m_geom->getGeometryType();
    if (t != wkbPolygon && t != wkbPolygon25D)
        throw pdal_error("Request for exterior ring on non-polygon.");

//    OGRPolygon *poly = m_geom->toPolygon();
     OGRPolygon *poly = static_cast<OGRPolygon *>(m_geom.get());
    for (int i = 0; i < poly->getNumInteriorRings(); ++i)
    {
        OGRLinearRing *er = poly->getInteriorRing(i);

        Ring r;
        for (int j = 0; j < er->getNumPoints(); ++j)
            r.push_back({er->getX(j), er->getY(j)});
        rings.push_back(r);
    }
    return rings;
}
Пример #7
0
	/**
	 * 複数のポリゴンから成るオブジェクトを読み込む。
	 * 今の実装は、正確には対応していない。オブジェクトのpartsに順次格納していくだけ。
	 * そのため、アプリケーション側でparts[0]しか使わない場合、まずい。
	 */
	void Shape::readMultiPolygon(OGRMultiPolygon* poMultiPolygon, ShapeObject& shapeObject) {
		int numGeometries = poMultiPolygon->getNumGeometries();
		int partsIndex = 0;
		for (int i = 0; i < numGeometries; ++i) {
			OGRGeometry* geo = poMultiPolygon->getGeometryRef(i);
			if (wkbFlatten(geo->getGeometryType()) == wkbPolygon) {
				OGRPolygon* poPolygon = (OGRPolygon*)geo;

				int nInteriorRings = poPolygon->getNumInteriorRings();
				shapeObject.parts.resize(shapeObject.parts.size() + nInteriorRings + 1);

				OGRLinearRing* ring = poPolygon->getExteriorRing();
				readRing(ring, shapeObject.parts[partsIndex++]);

				for (int j = 0; j < nInteriorRings; ++j) {
					OGRLinearRing* ring = poPolygon->getInteriorRing(j);
					readRing(ring, shapeObject.parts[partsIndex++]);
				}
			}
		}
	}
Пример #8
0
int main (int argc, const char * argv[]) {
  
  if (argc < 2 || argc > 3 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
    std::cout << "=== prepair Help ===\n" << std::endl;
    std::cout << "Usage:   triface 'POLYGON(...)'" << std::endl;
    std::cout << "OR" << std::endl;
    std::cout << "Usage:   triface -f infile.txt (infile.txt must contain one WKT on the 1st line)" << std::endl;
    return 0;
  }
  
  // Read input
  unsigned int bufferSize = 10000000;
  char *inputWKT = (char *)malloc(bufferSize*sizeof(char *));
  
  for (int argNum = 1; argNum < argc; ++argNum) {
    if (strcmp(argv[argNum], "-f") == 0) {
      
      if (argNum + 1 <= argc - 1 && argv[argNum+1][0] != '-') {
        std::ifstream infile(argv[argNum+1], std::ifstream::in);
        infile.getline(inputWKT, bufferSize);
        ++argNum;
      } else {
        std::cerr << "Error: Missing input file name." << std::endl;
        return 1;
      }
    }
    else 
      strcpy(inputWKT, argv[argNum]);
  }
  
//  std::cout << "Processing: " << inputWKT << std::endl;
  
  OGRGeometry *geometry;
  OGRGeometryFactory::createFromWkt(&inputWKT, NULL, &geometry);
  if (geometry == NULL) {
    std::cout << "Error: WKT is not valid" << std::endl;
    return 1;
  }

  if (geometry->getGeometryType() != wkbPolygon25D) {
    std::cout << "Error: input geometry is not a 3D polygon" << std::endl;
    return 1;
  }
  
  //-- project to proper plane + get flattened geometry
  int proj = get_projection_plane(geometry);
  OGRGeometry *flatgeom = geometry->clone();
  if (proj == 1) {
    OGRPolygon *polygon = (OGRPolygon *)flatgeom;
    for (int curp = 0; curp < polygon->getExteriorRing()->getNumPoints(); ++curp) 
      polygon->getExteriorRing()->setPoint(curp, polygon->getExteriorRing()->getX(curp), polygon->getExteriorRing()->getZ(curp), 0);
    for (int currentRing = 0; currentRing < polygon->getNumInteriorRings(); ++currentRing) {
      for (int curp = 0; curp < polygon->getInteriorRing(currentRing)->getNumPoints(); ++curp)
        polygon->getInteriorRing(currentRing)->setPoint(curp, polygon->getInteriorRing(currentRing)->getX(curp), polygon->getInteriorRing(currentRing)->getZ(curp), 0);
    }
  }
  else if (proj == 0) {
    OGRPolygon *polygon = (OGRPolygon *)geometry;
    for (int curp = 0; curp < polygon->getExteriorRing()->getNumPoints(); ++curp)
      polygon->getExteriorRing()->setPoint(curp, polygon->getExteriorRing()->getY(curp), polygon->getExteriorRing()->getZ(curp), 0);
    for (int currentRing = 0; currentRing < polygon->getNumInteriorRings(); ++currentRing) {
      for (int curp = 0; curp < polygon->getInteriorRing(currentRing)->getNumPoints(); ++curp)
        polygon->getInteriorRing(currentRing)->setPoint(curp, polygon->getInteriorRing(currentRing)->getY(curp), polygon->getInteriorRing(currentRing)->getZ(curp), 0);
    }
  }
  flatgeom->flattenTo2D();
//  std::cout << "geom: " << geometry->getCoordinateDimension() << std::endl;
//  std::cout << "flatgeom: " << flatgeom->getCoordinateDimension() << std::endl;
  
  //-- check if flattened geometry is valid
  if (flatgeom->IsValid() == FALSE) {
    std::cout << "Error: input polygon is not valid." << std::endl;
    return 1;
  }
  
  if (proj == 2) {
    Triangulationxy triangulation;
    triangulateandtag_xy(geometry, triangulation);
    for (Triangulationxy::Finite_faces_iterator currentFace = triangulation.finite_faces_begin(); currentFace != triangulation.finite_faces_end(); ++currentFace) {
      std::cout << "--triangle--" << std::endl;
      Point p = currentFace->vertex(0)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(1)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(2)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
    }
  }
  else if (proj == 1) {
    Triangulationxz triangulation;
    triangulateandtag_xz(geometry, triangulation);
    for (Triangulationxz::Finite_faces_iterator currentFace = triangulation.finite_faces_begin(); currentFace != triangulation.finite_faces_end(); ++currentFace) {
      std::cout << "--triangle--" << std::endl;
      Point p = currentFace->vertex(0)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(1)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(2)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
    }
  }
  else { //-- proj == 0
    Triangulationyz triangulation;
    triangulateandtag_yz(geometry, triangulation);    
    for (Triangulationyz::Finite_faces_iterator currentFace = triangulation.finite_faces_begin(); currentFace != triangulation.finite_faces_end(); ++currentFace) {
      std::cout << "--triangle--" << std::endl;
      Point p = currentFace->vertex(0)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(1)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
      p = currentFace->vertex(2)->point();
      std::cout << p.x() << ", " << p.y() << ", " << p.z() << std::endl;
    }
  }
     
  return 0;
}
Пример #9
0
static int OGR2GML3GeometryAppend( OGRGeometry *poGeometry,
                                   const OGRSpatialReference* poParentSRS,
                                  char **ppszText, int *pnLength,
                                  int *pnMaxLength,
                                  int bIsSubGeometry,
                                  int bLongSRS,
                                  int bLineStringAsCurve,
                                  const char* pszGMLId = NULL)

{

/* -------------------------------------------------------------------- */
/*      Check for Spatial Reference System attached to given geometry   */
/* -------------------------------------------------------------------- */

    // Buffer for srsName and gml:id attributes (srsName="..." gml:id="...")
    char szAttributes[256];
    int nAttrsLength = 0;

    szAttributes[0] = 0;

    const OGRSpatialReference* poSRS = NULL;
    if (poParentSRS)
        poSRS = poParentSRS;
    else
        poParentSRS = poSRS = poGeometry->getSpatialReference();

    int bCoordSwap = FALSE;

    if( NULL != poSRS )
    {
        const char* pszAuthName = NULL;
        const char* pszAuthCode = NULL;
        const char* pszTarget = NULL;

        if (poSRS->IsProjected())
            pszTarget = "PROJCS";
        else
            pszTarget = "GEOGCS";

        pszAuthName = poSRS->GetAuthorityName( pszTarget );
        if( NULL != pszAuthName )
        {
            if( EQUAL( pszAuthName, "EPSG" ) )
            {
                pszAuthCode = poSRS->GetAuthorityCode( pszTarget );
                if( NULL != pszAuthCode && strlen(pszAuthCode) < 10 )
                {
                    if (bLongSRS && !((OGRSpatialReference*)poSRS)->EPSGTreatsAsLatLong())
                    {
                        OGRSpatialReference oSRS;
                        if (oSRS.importFromEPSGA(atoi(pszAuthCode)) == OGRERR_NONE)
                        {
                            if (oSRS.EPSGTreatsAsLatLong())
                                bCoordSwap = TRUE;
                        }
                    }

                    if (!bIsSubGeometry)
                    {
                        if (bLongSRS)
                        {
                            snprintf( szAttributes, sizeof(szAttributes),
                                      " srsName=\"urn:ogc:def:crs:%s::%s\"",
                                      pszAuthName, pszAuthCode );
                        }
                        else
                        {
                            snprintf( szAttributes, sizeof(szAttributes),
                                      " srsName=\"%s:%s\"",
                                      pszAuthName, pszAuthCode );
                        }

                        nAttrsLength = strlen(szAttributes);
                    }
                }
            }
        }
    }

    if (pszGMLId != NULL && nAttrsLength + 9 + strlen(pszGMLId) + 1 < sizeof(szAttributes))
    {
        strcat(szAttributes, " gml:id=\"");
        strcat(szAttributes, pszGMLId);
        strcat(szAttributes, "\"");
        nAttrsLength = strlen(szAttributes);
    }

/* -------------------------------------------------------------------- */
/*      2D Point                                                        */
/* -------------------------------------------------------------------- */
    if( poGeometry->getGeometryType() == wkbPoint )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        if (bCoordSwap)
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getY(), poPoint->getX(), 0.0, 2 );
        else
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getX(), poPoint->getY(), 0.0, 2 );

        _GrowBuffer( *pnLength + strlen(szCoordinate) + 60 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength,
                "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }
/* -------------------------------------------------------------------- */
/*      3D Point                                                        */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPoint25D )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        if (bCoordSwap)
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getY(), poPoint->getX(), poPoint->getZ(), 3 );
        else
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getX(), poPoint->getY(), poPoint->getZ(), 3 );

        _GrowBuffer( *pnLength + strlen(szCoordinate) + 70 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength,
                "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }

/* -------------------------------------------------------------------- */
/*      LineString and LinearRing                                       */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbLineString
             || poGeometry->getGeometryType() == wkbLineString25D )
    {
        int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING");
        if (!bRing && bLineStringAsCurve)
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                            "<gml:Curve" );
            AppendString( ppszText, pnLength, pnMaxLength,
                            szAttributes );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "><gml:segments><gml:LineStringSegment>" );
            AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap,
                                ppszText, pnLength, pnMaxLength );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LineStringSegment></gml:segments></gml:Curve>" );
        }
        else
        {
            // Buffer for tag name + srsName attribute if set
            const size_t nLineTagLength = 16;
            char* pszLineTagName = NULL;
            pszLineTagName = (char *) CPLMalloc( nLineTagLength + nAttrsLength + 1 );

            if( bRing )
            {
                /* LinearRing isn't supposed to have srsName attribute according to GML3 SF-0 */
                AppendString( ppszText, pnLength, pnMaxLength,
                            "<gml:LinearRing>" );
            }
            else
            {
                sprintf( pszLineTagName, "<gml:LineString%s>", szAttributes );

                AppendString( ppszText, pnLength, pnMaxLength,
                            pszLineTagName );
            }

            // FREE TAG BUFFER
            CPLFree( pszLineTagName );

            AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap,
                                ppszText, pnLength, pnMaxLength );

            if( bRing )
                AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LinearRing>" );
            else
                AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LineString>" );
        }
    }

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPolygon
             || poGeometry->getGeometryType() == wkbPolygon25D )
    {
        OGRPolygon      *poPolygon = (OGRPolygon *) poGeometry;

        // Buffer for polygon tag name + srsName attribute if set
        const size_t nPolyTagLength = 13;
        char* pszPolyTagName = NULL;
        pszPolyTagName = (char *) CPLMalloc( nPolyTagLength + nAttrsLength + 1 );

        // Compose Polygon tag with or without srsName attribute
        sprintf( pszPolyTagName, "<gml:Polygon%s>", szAttributes );

        AppendString( ppszText, pnLength, pnMaxLength,
                      pszPolyTagName );

        // FREE TAG BUFFER
        CPLFree( pszPolyTagName );

        // Don't add srsName to polygon rings

        if( poPolygon->getExteriorRing() != NULL )
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:exterior>" );

            if( !OGR2GML3GeometryAppend( poPolygon->getExteriorRing(), poSRS,
                                        ppszText, pnLength, pnMaxLength,
                                        TRUE, bLongSRS, bLineStringAsCurve ) )
            {
                return FALSE;
            }

            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:exterior>" );
        }

        for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
        {
            OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);

            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:interior>" );

            if( !OGR2GML3GeometryAppend( poRing, poSRS, ppszText, pnLength,
                                        pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve ) )
                return FALSE;

            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:interior>" );
        }

        AppendString( ppszText, pnLength, pnMaxLength,
                      "</gml:Polygon>" );
    }

/* -------------------------------------------------------------------- */
/*      MultiPolygon, MultiLineString, MultiPoint, MultiGeometry        */
/* -------------------------------------------------------------------- */
    else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
        int             iMember;
        const char *pszElemClose = NULL;
        const char *pszMemberElem = NULL;

        // Buffer for opening tag + srsName attribute
        char* pszElemOpen = NULL;

        if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
        {
            pszElemOpen = (char *) CPLMalloc( 13 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiSurface%s>", szAttributes );

            pszElemClose = "MultiSurface>";
            pszMemberElem = "surfaceMember>";
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
        {
            pszElemOpen = (char *) CPLMalloc( 16 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiCurve%s>", szAttributes );

            pszElemClose = "MultiCurve>";
            pszMemberElem = "curveMember>";
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
        {
            pszElemOpen = (char *) CPLMalloc( 11 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiPoint%s>", szAttributes );

            pszElemClose = "MultiPoint>";
            pszMemberElem = "pointMember>";
        }
        else
        {
            pszElemOpen = (char *) CPLMalloc( 19 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiGeometry%s>", szAttributes );

            pszElemClose = "MultiGeometry>";
            pszMemberElem = "geometryMember>";
        }

        AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemOpen );

        for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );

            AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );

            if( !OGR2GML3GeometryAppend( poMember, poSRS,
                                        ppszText, pnLength, pnMaxLength,
                                        TRUE, bLongSRS, bLineStringAsCurve ) )
            {
                return FALSE;
            }

            AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
        }

        AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemClose );

        // FREE TAG BUFFER
        CPLFree( pszElemOpen );
    }
    else
    {
        return FALSE;
    }

    return TRUE;
}
Пример #10
0
static int OGR2GMLGeometryAppend( OGRGeometry *poGeometry, 
                                  char **ppszText, int *pnLength, 
                                  int *pnMaxLength,
                                  int bIsSubGeometry )

{

/* -------------------------------------------------------------------- */
/*      Check for Spatial Reference System attached to given geometry   */
/* -------------------------------------------------------------------- */

    // Buffer for srsName attribute (srsName="...")
    char szAttributes[30] = { 0 };
    int nAttrsLength = 0;

    const OGRSpatialReference* poSRS = NULL;
    poSRS = poGeometry->getSpatialReference();

    if( NULL != poSRS && !bIsSubGeometry )
    {
        const char* pszAuthName = NULL;
        const char* pszAuthCode = NULL;
        const char* pszTarget = NULL;

        if (poSRS->IsProjected())
            pszTarget = "PROJCS";
        else
            pszTarget = "GEOGCS";

        pszAuthName = poSRS->GetAuthorityName( pszTarget );
        if( NULL != pszAuthName )
        {
            if( EQUAL( pszAuthName, "EPSG" ) )
            {
                pszAuthCode = poSRS->GetAuthorityCode( pszTarget );
                if( NULL != pszAuthCode && strlen(pszAuthCode) < 10 )
                {
                    sprintf( szAttributes, " srsName=\"%s:%s\"",
                            pszAuthName, pszAuthCode );

                    nAttrsLength = strlen(szAttributes);
                }
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      2D Point                                                        */
/* -------------------------------------------------------------------- */
    if( poGeometry->getGeometryType() == wkbPoint )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        MakeGMLCoordinate( szCoordinate, 
                           poPoint->getX(), poPoint->getY(), 0.0, FALSE );

        _GrowBuffer( *pnLength + strlen(szCoordinate) + 60 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength, 
                "<gml:Point%s><gml:coordinates>%s</gml:coordinates></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }
/* -------------------------------------------------------------------- */
/*      3D Point                                                        */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPoint25D )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        MakeGMLCoordinate( szCoordinate, 
                           poPoint->getX(), poPoint->getY(), poPoint->getZ(), 
                           TRUE );
                           
        _GrowBuffer( *pnLength + strlen(szCoordinate) + 70 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength, 
                "<gml:Point%s><gml:coordinates>%s</gml:coordinates></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }

/* -------------------------------------------------------------------- */
/*      LineString and LinearRing                                       */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbLineString 
             || poGeometry->getGeometryType() == wkbLineString25D )
    {
        int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING");

        // Buffer for tag name + srsName attribute if set
        const size_t nLineTagLength = 16;
        char* pszLineTagName = NULL;
        pszLineTagName = (char *) CPLMalloc( nLineTagLength + nAttrsLength + 1 );

        if( bRing )
        {
            sprintf( pszLineTagName, "<gml:LinearRing%s>", szAttributes );

            AppendString( ppszText, pnLength, pnMaxLength,
                          pszLineTagName );
        }
        else
        {
            sprintf( pszLineTagName, "<gml:LineString%s>", szAttributes );

            AppendString( ppszText, pnLength, pnMaxLength,
                          pszLineTagName );
        }

        // FREE TAG BUFFER
        CPLFree( pszLineTagName );

        AppendCoordinateList( (OGRLineString *) poGeometry, 
                              ppszText, pnLength, pnMaxLength );
        
        if( bRing )
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:LinearRing>" );
        else
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:LineString>" );
    }

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPolygon 
             || poGeometry->getGeometryType() == wkbPolygon25D )
    {
        OGRPolygon      *poPolygon = (OGRPolygon *) poGeometry;

        // Buffer for polygon tag name + srsName attribute if set
        const size_t nPolyTagLength = 13;
        char* pszPolyTagName = NULL;
        pszPolyTagName = (char *) CPLMalloc( nPolyTagLength + nAttrsLength + 1 );

        // Compose Polygon tag with or without srsName attribute
        sprintf( pszPolyTagName, "<gml:Polygon%s>", szAttributes );

        AppendString( ppszText, pnLength, pnMaxLength,
                      pszPolyTagName );

        // FREE TAG BUFFER
        CPLFree( pszPolyTagName );

        // Don't add srsName to polygon rings

        if( poPolygon->getExteriorRing() != NULL )
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:outerBoundaryIs>" );

            if( !OGR2GMLGeometryAppend( poPolygon->getExteriorRing(), 
                                        ppszText, pnLength, pnMaxLength,
                                        TRUE ) )
            {
                return FALSE;
            }
            
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:outerBoundaryIs>" );
        }

        for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
        {
            OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);

            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:innerBoundaryIs>" );
            
            if( !OGR2GMLGeometryAppend( poRing, ppszText, pnLength, 
                                        pnMaxLength, TRUE ) )
                return FALSE;
            
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:innerBoundaryIs>" );
        }

        AppendString( ppszText, pnLength, pnMaxLength,
                      "</gml:Polygon>" );
    }

/* -------------------------------------------------------------------- */
/*      MultiPolygon, MultiLineString, MultiPoint, MultiGeometry        */
/* -------------------------------------------------------------------- */
    else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon 
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
        int             iMember;
        const char *pszElemClose = NULL;
        const char *pszMemberElem = NULL;

        // Buffer for opening tag + srsName attribute
        char* pszElemOpen = NULL;

        if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
        {
            pszElemOpen = (char *) CPLMalloc( 13 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiPolygon%s>", szAttributes );

            pszElemClose = "MultiPolygon>";
            pszMemberElem = "polygonMember>";
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
        {
            pszElemOpen = (char *) CPLMalloc( 16 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiLineString%s>", szAttributes );

            pszElemClose = "MultiLineString>";
            pszMemberElem = "lineStringMember>";
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
        {
            pszElemOpen = (char *) CPLMalloc( 11 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiPoint%s>", szAttributes );

            pszElemClose = "MultiPoint>";
            pszMemberElem = "pointMember>";
        }
        else
        {
            pszElemOpen = (char *) CPLMalloc( 19 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiGeometry%s>", szAttributes );

            pszElemClose = "MultiGeometry>";
            pszMemberElem = "geometryMember>";
        }

        AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemOpen );

        for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );

            AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
            
            if( !OGR2GMLGeometryAppend( poMember, 
                                        ppszText, pnLength, pnMaxLength,
                                        TRUE ) )
            {
                return FALSE;
            }
            
            AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
        }

        AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemClose );

        // FREE TAG BUFFER
        CPLFree( pszElemOpen );
    }
    else
    {
        return FALSE;
    }

    return TRUE;
}
Пример #11
0
bool ShpReader::Open(std::wstring fullPath, StudyControllerPtr studyController,
                     VectorMapControllerPtr vectorMapController, ProgressDlgPtr progressDlg) 
{
	// Registers all format drivers built into GDAL/OGR.
	OGRRegisterAll();

	OGRDataSource *OGRDataset;

	// Open vector file path
	std::string tempStr( fullPath.begin(), fullPath.end() );
	OGRDataset = OGRSFDriverRegistrar::Open( tempStr.c_str(), FALSE );

	// Return if no vector files are found
	if( OGRDataset == NULL )
	{
		Log::Inst().Warning("(Warning) Failed to open file at " + tempStr + ".");
		return false;
	}
	if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() >0 )

		MapControllerPtr mapController= App::Inst().GetLayerTreeController()->GetLayerTreeModel()->GetStudy(0)->GetMapLayer(0)->GetMapController();

	// It appears that shapefiles (*.SHP) only support up to one layer per file
	// This will need to be further investigated for other vector filetypes (e.g., KML)
	// For now just grab layer at position 0
	
	OGRLayer *poLayer = OGRDataset->GetLayer( 0 );
	
	// Determine the XY boundaries for the entire vector dataset
	OGREnvelope psEnvelope;

	VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel();
	poLayer->GetExtent( &psEnvelope );
	vectorMapModel->SetVectorBoundary(psEnvelope);

	if(!SetupVectorProjection(OGRDataset,studyController,poLayer,vectorMapController ))
	{
		OGRDataset->DestroyDataSource(OGRDataset);
		return false;
	}
	
	if(progressDlg)
	{
			if(!progressDlg->Update(0, _T("Reading Vector Map Information...")))
			{
				OGRDataset->DestroyDataSource(OGRDataset);
				return false;
			}
	}	
	GLdouble minX, minY, maxX, maxY;
	minX = minY = std::numeric_limits<float>::max();
	maxX = maxY = -std::numeric_limits<float>::max();

	// Retrieve features from the dataset
	OGRFeature *poFeature;
	poLayer->ResetReading();
	int numFeatures = poLayer->GetFeatureCount();
	int count=0;
    //Log::Inst().Write("Loading shapefile with the following meta data:");

	while ( ( poFeature = poLayer->GetNextFeature() ) != NULL )
	{
		/////////////////////////////////////////////////
		// PHASE 1: Retrieve METADATA from the dataset //
		/////////////////////////////////////////////////
		OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
		int iField;

		for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
		{
			OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField );

			//if( poFieldDefn->GetType() == OFTInteger )
			//    printf( "%d,", poFeature->GetFieldAsInteger( iField ) );
			//else if( poFieldDefn->GetType() == OFTReal )
			//    printf( "%.3f,", poFeature->GetFieldAsDouble(iField) );
			//else if( poFieldDefn->GetType() == OFTString )
			//    printf( "%s,", poFeature->GetFieldAsString(iField) );
			//else
			//    printf( "%s,", poFeature->GetFieldAsString(iField) );

			//ofs << poFeature->GetFieldAsString(iField) << ",";

			std::string metaData = poFeature->GetFieldAsString(iField);
			// do something with the meta data...
			//Log::Inst().Write(metaData);
		}
		count++;
		if(progressDlg)
		{
			if(!progressDlg->Update(int(50 + (float(count)/numFeatures)*50)))
				return false;
		}

		///////////////////////////////////////////////////
		// PHASE 2: Retrieve GEOMETRIES from the dataset //
		///////////////////////////////////////////////////
		OGRGeometry *poGeometry;
		poGeometry = poFeature->GetGeometryRef();

		// Move to the next feature in the set if no geometry present
		if( poGeometry == NULL )
		{
			OGRFeature::DestroyFeature( poFeature );
			continue;
		}

		OGRwkbGeometryType whatisit = poGeometry->getGeometryType();

		// Handle POINTS
		if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPoint )
		{
			GeoVector* geoVector = new GeoVector();
			OGRPoint *poPoint = (OGRPoint *) poGeometry;

			geoVector->SetGeometryType( wkbPoint );
			geoVector->SetNumberOfPoints( 1 );
			if(needProjection)
			{
				double x,y;
				x= poPoint->getX();
				y= poPoint->getY();
				if(!poTransform->Transform(1, &x, &y))
				{
					Log::Inst().Warning("(Warning) Failed to project vector map.");
					OGRDataset->DestroyDataSource(OGRDataset);
					return false;
				}
				
				// project and store the points
				geoVector->pointX[0] = x;
				geoVector->pointY[0] = y;

				if(x < minX) minX=x;
				if(y < minY) minY=y;
				if(x > maxX) maxX=x;
				if(y > maxY) maxY=y;
			}
			else 			
			{
				geoVector->pointX[0] = poPoint->getX();
				geoVector->pointY[0] = poPoint->getY();

			}
			vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector );
			
		}
		//Handle MultiPoint
		else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPoint )
		{
			OGRMultiPoint *poMultiPoint = (OGRMultiPoint *) poGeometry;

			for ( int currGeometry = 0; currGeometry < poMultiPoint->getNumGeometries(); currGeometry++ )
			{
				GeoVector* geoVector = new GeoVector();				
				OGRPoint *poPoint = ( OGRPoint* )poMultiPoint->getGeometryRef( currGeometry );			
				geoVector->SetGeometryType( wkbPoint );
				geoVector->SetNumberOfPoints( 1 );
				if(needProjection)
				{
					double x,y;
					x= poPoint->getX();
					y= poPoint->getY();
					if(!poTransform->Transform(1, &x, &y))
					{
						Log::Inst().Warning("(Warning) Failed to project vector map.");
						OGRDataset->DestroyDataSource(OGRDataset);
						return false;
					}
					
					// project and store the points
					geoVector->pointX[0] = x;
					geoVector->pointY[0] = y;

					if(x < minX) minX=x;
					if(y < minY) minY=y;
					if(x > maxX) maxX=x;
					if(y > maxY) maxY=y;
				}
				else 			
				{
					geoVector->pointX[0] = poPoint->getX();
					geoVector->pointY[0] = poPoint->getY();

				}
				vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector );
			}
			
		}

		//Handle Polylines
		else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbLineString )
		{
			GeoVector* geoVector = new GeoVector();
			OGRLineString  *poLine = (OGRLineString  *) poGeometry;

			geoVector->SetGeometryType( wkbLineString );
			geoVector->SetNumberOfPoints( poLine->getNumPoints() );

			// Convert and store the points

			for ( int currentPoint = 0; currentPoint < poLine->getNumPoints(); currentPoint++ )
			{
				// Convert and store the points

				if(needProjection)
				{
					double x,y;
					x= poLine->getX( currentPoint );
					y= poLine->getY( currentPoint );
					if(!poTransform->Transform(1, &x, &y))
					{
						Log::Inst().Warning("(Warning) Failed to project vector map.");
						OGRDataset->DestroyDataSource(OGRDataset);
						return false;
					}
				
					// project and store the points
					geoVector->pointX[currentPoint] = x;
					geoVector->pointY[currentPoint] = y;

					if(x < minX) minX=x;
					if(y < minY) minY=y;
					if(x > maxX) maxX=x;
					if(y > maxY) maxY=y;
				}
				else			
				{
					geoVector->pointX[currentPoint] = poLine->getX( currentPoint );
					geoVector->pointY[currentPoint] = poLine->getY( currentPoint );

				}

			}

			vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector );			
		}
		
		// Handle MultiPolyLine
		else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiLineString )
		{
			OGRMultiLineString *poMultiLine = (OGRMultiLineString *) poGeometry;

			for ( int currGeometry = 0; currGeometry < poMultiLine->getNumGeometries(); currGeometry++ )
			{
				GeoVector* geoVector = new GeoVector();
				
				OGRLineString *poLine = ( OGRLineString* )poMultiLine->getGeometryRef( currGeometry );

				geoVector->SetGeometryType( wkbLineString );
				geoVector->SetNumberOfPoints( poLine->getNumPoints() );				

				for ( int currentPoint = 0; currentPoint < poLine ->getNumPoints(); currentPoint++ )
				{

					 if(needProjection)
					{
						double x,y;
						x= poLine->getX( currentPoint );
						y= poLine->getY( currentPoint );
						if(!poTransform->Transform(1, &x, &y))
						{
							Log::Inst().Warning("(Warning) Failed to project vector map.");
							OGRDataset->DestroyDataSource(OGRDataset);
							return false;
						}
				
					// project and store the points
						geoVector->pointX[currentPoint] = x;
						geoVector->pointY[currentPoint] = y;

						if(x < minX) minX=x;
						if(y < minY) minY=y;
						if(x > maxX) maxX=x;
						if(y > maxY) maxY=y;
					}
					else			
					{
						geoVector->pointX[currentPoint] = poLine->getX( currentPoint );
						geoVector->pointY[currentPoint] = poLine->getY( currentPoint );

					}				
					
				}
				vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector );				
				
			}
		}

		// Handle POLYGONS
		else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPolygon )
		{
			GeoVector* geoVector = new GeoVector();

			OGRPolygon    *poPolygon    = ( OGRPolygon* )poGeometry;
			OGRLinearRing *poLinearRing = poPolygon->getExteriorRing();

			geoVector->SetGeometryType( wkbLinearRing );
			geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() );

			for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ )
			{
				if(needProjection)
				{
					double x,y;
					x= poLinearRing->getX( currentPoint );
					y= poLinearRing->getY( currentPoint );
					if(!poTransform->Transform(1, &x, &y))
					{
						Log::Inst().Warning("(Warning) Failed to project vector map.");
						OGRDataset->DestroyDataSource(OGRDataset);
						return false;
					}
				
					// project and store the points
					geoVector->pointX[currentPoint] = x;
					geoVector->pointY[currentPoint] = y;

					if(x < minX) minX=x;
					if(y < minY) minY=y;
					if(x > maxX) maxX=x;
					if(y > maxY) maxY=y;
				}
				else 			
				{
					geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint );
					geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint );

				}
			}

			vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector );			
		}

		// Handle MULTIPOLYGONS
		else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPolygon )
		{
			OGRMultiPolygon *poMultiPolygon = (OGRMultiPolygon *) poGeometry;

			for ( int currGeometry = 0; currGeometry < poMultiPolygon->getNumGeometries(); currGeometry++ )
			{
				GeoVector* geoVector = new GeoVector();

				// OGRPolygon http://www.gdal.org/ogr/classOGRPolygon.html
				OGRPolygon *poPolygon = ( OGRPolygon* )poMultiPolygon->getGeometryRef( currGeometry );

				// Retrieve the EXTERNAL ring of the multipolygon
				OGRLinearRing *poLinearRing = poPolygon->getExteriorRing();

				geoVector->SetGeometryType( wkbLinearRing );
				geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() );

				for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ )
				{

					 if(needProjection)
					{
						double x,y;
						x= poLinearRing->getX( currentPoint );
						y= poLinearRing->getY( currentPoint );
						if(!poTransform->Transform(1, &x, &y))
						{
							Log::Inst().Warning("(Warning) Failed to project vector map.");
							OGRDataset->DestroyDataSource(OGRDataset);
							return false;
						}
				
					// project and store the points
						geoVector->pointX[currentPoint] = x;
						geoVector->pointY[currentPoint] = y;

						if(x < minX) minX=x;
						if(y < minY) minY=y;
						if(x > maxX) maxX=x;
						if(y > maxY) maxY=y;
					}
					else			
					{
						geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint );
						geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint );

					}				
					
				}
				vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector );				
				
				// Retrieve all the INTERNAL rings of the multipolygon
				for ( int currentRing = 0; currentRing < poPolygon->getNumInteriorRings(); currentRing++ )
				{
					GeoVector* geoVector2 = new GeoVector();

					poLinearRing = poPolygon->getInteriorRing( currentRing );

					geoVector2->SetGeometryType( wkbLinearRing );
					geoVector2->SetNumberOfPoints( poLinearRing->getNumPoints() );

					for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ )
					{
						
						 if(needProjection)
						{
							double x,y;
							x= poLinearRing->getX( currentPoint );
							y= poLinearRing->getY( currentPoint );
							if(!poTransform->Transform(1, &x, &y))
							{
								Log::Inst().Warning("(Warning) Failed to project vector map.");
								OGRDataset->DestroyDataSource(OGRDataset);
								return false;
							}
				
						// project and store the points
							geoVector2->pointX[currentPoint] = x;
							geoVector2->pointY[currentPoint] = y;

							if(x < minX) minX=x;
							if(y < minY) minY=y;
							if(x > maxX) maxX=x;
							if(y > maxY) maxY=y;
						}
						else 		
						{
							geoVector2->pointX[currentPoint] = poLinearRing->getX( currentPoint );
							geoVector2->pointY[currentPoint] = poLinearRing->getY( currentPoint );

						}		
					}

					vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector2 );
				}
			}
		}


		// Report a warning message for unhandled geometries
		else
		{
			Log::Inst().Warning("(Warning) Could not load vector data: unsupported geometry.");
		}
		OGRFeature::DestroyFeature( poFeature );
	}

	if (float(minX) == float(maxX) && float(minY) == float(maxY))
	{
		Log::Inst().Warning("(Warning) Failed to project vector map.");
		OGRDataset->DestroyDataSource(OGRDataset);
		return false;
	}

	if(needProjection)
	{
		vectorMapModel->SetVectorBoundary_MinX(minX);
		vectorMapModel->SetVectorBoundary_MaxX(maxX);
		vectorMapModel->SetVectorBoundary_MinY(minY);
		vectorMapModel->SetVectorBoundary_MaxY(maxY);
	}	
	
	if(!SetupVectorScaling(vectorMapModel,progressDlg))
	{ 
		OGRDataset->DestroyDataSource(OGRDataset);
		return false;
	}

	VectorMetaDataInfo(OGRDataset, studyController, vectorMapController);
	OGRDataSource::DestroyDataSource( OGRDataset );
	return true;
}
Пример #12
0
OGRErr OGRDGNLayer::CreateFeatureWithGeom( OGRFeature *poFeature,
                                           OGRGeometry *poGeom)

{
/* -------------------------------------------------------------------- */
/*      Translate the geometry.                                         */
/* -------------------------------------------------------------------- */
    DGNElemCore **papsGroup = NULL;
    int i;
    const char *pszStyle = poFeature->GetStyleString();

    if( wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
    {
        OGRPoint *poPoint = (OGRPoint *) poGeom;
        const char *pszText = poFeature->GetFieldAsString("Text");

        if( (pszText == NULL || strlen(pszText) == 0)
            && (pszStyle == NULL || strstr(pszStyle,"LABEL") == NULL) )
        {
            DGNPoint asPoints[2];

            papsGroup = (DGNElemCore **) CPLCalloc(sizeof(void*),2);

            // Treat a non text point as a degenerate line.
            asPoints[0].x = poPoint->getX();
            asPoints[0].y = poPoint->getY();
            asPoints[0].z = poPoint->getZ();
            asPoints[1] = asPoints[0];
            
            papsGroup[0] = DGNCreateMultiPointElem( hDGN, DGNT_LINE, 
                                                    2, asPoints );
        }
        else
        {
            papsGroup = TranslateLabel( poFeature );
        }
    }
    else if( wkbFlatten(poGeom->getGeometryType()) == wkbLineString )
    {
        papsGroup = LineStringToElementGroup( (OGRLineString *) poGeom, 
                                              DGNT_LINE_STRING );
    }
    else if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon )
    {
        OGRPolygon *poPoly = ((OGRPolygon *) poGeom);

        DGNElemCore **papsGroupExt = LineStringToElementGroup(
                poPoly->getExteriorRing(), DGNT_SHAPE);

        int innerRingsCnt = poPoly->getNumInteriorRings();

        if (innerRingsCnt > 0) {
            CPLDebug("InnerRings", "there are %d inner rings", innerRingsCnt);
            std::list<DGNElemCore*> dgnElements;

            for (i = 0; papsGroupExt[i] != NULL; i++) {
                dgnElements.push_back(papsGroupExt[i]);
            }
            CPLFree(papsGroupExt);

            // get all interior rings and create complex group shape
            for (int iRing = 0; iRing < innerRingsCnt; iRing++) {
                DGNElemCore **papsGroupInner = LineStringToElementGroup(
                        poPoly->getInteriorRing(iRing), DGNT_SHAPE);
                papsGroupInner[0]->properties |= DGNPF_HOLE;
                DGNUpdateElemCoreExtended(hDGN, papsGroupInner[0]);
                for (i = 0; papsGroupInner[i] != NULL; i++) {
                    dgnElements.push_back(papsGroupInner[i]);
                }
                CPLFree(papsGroupInner);
            }
            int index = 1;
            papsGroup = (DGNElemCore **) CPLCalloc(sizeof(void*),
                    dgnElements.size() + 2);
            for (std::list<DGNElemCore*>::iterator list_iter =
                    dgnElements.begin(); list_iter != dgnElements.end();
                    list_iter++) {
                papsGroup[index++] = *list_iter;
            }

            //papsGroup[0] = DGNCreateComplexHeaderFromGroup( hDGN, DGNT_COMPLEX_SHAPE_HEADER, dgnElements.size(), papsGroup+1);
            DGNPoint asPoints[1];
            asPoints[0].x = 0;
            asPoints[0].y = 0;
            asPoints[0].z = 0;
            papsGroup[0] = DGNCreateCellHeaderFromGroup(hDGN, "", 1, NULL,
                    dgnElements.size(), papsGroup + 1, asPoints + 0, 1.0, 1.0,
                    0.0);
            DGNAddShapeFillInfo(hDGN, papsGroup[0], 6);
        } else {
            papsGroup = papsGroupExt;
        }
    }
    else if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon 
             || wkbFlatten(poGeom->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeom->getGeometryType()) == wkbGeometryCollection)
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom;
        int iGeom;

        for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ )
        {
            OGRErr eErr = CreateFeatureWithGeom( poFeature, 
                                                 poGC->getGeometryRef(iGeom) );
            if( eErr != OGRERR_NONE )
                return eErr;
        }

        return OGRERR_NONE;
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Unsupported geometry type (%s) for DGN.",
                  OGRGeometryTypeToName( poGeom->getGeometryType() ) );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Add other attributes.                                           */
/* -------------------------------------------------------------------- */
    int nLevel = poFeature->GetFieldAsInteger( "Level" );
    int nGraphicGroup = poFeature->GetFieldAsInteger( "GraphicGroup" );
    int nColor = poFeature->GetFieldAsInteger( "ColorIndex" );
    int nWeight = poFeature->GetFieldAsInteger( "Weight" );
    int nStyle = poFeature->GetFieldAsInteger( "Style" );
    int nMSLink = poFeature->GetFieldAsInteger( "MSLink" );

    nLevel = MAX(0,MIN(63,nLevel));
    nColor = MAX(0,MIN(255,nColor));
    nWeight = MAX(0,MIN(31,nWeight));
    nStyle = MAX(0,MIN(7,nStyle));
    nMSLink = MAX(0,MIN(4294967295,nMSLink));

    DGNUpdateElemCore( hDGN, papsGroup[0], nLevel, nGraphicGroup, nColor, 
                       nWeight, nStyle );
    DGNAddMSLink( hDGN, papsGroup[0], DGNLT_ODBC, 0, nMSLink );
/* -------------------------------------------------------------------- */
/*      Write to file.                                                  */
/* -------------------------------------------------------------------- */
    for( i = 0; papsGroup[i] != NULL; i++ )
    {
        DGNWriteElement( hDGN, papsGroup[i] );

        if( i == 0 )
            poFeature->SetFID( papsGroup[i]->element_id );

        DGNFreeElement( hDGN, papsGroup[i] );
    }

    CPLFree( papsGroup );

    return OGRERR_NONE;
}
Пример #13
0
OGRErr OGRBNALayer::CreateFeature( OGRFeature *poFeature )

{
    int i,j,k,n;
    OGRGeometry     *poGeom = poFeature->GetGeometryRef();
    char eol[3];
    const char* partialEol = (poDS->GetMultiLine()) ? eol : poDS->GetCoordinateSeparator();

    if (poGeom == NULL || poGeom->IsEmpty() )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "OGR BNA driver cannot write features with empty geometries.");
        return OGRERR_FAILURE;
    }

    if (poDS->GetUseCRLF())
    {
        eol[0] = 13;
        eol[1] = 10;
        eol[2] = 0;
    }
    else
    {
        eol[0] = 10;
        eol[1] = 0;
    }
    
    if ( ! bWriter )
    {
        return OGRERR_FAILURE;
    }
    
    if( poFeature->GetFID() == OGRNullFID )
        poFeature->SetFID( nFeatures++ );
    
    VSILFILE* fp = poDS->GetOutputFP();
    int nbPairPerLine = poDS->GetNbPairPerLine();

    switch( poGeom->getGeometryType() )
    {
        case wkbPoint:
        case wkbPoint25D:
        {
            OGRPoint* point = (OGRPoint*)poGeom;
            WriteFeatureAttributes(fp, poFeature);
            VSIFPrintfL( fp, "1");
            VSIFPrintfL( fp, "%s", partialEol);
            WriteCoord(fp, point->getX(), point->getY());
            VSIFPrintfL( fp, "%s", eol);
            break;
        }
            
        case wkbPolygon:
        case wkbPolygon25D:
        {
            OGRPolygon* polygon = (OGRPolygon*)poGeom;
            OGRLinearRing* ring = polygon->getExteriorRing();
            if (ring == NULL)
            {
                return OGRERR_FAILURE;
            }
            
            double firstX = ring->getX(0);
            double firstY = ring->getY(0);
            int nBNAPoints = ring->getNumPoints();
            int is_ellipse = FALSE;
            
            /* This code tries to detect an ellipse in a polygon geometry */
            /* This will only work presumably on ellipses already read from a BNA file */
            /* Mostly a BNA to BNA feature... */
            if (poDS->GetEllipsesAsEllipses() &&
                polygon->getNumInteriorRings() == 0 &&
                nBNAPoints == 361)
            {
                double oppositeX = ring->getX(180);
                double oppositeY = ring->getY(180);
                double quarterX = ring->getX(90);
                double quarterY = ring->getY(90);
                double antiquarterX = ring->getX(270);
                double antiquarterY = ring->getY(270);
                double center1X = 0.5*(firstX + oppositeX);
                double center1Y = 0.5*(firstY + oppositeY);
                double center2X = 0.5*(quarterX + antiquarterX);
                double center2Y = 0.5*(quarterY + antiquarterY);
                if (fabs(center1X - center2X) < 1e-5 && fabs(center1Y - center2Y) < 1e-5 &&
                    fabs(oppositeY - firstY) < 1e-5 &&
                    fabs(quarterX - antiquarterX) < 1e-5)
                {
                    double major_radius = fabs(firstX - center1X);
                    double minor_radius = fabs(quarterY - center1Y);
                    is_ellipse = TRUE;
                    for(i=0;i<360;i++)
                    {
                        if (!(fabs(center1X + major_radius * cos(i * (M_PI / 180)) - ring->getX(i)) < 1e-5 &&
                              fabs(center1Y + minor_radius * sin(i * (M_PI / 180)) - ring->getY(i)) < 1e-5))
                        {
                            is_ellipse = FALSE;
                            break;
                        }
                    }
                    if ( is_ellipse == TRUE )
                    {
                        WriteFeatureAttributes(fp, poFeature);
                        VSIFPrintfL( fp, "2");
                        VSIFPrintfL( fp, "%s", partialEol);
                        WriteCoord(fp, center1X, center1Y);
                        VSIFPrintfL( fp, "%s", partialEol);
                        WriteCoord(fp, major_radius, minor_radius);
                        VSIFPrintfL( fp, "%s", eol);
                    }
                }
            }

            if ( is_ellipse == FALSE)
            {
                int nInteriorRings = polygon->getNumInteriorRings();
                for(i=0;i<nInteriorRings;i++)
                {
                    nBNAPoints += polygon->getInteriorRing(i)->getNumPoints() + 1;
                }
                if (nBNAPoints <= 3)
                {
                    CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" );
                    return OGRERR_FAILURE;
                }
                WriteFeatureAttributes(fp, poFeature);
                VSIFPrintfL( fp, "%d", nBNAPoints);
                n = ring->getNumPoints();
                int nbPair = 0;
                for(i=0;i<n;i++)
                {
                    VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " ");
                    WriteCoord(fp, ring->getX(i), ring->getY(i));
                    nbPair++;
                }
                for(i=0;i<nInteriorRings;i++)
                {
                    ring = polygon->getInteriorRing(i);
                    n = ring->getNumPoints();
                    for(j=0;j<n;j++)
                    {
                        VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " ");
                        WriteCoord(fp, ring->getX(j), ring->getY(j));
                        nbPair++;
                    }
                    VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " ");
                    WriteCoord(fp, firstX, firstY);
                    nbPair++;
                }
                VSIFPrintfL( fp, "%s", eol);
            }
            break;
        }

        case wkbMultiPolygon:
        case wkbMultiPolygon25D:
        {
            OGRMultiPolygon* multipolygon = (OGRMultiPolygon*)poGeom;
            int N = multipolygon->getNumGeometries();
            int nBNAPoints = 0;
            double firstX = 0, firstY = 0; 
            for(i=0;i<N;i++)
            {
                OGRPolygon* polygon = (OGRPolygon*)multipolygon->getGeometryRef(i);
                OGRLinearRing* ring = polygon->getExteriorRing();
                if (ring == NULL)
                    continue;

                if (nBNAPoints)
                    nBNAPoints ++;
                else
                {
                    firstX = ring->getX(0);
                    firstY = ring->getY(0);
                }
                nBNAPoints += ring->getNumPoints();
                int nInteriorRings = polygon->getNumInteriorRings();
                for(j=0;j<nInteriorRings;j++)
                {
                    nBNAPoints += polygon->getInteriorRing(j)->getNumPoints() + 1;
                }
            }
            if (nBNAPoints <= 3)
            {
                CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" );
                return OGRERR_FAILURE;
            }
            WriteFeatureAttributes(fp, poFeature);
            VSIFPrintfL( fp, "%d", nBNAPoints);
            int nbPair = 0;
            for(i=0;i<N;i++)
            {
                OGRPolygon* polygon = (OGRPolygon*)multipolygon->getGeometryRef(i);
                OGRLinearRing* ring = polygon->getExteriorRing();
                if (ring == NULL)
                    continue;

                n = ring->getNumPoints();
                int nInteriorRings = polygon->getNumInteriorRings();
                for(j=0;j<n;j++)
                {
                    VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " ");
                    WriteCoord(fp, ring->getX(j), ring->getY(j));
                    nbPair++;
                }
                if (i != 0)
                {
                    VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " ");
                    WriteCoord(fp, firstX, firstY);
                    nbPair++;
                }
                for(j=0;j<nInteriorRings;j++)
                {
                    ring = polygon->getInteriorRing(j);
                    n = ring->getNumPoints();
                    for(k=0;k<n;k++)
                    {
                        VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " ");
                        WriteCoord(fp, ring->getX(k), ring->getY(k));
                        nbPair++;
                    }
                    VSIFPrintfL( fp, "%s", ((nbPair % nbPairPerLine) == 0) ? partialEol : " ");
                    WriteCoord(fp, firstX, firstY);
                    nbPair++;
                }
            }
            VSIFPrintfL( fp, "%s", eol);
            break;
        }

        case wkbLineString:
        case wkbLineString25D:
        {
            OGRLineString* line = (OGRLineString*)poGeom;
            int n = line->getNumPoints();
            int i;
            if (n < 2)
            {
                CPLError( CE_Failure, CPLE_AppDefined, "Invalid geometry" );
                return OGRERR_FAILURE;
            }
            WriteFeatureAttributes(fp, poFeature);
            VSIFPrintfL( fp, "-%d", n);
            int nbPair = 0;
            for(i=0;i<n;i++)
            {
                VSIFPrintfL( fp, "%s", partialEol);
                WriteCoord(fp, line->getX(i), line->getY(i));
                nbPair++;
            }
            VSIFPrintfL( fp, "%s", eol);
            break;
        }
            
        default:
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Unsupported geometry type : %s.",
                      poGeom->getGeometryName() );

            return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
        }
    }
    
    return OGRERR_NONE;
}
static void ProcessCommonGeometry(OGRGeometry* poGeom, OGRGeometry *poClipSrc,
                                int iBurnField, double dfBurnValue,
                                const double dfIncreaseBurnValue,
                                const double dfMultiplyBurnValue,
                                std::vector<double> &adfX,
                                std::vector<double> &adfY,
                                std::vector<double> &adfZ)
{
    if (NULL == poGeom)
        return;

    OGRwkbGeometryType eType = wkbFlatten(poGeom->getGeometryType());
    switch (eType)
    {
    case wkbPoint:
        return ProcessGeometry((OGRPoint *)poGeom, poClipSrc,
            iBurnField, dfBurnValue, dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ);
    case wkbLinearRing:
    case wkbLineString:
        {
            OGRLineString *poLS = (OGRLineString*)poGeom;
            OGRPoint point;
            for (int pointIndex = 0; pointIndex < poLS->getNumPoints(); pointIndex++)
            {
                poLS->getPoint(pointIndex, &point);
                ProcessCommonGeometry((OGRGeometry*)&point, poClipSrc,
                    iBurnField, dfBurnValue, dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ);
            }
        }
        break;
    case wkbPolygon:
        {
            int nRings(0);
            OGRPolygon* poPoly = (OGRPolygon*)poGeom;
            OGRLinearRing* poRing = poPoly->getExteriorRing();
            ProcessCommonGeometry((OGRGeometry*)poRing, poClipSrc,
                iBurnField, dfBurnValue, dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ);

            nRings = poPoly->getNumInteriorRings();
            if (nRings > 0)
            {
                for (int ir = 0; ir < nRings; ++ir)
                {
                    OGRLinearRing* poRing = poPoly->getInteriorRing(ir);
                    ProcessCommonGeometry((OGRGeometry*)poRing, poClipSrc,
                        iBurnField, dfBurnValue, dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ);
                }
            }
        }
        break;
    case wkbMultiPoint:
    case wkbMultiPolygon:
    case wkbMultiLineString:
    case wkbGeometryCollection:
        {
            OGRGeometryCollection* pOGRGeometryCollection = (OGRGeometryCollection*)poGeom;
            for (int i = 0; i < pOGRGeometryCollection->getNumGeometries(); ++i)
            {
                ProcessCommonGeometry(pOGRGeometryCollection->getGeometryRef(i), poClipSrc,
                    iBurnField, dfBurnValue, dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ);
            }
        }
        break;
    case wkbUnknown:
    case wkbNone:
    default:
        break;
    }
}
Пример #15
0
static int OGR2ILIGeometryAppend( OGRGeometry *poGeometry, VSILFILE* fp, const char *attrname, CPLString iliGeomType )
{
    //CPLDebug( "OGR_ILI", "OGR2ILIGeometryAppend getGeometryType %s iliGeomType %s", poGeometry->getGeometryName(), iliGeomType.c_str());
/* -------------------------------------------------------------------- */
/*      2D/3D Point                                                     */
/* -------------------------------------------------------------------- */
    if( poGeometry->getGeometryType() == wkbPoint || poGeometry->getGeometryType() == wkbPoint25D )
    {
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        VSIFPrintfL(fp, "<%s>\n", attrname);
        VSIFPrintfL(fp, "<COORD>");
        VSIFPrintfL(fp, "<C1>%s</C1>", d2str(poPoint->getX()));
        VSIFPrintfL(fp, "<C2>%s</C2>", d2str(poPoint->getY()));
        if( poGeometry->getGeometryType() == wkbPoint25D )
            VSIFPrintfL(fp, "<C3>%s</C3>", d2str(poPoint->getZ()));
        VSIFPrintfL(fp, "</COORD>\n");
        VSIFPrintfL(fp, "</%s>\n", attrname);
    }

/* -------------------------------------------------------------------- */
/*      LineString and LinearRing                                       */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbLineString
             || poGeometry->getGeometryType() == wkbLineString25D )
    {
        if (attrname) VSIFPrintfL(fp, "<%s>\n", attrname);
        VSIFPrintfL(fp, "<POLYLINE>\n");
        // unclipped polyline, add one sequence
        // VSIFPrintfL(fp, "<SEGMENTS>\n");
        AppendCoordinateList( (OGRLineString *) poGeometry, fp );
        // VSIFPrintfL(fp, "</SEGMENTS>\n");
        VSIFPrintfL(fp, "</POLYLINE>\n");
        if (attrname) VSIFPrintfL(fp, "</%s>\n", attrname);
    }

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPolygon
             || poGeometry->getGeometryType() == wkbPolygon25D )
    {
        OGRPolygon      *poPolygon = (OGRPolygon *) poGeometry;

        if (attrname) VSIFPrintfL(fp, "<%s>\n", attrname);
        if( iliGeomType == "Surface" || iliGeomType == "Area" )
        {
            //VSIFPrintfL(fp, "<MULTISURFACE>\n");
            VSIFPrintfL(fp, "<SURFACE>\n");
            VSIFPrintfL(fp, "<BOUNDARY>\n");
        }

        if( poPolygon->getExteriorRing() != NULL )
        {
            if( !OGR2ILIGeometryAppend( poPolygon->getExteriorRing(), fp, NULL, "" ) )
                return FALSE;
        }

        for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
        {
            OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);

            if( !OGR2ILIGeometryAppend( poRing, fp, NULL, "" ) )
                return FALSE;
        }
        if( iliGeomType == "Surface" || iliGeomType == "Area" )
        {
            VSIFPrintfL(fp, "</BOUNDARY>\n");
            VSIFPrintfL(fp, "</SURFACE>\n");
            //VSIFPrintfL(fp, "</MULTISURFACE>\n");
        }
        if (attrname) VSIFPrintfL(fp, "</%s>\n", attrname);
    }

/* -------------------------------------------------------------------- */
/*      MultiPolygon                                                    */
/* -------------------------------------------------------------------- */
    else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
        int             iMember;

        if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
        {
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
        {
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
        {
        }
        else
        {
        }

        for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );

            if( !OGR2ILIGeometryAppend( poMember, fp, NULL, "" ) )
                return FALSE;
        }

    }

    else
        return FALSE;

    return TRUE;
}
Пример #16
0
int OGRILI1Layer::GeometryAppend( OGRGeometry *poGeometry )
{
    //CPLDebug( "OGR_ILI", "OGRILI1Layer::GeometryAppend OGRGeometryType: %s", OGRGeometryTypeToName(poGeometry->getGeometryType()));
    /* -------------------------------------------------------------------- */
    /*      2D Point                                                        */
    /* -------------------------------------------------------------------- */
    if( poGeometry->getGeometryType() == wkbPoint )
    {
        /* embedded in from non-geometry fields */
    }
    /* -------------------------------------------------------------------- */
    /*      3D Point                                                        */
    /* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPoint25D )
    {
        /* embedded in from non-geometry fields */
    }

    /* -------------------------------------------------------------------- */
    /*      LineString and LinearRing                                       */
    /* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbLineString
             || poGeometry->getGeometryType() == wkbLineString25D )
    {
        AppendCoordinateList( (OGRLineString *) poGeometry, poDS );
    }

    /* -------------------------------------------------------------------- */
    /*      Polygon                                                         */
    /* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPolygon
             || poGeometry->getGeometryType() == wkbPolygon25D )
    {
        OGRPolygon      *poPolygon = (OGRPolygon *) poGeometry;

        if( poPolygon->getExteriorRing() != NULL )
        {
            if( !GeometryAppend( poPolygon->getExteriorRing() ) )
                return FALSE;
        }

        for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
        {
            OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);

            if( !GeometryAppend( poRing ) )
                return FALSE;
        }
    }

    /* -------------------------------------------------------------------- */
    /*      MultiPolygon                                                    */
    /* -------------------------------------------------------------------- */
    else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiCurve
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiCurveZ )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
        int             iMember;

        if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
        {
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
        {
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
        {
        }
        else
        {
        }

        for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );
            if( !GeometryAppend( poMember ) )
                return FALSE;
        }

    }
    else if( poGeometry->getGeometryType() == wkbCompoundCurve
             || poGeometry->getGeometryType() == wkbCompoundCurveZ )
    {
        AppendCoumpoundCurve( ( OGRCompoundCurve *) poGeometry, poDS );
    } else {
        CPLError(CE_Warning, CPLE_AppDefined, "Skipping unknown geometry type '%s'", OGRGeometryTypeToName(poGeometry->getGeometryType()));
        return FALSE;
    }

    return TRUE;
}
Пример #17
0
void wxSimpleFillSymbol::DrawPolyPolygon(OGRMultiPolygon* pPoly, IDisplay* pwxGISDisplay)
{
    IDisplayTransformation* pDisplayTransformation = pwxGISDisplay->GetDisplayTransformation();
    long nNumPolys(0);
    OGRGeometryCollection* pOGRGeometryCollection = (OGRGeometryCollection*)pPoly;
    for(int i = 0; i < pOGRGeometryCollection->getNumGeometries(); i++)
    {
        OGRPolygon* pPolygon = (OGRPolygon*)pOGRGeometryCollection->getGeometryRef(i);
        nNumPolys += pPolygon->getNumInteriorRings() + 1;
    }

    int *nN = new int[nNumPolys];
    long counter(0);
    long point_count(0);
    for(int i = 0; i < pOGRGeometryCollection->getNumGeometries(); i++)
    {
        OGRPolygon* pPolygon = (OGRPolygon*)pOGRGeometryCollection->getGeometryRef(i);
        OGRLinearRing *pRing = pPolygon->getExteriorRing();
        OGRLineString *pLStr = (OGRLineString*)pRing;
        nN[counter] = pLStr->getNumPoints();
        point_count += nN[counter];
        counter++;
        int NumInteriorRings = pPolygon->getNumInteriorRings();
        for(int iPart = 0; iPart < NumInteriorRings; iPart++)
        {
            pRing = pPolygon->getInteriorRing(iPart);
            OGRLineString *pLStrInt = (OGRLineString*)pRing;
            nN[counter] = pLStrInt->getNumPoints();
            point_count += nN[counter];
            counter++;
        }
    }

    wxPoint *pFullPoints = new wxPoint[point_count];

    counter = 0;
    long pos = 0;
    for(int i = 0; i < pOGRGeometryCollection->getNumGeometries(); i++)
    {
        OGRPolygon* pPolygon = (OGRPolygon*)pOGRGeometryCollection->getGeometryRef(i);
        OGRLinearRing *pRing = pPolygon->getExteriorRing();
        OGRLineString *pLStr = (OGRLineString*)pRing;

        OGRRawPoint* pOGRRawPoints = new OGRRawPoint[nN[counter]];
        pLStr->getPoints(pOGRRawPoints);
        pDisplayTransformation->TransformCoordWorld2DC(pOGRRawPoints, nN[counter], &pFullPoints[pos]);
        pos += nN[counter];
        delete[](pOGRRawPoints);
        counter++;
        int NumInteriorRings = pPolygon->getNumInteriorRings();
        for(int iPart = 0; iPart < NumInteriorRings; iPart++)
        {
            pRing = pPolygon->getInteriorRing(iPart);
            OGRLineString *pLStrInt = (OGRLineString*)pRing;
            pOGRRawPoints = new OGRRawPoint[nN[counter]];
            pLStrInt->getPoints(pOGRRawPoints);
            pDisplayTransformation->TransformCoordWorld2DC(pOGRRawPoints, nN[counter], &pFullPoints[pos]);
            pos += nN[counter];
            delete[](pOGRRawPoints);
            counter++;
        }
    }

    pwxGISDisplay->DrawPolyPolygon(nNumPolys, nN, pFullPoints, 0, 0, wxODDEVEN_RULE);
    delete[](pFullPoints);
    delete[](nN);
}
Пример #18
0
OGRErr OGRDXFWriterLayer::WriteHATCH( OGRFeature *poFeature,
                                      OGRGeometry *poGeom )

{
/* -------------------------------------------------------------------- */
/*      For now we handle multipolygons by writing a series of          */
/*      entities.                                                       */
/* -------------------------------------------------------------------- */
    if( poGeom == NULL )
        poGeom = poFeature->GetGeometryRef();

    if ( poGeom->IsEmpty() )
    {
        return OGRERR_NONE;
    }
            
    if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom;
        int iGeom;
        OGRErr eErr = OGRERR_NONE;

        for( iGeom = 0; 
             eErr == OGRERR_NONE && iGeom < poGC->getNumGeometries(); 
             iGeom++ )
        {
            eErr = WriteHATCH( poFeature, poGC->getGeometryRef( iGeom ) );
        }

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Do we now have a geometry we can work with?                     */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) != wkbPolygon )
        return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;

/* -------------------------------------------------------------------- */
/*      Write as a hatch.                                               */
/* -------------------------------------------------------------------- */
    WriteValue( 0, "HATCH" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    WriteValue( 100, "AcDbHatch" );

    WriteValue( 10, 0 ); // elevation point X. 0 for DXF
    WriteValue( 20, 0 ); // elevation point Y
    WriteValue( 30, 0 ); // elevation point Z
    WriteValue(210, 0 ); // extrusion direction X
    WriteValue(220, 0 ); // extrusion direction Y
    WriteValue(230,1.0); // extrusion direction Z

    WriteValue( 2, "SOLID" ); // fill pattern
    WriteValue( 70, 1 ); // solid fill
    WriteValue( 71, 0 ); // associativity 

/* -------------------------------------------------------------------- */
/*      Do we have styling information?                                 */
/* -------------------------------------------------------------------- */
    OGRStyleTool *poTool = NULL;
    OGRStyleMgr oSM;

    if( poFeature->GetStyleString() != NULL )
    {
        oSM.InitFromFeature( poFeature );

        if( oSM.GetPartCount() > 0 )
            poTool = oSM.GetPart(0);
    }
    // Write style brush fore color
    if( poTool && poTool->GetType() == OGRSTCBrush )
    {
        OGRStyleBrush *poBrush = (OGRStyleBrush *) poTool;
        GBool  bDefault;

        if( poBrush->ForeColor(bDefault) != NULL && !bDefault )
            WriteValue( 62, ColorStringToDXFColor( poBrush->ForeColor(bDefault) ) );
    }
    delete poTool;

/* -------------------------------------------------------------------- */
/*      Handle a PEN tool to control drawing color and width.           */
/*      Perhaps one day also dottedness, etc.                           */
/* -------------------------------------------------------------------- */
#ifdef notdef
    if( poTool && poTool->GetType() == OGRSTCPen )
    {
        OGRStylePen *poPen = (OGRStylePen *) poTool;
        GBool  bDefault;

        if( poPen->Color(bDefault) != NULL && !bDefault )
            WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) );
        
        double dfWidthInMM = poPen->Width(bDefault);

        if( !bDefault )
            WriteValue( 370, (int) floor(dfWidthInMM * 100 + 0.5) );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a Linetype for the feature?                          */
/* -------------------------------------------------------------------- */
    CPLString osLineType = poFeature->GetFieldAsString( "Linetype" );

    if( osLineType.size() > 0 
        && (poDS->oHeaderDS.LookupLineType( osLineType ) != NULL 
            || oNewLineTypes.count(osLineType) > 0 ) )
    {
        // Already define -> just reference it.
        WriteValue( 6, osLineType );
    }
    else if( poTool != NULL && poTool->GetType() == OGRSTCPen )
    {
        CPLString osDefinition = PrepareLineTypeDefinition( poFeature, 
                                                            poTool );

        if( osDefinition != "" && osLineType == "" )
        {
            // Is this definition already created and named?
            std::map<CPLString,CPLString>::iterator it;

            for( it = oNewLineTypes.begin();
                 it != oNewLineTypes.end();
                 it++ )
            {
                if( (*it).second == osDefinition )
                {
                    osLineType = (*it).first;
                    break;
                }
            }

            // create an automatic name for it.
            if( osLineType == "" )
            {
                do 
                { 
                    osLineType.Printf( "AutoLineType-%d", nNextAutoID++ );
                }
                while( poDS->oHeaderDS.LookupLineType(osLineType) != NULL );
            }
        }

        // If it isn't already defined, add it now.
        if( osDefinition != "" && oNewLineTypes.count(osLineType) == 0 )
        {
            oNewLineTypes[osLineType] = osDefinition;
            WriteValue( 6, osLineType );
        }
    }
    delete poTool;
#endif

/* -------------------------------------------------------------------- */
/*      Process the loops (rings).                                      */
/* -------------------------------------------------------------------- */
    OGRPolygon *poPoly = (OGRPolygon *) poGeom;

    WriteValue( 91, poPoly->getNumInteriorRings() + 1 );

    for( int iRing = -1; iRing < poPoly->getNumInteriorRings(); iRing++ )
    {
        OGRLinearRing *poLR;

        if( iRing == -1 )
            poLR = poPoly->getExteriorRing();
        else
            poLR = poPoly->getInteriorRing( iRing );

        WriteValue( 92, 2 ); // Polyline
        WriteValue( 72, 0 ); // has bulge
        WriteValue( 73, 1 ); // is closed
        WriteValue( 93, poLR->getNumPoints() );
        
        for( int iVert = 0; iVert < poLR->getNumPoints(); iVert++ )
        {
            WriteValue( 10, poLR->getX(iVert) );
            WriteValue( 20, poLR->getY(iVert) );
        }

        WriteValue( 97, 0 ); // 0 source boundary objects
    }

    WriteValue( 75, 0 ); // hatch style = Hatch "odd parity" area (Normal style)
    WriteValue( 76, 1 ); // hatch pattern type = predefined
    WriteValue( 98, 0 ); // 0 seed points
    
    return OGRERR_NONE;

#ifdef notdef
/* -------------------------------------------------------------------- */
/*      Alternate unmaintained implementation as a polyline entity.     */
/* -------------------------------------------------------------------- */
    WriteValue( 0, "POLYLINE" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    WriteValue( 100, "AcDbPolyline" );
    if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) )
        WriteValue( 70, 1 );
    else
        WriteValue( 70, 0 );
    WriteValue( 66, "1" );

    int iVert;

    for( iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
    {
        WriteValue( 0, "VERTEX" );
        WriteValue( 8, "0" );
        WriteValue( 10, poLS->getX(iVert) );
        if( !WriteValue( 20, poLS->getY(iVert) ) ) 
            return OGRERR_FAILURE;

        if( poLS->getGeometryType() == wkbLineString25D )
        {
            if( !WriteValue( 30, poLS->getZ(iVert) ) )
                return OGRERR_FAILURE;
        }
    }

    WriteValue( 0, "SEQEND" );
    WriteValue( 8, "0" );
    
    return OGRERR_NONE;
#endif
}
Пример #19
0
OGRErr OGRDXFWriterLayer::WritePOLYLINE( OGRFeature *poFeature,
                                         OGRGeometry *poGeom )

{
/* -------------------------------------------------------------------- */
/*      For now we handle multilinestrings by writing a series of       */
/*      entities.                                                       */
/* -------------------------------------------------------------------- */
    if( poGeom == NULL )
        poGeom = poFeature->GetGeometryRef();

    if ( poGeom->IsEmpty() )
    {
        return OGRERR_NONE;
    }
            
    if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon 
        || wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom;
        int iGeom;
        OGRErr eErr = OGRERR_NONE;

        for( iGeom = 0; 
             eErr == OGRERR_NONE && iGeom < poGC->getNumGeometries(); 
             iGeom++ )
        {
            eErr = WritePOLYLINE( poFeature, poGC->getGeometryRef( iGeom ) );
        }

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Polygons are written with on entity per ring.                   */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon )
    {
        OGRPolygon *poPoly = (OGRPolygon *) poGeom;
        int iGeom;
        OGRErr eErr;

        eErr = WritePOLYLINE( poFeature, poPoly->getExteriorRing() );
        for( iGeom = 0; 
             eErr == OGRERR_NONE && iGeom < poPoly->getNumInteriorRings(); 
             iGeom++ )
        {
            eErr = WritePOLYLINE( poFeature, poPoly->getInteriorRing(iGeom) );
        }

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Do we now have a geometry we can work with?                     */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) != wkbLineString )
        return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;

    OGRLineString *poLS = (OGRLineString *) poGeom;

/* -------------------------------------------------------------------- */
/*      Write as a lightweight polygon,                                 */
/*       or as POLYLINE if the line contains different heights          */
/* -------------------------------------------------------------------- */
    int bHasDifferentZ = FALSE;
    if( poLS->getGeometryType() == wkbLineString25D )
    {
        double z0 = poLS->getZ(0);
        for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
        {
            if (z0 != poLS->getZ(iVert))
            {
                bHasDifferentZ = TRUE;
                break;
            }
        }
    }

    WriteValue( 0, bHasDifferentZ ? "POLYLINE" : "LWPOLYLINE" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    if( bHasDifferentZ )
    {
        WriteValue( 100, "AcDb3dPolyline" );
        WriteValue( 10, 0.0 );
        WriteValue( 20, 0.0 );
        WriteValue( 30, 0.0 );
    }
    else
        WriteValue( 100, "AcDbPolyline" );
    if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) )
        WriteValue( 70, 1 + (bHasDifferentZ ? 8 : 0) );
    else
        WriteValue( 70, 0 + (bHasDifferentZ ? 8 : 0) );
    if( !bHasDifferentZ )
        WriteValue( 90, poLS->getNumPoints() );
    else
        WriteValue( 66, "1" );  // Vertex Flag

/* -------------------------------------------------------------------- */
/*      Do we have styling information?                                 */
/* -------------------------------------------------------------------- */
    OGRStyleTool *poTool = NULL;
    OGRStyleMgr oSM;

    if( poFeature->GetStyleString() != NULL )
    {
        oSM.InitFromFeature( poFeature );

        if( oSM.GetPartCount() > 0 )
            poTool = oSM.GetPart(0);
    }

/* -------------------------------------------------------------------- */
/*      Handle a PEN tool to control drawing color and width.           */
/*      Perhaps one day also dottedness, etc.                           */
/* -------------------------------------------------------------------- */
    if( poTool && poTool->GetType() == OGRSTCPen )
    {
        OGRStylePen *poPen = (OGRStylePen *) poTool;
        GBool  bDefault;

        if( poPen->Color(bDefault) != NULL && !bDefault )
            WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) );

        // we want to fetch the width in ground units. 
        poPen->SetUnit( OGRSTUGround, 1.0 );
        double dfWidth = poPen->Width(bDefault);

        if( !bDefault )
            WriteValue( 370, (int) floor(dfWidth * 100 + 0.5) );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a Linetype for the feature?                          */
/* -------------------------------------------------------------------- */
    CPLString osLineType = poFeature->GetFieldAsString( "Linetype" );

    if( osLineType.size() > 0 
        && (poDS->oHeaderDS.LookupLineType( osLineType ) != NULL 
            || oNewLineTypes.count(osLineType) > 0 ) )
    {
        // Already define -> just reference it.
        WriteValue( 6, osLineType );
    }
    else if( poTool != NULL && poTool->GetType() == OGRSTCPen )
    {
        CPLString osDefinition = PrepareLineTypeDefinition( poFeature, 
                                                            poTool );

        if( osDefinition != "" && osLineType == "" )
        {
            // Is this definition already created and named?
            std::map<CPLString,CPLString>::iterator it;

            for( it = oNewLineTypes.begin();
                 it != oNewLineTypes.end();
                 it++ )
            {
                if( (*it).second == osDefinition )
                {
                    osLineType = (*it).first;
                    break;
                }
            }

            // create an automatic name for it.
            if( osLineType == "" )
            {
                do 
                { 
                    osLineType.Printf( "AutoLineType-%d", nNextAutoID++ );
                }
                while( poDS->oHeaderDS.LookupLineType(osLineType) != NULL );
            }
        }

        // If it isn't already defined, add it now.
        if( osDefinition != "" && oNewLineTypes.count(osLineType) == 0 )
        {
            oNewLineTypes[osLineType] = osDefinition;
            WriteValue( 6, osLineType );
        }
    }

/* -------------------------------------------------------------------- */
/*      Write the vertices                                              */
/* -------------------------------------------------------------------- */

    if( !bHasDifferentZ && poLS->getGeometryType() == wkbLineString25D )
    {
     // if LWPOLYLINE with Z write it only once
        if( !WriteValue( 38, poLS->getZ(0) ) )
            return OGRERR_FAILURE;
    }

    int iVert;

    for( iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
    {
        if( bHasDifferentZ ) 
        {
            WriteValue( 0, "VERTEX" );
            WriteValue( 100, "AcDbEntity" );
            WriteValue( 100, "AcDbVertex" );
            WriteValue( 100, "AcDb3dPolylineVertex" );
            WriteCore( poFeature );
        }
        WriteValue( 10, poLS->getX(iVert) );
        if( !WriteValue( 20, poLS->getY(iVert) ) ) 
            return OGRERR_FAILURE;

        if( bHasDifferentZ )
        {
            if( !WriteValue( 30 , poLS->getZ(iVert) ) )
                return OGRERR_FAILURE;
            WriteValue( 70, 32 );
        }
    }

    if( bHasDifferentZ )
    {
        WriteValue( 0, "SEQEND" );
        WriteCore( poFeature );
        WriteValue( 100, "AcDbEntity" );
    }
    
    delete poTool;

    return OGRERR_NONE;

#ifdef notdef
/* -------------------------------------------------------------------- */
/*      Alternate unmaintained implementation as a polyline entity.     */
/* -------------------------------------------------------------------- */
    WriteValue( 0, "POLYLINE" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    WriteValue( 100, "AcDbPolyline" );
    if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) )
        WriteValue( 70, 1 );
    else
        WriteValue( 70, 0 );
    WriteValue( 66, "1" );

    int iVert;

    for( iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
    {
        WriteValue( 0, "VERTEX" );
        WriteValue( 8, "0" );
        WriteValue( 10, poLS->getX(iVert) );
        if( !WriteValue( 20, poLS->getY(iVert) ) ) 
            return OGRERR_FAILURE;

        if( poLS->getGeometryType() == wkbLineString25D )
        {
            if( !WriteValue( 30, poLS->getZ(iVert) ) )
                return OGRERR_FAILURE;
        }
    }

    WriteValue( 0, "SEQEND" );
    WriteValue( 8, "0" );
    
    return OGRERR_NONE;
#endif
}
Пример #20
0
OGRErr 
OGROCIWritableLayer::TranslateElementGroup( OGRGeometry *poGeometry )

{
    switch( wkbFlatten(poGeometry->getGeometryType()) )
    {
      case wkbPoint:
      {
          OGRPoint *poPoint = (OGRPoint *) poGeometry;

          PushElemInfo( nOrdinalCount+1, 1, 1 );

          PushOrdinal( poPoint->getX() );
          PushOrdinal( poPoint->getY() );
          if( nDimension == 3 )
              PushOrdinal( poPoint->getZ() );

          return OGRERR_NONE;
      }

      case wkbLineString:
      {
          OGRLineString *poLine = (OGRLineString *) poGeometry;
          int  iVert;
          
          PushElemInfo( nOrdinalCount+1, 2, 1 );

          for( iVert = 0; iVert < poLine->getNumPoints(); iVert++ )
          {
              PushOrdinal( poLine->getX(iVert) );
              PushOrdinal( poLine->getY(iVert) );
              if( nDimension == 3 )
                  PushOrdinal( poLine->getZ(iVert) );
          }
          return OGRERR_NONE;
      }

      case wkbPolygon:
      {
          OGRPolygon *poPoly = (OGRPolygon *) poGeometry;
          int iRing;

          for( iRing = -1; iRing < poPoly->getNumInteriorRings(); iRing++ )
          {
              OGRLinearRing *poRing;
              int            iVert;

              if( iRing == -1 )
                  poRing = poPoly->getExteriorRing();
              else
                  poRing = poPoly->getInteriorRing(iRing);

              if( iRing == -1 )
                  PushElemInfo( nOrdinalCount+1, 1003, 1 );
              else
                  PushElemInfo( nOrdinalCount+1, 2003, 1 );

              if( (iRing == -1 && poRing->isClockwise())
                  || (iRing != -1 && !poRing->isClockwise()) )
              {
                  for( iVert = poRing->getNumPoints()-1; iVert >= 0; iVert-- )
                  {
                      PushOrdinal( poRing->getX(iVert) );
                      PushOrdinal( poRing->getY(iVert) );
                      if( nDimension == 3 )
                          PushOrdinal( poRing->getZ(iVert) );
                  }
              }
              else
              {
                  for( iVert = 0; iVert < poRing->getNumPoints(); iVert++ )
                  {
                      PushOrdinal( poRing->getX(iVert) );
                      PushOrdinal( poRing->getY(iVert) );
                      if( nDimension == 3 )
                          PushOrdinal( poRing->getZ(iVert) );
                  }
              }
          }

          return OGRERR_NONE;
      }

      default:
      {
          return OGRERR_FAILURE;
      }
    }
}
Пример #21
0
static void GDALCollectRingsFromGeometry(
    OGRGeometry *poShape, 
    std::vector<double> &aPointX, std::vector<double> &aPointY, 
    std::vector<double> &aPointVariant, 
    std::vector<int> &aPartSize, GDALBurnValueSrc eBurnValueSrc)

{
    if( poShape == NULL )
        return;

    OGRwkbGeometryType eFlatType = wkbFlatten(poShape->getGeometryType());
    int i;

    if ( eFlatType == wkbPoint )
    {
        OGRPoint    *poPoint = (OGRPoint *) poShape;
        int nNewCount = aPointX.size() + 1;

        aPointX.reserve( nNewCount );
        aPointY.reserve( nNewCount );
        aPointX.push_back( poPoint->getX() );
        aPointY.push_back( poPoint->getY() );
        aPartSize.push_back( 1 );
        if( eBurnValueSrc != GBV_UserBurnValue )
        {
            /*switch( eBurnValueSrc )
            {
            case GBV_Z:*/
                aPointVariant.reserve( nNewCount );
                aPointVariant.push_back( poPoint->getZ() );
                /*break;
            case GBV_M:
                aPointVariant.reserve( nNewCount );
                aPointVariant.push_back( poPoint->getM() );
            }*/
        }
    }
    else if ( eFlatType == wkbLineString )
    {
        OGRLineString   *poLine = (OGRLineString *) poShape;
        int nCount = poLine->getNumPoints();
        int nNewCount = aPointX.size() + nCount;

        aPointX.reserve( nNewCount );
        aPointY.reserve( nNewCount );
        if( eBurnValueSrc != GBV_UserBurnValue )
            aPointVariant.reserve( nNewCount );
        for ( i = nCount - 1; i >= 0; i-- )
        {
            aPointX.push_back( poLine->getX(i) );
            aPointY.push_back( poLine->getY(i) );
            if( eBurnValueSrc != GBV_UserBurnValue )
            {
                /*switch( eBurnValueSrc )
                {
                    case GBV_Z:*/
                        aPointVariant.push_back( poLine->getZ(i) );
                        /*break;
                    case GBV_M:
                        aPointVariant.push_back( poLine->getM(i) );
                }*/
            }
        }
        aPartSize.push_back( nCount );
    }
    else if ( EQUAL(poShape->getGeometryName(),"LINEARRING") )
    {
        OGRLinearRing *poRing = (OGRLinearRing *) poShape;
        int nCount = poRing->getNumPoints();
        int nNewCount = aPointX.size() + nCount;

        aPointX.reserve( nNewCount );
        aPointY.reserve( nNewCount );
        if( eBurnValueSrc != GBV_UserBurnValue )
            aPointVariant.reserve( nNewCount );
        for ( i = nCount - 1; i >= 0; i-- )
        {
            aPointX.push_back( poRing->getX(i) );
            aPointY.push_back( poRing->getY(i) );
        }
        if( eBurnValueSrc != GBV_UserBurnValue )
        {
            /*switch( eBurnValueSrc )
            {
            case GBV_Z:*/
                aPointVariant.push_back( poRing->getZ(i) );
                /*break;
            case GBV_M:
                aPointVariant.push_back( poRing->getM(i) );
            }*/
        }
        aPartSize.push_back( nCount );
    }
    else if( eFlatType == wkbPolygon )
    {
        OGRPolygon *poPolygon = (OGRPolygon *) poShape;
        
        GDALCollectRingsFromGeometry( poPolygon->getExteriorRing(), 
                                      aPointX, aPointY, aPointVariant, 
                                      aPartSize, eBurnValueSrc );

        for( i = 0; i < poPolygon->getNumInteriorRings(); i++ )
            GDALCollectRingsFromGeometry( poPolygon->getInteriorRing(i), 
                                          aPointX, aPointY, aPointVariant, 
                                          aPartSize, eBurnValueSrc );
    }
    
    else if( eFlatType == wkbMultiPoint
             || eFlatType == wkbMultiLineString
             || eFlatType == wkbMultiPolygon
             || eFlatType == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poShape;

        for( i = 0; i < poGC->getNumGeometries(); i++ )
            GDALCollectRingsFromGeometry( poGC->getGeometryRef(i),
                                          aPointX, aPointY, aPointVariant, 
                                          aPartSize, eBurnValueSrc );
    }
    else
    {
        CPLDebug( "GDAL", "Rasterizer ignoring non-polygonal geometry." );
    }
}
Пример #22
0
void wxGISSimpleFillSymbol::Draw(const wxGISGeometry &Geometry, int nLevel)
{
    if(!Geometry.IsOk() || !m_pDisplay)
        return;

    OGRwkbGeometryType eGeomType = wkbFlatten(Geometry.GetType());
    if(eGeomType != wkbPolygon && eGeomType != wkbMultiPolygon)
        return;

    OGREnvelope Env = Geometry.GetEnvelope();
    if(!m_pDisplay->CanDraw(Env))
        return;

    wxCriticalSectionLocker lock(m_pDisplay->GetLock());

	if(!m_pDisplay->CheckDrawAsPoint(Env, m_pLineSymbol->GetWidth()))
    {
        OGRGeometry *pGeom = Geometry;

        if(eGeomType == wkbMultiPolygon)
        {
		    OGRGeometryCollection* pOGRGeometryCollection = (OGRGeometryCollection*)pGeom;
		    for(int i = 0; i < pOGRGeometryCollection->getNumGeometries(); ++i)
			    Draw(wxGISGeometry(pOGRGeometryCollection->getGeometryRef(i), false));
            return;
        }

        OGRPolygon* pPolygon = (OGRPolygon*)pGeom;
        const OGRLinearRing *pRing = pPolygon->getExteriorRing();
        if(!m_pLineSymbol->DrawPreserved((OGRLineString*)pRing, true))
        {
            return;
        }

	    int nNumInteriorRings = pPolygon->getNumInteriorRings();
	    for(int nPart = 0; nPart < nNumInteriorRings; ++nPart)
	    {
		    pRing = pPolygon->getInteriorRing(nPart);
            OGREnvelope IntEnv;
            pRing->getEnvelope(&IntEnv);
		    if(!m_pDisplay->CheckDrawAsPoint(IntEnv, m_pLineSymbol->GetWidth()))
            {
			    m_pLineSymbol->DrawPreserved((OGRLineString*)pRing, true);
            }
	    }

        if(m_Color.Alpha() > 0)
        {
            switch(m_eFillRule)
            {
            case enumGISFillRuleWinding:
	            m_pDisplay->SetFillRule( CAIRO_FILL_RULE_WINDING );
                break;
            case enumGISFillRuleOdd:
	            m_pDisplay->SetFillRule( CAIRO_FILL_RULE_EVEN_ODD );
                break;
            }
	        m_pDisplay->SetColor(m_Color);
	        m_pDisplay->FillPreserve();
        }
        m_pLineSymbol->SetStyleToDisplay();
    }
    else
    {
         m_pLineSymbol->SetLimitStyleToDisplay();
    }

	m_pDisplay->Stroke();
}
//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context
bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometry* geometry, bool isaLinearRing )
{
  OGRwkbGeometryType wkbGeometryType = wkbFlatten( geometry->getGeometryType() );

  // Simplify the geometry rewriting temporally its WKB-stream for saving calloc's.
  if ( wkbGeometryType == wkbLineString )
  {
    OGRLineString* lineString = ( OGRLineString* )geometry;

    int numPoints = lineString->getNumPoints();
    if (( isaLinearRing && numPoints <= 5 ) || ( !isaLinearRing && numPoints <= 2 ) ) return false;

    OGREnvelope env;
    geometry->getEnvelope( &env );
    QgsRectangle envelope( env.MinX, env.MinY, env.MaxX, env.MaxY );

    // Can replace the geometry by its BBOX ?
    if (( mSimplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) && canbeGeneralizedByMapBoundingBox( envelope ) )
    {
      OGRRawPoint* points = NULL;
      int numPoints = 0;

      double x1 = envelope.xMinimum();
      double y1 = envelope.yMinimum();
      double x2 = envelope.xMaximum();
      double y2 = envelope.yMaximum();

      if ( isaLinearRing )
      {
        numPoints = 5;
        points = mallocPoints( numPoints );
        points[0].x = x1; points[0].y = y1;
        points[1].x = x2; points[1].y = y1;
        points[2].x = x2; points[2].y = y2;
        points[3].x = x1; points[3].y = y2;
        points[4].x = x1; points[4].y = y1;
      }
      else
      {
        numPoints = 2;
        points = mallocPoints( numPoints );
        points[0].x = x1; points[0].y = y1;
        points[1].x = x2; points[1].y = y2;
      }
      lineString->setPoints( numPoints, points );
      lineString->flattenTo2D();
      return true;
    }
    else
      if ( mSimplifyFlags & QgsMapToPixelSimplifier::SimplifyGeometry )
      {
        QGis::GeometryType geometryType = isaLinearRing ? QGis::Polygon : QGis::Line;
        int numSimplifiedPoints = 0;

        OGRRawPoint* points = mallocPoints( numPoints );
        double* xptr = ( double* )points;
        double* yptr = xptr + 1;
        lineString->getPoints( points );

        if ( simplifyOgrGeometry( geometryType, envelope, xptr, 16, yptr, 16, numPoints, numSimplifiedPoints ) )
        {
          lineString->setPoints( numSimplifiedPoints, points );
          lineString->flattenTo2D();
        }
        return numSimplifiedPoints != numPoints;
      }
  }
  else
    if ( wkbGeometryType == wkbPolygon )
    {
      OGRPolygon* polygon = ( OGRPolygon* )geometry;
      bool result = simplifyOgrGeometry( polygon->getExteriorRing(), true );

      for ( int i = 0, numInteriorRings = polygon->getNumInteriorRings(); i < numInteriorRings; ++i )
      {
        result |= simplifyOgrGeometry( polygon->getInteriorRing( i ), true );
      }
      if ( result ) polygon->flattenTo2D();
      return result;
    }
    else
      if ( wkbGeometryType == wkbMultiLineString || wkbGeometryType == wkbMultiPolygon )
      {
        OGRGeometryCollection* collection = ( OGRGeometryCollection* )geometry;
        bool result = false;

        for ( int i = 0, numGeometries = collection->getNumGeometries(); i < numGeometries; ++i )
        {
          result |= simplifyOgrGeometry( collection->getGeometryRef( i ), wkbGeometryType == wkbMultiPolygon );
        }
        if ( result ) collection->flattenTo2D();
        return result;
      }
  return false;
}
OGRErr OGRWritableDWGLayer::WriteEntity( OGRGeometry *poGeom,
                                         OdDbObjectPtr *ppObjectRet )

{
    switch( wkbFlatten(poGeom->getGeometryType()) )
    {
      case wkbPoint:
      {
          OGRPoint *poOGRPoint = (OGRPoint *) poGeom;
          OdDbPointPtr pPoint = OdDbPoint::createObject();
          
          pPoint->setPosition( 
              OdGePoint3d(poOGRPoint->getX(), poOGRPoint->getY(), 
                          poOGRPoint->getZ() ) );

          pPoint->setLayer( hLayerId, false );
          poDS->pMs->appendOdDbEntity( pPoint );
          
          if( ppObjectRet != NULL )
              *ppObjectRet = pPoint;
          return OGRERR_NONE;
      }

      case wkbLineString:
      {
          OGRLineString *poLine = (OGRLineString *) poGeom;

          // Add a 2d polyline with vertices.
          OdDb2dPolylinePtr p2dPl = OdDb2dPolyline::createObject();
 
          int i;

          for (i = 0; i < poLine->getNumPoints(); i++)
          {
              OdDb2dVertexPtr pV;
              OdGePoint3d pos;

              pos.x = poLine->getX(i);
              pos.y = poLine->getY(i);
              pos.z = poLine->getZ(i);

              pV = OdDb2dVertex::createObject();
              p2dPl->appendVertex(pV);

              pV->setPosition(pos);
          }
  
          p2dPl->setLayer( hLayerId, false );

          poDS->pMs->appendOdDbEntity( p2dPl );

          if( ppObjectRet != NULL )
              *ppObjectRet = p2dPl;

          return OGRERR_NONE;
      }

      case wkbPolygon:
      {
          OGRPolygon *poPoly = (OGRPolygon *) poGeom;
          int iRing;
          OGRErr eErr;

          for( iRing = -1; iRing < poPoly->getNumInteriorRings(); iRing++ )
          {
              OGRLinearRing *poRing;

              if( iRing == -1 )
                  poRing = poPoly->getExteriorRing();
              else
                  poRing = poPoly->getInteriorRing( iRing );

              if( iRing == -1 )
                  eErr = WriteEntity( poRing, ppObjectRet );
              else
                  eErr = WriteEntity( poRing, NULL );
              if( eErr != OGRERR_NONE )
                  return eErr;

          }

          return OGRERR_NONE;
      }

      case wkbGeometryCollection:
      case wkbMultiPolygon:
      case wkbMultiPoint:
      case wkbMultiLineString:
      {
          OGRGeometryCollection *poColl = (OGRGeometryCollection *) poGeom;
          int iSubGeom;
          OGRErr eErr;

          for( iSubGeom=0; iSubGeom < poColl->getNumGeometries(); iSubGeom++ )
          {
              OGRGeometry *poGeom = poColl->getGeometryRef( iSubGeom );
              
              if( iSubGeom == 0 )
                  eErr = WriteEntity( poGeom, ppObjectRet );
              else
                  eErr = WriteEntity( poGeom, NULL );
                  
              if( eErr != OGRERR_NONE )
                  return eErr;
          }
          return OGRERR_NONE;
      }

      default:
        return OGRERR_FAILURE;
    }
}
Пример #25
0
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);
    }
}
Пример #26
0
static bool OGR2KMLGeometryAppend( OGRGeometry *poGeometry,
                                   char **ppszText, size_t *pnLength,
                                   size_t *pnMaxLength, char *szAltitudeMode )

{
/* -------------------------------------------------------------------- */
/*      2D Point                                                        */
/* -------------------------------------------------------------------- */
    if( poGeometry->getGeometryType() == wkbPoint )
    {
        OGRPoint* poPoint = static_cast<OGRPoint*>(poGeometry);

        if (poPoint->getCoordinateDimension() == 0)
        {
            _GrowBuffer( *pnLength + 10,
                     ppszText, pnMaxLength );
            strcat( *ppszText + *pnLength, "<Point/>");
            *pnLength += strlen( *ppszText + *pnLength );
        }
        else
        {
            char szCoordinate[256] = { 0 };
            MakeKMLCoordinate( szCoordinate, sizeof(szCoordinate),
                            poPoint->getX(), poPoint->getY(), 0.0, FALSE );

            _GrowBuffer( *pnLength + strlen(szCoordinate) + 60,
                         ppszText, pnMaxLength );

            snprintf( *ppszText + *pnLength, *pnMaxLength - *pnLength,
                      "<Point><coordinates>%s</coordinates></Point>",
                      szCoordinate );

            *pnLength += strlen( *ppszText + *pnLength );
        }
    }
/* -------------------------------------------------------------------- */
/*      3D Point                                                        */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPoint25D )
    {
        char szCoordinate[256] = { 0 };
        OGRPoint *poPoint = static_cast<OGRPoint*>(poGeometry);

        MakeKMLCoordinate( szCoordinate, sizeof(szCoordinate),
                           poPoint->getX(), poPoint->getY(), poPoint->getZ(),
                           true );

        if (NULL == szAltitudeMode)
        {
            _GrowBuffer( *pnLength + strlen(szCoordinate) + 70,
                         ppszText, pnMaxLength );

            snprintf( *ppszText + *pnLength, *pnMaxLength - *pnLength,
                      "<Point><coordinates>%s</coordinates></Point>",
                      szCoordinate );
        }
        else
        {
            _GrowBuffer( *pnLength + strlen(szCoordinate)
                         + strlen(szAltitudeMode) + 70,
                         ppszText, pnMaxLength );

            snprintf( *ppszText + *pnLength, *pnMaxLength - *pnLength,
                      "<Point>%s<coordinates>%s</coordinates></Point>",
                      szAltitudeMode, szCoordinate );
        }

        *pnLength += strlen( *ppszText + *pnLength );
    }
/* -------------------------------------------------------------------- */
/*      LineString and LinearRing                                       */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbLineString
             || poGeometry->getGeometryType() == wkbLineString25D )
    {
        const bool bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING");

        if( bRing )
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<LinearRing>" );
        else
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<LineString>" );

        if (NULL != szAltitudeMode)
        {
            AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode);
        }

        AppendCoordinateList( reinterpret_cast<OGRLineString *>(poGeometry),
                              ppszText, pnLength, pnMaxLength );

        if( bRing )
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</LinearRing>" );
        else
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</LineString>" );
    }

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPolygon
             || poGeometry->getGeometryType() == wkbPolygon25D )
    {
        OGRPolygon* poPolygon = static_cast<OGRPolygon*>(poGeometry);

        AppendString( ppszText, pnLength, pnMaxLength, "<Polygon>" );

        if (NULL != szAltitudeMode)
        {
            AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode);
        }

        if( poPolygon->getExteriorRing() != NULL )
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<outerBoundaryIs>" );

            if( !OGR2KMLGeometryAppend( poPolygon->getExteriorRing(),
                                        ppszText, pnLength, pnMaxLength,
                                        szAltitudeMode ) )
            {
                return false;
            }
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</outerBoundaryIs>" );
        }

        for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
        {
            OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);

            AppendString( ppszText, pnLength, pnMaxLength,
                          "<innerBoundaryIs>" );

            if( !OGR2KMLGeometryAppend( poRing, ppszText, pnLength,
                                        pnMaxLength, szAltitudeMode ) )
            {
                return false;
            }
            AppendString( ppszText, pnLength, pnMaxLength,
                          "</innerBoundaryIs>" );
        }

        AppendString( ppszText, pnLength, pnMaxLength,
                      "</Polygon>" );
    }

/* -------------------------------------------------------------------- */
/*      MultiPolygon                                                    */
/* -------------------------------------------------------------------- */
    else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeometry->getGeometryType()) ==
                wkbGeometryCollection )
    {
        OGRGeometryCollection* poGC = NULL;
        poGC = static_cast<OGRGeometryCollection*>(poGeometry);

        AppendString( ppszText, pnLength, pnMaxLength, "<MultiGeometry>" );

        // XXX - mloskot
        //if (NULL != szAltitudeMode)
        //{
        //    AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode);
        //}

        for( int iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );

            if( !OGR2KMLGeometryAppend( poMember, ppszText, pnLength,
                                        pnMaxLength, szAltitudeMode ) )
            {
                return false;
            }
        }

        AppendString( ppszText, pnLength, pnMaxLength, "</MultiGeometry>" );
    }
    else
    {
        return false;
    }

    return true;
}
Пример #27
0
int OGRILI1Layer::GeometryAppend( OGRGeometry *poGeometry )
{
/* -------------------------------------------------------------------- */
/*      2D Point                                                        */
/* -------------------------------------------------------------------- */
    if( poGeometry->getGeometryType() == wkbPoint )
    {
        /* embedded in from non-geometry fields */
    }
/* -------------------------------------------------------------------- */
/*      3D Point                                                        */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPoint25D )
    {
        /* embedded in from non-geometry fields */
    }

/* -------------------------------------------------------------------- */
/*      LineString and LinearRing                                       */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbLineString
             || poGeometry->getGeometryType() == wkbLineString25D )
    {
        AppendCoordinateList( (OGRLineString *) poGeometry, poDS );
    }

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPolygon
             || poGeometry->getGeometryType() == wkbPolygon25D )
    {
        OGRPolygon      *poPolygon = (OGRPolygon *) poGeometry;

        if( poPolygon->getExteriorRing() != NULL )
        {
            if( !GeometryAppend( poPolygon->getExteriorRing() ) )
                return FALSE;
        }

        for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
        {
            OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);

            if( !GeometryAppend( poRing ) )
                return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      MultiPolygon                                                    */
/* -------------------------------------------------------------------- */
    else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
        int             iMember;

        if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
        {
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
        {
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
        {
        }
        else
        {
        }

        for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );

            if( !GeometryAppend( poMember ) )
                return FALSE;
        }

    }

    else
        return FALSE;

    return TRUE;
}
Пример #28
0
ElementPtr geom2kml (
    OGRGeometry * poOgrGeom,
    int extra,
    KmlFactory * poKmlFactory )
{
    int i;

    if ( !poOgrGeom ) {
        return NULL;
    }

    /***** ogr geom vars *****/

    OGRPoint *poOgrPoint = NULL;
    OGRLineString *poOgrLineString;
    OGRPolygon *poOgrPolygon;
    OGRGeometryCollection *poOgrMultiGeom;

    /***** libkml geom vars *****/

    CoordinatesPtr coordinates;
    PointPtr poKmlPoint;
    LineStringPtr poKmlLineString;
    LinearRingPtr poKmlLinearRing;
    OuterBoundaryIsPtr poKmlOuterRing;
    InnerBoundaryIsPtr poKmlInnerRing;
    PolygonPtr poKmlPolygon;
    MultiGeometryPtr poKmlMultiGeometry;

    ElementPtr poKmlGeometry;
    ElementPtr poKmlTmpGeometry;

    /***** other vars *****/

    double x,
        y,
        z;

    int numpoints = 0;
    int nGeom;
    OGRwkbGeometryType type = poOgrGeom->getGeometryType (  );

    switch ( type ) {

    case wkbPoint:

        poOgrPoint = ( OGRPoint * ) poOgrGeom;
        if (poOgrPoint->getCoordinateDimension() == 0)
        {
            poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint (  );
        }
        else
        {
            x = poOgrPoint->getX (  );
            y = poOgrPoint->getY (  );

            if ( x > 180 )
                x -= 360;

            coordinates = poKmlFactory->CreateCoordinates (  );
            coordinates->add_latlng ( y, x );
            poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint (  );
            poKmlPoint->set_coordinates ( coordinates );
        }

        break;

    case wkbPoint25D:
        poOgrPoint = ( OGRPoint * ) poOgrGeom;

        x = poOgrPoint->getX (  );
        y = poOgrPoint->getY (  );
        z = poOgrPoint->getZ (  );

        if ( x > 180 )
            x -= 360;

        coordinates = poKmlFactory->CreateCoordinates (  );
        coordinates->add_latlngalt ( y, x, z );
        poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint (  );
        poKmlPoint->set_coordinates ( coordinates );

        break;

    case wkbLineString:
        poOgrLineString = ( OGRLineString * ) poOgrGeom;

        if( extra >= 0 )
        {
            ((OGRLinearRing*)poOgrGeom)->closeRings();
        }

        numpoints = poOgrLineString->getNumPoints (  );
        if( extra >= 0 )
        {
            if( numpoints < 4 &&
                CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) )
            {
                CPLError(CE_Failure, CPLE_NotSupported, "A linearring should have at least 4 points");
                return NULL;
            }
        }
        else
        {
            if( numpoints < 2 &&
                CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) )
            {
                CPLError(CE_Failure, CPLE_NotSupported, "A linestring should have at least 2 points");
                return NULL;
            }
        }

        coordinates = poKmlFactory->CreateCoordinates (  );

        poOgrPoint = new OGRPoint (  );

        for ( i = 0; i < numpoints; i++ ) {
            poOgrLineString->getPoint ( i, poOgrPoint );

            x = poOgrPoint->getX (  );
            y = poOgrPoint->getY (  );

            if ( x > 180 )
                x -= 360;

            coordinates->add_latlng ( y, x );
        }
        delete poOgrPoint;

        /***** check if its a wkbLinearRing *****/

        if ( extra < 0 ) {

            poKmlGeometry = poKmlLineString =
                poKmlFactory->CreateLineString (  );
            poKmlLineString->set_coordinates ( coordinates );

            break;
        }

      /***** fallthrough *****/

    case wkbLinearRing:        //this case is for readability only

        poKmlLinearRing = poKmlFactory->CreateLinearRing (  );
        poKmlLinearRing->set_coordinates ( coordinates );

        if ( !extra ) {
            poKmlOuterRing = poKmlFactory->CreateOuterBoundaryIs (  );
            poKmlOuterRing->set_linearring ( poKmlLinearRing );
            poKmlGeometry = poKmlOuterRing;
        }
        else {
            poKmlGeometry = poKmlInnerRing =
                poKmlFactory->CreateInnerBoundaryIs (  );
            poKmlInnerRing->set_linearring ( poKmlLinearRing );
        }

        break;

    case wkbLineString25D:

        poOgrLineString = ( OGRLineString * ) poOgrGeom;

        if( extra >= 0 )
        {
            ((OGRLinearRing*)poOgrGeom)->closeRings();
        }

        numpoints = poOgrLineString->getNumPoints (  );
        if( extra >= 0 )
        {
            if( numpoints < 4 &&
                CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) )
            {
                CPLError(CE_Failure, CPLE_NotSupported, "A linearring should have at least 4 points");
                return NULL;
            }
        }
        else
        {
            if( numpoints < 2 &&
                CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) )
            {
                CPLError(CE_Failure, CPLE_NotSupported, "A linestring should have at least 2 points");
                return NULL;
            }
        }

        coordinates = poKmlFactory->CreateCoordinates (  );
        poOgrPoint = new OGRPoint (  );

        for ( i = 0; i < numpoints; i++ ) {
            poOgrLineString->getPoint ( i, poOgrPoint );

            x = poOgrPoint->getX (  );
            y = poOgrPoint->getY (  );
            z = poOgrPoint->getZ (  );

            if ( x > 180 )
                x -= 360;

            coordinates->add_latlngalt ( y, x, z );
        }
        delete poOgrPoint;

        /***** check if its a wkbLinearRing *****/

        if ( extra < 0 ) {

            poKmlGeometry = poKmlLineString =
                poKmlFactory->CreateLineString (  );
            poKmlLineString->set_coordinates ( coordinates );

            break;
        }
            /***** fallthrough *****/

        //case wkbLinearRing25D: // this case is for readability only

        poKmlLinearRing = poKmlFactory->CreateLinearRing (  );
        poKmlLinearRing->set_coordinates ( coordinates );

        if ( !extra ) {
            poKmlGeometry = poKmlOuterRing =
                poKmlFactory->CreateOuterBoundaryIs (  );
            poKmlOuterRing->set_linearring ( poKmlLinearRing );
        }
        else {
            poKmlGeometry = poKmlInnerRing =
                poKmlFactory->CreateInnerBoundaryIs (  );
            poKmlInnerRing->set_linearring ( poKmlLinearRing );
        }

        break;

    case wkbPolygon:

        CPLErrorReset();
        if( CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) &&
            OGRGeometryFactory::haveGEOS() && (!poOgrGeom->IsValid() ||
             CPLGetLastErrorType() != CE_None) )
        {
            CPLError(CE_Failure, CPLE_NotSupported, "Invalid polygon");
            return NULL;
        }
        poOgrPolygon = ( OGRPolygon * ) poOgrGeom;

        poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon (  );

        poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing (  ),
                                      0, poKmlFactory );
        poKmlPolygon->
            set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) );

        nGeom = poOgrPolygon->getNumInteriorRings (  );
        for ( i = 0; i < nGeom; i++ ) {
            poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ),
                                          i + 1, poKmlFactory );
            poKmlPolygon->
                add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) );
        }

        break;

    case wkbPolygon25D:

        CPLErrorReset();
        if( CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) &&
            OGRGeometryFactory::haveGEOS() && (!poOgrGeom->IsValid() ||
             CPLGetLastErrorType() != CE_None) )
        {
            CPLError(CE_Failure, CPLE_NotSupported, "Invalid polygon");
            return NULL;
        }
        poOgrPolygon = ( OGRPolygon * ) poOgrGeom;

        poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon (  );

        poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing (  ),
                                      0, poKmlFactory );
        poKmlPolygon->
            set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) );

        nGeom = poOgrPolygon->getNumInteriorRings (  );
        for ( i = 0; i < nGeom; i++ ) {
            poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ),
                                          i + 1, poKmlFactory );
            poKmlPolygon->
                add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) );
        }

        break;

    case wkbMultiPoint:
    case wkbMultiLineString:
    case wkbMultiPolygon:
    case wkbGeometryCollection:
    case wkbMultiPoint25D:
    case wkbMultiLineString25D:
    case wkbMultiPolygon25D:
    case wkbGeometryCollection25D:

        poOgrMultiGeom = ( OGRGeometryCollection * ) poOgrGeom;

        nGeom = poOgrMultiGeom->getNumGeometries (  );

        if( nGeom == 1 &&
            CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) )
        {
            CPLDebug("LIBKML", "Turning multiple geometry into single geometry");
            poKmlGeometry = geom2kml( poOgrMultiGeom->getGeometryRef ( 0 ),
                                      -1, poKmlFactory );
        }
        else
        {
            if( nGeom == 0 &&
                CPLTestBool(CPLGetConfigOption("LIBKML_STRICT_COMPLIANCE", "TRUE")) )
            {
                CPLError(CE_Warning, CPLE_AppDefined, "Empty multi geometry are not recommended");
            }
            poKmlGeometry = poKmlMultiGeometry =
                poKmlFactory->CreateMultiGeometry (  );
            for ( i = 0; i < nGeom; i++ ) {
                poKmlTmpGeometry = geom2kml ( poOgrMultiGeom->getGeometryRef ( i ),
                                            -1, poKmlFactory );
                poKmlMultiGeometry->
                    add_geometry ( AsGeometry ( poKmlTmpGeometry ) );
            }
        }

        break;

    case wkbUnknown:
    case wkbNone:
    default:
        break;

    }

    return poKmlGeometry;
}
Пример #29
0
OGRMultiPolygon* Building::extrude_box() const
{
    OGRMultiPolygon* block = new OGRMultiPolygon;

    //extrude roof
    OGRPolygon roof;
    {
        roof.addRing(_footprint->getExteriorRing());
        OGRLinearRing* ring = roof.getExteriorRing();
        for(int i=0; i<ring->getNumPoints(); i++)
            ring->setPoint(i,ring->getX(i),ring->getY(i),_height);
    }

    if(int n = _footprint->getNumInteriorRings())
    {
        for (int j=0; j<n; j++)
        {
            roof.addRing(_footprint->getInteriorRing(j));
            OGRLinearRing* ring = roof.getInteriorRing(j);
            for(int i=0; i<ring->getNumPoints(); i++)
                ring->setPoint(i,ring->getX(i),ring->getY(i),_height);
        }
    }

    block->addGeometry(&roof);

    //extrude exter walls
    OGRLinearRing* ringEx = _footprint->getExteriorRing();
    for(int i=0; i<ringEx->getNumPoints()-1; i++)
    {
        OGRPolygon wall;
        OGRLinearRing ring;
        ring.addPoint(ringEx->getX(i),ringEx->getY(i),0);
        ring.addPoint(ringEx->getX(i+1),ringEx->getY(i+1),0);
        ring.addPoint(ringEx->getX(i+1),ringEx->getY(i+1),_height);
        ring.addPoint(ringEx->getX(i),ringEx->getY(i),_height);
        ring.addPoint(ringEx->getX(i),ringEx->getY(i),0);
        wall.addRing(&ring);
        block->addGeometry(&wall);
    }

    //extrude inner walls if exist
    if(int n = _footprint->getNumInteriorRings())
    {
        for (int i=0; i<n; i++)
        {
            OGRLinearRing* ringIn = _footprint->getInteriorRing(i);
            for(int j=0; j<ringIn->getNumPoints()-1; j++)
            {
                OGRPolygon wall;
                OGRLinearRing ring;
                ring.addPoint(ringIn->getX(j),ringIn->getY(j),0);
                ring.addPoint(ringIn->getX(j+1),ringIn->getY(j+1),0);
                ring.addPoint(ringIn->getX(j+1),ringIn->getY(j+1),_height);
                ring.addPoint(ringIn->getX(j),ringIn->getY(j),_height);
                ring.addPoint(ringIn->getX(j),ringIn->getY(j),0);
                wall.addRing(&ring);
                block->addGeometry(&wall);
            }
        }
    }


    return block;

}
Пример #30
0
OGRFeature *OGRGmtLayer::GetNextRawFeature()

{
#if 0
    int bMultiVertex =
        poFeatureDefn->GetGeomType() != wkbPoint
        && poFeatureDefn->GetGeomType() != wkbUnknown;
#endif
    CPLString osFieldData;
    OGRGeometry *poGeom = NULL;

/* -------------------------------------------------------------------- */
/*      Read lines associated with this feature.                        */
/* -------------------------------------------------------------------- */
    for( ; true; ReadLine() )
    {
        if( osLine.length() == 0 )
            break;

        if( osLine[0] == '>' )
        {
            if( poGeom != NULL
                && wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon )
            {
                OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom;
                if( ScanAheadForHole() )
                {
                    // Add a hole to the current polygon.
                    ((OGRPolygon *) poMP->getGeometryRef(
                        poMP->getNumGeometries()-1 ))->
                        addRingDirectly( new OGRLinearRing() );
                }
                else if( !NextIsFeature() )
                {
                    OGRPolygon *poPoly = new OGRPolygon();

                    poPoly->addRingDirectly( new OGRLinearRing() );

                    poMP->addGeometryDirectly( poPoly );
                }
                else
                    break; /* done geometry */
            }
            else if( poGeom != NULL
                     && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon)
            {
                if( ScanAheadForHole() )
                    ((OGRPolygon *)poGeom)->
                        addRingDirectly( new OGRLinearRing() );
                else
                    break; /* done geometry */
            }
            else if( poGeom != NULL
                     && (wkbFlatten(poGeom->getGeometryType())
                         == wkbMultiLineString)
                     && !NextIsFeature() )
            {
                ((OGRMultiLineString *) poGeom)->
                    addGeometryDirectly( new OGRLineString() );
            }
            else if( poGeom != NULL )
            {
                break;
            }
            else if( poFeatureDefn->GetGeomType() == wkbUnknown )
            {
                poFeatureDefn->SetGeomType( wkbLineString );
                /* bMultiVertex = TRUE; */
            }
        }
        else if( osLine[0] == '#' )
        {
            for( int i = 0;
                 papszKeyedValues != NULL && papszKeyedValues[i] != NULL;
                 i++ )
            {
                if( papszKeyedValues[i][0] == 'D' )
                    osFieldData = papszKeyedValues[i] + 1;
            }
        }
        else
        {
            // Parse point line.
            double dfX;
            double dfY;
            double dfZ = 0.0;
            const int nDim
                = CPLsscanf( osLine, "%lf %lf %lf", &dfX, &dfY, &dfZ );

            if( nDim >= 2 )
            {
                if( poGeom == NULL )
                {
                    switch( poFeatureDefn->GetGeomType() )
                    {
                      case wkbLineString:
                        poGeom = new OGRLineString();
                        break;

                      case wkbPolygon:
                        poGeom = new OGRPolygon();
                        reinterpret_cast<OGRPolygon *>(poGeom)->addRingDirectly(
                            new OGRLinearRing() );
                        break;

                      case wkbMultiPolygon:
                      {
                          OGRPolygon *poPoly = new OGRPolygon();
                          poPoly->addRingDirectly( new OGRLinearRing() );

                          poGeom = new OGRMultiPolygon();
                          reinterpret_cast<OGRMultiPolygon *>(poGeom)->
                              addGeometryDirectly( poPoly );
                      }
                      break;

                      case wkbMultiPoint:
                        poGeom = new OGRMultiPoint();
                        break;

                      case wkbMultiLineString:
                        poGeom = new OGRMultiLineString();
                        reinterpret_cast<OGRMultiLineString *>(poGeom)->
                            addGeometryDirectly(new OGRLineString() );
                        break;

                      case wkbPoint:
                      case wkbUnknown:
                      default:
                        poGeom = new OGRPoint();
                        break;
                    }

                }

                switch( wkbFlatten(poGeom->getGeometryType()) )
                {
                  case wkbPoint:
                    reinterpret_cast<OGRPoint *>(poGeom)->setX( dfX );
                    reinterpret_cast<OGRPoint *>(poGeom)->setY( dfY );
                    if( nDim == 3 )
                        reinterpret_cast<OGRPoint *>(poGeom)->setZ( dfZ );
                    break;

                  case wkbLineString:
                    if( nDim == 3 )
                        reinterpret_cast<OGRLineString *>(poGeom)->
                            addPoint( dfX, dfY, dfZ);
                    else
                        reinterpret_cast<OGRLineString *>(poGeom)->
                            addPoint( dfX, dfY );
                    break;

                  case wkbPolygon:
                  case wkbMultiPolygon:
                  {
                      OGRPolygon *poPoly = NULL;

                      if( wkbFlatten(poGeom->getGeometryType())
                          == wkbMultiPolygon )
                      {
                          OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom;
                          poPoly = (OGRPolygon*) poMP->getGeometryRef(
                              poMP->getNumGeometries() - 1 );
                      }
                      else
                          poPoly = reinterpret_cast<OGRPolygon *>(poGeom);

                      OGRLinearRing *poRing = NULL;
                      if( poPoly->getNumInteriorRings() == 0 )
                          poRing = poPoly->getExteriorRing();
                      else
                          poRing = poPoly->getInteriorRing(
                              poPoly->getNumInteriorRings()-1 );

                      if( nDim == 3 )
                          poRing->addPoint( dfX, dfY, dfZ );
                      else
                          poRing->addPoint( dfX, dfY );
                  }
                  break;

                  case wkbMultiLineString:
                  {
                      OGRMultiLineString *poML = (OGRMultiLineString *) poGeom;
                      OGRLineString *poLine = reinterpret_cast<OGRLineString *>(
                          poML->getGeometryRef( poML->getNumGeometries() -1 ) );

                      if( nDim == 3 )
                          poLine->addPoint( dfX, dfY, dfZ );
                      else
                          poLine->addPoint( dfX, dfY );
                  }
                  break;

                  default:
                    CPLAssert( FALSE );
                }
            }
        }

        if( poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
        {
            ReadLine();
            break;
        }
    }

    if( poGeom == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create feature.                                                 */
/* -------------------------------------------------------------------- */
    OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    poGeom->assignSpatialReference(poSRS);
    poFeature->SetGeometryDirectly( poGeom );
    poFeature->SetFID( iNextFID++ );

/* -------------------------------------------------------------------- */
/*      Process field values.                                           */
/* -------------------------------------------------------------------- */
    char **papszFD = CSLTokenizeStringComplex( osFieldData, "|", TRUE, TRUE );

    for( int iField = 0; papszFD != NULL && papszFD[iField] != NULL; iField++ )
    {
        if( iField >= poFeatureDefn->GetFieldCount() )
            break;

        poFeature->SetField( iField, papszFD[iField] );
    }

    CSLDestroy( papszFD );

    m_nFeaturesRead++;

    return poFeature;
}