@isofh/chuyen-doi-dia-chi-2-cap 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,12 +63,13 @@ console.log(splitResult);
63
63
 
64
64
  - chuỗi địa chỉ hành chính, ví dụ `"Xuân Thành, Xuân Lộc, Đồng Nai"`
65
65
  - hoặc mảng các phần tử địa chỉ, ví dụ `['Xuân Thành', 'Xuân Lộc', 'Đồng Nai']`
66
+ - ngoài ra hàm cũng cố gắng tự bóc đuôi hành chính nếu input có kèm `số nhà, tên đường, quốc gia...`
66
67
 
67
68
  ## Lưu ý quan trọng
68
69
 
69
- Hàm này chỉ xử lý phần địa chỉ hành chính.
70
+ Hàm này ưu tiên xử lý phần địa chỉ hành chính.
70
71
 
71
- Nếu input gốc có cả số nhà, tên đường, khu phố..., caller nên tách phần hành chính trước khi gọi hàm này.
72
+ Nếu input gốc có cả số nhà, tên đường, khu phố..., hàm sẽ cố gắng nhận diện đuôi hành chính hợp lệ để convert. Dù vậy, trong các case nhập liệu quá nhiễu hoặc thiếu tỉnh/xã rõ ràng, caller vẫn nên tách phần hành chính trước khi gọi để đảm bảo độ chính xác cao nhất.
72
73
 
73
74
  Ví dụ:
74
75
 
package/dataXa.json CHANGED
@@ -24414,10 +24414,14 @@
24414
24414
  "ten": "Thủ Dầu Một",
24415
24415
  "timKiem": "thudaumot",
24416
24416
  "satNhapTu": [
24417
- { "ten": "Phú Cường", "timKiem": "phucuong" },
24418
- { "ten": "Phú Thọ", "timKiem": "phutho" },
24419
- { "ten": "Chánh Nghĩa", "timKiem": "chanhnghia" },
24420
- { "ten": "Hiệp Thành", "timKiem": "hiepthanh" },
24417
+ { "ten": "Phú Cường", "timKiem": "phucuong", "huyen": "thudaumot" },
24418
+ { "ten": "Phú Thọ", "timKiem": "phutho", "huyen": "thudaumot" },
24419
+ {
24420
+ "ten": "Chánh Nghĩa",
24421
+ "timKiem": "chanhnghia",
24422
+ "huyen": "thudaumot"
24423
+ },
24424
+ { "ten": "Hiệp Thành", "timKiem": "hiepthanh", "huyen": "thudaumot" },
24421
24425
  { "ten": "Chánh Mỹ", "timKiem": "chanhmy" }
24422
24426
  ]
24423
24427
  },
@@ -24757,6 +24761,9 @@
24757
24761
  "timKiem": "chanhhung",
24758
24762
  "satNhapTu": [
24759
24763
  { "ten": "4", "timKiem": "4", "huyen": "8" },
24764
+ { "ten": "1", "timKiem": "1", "huyen": "8" },
24765
+ { "ten": "2", "timKiem": "2", "huyen": "8" },
24766
+ { "ten": "3", "timKiem": "3", "huyen": "8" },
24760
24767
  { "ten": "Rạch Ông", "timKiem": "rachong" },
24761
24768
  { "ten": "Hưng Phú", "timKiem": "hungphu" },
24762
24769
  { "ten": "5", "timKiem": "5", "huyen": "8" }
@@ -24869,7 +24876,7 @@
24869
24876
  "ten": "Tân Thới Hiệp",
24870
24877
  "timKiem": "tanthoihiep",
24871
24878
  "satNhapTu": [
24872
- { "ten": "Hiệp Thành", "timKiem": "hiepthanh" },
24879
+ { "ten": "Hiệp Thành", "timKiem": "hiepthanh", "huyen": "12" },
24873
24880
  { "ten": "Tân Thới Hiệp", "timKiem": "tanthoihiep" }
24874
24881
  ]
24875
24882
  },
@@ -24950,7 +24957,7 @@
24950
24957
  "satNhapTu": [
24951
24958
  { "ten": "12", "timKiem": "12", "huyen": "binhthanh" },
24952
24959
  { "ten": "14", "timKiem": "14", "huyen": "binhthanh" },
24953
- { "ten": "26", "timKiem": "26" }
24960
+ { "ten": "26", "timKiem": "26", "huyen": "binhthanh" }
24954
24961
  ]
24955
24962
  },
