コード例 #1
0
ファイル: raster.cpp プロジェクト: JamesSLC/rasterman
/*
     * Initializes the object, assuming that filename, origin, size, etc are already set on the
     * member variables. Makes sure the raster can be opened, sets the block size, NODATA value,
     * pixel size, and the extent of the raster. If not using the full image then makes sure that
     * the subset chosen (based on origin and size) is valid. If using the full image then sets the
     * size and origin is assumed to be 0,0 and is set in the constructor.
     * @param fullImage True if using the full image, False if using a subset.
     */
void Raster::Init(bool bFullImage)
{
    Init();
    GDALDataset * ds = (GDALDataset*) GDALOpen(m_sFilePath, GA_ReadOnly);

    if (ds == NULL)
        throw RasterManagerException(INPUT_FILE_NOT_VALID, CPLGetLastErrorMsg());

    GDALRasterBand * band = ds->GetRasterBand(1);

    double dRMin, dRMax, dRMean, dRStdDev;

    // Get some easy stats that GDAL gives us
    band->GetStatistics( 0 , true, &dRMin, &dRMax, &dRMean, &dRStdDev );
    m_dRasterMax = dRMax;
    m_dRasterMin = dRMin;

    m_dRasterMean = dRMean;
    m_dRasterStdDev = dRStdDev;

    OGRLinearRing ring = OGRLinearRing();
    if (bFullImage)
    {
        SetCols( band->GetXSize() );
        SetRows( band->GetYSize() );

        ring.addPoint(GetLeft(), GetTop());
        ring.addPoint(GetLeft(), GetTop() + (GetCellHeight() * GetRows()));
        ring.addPoint(GetLeft() + (GetCellWidth() * GetCols()), GetTop() + (GetCellHeight() * GetRows()));
        ring.addPoint(GetLeft() + (GetCellWidth() * GetCols()), GetTop());
        ring.closeRings();
    }
    else
    {
        if ((GetLeft() + GetCols() > band->GetXSize()) || (GetTop() + GetRows() > band->GetYSize()))
        {
            QString sErr = QString("Invalid origin ( %1, %2 ) and size ( %5, %6 ) for file: %7")
                    .arg(GetLeft())
                    .arg(GetTop())
                    .arg(GetCols())
                    .arg(GetRows())
                    .arg(FilePath());
            throw RasterManagerException(INPUT_FILE_NOT_VALID, sErr);
        }
        double xMapOrigin = GetLeft() + (GetLeft() * GetCellWidth());
        double yMapOrigin = GetTop() + (GetTop() * GetCellHeight());
        ring.addPoint(xMapOrigin, yMapOrigin);
        ring.addPoint(xMapOrigin, yMapOrigin + (GetCellHeight() * GetRows()));
        ring.addPoint(xMapOrigin + (GetCellWidth() * GetCols()), yMapOrigin + (GetCellHeight() * GetRows()));
        ring.addPoint(xMapOrigin + (GetCellWidth() * GetCols()), yMapOrigin);
        ring.closeRings();
    }
    GDALClose(ds);

}
コード例 #2
0
int ICLayerLineString::isSelected(double x, double y, double scale)
{
  OGRPolygon* Poly =
      static_cast<OGRPolygon*> (OGRGeometryFactory::createGeometry(wkbPolygon));

  OGRLinearRing* Ring =
      static_cast<OGRLinearRing*> (OGRGeometryFactory::createGeometry(
          wkbLinearRing));

  Ring->setPoint(0, new OGRPoint(x - 3 / scale, y - 3 / scale));
  Ring->setPoint(1, new OGRPoint(x + 3 / scale, y - 3 / scale));
  Ring->setPoint(2, new OGRPoint(x + 3 / scale, y + 3 / scale));
  Ring->setPoint(3, new OGRPoint(x - 3 / scale, y + 3 / scale));

  Ring->closeRings();

  Poly->addRingDirectly(Ring);

  std::map<int, ICLayerObject*>::iterator it;
  for (it = m_ICLayerObject.begin(); it != m_ICLayerObject.end(); it++)
  {
    if (Poly->Intersects(
        static_cast<OGRGeometry*> ((*it).second->getOGRGeometryObject())))
    {
      return (*it).first;
    }
  }
  return -1;

}
コード例 #3
0
ファイル: MapExtruder.cpp プロジェクト: HEShuang/3DCityLoD
void MapExtruder::extrusion()
{
	_sides = new OGRMultiPolygon();

	int n = _map2d->getNumGeometries();
	for(int i=0;i<n;i++)
	{

		OGRLinearRing* ring = ((OGRPolygon*)_map2d->getGeometryRef(i))->getExteriorRing();
		ring->closeRings();
		int nPoints = ring->getNumPoints();


		for(int j=0;j<nPoints-1;j++)
		{
			
			OGRPolygon side;
			OGRLinearRing* ring_side = new OGRLinearRing();

			OGRPoint p1,p4;

			ring->getPoint(j,&p1);
			ring->getPoint(j+1,&p4);

			OGRPoint p2(p1.getX(),p1.getY(),_height);
			OGRPoint p3(p4.getX(),p4.getY(),_height);
			
			
	
			ring_side->addPoint(&p1);			
		    ring_side->addPoint(&p2);
			ring_side->addPoint(&p3);
			ring_side->addPoint(&p4);
			ring_side->addPoint(&p1);

			side.addRing(ring_side);
			_sides->addGeometry(&side);
		}
	}
}
コード例 #4
0
static
OGRGeometry *kml2geom_latlonquad_int (
    GxLatLonQuadPtr poKmlLatLonQuad,
    OGRSpatialReference *poOgrSRS)

