Skip to content

Commit

Permalink
feat: adds get_country(mmsi)
Browse files Browse the repository at this point in the history
  • Loading branch information
M0r13n committed Apr 5, 2024
1 parent 7824cd5 commit 6b8ca2d
Show file tree
Hide file tree
Showing 7 changed files with 368 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
====================
pyais CHANGELOG
====================
-------------------------------------------------------------------------------
Version 2.6.3 05 Apr 2024
-------------------------------------------------------------------------------
* closes https://github.com/M0r13n/pyais/issues/131
* pyais now supports country codes/names using `get_country(mmsi)`
-------------------------------------------------------------------------------
Version 2.6.2 16 Mar 2024
-------------------------------------------------------------------------------
Expand Down
12 changes: 10 additions & 2 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The following example shows how you can get the communication state
of a message. This works for message types 1, 2, 4, 9, 11 and 18.

These messages contain diagnostic information for the radio system.::

from pyais import decode
from pyais.messages import MessageType18
import json
Expand Down Expand Up @@ -81,7 +81,7 @@ Gatehouse wrappers
-------------------

Some AIS messages have so-called Gatehouse wrappers::

import pathlib

from pyais.stream import FileReaderStream
Expand Down Expand Up @@ -203,3 +203,11 @@ so that you are is instantly notified whenever a track is created, updated, or d
for msg in pyais.TCPConnection(host, port=port):
tracker.update(msg)
latest_tracks = tracker.n_latest_tracks(10)

Country and Flag
-----------------

The first 3 digits of any MMSI number are indicative of the vessel's flag:

country_code, country_name = get_country(249110000)
assert country_code, country_name == ('MT', 'Malta')
7 changes: 7 additions & 0 deletions examples/country_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This example shows how to identify a vessel's country and flag
from pyais.util import get_country


# The first 3 digits of any MMSI number are indicative of the vessel's flag
country_code, country_name = get_country(249110000)
assert country_code, country_name == ('MT', 'Malta')
2 changes: 1 addition & 1 deletion pyais/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pyais.tracker import AISTracker, AISTrack

__license__ = 'MIT'
__version__ = '2.6.2'
__version__ = '2.6.3'
__author__ = 'Leon Morten Richter'

