CVNSS commited on
Commit
38cc9d1
·
verified ·
1 Parent(s): a124b1a

Upload 4 files

Browse files
Files changed (5) hide show
  1. .gitattributes +1 -0
  2. provinces.json +280 -0
  3. script.js +257 -0
  4. style.css +132 -28
  5. vietnam_map.jfif +3 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ vietnam_map.jfif filter=lfs diff=lfs merge=lfs -text
provinces.json ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "Hà Nội",
4
+ "mergedName": "Hà Nội",
5
+ "center": "Hà Nội",
6
+ "naturalArea": "3.359,8",
7
+ "population": "8.587,1",
8
+ "coords": "434,327,440,318,445,332,461,336,472,338,479,345,484,333,481,314,491,314,499,318,502,326,500,338,505,348,512,357,497,362,500,371,499,382,512,394,488,400,484,410,472,401,463,386,452,377,454,362,443,354,429,356,423,348,432,342,426,340"
9
+ },
10
+ {
11
+ "name": "Huế",
12
+ "mergedName": "Huế",
13
+ "center": "Huế",
14
+ "naturalArea": "4.947,1",
15
+ "population": "1.166,5",
16
+ "coords": "643,911,637,899,657,895,672,878,696,896,675,889,700,902,718,922,715,928,728,934,735,925,737,929,744,926,750,937,761,943,737,940,725,955,720,955,711,965,702,955,696,961,675,962,661,959,643,949,637,938,631,926"
17
+ },
18
+ {
19
+ "name": "Lai Châu",
20
+ "mergedName": "Lai Châu",
21
+ "center": "Lai Châu",
22
+ "naturalArea": "9.068,7",
23
+ "population": "489,3",
24
+ "coords": "199,213,207,218,214,236,223,245,223,234,231,228,232,209,241,207,253,196,255,184,243,180,229,175,231,162,226,153,219,160,213,153,207,144,196,135,189,151,178,156,177,166,168,168,166,177,149,172,143,159,113,142,107,145,104,138,98,136,86,160,103,162,115,171,122,180,134,187,139,195,142,206,151,209,155,215,165,216,195,228"
25
+ },
26
+ {
27
+ "name": "Điện Biên",
28
+ "mergedName": "Điện Biên",
29
+ "center": "Điện Biên",
30
+ "naturalArea": "9.539,9",
31
+ "population": "646,2",
32
+ "coords": "194,231,197,217,207,220,210,235,225,242,227,283,210,303,201,309,213,327,211,350,194,349,191,354,189,363,186,378,170,371,161,354,154,349,150,334,138,327,145,319,148,307,141,306,159,286,154,270,142,271,138,256,130,276,120,279,117,246,100,240,102,231,93,222,69,205,57,187,63,182,73,184,72,173,84,164,102,163,111,173,121,181,130,185,138,199,138,208,148,208,153,219,165,216"
33
+ },
34
+ {
35
+ "name": "Sơn La",
36
+ "mergedName": "Sơn La",
37
+ "center": "Sơn La",
38
+ "naturalArea": "14109,8",
39
+ "population": "1.313,3",
40
+ "coords": "217,391,231,390,237,400,244,400,240,391,250,388,250,376,277,369,282,361,297,364,302,372,312,370,320,385,329,388,347,400,359,408,372,408,375,393,387,390,398,387,402,379,377,355,383,346,378,334,371,316,362,308,348,304,333,313,323,308,314,299,318,277,311,269,300,274,279,274,255,265,243,247,237,235,223,233,226,280,204,308,214,328,210,349,196,349,187,378,202,385,211,379"
41
+ },
42
+ {
43
+ "name": "Lạng Sơn",
44
+ "mergedName": "Lạng Sơn",
45
+ "center": "Lạng Sơn",
46
+ "naturalArea": "8.310,2",
47
+ "population": "807,3",
48
+ "coords": "529,183,541,177,553,185,568,182,572,191,583,192,586,206,582,211,586,223,582,235,589,241,591,232,606,236,616,244,627,241,622,251,631,259,643,266,652,268,664,280,651,290,654,301,636,316,624,304,616,301,607,283,595,287,575,281,565,292,559,302,548,302,536,296,529,283,541,271,527,259,521,227,533,215,539,200"
49
+ },
50
+ {
51
+ "name": "Quảng Ninh",
52
+ "mergedName": "Quảng Ninh",
53
+ "center": "Quảng Ninh",
54
+ "naturalArea": "6.207,9",
55
+ "population": "1.381,2",
56
+ "coords": "621,329,624,317,652,305,651,289,663,281,673,278,675,284,702,281,708,275,720,278,737,293,738,308,693,353,679,379,630,393,607,382,598,373,595,363,585,356,560,349,571,334,604,340"
57
+ },
58
+ {
59
+ "name": "Thanh Hoá",
60
+ "mergedName": "Thanh Hoá",
61
+ "center": "Thanh Hoá",
62
+ "naturalArea": "11.114,7",
63
+ "population": "3.3739,5",
64
+ "coords": "348,402,362,408,374,405,396,411,405,408,425,424,452,436,514,472,514,481,503,490,500,507,490,525,487,546,482,554,485,570,470,566,454,546,440,545,432,537,422,539,425,530,408,508,414,493,387,483,390,468,383,468,384,457,371,454,354,456,356,438,344,432,321,429,326,417,339,418"
65
+ },
66
+ {
67
+ "name": "Nghệ An",
68
+ "mergedName": "Nghệ An",
69
+ "center": "Nghệ An",
70
+ "naturalArea": "16.486,5",
71
+ "population": "3.442",
72
+ "coords": "372,507,365,496,375,484,389,485,414,494,410,507,426,532,426,541,435,539,441,547,454,547,472,568,488,571,482,578,482,593,469,598,469,611,478,623,487,644,475,650,475,659,454,655,445,655,426,653,416,653,410,643,389,638,362,632,341,613,329,607,311,592,286,578,279,580,262,568,274,557,286,556,289,547,289,536,277,524,292,523,308,519,320,522,332,527,347,528,353,519"
73
+ },
74
+ {
75
+ "name": "Hà Tĩnh",
76
+ "mergedName": "Hà Tĩnh",
77
+ "center": "Hà Tĩnh",
78
+ "naturalArea": "5.994,4",
79
+ "population": "1.323,7",
80
+ "coords": "408,651,402,669,411,680,419,693,426,695,426,704,434,707,445,702,464,732,487,722,509,720,518,734,542,737,547,729,566,731,560,722,559,713,548,716,544,707,529,693,520,696,485,645,469,657"
81
+ },
82
+ {
83
+ "name": "Cao Bằng",
84
+ "mergedName": "Cao Bằng",
85
+ "center": "Cao Bằng",
86
+ "naturalArea": "6.700,4",
87
+ "population": "547,9",
88
+ "coords": "428,127,448,138,458,156,475,144,481,147,485,168,497,172,517,168,521,177,530,183,539,175,551,184,568,184,574,165,578,153,585,159,600,133,563,115,547,126,533,112,512,112,493,118,472,100,457,96"
89
+ },
90
+
91
+ {
92
+ "name": { "1": "Tuyên Quang", "2": "Hà Giang" },
93
+ "naturalArea": { "1": "5.867,9", "2": "7.927,5" },
94
+ "population": { "1": "812,2", "2": "899,9" },
95
+ "mergedName": "Tuyên Quang",
96
+ "center": "Tuyên Quang",
97
+ "coords": "321,146,340,131,360,132,373,120,369,99,378,96,376,86,385,90,400,80,417,78,420,71,427,66,447,78,459,102,429,126,449,138,465,177,447,203,458,239,452,271,459,293,449,296,433,298,407,268,384,224,364,209,358,201,348,204,345,191,334,183,327,165,333,162"
98
+ },
99
+ {
100
+ "name": { "1": "Lào Cai", "2": "Yên Bái" },
101
+ "naturalArea": { "1": "6.364,2", "2": "6.892,7" },
102
+ "population": { "1": "779,9", "2": "855,5" },
103
+ "mergedName": "Lào Cai",
104
+ "center": "Yên Bái",
105
+ "coords": "231,231,234,214,248,202,253,190,247,179,232,180,234,166,226,152,239,134,258,156,275,170,282,148,292,134,307,133,318,148,332,159,333,185,346,192,346,205,359,201,369,213,392,236,403,259,405,270,385,283,381,294,384,307,372,315,361,307,349,305,334,315,314,300,318,271,302,274,271,269,248,254"
106
+ },
107
+ {
108
+ "name": { "1": "Bắc Kạn", "2": "Thái Nguyên" },
109
+ "naturalArea": { "1": "4.860", "2": "3.522" },
110
+ "population": { "1": "326,5", "2": "1.350,3" },
111
+ "mergedName": "Thái Nguyên",
112
+ "center": "Thái Nguyên",
113
+ "coords": "459,184,450,199,451,221,459,240,454,263,451,279,459,290,481,311,498,318,504,306,514,302,514,284,525,281,528,293,537,275,528,260,522,242,520,227,534,213,538,201,531,183,523,177,520,168,507,168,490,169,480,157,480,145,466,153,459,159"
114
+ },
115
+ {
116
+ "name": { "1": "Vĩnh Phúc", "2": "Phú Thọ", "3": "Hoà Bình" },
117
+ "naturalArea": { "1": "1.236", "2": "3.534,6", "3":"4.590,3" },
118
+ "population": { "1": "1.211,3", "2": "1.530,8","3":"880,5" },
119
+ "mergedName": "Phú Thọ",
120
+ "center": "Phú Thọ",
121
+ "coords":"408,408,395,409,374,405,376,391,392,390,403,382,379,358,382,348,374,321,382,310,379,295,382,281,408,272,429,293,444,296,459,290,483,311,483,336,481,346,468,336,451,336,444,324,436,316,429,328,427,340,426,354,444,358,451,364,451,376,463,390,469,402,483,411,490,430,483,424,475,429,475,438,462,432,453,435,430,427"
122
+ },
123
+ {
124
+ "name": { "1": "Bắc Ninh", "2": "Bắc Giang" },
125
+ "naturalArea": { "1": "822,7", "2": "3.895,9" },
126
+ "population": { "1": "1517,4", "2": "1922,7" },
127
+ "mergedName": "Bắc Ninh",
128
+ "center": "Bắc Giang",
129
+ "coords":"508,359,523,359,541,361,544,352,544,341,549,332,564,329,571,334,579,334,592,334,602,335,614,335,621,329,626,319,629,310,623,301,608,287,597,292,588,284,577,284,568,292,562,304,552,305,544,301,531,293,525,280,514,283,517,298,504,308,499,317,504,328,501,337,505,349"
130
+ },
131
+ {
132
+ "name": { "1": "Hưng Yên", "2": "Thái Bình" },
133
+ "naturalArea": { "1": "930,2", "2": "1.584,6" },
134
+ "population": { "1": "1.301", "2": "1.882,3" },
135
+ "mergedName": "Hưng Yên",
136
+ "center": "Hưng Yên",
137
+ "coords":"523,405,529,417,535,424,541,432,541,441,549,435,559,444,570,441,576,448,574,433,574,420,576,409,564,403,558,396,540,396,531,388,523,377,528,365,517,358,504,362,501,376,501,385,508,393,514,400"
138
+ },
139
+ {
140
+ "name": { "1": "Hải Dương", "2": "TP Hải Phòng" },
141
+ "naturalArea": { "1": "1.668,3", "2": "1.526,5" },
142
+ "population": { "1": "1.956,9", "2": "2105" },
143
+ "mergedName": "Thành phố Hải Phòng",
144
+ "center": "Thành phố Hải Phòng",
145
+ "coords":"537,395,529,388,522,379,528,370,526,359,538,361,546,355,544,343,550,334,561,331,574,335,558,346,571,353,580,356,594,367,591,383,598,391,583,394,591,401,583,404,570,401,558,392,547,394"
146
+ },
147
+ {
148
+ "name": { "1": "Hà Nam", "2": "Ninh Bình", "3": "Nam Định" },
149
+ "naturalArea": { "1": "861,9", "2": "1.411,8", "3": "1.668,8" },
150
+ "population": { "1": "885,9", "2": "1.017,1", "3":"1.887,1" },
151
+ "mergedName": "Ninh Bình",
152
+ "center": "Ninh Bình",
153
+ "coords":"474,452,495,467,505,472,516,475,519,485,528,484,537,476,546,467,553,454,564,454,574,454,567,445,558,445,550,437,541,440,534,433,531,422,526,413,522,404,510,395,495,399,484,408,490,428,475,431,475,440,459,437"
154
+ },
155
+ {
156
+ "name": { "1": "Quảng Bình", "2": "Quảng Trị" },
157
+ "naturalArea": { "1": "7.998,8", "2": "4.701,2" },
158
+ "population": { "1": "918,7", "2": "654,2" },
159
+ "mergedName": "Quảng Trị",
160
+ "center": "Quảng Bình",
161
+ "coords":"463,731,472,730,483,724,495,721,508,721,519,733,532,736,544,736,553,731,571,733,558,743,562,760,577,785,586,798,602,811,624,828,636,838,647,859,672,880,662,892,635,900,644,910,630,927,623,931,614,924,609,907,595,913,585,915,585,897,576,892,571,883,571,849,558,849,553,838,543,826,543,811,534,814,522,808,504,792,493,776,478,767,465,745"
162
+
163
+ },
164
+ {
165
+ "name": { "1": "Quảng Nam", "2": "TP Đà Nẵng" },
166
+ "naturalArea": { "1": "10.574,9", "2": "1.284,7" },
167
+ "population": { "1": "1.526,1", "2": "1.245,2" },
168
+ "mergedName": "Đà Nẵng",
169
+ "center": "Thành phố Đà Nẵng",
170
+ "coords":"650,985,665,979,674,969,689,961,699,958,710,966,717,958,725,958,729,945,743,943,753,952,767,964,774,975,788,984,795,1003,811,1024,820,1032,827,1041,815,1042,795,1048,780,1051,770,1066,777,1078,765,1078,755,1092,747,1071,738,1062,726,1060,710,1051,699,1039,683,1038,677,1024,666,1029,654,1012,642,996"
171
+ },
172
+ {
173
+ "name": { "1": "Kon Tum", "2": "Quảng Ngãi" },
174
+ "naturalArea": { "1": "9.677,3", "2": "5.155,2" },
175
+ "population": { "1": "591,3", "2": "1.248,1" },
176
+ "mergedName": "Quảng Ngãi",
177
+ "center": "Quảng Ngãi",
178
+ "coords":"675,1219,690,1208,701,1193,716,1181,741,1175,767,1163,782,1149,786,1134,798,1134,811,1131,817,1136,832,1128,862,1127,859,1112,848,1086,844,1071,850,1058,842,1050,836,1038,832,1047,812,1044,788,1050,773,1067,779,1077,764,1080,758,1091,749,1082,749,1073,738,1067,726,1064,716,1055,705,1046,692,1043,702,1062,689,1082,678,1086,689,1100,681,1110,686,1124,678,1157,668,1157,665,1171,660,1193,666,1205"
179
+ },
180
+ {
181
+ "name": { "1": "Gia Lai", "2": "Bình Định" },
182
+ "naturalArea": { "1": "15.510,1", "2": "6.066,4" },
183
+ "population": { "1": "1.613,9", "2": "1.506,3" },
184
+ "mergedName": "Gia Lai",
185
+ "center": "Bình Định",
186
+ "coords": "677,1219,691,1207,698,1192,711,1184,727,1181,745,1172,762,1166,774,1160,781,1151,790,1134,802,1134,813,1133,828,1133,840,1127,852,1128,863,1128,867,1146,872,1164,879,1177,881,1189,887,1210,891,1222,888,1232,884,1243,872,1247,866,1258,851,1261,835,1261,838,1283,841,1302,823,1315,816,1327,804,1323,795,1315,789,1300,774,1286,754,1283,741,1282,721,1285,701,1288,686,1294,697,1270,692,1255,682,1240,676,1231"
187
+ },
188
+ {
189
+ "name": { "1": "Ninh Thuận", "2": "Khánh Hoà" },
190
+ "naturalArea": { "1": "3.355,7", "2": "5.199,6" },
191
+ "population": { "1": "601,2", "2": "1.260,6" },
192
+ "mergedName": "Khánh Hoà",
193
+ "center": "Khánh Hoà",
194
+ "coords": "811,1489,820,1481,814,1468,819,1450,820,1433,825,1424,820,1412,816,1399,819,1389,829,1386,837,1391,841,1374,848,1364,860,1358,876,1346,897,1349,885,1362,879,1374,878,1383,888,1388,896,1397,878,1394,881,1411,881,1432,881,1450,869,1466,882,1474,872,1495,861,1489,860,1519,848,1527,841,1517,832,1516,826,1504,817,1496"
195
+ },
196
+ {
197
+ "name": { "1": "Lâm Đồng", "2": "Đắk Nông", "3": "Bình Thuận"},
198
+ "naturalArea": { "1": "9.781,2", "2": "6.509,3", "3":"7.942,6"},
199
+ "population": { "1": "1.345,0", "2": "681,9", "3":"1.258,8"},
200
+ "mergedName": "Lâm Đồng",
201
+ "center": "Lâm Đồng",
202
+ "coords": "650,1411,652,1431,655,1443,667,1455,671,1473,661,1482,659,1497,671,1497,679,1506,677,1515,694,1521,685,1539,676,1561,683,1564,692,1582,685,1595,691,1615,711,1606,729,1598,739,1598,744,1577,765,1571,775,1576,781,1564,795,1558,799,1545,819,1541,828,1530,845,1526,840,1517,829,1517,823,1505,811,1497,810,1485,819,1478,814,1466,819,1446,819,1428,819,1411,808,1413,793,1414,780,1417,766,1428,756,1425,744,1410,732,1398,741,1389,727,1378,720,1359,686,1362,688,1389,682,1407,674,1414,661,1405"
203
+ },
204
+ {
205
+ "name": { "1": "Đắk Lắk", "2": "Phú Yên" },
206
+ "naturalArea": { "1": "13.070,4", "2": "5.026,0"},
207
+ "population": { "1": "1.931,5", "2": "877,7"},
208
+ "mergedName": "Đắk Lắk",
209
+ "center": "Đắk Lắk",
210
+ "coords":"834,1263,834,1276,840,1300,828,1312,817,1329,796,1320,790,1306,777,1290,751,1281,732,1287,711,1287,689,1294,677,1323,683,1344,686,1359,723,1359,726,1376,741,1388,733,1406,747,1412,754,1425,765,1428,774,1418,786,1416,799,1412,817,1412,816,1397,817,1388,835,1391,843,1371,863,1358,878,1346,897,1346,909,1344,906,1332,890,1312,891,1297,881,1281,890,1269,882,1245,870,1252,861,1258,845,1261"
211
+ },
212
+ {
213
+ "name": {
214
+ "1": "Bà Rịa - Vũng Tàu",
215
+ "2": "Bình Dương",
216
+ "3": "TP Hồ Chí Minh"
217
+ },
218
+ "naturalArea": { "1": "1.982,6", "2": "2.694,6", "3":"2.095,4"},
219
+ "population": { "1": "1.187,5", "2": "2.823,4", "3":"9.456,7"},
220
+ "mergedName": "Thành Phố Hồ Chí Minh",
221
+ "center": "Thành Phố Hồ Chí Minh",
222
+ "coords":"551,1566,555,1559,560,1550,551,1538,548,1522,554,1509,562,1500,568,1507,581,1515,580,1527,589,1522,596,1530,620,1531,617,1542,620,1550,610,1560,599,1562,601,1572,611,1590,595,1593,601,1602,613,1607,619,1614,628,1608,638,1605,643,1598,656,1593,659,1602,668,1599,679,1589,685,1595,691,1613,680,1620,665,1625,655,1637,646,1632,635,1641,640,1623,629,1625,617,1625,622,1634,613,1637,601,1629,599,1610,590,1601,577,1602,568,1595,572,1581,563,1571"
223
+ },
224
+ {
225
+ "name": { "1": "Đồng Nai", "2": "Bình Phước" },
226
+ "naturalArea": { "1": "5.863,6", "2": "6.873,6"},
227
+ "population": { "1": "3.310,9", "2": "1.045,5"},
228
+ "mergedName": "Đồng Nai",
229
+ "center": "Đồng Nai",
230
+ "coords":"652,1411,652,1433,655,1448,665,1456,671,1474,659,1481,655,1490,662,1498,670,1501,677,1511,694,1522,674,1563,688,1566,692,1581,685,1593,677,1587,667,1600,658,1593,646,1593,637,1602,619,1614,613,1603,596,1599,611,1591,607,1579,601,1563,610,1561,623,1554,617,1539,620,1528,601,1524,590,1522,581,1527,580,1514,563,1501,565,1490,554,1474,558,1463,554,1448,568,1450,587,1450,598,1439,617,1438,635,1418"
231
+ },
232
+ {
233
+ "name": { "1": "Tây Ninh", "2": "Long An" },
234
+ "naturalArea": { "1": "4.041,7", "2": "4.494,8"},
235
+ "population": { "1": "1.194,9", "2": "1.743,4"},
236
+ "mergedName": "Tây Ninh",
237
+ "center": "Long An",
238
+ "coords":"455,1572,477,1596,492,1610,504,1617,518,1617,528,1611,542,1611,549,1623,558,1625,562,1632,572,1632,581,1626,593,1620,592,1605,575,1604,566,1596,569,1581,563,1571,549,1565,558,1551,548,1534,548,1518,562,1501,562,1486,540,1485,524,1477,510,1473,501,1489,485,1492,492,1512,489,1528,506,1542,518,1559,530,1565,521,1569,530,1592,512,1589,501,1575,495,1584,480,1565,464,1569"
239
+ },
240
+ {
241
+ "name": { "1": "Cần Thơ", "2": "Sóc Trăng", "3": "Hậu Giang" },
242
+ "naturalArea": { "1": "1.440,4","2":"3.298,2", "3": "1.622,2"},
243
+ "population": { "1": "1.258,9", "2":"1.198,8","3": "728,3"},
244
+ "mergedName": "Cần Thơ",
245
+ "center": "Cần Thơ",
246
+ "coords":"440,1711,450,1703,455,1691,444,1678,420,1659,428,1649,434,1655,446,1652,458,1631,471,1635,483,1644,500,1658,489,1666,479,1659,473,1667,491,1682,497,1696,516,1712,530,1736,530,1753,513,1759,491,1769,489,1754,479,1751,462,1751,461,1726,440,1729,434,1718"
247
+ },
248
+ {
249
+ "name": { "1": "Bến Tre", "2": "Vĩnh Long", "3": "Trà Vinh" },
250
+ "naturalArea": { "1": "2.379,7", "2": "1.525,7", "3":"2.390,8"},
251
+ "population": { "1": "1.299,3", "2": "1.029,6", "3":"1.019,9"},
252
+ "mergedName": "Vĩnh Long",
253
+ "center": "Vĩnh Long",
254
+ "coords":"474,1669,489,1683,500,1687,509,1696,522,1711,537,1726,552,1734,568,1732,574,1723,575,1713,565,1704,551,1690,537,1675,522,1656,533,1665,548,1678,562,1690,572,1699,580,1704,589,1695,577,1684,589,1675,601,1669,593,1659,557,1648,548,1644,527,1645,513,1644,501,1648,492,1647,500,1657,489,1663,479,1659"
255
+ },
256
+ {
257
+ "name": { "1": "Tiền Giang", "2": "Đồng Tháp" },
258
+ "naturalArea": { "1": "2.556,4", "2": "3.382,3"},
259
+ "population": { "1": "1.790,7", "2": "1.600,2"},
260
+ "mergedName": "Đồng Tháp",
261
+ "center": "Tiền Giang",
262
+ "coords":"440,1614,437,1601,428,1598,422,1590,417,1576,429,1581,443,1569,455,1572,474,1596,485,1607,503,1617,516,1617,525,1611,539,1613,548,1622,558,1626,558,1635,574,1634,583,1626,595,1629,599,1647,560,1644,548,1641,534,1646,524,1649,512,1643,504,1647,494,1646,482,1644,474,1632,461,1631,453,1620"
263
+ },
264
+ {
265
+ "name": { "1": "Bạc Liêu", "2": "Cà Mau" },
266
+ "naturalArea": { "1": "2.667,9", "2": "5.274,5"},
267
+ "population": { "1": "925,2", "2": "1.207,4"},
268
+ "mergedName": "Cà Mau",
269
+ "center": "Cà Mau",
270
+ "coords":"373,1739,373,1760,372,1784,372,1798,366,1818,382,1821,378,1828,382,1836,364,1843,373,1848,385,1845,397,1843,405,1837,411,1827,422,1827,428,1815,435,1806,444,1797,452,1786,464,1781,479,1774,492,1769,491,1756,477,1754,465,1751,458,1742,458,1730,440,1729,428,1730,429,1738,428,1751,414,1745,405,1741,396,1736,387,1738"
271
+ },
272
+ {
273
+ "name": { "1": "An Giang", "2": "Kiên Giang" },
274
+ "naturalArea": { "1": "3.536,8", "2": "6.352"},
275
+ "population": { "1": "1.906,3", "2": "1.755,3"},
276
+ "mergedName": "An Giang",
277
+ "center": "Kiên Giang",
278
+ "coords":"371,1739,370,1725,374,1707,377,1699,385,1701,400,1690,403,1698,400,1674,383,1669,374,1662,361,1656,352,1662,343,1651,335,1638,335,1626,344,1623,359,1621,370,1621,379,1614,388,1605,398,1600,392,1584,398,1571,413,1579,421,1594,427,1600,435,1600,436,1612,448,1621,459,1630,450,1639,447,1647,438,1651,427,1648,416,1659,427,1665,438,1678,450,1690,447,1703,433,1719,435,1730,426,1743,424,1752,415,1748,397,1736"
279
+ }
280
+ ]
script.js ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const canvas = document.getElementById('mapCanvas');
2
+ const ctx = canvas.getContext('2d');
3
+
4
+ const img = document.querySelector('.map-container img');
5
+ canvas.width = img.clientWidth;
6
+ canvas.height = img.clientHeight;
7
+
8
+ const mapElement = document.getElementById('vietnam-map');
9
+
10
+ let areas = [];
11
+ let locationsData = [];
12
+
13
+ fetch('provinces.json')
14
+ .then(response => {
15
+ if (!response.ok) {
16
+ throw new Error('Network response was not ok');
17
+ }
18
+ return response.json();
19
+ })
20
+ .then(data => {
21
+ locationsData = data;
22
+ areas = locationsData.map(location => {
23
+ if (!location.coords) {
24
+ console.error('Missing coords for location:', location);
25
+ return { coords: [], shape: 'poly' };
26
+ }
27
+ const coords = location.coords.split(',').map(Number);
28
+ const shape = 'poly';
29
+ return { coords, shape };
30
+ });
31
+ createMapAreas();
32
+ })
33
+ .catch(error => {
34
+ console.error('Error loading the JSON file:', error);
35
+ });
36
+
37
+ function updateCanvasSize() {
38
+ // Cập nhật kích thước canvas theo kích thước thực của ảnh
39
+ canvas.width = img.offsetWidth;
40
+ canvas.height = img.offsetHeight;
41
+ canvas.style.width = `${img.offsetWidth}px`;
42
+ canvas.style.height = `${img.offsetHeight}px`;
43
+ }
44
+
45
+ // Sửa lại event listener resize
46
+ window.addEventListener('resize', () => {
47
+ updateCanvasSize();
48
+ createMapAreas();
49
+ });
50
+
51
+ // Thêm vào sau khi ảnh đã load
52
+ img.addEventListener('load', () => {
53
+ updateCanvasSize();
54
+ createMapAreas();
55
+ });
56
+
57
+ // Sửa lại hàm createMapAreas
58
+ function createMapAreas() {
59
+ mapElement.innerHTML = '';
60
+ const scaleX = img.offsetWidth / img.naturalWidth;
61
+ const scaleY = img.offsetHeight / img.naturalHeight;
62
+
63
+ areas.forEach((area) => {
64
+ const scaledCoords = area.coords.map((val, index) => {
65
+ return index % 2 === 0
66
+ ? Math.round(val * scaleX)
67
+ : Math.round(val * scaleY);
68
+ });
69
+
70
+ const areaElement = document.createElement('area');
71
+ areaElement.setAttribute('shape', area.shape);
72
+ areaElement.setAttribute('coords', scaledCoords.join(','));
73
+ areaElement.setAttribute('href', 'javascript:void(0)');
74
+ mapElement.appendChild(areaElement);
75
+ });
76
+
77
+ setupEventListeners();
78
+ }
79
+
80
+ const drawOutline = (coords) => {
81
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
82
+ ctx.beginPath();
83
+ const scaleX = canvas.width / img.naturalWidth;
84
+ const scaleY = canvas.height / img.naturalHeight;
85
+
86
+ ctx.moveTo(coords[0] * scaleX, coords[1] * scaleY);
87
+ for (let i = 2; i < coords.length; i += 2) {
88
+ ctx.lineTo(coords[i] * scaleX, coords[i + 1] * scaleY);
89
+ }
90
+
91
+ ctx.closePath();
92
+
93
+ // Thêm fill màu da cam nhạt
94
+ ctx.fillStyle = 'rgba(255, 165, 0, 0.3)'; // Màu da cam với độ trong suốt 0.3
95
+ ctx.fill();
96
+
97
+ // Vẽ viền đỏ
98
+ ctx.strokeStyle = 'red';
99
+ ctx.lineWidth = 2;
100
+ ctx.stroke();
101
+ };
102
+
103
+ const clearOutline = () => {
104
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
105
+ };
106
+
107
+ // Tooltip functionality
108
+ const tooltip = document.querySelector('.tooltip-box');
109
+
110
+ const showTooltip = (data, event) => {
111
+ tooltip.style.display = 'block';
112
+
113
+ let nameText = '';
114
+ let areaText = '';
115
+ let areaTotal = 0;
116
+ let popText = '';
117
+ let popTotal = 0;
118
+
119
+ if (typeof data.name === 'object' && Object.keys(data.name).length > 1) {
120
+ // Gộp tên
121
+ nameText = Object.values(data.name).join(' + ');
122
+
123
+ // Diện tích
124
+ for (const key in data.naturalArea) {
125
+ const value = parseFloat(data.naturalArea[key].replace('.', '').replace(',', '.'));
126
+ areaText += `<p>${data.name[key]}: ${data.naturalArea[key]}</p>`;
127
+ areaTotal += value;
128
+ }
129
+
130
+ // Dân số
131
+ for (const key in data.population) {
132
+ const value = parseFloat(data.population[key].replace('.', '').replace(',', '.'));
133
+ popText += `<p>${data.name[key]}: ${data.population[key]}</p>`;
134
+ popTotal += value;
135
+ }
136
+
137
+ tooltip.innerHTML = `
138
+ <h2>${nameText}</h2>
139
+ <hr>
140
+ <h3>DIỆN TÍCH TỰ NHIÊN (KM²)</h3>
141
+ ${areaText}
142
+ <p><strong>Tổng diện tích:</strong> ${areaTotal.toLocaleString('vi-VN')}</p>
143
+ <hr>
144
+ <h3>QUY MÔ DÂN SỐ (NGHÌN NGƯỜI)</h3>
145
+ ${popText}
146
+ <p><strong>Tổng dân số:</strong> ${popTotal.toLocaleString('vi-VN')}</p>
147
+ <hr>
148
+ <p>Tên tỉnh, thành sau sáp nhập: <span class="highlight">${data.mergedName}</span></p>
149
+ <p>Trung tâm chính trị - hành chính: <span class="highlight">${data.center}</span></p>
150
+ `;
151
+ } else {
152
+ // Trường hợp chỉ có 1 tỉnh
153
+ tooltip.innerHTML = `
154
+ <h2>${data.name}</h2>
155
+ <hr>
156
+ <h3>DIỆN TÍCH TỰ NHIÊN (KM²)</h3>
157
+ <p>${data.name}: ${data.naturalArea}</p>
158
+ <p><strong>Tổng diện tích:</strong> ${data.naturalArea}</p>
159
+ <hr>
160
+ <h3>QUY MÔ DÂN SỐ (NGHÌN NGƯỜI)</h3>
161
+ <p>${data.name}: ${data.population}</p>
162
+ <p><strong>Tổng dân số:</strong> ${data.population}</p>
163
+ <hr>
164
+ <!-- <p>Tên tỉnh, thành sau sáp nhập: <span class="highlight">${data.mergedName}</span></p>
165
+ <p>Trung tâm chính trị - hành chính: <span class="highlight">${data.center}</span></p>
166
+ -->
167
+ `;
168
+ }
169
+
170
+ // Hiện tooltip trước để lấy kích thước thực
171
+ tooltip.style.visibility = 'hidden';
172
+ tooltip.style.display = 'block';
173
+
174
+ const tooltipWidth = tooltip.offsetWidth;
175
+ const tooltipHeight = tooltip.offsetHeight;
176
+
177
+ // Lấy kích thước và vị trí của viewport
178
+ const viewportWidth = window.innerWidth;
179
+ const viewportHeight = window.innerHeight;
180
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
181
+ const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
182
+
183
+ // Tính toán vị trí tốt nhất cho tooltip
184
+ let left = event.pageX + 10;
185
+ let top = event.pageY + 10;
186
+
187
+ // Kiểm tra và điều chỉnh vị trí ngang
188
+ if (left + tooltipWidth > viewportWidth + scrollLeft) {
189
+ left = event.pageX - tooltipWidth - 10;
190
+ }
191
+
192
+ // Kiểm tra và điều chỉnh vị trí dọc
193
+ if (top + tooltipHeight > viewportHeight + scrollTop) {
194
+ top = event.pageY - tooltipHeight - 10;
195
+
196
+ // Nếu vẫn vượt quá phía trên viewport
197
+ if (top < scrollTop) {
198
+ // Đặt tooltip ở giữa màn hình theo chiều dọc
199
+ top = scrollTop + (viewportHeight - tooltipHeight) / 2;
200
+ }
201
+ }
202
+
203
+ // Đảm bảo tooltip không bị cắt ở các cạnh
204
+ left = Math.max(scrollLeft + 10, Math.min(left, viewportWidth + scrollLeft - tooltipWidth - 10));
205
+ top = Math.max(scrollTop + 10, Math.min(top, viewportHeight + scrollTop - tooltipHeight - 10));
206
+
207
+ // Áp dụng vị trí và hiện tooltip
208
+ tooltip.style.left = `${left}px`;
209
+ tooltip.style.top = `${top}px`;
210
+ tooltip.style.visibility = 'visible';
211
+ tooltip.classList.add('active');
212
+ };
213
+
214
+ // Thêm event listener cho viewport resize
215
+ window.addEventListener('resize', () => {
216
+ if (tooltip.classList.contains('active')) {
217
+ tooltip.classList.remove('active');
218
+ }
219
+ });
220
+
221
+ const hideTooltip = () => {
222
+ tooltip.classList.remove('active');
223
+ };
224
+
225
+ function setupEventListeners() {
226
+ document.querySelectorAll('area').forEach((area, index) => {
227
+ area.addEventListener('mouseenter', () => {
228
+ drawOutline(areas[index].coords);
229
+ });
230
+ area.addEventListener('mouseleave', clearOutline);
231
+
232
+ area.addEventListener('mouseenter', (event) => {
233
+ showTooltip(locationsData[index], event);
234
+ });
235
+ area.addEventListener('mousemove', (event) => {
236
+ // Chỉ cập nhật vị trí nếu tooltip không bị overflow
237
+ const tooltipRect = tooltip.getBoundingClientRect();
238
+ const viewportHeight = window.innerHeight;
239
+ const viewportWidth = window.innerWidth;
240
+
241
+ // Chỉ di chuyển tooltip theo chuột khi có đủ không gian
242
+ if (tooltipRect.width + event.clientX < viewportWidth &&
243
+ tooltipRect.height + event.clientY < viewportHeight) {
244
+ tooltip.style.left = `${event.pageX + 10}px`;
245
+ tooltip.style.top = `${event.pageY + 10}px`;
246
+ }
247
+ });
248
+ area.addEventListener('mouseleave', hideTooltip);
249
+ });
250
+
251
+ document.addEventListener('mousemove', (event) => {
252
+ if (!event.target.closest('area') && !tooltip.contains(event.target)) {
253
+ tooltip.style.display = 'none';
254
+ tooltip.innerHTML = '';
255
+ }
256
+ });
257
+ }
style.css CHANGED
@@ -1,28 +1,132 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .container {
2
+ width: 100%;
3
+ display: flex;
4
+ justify-content: center;
5
+ align-items: center;
6
+ }
7
+
8
+ .map-container {
9
+ position: relative;
10
+ width: 100%;
11
+ max-width: 1000px;
12
+ /* hoặc kích thước tối đa mong muốn */
13
+ margin: 0 auto;
14
+ }
15
+
16
+ .map-container img,
17
+ #mapCanvas {
18
+ width: 100%;
19
+ height: auto;
20
+ display: block;
21
+ }
22
+
23
+ .map-container img {
24
+ width: 100%;
25
+ height: auto;
26
+ display: block;
27
+ }
28
+
29
+ #mapCanvas {
30
+ position: absolute;
31
+ top: 0;
32
+ left: 0;
33
+ width: 100%;
34
+ height: 100%;
35
+ pointer-events: none;
36
+ }
37
+
38
+ #vietnam-map {
39
+ width: 100%;
40
+ height: 100%;
41
+ }
42
+
43
+ .tooltip-box {
44
+ width: 30vw;
45
+ min-width: 200px;
46
+ max-width: 350px;
47
+ background-color: #f0f8ff;
48
+ opacity: 0.9;
49
+ border-radius: 12px;
50
+ padding: 10px;
51
+ font-family: 'Segoe UI', sans-serif;
52
+ color: #1a1a1a;
53
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
54
+ display: none;
55
+ position: absolute;
56
+ text-align: center;
57
+ z-index: 1000;
58
+ transition: left 0.1s ease-out, top 0.1s ease-out;
59
+ pointer-events: none;
60
+ max-height: 80vh;
61
+ overflow-y: auto;
62
+ }
63
+
64
+ .tooltip-box.active {
65
+ display: block !important;
66
+ }
67
+
68
+ .tooltip-box h2 {
69
+ text-align: center;
70
+ color: #2b55b4;
71
+ font-size: 25px;
72
+ margin-bottom: 20px;
73
+ }
74
+
75
+ .tooltip-box .highlight {
76
+ color: #2b55b4;
77
+ font-weight: bold;
78
+ font-size: 16px;
79
+ }
80
+
81
+ .tooltip-box hr {
82
+ margin: 20px 0;
83
+ border: none;
84
+ border-top: 1px solid #ccc;
85
+ }
86
+
87
+ /* Media queries cho điện thoại */
88
+ @media screen and (max-width: 768px) {
89
+ .tooltip-box {
90
+ width: 85vw;
91
+ /* Giảm xuống để phù hợp với màn hình điện thoại */
92
+ min-width: 150px;
93
+ max-width: 300px;
94
+ font-size: 14px;
95
+ padding: 8px;
96
+ max-height: 60vh;
97
+ }
98
+
99
+ .tooltip-box h2 {
100
+ font-size: 16px;
101
+ margin-bottom: 10px;
102
+ }
103
+
104
+ .tooltip-box h3 {
105
+ font-size: 14px;
106
+ margin: 8px 0;
107
+ }
108
+
109
+ .tooltip-box p {
110
+ margin: 5px 0;
111
+ font-size: 13px;
112
+ }
113
+
114
+ .tooltip-box hr {
115
+ margin: 5px 0;
116
+ }
117
+
118
+ .tooltip-box .highlight {
119
+ font-size: 13px;
120
+ }
121
+ }
122
+
123
+ /* Media queries cho điện thoại nhỏ hơn */
124
+ @media screen and (max-width: 375px) {
125
+ .tooltip-box {
126
+ width: 90vw;
127
+ min-width: 120px;
128
+ max-width: 250px;
129
+ font-size: 12px;
130
+ padding: 6px;
131
+ }
132
+ }
vietnam_map.jfif ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:966cbddf0bb4b28486b51b81f93df86c45a4f6addecc8d88ab3ca39a6cb6ac2a
3
+ size 140208