153 if (xlon *
clon < 0.) {
160 if (fabs(xlon -
clon) > 180.) {
168 if (
clat != lat0_cache) {
170 switch (m_projection_type) {
171 case PROJECTION_MERCATOR:
172 case PROJECTION_WEB_MERCATOR:
173 cache0 = toSMcache_y30(
clat);
175 case PROJECTION_POLAR:
176 cache0 = toPOLARcache_e(
clat);
178 case PROJECTION_ORTHOGRAPHIC:
179 case PROJECTION_STEREOGRAPHIC:
180 case PROJECTION_GNOMONIC:
181 cache_phi0(
clat, &cache0, &cache1);
186 switch (m_projection_type) {
187 case PROJECTION_MERCATOR:
188 case PROJECTION_WEB_MERCATOR:
189 toSMcache(lat, xlon, cache0,
clon, &easting, &northing);
192 case PROJECTION_TRANSVERSE_MERCATOR:
196 double tmeasting, tmnorthing;
197 double tmceasting, tmcnorthing;
199 toTM(lat, xlon, 0.,
clon, &tmeasting, &tmnorthing);
201 northing = tmnorthing - tmcnorthing;
202 easting = tmeasting - tmceasting;
205 case PROJECTION_POLYCONIC:
209 double pceasting, pcnorthing;
212 double peasting, pnorthing;
213 toPOLY(lat, xlon, 0.,
clon, &peasting, &pnorthing);
216 northing = pnorthing - pcnorthing;
219 case PROJECTION_ORTHOGRAPHIC:
220 toORTHO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
223 case PROJECTION_POLAR:
224 toPOLAR(lat, xlon, cache0,
clat,
clon, &easting, &northing);
227 case PROJECTION_STEREOGRAPHIC:
228 toSTEREO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
231 case PROJECTION_GNOMONIC:
232 toGNO(lat, xlon, cache0, cache1,
clon, &easting, &northing);
235 case PROJECTION_EQUIRECTANGULAR:
236 toEQUIRECT(lat, xlon,
clat,
clon, &easting, &northing);
240 printf(
"unhandled projection\n");
243 if (!wxFinite(easting) || !wxFinite(northing))
244 return wxPoint2DDouble(easting, northing);
255 dxr = epix * cos(angle) + npix * sin(angle);
256 dyr = npix * cos(angle) - epix * sin(angle);
267 return wxPoint2DDouble(x, y);
284 xpr = (dx * cos(angle)) - (dy * sin(angle));
285 ypr = (dy * cos(angle)) + (dx * sin(angle));
290 double slat = 0.0, slon = 0.0;
291 switch (m_projection_type) {
292 case PROJECTION_MERCATOR:
293 case PROJECTION_WEB_MERCATOR:
297 fromSM(d_east, d_north,
clat,
clon, &slat, &slon);
300 case PROJECTION_TRANSVERSE_MERCATOR: {
301 double tmceasting, tmcnorthing;
304 fromTM(d_east, d_north + tmcnorthing, 0.,
clon, &slat, &slon);
307 case PROJECTION_POLYCONIC: {
308 double polyeasting, polynorthing;
309 toPOLY(
clat,
clon, 0.,
clon, &polyeasting, &polynorthing);
311 fromPOLY(d_east, d_north + polynorthing, 0.,
clon, &slat, &slon);
314 case PROJECTION_ORTHOGRAPHIC:
315 fromORTHO(d_east, d_north,
clat,
clon, &slat, &slon);
318 case PROJECTION_POLAR:
319 fromPOLAR(d_east, d_north,
clat,
clon, &slat, &slon);
322 case PROJECTION_STEREOGRAPHIC:
323 fromSTEREO(d_east, d_north,
clat,
clon, &slat, &slon);
326 case PROJECTION_GNOMONIC:
327 fromGNO(d_east, d_north,
clat,
clon, &slat, &slon);
330 case PROJECTION_EQUIRECTANGULAR:
331 fromEQUIRECT(d_east, d_north,
clat,
clon, &slat, &slon);
335 printf(
"unhandled projection\n");
342 else if (slon > 180.)
424 const LLRegion &llregion,
425 int chart_native_scale) {
429 std::list<ContourRegion> cregions;
430 for (std::list<poly_contour>::const_iterator i = llregion.contours.begin();
431 i != llregion.contours.end(); i++) {
432 float *contour_points =
new float[2 * i->size()];
434 std::list<contour_pt>::const_iterator j;
435 for (j = i->begin(); j != i->end(); j++) {
436 contour_points[idx++] = j->y;
437 contour_points[idx++] = j->x;
440 double total = 0, maxlat = -90;
442 double x0 = contour_points[0] - contour_points[pl + 0];
443 double y0 = contour_points[1] - contour_points[pl + 1];
445 for (
int p = 0; p < idx; p += 2) {
446 maxlat = wxMax(maxlat, contour_points[p]);
447 int pn = p < idx - 2 ? p + 2 : 0;
448 double x1 = contour_points[pn + 0] - contour_points[p + 0];
449 double y1 = contour_points[pn + 1] - contour_points[p + 1];
450 total += x1 * y0 - x0 * y1;
456 s.subtract = total < 0;
458 chart_native_scale, NULL);
459 delete[] contour_points;
461 std::list<ContourRegion>::iterator k = cregions.begin();
462 while (k != cregions.end()) {
463 if (k->maxlat < s.maxlat)
break;
466 cregions.insert(k, s);
470 for (std::list<ContourRegion>::iterator k = cregions.begin();
471 k != cregions.end(); k++) {
486 int chart_native_scale,
498 float *pfp = llpoints;
499 float lon_max = -10000.;
500 float lon_min = 10000.;
501 float lat_max = -10000.;
502 float lat_min = 10000.;
504 for (
int ip = 0; ip < nPoints; ip++) {
505 lon_max = wxMax(lon_max, pfp[1]);
506 lon_min = wxMin(lon_min, pfp[1]);
507 lat_max = wxMax(lat_max, pfp[0]);
508 lat_min = wxMin(lat_min, pfp[0]);
514 chart_box.Set(lat_min, lon_min, lat_max, lon_max);
518 if (chart_box.IntersectOut(vpBBox))
return OCPNRegion();
528 if (chart_box.IntersectIn(vpBBox))
return Region;
544 pp =
new wxPoint[nPoints];
548 float *pfp = llpoints;
551 int poly_x_max = INVALID_COORD, poly_y_max = INVALID_COORD,
552 poly_x_min = INVALID_COORD, poly_y_min = INVALID_COORD;
556 for (
int ip = 0; ip < nPoints; ip++) {
558 if (p.x == INVALID_COORD)
continue;
563 poly_x_max = wxMax(poly_x_max, p.x);
564 poly_y_max = wxMax(poly_y_max, p.y);
565 poly_x_min = wxMin(poly_x_min, p.x);
566 poly_y_min = wxMin(poly_y_min, p.y);
578 if (ppoints == NULL)
delete[] pp;
585 float_2Dpt p0, p1, p2, p3;
590 bool b_intersect =
false;
592 while (screen_region_it1.HaveRects()) {
593 wxRect rect = screen_region_it1.GetRect();
602 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y), &lat, &lon);
606 GetLLFromPix(wxPoint(rect.x + rect.width, rect.y + rect.height), &lat,
611 GetLLFromPix(wxPoint(rect.x, rect.y + rect.height), &lat, &lon);
615 for (
int i = 0; i < npPoints - 1; i++) {
618 int y1 = pp[i + 1].y;
620 if (((y0 < rect.y) && (y1 < rect.y)) ||
621 ((y0 > rect.y + rect.height) && (y1 > rect.y + rect.height)))
626 f0.y = llpoints[i * 2];
627 f0.x = llpoints[(i * 2) + 1];
629 f1.y = llpoints[(i + 1) * 2];
630 f1.x = llpoints[((i + 1) * 2) + 1];
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 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
645 if (b_intersect)
break;
646 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
647 if (b_intersect)
break;
648 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
649 if (b_intersect)
break;
650 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
651 if (b_intersect)
break;
657 f0.y = llpoints[(nPoints - 1) * 2];
658 f0.x = llpoints[((nPoints - 1) * 2) + 1];
662 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
663 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
664 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
665 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
669 b_intersect |= Intersect_FL(p0, p1, f0, f1) != 0;
670 b_intersect |= Intersect_FL(p1, p2, f0, f1) != 0;
671 b_intersect |= Intersect_FL(p2, p3, f0, f1) != 0;
672 b_intersect |= Intersect_FL(p3, p0, f0, f1) != 0;
675 screen_region_it1.NextRect();
681 bool b_contained =
false;
684 while (screen_region_it2.HaveRects()) {
685 wxRect rect = screen_region_it2.GetRect();
687 for (
int i = 0; i < npPoints - 1; i++) {
691 if ((x0 < rect.x) || (x0 > rect.x + rect.width) || (y0 < rect.y) ||
692 (y0 > rect.y + rect.height))
698 screen_region_it2.NextRect();
704 if (!b_contained && !b_intersect) {
706 wxRect rpoly(poly_x_min, poly_y_min, poly_x_max - poly_x_min,
707 poly_y_max - poly_y_min);
708 wxRect rRegion = Region.GetBox();
709 if (rpoly.Contains(rRegion)) {
719 float rlat = (p0.y + p2.y) / 2.;
720 float rlon = (p0.x + p1.x) / 2.;
722 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
723 if (NULL == ppoints)
delete[] pp;
727 if (G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
728 if (NULL == ppoints)
delete[] pp;
734 if (NULL == ppoints)
delete[] pp;
745 if (NULL == ppoints)
delete[] pp;
749 }
else if (b_contained && !b_intersect) {
753 if (NULL == ppoints)
delete[] pp;
760 sigaction(SIGSEGV, NULL,
763 struct sigaction temp;
764 sigaction(SIGSEGV, NULL, &temp);
766 temp.sa_handler = catch_signals;
767 sigemptyset(&temp.sa_mask);
772 sigaction(SIGSEGV, &temp, NULL);
774 if (sigsetjmp(env, 1))
776 sigaction(SIGSEGV, &sa_all_old, NULL);
784 if (NULL == ppoints)
delete[] pp;
786 sigaction(SIGSEGV, &sa_all_old, NULL);
794 if (NULL == ppoints)
delete[] pp;
843 int dy = wxRound(fabs(lpixh * cos(rotator)) + fabs(lpixw * sin(rotator)));
844 int dx = wxRound(fabs(lpixw * cos(rotator)) + fabs(lpixh * sin(rotator)));
848 if (dy % 4) dy += 4 - (dy % 4);
849 if (dx % 4) dx += 4 - (dx % 4);
851 int inflate_x = wxMax((dx -
pix_width) / 2, 0);
852 int inflate_y = wxMax((dy -
pix_height) / 2, 0);
855 rv_rect.Inflate(inflate_x, inflate_y);
863 SetRotationAngle(0.0);
865 wxPoint ul(rv_rect.x, rv_rect.y);
866 wxPoint lr(rv_rect.x + rv_rect.width,
867 rv_rect.y + rv_rect.height);
868 double dlat_min, dlat_max, dlon_min, dlon_max;
870 bool hourglass =
false;
871 switch (m_projection_type) {
872 case PROJECTION_TRANSVERSE_MERCATOR:
873 case PROJECTION_STEREOGRAPHIC:
874 case PROJECTION_GNOMONIC:
877 case PROJECTION_POLYCONIC:
878 case PROJECTION_POLAR:
879 case PROJECTION_ORTHOGRAPHIC: {
883 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
884 wxPoint ur(rv_rect.x + rv_rect.width, rv_rect.y);
890 if (fabs(fabs(d -
clon) - 180) < 1) {
894 }
else if (std::isnan(dlat_max))
899 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
902 dlat_min = wxMin(dlat_min, dlat_min2);
905 if (std::isnan(dlat_min))
906 dlat_min =
clat - 90;
908 wxPoint l(rv_rect.x + rv_rect.width / 2, rv_rect.y + rv_rect.height);
909 wxPoint ll(rv_rect.x, rv_rect.y + rv_rect.height);
915 if (fabs(fabs(d -
clon) - 180) < 1) {
919 }
else if (std::isnan(dlat_min))
924 wxPoint u(rv_rect.x + rv_rect.width / 2, rv_rect.y);
927 dlat_max = wxMax(dlat_max, dlat_max2);
930 if (std::isnan(dlat_max))
931 dlat_max =
clat + 90;
934 if (std::isnan(dlon_min)) {
937 if (dlat_max < 90 && dlat_min > -90) {
958 else if (
clon > dlon_max)
962 vpBBox.Set(dlat_min, dlon_min, dlat_max, dlon_max);
965 SetRotationAngle(rotation_save);