Skip to content

Instantly share code, notes, and snippets.

@Nub
Created November 15, 2011 02:11
Show Gist options
  • Select an option

  • Save Nub/1365914 to your computer and use it in GitHub Desktop.

Select an option

Save Nub/1365914 to your computer and use it in GitHub Desktop.
//
// main.m
// fccRadioListParser
//
// Created by Zachry Thayer on 11/14/11.
// Copyright (c) 2011 Zachry Thayer. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "JSONKit.h"
#define kFCCStationsFile @"FCCStations.txt"
#define kCountryCodesToNamesFile @"countryCodesToNames.json"
#define kStateCodesToNamesFile @"stateCodesToNames.json"
enum FCCIndexes{
Callsign = 1,
Frequency,
Service,
Channel,
DirectionalAntennaDAorNonDirectionalND,
NotUsedforFM,
FMStationClass,
NotUsedforFM2,
FMStatus,
City,
State,
Country,
FileNumberApplicationConstructionPermitorLicenseorDocketNumberRulemaking,
EffectiveRadiatedPower__horizontallypolarizedmaximum,
EffectiveRadiatedPower__verticallypolarizedmaximum,
AntennaHeightAboveAverageTerrainHAAT__horizontalpolarization,
AntennaHeightAboveAverageTerrainHAAT__verticalpolarization,
FacilityIDNumberuniquetoeachstation,
NorthOrSouthLatitude,
DegreesLatitude,
MinutesLatitude,
SecondsLatitude,
WestOrEastLongitude,
DegreesLongitude,
MinutesLongitude,
SecondsLongitude,
LicenseeorPermittee,
Kilometersdistantradiusfromenteredlatitude,longitude,
MilesDistantRadius,
Azimuth,
AntennaRadiationCenterAboveMeanSeaLevelRCAMSL_HorizontallyPolarized_meters,
AntennaRadiationCenterAboveMeanSeaLevelRCAMSL_VerticallyPolarized_meters,
DirectionalAntennaIDNumber,
DirectionalAntennaPatternRotation,
AntennaStructureRegistrationNumber,
ApplicationID,
FCCComponentsCount
};
double decimalDegrees(double degrees, double minutes, double seconds);
double decimalDegrees(double degrees, double minutes, double seconds){
return degrees + minutes/60.f + seconds/3600.f;
}
NSDictionary *countryCodesToNames = nil;
NSDictionary *stateCodesToNames = nil;
NSString *getCountryNameFromCode(NSString* countryCode);
NSString *getCountryNameFromCode(NSString* countryCode){
// if first lookup load DB
if (!countryCodesToNames) {
NSData *countryCodesToNamesData = [NSData dataWithContentsOfFile:kCountryCodesToNamesFile];
countryCodesToNames = [countryCodesToNamesData objectFromJSONData];
}
return [countryCodesToNames objectForKey:countryCode];
}
NSString *getStateNameFromCode(NSString* stateCode, NSString *country);
NSString *getStateNameFromCode(NSString* stateCode, NSString *country){
// if first lookup load DB
if (!stateCodesToNames) {
NSData *stateCodesToNamesData = [NSData dataWithContentsOfFile:kStateCodesToNamesFile];
stateCodesToNames = [stateCodesToNamesData objectFromJSONData];
}
NSDictionary *thisCountry = [stateCodesToNames objectForKey:country];//Must know what country to look in.
if (!thisCountry) {
return nil;
}
return [thisCountry objectForKey:stateCode];
}
void cleanup();
void cleanup(){
if (countryCodesToNames) {
countryCodesToNames = nil;//let arc cleanup
}
}
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSString *fccStationsText = [NSString stringWithContentsOfFile:kFCCStationsFile encoding:NSUTF8StringEncoding error:nil];
if (!fccStationsText) {
return -1;//Fail
}
NSMutableDictionary *fccStations = [NSMutableDictionary dictionary];
[fccStationsText enumerateLinesUsingBlock:^(NSString *line, BOOL *stop){
NSString *trimmedLine = [line stringByReplacingOccurrencesOfString:@" " withString:@""];
NSArray *lineComponents = [trimmedLine componentsSeparatedByString:@"|"];
if (!lineComponents ){//&& [lineComponents count] == FCCComponentsCount) {
return;//Skip to next line, this one is invalid
}
NSString *thisCountryCode = [lineComponents objectAtIndex:Country];
NSString *thisCountryName = getCountryNameFromCode(thisCountryCode);
if (!thisCountryName) {
return;//Skip this country, it's not available.
}
NSString *thisStateCode = [lineComponents objectAtIndex:State];
NSString *thisStateName = getStateNameFromCode(thisStateCode, thisCountryName);
if (!thisStateName) {
return;//Skip this state, it's not available.
}
NSMutableDictionary *thisCountry = [fccStations objectForKey:thisCountryName];
if (!thisCountry) {
//Setup Country if it doesn't exist
thisCountry = [NSMutableDictionary dictionary];
[thisCountry setObject:thisCountryCode forKey:@"Code"];
[thisCountry setObject:[NSMutableDictionary dictionary] forKey:@"Regions"];
[fccStations setObject:thisCountry forKey:thisStateName];
}
NSMutableDictionary *thisState = [[thisCountry objectForKey:@"Regions"] objectForKey:thisStateName];
if (!thisState) {
thisState = [NSMutableDictionary dictionary];
[thisState setObject:thisStateCode forKey:@"Code"];
[thisState setObject:[NSMutableDictionary dictionary] forKey:@"RadioStations"];
[[thisCountry objectForKey:@"Regions"] setObject:thisState forKey:thisStateName];
}
NSMutableDictionary *thisRadioStations = [thisState objectForKey:@"RadioStations"];
//Build station
NSMutableDictionary *thisStation = [NSMutableDictionary dictionary];
if (!thisStation) {
return;//Skip this, bad allocation.
}
NSString *thisStationImageUrl = @"NULL";
[thisStation setObject:thisStationImageUrl forKey:@"imageUrl"];
NSMutableArray *thisRepeatorArray = [NSMutableArray array];
NSMutableDictionary *thisRepeator = [NSMutableDictionary dictionary];
NSString *thisFrequency = [lineComponents objectAtIndex:Frequency];
[thisRepeator setObject:thisFrequency forKey:@"frequency"];
double thisDegreesLatitude = [[lineComponents objectAtIndex:DegreesLongitude] doubleValue];
double thisDegreesLongitude = [[lineComponents objectAtIndex:DegreesLatitude] doubleValue];
double thisMinutesLatitude = [[lineComponents objectAtIndex:MinutesLatitude] doubleValue];
double thisMinutesLongitude = [[lineComponents objectAtIndex:MinutesLongitude] doubleValue];
double thisSecondsLatitude = [[lineComponents objectAtIndex:SecondsLatitude] doubleValue];
double thisSecondsLongitude = [[lineComponents objectAtIndex:SecondsLongitude] doubleValue];
NSNumber *thisLatitude = [NSNumber numberWithDouble:decimalDegrees(thisDegreesLatitude, thisMinutesLatitude, thisSecondsLatitude)];
NSNumber *thisLongitude = [NSNumber numberWithDouble:decimalDegrees(thisDegreesLongitude, thisMinutesLongitude, thisMinutesLongitude)];
[thisRepeator setObject:thisLatitude forKey:@"latitude"];
[thisRepeator setObject:thisLongitude forKey:@"longitude"];
[thisRepeatorArray addObject:thisRepeator];
[thisStation setObject:thisRepeatorArray forKey:@"Repeators"];
//Add station
NSString *thisCallsign = [lineComponents objectAtIndex:Callsign];
[thisRadioStations setObject:thisStation forKey:thisCallsign];
}];
[[fccStations JSONData] writeToFile:@"testOut.json" atomically:YES];
}
cleanup();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment