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; }