__all__ = (
Expand Down
294 changes: 294 additions & 0 deletions pyais/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,297 @@ class SyncState(IntEnum):
UTC_INDIRECT = 0x01
BASE_DIRECT = 0x02
BASE_INDIRECT = 0x03


COUNTRY_MAPPING = {
201: ("AL", "Albania"),
202: ("AD", "Andorra"),
203: ("AT", "Austria"),
204: ("PT", "Portugal"),
205: ("BE", "Belgium"),
206: ("BY", "Belarus"),
207: ("BG", "Bulgaria"),
208: ("VA", "Vatican"),
209: ("CY", "Cyprus"),
210: ("CY", "Cyprus"),
211: ("DE", "Germany"),
212: ("CY", "Cyprus"),
213: ("GE", "Georgia"),
214: ("MD", "Moldova"),
215: ("MT", "Malta"),
216: ("AM", "Armenia"),
218: ("DE", "Germany"),
219: ("DK", "Denmark"),
220: ("DK", "Denmark"),
224: ("ES", "Spain"),
225: ("ES", "Spain"),
226: ("FR", "France"),
227: ("FR", "France"),
228: ("FR", "France"),
229: ("MT", "Malta"),
230: ("FI", "Finland"),
231: ("FO", "Faroe Is"),
232: ("GB", "United Kingdom"),
233: ("GB", "United Kingdom"),
234: ("GB", "United Kingdom"),
235: ("GB", "United Kingdom"),
236: ("GI", "Gibraltar"),
237: ("GR", "Greece"),
238: ("HR", "Croatia"),
239: ("GR", "Greece"),
240: ("GR", "Greece"),
241: ("GR", "Greece"),
242: ("MA", "Morocco"),
243: ("HU", "Hungary"),
244: ("NL", "Netherlands"),
245: ("NL", "Netherlands"),
246: ("NL", "Netherlands"),
247: ("IT", "Italy"),
248: ("MT", "Malta"),
249: ("MT", "Malta"),
250: ("IE", "Ireland"),
251: ("IS", "Iceland"),
252: ("LI", "Liechtenstein"),
253: ("LU", "Luxembourg"),
254: ("MC", "Monaco"),
255: ("PT", "Portugal"),
256: ("MT", "Malta"),
257: ("NO", "Norway"),
258: ("NO", "Norway"),
259: ("NO", "Norway"),
261: ("PL", "Poland"),
262: ("ME", "Montenegro"),
263: ("PT", "Portugal"),
264: ("RO", "Romania"),
265: ("SE", "Sweden"),
266: ("SE", "Sweden"),
267: ("SK", "Slovakia"),
268: ("SM", "San Marino"),
269: ("CH", "Switzerland"),
270: ("CZ", "Czech Republic"),
271: ("TR", "Turkey"),
272: ("UA", "Ukraine"),
273: ("RU", "Russia"),
274: ("MK", "FYR Macedonia"),
275: ("LV", "Latvia"),
276: ("EE", "Estonia"),
277: ("LT", "Lithuania"),
278: ("SI", "Slovenia"),
279: ("RS", "Serbia"),
301: ("AI", "Anguilla"),
303: ("US", "USA"),
304: ("AG", "Antigua Barbuda"),
305: ("AG", "Antigua Barbuda"),
306: ("CW", "Curacao"),
307: ("AW", "Aruba"),
308: ("BS", "Bahamas"),
309: ("BS", "Bahamas"),
310: ("BM", "Bermuda"),
311: ("BS", "Bahamas"),
312: ("BZ", "Belize"),
314: ("BB", "Barbados"),
316: ("CA", "Canada"),
319: ("KY", "Cayman Is"),
321: ("CR", "Costa Rica"),
323: ("CU", "Cuba"),
325: ("DM", "Dominica"),
327: ("DO", "Dominican Rep"),
329: ("GP", "Guadeloupe"),
330: ("GD", "Grenada"),
331: ("GL", "Greenland"),
332: ("GT", "Guatemala"),
334: ("HN", "Honduras"),
336: ("HT", "Haiti"),
338: ("US", "USA"),
339: ("JM", "Jamaica"),
341: ("KN", "St Kitts Nevis"),
343: ("LC", "St Lucia"),
345: ("MX", "Mexico"),
347: ("MQ", "Martinique"),
348: ("MS", "Montserrat"),
350: ("NI", "Nicaragua"),
351: ("PA", "Panama"),
352: ("PA", "Panama"),
353: ("PA", "Panama"),
354: ("PA", "Panama"),
355: ("PA", "Panama"),
356: ("PA", "Panama"),
357: ("PA", "Panama"),
358: ("PR", "Puerto Rico"),
359: ("SV", "El Salvador"),
361: ("PM", "St Pierre Miquelon"),
362: ("TT", "Trinidad Tobago"),
364: ("TC", "Turks Caicos Is"),
366: ("US", "USA"),
367: ("US", "USA"),
368: ("US", "USA"),
369: ("US", "USA"),
370: ("PA", "Panama"),
371: ("PA", "Panama"),
372: ("PA", "Panama"),
373: ("PA", "Panama"),
374: ("PA", "Panama"),
375: ("VC", "St Vincent Grenadines"),
376: ("VC", "St Vincent Grenadines"),
377: ("VC", "St Vincent Grenadines"),
378: ("VG", "British Virgin Is"),
379: ("VI", "US Virgin Is"),
401: ("AF", "Afghanistan"),
403: ("SA", "Saudi Arabia"),
405: ("BD", "Bangladesh"),
408: ("BH", "Bahrain"),
410: ("BT", "Bhutan"),
412: ("CN", "China"),
413: ("CN", "China"),
414: ("CN", "China"),
416: ("TW", "Taiwan"),
417: ("LK", "Sri Lanka"),
419: ("IN", "India"),
422: ("IR", "Iran"),
423: ("AZ", "Azerbaijan"),
425: ("IQ", "Iraq"),
428: ("IL", "Israel"),
431: ("JP", "Japan"),
432: ("JP", "Japan"),
434: ("TM", "Turkmenistan"),
436: ("KZ", "Kazakhstan"),
437: ("UZ", "Uzbekistan"),
438: ("JO", "Jordan"),
440: ("KR", "Korea"),
441: ("KR", "Korea"),
443: ("PS", "Palestine"),
445: ("KP", "DPR Korea"),
447: ("KW", "Kuwait"),
450: ("LB", "Lebanon"),
451: ("KG", "Kyrgyz Republic"),
453: ("MO", "Macao"),
455: ("MV", "Maldives"),
457: ("MN", "Mongolia"),
459: ("NP", "Nepal"),
461: ("OM", "Oman"),
463: ("PK", "Pakistan"),
466: ("QA", "Qatar"),
468: ("SY", "Syria"),
470: ("AE", "UAE"),
471: ("AE", "UAE"),
472: ("TJ", "Tajikistan"),
473: ("YE", "Yemen"),
475: ("YE", "Yemen"),
477: ("HK", "Hong Kong"),
478: ("BA", "Bosnia and Herzegovina"),
501: ("AQ", "Antarctica"),
503: ("AU", "Australia"),
506: ("MM", "Myanmar"),
508: ("BN", "Brunei"),
510: ("FM", "Micronesia"),
511: ("PW", "Palau"),
512: ("NZ", "New Zealand"),
514: ("KH", "Cambodia"),
515: ("KH", "Cambodia"),
516: ("CX", "Christmas Is"),
518: ("CK", "Cook Is"),
520: ("FJ", "Fiji"),
523: ("CC", "Cocos Is"),
525: ("ID", "Indonesia"),
529: ("KI", "Kiribati"),
531: ("LA", "Laos"),
533: ("MY", "Malaysia"),
536: ("MP", "N Mariana Is"),
538: ("MH", "Marshall Is"),
540: ("NC", "New Caledonia"),
542: ("NU", "Niue"),
544: ("NR", "Nauru"),
546: ("PF", "French Polynesia"),
548: ("PH", "Philippines"),
553: ("PG", "Papua New Guinea"),
555: ("PN", "Pitcairn Is"),
557: ("SB", "Solomon Is"),
559: ("AS", "American Samoa"),
561: ("WS", "Samoa"),
563: ("SG", "Singapore"),
564: ("SG", "Singapore"),
565: ("SG", "Singapore"),
566: ("SG", "Singapore"),
567: ("TH", "Thailand"),
570: ("TO", "Tonga"),
572: ("TV", "Tuvalu"),
574: ("VN", "Vietnam"),
576: ("VU", "Vanuatu"),
577: ("VU", "Vanuatu"),
578: ("WF", "Wallis Futuna Is"),
601: ("ZA", "South Africa"),
603: ("AO", "Angola"),
605: ("DZ", "Algeria"),
607: ("TF", "St Paul Amsterdam Is"),
608: ("IO", "Ascension Is"),
609: ("BI", "Burundi"),
610: ("BJ", "Benin"),
611: ("BW", "Botswana"),
612: ("CF", "Cen Afr Rep"),
613: ("CM", "Cameroon"),
615: ("CG", "Congo"),
616: ("KM", "Comoros"),
617: ("CV", "Cape Verde"),
618: ("AQ", "Antarctica"),
619: ("CI", "Ivory Coast"),
620: ("KM", "Comoros"),
621: ("DJ", "Djibouti"),
622: ("EG", "Egypt"),
624: ("ET", "Ethiopia"),
625: ("ER", "Eritrea"),
626: ("GA", "Gabon"),
627: ("GH", "Ghana"),
629: ("GM", "Gambia"),
630: ("GW", "Guinea-Bissau"),
631: ("GQ", "Equ. Guinea"),
632: ("GN", "Guinea"),
633: ("BF", "Burkina Faso"),
634: ("KE", "Kenya"),
635: ("AQ", "Antarctica"),
636: ("LR", "Liberia"),
637: ("LR", "Liberia"),
642: ("LY", "Libya"),
644: ("LS", "Lesotho"),
645: ("MU", "Mauritius"),
647: ("MG", "Madagascar"),
649: ("ML", "Mali"),
650: ("MZ", "Mozambique"),
654: ("MR", "Mauritania"),
655: ("MW", "Malawi"),
656: ("NE", "Niger"),
657: ("NG", "Nigeria"),
659: ("NA", "Namibia"),
660: ("RE", "Reunion"),
661: ("RW", "Rwanda"),
662: ("SD", "Sudan"),
663: ("SN", "Senegal"),
664: ("SC", "Seychelles"),
665: ("SH", "St Helena"),
666: ("SO", "Somalia"),
667: ("SL", "Sierra Leone"),
668: ("ST", "Sao Tome Principe"),
669: ("SZ", "Swaziland"),
670: ("TD", "Chad"),
671: ("TG", "Togo"),
672: ("TN", "Tunisia"),
674: ("TZ", "Tanzania"),
675: ("UG", "Uganda"),
676: ("CD", "DR Congo"),
677: ("TZ", "Tanzania"),
678: ("ZM", "Zambia"),
679: ("ZW", "Zimbabwe"),
701: ("AR", "Argentina"),
710: ("BR", "Brazil"),
720: ("BO", "Bolivia"),
725: ("CL", "Chile"),
730: ("CO", "Colombia"),
735: ("EC", "Ecuador"),
740: ("UK", "UK"),
745: ("GF", "Guiana"),
750: ("GY", "Guyana"),
755: ("PY", "Paraguay"),
760: ("PE", "Peru"),
765: ("SR", "Suriname"),
770: ("UY", "Uruguay"),
775: ("VE", "Venezuela"),
}
14 changes: 13 additions & 1 deletion pyais/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
import math
import typing
from collections import OrderedDict
from functools import partial, reduce
Expand All @@ -7,7 +8,7 @@

from bitarray import bitarray

from pyais.constants import SyncState
from pyais.constants import COUNTRY_MAPPING, SyncState
from pyais.exceptions import NonPrintableCharacterException

if TYPE_CHECKING:
Expand Down Expand Up @@ -418,3 +419,14 @@ def get_itdma_comm_state(radio: int) -> Dict[str, typing.Optional[int]]:
'num_slots': num_slots,
'keep_flag': keep_flag,
}


def get_first_three_digits(num: int) -> int:
if num < 1000:
return num
digits = int(math.log10(num)) + 1
return int(num // (10**(digits - 3)))


def get_country(mmsi: int) -> typing.Tuple[str, str]:
return COUNTRY_MAPPING.get(get_first_three_digits(mmsi), ('NA', 'Unknown'))
Loading

0 comments on commit 6b8ca2d

Please sign in to comment.