24956
24963
  {
@@ -24966,17 +24973,17 @@
24966
24973
  "ten": "Thạnh Mỹ Tây",
24967
24974
  "timKiem": "thanhmytay",
24968
24975
  "satNhapTu": [
24969
- { "ten": "19", "timKiem": "19" },
24970
- { "ten": "22", "timKiem": "22" },
24971
- { "ten": "25", "timKiem": "25" }
24976
+ { "ten": "19", "timKiem": "19", "huyen": "binhthanh" },
24977
+ { "ten": "22", "timKiem": "22", "huyen": "binhthanh" },
24978
+ { "ten": "25", "timKiem": "25", "huyen": "binhthanh" }
24972
24979
  ]
24973
24980
  },
24974
24981
  {
24975
24982
  "ten": "Bình Quới",
24976
24983
  "timKiem": "binhquoi",
24977
24984
  "satNhapTu": [
24978
- { "ten": "27", "timKiem": "27" },
24979
- { "ten": "28", "timKiem": "28" }
24985
+ { "ten": "27", "timKiem": "27", "huyen": "binhthanh" },
24986
+ { "ten": "28", "timKiem": "28", "huyen": "binhthanh" }
24980
24987
  ]
24981
24988
  },
24982
24989
  {
@@ -25292,11 +25299,11 @@
25292
25299
  "ten": "Tân Nhựt",
25293
25300
  "timKiem": "tannhut",
25294
25301
  "satNhapTu": [
25295
- { "ten": "Tân Túc", "timKiem": "tantuc" },
25296
- { "ten": "Tân Nhựt", "timKiem": "tannhut" },
25297
- { "ten": "Tân Tạo A", "timKiem": "tantaoa" },
25298
- { "ten": "Tân Kiên", "timKiem": "tankien" },
25299
- { "ten": "16", "timKiem": "16" }
25302
+ { "ten": "Tân Túc", "timKiem": "tantuc", "huyen": "binhchanh" },
25303
+ { "ten": "Tân Nhựt", "timKiem": "tannhut", "huyen": "binhchanh" },
25304
+ { "ten": "Tân Tạo A", "timKiem": "tantaoa", "huyen": "binhtan" },
25305
+ { "ten": "Tân Kiên", "timKiem": "tankien", "huyen": "binhchanh" },
25306
+ { "ten": "16", "timKiem": "16", "huyen": "8" }
25300
25307
  ]
25301
25308
  },
25302
25309
  {
@@ -25322,9 +25329,9 @@
25322
25329
  "ten": "Bình Hưng",
25323
25330
  "timKiem": "binhhung",
25324
25331
  "satNhapTu": [
25325
- { "ten": "Phong Phú", "timKiem": "phongphu" },
25326
- { "ten": "Bình Hưng", "timKiem": "binhhung" },
25327
- { "ten": "7", "timKiem": "7" }
25332
+ { "ten": "Phong Phú", "timKiem": "phongphu", "huyen": "binhchanh" },
25333
+ { "ten": "Bình Hưng", "timKiem": "binhhung", "huyen": "binhchanh" },
25334
+ { "ten": "7", "timKiem": "7", "huyen": "8" }
25328
25335
  ]
25329
25336
  },
