139 if (xlon *
clon < 0.) {
146 if (fabs(xlon -
clon) > 180.) {
154 if (
clat != lat0_cache) {
156 switch (m_projection_type) {
157 case PROJECTION_MERCATOR:
158 case PROJECTION_WEB_MERCATOR:
159 cache0 = toSMcache_y30(
clat);
161 case PROJECTION_POLAR:
162 cache0 = toPOLARcache_e(
clat);
164 case PROJECTION_ORTHOGRAPHIC:
165 case PROJECTION_STEREOGRAPHIC:
166 case PROJECTION_GNOMONIC:
167 cache_phi0(
clat, &cache0, &cache1);
172 switch (m_projection_type) {
173 case PROJECTION_MERCATOR:
174 case PROJECTION_WEB_MERCATOR:
175 toSMcache(lat, xlon, cache0,
clon, &easting, &northing);
178 case PROJECTION_TRANSVERSE_MERCATOR:
182 double tmeasting, tmnorthing;
183 double tmceasting, tmcnorthing;
185 toTM(lat, xlon, 0.,
clon, &tmeasting, &tmnorthing);
187 northing = tmnorthing - tmcnorthing;
188 easting = tmeasting - tmceasting;
191 case PROJECTION_POLYCONIC:
195 double pceasting, pcnorthing;
198 double peasting, pnorthing;
199 toPOLY(lat, xlon, 0.,
clon, &peasting, &pnorthing);
202 northing = pnorthing - pcnorthing;
205 case PROJECTION_ORTHOGRAPHIC:
206 toORTHO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
209 case PROJECTION_POLAR:
210 toPOLAR(lat, xlon, cache0,
clat,
clon, &easting, &northing);
213 case PROJECTION_STEREOGRAPHIC:
214 toSTEREO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
217 case PROJECTION_GNOMONIC:
218 toGNO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
221 case PROJECTION_EQUIRECTANGULAR:
222 toEQUIRECT(lat, xlon,
clat,
clon, &easting, &northing);
226 printf(
"unhandled projection\n");
229 if (!wxFinite(easting) || !wxFinite(northing))
230 return wxPoint2DDouble(easting, northing);
241 dxr = epix * cos(angle) + npix * sin(angle);
242 dyr = npix * cos(angle) - epix * sin(angle);
253 return wxPoint2DDouble(x, y);
270 xpr = (dx * cos(angle)) - (dy * sin(angle));
271 ypr = (dy * cos(angle)) + (dx * sin(angle));
276 double slat = 0.0, slon = 0.0;
277 switch (m_projection_type) {
278 case PROJECTION_MERCATOR:
279 case PROJECTION_WEB_MERCATOR:
283 fromSM(d_east, d_north,
clat,
clon, &slat, &slon);
286 case PROJECTION_TRANSVERSE_MERCATOR: {
287 double tmceasting, tmcnorthing;
290 fromTM(d_east, d_north + tmcnorthing, 0.,
clon, &slat, &slon);
293 case PROJECTION_POLYCONIC: {
294 double polyeasting, polynorthing;
295 toPOLY(
clat,
clon, 0.,
clon, &polyeasting, &polynorthing);
297 fromPOLY(d_east, d_north + polynorthing, 0.,
clon, &slat, &slon);
300 case PROJECTION_ORTHOGRAPHIC:
301 fromORTHO(d_east, d_north,
clat,
clon, &slat, &slon);
304 case PROJECTION_POLAR:
305 fromPOLAR(d_east, d_north,
clat,
clon, &slat, &slon);
308 case PROJECTION_STEREOGRAPHIC:
309 fromSTEREO(d_east, d_north,
clat,
clon, &slat, &slon);
312 case PROJECTION_GNOMONIC:
313 fromGNO(d_east, d_north,
clat,
clon, &slat, &slon);
316 case PROJECTION_EQUIRECTANGULAR:
317 fromEQUIRECT(d_east, d_north,
clat,
clon, &slat, &slon);
321 printf(
"unhandled projection\n");
328 else if (slon > 180.)
410 const LLRegion &llregion,
411 int chart_native_scale) {
415 std::list<ContourRegion> cregions;
416 for (std::list<poly_contour>::const_iterator i = llregion.contours.begin();
417 i != llregion.contours.end(); i++) {
418 float *contour_points =
new float[2 * i->size()];
420 std::list<contour_pt>::const_iterator j;
421 for (j = i->begin(); j != i->end(); j++) {
422 contour_points[idx++] = j->y;
423 contour_points[idx++] = j->x;
426 double total = 0, maxlat = -90;
428 double x0 = contour_points[0] - contour_points[pl + 0];
429 double y0 = contour_points[1] - contour_points[pl + 1];
431 for (
int p = 0; p < idx; p += 2) {
432 maxlat = wxMax(maxlat, contour_points[p]);
433 int pn = p < idx - 2 ? p + 2 : 0;
434 double x1 = contour_points[pn + 0] - contour_points[p + 0];
435 double y1 = contour_points[pn + 1] - contour_points[p + 1];
436 total += x1 * y0 - x0 * y1;
442 s.subtract = total < 0;
444 chart_native_scale, NULL);
445 delete[] contour_points;
447 std::list<ContourRegion>::iterator k = cregions.begin();
448 while (k != cregions.end()) {
449 if (k->maxlat < s.maxlat)
break;
452 cregions.insert(k, s);
456 for (std::list<ContourRegion>::iterator k = cregions.begin();
457 k != cregions.end(); k++) {
472 int chart_native_scale,
484 float *pfp = llpoints;
485 float lon_max = -10000.;
486 float lon_min = 10000.;
487 float lat_max = -10000.;
488 float lat_min = 10000.;
490 for (
int ip = 0; ip < nPoints; ip++) {
491 lon_max = wxMax(lon_max, pfp[1]);
492 lon_min = wxMin(lon_min, pfp[1]);
493 lat_max = wxMax(lat_max, pfp[0]);
494 lat_min = wxMin(lat_min, pfp[0]);
500 chart_box.Set(lat_min, lon_min, lat_max, lon_max);
504 if (chart_box.IntersectOut(vpBBox))
return OCPNRegion();
514 if (chart_box.IntersectIn(vpBBox))
return Region;
530 pp =
new wxPoint[nPoints];
534 float *pfp = llpoints;
537 int poly_x_max = INVALID_COORD, poly_y_max = INVALID_COORD,
538 poly_x_min = INVALID_COORD, poly_y_min = INVALID_COORD;
542 for (
int ip = 0; ip < nPoints; ip++) {
544 if (p.x == INVALID_COORD)
continue;
549 poly_x_max = wxMax(poly_x_max, p.x);
550 poly_y_max = wxMax(poly_y_max, p.y);
551 poly_x_min = wxMin(poly_x_min, p.x);
552 poly_y_min = wxMin(poly_y_min, p.y);
564 if (ppoints == NULL)
delete[] pp;
571 float_2Dpt p0, p1, p2, p3;
576 bool b_intersect =
false;
578 while (screen_region_it1.HaveRects()) {
579 wxRect rect = screen_region_it1.GetRect();
588 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y), &lat, &lon);
592 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y + rect.height), &lat,
597 GetLLFromPix(wxPoint(rect.x, rect.y + rect.height), &lat, &lon);
601 for (
int i = 0; i < npPoints - 1; i++) {
604 int y1 = pp[i + 1].y;
606 if (((y0 < rect.y) && (y1 < rect.y)) ||
607 ((y0 > rect.y + rect.height) && (y1 > rect.y + rect.height)))
612 f0.y = llpoints[i * 2];
613 f0.x = llpoints[(i * 2) + 1];
615 f1.y = llpoints[(i + 1) * 2];
616 f1.x = llpoints[((i + 1) * 2) + 1];
617 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
618 if (b_intersect)
break;
619 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
620 if (b_intersect)
break;
621 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
622 if (b_intersect)
break;
623 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
624 if (b_intersect)
break;
630 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
631 if (b_intersect)
break;
632 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
633 if (b_intersect)
break;
634 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
635 if (b_intersect)
break;
636 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
637 if (b_intersect)
break;
643 f0.y = llpoints[(nPoints - 1) * 2];
644 f0.x = llpoints[((nPoints - 1) * 2) + 1];
648 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
649 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
650 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
651 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
655 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
656 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
657 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
658 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
661 screen_region_it1.NextRect();
667 bool b_contained =
false;
670 while (screen_region_it2.HaveRects()) {
671 wxRect rect = screen_region_it2.GetRect();
673 for (
int i = 0; i < npPoints - 1; i++) {
677 if ((x0 < rect.x) || (x0 > rect.x + rect.width) || (y0 < rect.y) ||
678 (y0 > rect.y + rect.height))
684 screen_region_it2.NextRect();
690 if (!b_contained && !b_intersect) {
692 wxRect rpoly(poly_x_min, poly_y_min, poly_x_max - poly_x_min,
693 poly_y_max - poly_y_min);
694 wxRect rRegion = Region.GetBox();
695 if (rpoly.Contains(rRegion)) {
705 float rlat = (p0.y + p2.y) / 2.;
706 float rlon = (p0.x + p1.x) / 2.;
708 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
709 if (NULL == ppoints)
delete[] pp;
713 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
714 if (NULL == ppoints)
delete[] pp;
720 if (NULL == ppoints)
delete[] pp;
731 if (NULL == ppoints)
delete[] pp;
735 }
else if (b_contained && !b_intersect) {
739 if (NULL == ppoints)
delete[] pp;
746 sigaction(SIGSEGV, NULL,
749 struct sigaction temp;
750 sigaction(SIGSEGV, NULL, &temp);
752 temp.sa_handler = catch_signals;
753 sigemptyset(&temp.sa_mask);
758 sigaction(SIGSEGV, &temp, NULL);
760 if (sigsetjmp(env, 1))
762 sigaction(SIGSEGV, &sa_all_old, NULL);
770 if (NULL == ppoints)
delete[] pp;
772 sigaction(SIGSEGV, &sa_all_old, NULL);
780 if (NULL == ppoints)
delete[] pp;
829 int dy = wxRound(fabs(lpixh * cos(rotator)) + fabs(lpixw * sin(rotator)));
830 int dx = wxRound(fabs(lpixw * cos(rotator)) + fabs(lpixh * sin(rotator)));
834 if (dy % 4) dy += 4 - (dy % 4);
835 if (dx % 4) dx += 4 - (dx % 4);
837 int inflate_x = wxMax((dx -
pix_width) / 2, 0);
838 int inflate_y = wxMax((dy -
pix_height) / 2, 0);
841 rv_rect.Inflate(inflate_x, inflate_y);
849 SetRotationAngle(0.0);
851 wxPoint ul(rv_rect.x, rv_rect.y);
852 wxPoint lr(rv_rect.x + rv_rect.width,
853 rv_rect.y + rv_rect.height);
854 double dlat_min, dlat_max, dlon_min, dlon_max;
856 bool hourglass =
false;
857 switch (m_projection_type) {
858 case PROJECTION_TRANSVERSE_MERCATOR:
859 case PROJECTION_STEREOGRAPHIC:
860 case PROJECTION_GNOMONIC:
863 case PROJECTION_POLYCONIC:
864 case PROJECTION_POLAR:
865 case PROJECTION_ORTHOGRAPHIC: {
869 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
870 wxPoint ur(rv_rect.x + rv_rect.width, rv_rect.y);
876 if (fabs(fabs(d -
clon) - 180) < 1) {
880 }
else if (std::isnan(dlat_max))
885 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
888 dlat_min = wxMin(dlat_min, dlat_min2);
891 if (std::isnan(dlat_min))
892 dlat_min =
clat - 90;
894 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
895 wxPoint ll(rv_rect.x, rv_rect.y + rv_rect.height);
901 if (fabs(fabs(d -
clon) - 180) < 1) {
905 }
else if (std::isnan(dlat_min))
910 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
913 dlat_max = wxMax(dlat_max, dlat_max2);
916 if (std::isnan(dlat_max))
917 dlat_max =
clat + 90;
920 if (std::isnan(dlon_min)) {
923 if (dlat_max < 90 && dlat_min > -90) {
944 else if (
clon > dlon_max)
948 vpBBox.Set(dlat_min, dlon_min, dlat_max, dlon_max);
951 SetRotationAngle(rotation_save);