#ifndef FM_ADDRESS_H #define FM_ADDRESS_H #if (USE_JP_ADDRESS) #include #include #include #define USE_ADDR_DB_TYPE 1 // // _maxLenPref: 4 _maxLenCity: 8 _maxLenChome: 12 #define MAX_JA_AREA_NAME_LEN 30 #define MAX_PREF_COUNT 50 // 도도부현 개수 #define MAX_CITY_COUNT 200 // 도도부현당 최대 시/구 개수, "北海道" 52, "大阪府" 64 #if (USE_ADDR_DB_TYPE == 0) #define MAX_JIBUN_COUNT 4000 // 3381 #define MAX_CHOME_COUNT 1500 // 시/구당 최대 마을 개수 旭川市 1475 #elif (USE_ADDR_DB_TYPE == 1) #define MAX_JIBUN_COUNT 20000 // 20000 #define MAX_CHOME_COUNT 5000 // 福島県, 시/구당 최대 마을 개수 旭川市 1475 #endif typedef struct _JA_HEADER { char header[128]; // 0 char date[24]; // 128 char version[24]; // 152 uint32_t stringSize; // 176 문자열 테이블 크기 //uint32_t prefOffset; // 180 도도부현 시작 옵셋 (=sizeof header + stringSize) + .... uint32_t pref_count; // 184 pref 개수 uint32_t city_count; // 188 전체 city 개수 uint32_t town_count; // 192 전체 town 개수 uint32_t jibun_count; // 196 전체 지번 개수 int32_t xmin; // 영역.. int32_t ymin; int32_t xmax; int32_t ymax; } JA_HEADER; // 저장용 구조체 typedef struct _JA_AREA_PACKET { uint32_t nameOffset; uint32_t sub_count; uint32_t sub_offset; int32_t xmin; int32_t ymin; int32_t xmax; int32_t ymax; uint8_t bits[4]; // CHOME 만 사용 (BITS X,Y,A0,A1) } JA_AREA_PACKET; #if (USE_JP_ADDRESS_TOOL) // 주소(지번) -> 처리용 구조체 typedef struct _JA_JIBUN { uint16_t a0; // 150 : 8bit uint16_t a1; // 732 : 10bit int32_t x; int32_t y; } JA_JIBUN; // 12BYTE // 도도부현,시구,마을(丁目) -> 처리용 구조체 typedef struct _JA_AREA { ushort name[MAX_JA_AREA_NAME_LEN]; // 16(12 * 2) int32_t count; // sub area(or a) count _JA_AREA* subAreas; _JA_JIBUN* subJibuns; uint32_t offset; // sub area offset // or Pointer int32_t xmin; int32_t ymin; int32_t xmax; int32_t ymax; uint32_t nameOffset; uint16_t a0min; // BYTE PACK 계산하기 위해 사용 uint16_t a0max; uint16_t a1min; uint16_t a1max; uint8_t bits[4]; // CHOME 의 경우 포함된 지번 데이터의 BIT PACK } JA_AREA; #endif // #if (USE_JP_ADDRESS_TOOL) // 北海道 深川市 一条 (3066,1474) // 神奈川県 横浜市鶴見区 大黒町 (879,2625) // XMAX: 12bit, YMAX:12bit, // a0: // 150 : 8bit // a1: // 732 : 10bit class FMAddress { private: // 탐색 결과 int _found_a0; int _found_a1; int _found_dist_sq; // 거리^2 int _found_x; int _found_y; JA_HEADER _header; // 헤더 JA_AREA_PACKET* _areas; // 도도부현, 시구군, 읍면동.. uint8_t* _strings; // 문자열 " FILE* _file; // TOWN내에서 가장 가까운 지번 탐색 town, x,y (return dist, a0:대번지, a1:소번지) bool _searchTown(JA_AREA_PACKET* town,int x, int y,int tolerance); public: FMAddress(); ~FMAddress(); static FMAddress* instance() { static FMAddress * _instance = 0; if ( _instance == 0 ) { _instance = new FMAddress(); } return _instance; } bool isOpened() { return (_areas != NULL && _strings != NULL && _file != NULL); } bool open(); // 파일열기 (실행파일경로 or 테스트 경로) bool open(QString path); // 파일열기 // 탐색 (경위도, 도도부현, 시구군, 읍면동, 탐색거리, 허용 오차m) bool search(double lon,double lat,wchar_t** pref,wchar_t** city,wchar_t** town,int* a0, int*a1, int* pdist, int tolerance = 200); // 탐색 결과 도도부현,시군구,읍면동,번지,호,거리 bool search(double lon, double lat,QStringList& result, int tolerance = 200); #if (USE_JP_ADDRESS_TOOL) void debugList(); // 디버그 void _debugTown(JA_AREA_PACKET* town); // public: bool convert(QString src, QString target); bool verify(QString src); // TXT 데이터와 비교 // CODE,PREF,CITY,CHOME,A0,A1,LON,LAT,CDATE static QMap _stringTable; private: static void _updateBound(_JA_AREA* dest, _JA_AREA* src); static void _updateBoundP(_JA_AREA* dest, _JA_JIBUN* src); static void _initBound(_JA_AREA* dest); static void _calculateBitPack(_JA_AREA * src); // , uint8_t* byte static void _copyPacket(JA_AREA_PACKET* dest, JA_AREA* src); void _freeConvertData(); void _resizeChome(JA_AREA* chome); // MAX 크기로 할당된 지번을 원래 개수대로 변경 void _createStatCSV(); // 통계 생성 void _saveData(); void _saveStringTable(); void _savePref(); // 도도부현 저장 void _sortJIBUN(JA_AREA* chome); // 지번 XY 순으로 정렬 bool _packJibun(JA_AREA* town,uint8_t* buffer,uint32_t* offset); // 지번 BIT PACK uint32_t _totalJibunBytes; // 전체 지번 할당 데이터 uint32_t _writeOffset; // 현재 파일 포인터 FILE* _outFile; // 파일 uint32_t _totalStringBufferLength; // 전체 문자열 버퍼 크기(중복제거) uint32_t _totalStringLength; // 전체 문자열 크기 uint32_t _currentStringOffset; // 현재 문자열 버퍼 옵셋 void _setStringOffset(JA_AREA* area,QString name); // 문자열 추가 + 옵셋처리 // 현재 처리중인 도도부현,... QString _currentPrefName; QString _currentCityName; QString _currentChomeName; JA_AREA* _prefs; // 도도부현 저장 JA_AREA* _currentPref; // 현재 도도부현 JA_AREA* _currentCity; // " 시군구 JA_AREA* _currentChome; // " 마을 JA_JIBUN* _currentJibun; // " 지번 int _maxLenPref; // 통계 확인용 int _maxLenCity; // " int _maxLenChome; // " int _maxA0; // " 지번 대번지 최대값 int _maxA1; // " " 소번지 #endif // USE_JP_ADDRESS_TOOL }; #endif // USE_JP_ADDRESS #endif // FM_ADDRESS_H