瓦片切图工具gdal2tiles.py改写为纯c++版本(二)

python这么火,C++/C#的程序员都生存不下去了,为啥还要干把python转写成c++的这种反动的事?

项目需要呗。。。

gdal2tiles.py文件中有两个类是计算全球墨卡托与WGS84两种瓦片的分块规则的类,分别是GlobalMercator与GlobalGeodetic,但和目前网络上的谷歌地图与天地图等地图的瓦片划分规则还是不一致的。
不一致的地方是:
gdal2tiles.py的瓦片y轴是从上到下递减的,
谷歌地图与天地图瓦片y轴是从上到下递增的,
y轴的方向不同,所以用c++改写的时候添加了后面编号加2的函数,和谷歌与天地图一致起来。两个h头文件与cpp文件如下:
//--以下为HuGlobalGeodetic.h----------------------------------

#ifndef HU_GLOBAL_GEO_H
#define HU_GLOBAL_GEO_H

#include "math.h"
#include <stdio.h>
#include <list>

#include <iostream>
using namespace std;

class CHuGlobalGeodetic
{

private:

public:
CHuGlobalGeodetic(void);
virtual ~CHuGlobalGeodetic(void);

////Defaults the resolution factor to 0.703125 (2 tiles @ level 0)
//// Adhers to OSGeo TMS spec http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic
// self.resFact = 180.0 / self.tileSize
// else:
//# Defaults the resolution factor to 1.40625 (1 tile @ level 0)
//# Adheres OpenLayers, MapProxy, etc default resolution for WMTS
// self.resFact = 360.0 / self.tileSize
double resFact;

void LonLatToPixels(double lon,double lat,int zoom,double* pxy);
// y轴从上到下递增的情况
void LonLatToPixels2(double lon,double lat,int zoom,double* pxy);
void PixelsToTile(double px,double py,int* txy);
void LonLatToTile(double lon,double lat,int zoom,int* txy);
// y轴从上到下递增的情况
void LonLatToTile2(double lon,double lat,int zoom,int* txy);
double Resolution(int zoom);
int ZoomForPixelSize(double pixelSize);
void TileBounds(int tx, int ty,int zoom, double* bound4);
// y轴从上到下递增的情况
void TileBounds2(int tx, int ty,int zoom, double* bound4);

};

#endif

//--以下为HuGlobalGeodetic.h的cpp文件-----------------------------------------------

#include "HuGlobalGeodetic.h" //

///构造函数
CHuGlobalGeodetic::CHuGlobalGeodetic(void)
{
resFact = 180.0 / 256.0;

}
///析构函数
CHuGlobalGeodetic::~CHuGlobalGeodetic(void)
{

}

