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 (
auto i = llregion.contours.begin(); i != llregion.contours.end(); i++) {
417 float *contour_points =
new float[2 * i->size()];
419 for (
auto j = i->begin(); j != i->end(); j++) {
420 contour_points[idx++] = j->y;
421 contour_points[idx++] = j->x;
424 double total = 0, maxlat = -90;
426 double x0 = contour_points[0] - contour_points[pl + 0];
427 double y0 = contour_points[1] - contour_points[pl + 1];
429 for (
int p = 0; p < idx; p += 2) {
430 maxlat = wxMax(maxlat, contour_points[p]);
431 int pn = p < idx - 2 ? p + 2 : 0;
432 double x1 = contour_points[pn + 0] - contour_points[p + 0];
433 double y1 = contour_points[pn + 1] - contour_points[p + 1];
434 total += x1 * y0 - x0 * y1;
440 s.subtract = total < 0;
442 chart_native_scale, NULL);
443 delete[] contour_points;
445 std::list<ContourRegion>::iterator k = cregions.begin();
446 while (k != cregions.end()) {
447 if (k->maxlat < s.maxlat)
break;
450 cregions.insert(k, s);
454 for (std::list<ContourRegion>::iterator k = cregions.begin();
455 k != cregions.end(); k++) {
470 int chart_native_scale,
482 float *pfp = llpoints;
483 float lon_max = -10000.;
484 float lon_min = 10000.;
485 float lat_max = -10000.;
486 float lat_min = 10000.;
488 for (
int ip = 0; ip < nPoints; ip++) {
489 lon_max = wxMax(lon_max, pfp[1]);
490 lon_min = wxMin(lon_min, pfp[1]);
491 lat_max = wxMax(lat_max, pfp[0]);
492 lat_min = wxMin(lat_min, pfp[0]);
498 chart_box.Set(lat_min, lon_min, lat_max, lon_max);
502 if (chart_box.IntersectOut(vpBBox))
return OCPNRegion();
512 if (chart_box.IntersectIn(vpBBox))
return Region;
528 pp =
new wxPoint[nPoints];
532 float *pfp = llpoints;
535 int poly_x_max = INVALID_COORD, poly_y_max = INVALID_COORD,
536 poly_x_min = INVALID_COORD, poly_y_min = INVALID_COORD;
540 for (
int ip = 0; ip < nPoints; ip++) {
542 if (p.x == INVALID_COORD)
continue;
547 poly_x_max = wxMax(poly_x_max, p.x);
548 poly_y_max = wxMax(poly_y_max, p.y);
549 poly_x_min = wxMin(poly_x_min, p.x);
550 poly_y_min = wxMin(poly_y_min, p.y);
562 if (ppoints == NULL)
delete[] pp;
569 float_2Dpt p0, p1, p2, p3;
574 bool b_intersect =
false;
576 while (screen_region_it1.HaveRects()) {
577 wxRect rect = screen_region_it1.GetRect();
586 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y), &lat, &lon);
590 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y + rect.height), &lat,
595 GetLLFromPix(wxPoint(rect.x, rect.y + rect.height), &lat, &lon);
599 for (
int i = 0; i < npPoints - 1; i++) {
602 int y1 = pp[i + 1].y;
604 if (((y0 < rect.y) && (y1 < rect.y)) ||
605 ((y0 > rect.y + rect.height) && (y1 > rect.y + rect.height)))
610 f0.y = llpoints[i * 2];
611 f0.x = llpoints[(i * 2) + 1];
613 f1.y = llpoints[(i + 1) * 2];
614 f1.x = llpoints[((i + 1) * 2) + 1];
615 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
616 if (b_intersect)
break;
617 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
618 if (b_intersect)
break;
619 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
620 if (b_intersect)
break;
621 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
622 if (b_intersect)
break;
628 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
629 if (b_intersect)
break;
630 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
631 if (b_intersect)
break;
632 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
633 if (b_intersect)
break;
634 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
635 if (b_intersect)
break;
641 f0.y = llpoints[(nPoints - 1) * 2];
642 f0.x = llpoints[((nPoints - 1) * 2) + 1];
646 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
647 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
648 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
649 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
653 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
654 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
655 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
656 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
659 screen_region_it1.NextRect();
665 bool b_contained =
false;
668 while (screen_region_it2.HaveRects()) {
669 wxRect rect = screen_region_it2.GetRect();
671 for (
int i = 0; i < npPoints - 1; i++) {
675 if ((x0 < rect.x) || (x0 > rect.x + rect.width) || (y0 < rect.y) ||
676 (y0 > rect.y + rect.height))
682 screen_region_it2.NextRect();
688 if (!b_contained && !b_intersect) {
690 wxRect rpoly(poly_x_min, poly_y_min, poly_x_max - poly_x_min,
691 poly_y_max - poly_y_min);
692 wxRect rRegion = Region.GetBox();
693 if (rpoly.Contains(rRegion)) {
703 float rlat = (p0.y + p2.y) / 2.;
704 float rlon = (p0.x + p1.x) / 2.;
706 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
707 if (NULL == ppoints)
delete[] pp;
711 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
712 if (NULL == ppoints)
delete[] pp;
718 if (NULL == ppoints)
delete[] pp;
729 if (NULL == ppoints)
delete[] pp;
733 }
else if (b_contained && !b_intersect) {
737 if (NULL == ppoints)
delete[] pp;
744 sigaction(SIGSEGV, NULL,
747 struct sigaction temp;
748 sigaction(SIGSEGV, NULL, &temp);
750 temp.sa_handler = catch_signals;
751 sigemptyset(&temp.sa_mask);
756 sigaction(SIGSEGV, &temp, NULL);
758 if (sigsetjmp(env, 1))
760 sigaction(SIGSEGV, &sa_all_old, NULL);
768 if (NULL == ppoints)
delete[] pp;
770 sigaction(SIGSEGV, &sa_all_old, NULL);
778 if (NULL == ppoints)
delete[] pp;
827 int dy = wxRound(fabs(lpixh * cos(rotator)) + fabs(lpixw * sin(rotator)));
828 int dx = wxRound(fabs(lpixw * cos(rotator)) + fabs(lpixh * sin(rotator)));
832 if (dy % 4) dy += 4 - (dy % 4);
833 if (dx % 4) dx += 4 - (dx % 4);
835 int inflate_x = wxMax((dx -
pix_width) / 2, 0);
836 int inflate_y = wxMax((dy -
pix_height) / 2, 0);
839 rv_rect.Inflate(inflate_x, inflate_y);
847 SetRotationAngle(0.0);
849 wxPoint ul(rv_rect.x, rv_rect.y);
850 wxPoint lr(rv_rect.x + rv_rect.width,
851 rv_rect.y + rv_rect.height);
852 double dlat_min, dlat_max, dlon_min, dlon_max;
854 bool hourglass =
false;
855 switch (m_projection_type) {
856 case PROJECTION_TRANSVERSE_MERCATOR:
857 case PROJECTION_STEREOGRAPHIC:
858 case PROJECTION_GNOMONIC:
861 case PROJECTION_POLYCONIC:
862 case PROJECTION_POLAR:
863 case PROJECTION_ORTHOGRAPHIC: {
867 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
868 wxPoint ur(rv_rect.x + rv_rect.width, rv_rect.y);
874 if (fabs(fabs(d -
clon) - 180) < 1) {
878 }
else if (std::isnan(dlat_max))
883 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
886 dlat_min = wxMin(dlat_min, dlat_min2);
889 if (std::isnan(dlat_min))
890 dlat_min =
clat - 90;
892 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
893 wxPoint ll(rv_rect.x, rv_rect.y + rv_rect.height);
899 if (fabs(fabs(d -
clon) - 180) < 1) {
903 }
else if (std::isnan(dlat_min))
908 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
911 dlat_max = wxMax(dlat_max, dlat_max2);
914 if (std::isnan(dlat_max))
915 dlat_max =
clat + 90;
918 if (std::isnan(dlon_min)) {
921 if (dlat_max < 90 && dlat_min > -90) {
942 else if (
clon > dlon_max)
946 vpBBox.Set(dlat_min, dlon_min, dlat_max, dlon_max);
949 SetRotationAngle(rotation_save);