Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Commit 08d0a9a

Browse files
authored
Quadkey tokens in tile URL templates, limited WMS support (#5628)
* [core] Quadkey tokens in tile URL templates Fixes #5485. * [core] WMS tokens in tile URL templates Fixes #822. * [macos] Added WMS debug style Added a style to the macosapp resource bundle that can be used to test WMS support. To use it, zoom in to somewhere in New Jersey, then go to View ‣ Custom Style and enter “wms.json”.
1 parent 6329806 commit 08d0a9a

File tree

6 files changed

+122
-0
lines changed

6 files changed

+122
-0
lines changed

platform/ios/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Mapbox welcomes participation and contributions from everyone. Please read [CON
44

55
## master
66

7+
* Added [quadkey](https://msdn.microsoft.com/en-us/library/bb259689.aspx) support and limited WMS support in raster tile URL templates. ([#5628](https://github.com/mapbox/mapbox-gl-native/pull/5628))
8+
79
## 3.3.0
810

911
### Styles and data

platform/macos/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Right-clicking to open MGLMapView’s context menu no longer prevents the user from subsequently panning the map by clicking and dragging. ([#5593](https://github.com/mapbox/mapbox-gl-native/pull/5593))
66
* Replaced the wireframe debug mask with an overdraw visualization debug mask to match Mapbox GL JS’s overdraw inspector. ([#5403](https://github.com/mapbox/mapbox-gl-native/pull/5403))
77
* Improved the design of the generated API documentation. ([#5306](https://github.com/mapbox/mapbox-gl-native/pull/5306))
8+
* Added [quadkey](https://msdn.microsoft.com/en-us/library/bb259689.aspx) support and limited WMS support in raster tile URL templates. ([#5628](https://github.com/mapbox/mapbox-gl-native/pull/5628))
89

910
## 0.2.0
1011

platform/macos/app/wms.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"version": 8,
3+
"name": "WMS Test",
4+
"sources": {
5+
"wms-test": {
6+
"type": "raster",
7+
"tiles": [
8+
"https://geodata.state.nj.us/imagerywms/Natural2015?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&width=256&height=256&layers=Natural2015"
9+
],
10+
"tileSize": 256
11+
}
12+
},
13+
"layers": [{
14+
"id": "wms-test-layer",
15+
"type": "raster",
16+
"source": "wms-test",
17+
"paint": {
18+
"raster-fade-duration": 100
19+
}
20+
}]
21+
}

platform/macos/macos.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
DA35A2C21CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2C11CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m */; };
2121
DA35A2CF1CCAAED300E826B2 /* NSValue+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A2CD1CCAAED300E826B2 /* NSValue+MGLAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
2222
DA35A2D01CCAAED300E826B2 /* NSValue+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2CE1CCAAED300E826B2 /* NSValue+MGLAdditions.m */; };
23+
DA5589771D320C41006B7F64 /* wms.json in Resources */ = {isa = PBXBuildFile; fileRef = DA5589761D320C41006B7F64 /* wms.json */; };
2324
DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E961CC2E3400062CAFB /* AppDelegate.m */; };
2425
DA839E9A1CC2E3400062CAFB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E991CC2E3400062CAFB /* main.m */; };
2526
DA839E9D1CC2E3400062CAFB /* MapDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E9C1CC2E3400062CAFB /* MapDocument.m */; };
@@ -159,6 +160,7 @@
159160
DA35A2C11CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLClockDirectionFormatterTests.m; path = ../../darwin/test/MGLClockDirectionFormatterTests.m; sourceTree = "<group>"; };
160161
DA35A2CD1CCAAED300E826B2 /* NSValue+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLAdditions.h"; sourceTree = "<group>"; };
161162
DA35A2CE1CCAAED300E826B2 /* NSValue+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+MGLAdditions.m"; sourceTree = "<group>"; };
163+
DA5589761D320C41006B7F64 /* wms.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = wms.json; sourceTree = "<group>"; };
162164
DA839E921CC2E3400062CAFB /* Mapbox GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL.app"; sourceTree = BUILT_PRODUCTS_DIR; };
163165
DA839E951CC2E3400062CAFB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
164166
DA839E961CC2E3400062CAFB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -334,6 +336,7 @@
334336
DAE6C2EC1CC3050F00DB3429 /* TimeIntervalTransformer.m */,
335337
DA839EA11CC2E3400062CAFB /* Assets.xcassets */,
336338
DA839EA31CC2E3400062CAFB /* MainMenu.xib */,
339+
DA5589761D320C41006B7F64 /* wms.json */,
337340
DAE6C2E11CC304F900DB3429 /* Credits.rtf */,
338341
DA839EA61CC2E3400062CAFB /* Info.plist */,
339342
DA839E981CC2E3400062CAFB /* Supporting Files */,
@@ -721,6 +724,7 @@
721724
DA839EA21CC2E3400062CAFB /* Assets.xcassets in Resources */,
722725
DA839EA01CC2E3400062CAFB /* MapDocument.xib in Resources */,
723726
DA839EA51CC2E3400062CAFB /* MainMenu.xib in Resources */,
727+
DA5589771D320C41006B7F64 /* wms.json in Resources */,
724728
DAE6C2E21CC304F900DB3429 /* Credits.rtf in Resources */,
725729
);
726730
runOnlyForDeploymentPostprocessing = 0;

src/mbgl/storage/resource.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,44 @@
1+
#include <mapbox/geometry/box.hpp>
12
#include <mbgl/storage/resource.hpp>
3+
#include <mbgl/util/constants.hpp>
24
#include <mbgl/util/string.hpp>
35
#include <mbgl/util/token.hpp>
46
#include <mbgl/util/url.hpp>
57

8+
#include <cmath>
9+
610
namespace mbgl {
711

12+
static std::string getQuadKey(int32_t x, int32_t y, int8_t z) {
13+
std::string quadKey;
14+
quadKey.reserve(z);
15+
int32_t mask;
16+
for (int8_t i = z; i > 0; i--) {
17+
mask = 1 << (i - 1);
18+
quadKey += '0' + ((x & mask ? 1 : 0) + (y & mask ? 2 : 0));
19+
}
20+
return quadKey;
21+
}
22+
23+
static mapbox::geometry::point<double> getMercCoord(int32_t x, int32_t y, int8_t z) {
24+
double resolution = (util::M2PI * util::EARTH_RADIUS_M / 256) / std::pow(2.0f, z);
25+
return {
26+
x * resolution - util::M2PI * util::EARTH_RADIUS_M / 2,
27+
y * resolution - util::M2PI * util::EARTH_RADIUS_M / 2,
28+
};
29+
}
30+
31+
static std::string getTileBBox(int32_t x, int32_t y, int8_t z) {
32+
// Alter the y for the Google/OSM tile scheme.
33+
y = std::pow(2.0f, z) - y - 1;
34+
35+
auto min = getMercCoord(x * 256, y * 256, z);
36+
auto max = getMercCoord((x + 1) * 256, (y + 1) * 256, z);
37+
38+
return (util::toString(min.x) + "," + util::toString(min.y) + "," +
39+
util::toString(max.x) + "," + util::toString(max.y));
40+
}
41+
842
Resource Resource::style(const std::string& url) {
943
return Resource {
1044
Resource::Kind::Style,
@@ -64,6 +98,10 @@ Resource Resource::tile(const std::string& urlTemplate,
6498
return util::toString(x);
6599
} else if (token == "y") {
66100
return util::toString(y);
101+
} else if (token == "quadkey") {
102+
return getQuadKey(x, y, z);
103+
} else if (token == "bbox-epsg-3857") {
104+
return getTileBBox(x, y, z);
67105
} else if (token == "prefix") {
68106
std::string prefix{ 2 };
69107
prefix[0] = "0123456789abcdef"[x % 16];

test/storage/resource.cpp

+56
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,62 @@ TEST(Resource, Tile) {
3636
EXPECT_EQ(1, vectorTile.tileData->x);
3737
EXPECT_EQ(2, vectorTile.tileData->y);
3838
EXPECT_EQ(3, vectorTile.tileData->z);
39+
40+
Resource quadTile = Resource::tile("http://example.com/{quadkey}.png", 2.0, 0, 0, 1);
41+
EXPECT_EQ(Resource::Kind::Tile, quadTile.kind);
42+
EXPECT_EQ("http://example.com/0.png", quadTile.url);
43+
EXPECT_EQ("http://example.com/{quadkey}.png", quadTile.tileData->urlTemplate);
44+
EXPECT_EQ(1, quadTile.tileData->pixelRatio);
45+
EXPECT_EQ(0, quadTile.tileData->x);
46+
EXPECT_EQ(0, quadTile.tileData->y);
47+
EXPECT_EQ(1, quadTile.tileData->z);
48+
49+
quadTile = Resource::tile("http://example.com/{quadkey}.png", 2.0, 0, 0, 2);
50+
EXPECT_EQ(Resource::Kind::Tile, quadTile.kind);
51+
EXPECT_EQ("http://example.com/00.png", quadTile.url);
52+
EXPECT_EQ("http://example.com/{quadkey}.png", quadTile.tileData->urlTemplate);
53+
EXPECT_EQ(1, quadTile.tileData->pixelRatio);
54+
EXPECT_EQ(0, quadTile.tileData->x);
55+
EXPECT_EQ(0, quadTile.tileData->y);
56+
EXPECT_EQ(2, quadTile.tileData->z);
57+
58+
quadTile = Resource::tile("http://example.com/{quadkey}.png", 2.0, 1, 1, 2);
59+
EXPECT_EQ(Resource::Kind::Tile, quadTile.kind);
60+
EXPECT_EQ("http://example.com/03.png", quadTile.url);
61+
EXPECT_EQ("http://example.com/{quadkey}.png", quadTile.tileData->urlTemplate);
62+
EXPECT_EQ(1, quadTile.tileData->pixelRatio);
63+
EXPECT_EQ(1, quadTile.tileData->x);
64+
EXPECT_EQ(1, quadTile.tileData->y);
65+
EXPECT_EQ(2, quadTile.tileData->z);
66+
67+
quadTile = Resource::tile("http://example.com/{quadkey}.png", 2.0, 22914, 52870, 17);
68+
EXPECT_EQ(Resource::Kind::Tile, quadTile.kind);
69+
EXPECT_EQ("http://example.com/02301322130000230.png", quadTile.url);
70+
EXPECT_EQ("http://example.com/{quadkey}.png", quadTile.tileData->urlTemplate);
71+
EXPECT_EQ(1, quadTile.tileData->pixelRatio);
72+
EXPECT_EQ(22914, quadTile.tileData->x);
73+
EXPECT_EQ(52870, quadTile.tileData->y);
74+
EXPECT_EQ(17, quadTile.tileData->z);
75+
76+
// Test case confirmed by quadkeytools package
77+
// https://bitbucket.org/steele/quadkeytools/src/master/test/quadkey.js?fileviewer=file-view-default#quadkey.js-57
78+
quadTile = Resource::tile("http://example.com/{quadkey}.png", 2.0, 29, 3, 6);
79+
EXPECT_EQ(Resource::Kind::Tile, quadTile.kind);
80+
EXPECT_EQ("http://example.com/011123.png", quadTile.url);
81+
EXPECT_EQ("http://example.com/{quadkey}.png", quadTile.tileData->urlTemplate);
82+
EXPECT_EQ(1, quadTile.tileData->pixelRatio);
83+
EXPECT_EQ(29, quadTile.tileData->x);
84+
EXPECT_EQ(3, quadTile.tileData->y);
85+
EXPECT_EQ(6, quadTile.tileData->z);
86+
87+
Resource wmsTile = Resource::tile("http://example.com/?bbox={bbox-epsg-3857}", 2.0, 0, 0, 1);
88+
EXPECT_EQ(Resource::Kind::Tile, wmsTile.kind);
89+
EXPECT_EQ("http://example.com/?bbox=-20037508.342789245,0,0,20037508.342789245", wmsTile.url);
90+
EXPECT_EQ("http://example.com/?bbox={bbox-epsg-3857}", wmsTile.tileData->urlTemplate);
91+
EXPECT_EQ(1, wmsTile.tileData->pixelRatio);
92+
EXPECT_EQ(0, wmsTile.tileData->x);
93+
EXPECT_EQ(0, wmsTile.tileData->y);
94+
EXPECT_EQ(1, wmsTile.tileData->z);
3995
}
4096

4197
TEST(Resource, Glyphs) {

0 commit comments

Comments
 (0)