sv1djg.hamutils.dxcc.DXCCEntitiesReader.java Source code

Java tutorial

Introduction

Here is the source code for sv1djg.hamutils.dxcc.DXCCEntitiesReader.java

Source

////////////////////////////////////////////////////////////////////////
//
// This file is part of DXCCPlanner.
// 
// A utility to assist ham radio operators in planning their antennas
// especially when on limited space.
//
// Copyright 2016, Nick Tsakonas, SV1DJG
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////

package sv1djg.hamutils.dxcc;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;

import org.apache.commons.lang.StringUtils;

public class DXCCEntitiesReader {

    ArrayList<DXCCEntity> _dxccList;
    private String _countriesFile;

    ArrayList<DXCCEntity> _mostWantedList;
    private String _mostWantedFile;

    public DXCCEntitiesReader(String countriesFile, String mostWantedFile) {

        _countriesFile = countriesFile;
        _dxccList = new ArrayList<DXCCEntity>();

        _mostWantedFile = mostWantedFile;
        _mostWantedList = new ArrayList<DXCCEntity>();

        readDXCCList();
    }

    private void readDXCCList() {
        readCountryFile();
        readMostWantedFile();
        updateDXCCEntitiesWithMostWanted();

        // only for debug reasons
        //sortCountriesOnRarity();
        //printList();

    }

    private void readCountryFile() {
        // the country file used is taken from http://www.country-files.com/cty/
        // the appropriate version is for Aether log
        //
        // example entries
        // SV,Greece,236,EU,20,28,39.78,-21.78,-2.0,J4 SV SW SX SY SZ =SV9DRU/1;
        // field #1 -> prefix
        // field #2 -> country name
        // field #3 -> entity code (not needed)
        // field #4 -> continent (not needed)
        // field #5 -> CQ Zone (not needed)
        // field #6 -> ITU Zone (not needed)
        // field #7 -> latitude (+ for north, - for south)
        // field #8 -> longitude(+ for west, - for east)
        // field #9 -> time diff (not needed)
        // field #10 -> additional prefixes for this country
        //
        // we need fields 1,2,4,7,8
        // field 8 normally should be negated

        try {
            // Open the file (it is embedded in the jar)
            InputStream fstream = getClass().getResourceAsStream(_countriesFile);

            // Get the object of DataInputStream
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader countriesReader = new BufferedReader(new InputStreamReader(in), 65535);

            NumberFormat format = NumberFormat.getInstance(Locale.US);

            String countryEntry = countriesReader.readLine();

            while (countryEntry != null) {

                String[] countryDetails = StringUtils.split(countryEntry, ",");
                if (countryDetails != null && countryDetails.length >= 9) {

                    DXCCEntity dxccEntity = new DXCCEntity();

                    dxccEntity.prefix = countryDetails[0];
                    dxccEntity.countryName = countryDetails[1];
                    dxccEntity.continent = countryDetails[3];

                    dxccEntity.latitude = format.parse(countryDetails[6]).doubleValue();
                    dxccEntity.longitude = -format.parse(countryDetails[7]).doubleValue();

                    _dxccList.add(dxccEntity);

                }

                countryEntry = countriesReader.readLine();
            }

            countriesReader.close();

        } catch (Throwable e) {
            e.printStackTrace();
        }

    }

