wxPoint2DDouble ViewPort::GetDoublePixFromLL( double lat, double lon ) { double easting = 0; double northing = 0; double xlon = lon; /* Make sure lon and lon0 are same phase */ if( xlon * clon < 0. ) { if( xlon < 0. ) xlon += 360.; else xlon -= 360.; } if( fabs( xlon - clon ) > 180. ) { if( xlon > clon ) xlon -= 360.; else xlon += 360.; } // update cache of trig functions used for projections if(clat != lat0_cache) { lat0_cache = clat; switch( m_projection_type ) { case PROJECTION_MERCATOR: cache0 = toSMcache_y30(clat); break; case PROJECTION_POLAR: cache0 = toPOLARcache_e(clat); break; case PROJECTION_ORTHOGRAPHIC: case PROJECTION_STEREOGRAPHIC: case PROJECTION_GNOMONIC: cache_phi0(clat, &cache0, &cache1); break; } } switch( m_projection_type ) { case PROJECTION_MERCATOR: #if 0 toSM( lat, xlon, clat, clon, &easting, &northing ); #else toSMcache( lat, xlon, cache0, clon, &easting, &northing ); #endif break; case PROJECTION_TRANSVERSE_MERCATOR: // We calculate northings as referenced to the equator // And eastings as though the projection point is midscreen. double tmeasting, tmnorthing; double tmceasting, tmcnorthing; toTM( clat, clon, 0., clon, &tmceasting, &tmcnorthing ); toTM( lat, xlon, 0., clon, &tmeasting, &tmnorthing ); northing = tmnorthing - tmcnorthing; easting = tmeasting - tmceasting; break; case PROJECTION_POLYCONIC: // We calculate northings as referenced to the equator // And eastings as though the projection point is midscreen. double pceasting, pcnorthing; toPOLY( clat, clon, 0., clon, &pceasting, &pcnorthing ); double peasting, pnorthing; toPOLY( lat, xlon, 0., clon, &peasting, &pnorthing ); easting = peasting; northing = pnorthing - pcnorthing; break; case PROJECTION_ORTHOGRAPHIC: toORTHO( lat, xlon, cache0, cache1, clon, &easting, &northing ); break; case PROJECTION_POLAR: toPOLAR( lat, xlon, cache0, clat, clon, &easting, &northing ); break; case PROJECTION_STEREOGRAPHIC: toSTEREO( lat, xlon, cache0, cache1, clon, &easting, &northing ); break; case PROJECTION_GNOMONIC: toGNO( lat, xlon, cache0, cache1, clon, &easting, &northing ); break; case PROJECTION_EQUIRECTANGULAR: toEQUIRECT( lat, xlon, clat, clon, &easting, &northing ); break; default: printf("unhandled projection\n"); } if( !wxFinite(easting) || !wxFinite(northing) ) return wxPoint2DDouble( easting, northing ); double epix = easting * view_scale_ppm; double npix = northing * view_scale_ppm; double dxr = epix; double dyr = npix; // Apply VP Rotation double angle = rotation; if( angle ) { dxr = epix * cos( angle ) + npix * sin( angle ); dyr = npix * cos( angle ) - epix * sin( angle ); } return wxPoint2DDouble(( pix_width / 2.0 ) + dxr, ( pix_height / 2.0 ) - dyr); }
// TODO: eliminate the use of this function wxPoint ViewPort::GetPixFromLL( double lat, double lon ) { wxPoint2DDouble p = GetDoublePixFromLL(lat, lon); if(wxFinite(p.m_x) && wxFinite(p.m_y)) return wxPoint(wxRound(p.m_x), wxRound(p.m_y)); return wxPoint(INVALID_COORD, INVALID_COORD); }
wxPoint2DDouble ViewPort::GetDoublePixFromLL( double lat, double lon ) { double easting, northing; double xlon = lon; /* Make sure lon and lon0 are same phase */ if( xlon * clon < 0. ) { if( xlon < 0. ) xlon += 360.; else xlon -= 360.; } if( fabs( xlon - clon ) > 180. ) { if( xlon > clon ) xlon -= 360.; else xlon += 360.; } if( PROJECTION_TRANSVERSE_MERCATOR == m_projection_type ) { // We calculate northings as referenced to the equator // And eastings as though the projection point is midscreen. double tmeasting, tmnorthing; double tmceasting, tmcnorthing; toTM( clat, clon, 0., clon, &tmceasting, &tmcnorthing ); toTM( lat, xlon, 0., clon, &tmeasting, &tmnorthing ); northing = tmnorthing - tmcnorthing; easting = tmeasting - tmceasting; } else if( PROJECTION_POLYCONIC == m_projection_type ) { // We calculate northings as referenced to the equator // And eastings as though the projection point is midscreen. double pceasting, pcnorthing; toPOLY( clat, clon, 0., clon, &pceasting, &pcnorthing ); double peasting, pnorthing; toPOLY( lat, xlon, 0., clon, &peasting, &pnorthing ); easting = peasting; northing = pnorthing - pcnorthing; } else { #if 0 toSM( lat, xlon, clat, clon, &easting, &northing ); #else if(clat != toSM_lat0_cache) { toSM_lat0_cache = clat; toSM_y30_cache = toSMcache_y30(clat); } toSMcache( lat, xlon, toSM_y30_cache, clon, &easting, &northing ); #endif } if( !wxFinite(easting) || !wxFinite(northing) ) return wxPoint( 0, 0 ); double epix = easting * view_scale_ppm; double npix = northing * view_scale_ppm; double dxr = epix; double dyr = npix; // Apply VP Rotation double angle = rotation; if(!g_bskew_comp) angle += skew; if( angle ) { dxr = epix * cos( angle ) + npix * sin( angle ); dyr = npix * cos( angle ) - epix * sin( angle ); } return wxPoint2DDouble(( pix_width / 2 ) + dxr, ( pix_height / 2 ) - dyr); }
int ClipLineToRect( double &x0, double &y0, double &x1, double &y1, const wxRect2DDouble &rect ) { if (!wxFinite(x0) || !wxFinite(y0) || !wxFinite(x1) || !wxFinite(y1)) return ClippedOut; wxOutCode out0 = wxPlotRect2DDoubleOutCode( x0, y0, rect ); wxOutCode out1 = wxPlotRect2DDoubleOutCode( x1, y1, rect ); if ((out0 & out1) != wxInside) return ClippedOut; // both outside on same side if ((out0 | out1) == wxInside) return ClippedNeither; // both inside int ret = ClippedNeither; if (x0 == x1) // vertical line { if (out0 & wxOutTop) {y0 = rect.GetTop(); ret |= ClippedFirstY;} else if (out0 & wxOutBottom) {y0 = rect.GetBottom(); ret |= ClippedFirstY;} if (out1 & wxOutTop) {y1 = rect.GetTop(); ret |= ClippedSecondY;} else if (out1 & wxOutBottom) {y1 = rect.GetBottom(); ret |= ClippedSecondY;} return ret; } if (y0 == y1) // horiz line { if (out0 & wxOutLeft) {x0 = rect.GetLeft(); ret |= ClippedFirstX;} else if (out0 & wxOutRight) {x0 = rect.GetRight(); ret |= ClippedFirstX;} if (out1 & wxOutLeft) {x1 = rect.GetLeft(); ret |= ClippedSecondX;} else if (out1 & wxOutRight) {x1 = rect.GetRight(); ret |= ClippedSecondX;} return ret; } double x = x0, y = y0; wxOutCode out = out0; int points_out = 2; bool out0_outside = true; if (out0 == wxInside) { out0_outside = false; points_out = 1; out = out1; } else if (out1 == wxInside) points_out = 1; for (int i=0; i<points_out; i++) { if (out & wxOutTop) { y = rect.GetTop(); x = x0 + (x1 - x0) * (y - y0) / (y1 - y0); out = wxPlotRect2DDoubleOutCode( x, y, rect ); } else if (out & wxOutBottom) { y = rect.GetBottom(); x = x0 + (x1 - x0) * (y - y0) / (y1 - y0); out = wxPlotRect2DDoubleOutCode( x, y, rect ); } // check left and right if (out & wxOutRight) { x = rect.GetRight(); y = y0 + (y1 - y0) * (x - x0) / (x1 - x0); out = wxPlotRect2DDoubleOutCode( x, y, rect ); } else if (out & wxOutLeft) { x = rect.GetLeft(); y = y0 + (y1 - y0) * (x - x0) / (x1 - x0); out = wxPlotRect2DDoubleOutCode( x, y, rect ); } // check top and bottom again if (out & wxOutTop) { y = rect.GetTop(); x = x0 + (x1 - x0) * (y - y0) / (y1 - y0); out = wxPlotRect2DDoubleOutCode( x, y, rect ); } else if (out & wxOutBottom) { y = rect.GetBottom(); x = x0 + (x1 - x0) * (y - y0) / (y1 - y0); out = wxPlotRect2DDoubleOutCode( x, y, rect ); } if (!wxFinite(x) || !wxFinite(y)) return ClippedOut; if ((i == 0) && out0_outside) { x0 = x; y0 = y; ret |= ClippedFirst; out = out1; } else { x1 = x; y1 = y; ret |= ClippedSecond; return ret; } } return ret; }