|
2 | 2 |
|
3 | 3 | #include "citygml/vecs.hpp" |
4 | 4 | #include "citygml/cityobject.h" |
5 | | - |
| 5 | +#include <array> |
| 6 | +#include <utility> |
6 | 7 |
|
7 | 8 | namespace plateau::geometry { |
8 | 9 |
|
@@ -107,69 +108,59 @@ namespace plateau::geometry { |
107 | 108 | } |
108 | 109 | }; |
109 | 110 |
|
110 | | - /** |
111 | | - * 平面直角座標判定、平面直角座標の基準点取得 |
112 | | - */ |
| 111 | + /** |
| 112 | + * 平面直角座標系の判定、平面直角座標の基準点取得 |
| 113 | + */ |
113 | 114 | struct CoordinateReferenceFactory { |
114 | | - |
115 | 115 | static constexpr int default_epsg = 6697; |
116 | 116 |
|
| 117 | + // EPSGとZone IDのマッピング |
| 118 | + static constexpr std::array<std::pair<int, int>, 13> epsg_to_zone = { { |
| 119 | + {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, |
| 120 | + {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, |
| 121 | + {10172, 11}, {10173, 12}, {10174, 13} |
| 122 | + } }; |
| 123 | + |
| 124 | + // Zone IDごとの座標データ |
| 125 | + static constexpr std::array<std::pair<int, std::array<double, 3>>, 13> zone_to_point = { { |
| 126 | + {1, {33.0, 129.5, 0.0}}, {2, {33.0, 131.0, 0.0}}, {3, {36.0, 132.166667, 0.0}}, |
| 127 | + {4, {33.0, 133.5, 0.0}}, {5, {36.0, 134.333333, 0.0}}, {6, {36.0, 136.0, 0.0}}, |
| 128 | + {7, {36.0, 137.166667, 0.0}}, {8, {36.0, 138.5, 0.0}}, {9, {35.0, 139.833333, 0.0}}, |
| 129 | + {10, {40.0, 140.833333, 0.0}}, {11, {44.0, 140.25, 0.0}}, {12, {44.0, 142.0, 0.0}}, |
| 130 | + {13, {43.0, 144.0, 0.0}} |
| 131 | + } }; |
| 132 | + |
117 | 133 | // EPSGごとのzone取得 |
118 | | - static int GetZoneId(int epsg) { |
119 | | - // 日本測地系2011(JGD2011)に基づく平面直角座標系 |
120 | | - static const std::map<int, int> epsg_to_zone = { |
121 | | - {10162, 1}, {10163, 2}, {10164, 3}, {10165, 4}, {10166, 5}, |
122 | | - {10167, 6}, {10168, 7}, {10169, 8}, {10170, 9}, {10171, 10}, |
123 | | - {10172, 11}, {10173, 12}, {10174, 13} |
124 | | - }; |
125 | | - auto it = epsg_to_zone.find(epsg); |
126 | | - return it != epsg_to_zone.end() ? it->second : 0; |
| 134 | + static constexpr int GetZoneId(int epsg) { |
| 135 | + for (const auto& pair : epsg_to_zone) { |
| 136 | + if (pair.first == epsg) { |
| 137 | + return pair.second; |
| 138 | + } |
| 139 | + } |
| 140 | + return 0; |
127 | 141 | } |
128 | 142 |
|
129 | 143 | // EPSGごとの基準点取得 |
130 | 144 | static GeoCoordinate GetReferencePoint(int epsg) { |
131 | 145 | const int zone = GetZoneId(epsg); |
132 | | - if (zone != 0) |
133 | | - return GetReferencePointByZone(zone); |
| 146 | + if (zone != 0) { |
| 147 | + for (const auto& pair : zone_to_point) { |
| 148 | + if (pair.first == zone) { |
| 149 | + const auto& coords = pair.second; |
| 150 | + return GeoCoordinate(coords[0], coords[1], coords[2]); |
| 151 | + } |
| 152 | + } |
| 153 | + } |
134 | 154 | return GeoCoordinate(); |
135 | 155 | } |
136 | 156 |
|
137 | | - // Zone IDごとの基準点 |
138 | | - // zoneに紐づく基準点はPolarToPlaneCartesianにハードコードで持っているが値が取得できないので、ここで定義 |
139 | | - static GeoCoordinate GetReferencePointByZone(int zone_id) { |
140 | | - static const std::map<int, GeoCoordinate> zone_to_point = { |
141 | | - {1, GeoCoordinate(33, 129.5, 0)}, |
142 | | - {2, GeoCoordinate(33, 131, 0)}, |
143 | | - {3, GeoCoordinate(36, 132.166667, 0)}, |
144 | | - {4, GeoCoordinate(33, 133.5, 0)}, |
145 | | - {5, GeoCoordinate(36, 134.333333, 0)}, |
146 | | - {6, GeoCoordinate(36, 136, 0)}, |
147 | | - {7, GeoCoordinate(36, 137.166667, 0)}, |
148 | | - {8, GeoCoordinate(36, 138.5, 0)}, |
149 | | - {9, GeoCoordinate(35, 139.833333, 0)}, |
150 | | - {10, GeoCoordinate(40, 140.833333, 0)}, |
151 | | - {11, GeoCoordinate(44, 140.25, 0)}, |
152 | | - {12, GeoCoordinate(44, 142, 0)}, |
153 | | - {13, GeoCoordinate(43, 144, 0)}, |
154 | | - {14, GeoCoordinate(26, 142, 0)}, |
155 | | - {15, GeoCoordinate(26, 127.5, 0)}, |
156 | | - {16, GeoCoordinate(24, 124, 0)}, |
157 | | - {17, GeoCoordinate(31, 131, 0)}, |
158 | | - {18, GeoCoordinate(20, 136, 0)}, |
159 | | - {19, GeoCoordinate(25, 154, 0)} |
160 | | - }; |
161 | | - auto it = zone_to_point.find(zone_id); |
162 | | - return it != zone_to_point.end() ? it->second : GeoCoordinate(); |
163 | | - } |
164 | | - |
165 | 157 | // 極座標系・平面直角座標系判定 |
| 158 | + // 平面直角座標系の区分についてはこちらを参照してください : |
| 159 | + // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ |
| 160 | + // “該当範囲でなければ極座標” と単純化していますが、 |
| 161 | + // EPSG 4301(JGD2000) 等の別 CRS を誤って極座標と判定する恐れがあります。 |
166 | 162 | static bool IsPolarCoordinateSystem(int epsg) { |
167 | | - // 平面直角座標系の区分についてはこちらを参照してください : |
168 | | - // https://www.mlit.go.jp/plateaudocument/toc9/toc9_08/toc9_08_04/ |
169 | | - if (epsg >= 10162 && epsg <= 10174) { |
170 | | - return false; |
171 | | - } |
172 | | - return true; |
| 163 | + return !(epsg >= 10162 && epsg <= 10174); |
173 | 164 | } |
174 | 165 | }; |
175 | 166 | } |
0 commit comments