/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include "OdGeneralMaps.h" namespace OdGeneralMaps { void convertSphericalMercatorToWGS84(double dX, double dY, double& dLat, double& dLon) { dLon = (dX / EarthRadius / OdaPI) * 180; dLat = (dY / EarthRadius / OdaPI) * 180; dLat = 180 / OdaPI * (2 * atan(exp(dLat * OdaPI / 180)) - OdaPI / 2); } void convertWGS84ToSphericalMercator(double dLat, double dLon, double& dX, double& dY) { dX = dLon * EarthRadius * OdaPI / 180; dY = log(tan((90 + dLat) * OdaPI / 360)) / (OdaPI / 180); dY = dY * EarthRadius * OdaPI / 180; } double clip(double dValue, double minValue, double maxValue) { return odmin(odmax(dValue, minValue), maxValue); } OdUInt32 mapSize(OdUInt8 uLOD, OdUInt32 uTileSize) { return uTileSize << uLOD; } double groundResolution(double dLatitude, OdUInt8 uLOD, OdUInt32 uTileSize) { dLatitude = clip(dLatitude, MinLatitude, MaxLatitude); return cos(dLatitude * OdaPI / 180) * 2 * OdaPI * EarthRadius / mapSize(uLOD, uTileSize); } double mapScale(double dLatitude, OdUInt8 uLOD, int nScreenDpi, OdUInt32 uTileSize) { return groundResolution(dLatitude, uLOD, uTileSize) * nScreenDpi / 0.0254; } void convertLatLongToPixelXY(double dLatitude, double dLongitude, OdUInt8 uLOD, OdUInt32 uTileSize, OdUInt32& uPixelX, OdUInt32& uPixelY) { dLatitude = clip(dLatitude, MinLatitude, MaxLatitude); dLongitude = clip(dLongitude, MinLongitude, MaxLongitude); double dX = (dLongitude + 180) / 360; double dSinLatitude = sin(dLatitude * OdaPI / 180); double dY = 0.5 - log((1 + dSinLatitude) / (1 - dSinLatitude)) / (4 * OdaPI); unsigned int nMapSize = mapSize(uLOD, uTileSize); uPixelX = OdUInt32(clip(dX * nMapSize + 0.5, 0, nMapSize - 1)); uPixelY = OdUInt32(clip(dY * nMapSize + 0.5, 0, nMapSize - 1)); } void convertPixelXYToLatLong(OdUInt32 uPixelX, OdUInt32 uPixelY, OdUInt8 uLOD, OdUInt32 uTileSize, double& dLatitude, double& dLongitude) { double nMapSize = mapSize(uLOD, uTileSize); double dX = (clip(uPixelX, 0, nMapSize - 1) / nMapSize) - 0.5; double dY = 0.5 - (clip(uPixelY, 0, nMapSize - 1) / nMapSize); dLatitude = 90 - 360 * atan(exp(-dY * 2 * OdaPI)) / OdaPI; dLongitude = 360 * dX; } void convertTileXYToPixelXY(OdUInt32 uTileX, OdUInt32 uTileY, OdUInt32 uTileSize, OdUInt32& uPixelX, OdUInt32& uPixelY) { uPixelX = uTileX * uTileSize; uPixelY = uTileY * uTileSize; } void convertPixelXYToTileXY(OdUInt32 uPixelX, OdUInt32 uPixelY, OdUInt32 uTileSize, OdUInt32& uTileX, OdUInt32& uTileY) { uTileX = uPixelX / uTileSize; uTileY = uPixelY / uTileSize; } void convertTileXYToLatLong(OdUInt32 uTileX, OdUInt32 uTileY, OdUInt8 uLOD, OdUInt32 uTileSize, double& dLatitude, double& dLongitude) { OdUInt32 uPixelX, uPixelY; convertTileXYToPixelXY(uTileX, uTileY, uTileSize, uPixelX, uPixelY); convertPixelXYToLatLong(uPixelX, uPixelY, uLOD, uTileSize, dLatitude, dLongitude); } void convertLatLongToTileXY(double dLatitude, double dLongitude, OdUInt8 uLOD, OdUInt32 uTileSize, OdUInt32& uTileX, OdUInt32& uTileY) { OdUInt32 uPixelX, uPixelY; convertLatLongToPixelXY(dLatitude, dLongitude, uLOD, uTileSize, uPixelX, uPixelY); convertPixelXYToTileXY(uPixelX, uPixelY, uTileSize, uTileX, uTileY); } bool isTileValid(OdUInt8 uLOD, OdUInt32 uTileX, OdUInt32 uTileY) { OdUInt32 uTilesCountPerSide = 1 << uLOD; return uTileX < uTilesCountPerSide && uTileY < uTilesCountPerSide; } }