Esempio n. 1
0
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;
}
//! 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;
}