25330
25337
  {
@@ -25712,84 +25719,90 @@
25712
25719
  {
25713
25720
  "ten": "Đặc khu Côn Đảo",
25714
25721
  "timKiem": "dackhucondao",
25715
- "satNhapTu": [{ "ten": "Huyện Côn Đảo", "timKiem": "huyencondao" }]
25722
+ "satNhapTu": [
25723
+ { "ten": "Huyện Côn Đảo", "timKiem": "huyencondao" },
25724
+ { "ten": "Côn Đảo", "timKiem": "condao" }
25725
+ ]
25716
25726
  },
25717
25727
  {
25718
25728
  "ten": "Bàn Cờ",
25719
25729
  "timKiem": "banco",
25720
25730
  "satNhapTu": [
25721
- { "ten": "1", "timKiem": "1" },
25722
- { "ten": "2", "timKiem": "2" },
25723
- { "ten": "3", "timKiem": "3" },
25724
- { "ten": "5", "timKiem": "5" },
25725
- { "ten": "4", "timKiem": "4" }
25731
+ { "ten": "1", "timKiem": "1", "huyen": "3" },
25732
+ { "ten": "2", "timKiem": "2", "huyen": "3" },
25733
+ { "ten": "3", "timKiem": "3", "huyen": "3" },
25734
+ { "ten": "5", "timKiem": "5", "huyen": "3" },
25735
+ { "ten": "4", "timKiem": "4", "huyen": "3" }
25726
25736
  ]
25727
25737
  },
25728
25738
  {
25729
25739
  "ten": "Xuân Hòa",
25730
25740
  "timKiem": "xuanhoa",
25731
25741
  "satNhapTu": [
25732
- { "ten": "Võ Thị Sáu", "timKiem": "vothisau" },
25733
- { "ten": "4", "timKiem": "4" }
25742
+ { "ten": "Võ Thị Sáu", "timKiem": "vothisau", "huyen": "3" },
25743
+ { "ten": "4", "timKiem": "4", "huyen": "3" },
25744
+ { "ten": "6", "timKiem": "6", "huyen": "3" },
25745
+ { "ten": "7", "timKiem": "7", "huyen": "3" },
25746
+ { "ten": "8", "timKiem": "8", "huyen": "3" }
25734
25747
  ]
25735
25748
  },
25736
25749
  {
25737
25750
  "ten": "Nhiêu Lộc",
25738
25751
  "timKiem": "nhieuloc",
25739
25752
  "satNhapTu": [
25740
- { "ten": "9", "timKiem": "9" },
25741
- { "ten": "11", "timKiem": "11" },
25753
+ { "ten": "9", "timKiem": "9", "huyen": "3" },
25754
+ { "ten": "11", "timKiem": "11", "huyen": "3" },
25742
25755
  { "ten": "12", "timKiem": "12", "huyen": "3" },
25743
- { "ten": "14", "timKiem": "14" }
25756
+ { "ten": "14", "timKiem": "14", "huyen": "3" }
25744
25757
  ]
25745
25758
  },
25746
25759
  {
25747
25760
  "ten": "Xóm Chiếu",
25748
25761
  "timKiem": "xomchieu",
25749
25762
  "satNhapTu": [
25750
- { "ten": "13", "timKiem": "13" },
25751
- { "ten": "16", "timKiem": "16" },
25752
- { "ten": "18", "timKiem": "18" },
25753
- { "ten": "15", "timKiem": "15" }
25763
+ { "ten": "13", "timKiem": "13", "huyen": "4" },
25764
+ { "ten": "16", "timKiem": "16", "huyen": "4" },
25765
+ { "ten": "18", "timKiem": "18", "huyen": "4" },
25766
+ { "ten": "15", "timKiem": "15", "huyen": "4" }
25754
25767
  ]
25755
25768
  },
25756
25769
  {
25757
25770
  "ten": "Khánh Hội",
25758
25771
  "timKiem": "khanhhoi",
25759
25772
  "satNhapTu": [
25760
- { "ten": "8", "timKiem": "8" },
25761
- { "ten": "9", "timKiem": "9" },
25762
- { "ten": "2", "timKiem": "2" },
25763
- { "ten": "4", "timKiem": "4" },
25764
- { "ten": "15", "timKiem": "15" }
25773
+ { "ten": "8", "timKiem": "8", "huyen": "4" },
25774
+ { "ten": "9", "timKiem": "9", "huyen": "4" },
25775
+ { "ten": "2", "timKiem": "2", "huyen": "4" },
25776
+ { "ten": "4", "timKiem": "4", "huyen": "4" },
25777
+ { "ten": "15", "timKiem": "15", "huyen": "4" }
25765
25778
  ]
25766
25779
  },
25767
25780
  {
25768
25781
  "ten": "Vĩnh Hội",
25769
25782
  "timKiem": "vinhhoi",
25770
25783
  "satNhapTu": [
25771
- { "ten": "1", "timKiem": "1" },
25772
- { "ten": "3", "timKiem": "3" },
25773
- { "ten": "2", "timKiem": "2" },
25774
- { "ten": "4", "timKiem": "4" }
25784
+ { "ten": "1", "timKiem": "1", "huyen": "4" },
25785
+ { "ten": "3", "timKiem": "3", "huyen": "4" },
25786
+ { "ten": "2", "timKiem": "2", "huyen": "4" },
25787
+ { "ten": "4", "timKiem": "4", "huyen": "4" }
25775
25788
  ]
25776
25789
  },
25777
25790
  {
25778
25791
  "ten": "Chợ Quán",
25779
25792
  "timKiem": "choquan",
25780
25793
  "satNhapTu": [
25781
- { "ten": "1", "timKiem": "1" },
25782
- { "ten": "2", "timKiem": "2" },
25783
- { "ten": "4", "timKiem": "4" }
25794
+ { "ten": "1", "timKiem": "1", "huyen": "5" },
25795
+ { "ten": "2", "timKiem": "2", "huyen": "5" },
25796
+ { "ten": "4", "timKiem": "4", "huyen": "5" }
25784
25797
  ]
25785
25798
  },
25786
25799
  {
25787
25800
  "ten": "An Đông",
25788
25801
  "timKiem": "andong",
25789
25802
  "satNhapTu": [
25790
- { "ten": "Phường 5", "timKiem": "5" },
25791
- { "ten": "7", "timKiem": "7" },
25792
- { "ten": "9", "timKiem": "9" }
25803
+ { "ten": "5", "timKiem": "5", "huyen": "5" },
25804
+ { "ten": "7", "timKiem": "7", "huyen": "5" },
25805
+ { "ten": "9", "timKiem": "9", "huyen": "5" }
25793
25806
  ]
25794
25807
  }
25795
25808
  ]
package/index.js CHANGED
@@ -179,6 +179,75 @@ const getProvinceCandidates = (tinh, sourceDataXa) => {
179
179
  });
180
180
  };
181
181
 
182
+ // Tìm tỉnh/thành phù hợp nhất trong một vế địa chỉ bất kỳ.
183
+ const findProvinceByText = (value = "", sourceDataXa = []) => {
184
+ const normalizedValue = createUniqueText(value);
185
+
186
+ if (!normalizedValue) {
187
+ return null;
188
+ }
189
+
190
+ return (
191
+ sourceDataXa.find(
192
+ (item) =>
193
+ normalizedValue.indexOf(item.timKiem) !== -1 ||
194
+ item.dsTinh?.some((item2) => normalizedValue.indexOf(item2.timKiem) !== -1)
195
+ ) || null
196
+ );
197
+ };
198
+
199
+ // Với địa chỉ đầy đủ có số nhà/đường/quốc gia, cố gắng bóc ra đuôi hành chính để reuse thuật toán convert gốc.
200
+ const extractAdministrativeParts = (input, sourceDataXa) => {
201
+ const parts = splitAddressParts(input);
202
+
203
+ if (parts.length < 3) {
204
+ return parts;
205
+ }
206
+
207
+ for (let provinceIndex = parts.length - 1; provinceIndex >= 0; provinceIndex -= 1) {
208
+ const province = findProvinceByText(parts[provinceIndex], sourceDataXa);
209
+
210
+ if (!province) {
211
+ continue;
212
+ }
213
+
214
+ const provinceName = province.ten;
215
+
216
+ if (provinceIndex >= 2) {
217
+ const threeLevelXa = verifyXaName(parts[provinceIndex - 2], provinceName, {
218
+ dataXa: sourceDataXa,
219
+ huyen: parts[provinceIndex - 1],
220
+ });
221
+
222
+ if (threeLevelXa.isValid) {
223
+ return parts.slice(provinceIndex - 2, provinceIndex + 1);
224
+ }
225
+ }
226
+
227
+ if (provinceIndex >= 1) {
228
+ const twoLevelXa = verifyXaName(parts[provinceIndex - 1], provinceName, {
229
+ dataXa: sourceDataXa,
230
+ });
231
+
232
+ if (twoLevelXa.isValid) {
233
+ return parts.slice(provinceIndex - 1, provinceIndex + 1);
234
+ }
235
+ }
236
+
237
+ const splitResult = splitAddressByValidXa(parts.slice(0, provinceIndex + 1), provinceName, {
238
+ dataXa: sourceDataXa,
239
+ });
240
+
241
+ if (splitResult.matchedXaIndex >= 0) {
242
+ return splitAddressParts(splitResult.diaChi);
243
+ }
244
+
245
+ return parts.slice(Math.max(0, provinceIndex - 2), provinceIndex + 1);
246
+ }
247
+
248
+ return parts;
249
+ };
250
+
182
251
  // Loại bỏ kết quả trùng và ưu tiên match theo tên xã hiện tại trước `satNhapTu`.
183
252
  const dedupeMatches = (matches = []) => {
184
253
  const uniqueMatches = matches.filter((item, index, arr) => {
@@ -422,7 +491,7 @@ const convertDiaChiMoi = async (diaChi2CapCu, options = {}) => {
422
491
  }
423
492
 
424
493
  let diaChi = [];
425
- const arr = splitAddressParts(diaChi2CapCu);
494
+ const arr = extractAdministrativeParts(diaChi2CapCu, sourceDataXa);
426
495
 
427
496
  if (arr.length === 2) diaChi = [arr[0], arr[1]];
428
497
  if (arr.length === 3) diaChi = [arr[0], arr[2]];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isofh/chuyen-doi-dia-chi-2-cap",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Chuan hoa dia chi hanh chinh cu sang format 2 cap moi",
5
5
  "main": "index.js",
6
6
  "files": [