315 geos::geom::Coordinate lastPoint,
316 int recursionDepth) {
317 double x = lastPoint.x - currentPoint->x;
318 double y = lastPoint.y - currentPoint->y;
319 geos::geom::Coordinate result;
322 if (recursionDepth > 6) {
323 return *currentPoint;
327 if (x == 0.0 && y == 0.0) {
330 double s = currentPoint->x + samp;
331 double l = currentPoint->y + line;
335 geos::geom::Coordinate next(s, l);
341 std::string msg =
"Unable to create image footprint. Starting point is not on the edge of the image.";
342 throw IException(IException::Programmer, msg, _FILEINFO_);
344 else if (x < 0 && y < 0) {
345 geos::geom::Coordinate next(currentPoint->x, currentPoint->y - 1 *
p_lineinc);
348 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
354 else if (x == 0.0 && y < 0) {
355 geos::geom::Coordinate next(currentPoint->x + 1 *
p_sampinc, currentPoint->y - 1 *
p_lineinc);
358 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
364 else if (x > 0 && y < 0) {
365 geos::geom::Coordinate next(currentPoint->x + 1 *
p_sampinc, currentPoint->y);
368 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
374 else if (x > 0 && y == 0.0) {
375 geos::geom::Coordinate next(currentPoint->x + 1 *
p_sampinc, currentPoint->y + 1 *
p_lineinc);
378 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
384 else if (x > 0 && y > 0) {
385 geos::geom::Coordinate next(currentPoint->x, currentPoint->y + 1 *
p_lineinc);
388 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
394 else if (x == 0.0 && y > 0) {
395 geos::geom::Coordinate next(currentPoint->x - 1 *
p_sampinc, currentPoint->y + 1 *
p_lineinc);
398 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
404 else if (x < 0 && y > 0) {
405 geos::geom::Coordinate next(currentPoint->x - 1 *
p_sampinc, currentPoint->y);
408 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
414 else if (x < 0 && y == 0.0) {
415 geos::geom::Coordinate next(currentPoint->x - 1 *
p_sampinc, currentPoint->y - 1 *
p_lineinc);
418 result =
FindNextPoint(currentPoint, next, recursionDepth + 1);
425 std::string msg =
"Unable to create image footprint. Error walking image.";
426 throw IException(IException::Unknown, msg, _FILEINFO_);
636 vector<geos::geom::Coordinate> points;
637 double lat, lon, prevLat, prevLon;
642 points.push_back(firstPoint);
648 geos::geom::Coordinate currentPoint = firstPoint;
649 geos::geom::Coordinate lastPoint = firstPoint;
650 geos::geom::Coordinate tempPoint;
656 bool snapToFirstPoint =
true;
662 snapToFirstPoint &= (points.size() > 2);
669 snapToFirstPoint &= (
DistanceSquared(¤tPoint, &firstPoint) < (minStepSize * minStepSize));
672 if (snapToFirstPoint) {
673 tempPoint = firstPoint;
679 for (
int pt = 0; pt < (int)points.size(); pt ++) {
680 if (points[pt].equals(tempPoint)) {
681 tempPoint = firstPoint;
687 if (tempPoint.equals(currentPoint)) {
688 geos::geom::Coordinate oldDuplicatePoint = tempPoint;
691 tempPoint = lastPoint;
692 lastPoint = currentPoint;
693 currentPoint = tempPoint;
697 if (points.size() < 3) {
698 std::string msg =
"Failed to find next point in the image.";
699 throw IException(IException::Programmer, msg, _FILEINFO_);
707 if (tempPoint.equals(currentPoint) || tempPoint.equals(oldDuplicatePoint)) {
708 std::string msg =
"Failed to find next valid point in the image.";
709 throw IException(IException::Programmer, msg, _FILEINFO_);
716 if (points[points.size()-3].x == tempPoint.x &&
717 points[points.size()-3].y == tempPoint.y) {
723 currentPoint = points[points.size()-1];
735 if (points.size() > 250) {
739 for (
unsigned int pt = 1; pt < points.size() && cycleStart == 0; pt ++) {
740 for (
unsigned int check = pt + 1; check < points.size() && cycleStart == 0; check ++) {
741 if (points[pt] == points[check]) {
749 if (cycleStart != 0) {
750 vector<geos::geom::Coordinate> cyclePoints;
751 for (
int pt = cycleStart; pt <= cycleEnd; pt ++) {
752 cyclePoints.push_back(points[pt]);
755 points = cyclePoints;
762 lastPoint = currentPoint;
763 currentPoint = tempPoint;
764 points.push_back(currentPoint);
767 while (!currentPoint.equals(firstPoint));
769 if (points.size() <= 3) {
770 std::string msg =
"Failed to find enough points on the image.";
771 throw IException(IException::Programmer, msg, _FILEINFO_);
780 vector<geos::geom::Coordinate> *crossingPoints =
new vector<geos::geom::Coordinate>;
781 for (
unsigned int i = 0; i < points.size(); i++) {
782 geos::geom::Coordinate *temp = &(points.at(i));
784 lon =
p_gMap->UniversalLongitude();
785 lat =
p_gMap->UniversalLatitude();
786 if (abs(lon - prevLon) >= 180 && i != 0) {
787 crossingPoints->push_back(geos::geom::Coordinate(prevLon, prevLat));
789 p_pts->add(geos::geom::Coordinate(lon, lat));
796 geos::geom::CoordinateSequence *tempPts =
new geos::geom::CoordinateSequence();
799 tempPts->add(geos::geom::Coordinate((*
p_pts)[0].x, (*
p_pts)[0].y));
800 tempPts->add(geos::geom::Coordinate((*
p_pts)[1].x, (*
p_pts)[1].y));
803 tempPts->add(geos::geom::Coordinate((*
p_pts)[0].x, (*
p_pts)[0].y));
805 geos::geom::Polygon *tempPoly = globalFactory->createPolygon
806 (globalFactory->createLinearRing(*tempPts)).release();
809 if (!tempPoly->isValid()) {
810 std::vector<geos::geom::Coordinate> coords;
811 p_pts->toVector(coords);
812 coords.erase(coords.begin() +
p_pts->size() - 2);
813 p_pts->setPoints(coords);
821 delete crossingPoints;
822 crossingPoints = NULL;
835 bool hasNorthPole =
false;
836 bool hasSouthPole =
false;
838 if (
p_gMap->SetUniversalGround(90, 0)) {
839 double nPoleSample = Null;
840 double nPoleLine = Null;
842 if (
p_gMap->Projection()) {
843 nPoleSample =
p_gMap->Projection()->WorldX();
844 nPoleLine =
p_gMap->Projection()->WorldY();
846 else if (
p_gMap->Camera()) {
847 nPoleSample =
p_gMap->Camera()->Sample();
848 nPoleLine =
p_gMap->Camera()->Line();
851 if (nPoleSample >= 0.5 && nPoleLine >= 0.5 &&
852 nPoleSample <= p_cube->sampleCount() + 0.5 &&
853 nPoleLine <= p_cube->lineCount() + 0.5 &&
859 if (
p_gMap->SetUniversalGround(-90, 0)) {
860 double sPoleSample = Null;
861 double sPoleLine = Null;
863 if (
p_gMap->Projection()) {
864 sPoleSample =
p_gMap->Projection()->WorldX();
865 sPoleLine =
p_gMap->Projection()->WorldY();
867 else if (
p_gMap->Camera()) {
868 sPoleSample =
p_gMap->Camera()->Sample();
869 sPoleLine =
p_gMap->Camera()->Line();
872 if (sPoleSample >= 0.5 && sPoleLine >= 0.5 &&
873 sPoleSample <= p_cube->sampleCount() + 0.5 &&
874 sPoleLine <= p_cube->lineCount() + 0.5 &&
880 if (hasNorthPole && hasSouthPole) {
881 std::string msg =
"Unable to create image footprint because image has both poles";
882 throw IException(IException::Programmer, msg, _FILEINFO_);
884 else if (crossingPoints->size() == 0) {
890 p_gMap->SetUniversalGround(90, 0);
903 else if (hasSouthPole) {
904 p_gMap->SetUniversalGround(-90, 0);
918 geos::geom::Coordinate *closestPoint = &crossingPoints->at(0);
919 geos::geom::Coordinate *pole = NULL;
923 pole =
new geos::geom::Coordinate(0, 90);
925 else if (hasSouthPole) {
926 pole =
new geos::geom::Coordinate(0, -90);
928 else if (crossingPoints->size() % 2 == 1) {
929 geos::geom::Coordinate nPole(0, 90);
930 double nDist = DBL_MAX;
931 geos::geom::Coordinate sPole(0, -90);
932 double sDist = DBL_MAX;
934 for (
unsigned int index = 0; index <
p_pts->size(); index ++) {
946 pole =
new geos::geom::Coordinate(0, -90);
949 pole =
new geos::geom::Coordinate(0, 90);
959 double closestDistance = DBL_MAX;
960 for (
unsigned int i = 0; i < crossingPoints->size(); i++) {
961 geos::geom::Coordinate *temp = &crossingPoints->at(i);
966 while ((temp->x - mod) > 180) mod += 360.0;
969 geos::geom::Coordinate modPointMem = geos::geom::Coordinate(temp->x - mod, temp->y);
970 geos::geom::Coordinate *modPoint = &modPointMem;
976 if (tempDistance < closestDistance) {
977 closestDistance = tempDistance;
982 if (closestDistance == DBL_MAX) {
983 std::string msg =
"Image contains a pole but did not detect a meridian crossing!";
984 throw IException(IException::Programmer, msg, _FILEINFO_);
988 geos::geom::CoordinateSequence *new_points =
new geos::geom::CoordinateSequence();
989 for (
unsigned int i = 0; i <
p_pts->size(); i++) {
990 geos::geom::Coordinate temp =
p_pts->getAt(i);
991 new_points->add(temp);
992 if (temp.equals(*closestPoint)) {
994 if (i + 1 !=
p_pts->size()) {
995 double fromLon, toLon;
996 if ((
p_pts->getAt(i + 1).x - closestPoint->x) > 0) {
1005 geos::algorithm::LineIntersector lineIntersector;
1006 geos::geom::Coordinate crossingPoint;
1007 geos::geom::Coordinate nPole(0.0, 90.0);
1008 geos::geom::Coordinate sPole(0.0, -90.0);
1009 double dist = DBL_MAX;
1011 for (
int num = 0; num < 2 && dist > 180.0; num ++) {
1012 nPole = geos::geom::Coordinate(num * 360.0, 90.0);
1013 sPole = geos::geom::Coordinate(num * 360.0, -90.0);
1015 if (temp.x > 0.0 &&
p_pts->getAt(i + 1).x > 0.0) {
1016 crossingPoint = geos::geom::Coordinate(
p_pts->getAt(i + 1).x - 360.0 + (num * 720.0),
p_pts->getAt(i + 1).y);
1018 else if (temp.x < 0.0 &&
p_pts->getAt(i + 1).x < 0.0) {
1019 crossingPoint = geos::geom::Coordinate(
p_pts->getAt(i + 1).x + 360.0 - (num * 720.0),
p_pts->getAt(i + 1).y);
1025 lineIntersector.computeIntersection(nPole, sPole, temp, crossingPoint);
1027 if (lineIntersector.hasIntersection()) {
1028 const geos::geom::Coordinate &intersection = lineIntersector.getIntersection(0);
1031 if (pole->y < intersection.y) {
1034 vector<double> lats;
1035 double maxLat = std::max(intersection.y, pole->y);
1036 double minLat = std::min(intersection.y, pole->y);
1037 for (
double lat = intersection.y + dist; lat < maxLat && lat > minLat; lat += dist) {
1038 lats.push_back(lat);
1042 new_points->add(geos::geom::Coordinate(fromLon, intersection.y));
1043 for (
int lat = 0; lat < (int)lats.size(); lat ++) {
1044 new_points->add(geos::geom::Coordinate(fromLon, lats[lat]));
1046 new_points->add(geos::geom::Coordinate(fromLon, pole->y));
1047 new_points->add(geos::geom::Coordinate(toLon, pole->y));
1048 for (
int lat = lats.size() - 1; lat >= 0; lat --) {
1049 new_points->add(geos::geom::Coordinate(toLon, lats[lat]));
1051 new_points->add(geos::geom::Coordinate(toLon, intersection.y));
1054 std::string msg =
"Image contains a pole but could not determine a meridian crossing!";
1055 throw IException(IException::Programmer, msg, _FILEINFO_);
1142 bool convertLon =
false;
1143 bool negAdjust =
false;
1144 bool newCoords =
false;
1145 geos::geom::CoordinateSequence *newLonLatPts =
new geos::geom::CoordinateSequence();
1147 double lonOffset = 0;
1148 double prevLon =
p_pts->getAt(0).x;
1149 double prevLat =
p_pts->getAt(0).y;
1151 newLonLatPts->add(geos::geom::Coordinate(prevLon, prevLat));
1153 for (
unsigned int i = 1; i <
p_pts->getSize(); i++) {
1154 lon =
p_pts->getAt(i).x;
1155 lat =
p_pts->getAt(i).y;
1158 if (abs(lon - prevLon) > 180 && (prevLat != 90 && prevLat != -90)) {
1166 if ((lon - prevLon) > 0) {
1170 else if ((lon - prevLon) < 0) {
1181 if (newCoords && dist == 0.0) {
1182 double longitude = (lon + lonOffset) - prevLon;
1183 double latitude = lat - prevLat;
1184 dist = std::sqrt((longitude * longitude) + (latitude * latitude));
1188 newLonLatPts->add(geos::geom::Coordinate(lon + lonOffset, lat));
1197 geos::geom::Polygon *newPoly = globalFactory->createPolygon
1198 (globalFactory->createLinearRing(*newLonLatPts)).release();
1200 delete newLonLatPts;
1206 geos::geom::Polygon *newPoly = globalFactory->createPolygon
1207 (globalFactory->createLinearRing(*newLonLatPts)).release();
1209 geos::geom::CoordinateSequence *pts =
new geos::geom::CoordinateSequence();
1210 geos::geom::CoordinateSequence *pts2 =
new geos::geom::CoordinateSequence();
1218 pts->add(geos::geom::Coordinate(0., 90.));
1219 pts->add(geos::geom::Coordinate(-360., 90.));
1220 pts->add(geos::geom::Coordinate(-360., -90.));
1221 pts->add(geos::geom::Coordinate(0., -90.));
1222 for (
double lat = -90.0 + dist; lat < 90.0; lat += dist) {
1223 pts->add(geos::geom::Coordinate(0.0, lat));
1225 pts->add(geos::geom::Coordinate(0., 90.));
1226 pts2->add(geos::geom::Coordinate(0., 90.));
1227 pts2->add(geos::geom::Coordinate(360., 90.));
1228 pts2->add(geos::geom::Coordinate(360., -90.));
1229 pts2->add(geos::geom::Coordinate(0., -90.));
1230 for (
double lat = -90.0 + dist; lat < 90.0; lat += dist) {
1231 pts2->add(geos::geom::Coordinate(0.0, lat));
1233 pts2->add(geos::geom::Coordinate(0., 90.));
1236 pts->add(geos::geom::Coordinate(360., 90.));
1237 pts->add(geos::geom::Coordinate(720., 90.));
1238 pts->add(geos::geom::Coordinate(720., -90.));
1239 pts->add(geos::geom::Coordinate(360., -90.));
1240 for (
double lat = -90.0 + dist; lat < 90.0; lat += dist) {
1241 pts->add(geos::geom::Coordinate(360.0, lat));
1243 pts->add(geos::geom::Coordinate(360., 90.));
1244 pts2->add(geos::geom::Coordinate(360., 90.));
1245 pts2->add(geos::geom::Coordinate(0., 90.));
1246 pts2->add(geos::geom::Coordinate(0., -90.));
1247 pts2->add(geos::geom::Coordinate(360., -90.));
1248 for (
double lat = -90.0 + dist; lat < 90.0; lat += dist) {
1249 pts2->add(geos::geom::Coordinate(360.0, lat));
1251 pts2->add(geos::geom::Coordinate(360., 90.));
1254 geos::geom::Polygon *boundaryPoly = globalFactory->createPolygon
1255 (globalFactory->createLinearRing(*pts)).release();
1256 geos::geom::Polygon *boundaryPoly2 = globalFactory->createPolygon
1257 (globalFactory->createLinearRing(*pts2)).release();
1265 delete intersection;
1269 delete intersection;
1276 std::vector<const geos::geom::Geometry *> *finalpolys =
new std::vector<const geos::geom::Geometry *>;
1277 const geos::geom::Geometry *newGeom = NULL;
1279 for (
size_t i = 0; i < convertPoly->getNumGeometries(); i++) {
1280 newGeom = (convertPoly->getGeometryN(i))->clone().release();
1281 geos::geom::CoordinateSequence *pts3 = convertPoly->getGeometryN(i)->getCoordinates().release();
1282 geos::geom::CoordinateSequence *newLonLatPts =
new geos::geom::CoordinateSequence();
1285 for (
size_t k = 0; k < pts3->getSize() ; k++) {
1286 double lon = pts3->getAt(k).x;
1287 double lat = pts3->getAt(k).y;
1294 newLonLatPts->add(geos::geom::Coordinate(lon, lat), k);
1298 finalpolys->push_back(globalFactory->createPolygon
1299 (globalFactory->createLinearRing(*newLonLatPts)).release());
1303 for (
unsigned int i = 0; i < convertPoly2->getNumGeometries(); i++) {
1304 newGeom = (convertPoly2->getGeometryN(i))->clone().release();
1305 finalpolys->push_back(newGeom);
1308 p_polygons = globalFactory->createMultiPolygon(*finalpolys).release();
1310 delete newLonLatPts;
1314 catch(geos::util::IllegalArgumentException *geosIll) {
1315 std::string msg =
"Unable to create image footprint (Fix360Poly) due to ";
1316 msg +=
"geos illegal argument [" + IString(geosIll->what()) +
"]";
1318 throw IException(IException::Unknown, msg, _FILEINFO_);
1320 catch(geos::util::GEOSException *geosExc) {
1321 std::string msg =
"Unable to create image footprint (Fix360Poly) due to ";
1322 msg +=
"geos exception [" + IString(geosExc->what()) +
"]";
1324 throw IException(IException::Unknown, msg, _FILEINFO_);
1326 catch(IException &e) {
1327 std::string msg =
"Unable to create image footprint (Fix360Poly) due to ";
1328 msg +=
"isis operation exception [" + IString(e.what()) +
"]";
1329 throw IException(e, IException::Unknown, msg, _FILEINFO_);
1331 catch(std::exception &e) {
1332 std::string msg =
"Caught std::exception: ";
1334 throw IException(IException::Unknown, msg, _FILEINFO_);
1337 std::string msg =
"Unable to create image footprint (Fix360Poly) due to ";
1338 msg +=
"unknown exception";
1339 throw IException(IException::Unknown, msg, _FILEINFO_);
1478 geos::geom::Coordinate newPoint) {
1479 geos::geom::Coordinate originalPoint = newPoint;
1480 geos::geom::Coordinate modPoint = newPoint;
1488 else if (currentPoint->x < newPoint.x && currentPoint->y > newPoint.y) {
1489 while (newPoint.x >= currentPoint->x &&
SetImage(newPoint.x, newPoint.y)) {
1490 modPoint = newPoint;
1496 else if (currentPoint->y < newPoint.y && currentPoint->x < newPoint.x) {
1497 while (newPoint.y >= currentPoint->y &&
SetImage(newPoint.x, newPoint.y)) {
1498 modPoint = newPoint;
1504 else if (currentPoint->x > newPoint.x && currentPoint->y < newPoint.y) {
1505 while (newPoint.x <= currentPoint->x &&
SetImage(newPoint.x, newPoint.y)) {
1506 modPoint = newPoint;
1512 else if (currentPoint->y > newPoint.y && currentPoint->x > newPoint.x) {
1513 while (newPoint.y <= currentPoint->y &&
SetImage(newPoint.x, newPoint.y)) {
1514 modPoint = newPoint;
1519 if (currentPoint->x == modPoint.x && currentPoint->y == modPoint.y) {
1520 return originalPoint;