/src/gdal/frmts/wms/minidriver_virtualearth.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: WMS Client Driver |
4 | | * Purpose: Implementation of Dataset and RasterBand classes for WMS |
5 | | * and other similar services. |
6 | | * Author: Even Rouault |
7 | | * |
8 | | ****************************************************************************** |
9 | | * Copyright (c) 2011, Even Rouault <even dot rouault at spatialys.com> |
10 | | * |
11 | | * SPDX-License-Identifier: MIT |
12 | | ****************************************************************************/ |
13 | | |
14 | | #include "wmsdriver.h" |
15 | | #include "minidriver_virtualearth.h" |
16 | | |
17 | | #include <algorithm> |
18 | | |
19 | | // These should be global, they are used all over the place |
20 | | const double SPHERICAL_RADIUS = 6378137.0; |
21 | | const double MAX_GM = SPHERICAL_RADIUS * M_PI; // 20037508.342789244 |
22 | | |
23 | | WMSMiniDriver_VirtualEarth::WMSMiniDriver_VirtualEarth() |
24 | 0 | { |
25 | 0 | } |
26 | | |
27 | | WMSMiniDriver_VirtualEarth::~WMSMiniDriver_VirtualEarth() |
28 | 0 | { |
29 | 0 | } |
30 | | |
31 | | CPLErr |
32 | | WMSMiniDriver_VirtualEarth::Initialize(CPLXMLNode *config, |
33 | | CPL_UNUSED char **papszOpenOptions) |
34 | 0 | { |
35 | 0 | m_base_url = CPLGetXMLValue(config, "ServerURL", ""); |
36 | 0 | if (m_base_url.empty()) |
37 | 0 | { |
38 | 0 | CPLError(CE_Failure, CPLE_AppDefined, |
39 | 0 | "GDALWMS, VirtualEarth mini-driver: ServerURL missing."); |
40 | 0 | return CE_Failure; |
41 | 0 | } |
42 | | |
43 | 0 | if (m_base_url.find("${quadkey}") == std::string::npos) |
44 | 0 | { |
45 | 0 | CPLError(CE_Failure, CPLE_AppDefined, |
46 | 0 | "GDALWMS, VirtualEarth mini-driver: ${quadkey} missing in " |
47 | 0 | "ServerURL."); |
48 | 0 | return CE_Failure; |
49 | 0 | } |
50 | | |
51 | 0 | m_parent_dataset->WMSSetDefaultBlockSize(256, 256); |
52 | 0 | m_parent_dataset->WMSSetDefaultDataWindowCoordinates(-MAX_GM, MAX_GM, |
53 | 0 | MAX_GM, -MAX_GM); |
54 | 0 | m_parent_dataset->WMSSetDefaultTileLevel(21); |
55 | 0 | m_parent_dataset->WMSSetDefaultOverviewCount(20); |
56 | 0 | m_parent_dataset->WMSSetNeedsDataWindow(FALSE); |
57 | 0 | m_oSRS.importFromEPSG(3857); |
58 | 0 | return CE_None; |
59 | 0 | } |
60 | | |
61 | | CPLErr WMSMiniDriver_VirtualEarth::TiledImageRequest( |
62 | | WMSHTTPRequest &request, CPL_UNUSED const GDALWMSImageRequestInfo &iri, |
63 | | const GDALWMSTiledImageRequestInfo &tiri) |
64 | 0 | { |
65 | 0 | CPLString &url = request.URL; |
66 | 0 | url = m_base_url; |
67 | |
|
68 | 0 | char szTileNumber[64]; |
69 | 0 | int x = tiri.m_x; |
70 | 0 | int y = tiri.m_y; |
71 | 0 | int z = std::min(32, tiri.m_level); |
72 | |
|
73 | 0 | for (int i = 0; i < z; i++) |
74 | 0 | { |
75 | 0 | int row = (y & 1); |
76 | 0 | int col = (x & 1); |
77 | |
|
78 | 0 | szTileNumber[z - 1 - i] = static_cast<char>('0' + (col | (row << 1))); |
79 | |
|
80 | 0 | x = x >> 1; |
81 | 0 | y = y >> 1; |
82 | 0 | } |
83 | 0 | szTileNumber[z] = 0; |
84 | |
|
85 | 0 | URLSearchAndReplace(&url, "${quadkey}", "%s", szTileNumber); |
86 | | // Sounds like this should be random |
87 | 0 | URLSearchAndReplace(&url, "${server_num}", "%d", |
88 | 0 | (tiri.m_x + tiri.m_y + z) % 4); |
89 | 0 | return CE_None; |
90 | 0 | } |