python這麼火,C++/C#的程序員都生存不下去了,爲啥還要幹把python轉寫成c++的這種反動的事?python
項目須要唄。。。ios
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_Hc++
#include "math.h"
#include <stdio.h>
#include <list>git
#include <iostream>
using namespace std;程序員
class CHuGlobalGeodetic
{網絡
private:函數
public:
CHuGlobalGeodetic(void);
virtual ~CHuGlobalGeodetic(void);spa
////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;orm
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);ci
};
#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; } };