bool TileProjection::GeoToPixel(const GeoCoord& coord, double& x, double& y) const { assert(valid); x=coord.GetLon()*scaleGradtorad-lonOffset; y=height-(scale*atanh(sin(coord.GetLat()*gradtorad))-latOffset); return true; }
void SortWayDataGenerator::GetTopLeftCoordinate(const Way& data, GeoCoord& coord) { coord=data.nodes[0]; for (size_t n=1; n<data.nodes.size(); n++) { coord.Set(std::max(coord.GetLat(),data.nodes[n].GetLat()), std::min(coord.GetLon(),data.nodes[n].GetLon())); } }
double GeoCoord::CalcAzimuthTo(GeoCoord& oCoordTarget) { double fResult = 0.0; double fLat1 = _latitude; double fLon1 = _longitude; double fLat2 = oCoordTarget.GetLatitude(); double fLon2 = oCoordTarget.GetLongitude(); int ilat1 = (int)(0.50 + fLat1 * 360000.0); int ilat2 = (int)(0.50 + fLat2 * 360000.0); int ilon1 = (int)(0.50 + fLon1 * 360000.0); int ilon2 = (int)(0.50 + fLon2 * 360000.0); fLon1 = DEG2RAD(fLon1); fLon2 = DEG2RAD(fLon2); fLat1 = DEG2RAD(fLat1); fLat2 = DEG2RAD(fLat2); if ((ilat1 == ilat2) && (ilon1 == ilon2)) { return fResult; } else if (ilon1 == ilon2) { if (ilat1 > ilat2) fResult = AGEPI; } else { double c = acos(sin(fLat2)*sin(fLat1) + cos(fLat2)*cos(fLat1)*cos((fLon2-fLon1))); fResult = asin(cos(fLat2)*sin((fLon2-fLon1))/sin(c)); if ((ilat2 > ilat1) && (ilon2 > ilon1)) { } else if ((ilat2 < ilat1) && (ilon2 < ilon1)) { // fResult = AGEPI - fResult; fResult = atan(cos((fLat1-fLat2)/2.0f)/sin((fLat1+fLat2)/2.0f)/tan((fLon2-fLon1)/2.0f)) + atan(sin((fLat1-fLat2)/2.0f)/cos((fLat1+fLat2)/2.0f)/tan((fLon2-fLon1)/2.0f)); } else if ((ilat2 < ilat1) && (ilon2 > ilon1)) { if (abs(fLon2 - fLon1) < AGEPI/2.0f) fResult = AGEPI - fResult; else int nBreak = 0; } else if ((ilat2 > ilat1) && (ilon2 < ilon1)) { fResult += 2*AGEPI; } } return fResult; }
bool Area::Ring::GetCenter(GeoCoord& center) const { double minLat=0.0; double minLon=0.0; double maxLat=0.0; double maxLon=0.0; bool start=true; for (size_t j=0; j<nodes.size(); j++) { if (start) { minLat=nodes[j].GetLat(); minLon=nodes[j].GetLon(); maxLat=nodes[j].GetLat(); maxLon=nodes[j].GetLon(); start=false; } else { minLat=std::min(minLat,nodes[j].GetLat()); minLon=std::min(minLon,nodes[j].GetLon()); maxLat=std::max(maxLat,nodes[j].GetLat()); maxLon=std::max(maxLon,nodes[j].GetLon()); } } if (start) { return false; } center.Set(minLat+(maxLat-minLat)/2, minLon+(maxLon-minLon)/2); return true; }
void Passive_Motion(int x, int y) { Vec glpos; GeoCoord geopos; char titlestr[40]; if (!GVRec) return; GeoCoord *orig = GVRec->Get_Origin(); GL_MousetoGL(x, y, &glpos); geopos.Meters_Geo(orig, &glpos); sprintf(titlestr, "lat %.8f lon %.8f\n", geopos.lat, geopos.lon); glutSetWindowTitle(titlestr); menu_mouse_save_x = x; menu_mouse_save_y = y; }
void menu_process(int option) { Vec glpos; GeoCoord geopos; switch (option) { case ADD_FLAG: printf("%d %d\n", mouse_x, mouse_y); if (!GVRec) break; Display_Func(); GL_MousetoGL(menu_mouse_save_x, menu_mouse_save_y, &glpos); geopos.Meters_Geo(GVRec->Get_Origin(), &glpos); Add_Flag(glpos.x, glpos.y, geopos.lat, geopos.lon); printf("ADD FLAG %f %f %f %f\n", glpos.x, glpos.y, geopos.lat, geopos.lon); break; } }
bool MercatorProjection::GeoToPixel(const GeoCoord& coord, double& x, double& y) const { assert(valid); // Screen coordinate relative to center of image x=(coord.GetLon()-this->lon)*scaleGradtorad; y=(atanh(sin(coord.GetLat()*gradtorad))-latOffset)*scale; if (angle!=0.0) { double xn=x*angleNegCos-y*angleNegSin; double yn=x*angleNegSin+y*angleNegCos; x=xn; y=yn; } // Transform to canvas coordinate y=height/2-y; x+=width/2; return true; }
bool Area::GetCenter(GeoCoord& center) const { assert(!rings.empty()); double minLat=0.0; double minLon=0.0; double maxLat=0.0; double maxLon=0.0; bool start=true; for (const auto& ring : rings) { if (ring.ring==Area::outerRingId) { for (size_t j=0; j<ring.nodes.size(); j++) { if (start) { minLat=ring.nodes[j].GetLat(); maxLat=minLat; minLon=ring.nodes[j].GetLon(); maxLon=minLon; start=false; } else { minLat=std::min(minLat,ring.nodes[j].GetLat()); minLon=std::min(minLon,ring.nodes[j].GetLon()); maxLat=std::max(maxLat,ring.nodes[j].GetLat()); maxLon=std::max(maxLon,ring.nodes[j].GetLon()); } } } } assert(!start); if (start) { return false; } center.Set(minLat+(maxLat-minLat)/2, minLon+(maxLon-minLon)/2); return true; }
bool Way::GetCenter(GeoCoord& center) const { if (nodes.empty()) { return false; } double minLat=nodes[0].GetLat(); double minLon=nodes[0].GetLon(); double maxLat=nodes[0].GetLat(); double maxLon=nodes[0].GetLon(); for (size_t i=1; i<nodes.size(); i++) { minLat=std::min(minLat,nodes[i].GetLat()); minLon=std::min(minLon,nodes[i].GetLon()); maxLat=std::max(maxLat,nodes[i].GetLat()); maxLon=std::max(maxLon,nodes[i].GetLon()); } center.Set(minLat+(maxLat-minLat)/2, minLon+(maxLon-minLon)/2); return true; }
double GeoCoord::GetDistance(GeoCoord target) { return GetEllipsoidalDistance(GetLon(), GetLat(), target.GetLon(), target.GetLat()); }
bool GeoCoord::Parse(const std::string& text, GeoCoord& coord) { size_t currentPos=0; double latitude=0; bool latPos=true; bool latDirectionGiven=false; double longitude=0; bool lonPos=true; bool lonDirectionGiven=false; currentPos=EatWhitespace(text, currentPos); if (currentPos>=text.length()) { return false; } // // Latitude // if (text[currentPos]=='N') { latPos=true; latDirectionGiven=true; currentPos++; } else if (text[currentPos]=='S') { latPos=false; latDirectionGiven=true; currentPos++; } else if (text[currentPos]=='+') { latPos=true; latDirectionGiven=true; currentPos++; } else if (text[currentPos]=='-') { latPos=false; latDirectionGiven=true; currentPos++; } currentPos=EatWhitespace(text, currentPos); if (currentPos>=text.length()) { return false; } if (!ScanCoordinate(text, currentPos, latitude, 2)) { return false; } currentPos=EatWhitespace(text, currentPos); if (currentPos>=text.length()) { return false; } if (text[currentPos]=='N') { if (latDirectionGiven) { return false; } latPos=true; latDirectionGiven=true; currentPos++; } else if (text[currentPos]=='S') { if (latDirectionGiven) { return false; } latPos=false; latDirectionGiven=true; currentPos++; } currentPos=EatWhitespace(text, currentPos); if (currentPos>=text.length()) { return false; } if (!latPos) { latitude=-latitude; } // // Longitude // if (text[currentPos]=='E') { lonPos=true; lonDirectionGiven=true; currentPos++; } else if (text[currentPos]=='W') { lonPos=false; lonDirectionGiven=true; currentPos++; } else if (text[currentPos]=='+') { lonPos=true; lonDirectionGiven=true; currentPos++; } else if (text[currentPos]=='-') { lonPos=false; lonDirectionGiven=true; currentPos++; } currentPos=EatWhitespace(text, currentPos); if (currentPos>=text.length()) { return false; } if (!ScanCoordinate(text, currentPos, longitude, 3)) { return false; } currentPos=EatWhitespace(text, currentPos); if (currentPos<text.length()) { if (text[currentPos]=='E') { if (lonDirectionGiven) { return false; } lonPos=true; lonDirectionGiven=true; currentPos++; } else if (text[currentPos]=='W') { if (lonDirectionGiven) { return false; } lonPos=false; lonDirectionGiven=true; currentPos++; } } if (!lonPos) { longitude=-longitude; } currentPos=EatWhitespace(text, currentPos); if (currentPos>=text.length()) { coord.Set(latitude, longitude); return true; } else { return false; } }
double GeoCoord::CalcEllipsoidDistanceTo(GeoCoord& oCoordTarget) { double fLat1 = _latitude; double fLon1 = _longitude; double fLat2 = oCoordTarget.GetLatitude(); double fLon2 = oCoordTarget.GetLongitude(); double fDistance = 0.0; double fFaz; double fBaz; double fR = 1.0 - 1.000000/WGS84_F_INV; double tu1, tu2, cu1, su1, cu2, x, sx, cx, sy, cy, y, sa, c2a, cz, e, c, d; double fCosy1; double fCosy2; fDistance = 0.0; if((fLon1 == fLon2) && (fLat1 == fLat2)) return fDistance; fLon1 = DEG2RAD(fLon1); fLon2 = DEG2RAD(fLon2); fLat1 = DEG2RAD(fLat1); fLat2 = DEG2RAD(fLat2); fCosy1 = cos(fLat1); fCosy2 = cos(fLat2); if(fCosy1 == 0.0) fCosy1 = 0.0000000001; if(fCosy2 == 0.0) fCosy2 = 0.0000000001; tu1 = fR * sin(fLat1) / fCosy1; tu2 = fR * sin(fLat2) / fCosy2; cu1 = 1.0 / sqrt(tu1 * tu1 + 1.0); su1 = cu1 * tu1; cu2 = 1.0 / sqrt(tu2 * tu2 + 1.0); x = fLon2 - fLon1; fDistance = cu1 * cu2; fBaz = fDistance * tu2; fFaz = fBaz * tu1; do { sx = sin(x); cx = cos(x); tu1 = cu2 * sx; tu2 = fBaz - su1 * cu2 * cx; sy = sqrt(tu1 * tu1 + tu2 * tu2); cy = fDistance * cx + fFaz; y = atan2(sy, cy); sa = fDistance * sx / sy; c2a = -sa * sa + 1.0; cz = fFaz + fFaz; if(c2a > 0.0) cz = -cz / c2a + cy; e = cz * cz * 2. - 1.0; c = ((-3.0 * c2a + 4.0) * 1.000000/WGS84_F_INV + 4.0) * c2a * 1.000000/WGS84_F_INV / 16.0; d = x; x = ((e * cy * c + cz) * sy * c + y) * sa; x = (1.0 - c) * x * 1.000000/WGS84_F_INV + fLon2 - fLon1; } while(fabs(d - x) > 0.000000000005); x = sqrt((1.0 / fR / fR - 1.0) * c2a + 1.0) + 1.0; x = (x - 2.0) / x; c = 1.0 - x; c = (x * x / 4.0 + 1.0) / c; d = (0.375 * x * x - 1.0) * x; x = e * cy; fDistance = 1.0 - e - e; fDistance = ((((sy * sy * 4.0 - 3.0) * fDistance * cz * d / 6.0 - x) * d / 4.0 + cz) * sy * d + y) * c * 1.0/*GEO::ERAD*/ * fR; return fDistance; }
void ElevationTile::_PrecomputeTriangulation() { // Precompute Triangulation GeoCoord oGeoCoord; GeoCoord oGeoCoordNorm; double lng, lat; double x,y,z; boost::shared_ptr<math::DelaunayTriangulation> qTriangulation; qTriangulation = CreateTriangulation(); std::vector<ElevationPoint> lstElevationPoint; _lstIndices.clear(); _lstTexCoord.clear(); _lstElevationPointWGS84.clear(); qTriangulation->GetPointVec(lstElevationPoint); qTriangulation->GetTriangleIndices(_lstIndices); double TexCoordOffsetX = _ptsCorner[0].x; double TexCoordOffsetY = _ptsCorner[0].y; double TexCoordDX = fabs(_ptsCorner[1].x - _ptsCorner[0].x); double TexCoordDY = fabs(_ptsCorner[3].y - _ptsCorner[0].y); // Virtual Camera Offset (STORE) //********************************************************** // Calc virtual camera offset: //********************************************************** _vOffset.x = _ptsCorner[0].x + TexCoordDX/2.0; _vOffset.y = _ptsCorner[0].y + TexCoordDY/2.0; _vOffset.z = _ptsCorner[0].elevation; GeoRef::Mercator::ReverseCustom(_vOffset.x, _vOffset.y, lng, lat, 0.0); oGeoCoord.SetLatitude(lat); oGeoCoord.SetLongitude(lng); oGeoCoord.SetEllipsoidHeight(_vOffset.z); oGeoCoord.ToCartesian(&_vOffset.x,&_vOffset.y,&_vOffset.z); //********************************************************** std::vector<ElevationPoint>::iterator it = lstElevationPoint.begin(); while (it!=lstElevationPoint.end()) { GeoRef::Mercator::ReverseCustom((*it).x, (*it).y, lng, lat, 0.0); oGeoCoord.SetLatitude(lat); oGeoCoord.SetLongitude(lng); oGeoCoord.SetEllipsoidHeight((*it).elevation); oGeoCoord.ToCartesian(&x,&y,&z); double u = ((*it).x - TexCoordOffsetX) / TexCoordDX; double v = ((*it).y - TexCoordOffsetY) / TexCoordDY; _lstTexCoord.push_back(vec2<float>((float)u,(float)v)); _lstElevationPointWGS84.push_back(vec3<float>( (float) (x-_vOffset.x), (float) (y-_vOffset.y), (float) (z-_vOffset.z))); it++; //i++; } }