//////////////////////////////////////////////////////////////////////////////////////////////////
//def LonLatToPixels(self, lon, lat, zoom):
//"Converts lon/lat to pixel coordinates in given zoom of the EPSG:4326 pyramid"
//
// res = self.resFact / 2**zoom
// px = (180 + lon) / res
// py = (90 + lat) / res
// return px, py
void CHuGlobalGeodetic::LonLatToPixels(double lon,double lat,int zoom,double* pxy)
{
double res = resFact / pow(2,(double)zoom);
pxy[0] = (180.0 + lon) / res;
pxy[1] = (90.0 + lat) / res;
}
// y轴从上到下递增的情况
void CHuGlobalGeodetic::LonLatToPixels2(double lon,double lat,int zoom,double* pxy)
{
double res = resFact / pow(2,(double)zoom);
pxy[0] = (180.0 + lon) / res;
pxy[1] = (90.0 - lat) / res;//注意该处是减号
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// def PixelsToTile(self, px, py):
//"Returns coordinates of the tile covering region in pixel coordinates"
//
// tx = int( math.ceil( px / float(self.tileSize) ) - 1 )
// ty = int( math.ceil( py / float(self.tileSize) ) - 1 )
// return tx, ty
void CHuGlobalGeodetic::PixelsToTile(double px,double py,int* txy)
{
txy[0] = int(ceil(px/256.0) - 1);
txy[1] = int(ceil(py/256.0) - 1);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// def LonLatToTile(self, lon, lat, zoom):
//"Returns the tile for zoom which covers given lon/lat coordinates"
//
// px, py = self.LonLatToPixels( lon, lat, zoom)
// return self.PixelsToTile(px,py)
void CHuGlobalGeodetic::LonLatToTile(double lon,double lat,int zoom,int* txy)
{
double pxy[2] = {0.0,0.0};
double res = resFact / pow(2,(double)zoom);
pxy[0] = (180.0 + lon) / res;
pxy[1] = (90.0 + lat) / res;

txy[0] = int(ceil(pxy[0]/256.0) - 1);
txy[1] = int(ceil(pxy[1]/256.0) - 1);
}
// y轴从上到下递增的情况
void CHuGlobalGeodetic::LonLatToTile2(double lon,double lat,int zoom,int* txy)
{
double pxy[2] = {0.0,0.0};
double res = resFact / pow(2,(double)zoom);
pxy[0] = (180.0 + lon) / res;
pxy[1] = (90.0 - lat) / res;//注意该处是减号

txy[0] = int(ceil(pxy[0]/256.0) - 1);
txy[1] = int(ceil(pxy[1]/256.0) - 1);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// def Resolution(self, zoom ):
//"Resolution (arc/pixel) for given zoom level (measured at Equator)"
//
// return self.resFact / 2**zoom
//#return 180 / float( 1 << (8+zoom) )
double CHuGlobalGeodetic::Resolution(int zoom)
{
return resFact / pow(2,(double)zoom);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// def ZoomForPixelSize(self, pixelSize ):
//"Maximal scaledown zoom of the pyramid closest to the pixelSize."
//
// for i in range(MAXZOOMLEVEL):
// if pixelSize > self.Resolution(i):
// if i!=0:
// return i-1
// else:
// return 0 # We don't want to scale up
int CHuGlobalGeodetic::ZoomForPixelSize(double pixelSize)
{
for (int i=0;i<32;i++)
{
if(pixelSize > Resolution(i))
{
if (i!=0)
{
return i-1;
}
else
{
return 0;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// def TileBounds(self, tx, ty, zoom):
//"Returns bounds of the given tile"
// res = self.resFact / 2**zoom
// return (
// tx*self.tileSize*res - 180,
// ty*self.tileSize*res - 90,
// (tx+1)*self.tileSize*res - 180,
// (ty+1)*self.tileSize*res - 90
// )
void CHuGlobalGeodetic::TileBounds(int tx, int ty,int zoom, double* bound4)
{
double res = resFact / pow(2,(double)zoom);
bound4[0] = tx * 256.0 * res - 180.0;
bound4[1] = ty * 256.0 * res - 90.0;
bound4[2] = (tx+1) * 256.0 * res - 180.0;
bound4[3] = (ty+1) * 256.0 * res - 90.0;
}
// y轴从上到下递增的情况
void CHuGlobalGeodetic::TileBounds2(int tx, int ty,int zoom, double* bound4)
{
double res = resFact / pow(2,(double)zoom);
bound4[0] = tx * 256.0 * res - 180.0;
bound4[1] = 90.0 - ty * 256.0 * res;//
bound4[2] = (tx+1) * 256.0 * res - 180.0;
bound4[3] = 90.0 - (ty+1) * 256.0 * res;//
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// def TileLatLonBounds(self, tx, ty, zoom):
//"Returns bounds of the given tile in the SWNE form"
// b = self.TileBounds(tx, ty, zoom)
// return (b[1],b[0],b[3],b[2])

//--以下为---------------------------------------------

#ifndef HU_GLOBAL_MER_H
#define HU_GLOBAL_MER_H

#include "math.h"
#include <stdio.h>
#include <list>

#include <iostream>
using namespace std;

class CHuGlobalMercator
{

//typedef double value_typedef; //

private:

//-----------------------------------------------------------------------------------//
double m_pi;
int m_tileSize;
double m_initialResolution;
double m_originShift;

// 火星坐标与wgs84坐标互转
double x_PI;// = 3.14159265358979324 * 3000.0 / 180.0;
double PI;// = 3.1415926535897932384626;
double a;// = 6378245.0;
double ee;// = 0.00669342162296594323;

//-----------------------------------------------------------------------------------//
public:
CHuGlobalMercator(void);
virtual ~CHuGlobalMercator(void);

////////////////////////////////////////////////////////////////////////////////////////////////////
// 功能:
void LatLonToMeters(double lon,double lat,double* mxy);
void MetersToLatLon(double mx, double my, double* LatLon);
void PixelsToMeters(double px, double py, int zoom, double* mxy);
void MetersToPixels(double mx, double my, int zoom, double* pxy);
void PixelsToTile(double px, double py, int* txy);
void MetersToTile(double mx, double my, int zoom, int* txy);
void MetersToTile2(double mx, double my, int zoom, int* txy);
void TileBounds(int tx, int ty,int zoom, double* bound4);
void TileBounds2(int tx, int ty,int zoom, double* bound4);
void TileLatLonBounds(int tx, int ty,int zoom, double* LatLonbound4);
double Resolution(int zoom);
int ZoomForPixelSize(double pixelSize);
void GoogleTile(int tx, int ty,int zoom, int* txy);

// 火星坐标与wgs84坐标互转
void wgs84togcj02(double lng, double lat, double* mglnglat);
void gcj02towgs84(double mglng, double mglat, double* lnglat);

private:

// 火星坐标与wgs84坐标互转
double transformlat(double lng, double lat);
double transformlng(double lng, double lat);
bool out_of_china(double lng, double lat);

};

#endif

//-以下为墨卡托---------------------------------------------

#include "HuGlobalMercator.h" //

///构造函数
CHuGlobalMercator::CHuGlobalMercator(void)
{
//"Initialize the TMS Global Mercator pyramid"
// self.tileSize = tileSize
// self.initialResolution = 2 * math.pi * 6378137 / self.tileSize
// # 156543.03392804062 for tileSize 256 pixels
// self.originShift = 2 * math.pi * 6378137 / 2.0
// # 20037508.342789244
m_pi = 3.141592653589793;
m_tileSize = 256;
m_initialResolution = 2 * m_pi * 6378137 / m_tileSize;
m_originShift = 2 * m_pi * 6378137 / 2.0;

// 火星坐标与wgs84坐标互转
x_PI = 3.14159265358979324 * 3000.0 / 180.0;
PI = 3.1415926535897932384626;
a = 6378245.0;
ee = 0.00669342162296594323;
}
///析构函数
CHuGlobalMercator::~CHuGlobalMercator(void)
{

}
///////////////////////////////////////////////////////////////////////////////////////////
//def LatLonToMeters(self, lat, lon ):
//"Converts given lat/lon in WGS84 Datum to XY in Spherical Mercator EPSG:3857"
//
// mx = lon * self.originShift / 180.0
// my = math.log( math.tan((90 + lat) * math.pi / 360.0 )) / (math.pi / 180.0)
//
// my = my * self.originShift / 180.0
// return mx, my
void CHuGlobalMercator::LatLonToMeters(double lon, double lat,double* mxy)
{
mxy[0] = lon * m_originShift / 180.0;
mxy[1] = log( tan((90 + lat) * m_pi / 360.0 )) / (m_pi / 180.0);

mxy[1] = mxy[1] * m_originShift / 180.0;
}
/////////////////////////////////////////////////////////////////////////////////////////
// def MetersToLatLon(self, mx, my ):
//"Converts XY point from Spherical Mercator EPSG:3857 to lat/lon in WGS84 Datum"
//
// lon = (mx / self.originShift) * 180.0
// lat = (my / self.originShift) * 180.0
//
// lat = 180 / math.pi * (2 * math.atan( math.exp( lat * math.pi / 180.0)) - math.pi / 2.0)
// return lat, lon
void CHuGlobalMercator::MetersToLatLon(double mx, double my, double* LatLon)
{
LatLon[1] = (mx / m_originShift) * 180.0;
LatLon[0] = (my / m_originShift) * 180.0;

LatLon[0] = 180 / m_pi * (2 * atan( exp( LatLon[0] * m_pi / 180.0)) - m_pi / 2.0);
}
/////////////////////////////////////////////////////////////////////////////////////////
// def PixelsToMeters(self, px, py, zoom):
//"Converts pixel coordinates in given zoom level of pyramid to EPSG:3857"
//
// res = self.Resolution( zoom )
// mx = px * res - self.originShift
// my = py * res - self.originShift
// return mx, my
void CHuGlobalMercator::PixelsToMeters(double px, double py, int zoom, double* mxy)
{
double res = Resolution( zoom );
mxy[0] = px * res - m_originShift;
mxy[1] = py * res - m_originShift;
}
/////////////////////////////////////////////////////////////////////////////////////////
// def MetersToPixels(self, mx, my, zoom):
//"Converts EPSG:3857 to pyramid pixel coordinates in given zoom level"
//
// res = self.Resolution( zoom )
// px = (mx + self.originShift) / res
// py = (my + self.originShift) / res
// return px, py
void CHuGlobalMercator::MetersToPixels(double mx, double my, int zoom, double* pxy)
{
double res = Resolution( zoom );
pxy[0] = (mx + m_originShift) / res;
pxy[1] = (my + m_originShift) / res;
}
/////////////////////////////////////////////////////////////////////////////////////////
// def PixelsToTile(self, px, py):
//"Returns a tile covering region in given pixel coordinates"
//
// tx = int( math.ceil( px / float(self.tileSize) ) - 1 )
// ty = int( math.ceil( py / float(self.tileSize) ) - 1 )
// return tx, ty
void CHuGlobalMercator::PixelsToTile(double px, double py, int* txy)
{
txy[0] = int( ceil( px / float(m_tileSize) ) - 1 );
txy[1] = int( ceil( py / float(m_tileSize) ) - 1 );
}
/////////////////////////////////////////////////////////////////////////////////////////
// def PixelsToRaster(self, px, py, zoom):
//"Move the origin of pixel coordinates to top-left corner"
//
// mapSize = self.tileSize << zoom
// return px, mapSize - py
/////////////////////////////////////////////////////////////////////////////////////////
// def MetersToTile(self, mx, my, zoom):
//"Returns tile for given mercator coordinates"
//
// px, py = self.MetersToPixels( mx, my, zoom)
// return self.PixelsToTile( px, py)
void CHuGlobalMercator::MetersToTile(double mx, double my, int zoom, int* txy)
{
double res = Resolution( zoom );
double px = (mx + m_originShift) / res;
double py = (my + m_originShift) / res;

txy[0] = int( ceil( px / float(m_tileSize) ) - 1 );
txy[1] = int( ceil( py / float(m_tileSize) ) - 1 );
}
// y轴从上到下递增的情况
void CHuGlobalMercator::MetersToTile2(double mx, double my, int zoom, int* txy)
{
double res = Resolution( zoom );
double px = (mx + m_originShift) / res;
double py = (m_originShift - my) / res;//注意该处是减号

txy[0] = int( ceil( px / float(m_tileSize) ) - 1 );
txy[1] = int( ceil( py / float(m_tileSize) ) - 1 );
}
/////////////////////////////////////////////////////////////////////////////////////////
// def TileBounds(self, tx, ty, zoom):
//"Returns bounds of the given tile in EPSG:3857 coordinates"
//
// minx, miny = self.PixelsToMeters( tx*self.tileSize, ty*self.tileSize, zoom )
// maxx, maxy = self.PixelsToMeters( (tx+1)*self.tileSize, (ty+1)*self.tileSize, zoom )
// return ( minx, miny, maxx, maxy )
void CHuGlobalMercator::TileBounds(int tx, int ty,int zoom, double* bound4)
{
double res = Resolution( zoom );
bound4[0] = tx * m_tileSize * res - m_originShift;
bound4[1] = ty * m_tileSize * res - m_originShift;
bound4[2] = (tx+1) * m_tileSize * res - m_originShift;
bound4[3] = (ty+1) * m_tileSize * res - m_originShift;
}
// y轴从上到下递增的情况
void CHuGlobalMercator::TileBounds2(int tx, int ty,int zoom, double* bound4)
{
double res = Resolution( zoom );
bound4[0] = tx * m_tileSize * res - m_originShift;
bound4[1] = m_originShift - ty * m_tileSize * res;//
bound4[2] = (tx+1) * m_tileSize * res - m_originShift;
bound4[3] = m_originShift - (ty+1) * m_tileSize * res;//
}
/////////////////////////////////////////////////////////////////////////////////////////
// def TileLatLonBounds(self, tx, ty, zoom ):
//"Returns bounds of the given tile in latitude/longitude using WGS84 datum"
//
// bounds = self.TileBounds( tx, ty, zoom)
// minLat, minLon = self.MetersToLatLon(bounds[0], bounds[1])
// maxLat, maxLon = self.MetersToLatLon(bounds[2], bounds[3])
//
// return ( minLat, minLon, maxLat, maxLon )
void CHuGlobalMercator::TileLatLonBounds(int tx, int ty,int zoom, double* LatLonbound4)
{
double res = Resolution( zoom );
double minx = tx * m_tileSize * res - m_originShift;
double miny = ty * m_tileSize * res - m_originShift;
double maxx = (tx+1) * m_tileSize * res - m_originShift;
double maxy = (ty+1) * m_tileSize * res - m_originShift;

LatLonbound4[1] = (minx / m_originShift) * 180.0;
LatLonbound4[0] = (miny / m_originShift) * 180.0;
LatLonbound4[0] = 180 / m_pi * (2 * atan( exp( LatLonbound4[0] * m_pi / 180.0)) - m_pi / 2.0);

LatLonbound4[3] = (maxx / m_originShift) * 180.0;
LatLonbound4[2] = (maxy / m_originShift) * 180.0;
LatLonbound4[2] = 180 / m_pi * (2 * atan( exp( LatLonbound4[2] * m_pi / 180.0)) - m_pi / 2.0);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
// def Resolution(self, zoom ):
//"Resolution (meters/pixel) for given zoom level (measured at Equator)"
//
//# return (2 * math.pi * 6378137) / (self.tileSize * 2**zoom)
// return self.initialResolution / (2**zoom)
double CHuGlobalMercator::Resolution(int zoom)
{
return m_initialResolution / pow(2,(double)zoom);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// def ZoomForPixelSize(self, pixelSize ):
//"Maximal scaledown zoom of the pyramid closest to the pixelSize."
//
// for i in range(MAXZOOMLEVEL):
//if pixelSize > self.Resolution(i):
//if i!=0:
//return i-1
//else:
//return 0 # We don't want to scale up
int CHuGlobalMercator::ZoomForPixelSize(double pixelSize)
{
for (int i=0; i<32; i++)
{
if (pixelSize > Resolution(i))
{
if (i != 0)
{
return i-1;
}
else
{
return 0;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// def GoogleTile(self, tx, ty, zoom):
//"Converts TMS tile coordinates to Google Tile coordinates"
//
//# coordinate origin is moved from bottom-left to top-left corner of the extent
// return tx, (2**zoom - 1) - ty
void CHuGlobalMercator::GoogleTile(int tx, int ty,int zoom, int* txy)
{
txy[0] = tx;
txy[1] = (pow(2,(double)zoom) - 1) - ty;
}
/////////////////////////////////////////////////////////////////////////////////////////
// def QuadTree(self, tx, ty, zoom ):
//"Converts TMS tile coordinates to Microsoft QuadTree"
//
// quadKey = ""
// ty = (2**zoom - 1) - ty
// for i in range(zoom, 0, -1):
//digit = 0
// mask = 1 << (i-1)
// if (tx & mask) != 0:
//digit += 1
// if (ty & mask) != 0:
//digit += 2
// quadKey += str(digit)
//
// return quadKey
//////////////////////////////////////////////////////////////////////////////////////////
/**
* WGS84转GCj02
* @param lng
* @param lat
* @returns {*[]}
*/
//var wgs84togcj02 = function wgs84togcj02(lng, lat) {
// var lat = +lat;
// var lng = +lng;
// if (out_of_china(lng, lat)) {
// return [lng, lat]
// } else {
// var dlat = transformlat(lng - 105.0, lat - 35.0);
// var dlng = transformlng(lng - 105.0, lat - 35.0);
// var radlat = lat / 180.0 * PI;
// var magic = Math.sin(radlat);
// magic = 1 - ee * magic * magic;
// var sqrtmagic = Math.sqrt(magic);
// dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
// dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
// var mglat = lat + dlat;
// var mglng = lng + dlng;
// return [mglng, mglat]
// }
//};
void CHuGlobalMercator::wgs84togcj02(double lng, double lat, double* mglnglat)
{
if (out_of_china(lng, lat))
{
mglnglat[0] = lng;
mglnglat[1] = lat;
return;
}
else
{
double dlat = transformlat(lng - 105.0, lat - 35.0);
double dlng = transformlng(lng - 105.0, lat - 35.0);
double radlat = lat / 180.0 * PI;
double magic = sin(radlat);
magic = 1 - ee * magic * magic;
double sqrtmagic = sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
dlng = (dlng * 180.0) / (a / sqrtmagic * cos(radlat) * PI);
mglnglat[0] = lng + dlng;
mglnglat[1] = lat + dlat;

return;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
/**
* GCJ02 转换为 WGS84
* @param lng
* @param lat
* @returns {*[]}
*/
//var gcj02towgs84 = function gcj02towgs84(lng, lat) {
// var lat = +lat;
// var lng = +lng;
// if (out_of_china(lng, lat)) {
// return [lng, lat]
// } else {
// var dlat = transformlat(lng - 105.0, lat - 35.0);
// var dlng = transformlng(lng - 105.0, lat - 35.0);
// var radlat = lat / 180.0 * PI;
// var magic = Math.sin(radlat);
// magic = 1 - ee * magic * magic;
// var sqrtmagic = Math.sqrt(magic);
// dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
// dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
// var mglat = lat + dlat;
// var mglng = lng + dlng;
// return [lng * 2 - mglng, lat * 2 - mglat]
// }
//};
void CHuGlobalMercator::gcj02towgs84(double mglng, double mglat, double* lnglat)
{
double lng = mglng;
double lat = mglat;
if (out_of_china(lng, lat))
{
lnglat[0] = lng;
lnglat[1] = lat;
return;
}
else
{
double dlat = transformlat(lng - 105.0, lat - 35.0);
double dlng = transformlng(lng - 105.0, lat - 35.0);
double radlat = lat / 180.0 * PI;
double magic = sin(radlat);
magic = 1 - ee * magic * magic;
double sqrtmagic = sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
dlng = (dlng * 180.0) / (a / sqrtmagic * cos(radlat) * PI);
double mglat2 = lat + dlat;
double mglng2 = lng + dlng;
lnglat[0] = lng * 2 - mglng2;
lnglat[1] = lat * 2 - mglat2;
return;
}
}
//var transformlat = function transformlat(lng, lat) {
// var lat = +lat;
// var lng = +lng;
// var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
// ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
// ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
// ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
// return ret
//};
double CHuGlobalMercator::transformlat(double lng, double lat)
{
double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * sqrt(abs(lng));
ret += (20.0 * sin(6.0 * lng * PI) + 20.0 * sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * sin(lat * PI) + 40.0 * sin(lat / 3.0 * PI)) * 2.0 / 3.0;
ret += (160.0 * sin(lat / 12.0 * PI) + 320 * sin(lat * PI / 30.0)) * 2.0 / 3.0;
return ret;
}
//var transformlng = function transformlng(lng, lat) {
// var lat = +lat;
// var lng = +lng;
// var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
// ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
// ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
// ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
// return ret
//};
double CHuGlobalMercator::transformlng(double lng, double lat)
{
double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * sqrt(abs(lng));
ret += (20.0 * sin(6.0 * lng * PI) + 20.0 * sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * sin(lng * PI) + 40.0 * sin(lng / 3.0 * PI)) * 2.0 / 3.0;
ret += (150.0 * sin(lng / 12.0 * PI) + 300.0 * sin(lng / 30.0 * PI)) * 2.0 / 3.0;
return ret;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* 判断是否在国内,不在国内则不做偏移
* @param lng
* @param lat
* @returns {boolean}
*/
//var out_of_china = function out_of_china(lng, lat) {
// var lat = +lat;
// var lng = +lng;
// // 纬度3.86~53.55,经度73.66~135.05
// return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
//};
bool CHuGlobalMercator::out_of_china(double lng, double lat)
{
// 纬度3.86~53.55,经度73.66~135.05
if (lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)
{
return false;
}
else
{
return true;
}
};

上一篇:IAR project build with command line


下一篇:DrawableLayout