1+ package io .patamon .geocoding .region ;
2+
3+ import java .io .ByteArrayInputStream ;
4+ import java .io .ByteArrayOutputStream ;
5+ import java .io .File ;
6+ import java .io .IOException ;
7+ import java .sql .Connection ;
8+ import java .util .Base64 ;
9+ import java .util .List ;
10+ import java .util .zip .GZIPInputStream ;
11+ import java .util .zip .GZIPOutputStream ;
12+
13+ import org .apache .commons .io .IOUtils ;
14+
15+ import com .google .common .collect .Lists ;
16+ import com .google .common .io .Files ;
17+ import com .google .gson .Gson ;
18+
19+ import io .patamon .geocoding .model .RegionType ;
20+ import io .patamon .geocoding .region .model .RegionEntity ;
21+ import io .patamon .geocoding .region .util .JdbcUtil ;
22+ import kotlin .text .Charsets ;
23+
24+ public class RegionDatFileHelper {
25+
26+ final static List <String > provinceLevelCity1 = Lists .newArrayList ("北京市" , "天津市" , "上海市" , "重庆市" );
27+
28+ public static void writeDatFile (String pathname ) throws IOException {
29+ Connection conn = JdbcUtil .getConnection ();
30+ if (conn == null ) return ;
31+ List <RegionEntity > china = Lists .newArrayList ();
32+ List <RegionEntity > provinces = RegionSqlHelper .findProvinces (conn );
33+ for (int i = 0 ; i < provinces .size (); i ++) {
34+ RegionEntity province = provinces .get (i );
35+ List <RegionEntity > list = RegionSqlHelper .findByProvince (conn , province .getShortName () + "%" );
36+ if (i == 0 ) {
37+ List <RegionEntity > tree = parseProvince (list );
38+ china .add (tree .get (0 ));
39+ } else {
40+ List <RegionEntity > tree = parseProvince (list );
41+ china .get (0 ).getChildren ().add (tree .get (0 ));
42+ }
43+ }
44+ JdbcUtil .free (conn );
45+ Gson gson = new Gson ();
46+
47+ byte [] context = encode (gson .toJson (china .get (0 )));
48+ write (pathname , new String (context , Charsets .UTF_8 ));
49+ }
50+
51+ private static List <RegionEntity > parseProvince (List <RegionEntity > list ) {
52+ List <RegionEntity > province = Lists .newArrayList ();
53+
54+ for (RegionEntity entity : list ) {
55+ if (entity .getParentId ().equals (0L )) {
56+ if (entity .getChildren () == null ) entity .setChildren (Lists .newArrayList ());
57+ entity .setType (of (entity .getId (), entity .getLevel (), entity .getName ()));
58+ province .add (entity );
59+ }
60+ }
61+
62+ for (RegionEntity item : province ) {
63+ item = recursive (item , list , province .size ());
64+ }
65+
66+ return province ;
67+ }
68+
69+ private static RegionEntity recursive (RegionEntity parent , List <RegionEntity > list , int j ) {
70+ for (int i = j ; i < list .size (); i ++) {
71+ RegionEntity entity = list .get (i );
72+ if (parent .getId ().equals (entity .getParentId ())) {
73+ entity = recursive (entity , list , i + 1 );
74+ entity .setType (of (entity .getId (), entity .getLevel (), entity .getName ()));
75+ if (parent .getChildren () == null ) parent .setChildren (Lists .newArrayList ());
76+ parent .getChildren ().add (entity );
77+ }
78+ }
79+ return parent ;
80+ }
81+
82+ private static void write (final String fileName , final String contents ) throws IOException {
83+ File file = new File (fileName );
84+ file .deleteOnExit ();
85+ file .createNewFile ();
86+ Files .write (contents .getBytes (), file );
87+ }
88+
89+ private static RegionType of (Long id , int level , String name ) {
90+ if (id .equals (100000000000L )) return RegionType .Country ;
91+ if (level == 0 ) {
92+ if (provinceLevelCity1 .contains (name )) return RegionType .ProvinceLevelCity1 ;
93+ return RegionType .Province ;
94+ }
95+ if (level == 1 ) {
96+ if ("直辖区" .equalsIgnoreCase (name )) return RegionType .ProvinceLevelCity2 ;
97+ if ("直辖县" .equalsIgnoreCase (name )) return RegionType .CityLevelDistrict ;
98+ return RegionType .City ;
99+ }
100+ if (level == 2 ) return RegionType .District ;
101+ if (level == 3 ) {
102+ if (name .matches ("乡$" )) return RegionType .Town ;
103+ if (name .matches ("镇$" )) return RegionType .Town ;
104+ return RegionType .PlatformL4 ;
105+ }
106+ if (level == 4 ) return RegionType .Village ;
107+ return RegionType .Undefined ;
108+ }
109+
110+ public static RegionEntity readDatFile (String file ) throws IOException {
111+ byte [] byteArray = Files .toByteArray (new File (file ));
112+ String json = new String (byteArray );
113+ return new Gson ().fromJson (decode (json ), RegionEntity .class );
114+ }
115+
116+ private static String decode (String str ) throws IOException {
117+ byte decodedByteArray [] = Base64 .getMimeDecoder ().decode (str );
118+ GZIPInputStream gzipis = new GZIPInputStream (new ByteArrayInputStream (decodedByteArray ));
119+ return new String (IOUtils .toByteArray (gzipis ), Charsets .UTF_8 );
120+ }
121+
122+ private static byte [] encode (String str ) throws IOException {
123+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
124+ GZIPOutputStream gzipos = new GZIPOutputStream (out );
125+ gzipos .write (str .getBytes (Charsets .UTF_8 ));
126+ gzipos .close ();
127+ return Base64 .getMimeEncoder ().encode (out .toByteArray ());
128+ }
129+ }
0 commit comments