alaCarte Maps
Renderer for OpenStreetMap tiles
transform.cpp
Go to the documentation of this file.
1 
22 /*
23  * =====================================================================================
24  *
25  * Filename: tranform.cpp
26  *
27  * Description: Utility functions to transfrom from Merkcator to lat/lon.
28  *
29  * =====================================================================================
30  */
31 
32 #include <boost/math/constants/constants.hpp>
33 #include <cmath>
34 
35 #include "settings.hpp"
36 
37 #define NORM (FACTOR * RADIUS/2.0)
38 // earth radius WGS84
39 #define RADIUS 6378137.0
40 // 2 decimal places
41 #define FACTOR 100.0
42 
52 void tileToMercator(int tx, int ty, int zoom, coord_t& x, coord_t& y)
53 {
54  int n = (1 << zoom);
55  /*
56  * Calculate the inverse to:
57  * tx = floor(n * (1 + (x / (F * R/2))) / 2)
58  * ty = floor(n * (1 - (y / (F * R/2))) / 2)
59  */
60  x = (tx * 2.0 / n - 1) * NORM;
61  y = -(ty * 2.0 / n - 1) * NORM;
62 }
63 
73 void mercatorToTile(coord_t x, coord_t y, int zoom, int& tx, int& ty)
74 {
75  int n = (1 << zoom);
76  tx = (int) (n * (1 + (x / NORM)) / 2);
77  ty = (int) (n * (1 - (y / NORM)) / 2);
78 }
79 
87 void projectMercator(const FloatPoint& p, coord_t& x, coord_t& y)
88 {
89  double lon = p.lon / 180.0 * boost::math::constants::pi<double>();
90  double lat = p.lat / 180.0 * boost::math::constants::pi<double>();
91  x = lon / boost::math::constants::pi<double>() * NORM;
92  y = log(tan(boost::math::constants::pi<double>() / 4.0 + lat / 2.0)) / boost::math::constants::pi<double>() * NORM;
93 }
94 
102 void inverseMercator(const FixedPoint& p, double& lat, double& lon)
103 {
104  lon = p.x / NORM * 180.0;
105  lat = atan(sinh(p.y / NORM * boost::math::constants::pi<double>())) / boost::math::constants::pi<double>() * 180.0;
106 }
107 
108 uint64_t spreadBits32(uint32_t y)
109 {
110  uint64_t B[] = {
111  0x5555555555555555,
112  0x3333333333333333,
113  0x0f0f0f0f0f0f0f0f,
114  0x00ff00ff00ff00ff,
115  0x0000ffff0000ffff,
116  0x00000000ffffffff
117  };
118 
119  int S[] = { 1, 2, 4, 8, 16, 32 };
120 
121  uint64_t x = y;
122  x = (x | (x << S[5])) & B[5];
123  x = (x | (x << S[4])) & B[4];
124  x = (x | (x << S[3])) & B[3];
125  x = (x | (x << S[2])) & B[2];
126  x = (x | (x << S[1])) & B[1];
127  x = (x | (x << S[0])) & B[0];
128 
129  return x;
130 }
131 
132 uint64_t interleave64(uint32_t x, uint32_t y)
133 {
134  return spreadBits32(x) | (spreadBits32(y) << 1);
135 }
136 
138 {
139  // convert signed to unsigned with offset
140  uint32_t x = p.x - std::numeric_limits<coord_t>::min();
141  uint32_t y = p.y - std::numeric_limits<coord_t>::min();
142 
143  int r = 32;
144  uint64_t mask = (1 << r) - 1;
145  uint32_t hodd = 0;
146  uint32_t heven = x ^ y;
147  uint64_t notx = ~x & mask;
148  uint64_t noty = ~y & mask;
149  uint64_t temp = notx ^ y;
150 
151  uint64_t v0 = 0, v1 = 0;
152  for (int k = 1; k < r; k++) {
153  v1 = ((v1 & heven) | ((v0 ^ noty) & temp)) >> 1;
154  v0 = ((v0 & (v1 ^ notx)) | (~v0 & (v1 ^ noty))) >> 1;
155  }
156  hodd = (~v0 & (v1 ^ x)) | (v0 & (v1 ^ noty));
157 
158  return interleave64(heven, hodd);
159 }
160 
std::int32_t coord_t
Definition: settings.hpp:117
void tileToMercator(int tx, int ty, int zoom, coord_t &x, coord_t &y)
converts tile coordinates to north-west corner of the tile in the Mercator projection.
Definition: transform.cpp:52
#define NORM
This file is part of alaCarte.
Definition: transform.cpp:37
void projectMercator(const FloatPoint &p, coord_t &x, coord_t &y)
converts cooridinates in lat/lon (WGS84) to spherical Mercator (EPSG:3857).
Definition: transform.cpp:87
void inverseMercator(const FixedPoint &p, double &lat, double &lon)
converts cooridinates in lat/lon (WGS84) to spherical Mercator (EPSG:3857).
Definition: transform.cpp:102
uint64_t spreadBits32(uint32_t y)
Definition: transform.cpp:108
uint64_t interleave64(uint32_t x, uint32_t y)
Definition: transform.cpp:132
uint64_t xy2hilbert(FixedPoint p)
Definition: transform.cpp:137
void mercatorToTile(coord_t x, coord_t y, int zoom, int &tx, int &ty)
converts mercator coordinates to the coords of the tile they are contained in.
Definition: transform.cpp:73