142 if (xlon *
clon < 0.) {
149 if (fabs(xlon -
clon) > 180.) {
157 if (
clat != lat0_cache) {
159 switch (m_projection_type) {
160 case PROJECTION_MERCATOR:
161 case PROJECTION_WEB_MERCATOR:
162 cache0 = toSMcache_y30(
clat);
164 case PROJECTION_POLAR:
165 cache0 = toPOLARcache_e(
clat);
167 case PROJECTION_ORTHOGRAPHIC:
168 case PROJECTION_STEREOGRAPHIC:
169 case PROJECTION_GNOMONIC:
170 cache_phi0(
clat, &cache0, &cache1);
175 switch (m_projection_type) {
176 case PROJECTION_MERCATOR:
177 case PROJECTION_WEB_MERCATOR:
178 toSMcache(lat, xlon, cache0,
clon, &easting, &northing);
181 case PROJECTION_TRANSVERSE_MERCATOR:
185 double tmeasting, tmnorthing;
186 double tmceasting, tmcnorthing;
188 toTM(lat, xlon, 0.,
clon, &tmeasting, &tmnorthing);
190 northing = tmnorthing - tmcnorthing;
191 easting = tmeasting - tmceasting;
194 case PROJECTION_POLYCONIC:
198 double pceasting, pcnorthing;
201 double peasting, pnorthing;
202 toPOLY(lat, xlon, 0.,
clon, &peasting, &pnorthing);
205 northing = pnorthing - pcnorthing;
208 case PROJECTION_ORTHOGRAPHIC:
209 toORTHO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
212 case PROJECTION_POLAR:
213 toPOLAR(lat, xlon, cache0,
clat,
clon, &easting, &northing);
216 case PROJECTION_STEREOGRAPHIC:
217 toSTEREO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
220 case PROJECTION_GNOMONIC:
221 toGNO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
224 case PROJECTION_EQUIRECTANGULAR:
225 toEQUIRECT(lat, xlon,
clat,
clon, &easting, &northing);
229 printf(
"unhandled projection\n");
232 if (!wxFinite(easting) || !wxFinite(northing))
233 return wxPoint2DDouble(easting, northing);
244 dxr = epix * cos(angle) + npix * sin(angle);
245 dyr = npix * cos(angle) - epix * sin(angle);
256 return wxPoint2DDouble(x, y);
273 xpr = (dx * cos(angle)) - (dy * sin(angle));
274 ypr = (dy * cos(angle)) + (dx * sin(angle));
279 double slat = 0.0, slon = 0.0;
280 switch (m_projection_type) {
281 case PROJECTION_MERCATOR:
282 case PROJECTION_WEB_MERCATOR:
286 fromSM(d_east, d_north,
clat,
clon, &slat, &slon);
289 case PROJECTION_TRANSVERSE_MERCATOR: {
290 double tmceasting, tmcnorthing;
293 fromTM(d_east, d_north + tmcnorthing, 0.,
clon, &slat, &slon);
296 case PROJECTION_POLYCONIC: {
297 double polyeasting, polynorthing;
298 toPOLY(
clat,
clon, 0.,
clon, &polyeasting, &polynorthing);
300 fromPOLY(d_east, d_north + polynorthing, 0.,
clon, &slat, &slon);
303 case PROJECTION_ORTHOGRAPHIC:
304 fromORTHO(d_east, d_north,
clat,
clon, &slat, &slon);
307 case PROJECTION_POLAR:
308 fromPOLAR(d_east, d_north,
clat,
clon, &slat, &slon);
311 case PROJECTION_STEREOGRAPHIC:
312 fromSTEREO(d_east, d_north,
clat,
clon, &slat, &slon);
315 case PROJECTION_GNOMONIC:
316 fromGNO(d_east, d_north,
clat,
clon, &slat, &slon);
319 case PROJECTION_EQUIRECTANGULAR:
320 fromEQUIRECT(d_east, d_north,
clat,
clon, &slat, &slon);
324 printf(
"unhandled projection\n");
331 else if (slon > 180.)
413 const LLRegion &llregion,
414 int chart_native_scale) {
418 std::list<ContourRegion> cregions;
419 for (
auto i = llregion.contours.begin(); i != llregion.contours.end(); i++) {
420 float *contour_points =
new float[2 * i->size()];
422 for (
auto j = i->begin(); j != i->end(); j++) {
423 contour_points[idx++] = j->y;
424 contour_points[idx++] = j->x;
427 double total = 0, maxlat = -90;
429 double x0 = contour_points[0] - contour_points[pl + 0];
430 double y0 = contour_points[1] - contour_points[pl + 1];
432 for (
int p = 0; p < idx; p += 2) {
433 maxlat = wxMax(maxlat, contour_points[p]);
434 int pn = p < idx - 2 ? p + 2 : 0;
435 double x1 = contour_points[pn + 0] - contour_points[p + 0];
436 double y1 = contour_points[pn + 1] - contour_points[p + 1];
437 total += x1 * y0 - x0 * y1;
443 s.subtract = total < 0;
445 chart_native_scale, NULL);
446 delete[] contour_points;
448 std::list<ContourRegion>::iterator k = cregions.begin();
449 while (k != cregions.end()) {
450 if (k->maxlat < s.maxlat)
break;
453 cregions.insert(k, s);
457 for (std::list<ContourRegion>::iterator k = cregions.begin();
458 k != cregions.end(); k++) {
473 int chart_native_scale,
485 float *pfp = llpoints;
486 float lon_max = -10000.;
487 float lon_min = 10000.;
488 float lat_max = -10000.;
489 float lat_min = 10000.;
491 for (
int ip = 0; ip < nPoints; ip++) {
492 lon_max = wxMax(lon_max, pfp[1]);
493 lon_min = wxMin(lon_min, pfp[1]);
494 lat_max = wxMax(lat_max, pfp[0]);
495 lat_min = wxMin(lat_min, pfp[0]);
501 chart_box.Set(lat_min, lon_min, lat_max, lon_max);
505 if (chart_box.IntersectOut(vpBBox))
return OCPNRegion();
515 if (chart_box.IntersectIn(vpBBox))
return Region;
531 pp =
new wxPoint[nPoints];
535 float *pfp = llpoints;
538 int poly_x_max = INVALID_COORD, poly_y_max = INVALID_COORD,
539 poly_x_min = INVALID_COORD, poly_y_min = INVALID_COORD;
543 for (
int ip = 0; ip < nPoints; ip++) {
545 if (p.x == INVALID_COORD)
continue;
550 poly_x_max = wxMax(poly_x_max, p.x);
551 poly_y_max = wxMax(poly_y_max, p.y);
552 poly_x_min = wxMin(poly_x_min, p.x);
553 poly_y_min = wxMin(poly_y_min, p.y);
565 if (ppoints == NULL)
delete[] pp;
572 float_2Dpt p0, p1, p2, p3;
577 bool b_intersect =
false;
579 while (screen_region_it1.HaveRects()) {
580 wxRect rect = screen_region_it1.GetRect();
589 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y), &lat, &lon);
593 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y + rect.height), &lat,
598 GetLLFromPix(wxPoint(rect.x, rect.y + rect.height), &lat, &lon);
602 for (
int i = 0; i < npPoints - 1; i++) {
605 int y1 = pp[i + 1].y;
607 if (((y0 < rect.y) && (y1 < rect.y)) ||
608 ((y0 > rect.y + rect.height) && (y1 > rect.y + rect.height)))
613 f0.y = llpoints[i * 2];
614 f0.x = llpoints[(i * 2) + 1];
616 f1.y = llpoints[(i + 1) * 2];
617 f1.x = llpoints[((i + 1) * 2) + 1];
618 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
619 if (b_intersect)
break;
620 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
621 if (b_intersect)
break;
622 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
623 if (b_intersect)
break;
624 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
625 if (b_intersect)
break;
631 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
632 if (b_intersect)
break;
633 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
634 if (b_intersect)
break;
635 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
636 if (b_intersect)
break;
637 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
638 if (b_intersect)
break;
644 f0.y = llpoints[(nPoints - 1) * 2];
645 f0.x = llpoints[((nPoints - 1) * 2) + 1];
649 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
650 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
651 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
652 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
656 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
657 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
658 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
659 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
662 screen_region_it1.NextRect();
668 bool b_contained =
false;
671 while (screen_region_it2.HaveRects()) {
672 wxRect rect = screen_region_it2.GetRect();
674 for (
int i = 0; i < npPoints - 1; i++) {
678 if ((x0 < rect.x) || (x0 > rect.x + rect.width) || (y0 < rect.y) ||
679 (y0 > rect.y + rect.height))
685 screen_region_it2.NextRect();
691 if (!b_contained && !b_intersect) {
693 wxRect rpoly(poly_x_min, poly_y_min, poly_x_max - poly_x_min,
694 poly_y_max - poly_y_min);
695 wxRect rRegion = Region.GetBox();
696 if (rpoly.Contains(rRegion)) {
706 float rlat = (p0.y + p2.y) / 2.;
707 float rlon = (p0.x + p1.x) / 2.;
709 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
710 if (NULL == ppoints)
delete[] pp;
714 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
715 if (NULL == ppoints)
delete[] pp;
721 if (NULL == ppoints)
delete[] pp;
732 if (NULL == ppoints)
delete[] pp;
736 }
else if (b_contained && !b_intersect) {
740 if (NULL == ppoints)
delete[] pp;
747 sigaction(SIGSEGV, NULL,
750 struct sigaction temp;
751 sigaction(SIGSEGV, NULL, &temp);
753 temp.sa_handler = catch_signals;
754 sigemptyset(&temp.sa_mask);
759 sigaction(SIGSEGV, &temp, NULL);
761 if (sigsetjmp(env, 1))
763 sigaction(SIGSEGV, &sa_all_old, NULL);
771 if (NULL == ppoints)
delete[] pp;
773 sigaction(SIGSEGV, &sa_all_old, NULL);
781 if (NULL == ppoints)
delete[] pp;
830 int dy = wxRound(fabs(lpixh * cos(rotator)) + fabs(lpixw * sin(rotator)));
831 int dx = wxRound(fabs(lpixw * cos(rotator)) + fabs(lpixh * sin(rotator)));
835 if (dy % 4) dy += 4 - (dy % 4);
836 if (dx % 4) dx += 4 - (dx % 4);
838 int inflate_x = wxMax((dx -
pix_width) / 2, 0);
839 int inflate_y = wxMax((dy -
pix_height) / 2, 0);
842 rv_rect.Inflate(inflate_x, inflate_y);
850 SetRotationAngle(0.0);
852 wxPoint ul(rv_rect.x, rv_rect.y);
853 wxPoint lr(rv_rect.x + rv_rect.width,
854 rv_rect.y + rv_rect.height);
855 double dlat_min, dlat_max, dlon_min, dlon_max;
857 bool hourglass =
false;
858 switch (m_projection_type) {
859 case PROJECTION_TRANSVERSE_MERCATOR:
860 case PROJECTION_STEREOGRAPHIC:
861 case PROJECTION_GNOMONIC:
864 case PROJECTION_POLYCONIC:
865 case PROJECTION_POLAR:
866 case PROJECTION_ORTHOGRAPHIC: {
870 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
871 wxPoint ur(rv_rect.x + rv_rect.width, rv_rect.y);
877 if (fabs(fabs(d -
clon) - 180) < 1) {
881 }
else if (std::isnan(dlat_max))
886 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
889 dlat_min = wxMin(dlat_min, dlat_min2);
892 if (std::isnan(dlat_min))
893 dlat_min =
clat - 90;
895 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
896 wxPoint ll(rv_rect.x, rv_rect.y + rv_rect.height);
902 if (fabs(fabs(d -
clon) - 180) < 1) {
906 }
else if (std::isnan(dlat_min))
911 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
914 dlat_max = wxMax(dlat_max, dlat_max2);
917 if (std::isnan(dlat_max))
918 dlat_max =
clat + 90;
921 if (std::isnan(dlon_min)) {
924 if (dlat_max < 90 && dlat_min > -90) {
945 else if (
clon > dlon_max)
949 vpBBox.Set(dlat_min, dlon_min, dlat_max, dlon_max);
952 SetRotationAngle(rotation_save);