    private void readMostWantedFile() {
        // the most wanted file used is taken http://www.clublog.org/mostwanted.php
        // and manually cleaned to remove entities' names
        //
        // example entries
        // 1,P5
        // 2,3Y/B
        // 3,VP8S
        //
        // field #1 -> ranking in most wanted 
        // field #2 -> prefix
        //

        // we read the file and create DXCC entities although not all fields are used

        try {
            // Open the file (it is embedded in the jar)
            InputStream fstream = getClass().getResourceAsStream(_mostWantedFile);

            // Get the object of DataInputStream
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader countriesReader = new BufferedReader(new InputStreamReader(in), 65535);

            String countryEntry = countriesReader.readLine();

            while (countryEntry != null) {

                String[] countryDetails = StringUtils.split(countryEntry, ",");
                if (countryDetails != null && countryDetails.length == 2) {

                    DXCCEntity dxccEntity = new DXCCEntity();

                    dxccEntity.rankingInMostWanted = Integer.parseInt(countryDetails[0]);
                    dxccEntity.prefix = countryDetails[1];

                    _mostWantedList.add(dxccEntity);

                }

                countryEntry = countriesReader.readLine();
            }

            countriesReader.close();

        } catch (Throwable e) {
            e.printStackTrace();
        }

    }

    private void updateDXCCEntitiesWithMostWanted() {

        int dxccListCount = _dxccList.size();
        int wantedDxccCount = _mostWantedList.size();
        int matchedWantedDxccCount = 0;

        //System.out.println("Matching DXCC list to most wanted...PASS 1");

        // iterate once and match the most common ones
        for (DXCCEntity dxccEntity : _dxccList) {
            boolean foundMatch = false;
            for (DXCCEntity wantedEntity : _mostWantedList) {
                if (wantedEntity.prefix.equalsIgnoreCase(dxccEntity.prefix)) {
                    dxccEntity.rankingInMostWanted = wantedEntity.rankingInMostWanted;

                    matchedWantedDxccCount++;
                    foundMatch = true;
                    break;
                }
            }

            //  if (!foundMatch)
            //   System.out.println("-- prefix "+dxccEntity.prefix+" not found in most wanted list");
        }

        // iterate a second time and resolve the very specific ones
        // usually we don't get a match on the first iteration because of small differences like
        // DXCC -> 5V , most wanted -> 5V7
        //
        // so in this iteration we check all the unresolved and check sub-prefixes

        //System.out.println("Matching DXCC list to most wanted...PASS 2");
        for (DXCCEntity dxccEntity : _dxccList) {
            if (dxccEntity.rankingInMostWanted != 0)
                continue;

            boolean foundMatch = false;
            for (DXCCEntity wantedEntity : _mostWantedList) {
                if (StringUtils.startsWithIgnoreCase(StringUtils.remove(wantedEntity.prefix, '/'),
                        StringUtils.remove(dxccEntity.prefix, '/'))) {
                    dxccEntity.rankingInMostWanted = wantedEntity.rankingInMostWanted;

                    matchedWantedDxccCount++;
                    foundMatch = true;
                    break;
                }
            }

            // if (!foundMatch)
            //   System.out.println("-- prefix "+dxccEntity.prefix+" not found in most wanted list");
        }

        //System.out.println("* Checked "+dxccListCount+" DXCC entities across "+wantedDxccCount+" most wanted and found "+matchedWantedDxccCount+" matches");
    }

    public ArrayList<DXCCEntity> getDXCCList() {
        return _dxccList;
    }

    //
    // for validation purposes only
    //
    private void sortCountriesOnRarity() {

        Comparator<DXCCEntity> dxccListSorter = new Comparator<DXCCEntity>() {

            @Override
            public int compare(DXCCEntity o1, DXCCEntity o2) {
                if (o1.rankingInMostWanted < o2.rankingInMostWanted)
                    return -1;
                else if (o1.rankingInMostWanted > o2.rankingInMostWanted)
                    return 1;
                else
                    return 0;
            }
        };

        Collections.sort(_dxccList, dxccListSorter);
    }

    private void printList() {
        System.out.println("DXCC list sorted on rarity");

        for (int i = 0; i < _dxccList.size(); i++) {
            DXCCEntity entity = _dxccList.get(i);
            System.out.println(String.format("%03d %-5.5s %-40.40s %-2.2s   %8.2f  %03d",
                    entity.rankingInMostWanted, entity.prefix, entity.countryName, entity.continent,
                    entity.distance, (int) entity.bearing));
        }
    }
}