{
    if( !poKmlLatLonQuad->has_coordinates() )
        return NULL;

    const CoordinatesPtr& poKmlCoordinates =
        poKmlLatLonQuad->get_coordinates();

    OGRLinearRing* poOgrLinearRing = new OGRLinearRing (  );

    size_t nCoords = poKmlCoordinates->get_coordinates_array_size (  );
    for ( size_t i = 0; i < nCoords; i++ ) {
        Vec3 oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
        if ( oKmlVec.has_altitude (  ) )
            poOgrLinearRing->
                addPoint ( oKmlVec.get_longitude (  ),
                           oKmlVec.get_latitude (  ),
                           oKmlVec.get_altitude (  ) );
        else
            poOgrLinearRing->
                addPoint ( oKmlVec.get_longitude (  ),
                           oKmlVec.get_latitude (  ) );
    }
    poOgrLinearRing->closeRings();

    OGRPolygon *poOgrPolygon = new OGRPolygon();
    poOgrPolygon->
        addRingDirectly ( poOgrLinearRing );
    poOgrPolygon->assignSpatialReference(poOgrSRS);

    return poOgrPolygon;
}
コード例 #5
0
OGRFeature *OGROpenAirLayer::GetNextRawFeature()
{
    const char* pszLine;
    CPLString osCLASS, osNAME, osFLOOR, osCEILING;
    OGRLinearRing oLR;
    /* double dfLastLat = 0, dfLastLon = 0; */
    int bFirst = TRUE;
    int bClockWise = TRUE;
    double dfCenterLat = 0, dfCenterLon = 0;
    int bHasCenter = FALSE;
    OpenAirStyle sStyle;
    sStyle.penStyle = -1;
    sStyle.penWidth = -1;
    sStyle.penR = sStyle.penG = sStyle.penB = -1;
    sStyle.fillR = sStyle.fillG = sStyle.fillB = -1;

    if (bEOF)
        return NULL;

    while(TRUE)
    {
        if (bFirst && bHasLastLine)
        {
            pszLine = osLastLine.c_str();
            bFirst = FALSE;
        }
        else
        {
            pszLine = CPLReadLine2L(fpOpenAir, 1024, NULL);
            if (pszLine == NULL)
            {
                bEOF = TRUE;
                if (oLR.getNumPoints() == 0)
                    return NULL;

                if (osCLASS.size() != 0 &&
                    oStyleMap.find(osCLASS) != oStyleMap.end())
                {
                    memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle));
                }
                break;
            }
            osLastLine = pszLine;
            bHasLastLine = TRUE;
        }

        if (pszLine[0] == '*' || pszLine[0] == '\0')
            continue;

        if (EQUALN(pszLine, "AC ", 3) || EQUALN(pszLine, "AC,", 3))
        {
            if (osCLASS.size() != 0)
            {
                if (sStyle.penStyle != -1 || sStyle.fillR != -1)
                {
                    if (oLR.getNumPoints() == 0)
                    {
                        OpenAirStyle* psStyle;
                        if (oStyleMap.find(osCLASS) == oStyleMap.end())
                        {
                            psStyle = (OpenAirStyle*)CPLMalloc(
                                                    sizeof(OpenAirStyle));
                            oStyleMap[osCLASS] = psStyle;
                        }
                        else
                            psStyle = oStyleMap[osCLASS];
                        memcpy(psStyle, &sStyle, sizeof(sStyle));
                    }
                    else
                        break;
                }
                else if (oStyleMap.find(osCLASS) != oStyleMap.end())
                {
                    memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle));
                    break;
                }
                else
                    break;
            }
            sStyle.penStyle = -1;
            sStyle.penWidth = -1;
            sStyle.penR = sStyle.penG = sStyle.penB = -1;
            sStyle.fillR = sStyle.fillG = sStyle.fillB = -1;
            osCLASS = pszLine + 3;
            bClockWise = TRUE;
            bHasCenter = FALSE;
        }
        else if (EQUALN(pszLine, "AN ", 3))
        {
            if (osNAME.size() != 0)
                break;
            osNAME = pszLine + 3;
        }
        else if (EQUALN(pszLine, "AH ", 3))
            osCEILING = pszLine + 3;
        else if (EQUALN(pszLine, "AL ", 3))
            osFLOOR = pszLine + 3;
        else if (EQUALN(pszLine, "AT ", 3))
        {
            /* Ignored for that layer*/
        }
        else if (EQUALN(pszLine, "SP ", 3))
        {
            if (osCLASS.size() != 0)
            {
                char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0);
                if (CSLCount(papszTokens) == 5)
                {
                    sStyle.penStyle = atoi(papszTokens[0]);
                    sStyle.penWidth = atoi(papszTokens[1]);
                    sStyle.penR = atoi(papszTokens[2]);
                    sStyle.penG = atoi(papszTokens[3]);
                    sStyle.penB = atoi(papszTokens[4]);
                }
                CSLDestroy(papszTokens);
            }
        }
        else if (EQUALN(pszLine, "SB ", 3))
        {
            if (osCLASS.size() != 0)
            {
                char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0);
                if (CSLCount(papszTokens) == 3)
                {
                    sStyle.fillR = atoi(papszTokens[0]);
                    sStyle.fillG = atoi(papszTokens[1]);
                    sStyle.fillB = atoi(papszTokens[2]);
                }
                CSLDestroy(papszTokens);
            }
        }
        else if (EQUALN(pszLine, "DP ", 3))
        {
            pszLine += 3;

            double dfLat, dfLon;
            if (!OGROpenAirGetLatLon(pszLine, dfLat, dfLon))
                continue;

            oLR.addPoint(dfLon, dfLat);
            /* dfLastLat = dfLat; */
            /* dfLastLon = dfLon; */
        }
        else if (EQUALN(pszLine, "DA ", 3))
        {
            pszLine += 3;

            char* pszStar = strchr((char*)pszLine, '*');
            if (pszStar) *pszStar = 0;
            char** papszTokens = CSLTokenizeString2(pszLine, ",", 0);
            if (bHasCenter && CSLCount(papszTokens) == 3)
            {
                double dfRadius = CPLAtof(papszTokens[0]) * 1852;
                double dfStartAngle = CPLAtof(papszTokens[1]);
                double dfEndAngle = CPLAtof(papszTokens[2]);

                if (bClockWise && dfEndAngle < dfStartAngle)
                    dfEndAngle += 360;
                else if (!bClockWise && dfStartAngle < dfEndAngle)
                    dfEndAngle -= 360;

                double dfStartDistance = dfRadius;
                double dfEndDistance = dfRadius;
                int nSign = (bClockWise) ? 1 : -1;
                double dfAngle;
                double dfLat, dfLon;
                for(dfAngle = dfStartAngle;
                    (dfAngle - dfEndAngle) * nSign < 0;
                    dfAngle += nSign)
                {
                    double pct = (dfAngle - dfStartAngle) /
                                    (dfEndAngle - dfStartAngle);
                    double dfDist = dfStartDistance * (1-pct) +
                                                        dfEndDistance * pct;
                    OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
                                             dfDist, dfAngle, &dfLat, &dfLon);
                    oLR.addPoint(dfLon, dfLat);
                }
                OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
                                         dfEndDistance, dfEndAngle, &dfLat, &dfLon);
                oLR.addPoint(dfLon, dfLat);

                /* dfLastLat = oLR.getY(oLR.getNumPoints() - 1); */
                /* dfLastLon = oLR.getX(oLR.getNumPoints() - 1); */
            }
            CSLDestroy(papszTokens);
        }
        else if (EQUALN(pszLine, "DB ", 3))
        {
            pszLine += 3;

            char* pszStar = strchr((char*)pszLine, '*');
            if (pszStar) *pszStar = 0;
            char** papszTokens = CSLTokenizeString2(pszLine, ",", 0);
            double dfFirstLat, dfFirstLon;
            double dfSecondLat, dfSecondLon;
            if (bHasCenter && CSLCount(papszTokens) == 2 &&
                OGROpenAirGetLatLon(papszTokens[0], dfFirstLat, dfFirstLon) &&
                OGROpenAirGetLatLon(papszTokens[1], dfSecondLat, dfSecondLon))
            {
                double dfStartDistance =OGRXPlane_Distance(dfCenterLat,
                        dfCenterLon, dfFirstLat, dfFirstLon);
                double dfEndDistance = OGRXPlane_Distance(dfCenterLat,
                        dfCenterLon, dfSecondLat, dfSecondLon);
                double dfStartAngle = OGRXPlane_Track(dfCenterLat,
                        dfCenterLon, dfFirstLat, dfFirstLon);
                double dfEndAngle = OGRXPlane_Track(dfCenterLat,
                        dfCenterLon, dfSecondLat, dfSecondLon);

                if (bClockWise && dfEndAngle < dfStartAngle)
                    dfEndAngle += 360;
                else if (!bClockWise && dfStartAngle < dfEndAngle)
                    dfEndAngle -= 360;

                int nSign = (bClockWise) ? 1 : -1;
                double dfAngle;
                for(dfAngle = dfStartAngle;
                    (dfAngle - dfEndAngle) * nSign < 0;
                    dfAngle += nSign)
                {
                    double dfLat, dfLon;
                    double pct = (dfAngle - dfStartAngle) /
                                    (dfEndAngle - dfStartAngle);
                    double dfDist = dfStartDistance * (1-pct) +
                                                    dfEndDistance * pct;
                    OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
                                             dfDist, dfAngle, &dfLat, &dfLon);
                    oLR.addPoint(dfLon, dfLat);
                }
                oLR.addPoint(dfSecondLon, dfSecondLat);

                /* dfLastLat = oLR.getY(oLR.getNumPoints() - 1); */
                /* dfLastLon = oLR.getX(oLR.getNumPoints() - 1); */
            }
            CSLDestroy(papszTokens);
        }
        else if ((EQUALN(pszLine, "DC ", 3) || EQUALN(pszLine, "DC=", 3)) &&
                 (bHasCenter || strstr(pszLine, "V X=") != NULL))
        {
            if (!bHasCenter)
            {
                const char* pszVX = strstr(pszLine, "V X=");
                bHasCenter = OGROpenAirGetLatLon(pszVX, dfCenterLat, dfCenterLon);
            }
            if (bHasCenter)
            {
                pszLine += 3;

                double dfRADIUS = CPLAtof(pszLine) * 1852;

                double dfAngle;
                double dfLat, dfLon;
                for(dfAngle = 0; dfAngle < 360; dfAngle += 1)
                {
                    OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
                                             dfRADIUS, dfAngle, &dfLat, &dfLon);
                    oLR.addPoint(dfLon, dfLat);
                }
                OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon,
                                         dfRADIUS, 0, &dfLat, &dfLon);
                oLR.addPoint(dfLon, dfLat);

                /* dfLastLat = oLR.getY(oLR.getNumPoints() - 1); */
                /* dfLastLon = oLR.getX(oLR.getNumPoints() - 1); */
            }
        }
        else if (EQUALN(pszLine, "V X=", 4))
        {
            bHasCenter =
                    OGROpenAirGetLatLon(pszLine + 4, dfCenterLat, dfCenterLon);
        }
        else if (EQUALN(pszLine, "V D=-", 5))
        {
            bClockWise = FALSE;
        }
        else if (EQUALN(pszLine, "V D=+", 5))
        {
            bClockWise = TRUE;
        }
        else
        {
            //CPLDebug("OpenAir", "Unexpected content : %s", pszLine);
        }
    }

    OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
    poFeature->SetField(0, osCLASS.c_str());
    poFeature->SetField(1, osNAME.c_str());
    poFeature->SetField(2, osFLOOR.c_str());
    poFeature->SetField(3, osCEILING.c_str());

    if (sStyle.penStyle != -1 || sStyle.fillR != -1)
    {
        CPLString osStyle;
        if (sStyle.penStyle != -1)
        {
            osStyle += CPLString().Printf("PEN(c:#%02X%02X%02X,w:%dpt",
                                 sStyle.penR, sStyle.penG, sStyle.penB,
                                 sStyle.penWidth);
            if (sStyle.penStyle == 1)
                osStyle += ",p:\"5px 5px\"";
            osStyle += ")";
        }
        if (sStyle.fillR != -1)
        {
            if (osStyle.size() != 0)
                osStyle += ";";
            osStyle += CPLString().Printf("BRUSH(fc:#%02X%02X%02X)",
                                 sStyle.fillR, sStyle.fillG, sStyle.fillB);
        }
        else
        {
            if (osStyle.size() != 0)
                osStyle += ";";
            osStyle += "BRUSH(fc:#00000000,id:\"ogr-brush-1\")";
        }
        if (osStyle.size() != 0)
            poFeature->SetStyleString(osStyle);
    }

    OGRPolygon* poPoly = new OGRPolygon();
    oLR.closeRings();
    poPoly->addRing(&oLR);
    poPoly->assignSpatialReference(poSRS);
    poFeature->SetGeometryDirectly(poPoly);
    poFeature->SetFID(nNextFID++);

    return poFeature;
}
コード例 #6
0
ファイル: main.cpp プロジェクト: BishopGIS/gisconf2015
GDAL_GCP * PrepareGCP(const CPLString& sFileName, OGRPoint *pt1, OGRPoint *pt2, OGRPoint *pt3, OGRPoint *pt4, OGRPoint *ptCenter, const OGRSpatialReference &oDstOGRSpatialReference, const int nRasterSizeX, const int nRasterSizeY, int &nGCPCount, OGREnvelope &DstEnv)
{
    // to meters
    double dfFocusM = dfFocus / 100;
    double dfFilmHalfHeightM = dfFilmHeight / 200;
    double dfRatio = dfFilmHalfHeightM / dfFocusM;

    //create center point and line of scene
    OGRPoint ptShortSideBeg = GetCenterOfLine(pt1, pt4);
    OGRPoint ptShortSideEnd = GetCenterOfLine(pt2, pt3);

    OGRLineString lnTmp;
    lnTmp.addPoint(&ptShortSideBeg);
    lnTmp.addPoint(&ptShortSideEnd);

    lnTmp.Value(lnTmp.Project(pt1), &ptShortSideBeg);
    lnTmp.Value(lnTmp.Project(pt2), &ptShortSideEnd);

    double dfDist1 = pt1->Distance(pt2);
    double dfDist2 = pt2->Distance(pt3);
    double dfDist3 = pt3->Distance(pt4);
    double dfDist4 = pt4->Distance(pt1);
    double dfHalfWidth = (dfDist2 + dfDist4) / 4;
    double dfHalfHeight = (dfDist1 + dfDist3) / 4;

    double dfAltitudeAtSide = (dfHalfWidth * dfFocusM) / dfFilmHalfHeightM;
    double dfAltitudeAtSceneCenter = sqrt( dfAltitudeAtSide * dfAltitudeAtSide - dfHalfHeight * dfHalfHeight);
    double dfAltitude = dfAltitudeAtSceneCenter * cos(dfMountAngleRad); // 145 - 220 km
    double dfDistCenter = dfAltitudeAtSceneCenter * sin(dfMountAngleRad);

    OGRLineString lnCenterLeft;
    lnCenterLeft.addPoint(&ptShortSideBeg);
    lnCenterLeft.addPoint(ptCenter);
    OGRPoint ptSatCenter = GetTangetPoint(lnCenterLeft, dfDistCenter);

    std::vector<OGRPoint> aPt1, aPt2;
    int nTotalGCPCount = ((SEGMENT_STEPS + 1) * 2);
    GDAL_GCP *paGSPs = (GDAL_GCP *) CPLMalloc (nTotalGCPCount * sizeof(GDAL_GCP));
    GDALInitGCPs(nTotalGCPCount, paGSPs);

    double dfImageStepLen = double(nRasterSizeX) / SEGMENT_STEPS;
    double dfImageCenterX = 0;

    OGRLineString lnCenter;
    lnCenter.addPoint(&ptShortSideBeg);
    lnCenter.addPoint(ptCenter);
    lnCenter.addPoint(&ptShortSideEnd);

    double dfCenterLineLen = lnCenter.get_Length();
    double dfStepLen = dfCenterLineLen / SEGMENT_STEPS;
    double dfCenterLineHalfLen = dfCenterLineLen / 2;

    for(double i = 0; i <= dfCenterLineLen; i += dfStepLen)
    {
        OGRPoint ptTmp;
        lnCenter.Value(i, &ptTmp);

        double dfDist = fabs(dfCenterLineHalfLen - i);

        double dfWidthTmp = GetWidthForHeight(dfAltitudeAtSceneCenter, dfDist, dfRatio);

        OGRLineString lnTmpLine;
        lnTmpLine.addPoint(ptCenter);
        lnTmpLine.addPoint(&ptTmp);

        int direction = 1;
        if(dfCenterLineHalfLen < i)
            direction = -1;

        OGRPoint ptUp = GetTangetPoint(lnTmpLine, dfWidthTmp * direction);
        OGRPoint ptDown = GetTangetPoint(lnTmpLine, -dfWidthTmp * direction);

        //OGRPoint ptUp = GetValue(dfWidthTmp, lnTmpLine);
        //OGRPoint ptDown = GetValue(-dfWidthTmp, lnTmpLine);

        aPt1.push_back(ptUp);
        aPt2.push_back(ptDown);

        paGSPs[nGCPCount].dfGCPLine = 0;
        paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX;
        paGSPs[nGCPCount].dfGCPX = ptDown.getX();
        paGSPs[nGCPCount].dfGCPY = ptDown.getY();
        paGSPs[nGCPCount].dfGCPZ = dfMeanHeight;
        paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount));
        nGCPCount++;

        paGSPs[nGCPCount].dfGCPLine = nRasterSizeY;
        paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX;
        paGSPs[nGCPCount].dfGCPX = ptUp.getX();
        paGSPs[nGCPCount].dfGCPY = ptUp.getY();
        paGSPs[nGCPCount].dfGCPZ = dfMeanHeight;
        paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount));
        nGCPCount++;

        dfImageCenterX += dfImageStepLen;
    }

    // add points to polygon
    OGRLinearRing Ring;
    for(int i = 0; i < aPt1.size(); ++i)
        Ring.addPoint(aPt1[i].getX(), aPt1[i].getY());

    for(int i = aPt2.size() - 1; i >= 0; --i)
        Ring.addPoint(aPt2[i].getX(), aPt2[i].getY());

    Ring.closeRings();

    OGRPolygon Rgn;
    Rgn.addRingDirectly((OGRCurve*)Ring.clone());
    Rgn.assignSpatialReference(oDstOGRSpatialReference.Clone());
    Rgn.flattenTo2D();

    Rgn.getEnvelope(&DstEnv);

    SaveGeometry(CPLResetExtension(sFileName, "shp"), Rgn, oDstOGRSpatialReference);

    return paGSPs;
}
コード例 #7
0
ファイル: ogrhtflayer.cpp プロジェクト: AsherBond/MondocosmOS
OGRFeature *OGRHTFPolygonLayer::GetNextRawFeature()
{
    OGRFeature* poFeature = new OGRFeature(poFeatureDefn);

    const char* pszLine;

    OGRLinearRing oLR;
    int bHastFirstCoord = FALSE;
    double dfFirstEasting = 0, dfFirstNorthing = 0;
    double dfIslandEasting = 0, dfIslandNorthing = 0;
    int bInIsland = FALSE;
    OGRPolygon* poPoly = new OGRPolygon();

    while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
    {
        if (pszLine[0] == ';')
        {
            /* comment */ ;
        }
        else if (pszLine[0] == 0)
        {
            /* end of polygon is marked by a blank line */
            break;
        }
        else if (strncmp(pszLine, "POLYGON DESCRIPTION: ",
                         strlen("POLYGON DESCRIPTION: ")) == 0)
        {
            poFeature->SetField(0, pszLine + strlen("POLYGON DESCRIPTION: "));
        }
        else if (strncmp(pszLine, "POLYGON IDENTIFIER: ",
                         strlen("POLYGON IDENTIFIER: ")) == 0)
        {
            poFeature->SetField(1, pszLine + strlen("POLYGON IDENTIFIER: "));
        }
        else if (strncmp(pszLine, "SEAFLOOR COVERAGE: ",
                         strlen("SEAFLOOR COVERAGE:")) == 0)
        {
            const char* pszVal = pszLine + strlen("SEAFLOOR COVERAGE: ");
            if (*pszVal != '*')
                poFeature->SetField(2, pszVal);
        }
        else if (strncmp(pszLine, "POSITION ACCURACY: ",
                         strlen("POSITION ACCURACY:")) == 0)
        {
            const char* pszVal = pszLine + strlen("POSITION ACCURACY: ");
            if (*pszVal != '*')
                poFeature->SetField(3, pszVal);
        }
        else if (strncmp(pszLine, "DEPTH ACCURACY: ",
                         strlen("DEPTH ACCURACY:")) == 0)
        {
            const char* pszVal = pszLine + strlen("DEPTH ACCURACY: ");
            if (*pszVal != '*')
                poFeature->SetField(4, pszVal);
        }
        else if (strcmp(pszLine, "END OF POLYGON DATA") == 0)
        {
            bEOF = TRUE;
            break;
        }
        else
        {
            char** papszTokens = CSLTokenizeString(pszLine);
            if (CSLCount(papszTokens) == 4)
            {
                double dfEasting = atof(papszTokens[2]);
                double dfNorthing = atof(papszTokens[3]);
                if (!bHastFirstCoord)
                {
                    bHastFirstCoord = TRUE;
                    dfFirstEasting = dfEasting;
                    dfFirstNorthing = dfNorthing;
                    oLR.addPoint(dfEasting, dfNorthing);
                }
                else if (dfFirstEasting == dfEasting &&
                         dfFirstNorthing == dfNorthing)
                {
                    if (!bInIsland)
                    {
                        oLR.addPoint(dfEasting, dfNorthing);
                        poPoly->addRing(&oLR);
                        oLR.empty();
                        bInIsland = TRUE;
                    }
                }
                else if (bInIsland && oLR.getNumPoints() == 0)
                {
                    dfIslandEasting = dfEasting;
                    dfIslandNorthing = dfNorthing;
                    oLR.addPoint(dfEasting, dfNorthing);
                }
                else if (bInIsland && dfIslandEasting == dfEasting &&
                         dfIslandNorthing == dfNorthing)
                {
                    oLR.addPoint(dfEasting, dfNorthing);
                    poPoly->addRing(&oLR);
                    oLR.empty();
                }
                else
                {
                    oLR.addPoint(dfEasting, dfNorthing);
                }
            }
            CSLDestroy(papszTokens);
        }
    }

    if (pszLine == NULL)
        bEOF = TRUE;

    if (oLR.getNumPoints() >= 3)
    {
        oLR.closeRings();
        poPoly->addRing(&oLR);
    }
    poPoly->assignSpatialReference(poSRS);
    poFeature->SetGeometryDirectly(poPoly);
    poFeature->SetFID(nNextFID++);

    return poFeature;
}
コード例 #8
0
ファイル: ogrsualayer.cpp プロジェクト: koordinates/gdal
OGRFeature *OGRSUALayer::GetNextRawFeature()
{
    if( bEOF )
        return nullptr;

    CPLString osTYPE;
    CPLString osCLASS;
    CPLString osTITLE;
    CPLString osTOPS;
    CPLString osBASE;
    OGRLinearRing oLR;
    double dfLastLat = 0.0;
    double dfLastLon = 0.0;
    bool bFirst = true;

    while( true )
    {
        const char* pszLine = nullptr;
        if( bFirst && bHasLastLine )
        {
            pszLine = osLastLine.c_str();
            bFirst = false;
        }
        else
        {
            pszLine = CPLReadLine2L(fpSUA, 1024, nullptr);
            if (pszLine == nullptr)
            {
                bEOF = true;
                if (oLR.getNumPoints() == 0)
                    return nullptr;
                break;
            }
            osLastLine = pszLine;
            bHasLastLine = true;
        }

        if (pszLine[0] == '#' || pszLine[0] == '\0')
            continue;

        if (STARTS_WITH_CI(pszLine, "TYPE="))
        {
            if (!osTYPE.empty())
                break;
            osTYPE = pszLine + 5;
        }
        else if (STARTS_WITH_CI(pszLine, "CLASS="))
        {
            if (!osCLASS.empty())
                break;
            osCLASS = pszLine + 6;
        }
        else if (STARTS_WITH_CI(pszLine, "TITLE="))
        {
            if (!osTITLE.empty())
                break;
            osTITLE = pszLine + 6;
        }
        else if (STARTS_WITH_CI(pszLine, "TOPS="))
            osTOPS = pszLine + 5;
        else if (STARTS_WITH_CI(pszLine, "BASE="))
            osBASE = pszLine + 5;
        else if (STARTS_WITH_CI(pszLine, "POINT="))
        {
            pszLine += 6;
            if (strlen(pszLine) != 16)
                continue;

            double dfLat = 0.0;
            double dfLon = 0.0;
            if (!GetLatLon(pszLine, dfLat, dfLon))
                continue;

            oLR.addPoint(dfLon, dfLat);
            dfLastLat = dfLat;
            dfLastLon = dfLon;
        }
        else if (STARTS_WITH_CI(pszLine, "CLOCKWISE") || STARTS_WITH_CI(pszLine, "ANTI-CLOCKWISE"))
        {
            if (oLR.getNumPoints() == 0)
                continue;

            int bClockWise = STARTS_WITH_CI(pszLine, "CLOCKWISE");

            /*const char* pszRADIUS = strstr(pszLine, "RADIUS=");
            if (pszRADIUS == NULL)
                continue;
            double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852;*/

            const char* pszCENTRE = strstr(pszLine, "CENTRE=");
            if (pszCENTRE == nullptr)
                continue;
            pszCENTRE += 7;
            if (strlen(pszCENTRE) < 17 || pszCENTRE[16] != ' ')
                continue;
            double dfCenterLat = 0.0;
            double dfCenterLon = 0.0;
            if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon))
                continue;

            const char* pszTO = strstr(pszLine, "TO=");
            if (pszTO == nullptr)
                continue;
            pszTO += 3;
            if (strlen(pszTO) != 16)
                continue;
            double dfToLat = 0.0;
            double dfToLon = 0.0;
            if (!GetLatLon(pszTO, dfToLat, dfToLon))
                continue;

            const double dfStartDistance =
                OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon);
            const double dfEndDistance =
                OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfToLat, dfToLon);
            const double dfStartAngle =
                OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon);
            double dfEndAngle =
                OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfToLat, dfToLon);

            if( bClockWise && dfEndAngle < dfStartAngle )
                dfEndAngle += 360;
            else if (!bClockWise && dfStartAngle < dfEndAngle)
                dfEndAngle -= 360;

            int nSign = (bClockWise) ? 1 : -1;
            for( double dfAngle = dfStartAngle;
                 (dfAngle - dfEndAngle) * nSign < 0;
                 dfAngle += nSign )
            {
                const double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle);
                const double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct;
                double dfLat = 0.0;
                double dfLon = 0.0;
                OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon);
                oLR.addPoint(dfLon, dfLat);
            }
            oLR.addPoint(dfToLon, dfToLat);

            dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
            dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
        }
        else if (STARTS_WITH_CI(pszLine, "CIRCLE"))
        {
            const char* pszRADIUS = strstr(pszLine, "RADIUS=");
            if (pszRADIUS == nullptr)
                continue;
            double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852;

            const char* pszCENTRE = strstr(pszLine, "CENTRE=");
            if (pszCENTRE == nullptr)
                continue;
            pszCENTRE += 7;
            if (strlen(pszCENTRE) != 16)
                continue;
            double dfCenterLat = 0.0;
            double dfCenterLon = 0.0;
            if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon))
                continue;

            double dfLat = 0.0;
            double dfLon = 0.0;
            for( double dfAngle = 0; dfAngle < 360; dfAngle += 1 )
            {
                OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon);
                oLR.addPoint(dfLon, dfLat);
            }
            OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon);
            oLR.addPoint(dfLon, dfLat);

            dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
            dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
        }
        else if (STARTS_WITH_CI(pszLine, "INCLUDE") || STARTS_WITH_CI(pszLine, "END"))
        {
        }
        else
        {
            CPLDebug("SUA", "Unexpected content : %s", pszLine);
        }
    }

    OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
    poFeature->SetField(0, osTYPE.c_str());
    poFeature->SetField(1, osCLASS.c_str());
    poFeature->SetField(2, osTITLE.c_str());
    poFeature->SetField(3, osTOPS.c_str());
    poFeature->SetField(4, osBASE.c_str());

    OGRPolygon* poPoly = new OGRPolygon();
    poPoly->assignSpatialReference(poSRS);
    oLR.closeRings();
    poPoly->addRing(&oLR);
    poFeature->SetGeometryDirectly(poPoly);
    poFeature->SetFID(nNextFID++);

    return poFeature;
}
コード例 #9
0
ファイル: ogrsosilayer.cpp プロジェクト: ryandavid/rotobox
OGRFeature *OGRSOSILayer::GetNextFeature() {
    short nName, nNumLines;
    long  nNumCoo;
    unsigned short nInfo;

    /* iterate through the SOSI groups*/
    while (LC_NextBgr(poNextSerial,LC_FRAMGR)) {
        nName = LC_RxGr(&oNextSerial, LES_OPTIMALT, &nNumLines, &nNumCoo, &nInfo);

        S2S oHeaders;
        S2S::iterator iHeaders;
        /* extract reference strings from group header */
        CPLString osKey, osValue;
        for (short i=1; i<=nNumLines; i++) {
            char *pszLine = LC_GetGi(i);
            if (pszLine[0] == '!') continue;                 /* If we have a comment line, skip it. */
            if ((pszLine[0] == ':')||(pszLine[0] == '(')) {  /* if we have a continued REF line... */
                osValue.append(CPLString(pszLine));            /* append to previous line.           */
                oHeaders.insert(std::pair<CPLString,CPLString>(osKey,osValue));
                continue;
            }
            while (pszLine[0] == '.') pszLine++; /* skipping the dots at the beginning of a SOSI line */
            char *pszUTFLine = CPLRecode(pszLine, poParent->pszEncoding, CPL_ENC_UTF8); /* switch to UTF encoding here */
            char *pszPos = strstr(pszUTFLine, " ");
            if (pszPos != NULL) {
                osKey = CPLString(std::string(pszUTFLine,pszPos));
                osValue = CPLString(pszPos+1);
                oHeaders.insert(std::pair<CPLString,CPLString>(osKey,osValue));
            }
            CPLFree(pszUTFLine);
        }

        /* get Feature from fyba, according to feature definition */
        OGRGeometry *poGeom = NULL;
        OGRwkbGeometryType oGType = wkbUnknown;

        switch (nName) {
        case INGEN_GRUPPE: {  /* No group */
            CPLDebug( "[GetNextFeature]", "Could not load further groups - FYBA reported INGEN_GRUPPE.");
            break;
        }
        case L_FLATE: {  /* Area */
            oGType = wkbPolygon;
            OGRLinearRing *poOuter = new OGRLinearRing();  /* Initialize a new closed polygon */
            long nRefNr;
            unsigned char nRefStatus;
            long nRefCount;
            bool correct = true;
            LC_GRF_STATUS oGrfStat;

            // Iterate through all objects that constitute this area.
            LC_InitGetRefFlate(&oGrfStat);
            nRefCount = LC_GetRefFlate(&oGrfStat, GRF_YTRE, &nRefNr, &nRefStatus, 1);
            while (nRefCount > 0) {
                if (poParent->papoBuiltGeometries[nRefNr] == NULL) {
                    // This should not happen under normal operation.
                    CPLError( CE_Warning, CPLE_AppDefined, "Feature %li referenced by %li, but it was not initialized. Geometry may be broken.", nRefNr, oNextSerial.lNr);
                    correct = false;
                    //return NULL;
                    break;
                }
                OGRGeometry *geom = poParent->papoBuiltGeometries[nRefNr];
                if (geom->getGeometryType() == wkbLineString) {
                  OGRLineString *poCurve = (OGRLineString*)geom;
                  if (nRefStatus == LC_MED_DIG) {         /* clockwise */
                    poOuter->addSubLineString(poCurve);
                  } else if (nRefStatus == LC_MOT_DIG) {  /* counter-clockwise */
                      poOuter->addSubLineString(poCurve,poCurve->getNumPoints()-1,0);
                  } else {
                      CPLError( CE_Failure, CPLE_OpenFailed, "Internal error: GRF_*_OY encountered.");
                      return NULL;
                  }
                } else {
                    CPLError( CE_Warning, CPLE_AppDefined, "Element %li composed of non-linestrings (REF %li of type %i). Ignored.", oNextSerial.lNr, nRefNr, geom->getGeometryType());
                }
                nRefCount = LC_GetRefFlate(&oGrfStat, GRF_YTRE, &nRefNr, &nRefStatus, 1);
            }

            if (correct) {
              OGRPolygon *poLy = new OGRPolygon();
              poOuter->closeRings();
              poLy->addRingDirectly(poOuter);

              OGRLinearRing *poInner = 0;
              nRefCount = LC_GetRefFlate(&oGrfStat, GRF_INDRE, &nRefNr, &nRefStatus, 1);
              while (nRefCount > 0) {
                  if (nRefNr == -1) {
                    if (poInner && (poInner->getNumPoints()>2)) {   /* If this is not the first polygon, terminate and add the last */
                          poInner->closeRings();
                          poLy->addRingDirectly(poInner);
                    }
                    poInner = new OGRLinearRing();  /* Initialize a new closed polygon */
                  } else {
                    if (poParent->papoBuiltGeometries[nRefNr] == NULL) { /* this shouldn't happen under normal operation */
                        CPLError( CE_Fatal, CPLE_AppDefined, "Feature %li referenced by %li, but it was not initialized.", nRefNr, oNextSerial.lNr);
                        return NULL;
                    }
                    OGRGeometry *geom = poParent->papoBuiltGeometries[nRefNr];
                    if (geom->getGeometryType() == wkbLineString) {
                      OGRLineString *poCurve = (OGRLineString*)geom;
                      if (nRefStatus == LC_MED_DIG) {         /* clockwise */
                        poInner->addSubLineString(poCurve);
                      } else if (nRefStatus == LC_MOT_DIG) {  /* counter-clockwise */
                          poInner->addSubLineString(poCurve,poCurve->getNumPoints()-1,0);
                      } else {
                          CPLError( CE_Failure, CPLE_OpenFailed, "Internal error: GRF_*_OY encountered.");
                          return NULL;
                      }
                    } else {
                        CPLError( CE_Warning, CPLE_AppDefined, "Element %li composed of non-linestrings (REF %li of type %i). Ignored.", oNextSerial.lNr, nRefNr, geom->getGeometryType());
                    }
                  }
                  nRefCount = LC_GetRefFlate(&oGrfStat, GRF_INDRE, &nRefNr, &nRefStatus, 1);
              }
              poGeom = poLy;
            }
            break;
        }
        case L_KURVE:    /* curve */
        case L_LINJE:    /* curve, not simplifyable */
        case L_BUEP:  {  /* curve, interpolated from circular arc */
            oGType = wkbLineString;

            OGRLineString *poCurve = (OGRLineString*)(poParent->papoBuiltGeometries[oNextSerial.lNr]);
            if (poCurve == NULL) {
                CPLError( CE_Fatal, CPLE_AppDefined, "Curve %li was not initialized.", oNextSerial.lNr);
                return NULL;
            }
            poGeom = poCurve->clone();
            break;
        }
        case L_TEKST: {  /* text */
            oGType = wkbMultiPoint;

            OGRMultiPoint *poMP = (OGRMultiPoint*)(poParent->papoBuiltGeometries[oNextSerial.lNr]);
            if (poMP == NULL) {
                CPLError( CE_Fatal, CPLE_AppDefined, "Tekst %li was not initialized.", oNextSerial.lNr);
                return NULL;
            }
            poGeom = poMP->clone();
            break;
        }
        case L_SYMBOL: {
            //CPLError( CE_Warning, CPLE_OpenFailed, "Geometry of type SYMBOL treated as point (PUNKT).");
        }
        case L_PUNKT: {  /* point */
            oGType = wkbPoint;
            OGRPoint *poPoint = (OGRPoint*)(poParent->papoBuiltGeometries[oNextSerial.lNr]);
            if (poPoint == NULL) {
                CPLError( CE_Fatal, CPLE_AppDefined, "Point %li was not initialized.", oNextSerial.lNr);
                return NULL;
            }
            poGeom = poPoint->clone();
            break;
        }
        case L_DEF:    /* skip user definitions and headers here */
        case L_HODE: {
            break;
        }
        default: {     /* complain a bit about anything else that is not implemented */
            CPLError( CE_Failure, CPLE_OpenFailed, "Unrecognized geometry of type %i.", nName);
            break;
        }
        }

        if (poGeom == NULL) continue;                         /* skipping L_HODE and unrecognized groups */
        if (oGType != poFeatureDefn->GetGeomType()) {
            if (poGeom != NULL) delete poGeom;
            continue; /* skipping features that are not the correct geometry */
        }

        OGRFeature *poFeature = new OGRFeature( poFeatureDefn );

        /* set all headers found in this group - we export everything, just in case */
        for (iHeaders = oHeaders.begin(); iHeaders != oHeaders.end(); iHeaders++) {
            OGRSOSIDataType *poType = SOSIGetType(iHeaders->first);
            OGRSOSISimpleDataType *poElements = poType->getElements();

            const char *pszLine = iHeaders->second.c_str();
            char** tokens = CSLTokenizeString(iHeaders->second.c_str());

            for (int k=0; k<poType->getElementCount(); k++) {
                if (tokens[k] == 0) break;

                if (strcmp(poElements[k].GetName(),"")==0) continue;
                int iHNr = poHeaderDefn->find(poElements[k].GetName())->second;
                if (iHNr == -1) {
                    CPLError( CE_Warning, CPLE_AppDefined, "Could not find field definition for %s.", poElements[k].GetName());
                    continue;
                }
                OGRFieldType nType = poElements[k].GetType();
                switch (nType) {
                  case OFTInteger: {
                    poFeature->SetField( iHNr, SOSITypeToInt(tokens[k]));
                    break;
                  }
                  case OFTDate: {
                    int date[3];
                    SOSITypeToDate(tokens[k], date);
                    poFeature->SetField( iHNr, date[0], date[1], date[2]);
                    break;
                  }
                  case OFTDateTime: {
                    int date[6];
                    SOSITypeToDateTime(tokens[k], date);
                    if (date[0]>0)
                      poFeature->SetField( iHNr, date[0], date[1], date[2], date[3], date[4], static_cast<float>(date[5]), 1);
                    break;
                  }
                  case OFTReal: {
                    poFeature->SetField( iHNr, SOSITypeToReal(tokens[k]));
                    break;
                  }
                  default: {
                    if ((k==0)&&((pszLine[0] == '\'')||(pszLine[0] == '\"'))) { /* If the value is quoted, ignore these */
                        int nLen = static_cast<int>(strlen(pszLine));
                        char *pszNline = (char*)CPLMalloc(nLen-1);
                        strncpy(pszNline, pszLine+1, nLen-2);
                        pszNline[nLen-2] = '\0';
                        poFeature->SetField( iHNr, pszNline);
                        CPLFree(pszNline);
                    } else {
                        poFeature->SetField( iHNr, tokens[k]);
                    }
                    break;
                  }
                }
          }

          CSLDestroy(tokens);
        }

        if( poGeom != NULL )
            poGeom->assignSpatialReference(poParent->poSRS);

        poFeature->SetGeometryDirectly( poGeom );
        poFeature->SetFID( nNextFID++ );

        /* Loop until we have a feature that matches the definition */
        if ( (m_poFilterGeom == NULL || FilterGeometry( poFeature->GetGeometryRef() ) )
                && (m_poAttrQuery == NULL || m_poAttrQuery->Evaluate( poFeature )) )
            return poFeature;
        delete poFeature;
    }
    return NULL;
}
コード例 #10
0
ファイル: vector.cpp プロジェクト: caomw/gdal-segment
void SavePolygons( const std::vector< std::string > InFilenames,
                   const char *OutFilename,
                   const cv::Mat klabels,
                   const std::vector< cv::Mat > raster,
                   const std::vector< u_int32_t > labelpixels,
                   const std::vector< std::vector <double> > sumCH,
                   const std::vector< std::vector <double> > avgCH,
                   const std::vector< std::vector <double> > stdCH,
                   std::vector< std::vector< LINE > >& linelists )
{

  CPLLocaleC oLocaleCForcer();
  CPLErrorReset();

  const char *pszDriverName = "ESRI Shapefile";
  GDALDriver *liDriver;

  liDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName );
  if( liDriver == NULL )
  {
      printf( "\nERROR: %s driver not available.\n", pszDriverName );
      exit( 1 );
  }

  const size_t m_bands = raster.size();
  const size_t m_labels = labelpixels.size();

  GDALDataset *liDS;
  liDS = liDriver->Create( OutFilename, 0, 0, 0, GDT_Unknown, NULL );

  if( liDS == NULL )
  {
      printf( "\nERROR: Creation of output file failed.\n" );
      exit( 1 );
  }

  // dataset
  GDALDataset* piDataset;
  piDataset = (GDALDataset*) GDALOpen(InFilenames[0].c_str(), GA_ReadOnly);

  // spatialref
  OGRSpatialReference oSRS;
  oSRS.SetProjCS( piDataset->GetProjectionRef() );

  OGRLayer *liLayer;
  liLayer = liDS->CreateLayer( "segments", &oSRS, wkbPolygon, NULL );
  if( liLayer == NULL )
  {
      printf( "\nERROR: Layer creation failed.\n" );
      exit( 1 );
  }
  // spatial transform
  double adfGeoTransform[6];
  double oX = 0.0f; double oY = 0.0f;
  double mX = 1.0f; double mY = -1.0f;
  if( piDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) {
      oX = adfGeoTransform[0]; oY = adfGeoTransform[3];
      mX = adfGeoTransform[1]; mY = adfGeoTransform[5];
  }
  GDALClose( (GDALDatasetH) piDataset );

  OGRFieldDefn *clsIdField = new OGRFieldDefn( "CLASS", OFTInteger );
  liLayer->CreateField( clsIdField );

  OGRFieldDefn *pixArField = new OGRFieldDefn( "AREA", OFTInteger );
  liLayer->CreateField( pixArField );

  for ( size_t b = 0; b < m_bands; b++ )
  {
     stringstream value; value << b+1;
     std::string FieldName = value.str() + "_AVERAGE";
     OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal );
     liLayer->CreateField( lavrgField );
  }

  for ( size_t b = 0; b < m_bands; b++ )
  {
     stringstream value; value << b+1;
     std::string FieldName = value.str() + "_STDDEV";
     OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal );
     liLayer->CreateField( lavrgField );
  }

  int multiring = 0;
  printf ("Write File: %s (polygon)\n", OutFilename);
  for (size_t k = 0; k < m_labels; k++)
  {

      if (multiring == 1) {
        k = k - 1;
        multiring = 0;
      }

      if (linelists[k].size() == 0)
        continue;
      // insert field data
      OGRFeature *liFeature;
      liFeature = OGRFeature::CreateFeature( liLayer->GetLayerDefn() );
      liFeature->SetField( "CLASS", (int) k );
      liFeature->SetField( "AREA", (int) labelpixels.at(k) );
      for ( size_t b = 0; b < m_bands; b++ )
      {
        stringstream value; value << b+1;
        std::string FieldName = value.str() + "_AVERAGE";
        liFeature->SetField( FieldName.c_str(), (double) avgCH[b].at(k) );
      }
      for ( size_t b = 0; b < m_bands; b++ )
      {
        stringstream value; value << b+1;
        std::string FieldName = value.str() + "_STDDEV";
        liFeature->SetField( FieldName.c_str(), stdCH[b].at(k) );
      }

      // initiate polygon start
      OGRLinearRing linestring;
      linestring.setCoordinateDimension(2);
      linestring.addPoint( oX + (double) linelists[k][0].sX * mX, oY + mY * (double) linelists[k][0].sY );
      linestring.addPoint( oX + (double) linelists[k][0].eX * mX, oY + mY * (double) linelists[k][0].eY );
      linelists[k].erase( linelists[k].begin() );

      // construct polygon from lines
      while ( linelists[k].size() > 0 )
      {
        if (multiring == 1) break;

        vector<LINE>::iterator it = linelists[k].begin();
        for (; it != linelists[k].end(); ++it)
        {
          double ltX = linestring.getX(linestring.getNumPoints()-1);
          double ltY = linestring.getY(linestring.getNumPoints()-1);
          double csX = oX + (double) it->sX * mX;
          double csY = oY + mY * (double) it->sY;
          double ceX = oX + (double) it->eX * mX;
          double ceY = oY + mY * (double) it->eY;

          if ( ( csX == ltX  ) && ( csY == ltY ) ) {
              linestring.addPoint(ceX, ceY);
              linelists[k].erase(it);
              break;
          }
          if ( ( ceX == ltX  ) && ( ceY == ltY ) ) {
              linestring.addPoint(csX, csY);
              linelists[k].erase(it);
              break;
          }
          if (it == linelists[k].end()-1) {
              multiring = 1;
              break;
          }
        }
      }

      OGRPolygon polygon;
      linestring.closeRings();

      // simplify poligons
      // remove colinear vertices
      OGRLinearRing linesimple;
      float pointPrevX = 0, pointPrevY = 0;
      for (int i = 0; i < linestring.getNumPoints(); i++)
      {
        OGRPoint point;
        linestring.getPoint(i, &point);

        // start
        if ( i == 0)
        {
          linesimple.addPoint( &point );
          pointPrevX = point.getX();
          pointPrevY = point.getY();
          continue;
        }
        // end vertex
        if ( i == linestring.getNumPoints() - 1 )
        {
          linesimple.addPoint( &point );
          continue;
        }

        OGRPoint pointNext;
        linestring.getPoint(i+1, &pointNext);
        //     | x1 y1 1 |
        // det | x2 y2 1 | = 0 => p1,p2,p3 are colinear
        //     | x3 y3 1 |
        // x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2) == 0
        // only if not colinear with previous and next
        if ( pointPrevX*(point.getY()-pointNext.getY()) +
             point.getX()*(pointNext.getY()-pointPrevY) +
             pointNext.getX()*(pointPrevY-point.getY()) != 0 )
        {
          linesimple.addPoint( &point );
          pointPrevX = point.getX();
          pointPrevY = point.getY();
        }
      }

      // as polygon geometry
      polygon.addRing( &linesimple );
      liFeature->SetGeometry( &polygon );

      if( liLayer->CreateFeature( liFeature ) != OGRERR_NONE )
      {
         printf( "\nERROR: Failed to create feature in shapefile.\n" );
         exit( 1 );
      }
      OGRFeature::DestroyFeature( liFeature );
      GDALTermProgress( (float)(k+1) / (float)(m_labels), NULL, NULL );
  }
  GDALTermProgress( 1.0f, NULL, NULL );

  GDALClose( liDS );

}