mirror of
https://github.com/BertoldVdb/ZoneDetect.git
synced 2026-04-27 14:57:40 +00:00
Upload database generation code (not very clean...)
This commit is contained in:
parent
fffafa15cc
commit
3629e97f9d
8 changed files with 1015 additions and 0 deletions
3
database/README.md
Normal file
3
database/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Database files
|
||||
|
||||
Please download the database files [here](https://files.bertold.org/zd/db.zip) or create them using the builder.
|
||||
566
database/builder/builder.cpp
Normal file
566
database/builder/builder.cpp
Normal file
|
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Bertold Van den Bergh (vandenbergh@bertold.org)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <shapefil.h>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <math.h>
|
||||
#include <tuple>
|
||||
|
||||
const double Inf = std::numeric_limits<float>::infinity();
|
||||
|
||||
std::unordered_map<std::string, std::string> alpha2ToName;
|
||||
std::unordered_map<std::string, std::string> tzidToAlpha2;
|
||||
|
||||
void errorFatal(std::string what)
|
||||
{
|
||||
std::cerr<<what<<"\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int encodeVariableLength(std::vector<uint8_t>& output, int64_t valueIn, bool handleNeg = true)
|
||||
{
|
||||
uint64_t value = valueIn * 2;
|
||||
if(valueIn < 0) {
|
||||
value = -valueIn * 2 + 1;
|
||||
}
|
||||
|
||||
if(!handleNeg) {
|
||||
value = valueIn;
|
||||
}
|
||||
|
||||
int bytesUsed = 0;
|
||||
do {
|
||||
uint8_t byteOut = value & 0x7F;
|
||||
if(value >= 128) {
|
||||
byteOut |= 0x80;
|
||||
}
|
||||
output.push_back(byteOut);
|
||||
bytesUsed ++;
|
||||
value >>= 7;
|
||||
} while(value);
|
||||
|
||||
return bytesUsed;
|
||||
}
|
||||
|
||||
int64_t doubleToFixedPoint(double input, double scale, unsigned int precision = 32)
|
||||
{
|
||||
double inputScaled = input / scale;
|
||||
return inputScaled * pow(2, precision-1);
|
||||
|
||||
}
|
||||
|
||||
struct Point {
|
||||
Point(double lat = 0, double lon = 0)
|
||||
{
|
||||
lat_ = lat;
|
||||
lon_ = lon;
|
||||
}
|
||||
|
||||
Point operator-(const Point& p)
|
||||
{
|
||||
Point result(lat_ - p.lat_, lon_ - p.lon_);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::tuple<int64_t, int64_t> toFixedPoint(unsigned int precision = 32)
|
||||
{
|
||||
int64_t latFixedPoint = doubleToFixedPoint(lat_, 90, precision);
|
||||
int64_t lonFixedPoint = doubleToFixedPoint(lon_, 180, precision);
|
||||
|
||||
return std::make_tuple(latFixedPoint, lonFixedPoint);
|
||||
}
|
||||
|
||||
int encodePointBinary(std::vector<uint8_t>& output, unsigned int precision = 32)
|
||||
{
|
||||
int64_t latFixedPoint, lonFixedPoint;
|
||||
std::tie(latFixedPoint, lonFixedPoint) = toFixedPoint(precision);
|
||||
|
||||
int bytesUsed = encodeVariableLength(output, latFixedPoint);
|
||||
bytesUsed += encodeVariableLength(output, lonFixedPoint);
|
||||
|
||||
return bytesUsed;
|
||||
}
|
||||
|
||||
double lat_;
|
||||
double lon_;
|
||||
};
|
||||
|
||||
struct PolygonData {
|
||||
Point boundingMin;
|
||||
Point boundingMax;
|
||||
std::vector<Point> points_;
|
||||
unsigned long fileIndex_ = 0;
|
||||
unsigned long metadataId_;
|
||||
|
||||
void processPoint(const Point& p)
|
||||
{
|
||||
if(p.lat_ < boundingMin.lat_) {
|
||||
boundingMin.lat_ = p.lat_;
|
||||
}
|
||||
if(p.lon_ < boundingMin.lon_) {
|
||||
boundingMin.lon_ = p.lon_;
|
||||
}
|
||||
if(p.lat_ > boundingMax.lat_) {
|
||||
boundingMax.lat_ = p.lat_;
|
||||
}
|
||||
if(p.lon_ > boundingMax.lon_) {
|
||||
boundingMax.lon_ = p.lon_;
|
||||
}
|
||||
|
||||
points_.push_back(p);
|
||||
}
|
||||
|
||||
PolygonData(unsigned long id):
|
||||
boundingMin(Inf, Inf),
|
||||
boundingMax(-Inf, -Inf),
|
||||
metadataId_(id)
|
||||
{
|
||||
}
|
||||
|
||||
long encodeBinaryData(std::vector<uint8_t>& output, unsigned int precision = 20)
|
||||
{
|
||||
long bytesEncoded = 0;
|
||||
bool first = true;
|
||||
int64_t latFixedPoint = 0, lonFixedPoint = 0;
|
||||
int64_t latFixedPointPrev, lonFixedPointPrev;
|
||||
uint64_t vertices = 0;
|
||||
|
||||
std::vector<uint8_t> tmp;
|
||||
|
||||
int64_t diffLatAcc = 0, diffLonAcc = 0, diffLatPrev = 0, diffLonPrev = 0;
|
||||
|
||||
for(Point& point: points_) {
|
||||
/* The points should first be rounded, and then the integer value is differentiated */
|
||||
latFixedPointPrev = latFixedPoint;
|
||||
lonFixedPointPrev = lonFixedPoint;
|
||||
std::tie(latFixedPoint, lonFixedPoint) = point.toFixedPoint(precision);
|
||||
|
||||
int64_t diffLat = latFixedPoint - latFixedPointPrev;
|
||||
int64_t diffLon = lonFixedPoint - lonFixedPointPrev;
|
||||
|
||||
if(first) {
|
||||
/* First point is always encoded */
|
||||
vertices++;
|
||||
encodeVariableLength(tmp, latFixedPoint);
|
||||
encodeVariableLength(tmp, lonFixedPoint);
|
||||
first = false;
|
||||
} else {
|
||||
/* Ignore points that are not different */
|
||||
if(!diffLon && !diffLat) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(diffLat != diffLatPrev || diffLon != diffLonPrev) {
|
||||
/* Encode accumulator */
|
||||
vertices++;
|
||||
encodeVariableLength(tmp, diffLatAcc);
|
||||
encodeVariableLength(tmp, diffLonAcc);
|
||||
|
||||
diffLatAcc = 0;
|
||||
diffLonAcc = 0;
|
||||
}
|
||||
|
||||
diffLatAcc += diffLat;
|
||||
diffLonAcc += diffLon;
|
||||
}
|
||||
|
||||
diffLatPrev = diffLat;
|
||||
diffLonPrev = diffLon;
|
||||
}
|
||||
|
||||
/* Encode final point */
|
||||
vertices++;
|
||||
encodeVariableLength(tmp, diffLatAcc);
|
||||
encodeVariableLength(tmp, diffLonAcc);
|
||||
|
||||
encodeVariableLength(output, vertices, false);
|
||||
std::copy(tmp.begin(), tmp.end(), std::back_inserter(output));
|
||||
|
||||
return bytesEncoded;
|
||||
}
|
||||
};
|
||||
|
||||
void encodeStringToBinary(std::vector<uint8_t>& output, std::string& input)
|
||||
{
|
||||
encodeVariableLength(output, input.size(), false);
|
||||
for(unsigned int i=0; i<input.size(); i++) {
|
||||
output.push_back(input[i] ^ 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::unordered_map<std::string, uint64_t> usedStrings_;
|
||||
|
||||
struct MetaData {
|
||||
void encodeBinaryData(std::vector<uint8_t>& output)
|
||||
{
|
||||
for(std::string& str: data_) {
|
||||
if(str.length() >= 256) {
|
||||
std::cout << "Metadata string is too long\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!usedStrings_.count(str)) {
|
||||
usedStrings_[str] = output.size();
|
||||
encodeStringToBinary(output, str);
|
||||
} else {
|
||||
encodeVariableLength(output, usedStrings_[str] + 256, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> data_;
|
||||
|
||||
unsigned long fileIndex_;
|
||||
};
|
||||
|
||||
|
||||
std::vector<PolygonData*> polygons_;
|
||||
std::vector<MetaData> metadata_;
|
||||
std::vector<std::string> fieldNames_;
|
||||
|
||||
|
||||
unsigned int decodeVariableLength(uint8_t* buffer, int64_t* result, bool handleNeg = true)
|
||||
{
|
||||
int64_t value = 0;
|
||||
unsigned int i=0, shift = 0;
|
||||
|
||||
do {
|
||||
value |= (buffer[i] & 0x7F) << shift;
|
||||
shift += 7;
|
||||
} while(buffer[i++] & 0x80);
|
||||
|
||||
if(!handleNeg) {
|
||||
*result = value;
|
||||
} else {
|
||||
*result = (value & 1)?-(value/2):(value/2);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void readMetaDataTimezone(DBFHandle dataHandle)
|
||||
{
|
||||
/* Specify field names */
|
||||
fieldNames_.push_back("TimezoneIdPrefix");
|
||||
fieldNames_.push_back("TimezoneId");
|
||||
fieldNames_.push_back("CountryAlpha2");
|
||||
fieldNames_.push_back("CountryName");
|
||||
|
||||
/* Parse attribute names */
|
||||
for(int i = 0; i < DBFGetRecordCount(dataHandle); i++) {
|
||||
metadata_[i].data_.resize(4);
|
||||
for(int j = 0; j < DBFGetFieldCount(dataHandle); j++) {
|
||||
char fieldTitle[12];
|
||||
int fieldWidth, fieldDecimals;
|
||||
DBFFieldType eType = DBFGetFieldInfo(dataHandle, j, fieldTitle, &fieldWidth, &fieldDecimals);
|
||||
|
||||
fieldTitle[11] = 0;
|
||||
std::string fieldTitleStr(fieldTitle);
|
||||
|
||||
if( eType == FTString ) {
|
||||
if(fieldTitleStr == "tzid") {
|
||||
std::string data = DBFReadStringAttribute(dataHandle, i, j);
|
||||
size_t pos = data.find('/');
|
||||
if (pos == std::string::npos) {
|
||||
metadata_[i].data_.at(0) = data;
|
||||
} else {
|
||||
metadata_[i].data_.at(0) = data.substr(0, pos) + "/";
|
||||
metadata_[i].data_.at(1) = data.substr(pos + 1, std::string::npos);
|
||||
}
|
||||
if(tzidToAlpha2.count(data)) {
|
||||
metadata_[i].data_.at(2) = tzidToAlpha2[data];
|
||||
if(alpha2ToName.count(metadata_[i].data_.at(2))) {
|
||||
metadata_[i].data_.at(3) = alpha2ToName[metadata_[i].data_.at(2)];
|
||||
} else {
|
||||
std::cout<<metadata_[i].data_.at(2)<< " not found in alpha2ToName! ("<<data<<")\n";
|
||||
}
|
||||
} else {
|
||||
std::cout<<data<<" not found in zoneToAlpha2!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readMetaDataNaturalEarthCountry(DBFHandle dataHandle)
|
||||
{
|
||||
/* Specify field names */
|
||||
fieldNames_.push_back("Alpha2");
|
||||
fieldNames_.push_back("Alpha3");
|
||||
fieldNames_.push_back("Name");
|
||||
|
||||
/* Parse attribute names */
|
||||
for(int i = 0; i < DBFGetRecordCount(dataHandle); i++) {
|
||||
metadata_[i].data_.resize(3);
|
||||
for(int j = 0; j < DBFGetFieldCount(dataHandle); j++) {
|
||||
char fieldTitle[12];
|
||||
int fieldWidth, fieldDecimals;
|
||||
DBFFieldType eType = DBFGetFieldInfo(dataHandle, j, fieldTitle, &fieldWidth, &fieldDecimals);
|
||||
|
||||
fieldTitle[11] = 0;
|
||||
std::string fieldTitleStr(fieldTitle);
|
||||
|
||||
if( eType == FTString ) {
|
||||
if(fieldTitleStr == "ISO_A2" || fieldTitleStr == "WB_A2") {
|
||||
std::string tmp = DBFReadStringAttribute(dataHandle, i, j);
|
||||
if(tmp != "-99") {
|
||||
metadata_[i].data_.at(0) = tmp;
|
||||
}
|
||||
} else if(fieldTitleStr == "ISO_A3" || fieldTitleStr == "WB_A3" || fieldTitleStr == "BRK_A3") {
|
||||
std::string tmp = DBFReadStringAttribute(dataHandle, i, j);
|
||||
if(tmp != "-99") {
|
||||
metadata_[i].data_.at(1) = tmp;
|
||||
}
|
||||
} else if(fieldTitleStr == "NAME_LONG") {
|
||||
metadata_[i].data_.at(2) = DBFReadStringAttribute(dataHandle, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> parseAlpha2ToName(DBFHandle dataHandle)
|
||||
{
|
||||
std::unordered_map<std::string, std::string> result;
|
||||
|
||||
for(int i = 0; i < DBFGetRecordCount(dataHandle); i++) {
|
||||
std::string alpha2, name;
|
||||
for(int j = 0; j < DBFGetFieldCount(dataHandle); j++) {
|
||||
char fieldTitle[12];
|
||||
int fieldWidth, fieldDecimals;
|
||||
DBFFieldType eType = DBFGetFieldInfo(dataHandle, j, fieldTitle, &fieldWidth, &fieldDecimals);
|
||||
|
||||
fieldTitle[11] = 0;
|
||||
std::string fieldTitleStr(fieldTitle);
|
||||
|
||||
if( eType == FTString ) {
|
||||
if(fieldTitleStr == "ISO_A2" || fieldTitleStr == "WB_A2") {
|
||||
std::string tmp = DBFReadStringAttribute(dataHandle, i, j);
|
||||
if(tmp != "-99" && alpha2 == "") {
|
||||
alpha2 = tmp;
|
||||
}
|
||||
} else if(fieldTitleStr == "NAME_LONG") {
|
||||
name = DBFReadStringAttribute(dataHandle, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(alpha2 != "") {
|
||||
result[alpha2]=name;
|
||||
}
|
||||
}
|
||||
|
||||
result["GF"]="French Guiana";
|
||||
result["GP"]="Guadeloupe";
|
||||
result["BQ"]="Bonaire";
|
||||
result["MQ"]="Martinique";
|
||||
result["SJ"]="Svalbard and Jan Mayen Islands";
|
||||
result["NO"]="Norway";
|
||||
result["CX"]="Christmas Island";
|
||||
result["CC"]="Cocos Islands";
|
||||
result["YT"]="Mayotte";
|
||||
result["RE"]="Réunion";
|
||||
result["TK"]="Tokelau";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> parseTimezoneToAlpha2(std::string path)
|
||||
{
|
||||
std::unordered_map<std::string, std::string> result;
|
||||
//TODO: Clean solution...
|
||||
#include "zoneToAlpha.h"
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv )
|
||||
{
|
||||
if(argc != 6) {
|
||||
std::cout << "Wrong number of parameters\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
tzidToAlpha2 = parseTimezoneToAlpha2("TODO");
|
||||
|
||||
char tableType = argv[1][0];
|
||||
std::string path = argv[2];
|
||||
std::string outPath = argv[3];
|
||||
unsigned int precision = strtol(argv[4], NULL, 10);
|
||||
std::string notice = argv[5];
|
||||
|
||||
DBFHandle dataHandle = DBFOpen("naturalearth/ne_10m_admin_0_countries_lakes", "rb" );
|
||||
alpha2ToName = parseAlpha2ToName(dataHandle);
|
||||
DBFClose(dataHandle);
|
||||
|
||||
dataHandle = DBFOpen(path.c_str(), "rb" );
|
||||
if( dataHandle == NULL ) {
|
||||
errorFatal("Could not open attribute file\n");
|
||||
}
|
||||
|
||||
metadata_.resize(DBFGetRecordCount(dataHandle));
|
||||
std::cout << "Reading "<<metadata_.size()<<" metadata records.\n";
|
||||
|
||||
if(tableType == 'C') {
|
||||
readMetaDataNaturalEarthCountry(dataHandle);
|
||||
} else if(tableType == 'T') {
|
||||
readMetaDataTimezone(dataHandle);
|
||||
} else {
|
||||
std::cout << "Unknown table type\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
DBFClose(dataHandle);
|
||||
|
||||
SHPHandle shapeHandle = SHPOpen(path.c_str(), "rb");
|
||||
if( shapeHandle == NULL ) {
|
||||
errorFatal("Could not open shapefile\n");
|
||||
}
|
||||
|
||||
int numEntities, shapeType, totalPolygons = 0;
|
||||
SHPGetInfo(shapeHandle, &numEntities, &shapeType, NULL, NULL);
|
||||
|
||||
std::cout<<"Opened "<<SHPTypeName( shapeType )<< " file with "<<numEntities<<" entries.\n";
|
||||
|
||||
for(int i = 0; i < numEntities; i++ ) {
|
||||
SHPObject *shapeObject;
|
||||
|
||||
shapeObject = SHPReadObject( shapeHandle, i );
|
||||
if(shapeObject) {
|
||||
if(shapeObject->nSHPType != 3 && shapeObject->nSHPType != 5 &&
|
||||
shapeObject->nSHPType != 13 && shapeObject->nSHPType != 15) {
|
||||
std::cout<<"Unsupported shape object ("<< SHPTypeName(shapeObject->nSHPType) <<")\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
int partIndex = 0;
|
||||
|
||||
PolygonData* polygonData = nullptr;
|
||||
|
||||
for(int j = 0; j < shapeObject->nVertices; j++ ) {
|
||||
if(j == 0 || j == shapeObject->panPartStart[partIndex]) {
|
||||
totalPolygons++;
|
||||
|
||||
if(polygonData) {
|
||||
/* Commit it */
|
||||
polygons_.push_back(polygonData);
|
||||
}
|
||||
polygonData = new PolygonData(i);
|
||||
|
||||
if(partIndex + 1 < shapeObject->nParts) {
|
||||
partIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
Point p(shapeObject->padfY[j], shapeObject->padfX[j]);
|
||||
polygonData->processPoint(p);
|
||||
|
||||
}
|
||||
|
||||
if(polygonData) {
|
||||
/* Commit it */
|
||||
polygons_.push_back(polygonData);
|
||||
}
|
||||
|
||||
SHPDestroyObject(shapeObject);
|
||||
}
|
||||
}
|
||||
|
||||
SHPClose(shapeHandle);
|
||||
|
||||
std::cout<<"Parsed "<<totalPolygons<<" polygons.\n";
|
||||
|
||||
/* Sort according to bounding box */
|
||||
std::sort(polygons_.begin(), polygons_.end(), [](PolygonData* a, PolygonData* b) {
|
||||
return a->boundingMin.lat_ < b->boundingMin.lat_;
|
||||
});
|
||||
|
||||
/* Encode data section and store pointers */
|
||||
std::vector<uint8_t> outputData;
|
||||
for(PolygonData* polygon: polygons_) {
|
||||
polygon->fileIndex_ = outputData.size();
|
||||
polygon->encodeBinaryData(outputData, precision);
|
||||
}
|
||||
std::cout << "Encoded data section into "<<outputData.size()<<" bytes.\n";
|
||||
|
||||
/* Encode metadata */
|
||||
std::vector<uint8_t> outputMeta;
|
||||
for(MetaData& metadata: metadata_) {
|
||||
metadata.fileIndex_ = outputMeta.size();
|
||||
metadata.encodeBinaryData(outputMeta);
|
||||
}
|
||||
std::cout << "Encoded metadata into "<<outputMeta.size()<<" bytes.\n";
|
||||
|
||||
/* Encode bounding boxes */
|
||||
std::vector<uint8_t> outputBBox;
|
||||
int64_t prevFileIndex = 0;
|
||||
int64_t prevMetaIndex = 0;
|
||||
for(PolygonData* polygon: polygons_) {
|
||||
polygon->boundingMin.encodePointBinary(outputBBox, precision);
|
||||
polygon->boundingMax.encodePointBinary(outputBBox, precision);
|
||||
|
||||
encodeVariableLength(outputBBox, metadata_.at(polygon->metadataId_).fileIndex_ - prevMetaIndex);
|
||||
prevMetaIndex = metadata_[polygon->metadataId_].fileIndex_;
|
||||
|
||||
encodeVariableLength(outputBBox, polygon->fileIndex_ - prevFileIndex, false);
|
||||
prevFileIndex = polygon->fileIndex_;
|
||||
}
|
||||
std::cout << "Encoded bounding box section into "<<outputBBox.size()<<" bytes.\n";
|
||||
|
||||
/* Encode header */
|
||||
std::vector<uint8_t> outputHeader;
|
||||
outputHeader.push_back('P');
|
||||
outputHeader.push_back('L');
|
||||
outputHeader.push_back('B');
|
||||
outputHeader.push_back(tableType);
|
||||
outputHeader.push_back(0);
|
||||
outputHeader.push_back(precision);
|
||||
outputHeader.push_back(fieldNames_.size());
|
||||
for(unsigned int i=0; i<fieldNames_.size(); i++) {
|
||||
encodeStringToBinary(outputHeader, fieldNames_[i]);
|
||||
}
|
||||
encodeStringToBinary(outputHeader, notice);
|
||||
encodeVariableLength(outputHeader, outputBBox.size(), false);
|
||||
encodeVariableLength(outputHeader, outputMeta.size(), false);
|
||||
encodeVariableLength(outputHeader, outputData.size(), false);
|
||||
std::cout << "Encoded header into "<<outputHeader.size()<<" bytes.\n";
|
||||
|
||||
FILE* outputFile = fopen(outPath.c_str(), "wb");
|
||||
fwrite(outputHeader.data(), 1, outputHeader.size(), outputFile);
|
||||
fwrite(outputBBox.data(), 1, outputBBox.size(), outputFile);
|
||||
fwrite(outputMeta.data(), 1, outputMeta.size(), outputFile);
|
||||
fwrite(outputData.data(), 1, outputData.size(), outputFile);
|
||||
fclose(outputFile);
|
||||
|
||||
}
|
||||
21
database/builder/makedb.sh
Executable file
21
database/builder/makedb.sh
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
g++ builder.cpp -o builder -lshp
|
||||
|
||||
rm -rf out naturalearth timezone db.zip
|
||||
mkdir out
|
||||
mkdir naturalearth; cd naturalearth
|
||||
wget https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_0_countries_lakes.zip
|
||||
unzip ne_10m_admin_0_countries_lakes.zip
|
||||
cd ..
|
||||
./builder C naturalearth/ne_10m_admin_0_countries_lakes ./out/country16.bin 16 "Made with Natural Earth, placed in the Public Domain."
|
||||
./builder C naturalearth/ne_10m_admin_0_countries_lakes ./out/country21.bin 21 "Made with Natural Earth, placed in the Public Domain."
|
||||
|
||||
mkdir timezone; cd timezone
|
||||
wget https://github.com/evansiroky/timezone-boundary-builder/releases/download/2018i/timezones.shapefile.zip
|
||||
unzip timezones.shapefile.zip
|
||||
cd ..
|
||||
./builder T timezone/dist/combined-shapefile ./out/timezone16.bin 16 "Contains data from Natural Earth, placed in the Public Domain. Contains information from https://github.com/evansiroky/timezone-boundary-builder, which is made available here under the Open Database License (ODbL)."
|
||||
./builder T timezone/dist/combined-shapefile ./out/timezone21.bin 21 "Contains data from Natural Earth, placed in the Public Domain. Contains information from https://github.com/evansiroky/timezone-boundary-builder, which is made available here under the Open Database License (ODbL)."
|
||||
rm -rf naturalearth
|
||||
zip db.zip out/*
|
||||
425
database/builder/zoneToAlpha.h
Normal file
425
database/builder/zoneToAlpha.h
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
result["Europe/Andorra"] = "AD";
|
||||
result["Asia/Dubai"] = "AE";
|
||||
result["Asia/Kabul"] = "AF";
|
||||
result["America/Antigua"] = "AG";
|
||||
result["America/Anguilla"] = "AI";
|
||||
result["Europe/Tirane"] = "AL";
|
||||
result["Asia/Yerevan"] = "AM";
|
||||
result["Africa/Luanda"] = "AO";
|
||||
result["Antarctica/McMurdo"] = "AQ";
|
||||
result["Antarctica/Casey"] = "AQ";
|
||||
result["Antarctica/Davis"] = "AQ";
|
||||
result["Antarctica/DumontDUrville"] = "AQ";
|
||||
result["Antarctica/Mawson"] = "AQ";
|
||||
result["Antarctica/Palmer"] = "AQ";
|
||||
result["Antarctica/Rothera"] = "AQ";
|
||||
result["Antarctica/Syowa"] = "AQ";
|
||||
result["Antarctica/Troll"] = "AQ";
|
||||
result["Antarctica/Vostok"] = "AQ";
|
||||
result["America/Argentina/Buenos_Aires"] = "AR";
|
||||
result["America/Argentina/Cordoba"] = "AR";
|
||||
result["America/Argentina/Salta"] = "AR";
|
||||
result["America/Argentina/Jujuy"] = "AR";
|
||||
result["America/Argentina/Tucuman"] = "AR";
|
||||
result["America/Argentina/Catamarca"] = "AR";
|
||||
result["America/Argentina/La_Rioja"] = "AR";
|
||||
result["America/Argentina/San_Juan"] = "AR";
|
||||
result["America/Argentina/Mendoza"] = "AR";
|
||||
result["America/Argentina/San_Luis"] = "AR";
|
||||
result["America/Argentina/Rio_Gallegos"] = "AR";
|
||||
result["America/Argentina/Ushuaia"] = "AR";
|
||||
result["Pacific/Pago_Pago"] = "AS";
|
||||
result["Europe/Vienna"] = "AT";
|
||||
result["Australia/Lord_Howe"] = "AU";
|
||||
result["Antarctica/Macquarie"] = "AU";
|
||||
result["Australia/Hobart"] = "AU";
|
||||
result["Australia/Currie"] = "AU";
|
||||
result["Australia/Melbourne"] = "AU";
|
||||
result["Australia/Sydney"] = "AU";
|
||||
result["Australia/Broken_Hill"] = "AU";
|
||||
result["Australia/Brisbane"] = "AU";
|
||||
result["Australia/Lindeman"] = "AU";
|
||||
result["Australia/Adelaide"] = "AU";
|
||||
result["Australia/Darwin"] = "AU";
|
||||
result["Australia/Perth"] = "AU";
|
||||
result["Australia/Eucla"] = "AU";
|
||||
result["America/Aruba"] = "AW";
|
||||
result["Europe/Mariehamn"] = "AX";
|
||||
result["Asia/Baku"] = "AZ";
|
||||
result["Europe/Sarajevo"] = "BA";
|
||||
result["America/Barbados"] = "BB";
|
||||
result["Asia/Dhaka"] = "BD";
|
||||
result["Europe/Brussels"] = "BE";
|
||||
result["Africa/Ouagadougou"] = "BF";
|
||||
result["Europe/Sofia"] = "BG";
|
||||
result["Asia/Bahrain"] = "BH";
|
||||
result["Africa/Bujumbura"] = "BI";
|
||||
result["Africa/Porto-Novo"] = "BJ";
|
||||
result["America/St_Barthelemy"] = "BL";
|
||||
result["Atlantic/Bermuda"] = "BM";
|
||||
result["Asia/Brunei"] = "BN";
|
||||
result["America/La_Paz"] = "BO";
|
||||
result["America/Kralendijk"] = "BQ";
|
||||
result["America/Noronha"] = "BR";
|
||||
result["America/Belem"] = "BR";
|
||||
result["America/Fortaleza"] = "BR";
|
||||
result["America/Recife"] = "BR";
|
||||
result["America/Araguaina"] = "BR";
|
||||
result["America/Maceio"] = "BR";
|
||||
result["America/Bahia"] = "BR";
|
||||
result["America/Sao_Paulo"] = "BR";
|
||||
result["America/Campo_Grande"] = "BR";
|
||||
result["America/Cuiaba"] = "BR";
|
||||
result["America/Santarem"] = "BR";
|
||||
result["America/Porto_Velho"] = "BR";
|
||||
result["America/Boa_Vista"] = "BR";
|
||||
result["America/Manaus"] = "BR";
|
||||
result["America/Eirunepe"] = "BR";
|
||||
result["America/Rio_Branco"] = "BR";
|
||||
result["America/Nassau"] = "BS";
|
||||
result["Asia/Thimphu"] = "BT";
|
||||
result["Africa/Gaborone"] = "BW";
|
||||
result["Europe/Minsk"] = "BY";
|
||||
result["America/Belize"] = "BZ";
|
||||
result["America/St_Johns"] = "CA";
|
||||
result["America/Halifax"] = "CA";
|
||||
result["America/Glace_Bay"] = "CA";
|
||||
result["America/Moncton"] = "CA";
|
||||
result["America/Goose_Bay"] = "CA";
|
||||
result["America/Blanc-Sablon"] = "CA";
|
||||
result["America/Toronto"] = "CA";
|
||||
result["America/Nipigon"] = "CA";
|
||||
result["America/Thunder_Bay"] = "CA";
|
||||
result["America/Iqaluit"] = "CA";
|
||||
result["America/Pangnirtung"] = "CA";
|
||||
result["America/Atikokan"] = "CA";
|
||||
result["America/Winnipeg"] = "CA";
|
||||
result["America/Rainy_River"] = "CA";
|
||||
result["America/Resolute"] = "CA";
|
||||
result["America/Rankin_Inlet"] = "CA";
|
||||
result["America/Regina"] = "CA";
|
||||
result["America/Swift_Current"] = "CA";
|
||||
result["America/Edmonton"] = "CA";
|
||||
result["America/Cambridge_Bay"] = "CA";
|
||||
result["America/Yellowknife"] = "CA";
|
||||
result["America/Inuvik"] = "CA";
|
||||
result["America/Creston"] = "CA";
|
||||
result["America/Dawson_Creek"] = "CA";
|
||||
result["America/Fort_Nelson"] = "CA";
|
||||
result["America/Vancouver"] = "CA";
|
||||
result["America/Whitehorse"] = "CA";
|
||||
result["America/Dawson"] = "CA";
|
||||
result["Indian/Cocos"] = "CC";
|
||||
result["Africa/Kinshasa"] = "CD";
|
||||
result["Africa/Lubumbashi"] = "CD";
|
||||
result["Africa/Bangui"] = "CF";
|
||||
result["Africa/Brazzaville"] = "CG";
|
||||
result["Europe/Zurich"] = "CH";
|
||||
result["Africa/Abidjan"] = "CI";
|
||||
result["Pacific/Rarotonga"] = "CK";
|
||||
result["America/Santiago"] = "CL";
|
||||
result["America/Punta_Arenas"] = "CL";
|
||||
result["Pacific/Easter"] = "CL";
|
||||
result["Africa/Douala"] = "CM";
|
||||
result["Asia/Shanghai"] = "CN";
|
||||
result["Asia/Urumqi"] = "CN";
|
||||
result["America/Bogota"] = "CO";
|
||||
result["America/Costa_Rica"] = "CR";
|
||||
result["America/Havana"] = "CU";
|
||||
result["Atlantic/Cape_Verde"] = "CV";
|
||||
result["America/Curacao"] = "CW";
|
||||
result["Indian/Christmas"] = "CX";
|
||||
result["Asia/Nicosia"] = "CY";
|
||||
result["Asia/Famagusta"] = "CY";
|
||||
result["Europe/Prague"] = "CZ";
|
||||
result["Europe/Berlin"] = "DE";
|
||||
result["Europe/Busingen"] = "DE";
|
||||
result["Africa/Djibouti"] = "DJ";
|
||||
result["Europe/Copenhagen"] = "DK";
|
||||
result["America/Dominica"] = "DM";
|
||||
result["America/Santo_Domingo"] = "DO";
|
||||
result["Africa/Algiers"] = "DZ";
|
||||
result["America/Guayaquil"] = "EC";
|
||||
result["Pacific/Galapagos"] = "EC";
|
||||
result["Europe/Tallinn"] = "EE";
|
||||
result["Africa/Cairo"] = "EG";
|
||||
result["Africa/El_Aaiun"] = "EH";
|
||||
result["Africa/Asmara"] = "ER";
|
||||
result["Europe/Madrid"] = "ES";
|
||||
result["Africa/Ceuta"] = "ES";
|
||||
result["Atlantic/Canary"] = "ES";
|
||||
result["Africa/Addis_Ababa"] = "ET";
|
||||
result["Europe/Helsinki"] = "FI";
|
||||
result["Pacific/Fiji"] = "FJ";
|
||||
result["Atlantic/Stanley"] = "FK";
|
||||
result["Pacific/Chuuk"] = "FM";
|
||||
result["Pacific/Pohnpei"] = "FM";
|
||||
result["Pacific/Kosrae"] = "FM";
|
||||
result["Atlantic/Faroe"] = "FO";
|
||||
result["Europe/Paris"] = "FR";
|
||||
result["Africa/Libreville"] = "GA";
|
||||
result["Europe/London"] = "GB";
|
||||
result["America/Grenada"] = "GD";
|
||||
result["Asia/Tbilisi"] = "GE";
|
||||
result["America/Cayenne"] = "GF";
|
||||
result["Europe/Guernsey"] = "GG";
|
||||
result["Africa/Accra"] = "GH";
|
||||
result["Europe/Gibraltar"] = "GI";
|
||||
result["America/Godthab"] = "GL";
|
||||
result["America/Danmarkshavn"] = "GL";
|
||||
result["America/Scoresbysund"] = "GL";
|
||||
result["America/Thule"] = "GL";
|
||||
result["Africa/Banjul"] = "GM";
|
||||
result["Africa/Conakry"] = "GN";
|
||||
result["America/Guadeloupe"] = "GP";
|
||||
result["Africa/Malabo"] = "GQ";
|
||||
result["Europe/Athens"] = "GR";
|
||||
result["Atlantic/South_Georgia"] = "GS";
|
||||
result["America/Guatemala"] = "GT";
|
||||
result["Pacific/Guam"] = "GU";
|
||||
result["Africa/Bissau"] = "GW";
|
||||
result["America/Guyana"] = "GY";
|
||||
result["Asia/Hong_Kong"] = "HK";
|
||||
result["America/Tegucigalpa"] = "HN";
|
||||
result["Europe/Zagreb"] = "HR";
|
||||
result["America/Port-au-Prince"] = "HT";
|
||||
result["Europe/Budapest"] = "HU";
|
||||
result["Asia/Jakarta"] = "ID";
|
||||
result["Asia/Pontianak"] = "ID";
|
||||
result["Asia/Makassar"] = "ID";
|
||||
result["Asia/Jayapura"] = "ID";
|
||||
result["Europe/Dublin"] = "IE";
|
||||
result["Asia/Jerusalem"] = "IL";
|
||||
result["Europe/Isle_of_Man"] = "IM";
|
||||
result["Asia/Kolkata"] = "IN";
|
||||
result["Indian/Chagos"] = "IO";
|
||||
result["Asia/Baghdad"] = "IQ";
|
||||
result["Asia/Tehran"] = "IR";
|
||||
result["Atlantic/Reykjavik"] = "IS";
|
||||
result["Europe/Rome"] = "IT";
|
||||
result["Europe/Jersey"] = "JE";
|
||||
result["America/Jamaica"] = "JM";
|
||||
result["Asia/Amman"] = "JO";
|
||||
result["Asia/Tokyo"] = "JP";
|
||||
result["Africa/Nairobi"] = "KE";
|
||||
result["Asia/Bishkek"] = "KG";
|
||||
result["Asia/Phnom_Penh"] = "KH";
|
||||
result["Pacific/Tarawa"] = "KI";
|
||||
result["Pacific/Enderbury"] = "KI";
|
||||
result["Pacific/Kiritimati"] = "KI";
|
||||
result["Indian/Comoro"] = "KM";
|
||||
result["America/St_Kitts"] = "KN";
|
||||
result["Asia/Pyongyang"] = "KP";
|
||||
result["Asia/Seoul"] = "KR";
|
||||
result["Asia/Kuwait"] = "KW";
|
||||
result["America/Cayman"] = "KY";
|
||||
result["Asia/Almaty"] = "KZ";
|
||||
result["Asia/Qyzylorda"] = "KZ";
|
||||
result["Asia/Aqtobe"] = "KZ";
|
||||
result["Asia/Aqtau"] = "KZ";
|
||||
result["Asia/Atyrau"] = "KZ";
|
||||
result["Asia/Oral"] = "KZ";
|
||||
result["Asia/Vientiane"] = "LA";
|
||||
result["Asia/Beirut"] = "LB";
|
||||
result["America/St_Lucia"] = "LC";
|
||||
result["Europe/Vaduz"] = "LI";
|
||||
result["Asia/Colombo"] = "LK";
|
||||
result["Africa/Monrovia"] = "LR";
|
||||
result["Africa/Maseru"] = "LS";
|
||||
result["Europe/Vilnius"] = "LT";
|
||||
result["Europe/Luxembourg"] = "LU";
|
||||
result["Europe/Riga"] = "LV";
|
||||
result["Africa/Tripoli"] = "LY";
|
||||
result["Africa/Casablanca"] = "MA";
|
||||
result["Europe/Monaco"] = "MC";
|
||||
result["Europe/Chisinau"] = "MD";
|
||||
result["Europe/Podgorica"] = "ME";
|
||||
result["America/Marigot"] = "MF";
|
||||
result["Indian/Antananarivo"] = "MG";
|
||||
result["Pacific/Majuro"] = "MH";
|
||||
result["Pacific/Kwajalein"] = "MH";
|
||||
result["Europe/Skopje"] = "MK";
|
||||
result["Africa/Bamako"] = "ML";
|
||||
result["Asia/Yangon"] = "MM";
|
||||
result["Asia/Ulaanbaatar"] = "MN";
|
||||
result["Asia/Hovd"] = "MN";
|
||||
result["Asia/Choibalsan"] = "MN";
|
||||
result["Asia/Macau"] = "MO";
|
||||
result["Pacific/Saipan"] = "MP";
|
||||
result["America/Martinique"] = "MQ";
|
||||
result["Africa/Nouakchott"] = "MR";
|
||||
result["America/Montserrat"] = "MS";
|
||||
result["Europe/Malta"] = "MT";
|
||||
result["Indian/Mauritius"] = "MU";
|
||||
result["Indian/Maldives"] = "MV";
|
||||
result["Africa/Blantyre"] = "MW";
|
||||
result["America/Mexico_City"] = "MX";
|
||||
result["America/Cancun"] = "MX";
|
||||
result["America/Merida"] = "MX";
|
||||
result["America/Monterrey"] = "MX";
|
||||
result["America/Matamoros"] = "MX";
|
||||
result["America/Mazatlan"] = "MX";
|
||||
result["America/Chihuahua"] = "MX";
|
||||
result["America/Ojinaga"] = "MX";
|
||||
result["America/Hermosillo"] = "MX";
|
||||
result["America/Tijuana"] = "MX";
|
||||
result["America/Bahia_Banderas"] = "MX";
|
||||
result["Asia/Kuala_Lumpur"] = "MY";
|
||||
result["Asia/Qostanay"] = "KZ";
|
||||
result["Asia/Kuching"] = "MY";
|
||||
result["Africa/Maputo"] = "MZ";
|
||||
result["Africa/Windhoek"] = "NA";
|
||||
result["Pacific/Noumea"] = "NC";
|
||||
result["Africa/Niamey"] = "NE";
|
||||
result["Pacific/Norfolk"] = "NF";
|
||||
result["Africa/Lagos"] = "NG";
|
||||
result["America/Managua"] = "NI";
|
||||
result["Europe/Amsterdam"] = "NL";
|
||||
result["Europe/Oslo"] = "NO";
|
||||
result["Asia/Kathmandu"] = "NP";
|
||||
result["Pacific/Nauru"] = "NR";
|
||||
result["Pacific/Niue"] = "NU";
|
||||
result["Pacific/Auckland"] = "NZ";
|
||||
result["Pacific/Chatham"] = "NZ";
|
||||
result["Asia/Muscat"] = "OM";
|
||||
result["America/Panama"] = "PA";
|
||||
result["America/Lima"] = "PE";
|
||||
result["Pacific/Tahiti"] = "PF";
|
||||
result["Pacific/Marquesas"] = "PF";
|
||||
result["Pacific/Gambier"] = "PF";
|
||||
result["Pacific/Port_Moresby"] = "PG";
|
||||
result["Pacific/Bougainville"] = "PG";
|
||||
result["Asia/Manila"] = "PH";
|
||||
result["Asia/Karachi"] = "PK";
|
||||
result["Europe/Warsaw"] = "PL";
|
||||
result["America/Miquelon"] = "PM";
|
||||
result["Pacific/Pitcairn"] = "PN";
|
||||
result["America/Puerto_Rico"] = "PR";
|
||||
result["Asia/Gaza"] = "PS";
|
||||
result["Asia/Hebron"] = "PS";
|
||||
result["Europe/Lisbon"] = "PT";
|
||||
result["Atlantic/Madeira"] = "PT";
|
||||
result["Atlantic/Azores"] = "PT";
|
||||
result["Pacific/Palau"] = "PW";
|
||||
result["America/Asuncion"] = "PY";
|
||||
result["Asia/Qatar"] = "QA";
|
||||
result["Indian/Reunion"] = "RE";
|
||||
result["Europe/Bucharest"] = "RO";
|
||||
result["Europe/Belgrade"] = "RS";
|
||||
result["Europe/Kaliningrad"] = "RU";
|
||||
result["Europe/Moscow"] = "RU";
|
||||
result["Europe/Simferopol"] = "RU";
|
||||
result["Europe/Volgograd"] = "RU";
|
||||
result["Europe/Kirov"] = "RU";
|
||||
result["Europe/Astrakhan"] = "RU";
|
||||
result["Europe/Saratov"] = "RU";
|
||||
result["Europe/Ulyanovsk"] = "RU";
|
||||
result["Europe/Samara"] = "RU";
|
||||
result["Asia/Yekaterinburg"] = "RU";
|
||||
result["Asia/Omsk"] = "RU";
|
||||
result["Asia/Novosibirsk"] = "RU";
|
||||
result["Asia/Barnaul"] = "RU";
|
||||
result["Asia/Tomsk"] = "RU";
|
||||
result["Asia/Novokuznetsk"] = "RU";
|
||||
result["Asia/Krasnoyarsk"] = "RU";
|
||||
result["Asia/Irkutsk"] = "RU";
|
||||
result["Asia/Chita"] = "RU";
|
||||
result["Asia/Yakutsk"] = "RU";
|
||||
result["Asia/Khandyga"] = "RU";
|
||||
result["Asia/Vladivostok"] = "RU";
|
||||
result["Asia/Ust-Nera"] = "RU";
|
||||
result["Asia/Magadan"] = "RU";
|
||||
result["Asia/Sakhalin"] = "RU";
|
||||
result["Asia/Srednekolymsk"] = "RU";
|
||||
result["Asia/Kamchatka"] = "RU";
|
||||
result["Asia/Anadyr"] = "RU";
|
||||
result["Africa/Kigali"] = "RW";
|
||||
result["Asia/Riyadh"] = "SA";
|
||||
result["Pacific/Guadalcanal"] = "SB";
|
||||
result["Indian/Mahe"] = "SC";
|
||||
result["Africa/Khartoum"] = "SD";
|
||||
result["Europe/Stockholm"] = "SE";
|
||||
result["Asia/Singapore"] = "SG";
|
||||
result["Atlantic/St_Helena"] = "SH";
|
||||
result["Europe/Ljubljana"] = "SI";
|
||||
result["Arctic/Longyearbyen"] = "SJ";
|
||||
result["Europe/Bratislava"] = "SK";
|
||||
result["Africa/Freetown"] = "SL";
|
||||
result["Europe/San_Marino"] = "SM";
|
||||
result["Africa/Dakar"] = "SN";
|
||||
result["Africa/Mogadishu"] = "SO";
|
||||
result["America/Paramaribo"] = "SR";
|
||||
result["Africa/Juba"] = "SS";
|
||||
result["Africa/Sao_Tome"] = "ST";
|
||||
result["America/El_Salvador"] = "SV";
|
||||
result["America/Lower_Princes"] = "SX";
|
||||
result["Asia/Damascus"] = "SY";
|
||||
result["Africa/Mbabane"] = "SZ";
|
||||
result["America/Grand_Turk"] = "TC";
|
||||
result["Africa/Ndjamena"] = "TD";
|
||||
result["Indian/Kerguelen"] = "TF";
|
||||
result["Africa/Lome"] = "TG";
|
||||
result["Asia/Bangkok"] = "TH";
|
||||
result["Asia/Dushanbe"] = "TJ";
|
||||
result["Pacific/Fakaofo"] = "TK";
|
||||
result["Asia/Dili"] = "TL";
|
||||
result["Asia/Ashgabat"] = "TM";
|
||||
result["Africa/Tunis"] = "TN";
|
||||
result["Pacific/Tongatapu"] = "TO";
|
||||
result["Europe/Istanbul"] = "TR";
|
||||
result["America/Port_of_Spain"] = "TT";
|
||||
result["Pacific/Funafuti"] = "TV";
|
||||
result["Asia/Taipei"] = "TW";
|
||||
result["Africa/Dar_es_Salaam"] = "TZ";
|
||||
result["Europe/Kiev"] = "UA";
|
||||
result["Europe/Uzhgorod"] = "UA";
|
||||
result["Europe/Zaporozhye"] = "UA";
|
||||
result["Africa/Kampala"] = "UG";
|
||||
result["Pacific/Midway"] = "UM";
|
||||
result["Pacific/Wake"] = "UM";
|
||||
result["America/New_York"] = "US";
|
||||
result["America/Detroit"] = "US";
|
||||
result["America/Kentucky/Louisville"] = "US";
|
||||
result["America/Kentucky/Monticello"] = "US";
|
||||
result["America/Indiana/Indianapolis"] = "US";
|
||||
result["America/Indiana/Vincennes"] = "US";
|
||||
result["America/Indiana/Winamac"] = "US";
|
||||
result["America/Indiana/Marengo"] = "US";
|
||||
result["America/Indiana/Petersburg"] = "US";
|
||||
result["America/Indiana/Vevay"] = "US";
|
||||
result["America/Chicago"] = "US";
|
||||
result["America/Indiana/Tell_City"] = "US";
|
||||
result["America/Indiana/Knox"] = "US";
|
||||
result["America/Menominee"] = "US";
|
||||
result["America/North_Dakota/Center"] = "US";
|
||||
result["America/North_Dakota/New_Salem"] = "US";
|
||||
result["America/North_Dakota/Beulah"] = "US";
|
||||
result["America/Denver"] = "US";
|
||||
result["America/Boise"] = "US";
|
||||
result["America/Phoenix"] = "US";
|
||||
result["America/Los_Angeles"] = "US";
|
||||
result["America/Anchorage"] = "US";
|
||||
result["America/Juneau"] = "US";
|
||||
result["America/Sitka"] = "US";
|
||||
result["America/Metlakatla"] = "US";
|
||||
result["America/Yakutat"] = "US";
|
||||
result["America/Nome"] = "US";
|
||||
result["America/Adak"] = "US";
|
||||
result["Pacific/Honolulu"] = "US";
|
||||
result["America/Montevideo"] = "UY";
|
||||
result["Asia/Samarkand"] = "UZ";
|
||||
result["Asia/Tashkent"] = "UZ";
|
||||
result["Europe/Vatican"] = "VA";
|
||||
result["America/St_Vincent"] = "VC";
|
||||
result["America/Caracas"] = "VE";
|
||||
result["America/Tortola"] = "VG";
|
||||
result["America/St_Thomas"] = "VI";
|
||||
result["Asia/Ho_Chi_Minh"] = "VN";
|
||||
result["Pacific/Efate"] = "VU";
|
||||
result["Pacific/Wallis"] = "WF";
|
||||
result["Pacific/Apia"] = "WS";
|
||||
result["Asia/Aden"] = "YE";
|
||||
result["Indian/Mayotte"] = "YT";
|
||||
result["Africa/Johannesburg"] = "ZA";
|
||||
result["Africa/Lusaka"] = "ZM";
|
||||
result["Africa/Harare"] = "ZW";
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue