diff --git a/.gitignore b/.gitignore index 4d64059..d141099 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,37 @@ /node_modules +#Ignore thumbnails created by Windows +Thumbs.db +#Ignore files built by Visual Studio +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +[Dd]ebug*/ +*.lib +*.sbr +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* +.vs/ +#Nuget packages folder +packages/ + + +*.config +SlackBotPrototype/SlackBotPrototype/App.config \ No newline at end of file diff --git a/SlackBotPrototype/.gitignore b/SlackBotPrototype/.gitignore new file mode 100644 index 0000000..27b5c94 --- /dev/null +++ b/SlackBotPrototype/.gitignore @@ -0,0 +1,32 @@ + +#Ignore thumbnails created by Windows +Thumbs.db +#Ignore files built by Visual Studio +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +[Dd]ebug*/ +*.lib +*.sbr +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* +.vs/ +#Nuget packages folder +packages/ diff --git a/SlackBotPrototype/API.Tests/API.Tests.csproj b/SlackBotPrototype/API.Tests/API.Tests.csproj new file mode 100644 index 0000000..c35b6b5 --- /dev/null +++ b/SlackBotPrototype/API.Tests/API.Tests.csproj @@ -0,0 +1,72 @@ + + + + + Debug + AnyCPU + {BEAB33E8-9F1E-4D39-B741-2069E95834DD} + Library + Properties + API.Tests + API.Tests + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Castle.Core.4.1.1\lib\net45\Castle.Core.dll + + + ..\packages\Moq.4.7.99\lib\net45\Moq.dll + + + ..\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll + + + + + + + + + + + + + + + + + + + + + Designer + + + + + + {A234D7B8-EAB9-497F-84E7-354DC066BCB5} + API + + + + \ No newline at end of file diff --git a/SlackBotPrototype/API.Tests/CommandTests.cs b/SlackBotPrototype/API.Tests/CommandTests.cs new file mode 100644 index 0000000..883ac22 --- /dev/null +++ b/SlackBotPrototype/API.Tests/CommandTests.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Moq; +using NUnit.Framework; + +namespace API.Tests +{ + + [TestFixture] + public class CommandTests : EmbeddedResourceTestBase + { + private static readonly Location TestLocation = + new Location {Latitude = 38.889931, Longitude = -77.009003, DisplayName = "Washington, DC"}; + + private IWeatherProvider _weatherProvider; + private IRepository _repository; + + [OneTimeSetUp] + public void Init() + { + var mockHttp = new Mock(); + + var dailyForecastJson = GetFromResource("dc-daily.json"); + mockHttp.Setup(m => m.GetContent(It.IsAny())).Returns(dailyForecastJson); + _weatherProvider = new DarkSkyWeatherProvider(ConfigConstants.DarkSkyApiSecret, mockHttp.Object); + + var mockRepo = new Mock(); + mockRepo.Setup(m => m.GetLocation("San Francisco", "CA")) + .Returns(new Location() { City = "San Francisco", State = "CA", DisplayName = "San Francisco, CA" }); + + _repository = mockRepo.Object; + } + + [Test] + public void TestLocationInvalidWeatherCommand() + { + + var location = new Location() + { + Latitude = 0, + Longitude = 0 + }; + + var when = DateTime.Parse("2017/07/01"); + + var weatherCommand = new WeatherNowCommand(_weatherProvider, location, when); + var msg = weatherCommand.Invoke(); + + // SHORTCUT: A bit of shortcut here, normally we'd define a + // some sort of reponse code enum and test based on the response code. + // Since we don't return a result code right now (requires more boilerplate), just test based on expected string. + Assert.IsTrue(msg.Contains("No location specified")); + } + + [Test] + public void TestValidLocationWeatherCommand() + { + var when = DateTime.Parse("2017/07/01"); + + var weatherCommand = new WeatherNowCommand(_weatherProvider, TestLocation, when); + var msg = weatherCommand.Invoke(); + + // we know that we always include the city in weather results, this would have + // to be updated as things change + Assert.IsTrue(msg.Contains("Washington, DC")); + } + + [Test] + public void TestSetLocationCommand() + { + var location = new Location(); + + var setLocationCommand = new SetUserLocationCommand(_repository, "Test", "123", location); + var msg = setLocationCommand.Invoke(); + + Assert.IsTrue(msg.Contains("Location invalid")); + } + + [Test] + public void TestSetValidLocationCommand() + { + var setLocationCommand = new SetUserLocationCommand(_repository, "Test", "123", TestLocation); + + // Don't think there's much of a point to testing the repository inserts since + // without setting up an integration test with SQLite + var msg = setLocationCommand.Invoke(); + + Assert.IsTrue(msg.Contains("Set location")); + } + + [Test] + public void TestSetNullLocation() + { + var setLocationCommand = new SetUserLocationCommand(_repository, "Test", "123", null); + + // Don't think there's much of a point to testing the repository inserts since + // without setting up an integration test with SQLite + var msg = setLocationCommand.Invoke(); + + Assert.IsTrue(msg.Contains("Location not found")); + } + + [TestCase(ExpectedResult = "")] + public string TestNoopCommand() + { + var noop = new NoOpCommand(); + return noop.Invoke(); + } + + [Test] + public void TestWhatToWearCommand() + { + var whatToWear = new WhatToWearCommand(_weatherProvider); + var msg = whatToWear.Invoke(); + + Assert.IsTrue(msg == "Bring a jacket"); + } + } +} diff --git a/SlackBotPrototype/API.Tests/DarkSkyTests.cs b/SlackBotPrototype/API.Tests/DarkSkyTests.cs new file mode 100644 index 0000000..4bb0f2c --- /dev/null +++ b/SlackBotPrototype/API.Tests/DarkSkyTests.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Moq; +using NUnit.Framework; + +namespace API.Tests +{ + + /// + /// Not a unit test, normally would do this in separate REPL but + /// put here for demonstrative purposes + /// + [TestFixture] + public class TestDarkskyRequests : EmbeddedResourceTestBase + { + private Location _testLocation; + private IWeatherProvider _weatherProvider; + + [OneTimeSetUp] + public void Init() + { + _testLocation = new Location() { Latitude = 38.889931, Longitude = -77.0369 }; + + var mockHttp = new Mock(); + + var dcDailyForecastJson = GetFromResource("dc-daily.json"); + mockHttp.Setup(m => m.GetContent(It.IsRegex("-77.0369"))).Returns(dcDailyForecastJson); + _weatherProvider = new DarkSkyWeatherProvider(ConfigConstants.DarkSkyApiSecret, mockHttp.Object); + } + + [Test] + public void TestGetDailyForecast() + { + var forecast = _weatherProvider.GetForecast(_testLocation, DateTime.Now); + Assert.IsNotNull(forecast); + } + + [Test] + public void TestSummary() + { + var forecast = _weatherProvider.GetForecast(_testLocation, DateTime.Now); + Assert.IsTrue(forecast == "Partly cloudy starting in the evening."); + } + + // SHORTCUT: Skip testing for time based weather requests, we'd need to mock out + // the requests which doesn't really help testing the temporal component of the weather + // requests as those are really mainly handled by DarkSky + } +} diff --git a/SlackBotPrototype/API.Tests/EmbeddedResourceTestBase.cs b/SlackBotPrototype/API.Tests/EmbeddedResourceTestBase.cs new file mode 100644 index 0000000..17e66f7 --- /dev/null +++ b/SlackBotPrototype/API.Tests/EmbeddedResourceTestBase.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; + +namespace API.Tests +{ + public class EmbeddedResourceTestBase + { + + protected string GetFromResource(string fileName) + { + if (fileName == null) + throw new ArgumentNullException(nameof(fileName)); + + var assembly = Assembly.GetExecutingAssembly(); + var resourceName = assembly.GetManifestResourceNames().First(x => x.Contains(fileName)); + + using (var file = assembly.GetManifestResourceStream(resourceName)) + { + if (file == null) + Assert.Fail(); + + using (var sr = new StreamReader(file)) + { + var json = sr.ReadToEnd(); + return json; + } + } + } + } +} diff --git a/SlackBotPrototype/API.Tests/LocationServiceTests.cs b/SlackBotPrototype/API.Tests/LocationServiceTests.cs new file mode 100644 index 0000000..eb6177d --- /dev/null +++ b/SlackBotPrototype/API.Tests/LocationServiceTests.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Moq; +using NUnit.Framework; + +namespace API.Tests +{ + + [TestFixture] + public class LocationServiceTests + { + // SHORTCUT: We wouldn't normally be able to test a + // location service like this since it'd probably involve a service call. We'd need to mock + // it in some way. + private LocationService _locationService; + + [OneTimeSetUp] + public void Init() + { + // Not much of a point to mock up (test) DB retrieval since there's really no logic in repository + // at this moment + var repository = new Mock(); + _locationService = new LocationService(repository.Object); + } + + [TestCase("Invalid")] + [TestCase("")] + [TestCase(null)] + public void TestInvalidLocation(string name) + { + var location = new Location() + { + DisplayName = name + }; + + Assert.IsTrue(location.IsInvalid(), "location.IsInvalid() != true"); + } + + // Since we don't have an integrated test setup with SQLite + // there's not really a point to testing retrieval from a mock object as there's not + // much logic in the retrieval code. Just verify that we handle nulls correctly. + [TestCase(100, ExpectedResult = null)] + [TestCase(-1, ExpectedResult = null)] + public Location TestGetLocationById(int id) + { + return _locationService.GetLocation(id); + } + } +} diff --git a/SlackBotPrototype/API.Tests/MessageParserTests.cs b/SlackBotPrototype/API.Tests/MessageParserTests.cs new file mode 100644 index 0000000..05c06b8 --- /dev/null +++ b/SlackBotPrototype/API.Tests/MessageParserTests.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Moq; +using NUnit.Framework; + +namespace API.Tests +{ + + [TestFixture] + public class MessageParserTests : EmbeddedResourceTestBase + { + private MessageToCommandConverter _messageToCommandConverter; + + [OneTimeSetUp] + public void Init() + { + var mockHttp = new Mock(); + + var dailyForecastJson = GetFromResource("dc-daily.json"); + mockHttp.Setup(m => m.GetContent(It.IsAny())).Returns(dailyForecastJson); + + var weatherProvider = new DarkSkyWeatherProvider(ConfigConstants.DarkSkyApiSecret, mockHttp.Object); + + var mockRepo = new Mock(); + mockRepo.Setup(m => m.GetLocation("San Francisco", "CA")) + .Returns(new Location() {City = "San Francisco", State = "CA", DisplayName = "San Francisco, CA"}); + mockRepo.Setup(m => m.GetLocation("new york", "ny")) + .Returns(new Location() { City = "New York", State = "NY", DisplayName = "New York, NY" }); + mockRepo.Setup(m => m.GetLocation("New York", "NY")) + .Returns(new Location() { City = "New York", State = "NY", DisplayName = "New York, NY" }); + + _messageToCommandConverter = new MessageToCommandConverter(weatherProvider, mockRepo.Object); + } + + [TestCase("<@U6BQE1XGD> weather now", typeof(WeatherNowCommand))] + [TestCase("<@U6BQE1XGD> weather tomorrow", typeof(WeatherNowCommand))] + [TestCase("<@U6BQE1XGD> weather today", typeof(InvalidCommand))] + [TestCase("<@U6BQE1XGD> WEATHER NOW!", typeof(NoOpCommand))] + [TestCase("<@U6BQE1XGD> WEATHER TOMORROW", typeof(WeatherNowCommand))] + [TestCase("<@U6BQE1XGD> What should I wear?", typeof(WhatToWearCommand))] + [TestCase("<@U6BQE1XGD> Set me to San Fransisco, CA", typeof(SetUserLocationCommand))] + [TestCase("<@U6BQE1XGD> Set me to new york, ny", typeof(SetUserLocationCommand))] + [TestCase("<@U6BQE1XGD> Set me to Washington, DC", typeof(SetUserLocationCommand))] + [TestCase("<@U6BQE1XGD> Set me to Nowheresville123, NY", typeof(SetUserLocationCommand))] + [TestCase("<@U6BQE1XGD> Weather now San Francisco, CA", typeof(WeatherNowCommand))] + [TestCase("<@U6BQE1XGD> set me to new york, ny", typeof(SetUserLocationCommand))] + [TestCase("<@U6BQE1XGD> set me to Unrecognizable location, OkayCity", typeof(SetUserLocationCommand))] + [TestCase("<@U6BQE1XGD> set me to Unrecognizable location!!! !!, OkayCity", typeof(SetUserLocationCommand))] + [TestCase("<@U6BQE1XGD> Weather now New York, NY", typeof(WeatherNowCommand))] + [TestCase("<@U6BQE1XGD> Hello", typeof(NoOpCommand))] + [TestCase("set me to new york, ny", typeof(NoOpCommand))] + [TestCase("weather now", typeof(NoOpCommand))] + [TestCase("", typeof(NoOpCommand))] + [TestCase(null, typeof(NoOpCommand))] + public void VerifyCommands(string message, Type expectedType) + { + var resp = _messageToCommandConverter.HandleRequest("test", message); + var command = resp.Command; + + Assert.IsTrue(expectedType == command.GetType(), $"command did not match expected for message: {message} --> {command.GetType()}"); + } + } +} diff --git a/SlackBotPrototype/API.Tests/Properties/AssemblyInfo.cs b/SlackBotPrototype/API.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..740a44a --- /dev/null +++ b/SlackBotPrototype/API.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("API.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("API.Tests")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("beab33e8-9f1e-4d39-b741-2069e95834dd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SlackBotPrototype/API.Tests/TestData/dc-daily.json b/SlackBotPrototype/API.Tests/TestData/dc-daily.json new file mode 100644 index 0000000..f7f9ec2 --- /dev/null +++ b/SlackBotPrototype/API.Tests/TestData/dc-daily.json @@ -0,0 +1,258 @@ +{ + "latitude": 38.9072, + "longitude": -77.0369, + "timezone": "America/New_York", + "offset": -4, + "daily": { + "summary": "Light rain on Monday through next Friday, with temperatures falling to 73°F next Friday.", + "icon": "rain", + "data": [{ + "time": 1501819200, + "summary": "Partly cloudy starting in the evening.", + "icon": "partly-cloudy-night", + "sunriseTime": 1501841593, + "sunsetTime": 1501892265, + "moonPhase": 0.4, + "precipIntensity": 0.0007, + "precipIntensityMax": 0.0038, + "precipIntensityMaxTime": 1501902000, + "precipProbability": 0.11, + "precipType": "rain", + "temperatureMin": 68.5, + "temperatureMinTime": 1501840800, + "temperatureMax": 89.4, + "temperatureMaxTime": 1501873200, + "apparentTemperatureMin": 69.49, + "apparentTemperatureMinTime": 1501840800, + "apparentTemperatureMax": 93.91, + "apparentTemperatureMaxTime": 1501866000, + "dewPoint": 67.87, + "humidity": 0.73, + "windSpeed": 3.83, + "windGust": 18.95, + "windGustTime": 1501891200, + "windBearing": 169, + "visibility": 9.95, + "cloudCover": 0.12, + "pressure": 1014.69, + "ozone": 307.17, + "uvIndex": 9, + "uvIndexTime": 1501866000 + }, { + "time": 1501905600, + "summary": "Mostly cloudy until afternoon.", + "icon": "partly-cloudy-day", + "sunriseTime": 1501928047, + "sunsetTime": 1501978600, + "moonPhase": 0.43, + "precipIntensity": 0.0005, + "precipIntensityMax": 0.0035, + "precipIntensityMaxTime": 1501912800, + "precipProbability": 0.06, + "precipType": "rain", + "temperatureMin": 69.22, + "temperatureMinTime": 1501988400, + "temperatureMax": 79.33, + "temperatureMaxTime": 1501966800, + "apparentTemperatureMin": 69.22, + "apparentTemperatureMinTime": 1501988400, + "apparentTemperatureMax": 79.33, + "apparentTemperatureMaxTime": 1501966800, + "dewPoint": 59.32, + "humidity": 0.61, + "windSpeed": 7.69, + "windGust": 21.69, + "windGustTime": 1501938000, + "windBearing": 298, + "cloudCover": 0.44, + "pressure": 1014.64, + "ozone": 311.44, + "uvIndex": 7, + "uvIndexTime": 1501952400 + }, { + "time": 1501992000, + "summary": "Light rain overnight.", + "icon": "rain", + "sunriseTime": 1502014502, + "sunsetTime": 1502064934, + "moonPhase": 0.46, + "precipIntensity": 0, + "precipIntensityMax": 0, + "precipProbability": 0, + "temperatureMin": 63.71, + "temperatureMinTime": 1502010000, + "temperatureMax": 81.53, + "temperatureMaxTime": 1502053200, + "apparentTemperatureMin": 63.71, + "apparentTemperatureMinTime": 1502010000, + "apparentTemperatureMax": 81.53, + "apparentTemperatureMaxTime": 1502053200, + "dewPoint": 53.96, + "humidity": 0.53, + "windSpeed": 1.46, + "windGust": 15.99, + "windGustTime": 1502074800, + "windBearing": 195, + "cloudCover": 0.48, + "pressure": 1020.12, + "ozone": 300.61, + "uvIndex": 6, + "uvIndexTime": 1502038800 + }, { + "time": 1502078400, + "summary": "Rain throughout the day.", + "icon": "rain", + "sunriseTime": 1502100957, + "sunsetTime": 1502151267, + "moonPhase": 0.49, + "precipIntensity": 0.029, + "precipIntensityMax": 0.0685, + "precipIntensityMaxTime": 1502118000, + "precipProbability": 0.88, + "precipType": "rain", + "temperatureMin": 69.32, + "temperatureMinTime": 1502103600, + "temperatureMax": 76.38, + "temperatureMaxTime": 1502143200, + "apparentTemperatureMin": 69.65, + "apparentTemperatureMinTime": 1502103600, + "apparentTemperatureMax": 77.43, + "apparentTemperatureMaxTime": 1502143200, + "dewPoint": 65.55, + "humidity": 0.79, + "windSpeed": 5.67, + "windGust": 21.82, + "windGustTime": 1502118000, + "windBearing": 181, + "cloudCover": 0.92, + "pressure": 1016.01, + "ozone": 290.12, + "uvIndex": 6, + "uvIndexTime": 1502125200 + }, { + "time": 1502164800, + "summary": "Mostly cloudy throughout the day.", + "icon": "partly-cloudy-day", + "sunriseTime": 1502187412, + "sunsetTime": 1502237598, + "moonPhase": 0.53, + "precipIntensity": 0.0009, + "precipIntensityMax": 0.016, + "precipIntensityMaxTime": 1502164800, + "precipProbability": 0.28, + "precipType": "rain", + "temperatureMin": 68.09, + "temperatureMinTime": 1502193600, + "temperatureMax": 78.45, + "temperatureMaxTime": 1502226000, + "apparentTemperatureMin": 68.52, + "apparentTemperatureMinTime": 1502247600, + "apparentTemperatureMax": 78.59, + "apparentTemperatureMaxTime": 1502226000, + "dewPoint": 63, + "humidity": 0.73, + "windSpeed": 5.36, + "windGust": 16.38, + "windGustTime": 1502175600, + "windBearing": 350, + "cloudCover": 0.88, + "pressure": 1016.18, + "ozone": 299.76, + "uvIndex": 5, + "uvIndexTime": 1502208000 + }, { + "time": 1502251200, + "summary": "Mostly cloudy throughout the day.", + "icon": "partly-cloudy-day", + "sunriseTime": 1502273867, + "sunsetTime": 1502323928, + "moonPhase": 0.56, + "precipIntensity": 0.0004, + "precipIntensityMax": 0.0018, + "precipIntensityMaxTime": 1502269200, + "precipProbability": 0.01, + "precipType": "rain", + "temperatureMin": 66.31, + "temperatureMinTime": 1502258400, + "temperatureMax": 79.17, + "temperatureMaxTime": 1502312400, + "apparentTemperatureMin": 66.31, + "apparentTemperatureMinTime": 1502258400, + "apparentTemperatureMax": 79.17, + "apparentTemperatureMaxTime": 1502312400, + "dewPoint": 57.95, + "humidity": 0.62, + "windSpeed": 4.04, + "windGust": 15.71, + "windGustTime": 1502334000, + "windBearing": 94, + "cloudCover": 0.47, + "pressure": 1022.09, + "ozone": 308.79, + "uvIndex": 6, + "uvIndexTime": 1502298000 + }, { + "time": 1502337600, + "summary": "Light rain in the morning and afternoon.", + "icon": "rain", + "sunriseTime": 1502360322, + "sunsetTime": 1502410256, + "moonPhase": 0.59, + "precipIntensity": 0.0113, + "precipIntensityMax": 0.0339, + "precipIntensityMaxTime": 1502406000, + "precipProbability": 0.44, + "precipType": "rain", + "temperatureMin": 66.88, + "temperatureMinTime": 1502341200, + "temperatureMax": 79.46, + "temperatureMaxTime": 1502388000, + "apparentTemperatureMin": 67.03, + "apparentTemperatureMinTime": 1502341200, + "apparentTemperatureMax": 81.4, + "apparentTemperatureMaxTime": 1502388000, + "dewPoint": 64.56, + "humidity": 0.76, + "windSpeed": 4.8, + "windGust": 22.06, + "windGustTime": 1502366400, + "windBearing": 130, + "cloudCover": 0.85, + "pressure": 1018.99, + "ozone": 290.2, + "uvIndex": 6, + "uvIndexTime": 1502384400 + }, { + "time": 1502424000, + "summary": "Rain throughout the day.", + "icon": "rain", + "sunriseTime": 1502446777, + "sunsetTime": 1502496584, + "moonPhase": 0.63, + "precipIntensity": 0.0244, + "precipIntensityMax": 0.0668, + "precipIntensityMaxTime": 1502442000, + "precipProbability": 0.6, + "precipType": "rain", + "temperatureMin": 68.63, + "temperatureMinTime": 1502452800, + "temperatureMax": 72.62, + "temperatureMaxTime": 1502467200, + "apparentTemperatureMin": 69.4, + "apparentTemperatureMinTime": 1502452800, + "apparentTemperatureMax": 73.42, + "apparentTemperatureMaxTime": 1502467200, + "dewPoint": 67.07, + "humidity": 0.89, + "windSpeed": 3.96, + "windGust": 10.47, + "windGustTime": 1502488800, + "windBearing": 83, + "cloudCover": 0.87, + "pressure": 1016.08, + "ozone": 287.07, + "uvIndex": 6, + "uvIndexTime": 1502470800 + }] + } +} \ No newline at end of file diff --git a/SlackBotPrototype/API.Tests/packages.config b/SlackBotPrototype/API.Tests/packages.config new file mode 100644 index 0000000..eaa6c5c --- /dev/null +++ b/SlackBotPrototype/API.Tests/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SlackBotPrototype/API/API.csproj b/SlackBotPrototype/API/API.csproj new file mode 100644 index 0000000..69306a3 --- /dev/null +++ b/SlackBotPrototype/API/API.csproj @@ -0,0 +1,181 @@ + + + + + Debug + AnyCPU + {A234D7B8-EAB9-497F-84E7-354DC066BCB5} + Library + Properties + API + API + v4.5.2 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.AWT.WinForms.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Beans.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Charsets.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Cldrdata.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Corba.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Core.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Jdbc.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Localedata.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Management.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Media.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Misc.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Naming.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Nashorn.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Remoting.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Security.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.SwingAWT.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Text.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Tools.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Util.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.API.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Bind.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Crypto.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Parse.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Transform.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.WebServices.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.XPath.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.Runtime.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.Runtime.JNI.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll + + + ..\packages\sqlite-net-pcl.1.5.151-beta\lib\netstandard1.1\SQLite-net.dll + + + ..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_green.dll + + + ..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_v2.dll + + + ..\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll + + + ..\packages\SQLitePCLRaw.provider.e_sqlite3.net45.1.1.8\lib\net45\SQLitePCLRaw.provider.e_sqlite3.dll + + + ..\packages\Stanford.NLP.POSTagger.3.7.0.1\lib\stanford-postagger-3.7.0.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + \ No newline at end of file diff --git a/SlackBotPrototype/API/Commands.cs b/SlackBotPrototype/API/Commands.cs new file mode 100644 index 0000000..7eecb63 --- /dev/null +++ b/SlackBotPrototype/API/Commands.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace API +{ + public class WeatherNowCommand : ICommandImpl + { + private readonly IWeatherProvider _weatherProvider; + private readonly Location _location; + private readonly DateTime _when; + + // SHORTCUT: Could set up dependency injection here instead of using constructors. + // We need to pass in dependencies for commands to make them easier to test + public WeatherNowCommand(IWeatherProvider weatherProvider, Location location, DateTime when) + { + _weatherProvider = weatherProvider; + _location = location; + _when = when; + } + + public string Invoke() + { + return _location.IsInvalid() + ? "No location specified. Specify location or set your location with `set me to City, State`, eg. `set me to new york, ny" + : $"{_location.DisplayName}: {_weatherProvider.GetForecast(_location, _when)}"; + } + } + + public class WhatToWearCommand : ICommandImpl + { + private readonly IWeatherProvider _weatherProvider; + + // SHORTCUT: We could choose to keep this lookup in a configuration file, or in persistence layer (DB). + // This would allow us to update the mapping without having to deploy code. + private readonly IDictionary _weatherToClothingLookup = new Dictionary + { + {"clear-day", "Wear your comfortable clothing, no jacket required"}, + {"clear-night", "Wear your comfortable clothing, no jacket required"}, + {"snow", "Wear winter jackets, bring boots!"}, + {"wind", "Bring a wind jacket, it\'s going to breezy"}, + {"partly-cloudy-day","Bring a jacket"}, + {"partly-cloudy-night","Bring a jacket"}, + {"cloudy","Bring a jacket"}, + {"fog","Bring a jacket"}, + {"rain", "Dress comfortably, bring an umbrella"} + }; + + public WhatToWearCommand(IWeatherProvider weatherProvider) + { + _weatherProvider = weatherProvider; + } + + public string Invoke() + { + // SHORTCUT: Not implementing location support for this command to save time, it's not in scope of project. + // Just use a hard coded location. + var dcLocation = new Location {Latitude = 38.889931, Longitude = -77.009003, DisplayName = "Washington, DC"}; + var summaryIcon = _weatherProvider.GetForecastRaw(dcLocation, DateTime.Now).Icon; + return _weatherToClothingLookup.TryGetValue(summaryIcon, out string recommendation) ? recommendation : "I don't know, anything you want?"; + } + } + + public class SetUserLocationCommand : ICommandImpl + { + private readonly IRepository _repository; + private readonly string _name; + private readonly string _slackId; + private readonly Location _location; + + // We need to pass in dependencies for commands to make them easier to test + public SetUserLocationCommand(IRepository repository, string name, string slackId, Location location) + { + _repository = repository; + _name = name; + _slackId = slackId; + _location = location; + } + + public string Invoke() + { + if (_location == null) + { + return "Location not found"; + } + + if (_location.IsInvalid()) + { + return "Location invalid"; + } + + _repository.CreateOrUpdate(_name, _slackId, _location); + return $"Set location to: {_location.DisplayName}"; + } + } + + public class InvalidCommand : ICommandImpl + { + private readonly string _message; + + public InvalidCommand() + { + } + + public InvalidCommand(string message) + { + _message = message; + } + + public string Invoke() + { + return _message ?? "Huh?"; + } + } + + public class NoOpCommand : ICommandImpl + { + public string Invoke() + { + return string.Empty; + } + } +} diff --git a/SlackBotPrototype/API/ConfigConstants.cs b/SlackBotPrototype/API/ConfigConstants.cs new file mode 100644 index 0000000..f8389f7 --- /dev/null +++ b/SlackBotPrototype/API/ConfigConstants.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace API +{ + public static class ConfigConstants + { + public static readonly string DarkSkyApiSecret = Environment.GetEnvironmentVariable("DARK_SKY_TOKEN"); + public static readonly string SlackApiSecret = Environment.GetEnvironmentVariable("SLACK_API_TOKEN"); + public const string DbName = "SlackBotDb.db"; + public const string DarkSkyBaseUrl = "https://api.darksky.net"; + } +} diff --git a/SlackBotPrototype/API/DarkSkyWeatherProvider.cs b/SlackBotPrototype/API/DarkSkyWeatherProvider.cs new file mode 100644 index 0000000..33b484f --- /dev/null +++ b/SlackBotPrototype/API/DarkSkyWeatherProvider.cs @@ -0,0 +1,44 @@ +using System; +using System.Linq; +using Newtonsoft.Json; + +namespace API +{ + + public class DarkSkyWeatherProvider : IWeatherProvider + { + private readonly string _apiSecret; + private readonly IHttpRequestClient _client; + + public DarkSkyWeatherProvider(string apiSecret, IHttpRequestClient client) + { + _apiSecret = apiSecret; + _client = client; + } + + public string GetForecast(Location location, DateTime when) + { + var forecastItem = GetForecastRaw(location, when); + return forecastItem.Summary; + } + + public ChatBotForecast GetForecastRaw(Location location, DateTime when) + { + + var timeStamp = when.DateTimeToUnixTimestamp(); + // SHORTCUT: We could cache requests in memory for recent forecast requests so we don't have + // to keep making network calls and improve performance. The tricky part would be + // figuring out what's the right invalidation scheme. It would probably involve the time + // returned in each request, location, and UTC time. Skipping it for now. + var content = _client.GetContent($"/forecast/{_apiSecret}/{location.Latitude},{location.Longitude},{(int)timeStamp}?exclude=currently,minutely,hourly,flags"); + var forecastItem = JsonConvert.DeserializeObject(content); + + return new ChatBotForecast + { + Location = location, + Icon = forecastItem.Daily.Data.FirstOrDefault()?.Icon, + Summary = forecastItem.Daily.Data.FirstOrDefault()?.Summary + }; + } + } +} diff --git a/SlackBotPrototype/API/Extensions.cs b/SlackBotPrototype/API/Extensions.cs new file mode 100644 index 0000000..d409270 --- /dev/null +++ b/SlackBotPrototype/API/Extensions.cs @@ -0,0 +1,15 @@ +using System; + +namespace API +{ + public static class Extensions + { + + public static double DateTimeToUnixTimestamp(this DateTime dateTime) + { + return (TimeZoneInfo.ConvertTimeToUtc(dateTime) - + new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; + } + + } +} diff --git a/SlackBotPrototype/API/ExternalModels.cs b/SlackBotPrototype/API/ExternalModels.cs new file mode 100644 index 0000000..9005fe0 --- /dev/null +++ b/SlackBotPrototype/API/ExternalModels.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace API +{ + // Notes: Normally in web context, we'd have have separate domain + // models for back end and front end. In the case of the chatbot, we + // have model objects for external services and model objects for our our + // domain model (e.g. Users) + + public class ForecastItem + { + [JsonProperty("daily")] + public DailyForecastItem Daily { get; set; } + } + + public class DailyForecastItem + { + [JsonProperty("data")] + public List Data { get; set; } + } + + public class TemporalDataBlock + { + [JsonProperty("summary")] + public string Summary { get; set; } + [JsonProperty("icon")] + public string Icon { get; set; } + [JsonProperty("apparentTemperatureMax")] + public string ApparentTemperatureMax { get; set; } + } +} diff --git a/SlackBotPrototype/API/Interfaces.cs b/SlackBotPrototype/API/Interfaces.cs new file mode 100644 index 0000000..2e46c6d --- /dev/null +++ b/SlackBotPrototype/API/Interfaces.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; + +namespace API +{ + /// + /// Internal interface to decouple weather service + /// + public interface IWeatherProvider + { + string GetForecast(Location location, DateTime when); + ChatBotForecast GetForecastRaw(Location location, DateTime when); + } + + public interface IMessageToCommandConverter + { + MessageParserResponse HandleRequest(string slackId, string message); + } + + public interface IHttpRequestClient + { + /// + /// Makes an http GET request and returns the content. + /// + /// Normally we encapsulate the whole response object in a DTO object so we can handle different HTTP status + /// codes and error conditions. To save time, we're only going to handle HTTP Status = 200, other other status codes + /// will return no content. + /// + /// the url to resource to request + /// the content of the response if successful otherwise null + string GetContent(string url); + } + + /// + /// Define a interface for user persistence, in a production app the de-coupling + /// this allows us to swap ersistence strategies as needed from in-memory object, flat file, + /// or whatever DB desired + /// + public interface IRepository + { + User Get(string slackId); + Location GetLocation(string city, string state); + Location GetLocation(int id); + int CreateOrUpdate(string name, string slackId, Location location = null); + + // Shortcut: skipping some CRUD + } + + public interface ICommandImpl + { + // Invoke the command, expects a single string result. + // This could be changed later as needed to a more complex object. + string Invoke(); + } + + /// + /// Define an interface for a service that will provide location information + /// + public interface ILocationService + { + Location GetLocation(string city, string stateAbbreviation); + Location GetLocation(int id); + } + +} diff --git a/SlackBotPrototype/API/LocationService.cs b/SlackBotPrototype/API/LocationService.cs new file mode 100644 index 0000000..c7e082d --- /dev/null +++ b/SlackBotPrototype/API/LocationService.cs @@ -0,0 +1,24 @@ +using System.Linq; + +namespace API +{ + public class LocationService : ILocationService + { + private readonly IRepository _repository; + + public LocationService(IRepository repository) + { + _repository = repository; + } + + public Location GetLocation(string city, string stateAbbreviation) + { + return _repository.GetLocation(city, stateAbbreviation); + } + + public Location GetLocation(int id) + { + return _repository.GetLocation(id); + } + } +} diff --git a/SlackBotPrototype/API/MessageParser.cs b/SlackBotPrototype/API/MessageParser.cs new file mode 100644 index 0000000..1604a4d --- /dev/null +++ b/SlackBotPrototype/API/MessageParser.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Console = System.Console; +using edu.stanford.nlp.ling; +using edu.stanford.nlp.tagger.maxent; + +namespace API +{ + public class MessageParser : IMessageParser + { + private readonly string _modelsDirectory; + + public MessageParser(string nlpFolder) + { + _modelsDirectory = nlpFolder + @"\models"; + } + + public string HandleRequest(string message) + { + var wordSet = BuildWordSet(message); + var weatherProvider = new DarkSkyWeatherProvider(ConfigConstants.DarkSkyApiSecret); + + if (wordSet.Contains("wear", StringComparer.InvariantCultureIgnoreCase) && + wordSet.Contains("I", StringComparer.InvariantCultureIgnoreCase)) + { + var rawForecast = weatherProvider.GetForecastRaw(DateTime.Now); + var icon = rawForecast.Daily.Data.FirstOrDefault()?.Icon; + + // Skip accounting for temperature for now, could have thresholds for certain apparel + switch (icon) + { + case "clear-day": + case "clear-night": + return "Wear your comfortable clothing, no jacket required"; + case "snow": + return "Wear winter jackets, bring boots!"; + case "wind": + return "Bring a wind jacket, it\'s going to breezy"; + case "partly-cloudy-day": + case "partly-cloudy-night": + case "cloudy": + case "fog": + return "Bring a jacket"; + case "rain": + return "Dress comfortably, bring an umbrella"; + + default: + return "I don't know, anything you want?"; + } + } + + if (wordSet.Contains("weather", StringComparer.InvariantCultureIgnoreCase)) + { + if (wordSet.Contains("now", StringComparer.InvariantCultureIgnoreCase) + || wordSet.Contains("today", StringComparer.InvariantCultureIgnoreCase)) + { + return weatherProvider.GetForecast(DateTime.Now); + } + + if (wordSet.Contains("tomorrow")) + { + return weatherProvider.GetForecast(DateTime.Now.AddDays(1)); + } + + return "Weather now or tomorrow?"; + } + + return string.Empty; + } + + public HashSet BuildWordSet(string message) + { + var tagger = new MaxentTagger(_modelsDirectory + @"\wsj-0-18-bidirectional-distsim.tagger"); + + var sentences = MaxentTagger.tokenizeText(new java.io.StringReader(message)).toArray(); + var wordSet = new HashSet(); + + foreach (java.util.ArrayList sentence in sentences) + { + var taggedSentence = tagger.tagSentence(sentence); + + Console.WriteLine(SentenceUtils.listToString(taggedSentence, false)); + + for (var i = 0; i < taggedSentence.size(); i++) + { + var taggedWord = taggedSentence.get(i) as TaggedWord; + + if (taggedWord == null) + continue; + + // could use part of speech and sentence structure as well + var value = taggedWord.value(); + + if (wordSet.Contains(value)) + continue; + + wordSet.Add(value); + } + } + + return wordSet; + } + } +} diff --git a/SlackBotPrototype/API/MessageToCommandConverter.cs b/SlackBotPrototype/API/MessageToCommandConverter.cs new file mode 100644 index 0000000..4a0a688 --- /dev/null +++ b/SlackBotPrototype/API/MessageToCommandConverter.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace API +{ + public class MessageToCommandConverter : IMessageToCommandConverter + { + private readonly IWeatherProvider _weatherProvider; + private readonly IRepository _repository; + + // Build a dictionary of regex patterns to match for commands, we iterate through sequentially so + // order of patterns matters, since the first match is the one we go with. Once we reach a certain number of commands this + // will become unwieldy. At that point we'd need to switch to something more robust for parsing like NLP + // + // Shortcut: We use a tuple here but this could be a class instead, reducing boilerplate by skipping another class + private readonly ICollection>> _messageMap = + new List>> + { + new Tuple>(new Regex("^<@.*>\\sset me to\\s(.*)\\s?[,]\\s(.*)$", RegexOptions.IgnoreCase), BuildSetLocation), + new Tuple>(new Regex("^<@.*>\\sweather\\s(now|today|tomorrow)$", RegexOptions.IgnoreCase), BuildWeatherNow), + new Tuple>(new Regex("^<@.*>\\sweather\\s(now|today|tomorrow)\\s(.*)\\s?[,]\\s(.*)$", RegexOptions.IgnoreCase), BuildWeatherNowWithLocation), + new Tuple>(new Regex("^<@.*>\\swhat should i wear", RegexOptions.IgnoreCase), BuildWhatToWear) + }; + + private readonly LocationService _locationService; + + private static ICommandImpl BuildSetLocation(SlackQueryDto dto) + { + var matches = dto.QueryParams; + var invalid = new InvalidCommand(); + + if (matches.Count == 0) + { + return invalid; + } + + var city = matches.Skip(0).Take(1).First(); + var state = matches.Skip(1).Take(1).First(); + + var location = dto.LocationService.GetLocation(city, state); + + return new SetUserLocationCommand(dto.Repository, dto.UserSlackId, dto.UserSlackId, location); + } + + private static ICommandImpl BuildWhatToWear(SlackQueryDto dto) + { + var weatherProvider = dto.WeatherProvider; + // Require user to set location first?? + return new WhatToWearCommand(weatherProvider); + } + + private static ICommandImpl BuildWeatherNow(SlackQueryDto dto) + { + var matches = dto.QueryParams; + var weatherProvider = dto.WeatherProvider; + + if (matches.Count == 0) + { + return new InvalidCommand("Timme for weather command not specified"); + } + + var timeParam = matches.First(); + + if (string.Equals(timeParam, "now", StringComparison.InvariantCultureIgnoreCase)) + { + return new WeatherNowCommand(weatherProvider, dto.Location, DateTime.Now); + } + + if (string.Equals(timeParam, "tomorrow", StringComparison.InvariantCultureIgnoreCase)) + { + return new WeatherNowCommand(weatherProvider, dto.Location, DateTime.Now.AddDays(1)); + } + + return new InvalidCommand("Expected `now` or `tomorrow`"); + } + + private static ICommandImpl BuildWeatherNowWithLocation(SlackQueryDto dto) + { + var matches = dto.QueryParams; + var weatherProvider = dto.WeatherProvider; + + if (matches.Count == 0) + { + return new InvalidCommand("Timme for weather command not specified"); + } + + var timeParam = matches.First(); + var city = matches.Skip(1).Take(1).First(); + var state = matches.Skip(2).Take(1).First(); + + + var location = dto.LocationService.GetLocation(city, state); + + if (location == null || location.IsInvalid()) + { + return new InvalidCommand($"Location not found for: {city} {state}"); + } + + if (string.Equals(timeParam, "now", StringComparison.InvariantCultureIgnoreCase)) + { + return new WeatherNowCommand(weatherProvider, location, DateTime.Now); + } + + if (string.Equals(timeParam, "tomorrow", StringComparison.InvariantCultureIgnoreCase)) + { + return new WeatherNowCommand(weatherProvider, location, DateTime.Now.AddDays(1)); + } + + return new InvalidCommand("Expected `now` or `tomorrow`"); + } + + public MessageToCommandConverter(IWeatherProvider weatherProvider, IRepository repository) + { + _weatherProvider = weatherProvider; + _repository = repository; + _locationService = new LocationService(_repository); + } + + /// + /// Parse a message and return a command that can be invoked + /// + /// the Slack Id of the user who queried bott + /// the message user sent + /// + public MessageParserResponse HandleRequest(string slackId, string message) + { + var noop = new MessageParserResponse + { + Command = new NoOpCommand(), + OriginalMessage = message + }; + + if (message == null) + { + return noop; + } + + var user = _repository.Get(slackId); + var location = _locationService.GetLocation(user?.LocationId ?? 0); + + foreach (var pair in _messageMap) + { + var match = pair.Item1.Match(message.Trim()); + + if (!match.Success) + { + continue; + } + + var capturedWords = new HashSet(); + + // first group is always the full original matched string so skip + for (var i = 1; i < match.Groups.Count; i++) + { + capturedWords.Add(match.Groups[i].Value); + } + + var queryDto = new SlackQueryDto + { + UserSlackId = slackId, + QueryParams = capturedWords, + // NOTE: We need to pass dependencies so static + // builders can use it. + WeatherProvider = _weatherProvider, + Repository = _repository, + LocationService = _locationService, + Location = location + }; + + // Shortcut: We could have each command handle the group matches + // themselves in order to handle more complex parameters + return new MessageParserResponse + { + Command = pair.Item2(queryDto), + OriginalMessage = message + }; + } + + return noop; + } + } + +} diff --git a/SlackBotPrototype/API/Models.cs b/SlackBotPrototype/API/Models.cs new file mode 100644 index 0000000..d31c62c --- /dev/null +++ b/SlackBotPrototype/API/Models.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using SQLite; + +namespace API +{ + public class User + { + [PrimaryKey, AutoIncrement, Column("_id")] + public int Id { get; set; } + + [Indexed] + public string SlackId { get; set; } + public string Name { get; set; } + + // SHORTCUT: Reference the lookup in memory rather than using FK on actual DB table + public int? LocationId { get; set; } + } + + // SHORTCUT: Skip storing this as actual entity in DB + public class Location + { + [PrimaryKey] + public int Id { get; set; } + [Indexed] + public string City { get; set; } + [Indexed] + public string State { get; set; } + [Indexed] + public string StateAbbreviation { get; set; } + public string DisplayName { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } + + public bool IsInvalid() + { + return string.IsNullOrWhiteSpace(DisplayName) || DisplayName == "Invalid"; + } + } + + public class ChatBotForecast + { + public string Summary { get; set; } + public string Icon { get; set; } + public Location Location { get; set; } + } + + public enum BotCommands + { + Unknown, + WeatherNow, + WeatherTomorrow, + SetLocation, + WeatherLocation + } + + /// + /// Property bag for query context information that we need for building + /// commands. + /// + public class SlackQueryDto + { + // SHORTCUT: Instead of having to pass the weather provider around, + // we could use some sort of dependency injection here. + public IWeatherProvider WeatherProvider { get; set; } + public ILocationService LocationService { get; set; } + public IRepository Repository { get; set; } + public ICollection QueryParams { get; set; } + public string UserSlackId { get; set; } + public Location Location { get; set; } + } + + public class MessageParserResponse + { + + public ICommandImpl Command { get; set; } + + public string OriginalMessage { get; set; } + } + +} diff --git a/SlackBotPrototype/API/Properties/AssemblyInfo.cs b/SlackBotPrototype/API/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4d69960 --- /dev/null +++ b/SlackBotPrototype/API/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("API")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("API")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a234d7b8-eab9-497f-84e7-354dc066bcb5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SlackBotPrototype/API/RestClientHttpProvider.cs b/SlackBotPrototype/API/RestClientHttpProvider.cs new file mode 100644 index 0000000..2526949 --- /dev/null +++ b/SlackBotPrototype/API/RestClientHttpProvider.cs @@ -0,0 +1,26 @@ +using System.Net; +using RestSharp; + +namespace API +{ + public class RestClientHttpProvider : IHttpRequestClient + { + private readonly RestClient _client; + + public RestClientHttpProvider(string baseUrl) + { + _client= new RestClient(baseUrl); + } + + public string GetContent(string url) + { + var resp = _client.Get(new RestRequest(Method.GET) + { + // To save time, hard code location + Resource = url + }); + + return resp.StatusCode == HttpStatusCode.OK ? resp.Content : null; + } + } +} diff --git a/SlackBotPrototype/API/SqLitePersistence.cs b/SlackBotPrototype/API/SqLitePersistence.cs new file mode 100644 index 0000000..4574cfa --- /dev/null +++ b/SlackBotPrototype/API/SqLitePersistence.cs @@ -0,0 +1,84 @@ +using System; +using System.Linq; +using SQLite; + +namespace API +{ + // SHORTCUT: Normally we'd break out the repositories into + // a file per entity. Keep them together for simplicity here. + // + // Also skipping tests for these because we'd need to set up integration tests + // with a SQLite database. If we weren't using a embedded file DB like SQLite, testing + // against a DB could get complicated. + public class SqLitePersistence : IRepository + { + + public User Get(string slackId) + { + if (string.IsNullOrWhiteSpace(slackId)) + { + return null; + } + + using (var db = new SQLiteConnection(ConfigConstants.DbName)) + { + return db.Query($"SELECT * FROM User WHERE SlackId = '{slackId}'").FirstOrDefault(); + } + } + + // SHORTCUT: We skip testing this because it's hard to test this in isolation, but it contains + // logic for matching up cities which is critical + public Location GetLocation(string city, string state) + { + if (string.IsNullOrWhiteSpace(city) || string.IsNullOrWhiteSpace(state)) + { + return null; + } + + using (var db = new SQLiteConnection(ConfigConstants.DbName)) + { + return db.Query($"SELECT * FROM Location WHERE UPPER(City) = '{city.ToUpper()}' AND UPPER(StateAbbreviation) = '{state.ToUpper()}'").FirstOrDefault(); + } + } + + public Location GetLocation(int id) + { + if (id <= 0) + { + return null; + } + + try + { + using (var db = new SQLiteConnection(ConfigConstants.DbName)) + { + return db.Get(id); + } + } + catch (Exception ex) + { + // SHORTCUT: Would normally log exception w/ logging library or service of choice + Console.WriteLine(ex.StackTrace); + } + + return null; + } + + public int CreateOrUpdate(string name, string slackId, Location location = null) + { + using (var db = new SQLiteConnection(ConfigConstants.DbName)) + { + // SHORTCUT: This should be wrapped in a transaction. Not doing so + // because I'm unfamiliar with this particular SQLite ORM + var id = db.InsertOrReplace(new User + { + Name = name, + SlackId = slackId, + LocationId = location?.Id + }); + + return id; + } + } + } +} diff --git a/SlackBotPrototype/API/packages.config b/SlackBotPrototype/API/packages.config new file mode 100644 index 0000000..8c2c9cf --- /dev/null +++ b/SlackBotPrototype/API/packages.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SlackBotPrototype/DBPreparer/DBPreparer.csproj b/SlackBotPrototype/DBPreparer/DBPreparer.csproj new file mode 100644 index 0000000..0fda789 --- /dev/null +++ b/SlackBotPrototype/DBPreparer/DBPreparer.csproj @@ -0,0 +1,93 @@ + + + + + Debug + AnyCPU + {41D05933-278A-45E7-A64D-933527E27883} + Exe + DBPreparer + DBPreparer + v4.5.2 + 512 + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\sqlite-net-pcl.1.5.151-beta\lib\netstandard1.1\SQLite-net.dll + + + ..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_green.dll + + + ..\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_v2.dll + + + ..\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll + + + ..\packages\SQLitePCLRaw.provider.e_sqlite3.net45.1.1.8\lib\net45\SQLitePCLRaw.provider.e_sqlite3.dll + + + + + + + + + + + + + + + + + + Always + + + + + + {A234D7B8-EAB9-497F-84E7-354DC066BCB5} + API + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + \ No newline at end of file diff --git a/SlackBotPrototype/DBPreparer/Program.cs b/SlackBotPrototype/DBPreparer/Program.cs new file mode 100644 index 0000000..b797992 --- /dev/null +++ b/SlackBotPrototype/DBPreparer/Program.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using API; +using Newtonsoft.Json; +using SQLite; + +namespace DBPreparer +{ + internal static class Program + { + static void Main(string[] args) + { + using (var db = new SQLiteConnection(ConfigConstants.DbName)) + { + // Prep DB schema initial state + db.CreateTable(); + db.CreateTable(); + + // SHORTCUT: Normally the source of the + // data would not be hard coded this way but rather come from a proper geocoding service, and we would store the results + // for performance. We would probably also prime the lookup table with the commmon locations that we anticipate so we + // don't have a cold start problem with locations. + var seedData = File.ReadAllText("locations-seed.json"); + var locations = JsonConvert.DeserializeObject(seedData); + + // Seed the database + db.InsertAll(locations); + + // Migration as needed as the application grows + } + } + } +} diff --git a/SlackBotPrototype/DBPreparer/Properties/AssemblyInfo.cs b/SlackBotPrototype/DBPreparer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4c97e73 --- /dev/null +++ b/SlackBotPrototype/DBPreparer/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DBPreparer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DBPreparer")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("41d05933-278a-45e7-a64d-933527e27883")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SlackBotPrototype/DBPreparer/locations-seed.json b/SlackBotPrototype/DBPreparer/locations-seed.json new file mode 100644 index 0000000..d8aef86 --- /dev/null +++ b/SlackBotPrototype/DBPreparer/locations-seed.json @@ -0,0 +1,9002 @@ +[ + { + "Id": 1, + "City": "New York", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "New York, New York", + "Latitude": 40.7127837, + "Longitude": -74.0059413 + }, + { + "Id": 2, + "City": "Los Angeles", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Los Angeles, California", + "Latitude": 34.0522342, + "Longitude": -118.2436849 + }, + { + "Id": 3, + "City": "Chicago", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Chicago, Illinois", + "Latitude": 41.8781136, + "Longitude": -87.6297982 + }, + { + "Id": 4, + "City": "Houston", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Houston, Texas", + "Latitude": 29.7604267, + "Longitude": -95.3698028 + }, + { + "Id": 5, + "City": "Philadelphia", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Philadelphia, Pennsylvania", + "Latitude": 39.9525839, + "Longitude": -75.1652215 + }, + { + "Id": 6, + "City": "Phoenix", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Phoenix, Arizona", + "Latitude": 33.4483771, + "Longitude": -112.0740373 + }, + { + "Id": 7, + "City": "San Antonio", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "San Antonio, Texas", + "Latitude": 29.4241219, + "Longitude": -98.493628199999989 + }, + { + "Id": 8, + "City": "San Diego", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Diego, California", + "Latitude": 32.715738, + "Longitude": -117.1610838 + }, + { + "Id": 9, + "City": "Dallas", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Dallas, Texas", + "Latitude": 32.7766642, + "Longitude": -96.796987899999991 + }, + { + "Id": 10, + "City": "San Jose", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Jose, California", + "Latitude": 37.3382082, + "Longitude": -121.8863286 + }, + { + "Id": 11, + "City": "Austin", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Austin, Texas", + "Latitude": 30.267153, + "Longitude": -97.7430608 + }, + { + "Id": 12, + "City": "Indianapolis", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Indianapolis, Indiana", + "Latitude": 39.768403, + "Longitude": -86.158068 + }, + { + "Id": 13, + "City": "Jacksonville", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Jacksonville, Florida", + "Latitude": 30.3321838, + "Longitude": -81.655650999999992 + }, + { + "Id": 14, + "City": "San Francisco", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Francisco, California", + "Latitude": 37.7749295, + "Longitude": -122.4194155 + }, + { + "Id": 15, + "City": "Columbus", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Columbus, Ohio", + "Latitude": 39.9611755, + "Longitude": -82.998794199999992 + }, + { + "Id": 16, + "City": "Charlotte", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Charlotte, North Carolina", + "Latitude": 35.2270869, + "Longitude": -80.8431267 + }, + { + "Id": 17, + "City": "Fort Worth", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Fort Worth, Texas", + "Latitude": 32.7554883, + "Longitude": -97.3307658 + }, + { + "Id": 18, + "City": "Detroit", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Detroit, Michigan", + "Latitude": 42.331427, + "Longitude": -83.0457538 + }, + { + "Id": 19, + "City": "El Paso", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "El Paso, Texas", + "Latitude": 31.7775757, + "Longitude": -106.4424559 + }, + { + "Id": 20, + "City": "Memphis", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Memphis, Tennessee", + "Latitude": 35.1495343, + "Longitude": -90.0489801 + }, + { + "Id": 21, + "City": "Seattle", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Seattle, Washington", + "Latitude": 47.6062095, + "Longitude": -122.3320708 + }, + { + "Id": 22, + "City": "Denver", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Denver, Colorado", + "Latitude": 39.7392358, + "Longitude": -104.990251 + }, + { + "Id": 23, + "City": "Washington", + "State": "District of Columbia", + "StateAbbreviation": "DC", + "DisplayName": "Washington, District of Columbia", + "Latitude": 38.9071923, + "Longitude": -77.0368707 + }, + { + "Id": 24, + "City": "Boston", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Boston, Massachusetts", + "Latitude": 42.3600825, + "Longitude": -71.0588801 + }, + { + "Id": 25, + "City": "Nashville-Davidson", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Nashville-Davidson, Tennessee", + "Latitude": 36.1626638, + "Longitude": -86.7816016 + }, + { + "Id": 26, + "City": "Baltimore", + "State": "Maryland", + "StateAbbreviation": "MD", + "DisplayName": "Baltimore, Maryland", + "Latitude": 39.2903848, + "Longitude": -76.6121893 + }, + { + "Id": 27, + "City": "Oklahoma City", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Oklahoma City, Oklahoma", + "Latitude": 35.4675602, + "Longitude": -97.5164276 + }, + { + "Id": 28, + "City": "Louisville/Jefferson County", + "State": "Kentucky", + "StateAbbreviation": "KY", + "DisplayName": "Louisville/Jefferson County, Kentucky", + "Latitude": 38.2526647, + "Longitude": -85.7584557 + }, + { + "Id": 29, + "City": "Portland", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Portland, Oregon", + "Latitude": 45.5230622, + "Longitude": -122.6764816 + }, + { + "Id": 30, + "City": "Las Vegas", + "State": "Nevada", + "StateAbbreviation": "NV", + "DisplayName": "Las Vegas, Nevada", + "Latitude": 36.1699412, + "Longitude": -115.1398296 + }, + { + "Id": 31, + "City": "Milwaukee", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Milwaukee, Wisconsin", + "Latitude": 43.0389025, + "Longitude": -87.9064736 + }, + { + "Id": 32, + "City": "Albuquerque", + "State": "New Mexico", + "StateAbbreviation": "NM", + "DisplayName": "Albuquerque, New Mexico", + "Latitude": 35.0853336, + "Longitude": -106.6055534 + }, + { + "Id": 33, + "City": "Tucson", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Tucson, Arizona", + "Latitude": 32.2217429, + "Longitude": -110.926479 + }, + { + "Id": 34, + "City": "Fresno", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Fresno, California", + "Latitude": 36.7468422, + "Longitude": -119.7725868 + }, + { + "Id": 35, + "City": "Sacramento", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Sacramento, California", + "Latitude": 38.5815719, + "Longitude": -121.4943996 + }, + { + "Id": 36, + "City": "Long Beach", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Long Beach, California", + "Latitude": 33.7700504, + "Longitude": -118.1937395 + }, + { + "Id": 37, + "City": "Kansas City", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Kansas City, Missouri", + "Latitude": 39.0997265, + "Longitude": -94.5785667 + }, + { + "Id": 38, + "City": "Mesa", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Mesa, Arizona", + "Latitude": 33.4151843, + "Longitude": -111.8314724 + }, + { + "Id": 39, + "City": "Virginia Beach", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Virginia Beach, Virginia", + "Latitude": 36.8529263, + "Longitude": -75.97798499999999 + }, + { + "Id": 40, + "City": "Atlanta", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Atlanta, Georgia", + "Latitude": 33.7489954, + "Longitude": -84.3879824 + }, + { + "Id": 41, + "City": "Colorado Springs", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Colorado Springs, Colorado", + "Latitude": 38.8338816, + "Longitude": -104.8213634 + }, + { + "Id": 42, + "City": "Omaha", + "State": "Nebraska", + "StateAbbreviation": "NE", + "DisplayName": "Omaha, Nebraska", + "Latitude": 41.2523634, + "Longitude": -95.997988299999989 + }, + { + "Id": 43, + "City": "Raleigh", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Raleigh, North Carolina", + "Latitude": 35.7795897, + "Longitude": -78.6381787 + }, + { + "Id": 44, + "City": "Miami", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Miami, Florida", + "Latitude": 25.7616798, + "Longitude": -80.1917902 + }, + { + "Id": 45, + "City": "Oakland", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Oakland, California", + "Latitude": 37.8043637, + "Longitude": -122.2711137 + }, + { + "Id": 46, + "City": "Minneapolis", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Minneapolis, Minnesota", + "Latitude": 44.977753, + "Longitude": -93.2650108 + }, + { + "Id": 47, + "City": "Tulsa", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Tulsa, Oklahoma", + "Latitude": 36.1539816, + "Longitude": -95.992775000000009 + }, + { + "Id": 48, + "City": "Cleveland", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Cleveland, Ohio", + "Latitude": 41.49932, + "Longitude": -81.6943605 + }, + { + "Id": 49, + "City": "Wichita", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Wichita, Kansas", + "Latitude": 37.688889, + "Longitude": -97.336111 + }, + { + "Id": 50, + "City": "Arlington", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Arlington, Texas", + "Latitude": 32.735687, + "Longitude": -97.108065599999989 + }, + { + "Id": 51, + "City": "New Orleans", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "New Orleans, Louisiana", + "Latitude": 29.951065799999991, + "Longitude": -90.0715323 + }, + { + "Id": 52, + "City": "Bakersfield", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Bakersfield, California", + "Latitude": 35.3732921, + "Longitude": -119.0187125 + }, + { + "Id": 53, + "City": "Tampa", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Tampa, Florida", + "Latitude": 27.950575, + "Longitude": -82.4571776 + }, + { + "Id": 54, + "City": "Honolulu", + "State": "Hawaii", + "StateAbbreviation": "HI", + "DisplayName": "Honolulu, Hawaii", + "Latitude": 21.3069444, + "Longitude": -157.8583333 + }, + { + "Id": 55, + "City": "Aurora", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Aurora, Colorado", + "Latitude": 39.7294319, + "Longitude": -104.8319195 + }, + { + "Id": 56, + "City": "Anaheim", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Anaheim, California", + "Latitude": 33.8352932, + "Longitude": -117.9145036 + }, + { + "Id": 57, + "City": "Santa Ana", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Ana, California", + "Latitude": 33.7455731, + "Longitude": -117.8678338 + }, + { + "Id": 58, + "City": "St. Louis", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "St. Louis, Missouri", + "Latitude": 38.6270025, + "Longitude": -90.199404199999989 + }, + { + "Id": 59, + "City": "Riverside", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Riverside, California", + "Latitude": 33.9533487, + "Longitude": -117.3961564 + }, + { + "Id": 60, + "City": "Corpus Christi", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Corpus Christi, Texas", + "Latitude": 27.8005828, + "Longitude": -97.396380999999991 + }, + { + "Id": 61, + "City": "Lexington-Fayette", + "State": "Kentucky", + "StateAbbreviation": "KY", + "DisplayName": "Lexington-Fayette, Kentucky", + "Latitude": 38.0405837, + "Longitude": -84.5037164 + }, + { + "Id": 62, + "City": "Pittsburgh", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Pittsburgh, Pennsylvania", + "Latitude": 40.440624799999988, + "Longitude": -79.9958864 + }, + { + "Id": 63, + "City": "Anchorage", + "State": "Alaska", + "StateAbbreviation": "AK", + "DisplayName": "Anchorage, Alaska", + "Latitude": 61.2180556, + "Longitude": -149.9002778 + }, + { + "Id": 64, + "City": "Stockton", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Stockton, California", + "Latitude": 37.9577016, + "Longitude": -121.2907796 + }, + { + "Id": 65, + "City": "Cincinnati", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Cincinnati, Ohio", + "Latitude": 39.1031182, + "Longitude": -84.5120196 + }, + { + "Id": 66, + "City": "St. Paul", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "St. Paul, Minnesota", + "Latitude": 44.9537029, + "Longitude": -93.0899578 + }, + { + "Id": 67, + "City": "Toledo", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Toledo, Ohio", + "Latitude": 41.6639383, + "Longitude": -83.555212000000012 + }, + { + "Id": 68, + "City": "Greensboro", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Greensboro, North Carolina", + "Latitude": 36.0726354, + "Longitude": -79.7919754 + }, + { + "Id": 69, + "City": "Newark", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Newark, New Jersey", + "Latitude": 40.735657, + "Longitude": -74.1723667 + }, + { + "Id": 70, + "City": "Plano", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Plano, Texas", + "Latitude": 33.0198431, + "Longitude": -96.6988856 + }, + { + "Id": 71, + "City": "Henderson", + "State": "Nevada", + "StateAbbreviation": "NV", + "DisplayName": "Henderson, Nevada", + "Latitude": 36.0395247, + "Longitude": -114.9817213 + }, + { + "Id": 72, + "City": "Lincoln", + "State": "Nebraska", + "StateAbbreviation": "NE", + "DisplayName": "Lincoln, Nebraska", + "Latitude": 40.8257625, + "Longitude": -96.6851982 + }, + { + "Id": 73, + "City": "Buffalo", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Buffalo, New York", + "Latitude": 42.886446799999987, + "Longitude": -78.8783689 + }, + { + "Id": 74, + "City": "Jersey City", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Jersey City, New Jersey", + "Latitude": 40.728157499999988, + "Longitude": -74.0776417 + }, + { + "Id": 75, + "City": "Chula Vista", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Chula Vista, California", + "Latitude": 32.6400541, + "Longitude": -117.0841955 + }, + { + "Id": 76, + "City": "Fort Wayne", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Fort Wayne, Indiana", + "Latitude": 41.079273, + "Longitude": -85.1393513 + }, + { + "Id": 77, + "City": "Orlando", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Orlando, Florida", + "Latitude": 28.5383355, + "Longitude": -81.3792365 + }, + { + "Id": 78, + "City": "St. Petersburg", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "St. Petersburg, Florida", + "Latitude": 27.773056, + "Longitude": -82.64 + }, + { + "Id": 79, + "City": "Chandler", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Chandler, Arizona", + "Latitude": 33.3061605, + "Longitude": -111.8412502 + }, + { + "Id": 80, + "City": "Laredo", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Laredo, Texas", + "Latitude": 27.5305671, + "Longitude": -99.48032409999999 + }, + { + "Id": 81, + "City": "Norfolk", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Norfolk, Virginia", + "Latitude": 36.8507689, + "Longitude": -76.28587259999999 + }, + { + "Id": 82, + "City": "Durham", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Durham, North Carolina", + "Latitude": 35.9940329, + "Longitude": -78.898619 + }, + { + "Id": 83, + "City": "Madison", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Madison, Wisconsin", + "Latitude": 43.0730517, + "Longitude": -89.4012302 + }, + { + "Id": 84, + "City": "Lubbock", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Lubbock, Texas", + "Latitude": 33.5778631, + "Longitude": -101.8551665 + }, + { + "Id": 85, + "City": "Irvine", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Irvine, California", + "Latitude": 33.6839473, + "Longitude": -117.7946942 + }, + { + "Id": 86, + "City": "Winston-Salem", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Winston-Salem, North Carolina", + "Latitude": 36.099859599999988, + "Longitude": -80.244216 + }, + { + "Id": 87, + "City": "Glendale", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Glendale, Arizona", + "Latitude": 33.5386523, + "Longitude": -112.1859866 + }, + { + "Id": 88, + "City": "Garland", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Garland, Texas", + "Latitude": 32.912624, + "Longitude": -96.638883299999989 + }, + { + "Id": 89, + "City": "Hialeah", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Hialeah, Florida", + "Latitude": 25.8575963, + "Longitude": -80.2781057 + }, + { + "Id": 90, + "City": "Reno", + "State": "Nevada", + "StateAbbreviation": "NV", + "DisplayName": "Reno, Nevada", + "Latitude": 39.5296329, + "Longitude": -119.8138027 + }, + { + "Id": 91, + "City": "Chesapeake", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Chesapeake, Virginia", + "Latitude": 36.7682088, + "Longitude": -76.2874927 + }, + { + "Id": 92, + "City": "Gilbert", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Gilbert, Arizona", + "Latitude": 33.3528264, + "Longitude": -111.789027 + }, + { + "Id": 93, + "City": "Baton Rouge", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Baton Rouge, Louisiana", + "Latitude": 30.4582829, + "Longitude": -91.1403196 + }, + { + "Id": 94, + "City": "Irving", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Irving, Texas", + "Latitude": 32.8140177, + "Longitude": -96.9488945 + }, + { + "Id": 95, + "City": "Scottsdale", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Scottsdale, Arizona", + "Latitude": 33.4941704, + "Longitude": -111.9260519 + }, + { + "Id": 96, + "City": "North Las Vegas", + "State": "Nevada", + "StateAbbreviation": "NV", + "DisplayName": "North Las Vegas, Nevada", + "Latitude": 36.1988592, + "Longitude": -115.1175013 + }, + { + "Id": 97, + "City": "Fremont", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Fremont, California", + "Latitude": 37.5482697, + "Longitude": -121.9885719 + }, + { + "Id": 98, + "City": "Boise City", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Boise City, Idaho", + "Latitude": 43.6187102, + "Longitude": -116.2146068 + }, + { + "Id": 99, + "City": "Richmond", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Richmond, Virginia", + "Latitude": 37.5407246, + "Longitude": -77.4360481 + }, + { + "Id": 100, + "City": "San Bernardino", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Bernardino, California", + "Latitude": 34.1083449, + "Longitude": -117.2897652 + }, + { + "Id": 101, + "City": "Birmingham", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Birmingham, Alabama", + "Latitude": 33.5206608, + "Longitude": -86.802489999999992 + }, + { + "Id": 102, + "City": "Spokane", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Spokane, Washington", + "Latitude": 47.6587802, + "Longitude": -117.4260466 + }, + { + "Id": 103, + "City": "Rochester", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Rochester, New York", + "Latitude": 43.16103, + "Longitude": -77.6109219 + }, + { + "Id": 104, + "City": "Des Moines", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Des Moines, Iowa", + "Latitude": 41.6005448, + "Longitude": -93.6091064 + }, + { + "Id": 105, + "City": "Modesto", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Modesto, California", + "Latitude": 37.639097199999988, + "Longitude": -120.9968782 + }, + { + "Id": 106, + "City": "Fayetteville", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Fayetteville, North Carolina", + "Latitude": 35.0526641, + "Longitude": -78.87835849999999 + }, + { + "Id": 107, + "City": "Tacoma", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Tacoma, Washington", + "Latitude": 47.2528768, + "Longitude": -122.4442906 + }, + { + "Id": 108, + "City": "Oxnard", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Oxnard, California", + "Latitude": 34.1975048, + "Longitude": -119.1770516 + }, + { + "Id": 109, + "City": "Fontana", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Fontana, California", + "Latitude": 34.0922335, + "Longitude": -117.435048 + }, + { + "Id": 110, + "City": "Columbus", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Columbus, Georgia", + "Latitude": 32.4609764, + "Longitude": -84.9877094 + }, + { + "Id": 111, + "City": "Montgomery", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Montgomery, Alabama", + "Latitude": 32.3668052, + "Longitude": -86.2999689 + }, + { + "Id": 112, + "City": "Moreno Valley", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Moreno Valley, California", + "Latitude": 33.9424658, + "Longitude": -117.2296717 + }, + { + "Id": 113, + "City": "Shreveport", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Shreveport, Louisiana", + "Latitude": 32.5251516, + "Longitude": -93.7501789 + }, + { + "Id": 114, + "City": "Aurora", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Aurora, Illinois", + "Latitude": 41.7605849, + "Longitude": -88.320071500000012 + }, + { + "Id": 115, + "City": "Yonkers", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Yonkers, New York", + "Latitude": 40.9312099, + "Longitude": -73.898746899999992 + }, + { + "Id": 116, + "City": "Akron", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Akron, Ohio", + "Latitude": 41.0814447, + "Longitude": -81.519005299999989 + }, + { + "Id": 117, + "City": "Huntington Beach", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Huntington Beach, California", + "Latitude": 33.660297, + "Longitude": -117.9992265 + }, + { + "Id": 118, + "City": "Little Rock", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Little Rock, Arkansas", + "Latitude": 34.7464809, + "Longitude": -92.289594799999989 + }, + { + "Id": 119, + "City": "Augusta-Richmond County", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Augusta-Richmond County, Georgia", + "Latitude": 33.4734978, + "Longitude": -82.0105148 + }, + { + "Id": 120, + "City": "Amarillo", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Amarillo, Texas", + "Latitude": 35.2219971, + "Longitude": -101.8312969 + }, + { + "Id": 121, + "City": "Glendale", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Glendale, California", + "Latitude": 34.1425078, + "Longitude": -118.255075 + }, + { + "Id": 122, + "City": "Mobile", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Mobile, Alabama", + "Latitude": 30.6953657, + "Longitude": -88.0398912 + }, + { + "Id": 123, + "City": "Grand Rapids", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Grand Rapids, Michigan", + "Latitude": 42.9633599, + "Longitude": -85.6680863 + }, + { + "Id": 124, + "City": "Salt Lake City", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Salt Lake City, Utah", + "Latitude": 40.7607793, + "Longitude": -111.8910474 + }, + { + "Id": 125, + "City": "Tallahassee", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Tallahassee, Florida", + "Latitude": 30.4382559, + "Longitude": -84.28073289999999 + }, + { + "Id": 126, + "City": "Huntsville", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Huntsville, Alabama", + "Latitude": 34.7303688, + "Longitude": -86.5861037 + }, + { + "Id": 127, + "City": "Grand Prairie", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Grand Prairie, Texas", + "Latitude": 32.7459645, + "Longitude": -96.997784599999989 + }, + { + "Id": 128, + "City": "Knoxville", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Knoxville, Tennessee", + "Latitude": 35.9606384, + "Longitude": -83.9207392 + }, + { + "Id": 129, + "City": "Worcester", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Worcester, Massachusetts", + "Latitude": 42.2625932, + "Longitude": -71.8022934 + }, + { + "Id": 130, + "City": "Newport News", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Newport News, Virginia", + "Latitude": 37.0870821, + "Longitude": -76.4730122 + }, + { + "Id": 131, + "City": "Brownsville", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Brownsville, Texas", + "Latitude": 25.9017472, + "Longitude": -97.4974838 + }, + { + "Id": 132, + "City": "Overland Park", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Overland Park, Kansas", + "Latitude": 38.9822282, + "Longitude": -94.6707917 + }, + { + "Id": 133, + "City": "Santa Clarita", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Clarita, California", + "Latitude": 34.3916641, + "Longitude": -118.542586 + }, + { + "Id": 134, + "City": "Providence", + "State": "Rhode Island", + "StateAbbreviation": "RI", + "DisplayName": "Providence, Rhode Island", + "Latitude": 41.8239891, + "Longitude": -71.4128343 + }, + { + "Id": 135, + "City": "Garden Grove", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Garden Grove, California", + "Latitude": 33.7739053, + "Longitude": -117.9414477 + }, + { + "Id": 136, + "City": "Chattanooga", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Chattanooga, Tennessee", + "Latitude": 35.0456297, + "Longitude": -85.3096801 + }, + { + "Id": 137, + "City": "Oceanside", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Oceanside, California", + "Latitude": 33.1958696, + "Longitude": -117.3794834 + }, + { + "Id": 138, + "City": "Jackson", + "State": "Mississippi", + "StateAbbreviation": "MS", + "DisplayName": "Jackson, Mississippi", + "Latitude": 32.2987573, + "Longitude": -90.1848103 + }, + { + "Id": 139, + "City": "Fort Lauderdale", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Fort Lauderdale, Florida", + "Latitude": 26.1224386, + "Longitude": -80.137317400000015 + }, + { + "Id": 140, + "City": "Santa Rosa", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Rosa, California", + "Latitude": 38.440429, + "Longitude": -122.7140548 + }, + { + "Id": 141, + "City": "Rancho Cucamonga", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rancho Cucamonga, California", + "Latitude": 34.106398899999988, + "Longitude": -117.5931084 + }, + { + "Id": 142, + "City": "Port St. Lucie", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Port St. Lucie, Florida", + "Latitude": 27.2730492, + "Longitude": -80.3582261 + }, + { + "Id": 143, + "City": "Tempe", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Tempe, Arizona", + "Latitude": 33.4255104, + "Longitude": -111.9400054 + }, + { + "Id": 144, + "City": "Ontario", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Ontario, California", + "Latitude": 34.0633443, + "Longitude": -117.6508876 + }, + { + "Id": 145, + "City": "Vancouver", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Vancouver, Washington", + "Latitude": 45.6387281, + "Longitude": -122.6614861 + }, + { + "Id": 146, + "City": "Cape Coral", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Cape Coral, Florida", + "Latitude": 26.5628537, + "Longitude": -81.9495331 + }, + { + "Id": 147, + "City": "Sioux Falls", + "State": "South Dakota", + "StateAbbreviation": "SD", + "DisplayName": "Sioux Falls, South Dakota", + "Latitude": 43.5445959, + "Longitude": -96.731103400000009 + }, + { + "Id": 148, + "City": "Springfield", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Springfield, Missouri", + "Latitude": 37.2089572, + "Longitude": -93.292298899999992 + }, + { + "Id": 149, + "City": "Peoria", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Peoria, Arizona", + "Latitude": 33.5805955, + "Longitude": -112.2373779 + }, + { + "Id": 150, + "City": "Pembroke Pines", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Pembroke Pines, Florida", + "Latitude": 26.007765, + "Longitude": -80.2962555 + }, + { + "Id": 151, + "City": "Elk Grove", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Elk Grove, California", + "Latitude": 38.4087993, + "Longitude": -121.3716178 + }, + { + "Id": 152, + "City": "Salem", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Salem, Oregon", + "Latitude": 44.9428975, + "Longitude": -123.0350963 + }, + { + "Id": 153, + "City": "Lancaster", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lancaster, California", + "Latitude": 34.6867846, + "Longitude": -118.1541632 + }, + { + "Id": 154, + "City": "Corona", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Corona, California", + "Latitude": 33.8752935, + "Longitude": -117.5664384 + }, + { + "Id": 155, + "City": "Eugene", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Eugene, Oregon", + "Latitude": 44.0520691, + "Longitude": -123.0867536 + }, + { + "Id": 156, + "City": "Palmdale", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Palmdale, California", + "Latitude": 34.5794343, + "Longitude": -118.1164613 + }, + { + "Id": 157, + "City": "Salinas", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Salinas, California", + "Latitude": 36.6777372, + "Longitude": -121.6555013 + }, + { + "Id": 158, + "City": "Springfield", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Springfield, Massachusetts", + "Latitude": 42.1014831, + "Longitude": -72.589811 + }, + { + "Id": 159, + "City": "Pasadena", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Pasadena, Texas", + "Latitude": 29.6910625, + "Longitude": -95.2091006 + }, + { + "Id": 160, + "City": "Fort Collins", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Fort Collins, Colorado", + "Latitude": 40.5852602, + "Longitude": -105.084423 + }, + { + "Id": 161, + "City": "Hayward", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Hayward, California", + "Latitude": 37.6688205, + "Longitude": -122.0807964 + }, + { + "Id": 162, + "City": "Pomona", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Pomona, California", + "Latitude": 34.055103, + "Longitude": -117.7499909 + }, + { + "Id": 163, + "City": "Cary", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Cary, North Carolina", + "Latitude": 35.79154, + "Longitude": -78.7811169 + }, + { + "Id": 164, + "City": "Rockford", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Rockford, Illinois", + "Latitude": 42.2711311, + "Longitude": -89.0939952 + }, + { + "Id": 165, + "City": "Alexandria", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Alexandria, Virginia", + "Latitude": 38.8048355, + "Longitude": -77.0469214 + }, + { + "Id": 166, + "City": "Escondido", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Escondido, California", + "Latitude": 33.1192068, + "Longitude": -117.086421 + }, + { + "Id": 167, + "City": "McKinney", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "McKinney, Texas", + "Latitude": 33.1972465, + "Longitude": -96.6397822 + }, + { + "Id": 168, + "City": "Kansas City", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Kansas City, Kansas", + "Latitude": 39.114053, + "Longitude": -94.6274636 + }, + { + "Id": 169, + "City": "Joliet", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Joliet, Illinois", + "Latitude": 41.525031, + "Longitude": -88.0817251 + }, + { + "Id": 170, + "City": "Sunnyvale", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Sunnyvale, California", + "Latitude": 37.36883, + "Longitude": -122.0363496 + }, + { + "Id": 171, + "City": "Torrance", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Torrance, California", + "Latitude": 33.8358492, + "Longitude": -118.3406288 + }, + { + "Id": 172, + "City": "Bridgeport", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Bridgeport, Connecticut", + "Latitude": 41.1865478, + "Longitude": -73.19517669999999 + }, + { + "Id": 173, + "City": "Lakewood", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Lakewood, Colorado", + "Latitude": 39.7047095, + "Longitude": -105.0813734 + }, + { + "Id": 174, + "City": "Hollywood", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Hollywood, Florida", + "Latitude": 26.0112014, + "Longitude": -80.1494901 + }, + { + "Id": 175, + "City": "Paterson", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Paterson, New Jersey", + "Latitude": 40.9167654, + "Longitude": -74.171810999999991 + }, + { + "Id": 176, + "City": "Naperville", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Naperville, Illinois", + "Latitude": 41.7508391, + "Longitude": -88.1535352 + }, + { + "Id": 177, + "City": "Syracuse", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Syracuse, New York", + "Latitude": 43.0481221, + "Longitude": -76.147424399999991 + }, + { + "Id": 178, + "City": "Mesquite", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Mesquite, Texas", + "Latitude": 32.766795500000008, + "Longitude": -96.5991593 + }, + { + "Id": 179, + "City": "Dayton", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Dayton, Ohio", + "Latitude": 39.7589478, + "Longitude": -84.1916069 + }, + { + "Id": 180, + "City": "Savannah", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Savannah, Georgia", + "Latitude": 32.0835407, + "Longitude": -81.099834199999989 + }, + { + "Id": 181, + "City": "Clarksville", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Clarksville, Tennessee", + "Latitude": 36.5297706, + "Longitude": -87.3594528 + }, + { + "Id": 182, + "City": "Orange", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Orange, California", + "Latitude": 33.7877944, + "Longitude": -117.8531119 + }, + { + "Id": 183, + "City": "Pasadena", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Pasadena, California", + "Latitude": 34.1477849, + "Longitude": -118.1445155 + }, + { + "Id": 184, + "City": "Fullerton", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Fullerton, California", + "Latitude": 33.8703596, + "Longitude": -117.9242966 + }, + { + "Id": 185, + "City": "Killeen", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Killeen, Texas", + "Latitude": 31.1171194, + "Longitude": -97.72779589999999 + }, + { + "Id": 186, + "City": "Frisco", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Frisco, Texas", + "Latitude": 33.1506744, + "Longitude": -96.823611599999992 + }, + { + "Id": 187, + "City": "Hampton", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Hampton, Virginia", + "Latitude": 37.0298687, + "Longitude": -76.34522179999999 + }, + { + "Id": 188, + "City": "McAllen", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "McAllen, Texas", + "Latitude": 26.2034071, + "Longitude": -98.230012399999993 + }, + { + "Id": 189, + "City": "Warren", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Warren, Michigan", + "Latitude": 42.5144566, + "Longitude": -83.014652599999991 + }, + { + "Id": 190, + "City": "Bellevue", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Bellevue, Washington", + "Latitude": 47.610377, + "Longitude": -122.2006786 + }, + { + "Id": 191, + "City": "West Valley City", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "West Valley City, Utah", + "Latitude": 40.6916132, + "Longitude": -112.0010501 + }, + { + "Id": 192, + "City": "Columbia", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Columbia, South Carolina", + "Latitude": 34.0007104, + "Longitude": -81.0348144 + }, + { + "Id": 193, + "City": "Olathe", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Olathe, Kansas", + "Latitude": 38.8813958, + "Longitude": -94.819128499999991 + }, + { + "Id": 194, + "City": "Sterling Heights", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Sterling Heights, Michigan", + "Latitude": 42.5803122, + "Longitude": -83.0302033 + }, + { + "Id": 195, + "City": "New Haven", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "New Haven, Connecticut", + "Latitude": 41.308274, + "Longitude": -72.9278835 + }, + { + "Id": 196, + "City": "Miramar", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Miramar, Florida", + "Latitude": 25.9860762, + "Longitude": -80.303560199999993 + }, + { + "Id": 197, + "City": "Waco", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Waco, Texas", + "Latitude": 31.549333, + "Longitude": -97.1466695 + }, + { + "Id": 198, + "City": "Thousand Oaks", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Thousand Oaks, California", + "Latitude": 34.1705609, + "Longitude": -118.8375937 + }, + { + "Id": 199, + "City": "Cedar Rapids", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Cedar Rapids, Iowa", + "Latitude": 41.9778795, + "Longitude": -91.6656232 + }, + { + "Id": 200, + "City": "Charleston", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Charleston, South Carolina", + "Latitude": 32.7764749, + "Longitude": -79.931051200000013 + }, + { + "Id": 201, + "City": "Visalia", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Visalia, California", + "Latitude": 36.3302284, + "Longitude": -119.2920585 + }, + { + "Id": 202, + "City": "Topeka", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Topeka, Kansas", + "Latitude": 39.0558235, + "Longitude": -95.689018499999989 + }, + { + "Id": 203, + "City": "Elizabeth", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Elizabeth, New Jersey", + "Latitude": 40.6639916, + "Longitude": -74.2107006 + }, + { + "Id": 204, + "City": "Gainesville", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Gainesville, Florida", + "Latitude": 29.6516344, + "Longitude": -82.32482619999999 + }, + { + "Id": 205, + "City": "Thornton", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Thornton, Colorado", + "Latitude": 39.8680412, + "Longitude": -104.9719243 + }, + { + "Id": 206, + "City": "Roseville", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Roseville, California", + "Latitude": 38.7521235, + "Longitude": -121.2880059 + }, + { + "Id": 207, + "City": "Carrollton", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Carrollton, Texas", + "Latitude": 32.9756415, + "Longitude": -96.8899636 + }, + { + "Id": 208, + "City": "Coral Springs", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Coral Springs, Florida", + "Latitude": 26.271192, + "Longitude": -80.2706044 + }, + { + "Id": 209, + "City": "Stamford", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Stamford, Connecticut", + "Latitude": 41.0534302, + "Longitude": -73.5387341 + }, + { + "Id": 210, + "City": "Simi Valley", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Simi Valley, California", + "Latitude": 34.2694474, + "Longitude": -118.781482 + }, + { + "Id": 211, + "City": "Concord", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Concord, California", + "Latitude": 37.9779776, + "Longitude": -122.0310733 + }, + { + "Id": 212, + "City": "Hartford", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Hartford, Connecticut", + "Latitude": 41.763711099999988, + "Longitude": -72.6850932 + }, + { + "Id": 213, + "City": "Kent", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Kent, Washington", + "Latitude": 47.3809335, + "Longitude": -122.2348431 + }, + { + "Id": 214, + "City": "Lafayette", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Lafayette, Louisiana", + "Latitude": 30.2240897, + "Longitude": -92.0198427 + }, + { + "Id": 215, + "City": "Midland", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Midland, Texas", + "Latitude": 31.9973456, + "Longitude": -102.0779146 + }, + { + "Id": 216, + "City": "Surprise", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Surprise, Arizona", + "Latitude": 33.6292337, + "Longitude": -112.3679279 + }, + { + "Id": 217, + "City": "Denton", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Denton, Texas", + "Latitude": 33.2148412, + "Longitude": -97.133068299999991 + }, + { + "Id": 218, + "City": "Victorville", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Victorville, California", + "Latitude": 34.5362184, + "Longitude": -117.2927641 + }, + { + "Id": 219, + "City": "Evansville", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Evansville, Indiana", + "Latitude": 37.9715592, + "Longitude": -87.5710898 + }, + { + "Id": 220, + "City": "Santa Clara", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Clara, California", + "Latitude": 37.3541079, + "Longitude": -121.9552356 + }, + { + "Id": 221, + "City": "Abilene", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Abilene, Texas", + "Latitude": 32.4487364, + "Longitude": -99.733143900000016 + }, + { + "Id": 222, + "City": "Athens-Clarke County", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Athens-Clarke County, Georgia", + "Latitude": 33.9519347, + "Longitude": -83.357567 + }, + { + "Id": 223, + "City": "Vallejo", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Vallejo, California", + "Latitude": 38.1040864, + "Longitude": -122.2566367 + }, + { + "Id": 224, + "City": "Allentown", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Allentown, Pennsylvania", + "Latitude": 40.6084305, + "Longitude": -75.4901833 + }, + { + "Id": 225, + "City": "Norman", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Norman, Oklahoma", + "Latitude": 35.2225668, + "Longitude": -97.4394777 + }, + { + "Id": 226, + "City": "Beaumont", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Beaumont, Texas", + "Latitude": 30.080174, + "Longitude": -94.1265562 + }, + { + "Id": 227, + "City": "Independence", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Independence, Missouri", + "Latitude": 39.0911161, + "Longitude": -94.415506799999989 + }, + { + "Id": 228, + "City": "Murfreesboro", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Murfreesboro, Tennessee", + "Latitude": 35.8456213, + "Longitude": -86.39027 + }, + { + "Id": 229, + "City": "Ann Arbor", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Ann Arbor, Michigan", + "Latitude": 42.2808256, + "Longitude": -83.7430378 + }, + { + "Id": 230, + "City": "Springfield", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Springfield, Illinois", + "Latitude": 39.781721300000008, + "Longitude": -89.6501481 + }, + { + "Id": 231, + "City": "Berkeley", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Berkeley, California", + "Latitude": 37.8715926, + "Longitude": -122.272747 + }, + { + "Id": 232, + "City": "Peoria", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Peoria, Illinois", + "Latitude": 40.6936488, + "Longitude": -89.5889864 + }, + { + "Id": 233, + "City": "Provo", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Provo, Utah", + "Latitude": 40.2338438, + "Longitude": -111.6585337 + }, + { + "Id": 234, + "City": "El Monte", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "El Monte, California", + "Latitude": 34.0686206, + "Longitude": -118.0275667 + }, + { + "Id": 235, + "City": "Columbia", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Columbia, Missouri", + "Latitude": 38.9517053, + "Longitude": -92.3340724 + }, + { + "Id": 236, + "City": "Lansing", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Lansing, Michigan", + "Latitude": 42.732535, + "Longitude": -84.5555347 + }, + { + "Id": 237, + "City": "Fargo", + "State": "North Dakota", + "StateAbbreviation": "ND", + "DisplayName": "Fargo, North Dakota", + "Latitude": 46.8771863, + "Longitude": -96.7898034 + }, + { + "Id": 238, + "City": "Downey", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Downey, California", + "Latitude": 33.9401088, + "Longitude": -118.1331593 + }, + { + "Id": 239, + "City": "Costa Mesa", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Costa Mesa, California", + "Latitude": 33.6411316, + "Longitude": -117.9186689 + }, + { + "Id": 240, + "City": "Wilmington", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Wilmington, North Carolina", + "Latitude": 34.2257255, + "Longitude": -77.9447102 + }, + { + "Id": 241, + "City": "Arvada", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Arvada, Colorado", + "Latitude": 39.8027644, + "Longitude": -105.0874842 + }, + { + "Id": 242, + "City": "Inglewood", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Inglewood, California", + "Latitude": 33.9616801, + "Longitude": -118.3531311 + }, + { + "Id": 243, + "City": "Miami Gardens", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Miami Gardens, Florida", + "Latitude": 25.9420377, + "Longitude": -80.2456045 + }, + { + "Id": 244, + "City": "Carlsbad", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Carlsbad, California", + "Latitude": 33.1580933, + "Longitude": -117.3505939 + }, + { + "Id": 245, + "City": "Westminster", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Westminster, Colorado", + "Latitude": 39.8366528, + "Longitude": -105.0372046 + }, + { + "Id": 246, + "City": "Rochester", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Rochester, Minnesota", + "Latitude": 44.0121221, + "Longitude": -92.4801989 + }, + { + "Id": 247, + "City": "Odessa", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Odessa, Texas", + "Latitude": 31.8456816, + "Longitude": -102.3676431 + }, + { + "Id": 248, + "City": "Manchester", + "State": "New Hampshire", + "StateAbbreviation": "NH", + "DisplayName": "Manchester, New Hampshire", + "Latitude": 42.9956397, + "Longitude": -71.4547891 + }, + { + "Id": 249, + "City": "Elgin", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Elgin, Illinois", + "Latitude": 42.0354084, + "Longitude": -88.2825668 + }, + { + "Id": 250, + "City": "West Jordan", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "West Jordan, Utah", + "Latitude": 40.6096698, + "Longitude": -111.9391031 + }, + { + "Id": 251, + "City": "Round Rock", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Round Rock, Texas", + "Latitude": 30.5082551, + "Longitude": -97.678896 + }, + { + "Id": 252, + "City": "Clearwater", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Clearwater, Florida", + "Latitude": 27.9658533, + "Longitude": -82.8001026 + }, + { + "Id": 253, + "City": "Waterbury", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Waterbury, Connecticut", + "Latitude": 41.5581525, + "Longitude": -73.0514965 + }, + { + "Id": 254, + "City": "Gresham", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Gresham, Oregon", + "Latitude": 45.5001357, + "Longitude": -122.4302013 + }, + { + "Id": 255, + "City": "Fairfield", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Fairfield, California", + "Latitude": 38.249358099999988, + "Longitude": -122.0399663 + }, + { + "Id": 256, + "City": "Billings", + "State": "Montana", + "StateAbbreviation": "MT", + "DisplayName": "Billings, Montana", + "Latitude": 45.7832856, + "Longitude": -108.5006904 + }, + { + "Id": 257, + "City": "Lowell", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Lowell, Massachusetts", + "Latitude": 42.6334247, + "Longitude": -71.316171799999992 + }, + { + "Id": 258, + "City": "San Buenaventura (Ventura)", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Buenaventura (Ventura), California", + "Latitude": 34.274646, + "Longitude": -119.2290316 + }, + { + "Id": 259, + "City": "Pueblo", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Pueblo, Colorado", + "Latitude": 38.2544472, + "Longitude": -104.6091409 + }, + { + "Id": 260, + "City": "High Point", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "High Point, North Carolina", + "Latitude": 35.9556923, + "Longitude": -80.0053176 + }, + { + "Id": 261, + "City": "West Covina", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "West Covina, California", + "Latitude": 34.0686208, + "Longitude": -117.9389526 + }, + { + "Id": 262, + "City": "Richmond", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Richmond, California", + "Latitude": 37.9357576, + "Longitude": -122.3477486 + }, + { + "Id": 263, + "City": "Murrieta", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Murrieta, California", + "Latitude": 33.5539143, + "Longitude": -117.2139232 + }, + { + "Id": 264, + "City": "Cambridge", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Cambridge, Massachusetts", + "Latitude": 42.3736158, + "Longitude": -71.10973349999999 + }, + { + "Id": 265, + "City": "Antioch", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Antioch, California", + "Latitude": 38.0049214, + "Longitude": -121.805789 + }, + { + "Id": 266, + "City": "Temecula", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Temecula, California", + "Latitude": 33.4936391, + "Longitude": -117.1483648 + }, + { + "Id": 267, + "City": "Norwalk", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Norwalk, California", + "Latitude": 33.9022367, + "Longitude": -118.081733 + }, + { + "Id": 268, + "City": "Centennial", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Centennial, Colorado", + "Latitude": 39.5807452, + "Longitude": -104.8771726 + }, + { + "Id": 269, + "City": "Everett", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Everett, Washington", + "Latitude": 47.9789848, + "Longitude": -122.2020794 + }, + { + "Id": 270, + "City": "Palm Bay", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Palm Bay, Florida", + "Latitude": 28.0344621, + "Longitude": -80.5886646 + }, + { + "Id": 271, + "City": "Wichita Falls", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Wichita Falls, Texas", + "Latitude": 33.9137085, + "Longitude": -98.4933873 + }, + { + "Id": 272, + "City": "Green Bay", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Green Bay, Wisconsin", + "Latitude": 44.519158999999988, + "Longitude": -88.019826 + }, + { + "Id": 273, + "City": "Daly City", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Daly City, California", + "Latitude": 37.6879241, + "Longitude": -122.4702079 + }, + { + "Id": 274, + "City": "Burbank", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Burbank, California", + "Latitude": 34.1808392, + "Longitude": -118.3089661 + }, + { + "Id": 275, + "City": "Richardson", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Richardson, Texas", + "Latitude": 32.9483335, + "Longitude": -96.7298519 + }, + { + "Id": 276, + "City": "Pompano Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Pompano Beach, Florida", + "Latitude": 26.2378597, + "Longitude": -80.1247667 + }, + { + "Id": 277, + "City": "North Charleston", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "North Charleston, South Carolina", + "Latitude": 32.8546197, + "Longitude": -79.9748103 + }, + { + "Id": 278, + "City": "Broken Arrow", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Broken Arrow, Oklahoma", + "Latitude": 36.060949, + "Longitude": -95.7974526 + }, + { + "Id": 279, + "City": "Boulder", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Boulder, Colorado", + "Latitude": 40.0149856, + "Longitude": -105.2705456 + }, + { + "Id": 280, + "City": "West Palm Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "West Palm Beach, Florida", + "Latitude": 26.7153424, + "Longitude": -80.0533746 + }, + { + "Id": 281, + "City": "Santa Maria", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Maria, California", + "Latitude": 34.9530337, + "Longitude": -120.4357191 + }, + { + "Id": 282, + "City": "El Cajon", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "El Cajon, California", + "Latitude": 32.7947731, + "Longitude": -116.9625269 + }, + { + "Id": 283, + "City": "Davenport", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Davenport, Iowa", + "Latitude": 41.5236437, + "Longitude": -90.5776367 + }, + { + "Id": 284, + "City": "Rialto", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rialto, California", + "Latitude": 34.1064001, + "Longitude": -117.3703235 + }, + { + "Id": 285, + "City": "Las Cruces", + "State": "New Mexico", + "StateAbbreviation": "NM", + "DisplayName": "Las Cruces, New Mexico", + "Latitude": 32.3199396, + "Longitude": -106.7636538 + }, + { + "Id": 286, + "City": "San Mateo", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Mateo, California", + "Latitude": 37.5629917, + "Longitude": -122.3255254 + }, + { + "Id": 287, + "City": "Lewisville", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Lewisville, Texas", + "Latitude": 33.046233, + "Longitude": -96.994174 + }, + { + "Id": 288, + "City": "South Bend", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "South Bend, Indiana", + "Latitude": 41.6763545, + "Longitude": -86.25198979999999 + }, + { + "Id": 289, + "City": "Lakeland", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Lakeland, Florida", + "Latitude": 28.0394654, + "Longitude": -81.9498042 + }, + { + "Id": 290, + "City": "Erie", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Erie, Pennsylvania", + "Latitude": 42.129224099999988, + "Longitude": -80.085059 + }, + { + "Id": 291, + "City": "Tyler", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Tyler, Texas", + "Latitude": 32.3512601, + "Longitude": -95.301062399999992 + }, + { + "Id": 292, + "City": "Pearland", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Pearland, Texas", + "Latitude": 29.5635666, + "Longitude": -95.2860474 + }, + { + "Id": 293, + "City": "College Station", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "College Station, Texas", + "Latitude": 30.627977, + "Longitude": -96.3344068 + }, + { + "Id": 294, + "City": "Kenosha", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Kenosha, Wisconsin", + "Latitude": 42.5847425, + "Longitude": -87.82118539999999 + }, + { + "Id": 295, + "City": "Sandy Springs", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Sandy Springs, Georgia", + "Latitude": 33.9304352, + "Longitude": -84.3733147 + }, + { + "Id": 296, + "City": "Clovis", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Clovis, California", + "Latitude": 36.8252277, + "Longitude": -119.7029194 + }, + { + "Id": 297, + "City": "Flint", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Flint, Michigan", + "Latitude": 43.0125274, + "Longitude": -83.6874562 + }, + { + "Id": 298, + "City": "Roanoke", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Roanoke, Virginia", + "Latitude": 37.2709704, + "Longitude": -79.9414266 + }, + { + "Id": 299, + "City": "Albany", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Albany, New York", + "Latitude": 42.6525793, + "Longitude": -73.7562317 + }, + { + "Id": 300, + "City": "Jurupa Valley", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Jurupa Valley, California", + "Latitude": 33.9971974, + "Longitude": -117.4854802 + }, + { + "Id": 301, + "City": "Compton", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Compton, California", + "Latitude": 33.8958492, + "Longitude": -118.2200712 + }, + { + "Id": 302, + "City": "San Angelo", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "San Angelo, Texas", + "Latitude": 31.4637723, + "Longitude": -100.4370375 + }, + { + "Id": 303, + "City": "Hillsboro", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Hillsboro, Oregon", + "Latitude": 45.5228939, + "Longitude": -122.989827 + }, + { + "Id": 304, + "City": "Lawton", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Lawton, Oklahoma", + "Latitude": 34.6035669, + "Longitude": -98.395929099999989 + }, + { + "Id": 305, + "City": "Renton", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Renton, Washington", + "Latitude": 47.482877599999988, + "Longitude": -122.2170661 + }, + { + "Id": 306, + "City": "Vista", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Vista, California", + "Latitude": 33.2000368, + "Longitude": -117.2425355 + }, + { + "Id": 307, + "City": "Davie", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Davie, Florida", + "Latitude": 26.0764783, + "Longitude": -80.25211569999999 + }, + { + "Id": 308, + "City": "Greeley", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Greeley, Colorado", + "Latitude": 40.4233142, + "Longitude": -104.7091322 + }, + { + "Id": 309, + "City": "Mission Viejo", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Mission Viejo, California", + "Latitude": 33.6000232, + "Longitude": -117.6719953 + }, + { + "Id": 310, + "City": "Portsmouth", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Portsmouth, Virginia", + "Latitude": 36.8354258, + "Longitude": -76.2982742 + }, + { + "Id": 311, + "City": "Dearborn", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Dearborn, Michigan", + "Latitude": 42.3222599, + "Longitude": -83.176314499999989 + }, + { + "Id": 312, + "City": "South Gate", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "South Gate, California", + "Latitude": 33.954737, + "Longitude": -118.2120161 + }, + { + "Id": 313, + "City": "Tuscaloosa", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Tuscaloosa, Alabama", + "Latitude": 33.2098407, + "Longitude": -87.569173499999991 + }, + { + "Id": 314, + "City": "Livonia", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Livonia, Michigan", + "Latitude": 42.36837, + "Longitude": -83.352709699999991 + }, + { + "Id": 315, + "City": "New Bedford", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "New Bedford, Massachusetts", + "Latitude": 41.6362152, + "Longitude": -70.934204999999992 + }, + { + "Id": 316, + "City": "Vacaville", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Vacaville, California", + "Latitude": 38.3565773, + "Longitude": -121.9877444 + }, + { + "Id": 317, + "City": "Brockton", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Brockton, Massachusetts", + "Latitude": 42.0834335, + "Longitude": -71.0183787 + }, + { + "Id": 318, + "City": "Roswell", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Roswell, Georgia", + "Latitude": 34.0232431, + "Longitude": -84.3615555 + }, + { + "Id": 319, + "City": "Beaverton", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Beaverton, Oregon", + "Latitude": 45.487061999999987, + "Longitude": -122.8037102 + }, + { + "Id": 320, + "City": "Quincy", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Quincy, Massachusetts", + "Latitude": 42.2528772, + "Longitude": -71.0022705 + }, + { + "Id": 321, + "City": "Sparks", + "State": "Nevada", + "StateAbbreviation": "NV", + "DisplayName": "Sparks, Nevada", + "Latitude": 39.5349112, + "Longitude": -119.7526886 + }, + { + "Id": 322, + "City": "Yakima", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Yakima, Washington", + "Latitude": 46.6020711, + "Longitude": -120.5058987 + }, + { + "Id": 323, + "City": "Lee's Summit", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Lee's Summit, Missouri", + "Latitude": 38.9108408, + "Longitude": -94.3821724 + }, + { + "Id": 324, + "City": "Federal Way", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Federal Way, Washington", + "Latitude": 47.3223221, + "Longitude": -122.3126222 + }, + { + "Id": 325, + "City": "Carson", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Carson, California", + "Latitude": 33.8316745, + "Longitude": -118.281693 + }, + { + "Id": 326, + "City": "Santa Monica", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Monica, California", + "Latitude": 34.0194543, + "Longitude": -118.4911912 + }, + { + "Id": 327, + "City": "Hesperia", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Hesperia, California", + "Latitude": 34.4263886, + "Longitude": -117.3008784 + }, + { + "Id": 328, + "City": "Allen", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Allen, Texas", + "Latitude": 33.1031744, + "Longitude": -96.670550300000016 + }, + { + "Id": 329, + "City": "Rio Rancho", + "State": "New Mexico", + "StateAbbreviation": "NM", + "DisplayName": "Rio Rancho, New Mexico", + "Latitude": 35.2327544, + "Longitude": -106.6630437 + }, + { + "Id": 330, + "City": "Yuma", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Yuma, Arizona", + "Latitude": 32.6926512, + "Longitude": -114.6276916 + }, + { + "Id": 331, + "City": "Westminster", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Westminster, California", + "Latitude": 33.7513419, + "Longitude": -117.9939921 + }, + { + "Id": 332, + "City": "Orem", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Orem, Utah", + "Latitude": 40.2968979, + "Longitude": -111.6946475 + }, + { + "Id": 333, + "City": "Lynn", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Lynn, Massachusetts", + "Latitude": 42.466763000000007, + "Longitude": -70.9494938 + }, + { + "Id": 334, + "City": "Redding", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Redding, California", + "Latitude": 40.5865396, + "Longitude": -122.3916754 + }, + { + "Id": 335, + "City": "Spokane Valley", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Spokane Valley, Washington", + "Latitude": 47.6732281, + "Longitude": -117.2393748 + }, + { + "Id": 336, + "City": "Miami Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Miami Beach, Florida", + "Latitude": 25.790654, + "Longitude": -80.1300455 + }, + { + "Id": 337, + "City": "League City", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "League City, Texas", + "Latitude": 29.5074538, + "Longitude": -95.0949303 + }, + { + "Id": 338, + "City": "Lawrence", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Lawrence, Kansas", + "Latitude": 38.9716689, + "Longitude": -95.2352501 + }, + { + "Id": 339, + "City": "Santa Barbara", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Barbara, California", + "Latitude": 34.4208305, + "Longitude": -119.6981901 + }, + { + "Id": 340, + "City": "Plantation", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Plantation, Florida", + "Latitude": 26.1275862, + "Longitude": -80.233103599999993 + }, + { + "Id": 341, + "City": "Sandy", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Sandy, Utah", + "Latitude": 40.5649781, + "Longitude": -111.8389726 + }, + { + "Id": 342, + "City": "Sunrise", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Sunrise, Florida", + "Latitude": 26.1669711, + "Longitude": -80.25659499999999 + }, + { + "Id": 343, + "City": "Macon", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Macon, Georgia", + "Latitude": 32.8406946, + "Longitude": -83.6324022 + }, + { + "Id": 344, + "City": "Longmont", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Longmont, Colorado", + "Latitude": 40.1672068, + "Longitude": -105.1019275 + }, + { + "Id": 345, + "City": "Boca Raton", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Boca Raton, Florida", + "Latitude": 26.3683064, + "Longitude": -80.1289321 + }, + { + "Id": 346, + "City": "San Marcos", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Marcos, California", + "Latitude": 33.1433723, + "Longitude": -117.1661449 + }, + { + "Id": 347, + "City": "Greenville", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Greenville, North Carolina", + "Latitude": 35.612661, + "Longitude": -77.3663538 + }, + { + "Id": 348, + "City": "Waukegan", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Waukegan, Illinois", + "Latitude": 42.3636331, + "Longitude": -87.844793799999991 + }, + { + "Id": 349, + "City": "Fall River", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Fall River, Massachusetts", + "Latitude": 41.7014912, + "Longitude": -71.1550451 + }, + { + "Id": 350, + "City": "Chico", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Chico, California", + "Latitude": 39.7284944, + "Longitude": -121.8374777 + }, + { + "Id": 351, + "City": "Newton", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Newton, Massachusetts", + "Latitude": 42.3370413, + "Longitude": -71.20922139999999 + }, + { + "Id": 352, + "City": "San Leandro", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Leandro, California", + "Latitude": 37.7249296, + "Longitude": -122.1560768 + }, + { + "Id": 353, + "City": "Reading", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Reading, Pennsylvania", + "Latitude": 40.3356483, + "Longitude": -75.9268747 + }, + { + "Id": 354, + "City": "Norwalk", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Norwalk, Connecticut", + "Latitude": 41.117743999999988, + "Longitude": -73.4081575 + }, + { + "Id": 355, + "City": "Fort Smith", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Fort Smith, Arkansas", + "Latitude": 35.3859242, + "Longitude": -94.398547499999992 + }, + { + "Id": 356, + "City": "Newport Beach", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Newport Beach, California", + "Latitude": 33.6189101, + "Longitude": -117.9289469 + }, + { + "Id": 357, + "City": "Asheville", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Asheville, North Carolina", + "Latitude": 35.5950581, + "Longitude": -82.5514869 + }, + { + "Id": 358, + "City": "Nashua", + "State": "New Hampshire", + "StateAbbreviation": "NH", + "DisplayName": "Nashua, New Hampshire", + "Latitude": 42.7653662, + "Longitude": -71.467565999999991 + }, + { + "Id": 359, + "City": "Edmond", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Edmond, Oklahoma", + "Latitude": 35.6528323, + "Longitude": -97.478095400000015 + }, + { + "Id": 360, + "City": "Whittier", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Whittier, California", + "Latitude": 33.9791793, + "Longitude": -118.032844 + }, + { + "Id": 361, + "City": "Nampa", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Nampa, Idaho", + "Latitude": 43.5407172, + "Longitude": -116.5634624 + }, + { + "Id": 362, + "City": "Bloomington", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Bloomington, Minnesota", + "Latitude": 44.840798, + "Longitude": -93.2982799 + }, + { + "Id": 363, + "City": "Deltona", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Deltona, Florida", + "Latitude": 28.9005446, + "Longitude": -81.263673799999992 + }, + { + "Id": 364, + "City": "Hawthorne", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Hawthorne, California", + "Latitude": 33.9164032, + "Longitude": -118.3525748 + }, + { + "Id": 365, + "City": "Duluth", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Duluth, Minnesota", + "Latitude": 46.786671899999988, + "Longitude": -92.1004852 + }, + { + "Id": 366, + "City": "Carmel", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Carmel, Indiana", + "Latitude": 39.978371, + "Longitude": -86.1180435 + }, + { + "Id": 367, + "City": "Suffolk", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Suffolk, Virginia", + "Latitude": 36.7282054, + "Longitude": -76.5835621 + }, + { + "Id": 368, + "City": "Clifton", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Clifton, New Jersey", + "Latitude": 40.8584328, + "Longitude": -74.163755299999991 + }, + { + "Id": 369, + "City": "Citrus Heights", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Citrus Heights, California", + "Latitude": 38.7071247, + "Longitude": -121.2810611 + }, + { + "Id": 370, + "City": "Livermore", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Livermore, California", + "Latitude": 37.6818745, + "Longitude": -121.7680088 + }, + { + "Id": 371, + "City": "Tracy", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Tracy, California", + "Latitude": 37.7396513, + "Longitude": -121.4252227 + }, + { + "Id": 372, + "City": "Alhambra", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Alhambra, California", + "Latitude": 34.095287, + "Longitude": -118.1270146 + }, + { + "Id": 373, + "City": "Kirkland", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Kirkland, Washington", + "Latitude": 47.6814875, + "Longitude": -122.2087353 + }, + { + "Id": 374, + "City": "Trenton", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Trenton, New Jersey", + "Latitude": 40.2170534, + "Longitude": -74.7429384 + }, + { + "Id": 375, + "City": "Ogden", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Ogden, Utah", + "Latitude": 41.223, + "Longitude": -111.9738304 + }, + { + "Id": 376, + "City": "Hoover", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Hoover, Alabama", + "Latitude": 33.4053867, + "Longitude": -86.8113781 + }, + { + "Id": 377, + "City": "Cicero", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Cicero, Illinois", + "Latitude": 41.8455877, + "Longitude": -87.7539448 + }, + { + "Id": 378, + "City": "Fishers", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Fishers, Indiana", + "Latitude": 39.9567548, + "Longitude": -86.01335 + }, + { + "Id": 379, + "City": "Sugar Land", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Sugar Land, Texas", + "Latitude": 29.6196787, + "Longitude": -95.6349463 + }, + { + "Id": 380, + "City": "Danbury", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Danbury, Connecticut", + "Latitude": 41.394817, + "Longitude": -73.4540111 + }, + { + "Id": 381, + "City": "Meridian", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Meridian, Idaho", + "Latitude": 43.6121087, + "Longitude": -116.3915131 + }, + { + "Id": 382, + "City": "Indio", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Indio, California", + "Latitude": 33.7205771, + "Longitude": -116.2155619 + }, + { + "Id": 383, + "City": "Concord", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Concord, North Carolina", + "Latitude": 35.4087517, + "Longitude": -80.579511 + }, + { + "Id": 384, + "City": "Menifee", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Menifee, California", + "Latitude": 33.6971468, + "Longitude": -117.185294 + }, + { + "Id": 385, + "City": "Champaign", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Champaign, Illinois", + "Latitude": 40.1164204, + "Longitude": -88.2433829 + }, + { + "Id": 386, + "City": "Buena Park", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Buena Park, California", + "Latitude": 33.8675143, + "Longitude": -117.9981181 + }, + { + "Id": 387, + "City": "Troy", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Troy, Michigan", + "Latitude": 42.6064095, + "Longitude": -83.1497751 + }, + { + "Id": 388, + "City": "O'Fallon", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "O'Fallon, Missouri", + "Latitude": 38.8106075, + "Longitude": -90.699847699999992 + }, + { + "Id": 389, + "City": "Johns Creek", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Johns Creek, Georgia", + "Latitude": 34.0289259, + "Longitude": -84.198579 + }, + { + "Id": 390, + "City": "Bellingham", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Bellingham, Washington", + "Latitude": 48.74908, + "Longitude": -122.4781473 + }, + { + "Id": 391, + "City": "Westland", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Westland, Michigan", + "Latitude": 42.324203999999988, + "Longitude": -83.400211 + }, + { + "Id": 392, + "City": "Bloomington", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Bloomington, Indiana", + "Latitude": 39.165325, + "Longitude": -86.526385699999992 + }, + { + "Id": 393, + "City": "Sioux City", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Sioux City, Iowa", + "Latitude": 42.4999942, + "Longitude": -96.40030689999999 + }, + { + "Id": 394, + "City": "Warwick", + "State": "Rhode Island", + "StateAbbreviation": "RI", + "DisplayName": "Warwick, Rhode Island", + "Latitude": 41.7001009, + "Longitude": -71.4161671 + }, + { + "Id": 395, + "City": "Hemet", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Hemet, California", + "Latitude": 33.7475203, + "Longitude": -116.9719684 + }, + { + "Id": 396, + "City": "Longview", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Longview, Texas", + "Latitude": 32.5007037, + "Longitude": -94.740489099999991 + }, + { + "Id": 397, + "City": "Farmington Hills", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Farmington Hills, Michigan", + "Latitude": 42.4989936, + "Longitude": -83.3677168 + }, + { + "Id": 398, + "City": "Bend", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Bend, Oregon", + "Latitude": 44.0581728, + "Longitude": -121.3153096 + }, + { + "Id": 399, + "City": "Lakewood", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lakewood, California", + "Latitude": 33.8536269, + "Longitude": -118.1339563 + }, + { + "Id": 400, + "City": "Merced", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Merced, California", + "Latitude": 37.3021632, + "Longitude": -120.4829677 + }, + { + "Id": 401, + "City": "Mission", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Mission, Texas", + "Latitude": 26.2159066, + "Longitude": -98.32529319999999 + }, + { + "Id": 402, + "City": "Chino", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Chino, California", + "Latitude": 34.0122346, + "Longitude": -117.688944 + }, + { + "Id": 403, + "City": "Redwood City", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Redwood City, California", + "Latitude": 37.485215200000013, + "Longitude": -122.2363548 + }, + { + "Id": 404, + "City": "Edinburg", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Edinburg, Texas", + "Latitude": 26.3017374, + "Longitude": -98.1633432 + }, + { + "Id": 405, + "City": "Cranston", + "State": "Rhode Island", + "StateAbbreviation": "RI", + "DisplayName": "Cranston, Rhode Island", + "Latitude": 41.7798226, + "Longitude": -71.4372796 + }, + { + "Id": 406, + "City": "Parma", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Parma, Ohio", + "Latitude": 41.4047742, + "Longitude": -81.7229086 + }, + { + "Id": 407, + "City": "New Rochelle", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "New Rochelle, New York", + "Latitude": 40.9114882, + "Longitude": -73.7823549 + }, + { + "Id": 408, + "City": "Lake Forest", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lake Forest, California", + "Latitude": 33.6469661, + "Longitude": -117.689218 + }, + { + "Id": 409, + "City": "Napa", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Napa, California", + "Latitude": 38.2975381, + "Longitude": -122.286865 + }, + { + "Id": 410, + "City": "Hammond", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Hammond, Indiana", + "Latitude": 41.5833688, + "Longitude": -87.5000412 + }, + { + "Id": 411, + "City": "Fayetteville", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Fayetteville, Arkansas", + "Latitude": 36.0625795, + "Longitude": -94.1574263 + }, + { + "Id": 412, + "City": "Bloomington", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Bloomington, Illinois", + "Latitude": 40.4842027, + "Longitude": -88.993687299999991 + }, + { + "Id": 413, + "City": "Avondale", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Avondale, Arizona", + "Latitude": 33.4355977, + "Longitude": -112.3496021 + }, + { + "Id": 414, + "City": "Somerville", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Somerville, Massachusetts", + "Latitude": 42.3875968, + "Longitude": -71.0994968 + }, + { + "Id": 415, + "City": "Palm Coast", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Palm Coast, Florida", + "Latitude": 29.5844524, + "Longitude": -81.207869899999992 + }, + { + "Id": 416, + "City": "Bryan", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Bryan, Texas", + "Latitude": 30.6743643, + "Longitude": -96.3699632 + }, + { + "Id": 417, + "City": "Gary", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Gary, Indiana", + "Latitude": 41.5933696, + "Longitude": -87.3464271 + }, + { + "Id": 418, + "City": "Largo", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Largo, Florida", + "Latitude": 27.9094665, + "Longitude": -82.7873244 + }, + { + "Id": 419, + "City": "Brooklyn Park", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Brooklyn Park, Minnesota", + "Latitude": 45.0941315, + "Longitude": -93.3563405 + }, + { + "Id": 420, + "City": "Tustin", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Tustin, California", + "Latitude": 33.7458511, + "Longitude": -117.826166 + }, + { + "Id": 421, + "City": "Racine", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Racine, Wisconsin", + "Latitude": 42.7261309, + "Longitude": -87.782852300000016 + }, + { + "Id": 422, + "City": "Deerfield Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Deerfield Beach, Florida", + "Latitude": 26.3184123, + "Longitude": -80.099765699999992 + }, + { + "Id": 423, + "City": "Lynchburg", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Lynchburg, Virginia", + "Latitude": 37.4137536, + "Longitude": -79.142246399999991 + }, + { + "Id": 424, + "City": "Mountain View", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Mountain View, California", + "Latitude": 37.3860517, + "Longitude": -122.0838511 + }, + { + "Id": 425, + "City": "Medford", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Medford, Oregon", + "Latitude": 42.3265152, + "Longitude": -122.8755949 + }, + { + "Id": 426, + "City": "Lawrence", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Lawrence, Massachusetts", + "Latitude": 42.7070354, + "Longitude": -71.1631137 + }, + { + "Id": 427, + "City": "Bellflower", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Bellflower, California", + "Latitude": 33.8816818, + "Longitude": -118.1170117 + }, + { + "Id": 428, + "City": "Melbourne", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Melbourne, Florida", + "Latitude": 28.0836269, + "Longitude": -80.608108899999991 + }, + { + "Id": 429, + "City": "St. Joseph", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "St. Joseph, Missouri", + "Latitude": 39.7674578, + "Longitude": -94.84668099999999 + }, + { + "Id": 430, + "City": "Camden", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Camden, New Jersey", + "Latitude": 39.9259463, + "Longitude": -75.1196199 + }, + { + "Id": 431, + "City": "St. George", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "St. George, Utah", + "Latitude": 37.0965278, + "Longitude": -113.5684164 + }, + { + "Id": 432, + "City": "Kennewick", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Kennewick, Washington", + "Latitude": 46.2112458, + "Longitude": -119.1372338 + }, + { + "Id": 433, + "City": "Baldwin Park", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Baldwin Park, California", + "Latitude": 34.0852868, + "Longitude": -117.9608978 + }, + { + "Id": 434, + "City": "Chino Hills", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Chino Hills, California", + "Latitude": 33.9898188, + "Longitude": -117.7325848 + }, + { + "Id": 435, + "City": "Alameda", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Alameda, California", + "Latitude": 37.7652065, + "Longitude": -122.2416355 + }, + { + "Id": 436, + "City": "Albany", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Albany, Georgia", + "Latitude": 31.5785074, + "Longitude": -84.155740999999992 + }, + { + "Id": 437, + "City": "Arlington Heights", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Arlington Heights, Illinois", + "Latitude": 42.0883603, + "Longitude": -87.980626500000014 + }, + { + "Id": 438, + "City": "Scranton", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Scranton, Pennsylvania", + "Latitude": 41.408969, + "Longitude": -75.662412199999991 + }, + { + "Id": 439, + "City": "Evanston", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Evanston, Illinois", + "Latitude": 42.0450722, + "Longitude": -87.687696899999992 + }, + { + "Id": 440, + "City": "Kalamazoo", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Kalamazoo, Michigan", + "Latitude": 42.2917069, + "Longitude": -85.5872286 + }, + { + "Id": 441, + "City": "Baytown", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Baytown, Texas", + "Latitude": 29.7355047, + "Longitude": -94.97742740000001 + }, + { + "Id": 442, + "City": "Upland", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Upland, California", + "Latitude": 34.09751, + "Longitude": -117.6483876 + }, + { + "Id": 443, + "City": "Springdale", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Springdale, Arkansas", + "Latitude": 36.186744200000007, + "Longitude": -94.1288141 + }, + { + "Id": 444, + "City": "Bethlehem", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Bethlehem, Pennsylvania", + "Latitude": 40.6259316, + "Longitude": -75.370457899999991 + }, + { + "Id": 445, + "City": "Schaumburg", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Schaumburg, Illinois", + "Latitude": 42.0333607, + "Longitude": -88.0834059 + }, + { + "Id": 446, + "City": "Mount Pleasant", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Mount Pleasant, South Carolina", + "Latitude": 32.8323225, + "Longitude": -79.828425799999991 + }, + { + "Id": 447, + "City": "Auburn", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Auburn, Washington", + "Latitude": 47.307322799999987, + "Longitude": -122.2284532 + }, + { + "Id": 448, + "City": "Decatur", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Decatur, Illinois", + "Latitude": 39.8403147, + "Longitude": -88.9548001 + }, + { + "Id": 449, + "City": "San Ramon", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Ramon, California", + "Latitude": 37.7799273, + "Longitude": -121.9780153 + }, + { + "Id": 450, + "City": "Pleasanton", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Pleasanton, California", + "Latitude": 37.6624312, + "Longitude": -121.8746789 + }, + { + "Id": 451, + "City": "Wyoming", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Wyoming, Michigan", + "Latitude": 42.9133602, + "Longitude": -85.7053085 + }, + { + "Id": 452, + "City": "Lake Charles", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Lake Charles, Louisiana", + "Latitude": 30.2265949, + "Longitude": -93.2173758 + }, + { + "Id": 453, + "City": "Plymouth", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Plymouth, Minnesota", + "Latitude": 45.0105194, + "Longitude": -93.4555093 + }, + { + "Id": 454, + "City": "Bolingbrook", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Bolingbrook, Illinois", + "Latitude": 41.698641599999988, + "Longitude": -88.0683955 + }, + { + "Id": 455, + "City": "Pharr", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Pharr, Texas", + "Latitude": 26.1947962, + "Longitude": -98.1836216 + }, + { + "Id": 456, + "City": "Appleton", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Appleton, Wisconsin", + "Latitude": 44.2619309, + "Longitude": -88.41538469999999 + }, + { + "Id": 457, + "City": "Gastonia", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Gastonia, North Carolina", + "Latitude": 35.262082, + "Longitude": -81.187300499999992 + }, + { + "Id": 458, + "City": "Folsom", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Folsom, California", + "Latitude": 38.6779591, + "Longitude": -121.1760583 + }, + { + "Id": 459, + "City": "Southfield", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Southfield, Michigan", + "Latitude": 42.4733688, + "Longitude": -83.2218731 + }, + { + "Id": 460, + "City": "Rochester Hills", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Rochester Hills, Michigan", + "Latitude": 42.658366099999988, + "Longitude": -83.1499322 + }, + { + "Id": 461, + "City": "New Britain", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "New Britain, Connecticut", + "Latitude": 41.6612104, + "Longitude": -72.7795419 + }, + { + "Id": 462, + "City": "Goodyear", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Goodyear, Arizona", + "Latitude": 33.4353394, + "Longitude": -112.3576567 + }, + { + "Id": 463, + "City": "Canton", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Canton, Ohio", + "Latitude": 40.798947299999988, + "Longitude": -81.378447 + }, + { + "Id": 464, + "City": "Warner Robins", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Warner Robins, Georgia", + "Latitude": 32.6130007, + "Longitude": -83.624201 + }, + { + "Id": 465, + "City": "Union City", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Union City, California", + "Latitude": 37.5933918, + "Longitude": -122.0438298 + }, + { + "Id": 466, + "City": "Perris", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Perris, California", + "Latitude": 33.7825194, + "Longitude": -117.2286478 + }, + { + "Id": 467, + "City": "Manteca", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Manteca, California", + "Latitude": 37.7974273, + "Longitude": -121.2160526 + }, + { + "Id": 468, + "City": "Iowa City", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Iowa City, Iowa", + "Latitude": 41.6611277, + "Longitude": -91.5301683 + }, + { + "Id": 469, + "City": "Jonesboro", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Jonesboro, Arkansas", + "Latitude": 35.842296700000013, + "Longitude": -90.704279 + }, + { + "Id": 470, + "City": "Wilmington", + "State": "Delaware", + "StateAbbreviation": "DE", + "DisplayName": "Wilmington, Delaware", + "Latitude": 39.7390721, + "Longitude": -75.5397878 + }, + { + "Id": 471, + "City": "Lynwood", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lynwood, California", + "Latitude": 33.930293, + "Longitude": -118.2114603 + }, + { + "Id": 472, + "City": "Loveland", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Loveland, Colorado", + "Latitude": 40.3977612, + "Longitude": -105.0749801 + }, + { + "Id": 473, + "City": "Pawtucket", + "State": "Rhode Island", + "StateAbbreviation": "RI", + "DisplayName": "Pawtucket, Rhode Island", + "Latitude": 41.878711, + "Longitude": -71.382555799999992 + }, + { + "Id": 474, + "City": "Boynton Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Boynton Beach, Florida", + "Latitude": 26.5317866, + "Longitude": -80.0905465 + }, + { + "Id": 475, + "City": "Waukesha", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Waukesha, Wisconsin", + "Latitude": 43.0116784, + "Longitude": -88.2314813 + }, + { + "Id": 476, + "City": "Gulfport", + "State": "Mississippi", + "StateAbbreviation": "MS", + "DisplayName": "Gulfport, Mississippi", + "Latitude": 30.3674198, + "Longitude": -89.0928155 + }, + { + "Id": 477, + "City": "Apple Valley", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Apple Valley, California", + "Latitude": 34.5008311, + "Longitude": -117.1858759 + }, + { + "Id": 478, + "City": "Passaic", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Passaic, New Jersey", + "Latitude": 40.8567662, + "Longitude": -74.1284764 + }, + { + "Id": 479, + "City": "Rapid City", + "State": "South Dakota", + "StateAbbreviation": "SD", + "DisplayName": "Rapid City, South Dakota", + "Latitude": 44.0805434, + "Longitude": -103.2310149 + }, + { + "Id": 480, + "City": "Layton", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Layton, Utah", + "Latitude": 41.0602216, + "Longitude": -111.9710529 + }, + { + "Id": 481, + "City": "Lafayette", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Lafayette, Indiana", + "Latitude": 40.4167022, + "Longitude": -86.875286899999992 + }, + { + "Id": 482, + "City": "Turlock", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Turlock, California", + "Latitude": 37.4946568, + "Longitude": -120.8465941 + }, + { + "Id": 483, + "City": "Muncie", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Muncie, Indiana", + "Latitude": 40.1933767, + "Longitude": -85.3863599 + }, + { + "Id": 484, + "City": "Temple", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Temple, Texas", + "Latitude": 31.0982344, + "Longitude": -97.342782 + }, + { + "Id": 485, + "City": "Missouri City", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Missouri City, Texas", + "Latitude": 29.6185669, + "Longitude": -95.5377215 + }, + { + "Id": 486, + "City": "Redlands", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Redlands, California", + "Latitude": 34.0555693, + "Longitude": -117.1825381 + }, + { + "Id": 487, + "City": "Santa Fe", + "State": "New Mexico", + "StateAbbreviation": "NM", + "DisplayName": "Santa Fe, New Mexico", + "Latitude": 35.6869752, + "Longitude": -105.937799 + }, + { + "Id": 488, + "City": "Lauderhill", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Lauderhill, Florida", + "Latitude": 26.1403635, + "Longitude": -80.2133808 + }, + { + "Id": 489, + "City": "Milpitas", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Milpitas, California", + "Latitude": 37.4323341, + "Longitude": -121.8995741 + }, + { + "Id": 490, + "City": "Palatine", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Palatine, Illinois", + "Latitude": 42.1103041, + "Longitude": -88.034240000000011 + }, + { + "Id": 491, + "City": "Missoula", + "State": "Montana", + "StateAbbreviation": "MT", + "DisplayName": "Missoula, Montana", + "Latitude": 46.878717599999987, + "Longitude": -113.996586 + }, + { + "Id": 492, + "City": "Rock Hill", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Rock Hill, South Carolina", + "Latitude": 34.9248667, + "Longitude": -81.025078400000012 + }, + { + "Id": 493, + "City": "Jacksonville", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Jacksonville, North Carolina", + "Latitude": 34.7540524, + "Longitude": -77.4302414 + }, + { + "Id": 494, + "City": "Franklin", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Franklin, Tennessee", + "Latitude": 35.9250637, + "Longitude": -86.8688899 + }, + { + "Id": 495, + "City": "Flagstaff", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Flagstaff, Arizona", + "Latitude": 35.1982836, + "Longitude": -111.651302 + }, + { + "Id": 496, + "City": "Flower Mound", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Flower Mound, Texas", + "Latitude": 33.0145673, + "Longitude": -97.0969552 + }, + { + "Id": 497, + "City": "Weston", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Weston, Florida", + "Latitude": 26.1003654, + "Longitude": -80.3997748 + }, + { + "Id": 498, + "City": "Waterloo", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Waterloo, Iowa", + "Latitude": 42.492786, + "Longitude": -92.34257749999999 + }, + { + "Id": 499, + "City": "Union City", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Union City, New Jersey", + "Latitude": 40.6975898, + "Longitude": -74.26316349999999 + }, + { + "Id": 500, + "City": "Mount Vernon", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Mount Vernon, New York", + "Latitude": 40.9125992, + "Longitude": -73.8370786 + }, + { + "Id": 501, + "City": "Fort Myers", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Fort Myers, Florida", + "Latitude": 26.640628, + "Longitude": -81.8723084 + }, + { + "Id": 502, + "City": "Dothan", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Dothan, Alabama", + "Latitude": 31.2232313, + "Longitude": -85.3904888 + }, + { + "Id": 503, + "City": "Rancho Cordova", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rancho Cordova, California", + "Latitude": 38.5890723, + "Longitude": -121.302728 + }, + { + "Id": 504, + "City": "Redondo Beach", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Redondo Beach, California", + "Latitude": 33.8491816, + "Longitude": -118.3884078 + }, + { + "Id": 505, + "City": "Jackson", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Jackson, Tennessee", + "Latitude": 35.6145169, + "Longitude": -88.813946899999991 + }, + { + "Id": 506, + "City": "Pasco", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Pasco, Washington", + "Latitude": 46.2395793, + "Longitude": -119.1005657 + }, + { + "Id": 507, + "City": "St. Charles", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "St. Charles, Missouri", + "Latitude": 38.7881062, + "Longitude": -90.4974359 + }, + { + "Id": 508, + "City": "Eau Claire", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Eau Claire, Wisconsin", + "Latitude": 44.811349, + "Longitude": -91.4984941 + }, + { + "Id": 509, + "City": "North Richland Hills", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "North Richland Hills, Texas", + "Latitude": 32.8342952, + "Longitude": -97.2289029 + }, + { + "Id": 510, + "City": "Bismarck", + "State": "North Dakota", + "StateAbbreviation": "ND", + "DisplayName": "Bismarck, North Dakota", + "Latitude": 46.8083268, + "Longitude": -100.7837392 + }, + { + "Id": 511, + "City": "Yorba Linda", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Yorba Linda, California", + "Latitude": 33.8886259, + "Longitude": -117.8131125 + }, + { + "Id": 512, + "City": "Kenner", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Kenner, Louisiana", + "Latitude": 29.9940924, + "Longitude": -90.2417434 + }, + { + "Id": 513, + "City": "Walnut Creek", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Walnut Creek, California", + "Latitude": 37.9100783, + "Longitude": -122.0651819 + }, + { + "Id": 514, + "City": "Frederick", + "State": "Maryland", + "StateAbbreviation": "MD", + "DisplayName": "Frederick, Maryland", + "Latitude": 39.414268799999988, + "Longitude": -77.4105409 + }, + { + "Id": 515, + "City": "Oshkosh", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Oshkosh, Wisconsin", + "Latitude": 44.0247062, + "Longitude": -88.5426136 + }, + { + "Id": 516, + "City": "Pittsburg", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Pittsburg, California", + "Latitude": 38.0279762, + "Longitude": -121.8846806 + }, + { + "Id": 517, + "City": "Palo Alto", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Palo Alto, California", + "Latitude": 37.4418834, + "Longitude": -122.1430195 + }, + { + "Id": 518, + "City": "Bossier City", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Bossier City, Louisiana", + "Latitude": 32.5159852, + "Longitude": -93.7321228 + }, + { + "Id": 519, + "City": "Portland", + "State": "Maine", + "StateAbbreviation": "ME", + "DisplayName": "Portland, Maine", + "Latitude": 43.661471000000013, + "Longitude": -70.2553259 + }, + { + "Id": 520, + "City": "St. Cloud", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "St. Cloud, Minnesota", + "Latitude": 45.5579451, + "Longitude": -94.163240399999992 + }, + { + "Id": 521, + "City": "Davis", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Davis, California", + "Latitude": 38.5449065, + "Longitude": -121.7405167 + }, + { + "Id": 522, + "City": "South San Francisco", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "South San Francisco, California", + "Latitude": 37.654656, + "Longitude": -122.4077498 + }, + { + "Id": 523, + "City": "Camarillo", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Camarillo, California", + "Latitude": 34.2163937, + "Longitude": -119.0376023 + }, + { + "Id": 524, + "City": "North Little Rock", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "North Little Rock, Arkansas", + "Latitude": 34.769536, + "Longitude": -92.2670941 + }, + { + "Id": 525, + "City": "Schenectady", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Schenectady, New York", + "Latitude": 42.8142432, + "Longitude": -73.9395687 + }, + { + "Id": 526, + "City": "Gaithersburg", + "State": "Maryland", + "StateAbbreviation": "MD", + "DisplayName": "Gaithersburg, Maryland", + "Latitude": 39.1434406, + "Longitude": -77.2013705 + }, + { + "Id": 527, + "City": "Harlingen", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Harlingen, Texas", + "Latitude": 26.1906306, + "Longitude": -97.696102599999989 + }, + { + "Id": 528, + "City": "Woodbury", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Woodbury, Minnesota", + "Latitude": 44.9238552, + "Longitude": -92.9593797 + }, + { + "Id": 529, + "City": "Eagan", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Eagan, Minnesota", + "Latitude": 44.8041322, + "Longitude": -93.1668858 + }, + { + "Id": 530, + "City": "Yuba City", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Yuba City, California", + "Latitude": 39.1404477, + "Longitude": -121.6169108 + }, + { + "Id": 531, + "City": "Maple Grove", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Maple Grove, Minnesota", + "Latitude": 45.0724642, + "Longitude": -93.4557877 + }, + { + "Id": 532, + "City": "Youngstown", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Youngstown, Ohio", + "Latitude": 41.0997803, + "Longitude": -80.6495194 + }, + { + "Id": 533, + "City": "Skokie", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Skokie, Illinois", + "Latitude": 42.0324025, + "Longitude": -87.7416246 + }, + { + "Id": 534, + "City": "Kissimmee", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Kissimmee, Florida", + "Latitude": 28.2919557, + "Longitude": -81.40757099999999 + }, + { + "Id": 535, + "City": "Johnson City", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Johnson City, Tennessee", + "Latitude": 36.3134397, + "Longitude": -82.3534727 + }, + { + "Id": 536, + "City": "Victoria", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Victoria, Texas", + "Latitude": 28.8052674, + "Longitude": -97.0035982 + }, + { + "Id": 537, + "City": "San Clemente", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Clemente, California", + "Latitude": 33.4269728, + "Longitude": -117.6119925 + }, + { + "Id": 538, + "City": "Bayonne", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Bayonne, New Jersey", + "Latitude": 40.6687141, + "Longitude": -74.1143091 + }, + { + "Id": 539, + "City": "Laguna Niguel", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Laguna Niguel, California", + "Latitude": 33.5225261, + "Longitude": -117.7075526 + }, + { + "Id": 540, + "City": "East Orange", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "East Orange, New Jersey", + "Latitude": 40.767323, + "Longitude": -74.2048677 + }, + { + "Id": 541, + "City": "Shawnee", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Shawnee, Kansas", + "Latitude": 39.022848499999988, + "Longitude": -94.7151865 + }, + { + "Id": 542, + "City": "Homestead", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Homestead, Florida", + "Latitude": 25.4687224, + "Longitude": -80.4775569 + }, + { + "Id": 544, + "City": "Rockville", + "State": "Maryland", + "StateAbbreviation": "MD", + "DisplayName": "Rockville, Maryland", + "Latitude": 39.0839973, + "Longitude": -77.1527578 + }, + { + "Id": 543, + "City": "Delray Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Delray Beach, Florida", + "Latitude": 26.4614625, + "Longitude": -80.0728201 + }, + { + "Id": 545, + "City": "Janesville", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Janesville, Wisconsin", + "Latitude": 42.6827885, + "Longitude": -89.0187222 + }, + { + "Id": 546, + "City": "Conway", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Conway, Arkansas", + "Latitude": 35.0886963, + "Longitude": -92.4421011 + }, + { + "Id": 547, + "City": "Pico Rivera", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Pico Rivera, California", + "Latitude": 33.9830688, + "Longitude": -118.096735 + }, + { + "Id": 548, + "City": "Lorain", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Lorain, Ohio", + "Latitude": 41.452819, + "Longitude": -82.1823746 + }, + { + "Id": 549, + "City": "Montebello", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Montebello, California", + "Latitude": 34.0165053, + "Longitude": -118.1137535 + }, + { + "Id": 550, + "City": "Lodi", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lodi, California", + "Latitude": 38.1341477, + "Longitude": -121.2722194 + }, + { + "Id": 551, + "City": "New Braunfels", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "New Braunfels, Texas", + "Latitude": 29.7030024, + "Longitude": -98.1244531 + }, + { + "Id": 552, + "City": "Marysville", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Marysville, Washington", + "Latitude": 48.0517637, + "Longitude": -122.1770818 + }, + { + "Id": 553, + "City": "Tamarac", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Tamarac, Florida", + "Latitude": 26.2128609, + "Longitude": -80.2497707 + }, + { + "Id": 554, + "City": "Madera", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Madera, California", + "Latitude": 36.9613356, + "Longitude": -120.0607176 + }, + { + "Id": 555, + "City": "Conroe", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Conroe, Texas", + "Latitude": 30.3118769, + "Longitude": -95.45605119999999 + }, + { + "Id": 556, + "City": "Santa Cruz", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santa Cruz, California", + "Latitude": 36.9741171, + "Longitude": -122.0307963 + }, + { + "Id": 557, + "City": "Eden Prairie", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Eden Prairie, Minnesota", + "Latitude": 44.8546856, + "Longitude": -93.47078599999999 + }, + { + "Id": 558, + "City": "Cheyenne", + "State": "Wyoming", + "StateAbbreviation": "WY", + "DisplayName": "Cheyenne, Wyoming", + "Latitude": 41.1399814, + "Longitude": -104.8202462 + }, + { + "Id": 559, + "City": "Daytona Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Daytona Beach, Florida", + "Latitude": 29.2108147, + "Longitude": -81.0228331 + }, + { + "Id": 560, + "City": "Alpharetta", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Alpharetta, Georgia", + "Latitude": 34.0753762, + "Longitude": -84.2940899 + }, + { + "Id": 561, + "City": "Hamilton", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Hamilton, Ohio", + "Latitude": 39.3995008, + "Longitude": -84.5613355 + }, + { + "Id": 562, + "City": "Waltham", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Waltham, Massachusetts", + "Latitude": 42.3764852, + "Longitude": -71.2356113 + }, + { + "Id": 563, + "City": "Coon Rapids", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Coon Rapids, Minnesota", + "Latitude": 45.1732394, + "Longitude": -93.303006299999993 + }, + { + "Id": 564, + "City": "Haverhill", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Haverhill, Massachusetts", + "Latitude": 42.7762015, + "Longitude": -71.0772796 + }, + { + "Id": 565, + "City": "Council Bluffs", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Council Bluffs, Iowa", + "Latitude": 41.2619444, + "Longitude": -95.8608333 + }, + { + "Id": 566, + "City": "Taylor", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Taylor, Michigan", + "Latitude": 42.240872, + "Longitude": -83.2696509 + }, + { + "Id": 567, + "City": "Utica", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Utica, New York", + "Latitude": 43.100903, + "Longitude": -75.232664 + }, + { + "Id": 568, + "City": "Ames", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Ames, Iowa", + "Latitude": 42.034722, + "Longitude": -93.61999999999999 + }, + { + "Id": 569, + "City": "La Habra", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "La Habra, California", + "Latitude": 33.9319578, + "Longitude": -117.9461734 + }, + { + "Id": 570, + "City": "Encinitas", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Encinitas, California", + "Latitude": 33.0369867, + "Longitude": -117.2919818 + }, + { + "Id": 571, + "City": "Bowling Green", + "State": "Kentucky", + "StateAbbreviation": "KY", + "DisplayName": "Bowling Green, Kentucky", + "Latitude": 36.9685219, + "Longitude": -86.4808043 + }, + { + "Id": 572, + "City": "Burnsville", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Burnsville, Minnesota", + "Latitude": 44.7677424, + "Longitude": -93.27772259999999 + }, + { + "Id": 573, + "City": "Greenville", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Greenville, South Carolina", + "Latitude": 34.852617599999988, + "Longitude": -82.3940104 + }, + { + "Id": 574, + "City": "West Des Moines", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "West Des Moines, Iowa", + "Latitude": 41.5772115, + "Longitude": -93.711332 + }, + { + "Id": 575, + "City": "Cedar Park", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Cedar Park, Texas", + "Latitude": 30.505198, + "Longitude": -97.8202888 + }, + { + "Id": 576, + "City": "Tulare", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Tulare, California", + "Latitude": 36.2077288, + "Longitude": -119.3473379 + }, + { + "Id": 577, + "City": "Monterey Park", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Monterey Park, California", + "Latitude": 34.0625106, + "Longitude": -118.1228476 + }, + { + "Id": 578, + "City": "Vineland", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Vineland, New Jersey", + "Latitude": 39.4863773, + "Longitude": -75.025963699999991 + }, + { + "Id": 579, + "City": "Terre Haute", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Terre Haute, Indiana", + "Latitude": 39.4667034, + "Longitude": -87.413909199999992 + }, + { + "Id": 580, + "City": "North Miami", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "North Miami, Florida", + "Latitude": 25.8900949, + "Longitude": -80.1867138 + }, + { + "Id": 581, + "City": "Mansfield", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Mansfield, Texas", + "Latitude": 32.5631924, + "Longitude": -97.1416768 + }, + { + "Id": 582, + "City": "West Allis", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "West Allis, Wisconsin", + "Latitude": 43.0166806, + "Longitude": -88.0070315 + }, + { + "Id": 583, + "City": "Bristol", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Bristol, Connecticut", + "Latitude": 41.671764800000012, + "Longitude": -72.9492703 + }, + { + "Id": 584, + "City": "Taylorsville", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Taylorsville, Utah", + "Latitude": 40.667724799999988, + "Longitude": -111.9388258 + }, + { + "Id": 585, + "City": "Malden", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Malden, Massachusetts", + "Latitude": 42.4250964, + "Longitude": -71.066163 + }, + { + "Id": 586, + "City": "Meriden", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Meriden, Connecticut", + "Latitude": 41.5381535, + "Longitude": -72.807043499999992 + }, + { + "Id": 587, + "City": "Blaine", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Blaine, Minnesota", + "Latitude": 45.1607987, + "Longitude": -93.234948899999992 + }, + { + "Id": 588, + "City": "Wellington", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Wellington, Florida", + "Latitude": 26.6617635, + "Longitude": -80.2683571 + }, + { + "Id": 589, + "City": "Cupertino", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Cupertino, California", + "Latitude": 37.3229978, + "Longitude": -122.0321823 + }, + { + "Id": 590, + "City": "Springfield", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Springfield, Oregon", + "Latitude": 44.0462362, + "Longitude": -123.0220289 + }, + { + "Id": 591, + "City": "Rogers", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Rogers, Arkansas", + "Latitude": 36.3320196, + "Longitude": -94.1185366 + }, + { + "Id": 592, + "City": "St. Clair Shores", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "St. Clair Shores, Michigan", + "Latitude": 42.4974085, + "Longitude": -82.896360399999992 + }, + { + "Id": 593, + "City": "Gardena", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Gardena, California", + "Latitude": 33.8883487, + "Longitude": -118.3089624 + }, + { + "Id": 594, + "City": "Pontiac", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Pontiac, Michigan", + "Latitude": 42.6389216, + "Longitude": -83.29104679999999 + }, + { + "Id": 595, + "City": "National City", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "National City, California", + "Latitude": 32.6781085, + "Longitude": -117.0991967 + }, + { + "Id": 596, + "City": "Grand Junction", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Grand Junction, Colorado", + "Latitude": 39.0638705, + "Longitude": -108.5506486 + }, + { + "Id": 597, + "City": "Rocklin", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rocklin, California", + "Latitude": 38.7907339, + "Longitude": -121.2357828 + }, + { + "Id": 598, + "City": "Chapel Hill", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Chapel Hill, North Carolina", + "Latitude": 35.9131996, + "Longitude": -79.0558445 + }, + { + "Id": 599, + "City": "Casper", + "State": "Wyoming", + "StateAbbreviation": "WY", + "DisplayName": "Casper, Wyoming", + "Latitude": 42.866632, + "Longitude": -106.313081 + }, + { + "Id": 600, + "City": "Broomfield", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Broomfield, Colorado", + "Latitude": 39.9205411, + "Longitude": -105.0866504 + }, + { + "Id": 601, + "City": "Petaluma", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Petaluma, California", + "Latitude": 38.232417, + "Longitude": -122.6366524 + }, + { + "Id": 602, + "City": "South Jordan", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "South Jordan, Utah", + "Latitude": 40.5621704, + "Longitude": -111.929658 + }, + { + "Id": 603, + "City": "Springfield", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Springfield, Ohio", + "Latitude": 39.9242266, + "Longitude": -83.8088171 + }, + { + "Id": 604, + "City": "Great Falls", + "State": "Montana", + "StateAbbreviation": "MT", + "DisplayName": "Great Falls, Montana", + "Latitude": 47.4941836, + "Longitude": -111.2833449 + }, + { + "Id": 605, + "City": "Lancaster", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Lancaster, Pennsylvania", + "Latitude": 40.0378755, + "Longitude": -76.3055144 + }, + { + "Id": 606, + "City": "North Port", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "North Port, Florida", + "Latitude": 27.044224, + "Longitude": -82.2359254 + }, + { + "Id": 607, + "City": "Lakewood", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Lakewood, Washington", + "Latitude": 47.1717649, + "Longitude": -122.518458 + }, + { + "Id": 608, + "City": "Marietta", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Marietta, Georgia", + "Latitude": 33.952602000000013, + "Longitude": -84.5499327 + }, + { + "Id": 609, + "City": "San Rafael", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Rafael, California", + "Latitude": 37.9735346, + "Longitude": -122.5310874 + }, + { + "Id": 610, + "City": "Royal Oak", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Royal Oak, Michigan", + "Latitude": 42.4894801, + "Longitude": -83.1446485 + }, + { + "Id": 611, + "City": "Des Plaines", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Des Plaines, Illinois", + "Latitude": 42.0333623, + "Longitude": -87.883399099999991 + }, + { + "Id": 612, + "City": "Huntington Park", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Huntington Park, California", + "Latitude": 33.9816812, + "Longitude": -118.2250725 + }, + { + "Id": 613, + "City": "La Mesa", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "La Mesa, California", + "Latitude": 32.7678287, + "Longitude": -117.0230839 + }, + { + "Id": 614, + "City": "Orland Park", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Orland Park, Illinois", + "Latitude": 41.6303103, + "Longitude": -87.853942500000016 + }, + { + "Id": 615, + "City": "Auburn", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Auburn, Alabama", + "Latitude": 32.6098566, + "Longitude": -85.480782499999989 + }, + { + "Id": 616, + "City": "Lakeville", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Lakeville, Minnesota", + "Latitude": 44.6496868, + "Longitude": -93.242719999999991 + }, + { + "Id": 617, + "City": "Owensboro", + "State": "Kentucky", + "StateAbbreviation": "KY", + "DisplayName": "Owensboro, Kentucky", + "Latitude": 37.7719074, + "Longitude": -87.1111676 + }, + { + "Id": 618, + "City": "Moore", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Moore, Oklahoma", + "Latitude": 35.3395079, + "Longitude": -97.486702799999989 + }, + { + "Id": 619, + "City": "Jupiter", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Jupiter, Florida", + "Latitude": 26.9342246, + "Longitude": -80.0942087 + }, + { + "Id": 620, + "City": "Idaho Falls", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Idaho Falls, Idaho", + "Latitude": 43.491651399999988, + "Longitude": -112.0339645 + }, + { + "Id": 621, + "City": "Dubuque", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Dubuque, Iowa", + "Latitude": 42.5005583, + "Longitude": -90.66457179999999 + }, + { + "Id": 622, + "City": "Bartlett", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Bartlett, Tennessee", + "Latitude": 35.2045328, + "Longitude": -89.8739753 + }, + { + "Id": 623, + "City": "Rowlett", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Rowlett, Texas", + "Latitude": 32.9029017, + "Longitude": -96.56388 + }, + { + "Id": 624, + "City": "Novi", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Novi, Michigan", + "Latitude": 42.48059, + "Longitude": -83.4754913 + }, + { + "Id": 625, + "City": "White Plains", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "White Plains, New York", + "Latitude": 41.033986200000008, + "Longitude": -73.7629097 + }, + { + "Id": 626, + "City": "Arcadia", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Arcadia, California", + "Latitude": 34.1397292, + "Longitude": -118.0353449 + }, + { + "Id": 627, + "City": "Redmond", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Redmond, Washington", + "Latitude": 47.6739881, + "Longitude": -122.121512 + }, + { + "Id": 628, + "City": "Lake Elsinore", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lake Elsinore, California", + "Latitude": 33.6680772, + "Longitude": -117.3272615 + }, + { + "Id": 629, + "City": "Ocala", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Ocala, Florida", + "Latitude": 29.1871986, + "Longitude": -82.140092299999992 + }, + { + "Id": 630, + "City": "Tinley Park", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Tinley Park, Illinois", + "Latitude": 41.5731442, + "Longitude": -87.7932939 + }, + { + "Id": 631, + "City": "Port Orange", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Port Orange, Florida", + "Latitude": 29.1383165, + "Longitude": -80.9956105 + }, + { + "Id": 632, + "City": "Medford", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Medford, Massachusetts", + "Latitude": 42.4184296, + "Longitude": -71.1061639 + }, + { + "Id": 633, + "City": "Oak Lawn", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Oak Lawn, Illinois", + "Latitude": 41.719978, + "Longitude": -87.7479528 + }, + { + "Id": 634, + "City": "Rocky Mount", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Rocky Mount, North Carolina", + "Latitude": 35.9382103, + "Longitude": -77.7905339 + }, + { + "Id": 635, + "City": "Kokomo", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Kokomo, Indiana", + "Latitude": 40.486427, + "Longitude": -86.13360329999999 + }, + { + "Id": 636, + "City": "Coconut Creek", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Coconut Creek, Florida", + "Latitude": 26.2517482, + "Longitude": -80.17893509999999 + }, + { + "Id": 637, + "City": "Bowie", + "State": "Maryland", + "StateAbbreviation": "MD", + "DisplayName": "Bowie, Maryland", + "Latitude": 39.0067768, + "Longitude": -76.779136499999993 + }, + { + "Id": 638, + "City": "Berwyn", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Berwyn, Illinois", + "Latitude": 41.850587399999988, + "Longitude": -87.7936685 + }, + { + "Id": 639, + "City": "Midwest City", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Midwest City, Oklahoma", + "Latitude": 35.4495065, + "Longitude": -97.3967019 + }, + { + "Id": 640, + "City": "Fountain Valley", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Fountain Valley, California", + "Latitude": 33.7091847, + "Longitude": -117.9536697 + }, + { + "Id": 641, + "City": "Buckeye", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Buckeye, Arizona", + "Latitude": 33.3703197, + "Longitude": -112.5837766 + }, + { + "Id": 642, + "City": "Dearborn Heights", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Dearborn Heights, Michigan", + "Latitude": 42.3369816, + "Longitude": -83.273262699999989 + }, + { + "Id": 643, + "City": "Woodland", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Woodland, California", + "Latitude": 38.678515700000013, + "Longitude": -121.7732971 + }, + { + "Id": 644, + "City": "Noblesville", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Noblesville, Indiana", + "Latitude": 40.0455917, + "Longitude": -86.0085955 + }, + { + "Id": 645, + "City": "Valdosta", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Valdosta, Georgia", + "Latitude": 30.8327022, + "Longitude": -83.2784851 + }, + { + "Id": 646, + "City": "Diamond Bar", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Diamond Bar, California", + "Latitude": 34.0286226, + "Longitude": -117.8103367 + }, + { + "Id": 647, + "City": "Manhattan", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Manhattan, Kansas", + "Latitude": 39.183608199999988, + "Longitude": -96.57166939999999 + }, + { + "Id": 648, + "City": "Santee", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Santee, California", + "Latitude": 32.8383828, + "Longitude": -116.9739167 + }, + { + "Id": 649, + "City": "Taunton", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Taunton, Massachusetts", + "Latitude": 41.900101, + "Longitude": -71.0897674 + }, + { + "Id": 650, + "City": "Sanford", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Sanford, Florida", + "Latitude": 28.8028612, + "Longitude": -81.269453 + }, + { + "Id": 651, + "City": "Kettering", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Kettering, Ohio", + "Latitude": 39.689503599999988, + "Longitude": -84.1688274 + }, + { + "Id": 652, + "City": "New Brunswick", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "New Brunswick, New Jersey", + "Latitude": 40.4862157, + "Longitude": -74.4518188 + }, + { + "Id": 653, + "City": "Decatur", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Decatur, Alabama", + "Latitude": 34.6059253, + "Longitude": -86.9833417 + }, + { + "Id": 654, + "City": "Chicopee", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Chicopee, Massachusetts", + "Latitude": 42.1487043, + "Longitude": -72.6078672 + }, + { + "Id": 655, + "City": "Anderson", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Anderson, Indiana", + "Latitude": 40.1053196, + "Longitude": -85.6802541 + }, + { + "Id": 656, + "City": "Margate", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Margate, Florida", + "Latitude": 26.2445263, + "Longitude": -80.206436 + }, + { + "Id": 657, + "City": "Weymouth Town", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Weymouth Town, Massachusetts", + "Latitude": 42.2180724, + "Longitude": -70.941035599999992 + }, + { + "Id": 658, + "City": "Hempstead", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Hempstead, New York", + "Latitude": 40.7062128, + "Longitude": -73.6187397 + }, + { + "Id": 659, + "City": "Corvallis", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Corvallis, Oregon", + "Latitude": 44.5645659, + "Longitude": -123.2620435 + }, + { + "Id": 660, + "City": "Eastvale", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Eastvale, California", + "Latitude": 33.952463, + "Longitude": -117.5848025 + }, + { + "Id": 661, + "City": "Porterville", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Porterville, California", + "Latitude": 36.06523, + "Longitude": -119.0167679 + }, + { + "Id": 662, + "City": "West Haven", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "West Haven, Connecticut", + "Latitude": 41.2705484, + "Longitude": -72.9469711 + }, + { + "Id": 663, + "City": "Brentwood", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Brentwood, California", + "Latitude": 37.931868, + "Longitude": -121.6957863 + }, + { + "Id": 664, + "City": "Paramount", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Paramount, California", + "Latitude": 33.8894598, + "Longitude": -118.1597911 + }, + { + "Id": 665, + "City": "Grand Forks", + "State": "North Dakota", + "StateAbbreviation": "ND", + "DisplayName": "Grand Forks, North Dakota", + "Latitude": 47.9252568, + "Longitude": -97.0328547 + }, + { + "Id": 666, + "City": "Georgetown", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Georgetown, Texas", + "Latitude": 30.6332618, + "Longitude": -97.6779842 + }, + { + "Id": 667, + "City": "St. Peters", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "St. Peters, Missouri", + "Latitude": 38.7874699, + "Longitude": -90.6298922 + }, + { + "Id": 668, + "City": "Shoreline", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Shoreline, Washington", + "Latitude": 47.7556531, + "Longitude": -122.3415178 + }, + { + "Id": 669, + "City": "Mount Prospect", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Mount Prospect, Illinois", + "Latitude": 42.0664167, + "Longitude": -87.9372908 + }, + { + "Id": 670, + "City": "Hanford", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Hanford, California", + "Latitude": 36.3274502, + "Longitude": -119.6456844 + }, + { + "Id": 671, + "City": "Normal", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Normal, Illinois", + "Latitude": 40.5142026, + "Longitude": -88.9906312 + }, + { + "Id": 672, + "City": "Rosemead", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rosemead, California", + "Latitude": 34.0805651, + "Longitude": -118.072846 + }, + { + "Id": 673, + "City": "Lehi", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Lehi, Utah", + "Latitude": 40.3916172, + "Longitude": -111.8507662 + }, + { + "Id": 674, + "City": "Pocatello", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Pocatello, Idaho", + "Latitude": 42.8713032, + "Longitude": -112.4455344 + }, + { + "Id": 675, + "City": "Highland", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Highland, California", + "Latitude": 34.1283442, + "Longitude": -117.2086513 + }, + { + "Id": 676, + "City": "Novato", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Novato, California", + "Latitude": 38.1074198, + "Longitude": -122.5697032 + }, + { + "Id": 677, + "City": "Port Arthur", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Port Arthur, Texas", + "Latitude": 29.8849504, + "Longitude": -93.939946999999989 + }, + { + "Id": 678, + "City": "Carson City", + "State": "Nevada", + "StateAbbreviation": "NV", + "DisplayName": "Carson City, Nevada", + "Latitude": 39.1637984, + "Longitude": -119.7674034 + }, + { + "Id": 679, + "City": "San Marcos", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "San Marcos, Texas", + "Latitude": 29.8832749, + "Longitude": -97.9413941 + }, + { + "Id": 680, + "City": "Hendersonville", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Hendersonville, Tennessee", + "Latitude": 36.3047735, + "Longitude": -86.6199957 + }, + { + "Id": 681, + "City": "Elyria", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Elyria, Ohio", + "Latitude": 41.3683798, + "Longitude": -82.10764859999999 + }, + { + "Id": 682, + "City": "Revere", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Revere, Massachusetts", + "Latitude": 42.4084302, + "Longitude": -71.0119948 + }, + { + "Id": 683, + "City": "Pflugerville", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Pflugerville, Texas", + "Latitude": 30.4393696, + "Longitude": -97.620004299999991 + }, + { + "Id": 684, + "City": "Greenwood", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Greenwood, Indiana", + "Latitude": 39.6136578, + "Longitude": -86.10665259999999 + }, + { + "Id": 685, + "City": "Bellevue", + "State": "Nebraska", + "StateAbbreviation": "NE", + "DisplayName": "Bellevue, Nebraska", + "Latitude": 41.1543623, + "Longitude": -95.9145568 + }, + { + "Id": 686, + "City": "Wheaton", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Wheaton, Illinois", + "Latitude": 41.8661403, + "Longitude": -88.1070127 + }, + { + "Id": 687, + "City": "Smyrna", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Smyrna, Georgia", + "Latitude": 33.8839926, + "Longitude": -84.514376099999993 + }, + { + "Id": 688, + "City": "Sarasota", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Sarasota, Florida", + "Latitude": 27.3364347, + "Longitude": -82.53065269999999 + }, + { + "Id": 689, + "City": "Blue Springs", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Blue Springs, Missouri", + "Latitude": 39.0169509, + "Longitude": -94.2816148 + }, + { + "Id": 690, + "City": "Colton", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Colton, California", + "Latitude": 34.0739016, + "Longitude": -117.3136547 + }, + { + "Id": 691, + "City": "Euless", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Euless, Texas", + "Latitude": 32.8370727, + "Longitude": -97.08195409999999 + }, + { + "Id": 692, + "City": "Castle Rock", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Castle Rock, Colorado", + "Latitude": 39.3722121, + "Longitude": -104.8560902 + }, + { + "Id": 693, + "City": "Cathedral City", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Cathedral City, California", + "Latitude": 33.7805388, + "Longitude": -116.4668036 + }, + { + "Id": 694, + "City": "Kingsport", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Kingsport, Tennessee", + "Latitude": 36.548434, + "Longitude": -82.5618186 + }, + { + "Id": 695, + "City": "Lake Havasu City", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Lake Havasu City, Arizona", + "Latitude": 34.483901, + "Longitude": -114.3224548 + }, + { + "Id": 696, + "City": "Pensacola", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Pensacola, Florida", + "Latitude": 30.42130899999999, + "Longitude": -87.2169149 + }, + { + "Id": 697, + "City": "Hoboken", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Hoboken, New Jersey", + "Latitude": 40.7439905, + "Longitude": -74.0323626 + }, + { + "Id": 698, + "City": "Yucaipa", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Yucaipa, California", + "Latitude": 34.033625, + "Longitude": -117.0430865 + }, + { + "Id": 699, + "City": "Watsonville", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Watsonville, California", + "Latitude": 36.910231, + "Longitude": -121.7568946 + }, + { + "Id": 700, + "City": "Richland", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Richland, Washington", + "Latitude": 46.2856907, + "Longitude": -119.2844621 + }, + { + "Id": 701, + "City": "Delano", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Delano, California", + "Latitude": 35.7688425, + "Longitude": -119.2470536 + }, + { + "Id": 702, + "City": "Hoffman Estates", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Hoffman Estates, Illinois", + "Latitude": 42.0629915, + "Longitude": -88.122719899999993 + }, + { + "Id": 703, + "City": "Florissant", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Florissant, Missouri", + "Latitude": 38.789217, + "Longitude": -90.322614 + }, + { + "Id": 704, + "City": "Placentia", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Placentia, California", + "Latitude": 33.8722371, + "Longitude": -117.8703363 + }, + { + "Id": 705, + "City": "West New York", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "West New York, New Jersey", + "Latitude": 40.7878788, + "Longitude": -74.0143064 + }, + { + "Id": 706, + "City": "Dublin", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Dublin, California", + "Latitude": 37.7021521, + "Longitude": -121.9357918 + }, + { + "Id": 707, + "City": "Oak Park", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Oak Park, Illinois", + "Latitude": 41.8850317, + "Longitude": -87.7845025 + }, + { + "Id": 708, + "City": "Peabody", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Peabody, Massachusetts", + "Latitude": 42.5278731, + "Longitude": -70.9286609 + }, + { + "Id": 709, + "City": "Perth Amboy", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Perth Amboy, New Jersey", + "Latitude": 40.5067723, + "Longitude": -74.2654234 + }, + { + "Id": 710, + "City": "Battle Creek", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Battle Creek, Michigan", + "Latitude": 42.3211522, + "Longitude": -85.179714199999992 + }, + { + "Id": 711, + "City": "Bradenton", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Bradenton, Florida", + "Latitude": 27.4989278, + "Longitude": -82.5748194 + }, + { + "Id": 712, + "City": "Gilroy", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Gilroy, California", + "Latitude": 37.0057816, + "Longitude": -121.5682751 + }, + { + "Id": 713, + "City": "Milford", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Milford, Connecticut", + "Latitude": 41.2306979, + "Longitude": -73.064036 + }, + { + "Id": 714, + "City": "Albany", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Albany, Oregon", + "Latitude": 44.6365107, + "Longitude": -123.1059282 + }, + { + "Id": 715, + "City": "Ankeny", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Ankeny, Iowa", + "Latitude": 41.7317884, + "Longitude": -93.6001278 + }, + { + "Id": 716, + "City": "La Crosse", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "La Crosse, Wisconsin", + "Latitude": 43.8013556, + "Longitude": -91.239580699999991 + }, + { + "Id": 717, + "City": "Burlington", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Burlington, North Carolina", + "Latitude": 36.0956918, + "Longitude": -79.437799099999992 + }, + { + "Id": 718, + "City": "DeSoto", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "DeSoto, Texas", + "Latitude": 32.5896998, + "Longitude": -96.8570738 + }, + { + "Id": 719, + "City": "Harrisonburg", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Harrisonburg, Virginia", + "Latitude": 38.4495688, + "Longitude": -78.8689155 + }, + { + "Id": 720, + "City": "Minnetonka", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Minnetonka, Minnesota", + "Latitude": 44.9211836, + "Longitude": -93.4687489 + }, + { + "Id": 721, + "City": "Elkhart", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Elkhart, Indiana", + "Latitude": 41.6819935, + "Longitude": -85.9766671 + }, + { + "Id": 722, + "City": "Lakewood", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Lakewood, Ohio", + "Latitude": 41.4819932, + "Longitude": -81.7981908 + }, + { + "Id": 723, + "City": "Glendora", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Glendora, California", + "Latitude": 34.1361187, + "Longitude": -117.865339 + }, + { + "Id": 724, + "City": "Southaven", + "State": "Mississippi", + "StateAbbreviation": "MS", + "DisplayName": "Southaven, Mississippi", + "Latitude": 34.9889818, + "Longitude": -90.0125913 + }, + { + "Id": 725, + "City": "Charleston", + "State": "West Virginia", + "StateAbbreviation": "WV", + "DisplayName": "Charleston, West Virginia", + "Latitude": 38.3498195, + "Longitude": -81.6326234 + }, + { + "Id": 726, + "City": "Joplin", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Joplin, Missouri", + "Latitude": 37.084227100000007, + "Longitude": -94.513280999999992 + }, + { + "Id": 727, + "City": "Enid", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Enid, Oklahoma", + "Latitude": 36.3955891, + "Longitude": -97.8783911 + }, + { + "Id": 728, + "City": "Palm Beach Gardens", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Palm Beach Gardens, Florida", + "Latitude": 26.8233946, + "Longitude": -80.138654699999989 + }, + { + "Id": 729, + "City": "Brookhaven", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Brookhaven, Georgia", + "Latitude": 33.8651033, + "Longitude": -84.3365917 + }, + { + "Id": 730, + "City": "Plainfield", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Plainfield, New Jersey", + "Latitude": 40.6337136, + "Longitude": -74.4073736 + }, + { + "Id": 731, + "City": "Grand Island", + "State": "Nebraska", + "StateAbbreviation": "NE", + "DisplayName": "Grand Island, Nebraska", + "Latitude": 40.9263957, + "Longitude": -98.3420118 + }, + { + "Id": 732, + "City": "Palm Desert", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Palm Desert, California", + "Latitude": 33.7222445, + "Longitude": -116.3744556 + }, + { + "Id": 733, + "City": "Huntersville", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Huntersville, North Carolina", + "Latitude": 35.410694, + "Longitude": -80.842850400000017 + }, + { + "Id": 734, + "City": "Tigard", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Tigard, Oregon", + "Latitude": 45.4312294, + "Longitude": -122.7714861 + }, + { + "Id": 735, + "City": "Lenexa", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Lenexa, Kansas", + "Latitude": 38.9536174, + "Longitude": -94.733570899999989 + }, + { + "Id": 736, + "City": "Saginaw", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Saginaw, Michigan", + "Latitude": 43.4194699, + "Longitude": -83.9508068 + }, + { + "Id": 737, + "City": "Kentwood", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Kentwood, Michigan", + "Latitude": 42.8694731, + "Longitude": -85.644749199999993 + }, + { + "Id": 738, + "City": "Doral", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Doral, Florida", + "Latitude": 25.8195424, + "Longitude": -80.3553302 + }, + { + "Id": 739, + "City": "Apple Valley", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Apple Valley, Minnesota", + "Latitude": 44.7319094, + "Longitude": -93.217720000000014 + }, + { + "Id": 740, + "City": "Grapevine", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Grapevine, Texas", + "Latitude": 32.9342919, + "Longitude": -97.0780654 + }, + { + "Id": 741, + "City": "Aliso Viejo", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Aliso Viejo, California", + "Latitude": 33.5676842, + "Longitude": -117.7256083 + }, + { + "Id": 742, + "City": "Sammamish", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Sammamish, Washington", + "Latitude": 47.616268299999987, + "Longitude": -122.0355736 + }, + { + "Id": 743, + "City": "Casa Grande", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Casa Grande, Arizona", + "Latitude": 32.8795022, + "Longitude": -111.7573521 + }, + { + "Id": 744, + "City": "Pinellas Park", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Pinellas Park, Florida", + "Latitude": 27.8428025, + "Longitude": -82.6995443 + }, + { + "Id": 745, + "City": "Troy", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Troy, New York", + "Latitude": 42.7284117, + "Longitude": -73.69178509999999 + }, + { + "Id": 746, + "City": "West Sacramento", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "West Sacramento, California", + "Latitude": 38.5804609, + "Longitude": -121.530234 + }, + { + "Id": 747, + "City": "Burien", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Burien, Washington", + "Latitude": 47.4703767, + "Longitude": -122.3467918 + }, + { + "Id": 748, + "City": "Commerce City", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Commerce City, Colorado", + "Latitude": 39.8083196, + "Longitude": -104.9338675 + }, + { + "Id": 749, + "City": "Monroe", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Monroe, Louisiana", + "Latitude": 32.5093109, + "Longitude": -92.1193012 + }, + { + "Id": 750, + "City": "Cerritos", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Cerritos, California", + "Latitude": 33.8583483, + "Longitude": -118.0647871 + }, + { + "Id": 751, + "City": "Downers Grove", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Downers Grove, Illinois", + "Latitude": 41.8089191, + "Longitude": -88.01117459999999 + }, + { + "Id": 752, + "City": "Coral Gables", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Coral Gables, Florida", + "Latitude": 25.72149, + "Longitude": -80.2683838 + }, + { + "Id": 753, + "City": "Wilson", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Wilson, North Carolina", + "Latitude": 35.7212689, + "Longitude": -77.9155395 + }, + { + "Id": 754, + "City": "Niagara Falls", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Niagara Falls, New York", + "Latitude": 43.0962143, + "Longitude": -79.0377388 + }, + { + "Id": 755, + "City": "Poway", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Poway, California", + "Latitude": 32.9628232, + "Longitude": -117.0358646 + }, + { + "Id": 756, + "City": "Edina", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Edina, Minnesota", + "Latitude": 44.8896866, + "Longitude": -93.3499489 + }, + { + "Id": 757, + "City": "Cuyahoga Falls", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Cuyahoga Falls, Ohio", + "Latitude": 41.1339449, + "Longitude": -81.484558499999991 + }, + { + "Id": 758, + "City": "Rancho Santa Margarita", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rancho Santa Margarita, California", + "Latitude": 33.640855, + "Longitude": -117.603104 + }, + { + "Id": 759, + "City": "Harrisburg", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Harrisburg, Pennsylvania", + "Latitude": 40.2731911, + "Longitude": -76.8867008 + }, + { + "Id": 760, + "City": "Huntington", + "State": "West Virginia", + "StateAbbreviation": "WV", + "DisplayName": "Huntington, West Virginia", + "Latitude": 38.4192496, + "Longitude": -82.445154000000016 + }, + { + "Id": 761, + "City": "La Mirada", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "La Mirada, California", + "Latitude": 33.9172357, + "Longitude": -118.0120086 + }, + { + "Id": 762, + "City": "Cypress", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Cypress, California", + "Latitude": 33.8169599, + "Longitude": -118.0372852 + }, + { + "Id": 763, + "City": "Caldwell", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Caldwell, Idaho", + "Latitude": 43.662938399999987, + "Longitude": -116.6873596 + }, + { + "Id": 764, + "City": "Logan", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Logan, Utah", + "Latitude": 41.7369803, + "Longitude": -111.8338359 + }, + { + "Id": 765, + "City": "Galveston", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Galveston, Texas", + "Latitude": 29.3013479, + "Longitude": -94.7976958 + }, + { + "Id": 766, + "City": "Sheboygan", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Sheboygan, Wisconsin", + "Latitude": 43.7508284, + "Longitude": -87.71453 + }, + { + "Id": 767, + "City": "Middletown", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Middletown, Ohio", + "Latitude": 39.5150576, + "Longitude": -84.398276299999992 + }, + { + "Id": 768, + "City": "Murray", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Murray, Utah", + "Latitude": 40.6668916, + "Longitude": -111.8879909 + }, + { + "Id": 769, + "City": "Roswell", + "State": "New Mexico", + "StateAbbreviation": "NM", + "DisplayName": "Roswell, New Mexico", + "Latitude": 33.3942655, + "Longitude": -104.5230242 + }, + { + "Id": 770, + "City": "Parker", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Parker, Colorado", + "Latitude": 39.5186002, + "Longitude": -104.7613633 + }, + { + "Id": 771, + "City": "Bedford", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Bedford, Texas", + "Latitude": 32.844017, + "Longitude": -97.1430671 + }, + { + "Id": 772, + "City": "East Lansing", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "East Lansing, Michigan", + "Latitude": 42.7369792, + "Longitude": -84.483865400000013 + }, + { + "Id": 773, + "City": "Methuen", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Methuen, Massachusetts", + "Latitude": 42.7262016, + "Longitude": -71.1908924 + }, + { + "Id": 774, + "City": "Covina", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Covina, California", + "Latitude": 34.0900091, + "Longitude": -117.8903397 + }, + { + "Id": 775, + "City": "Alexandria", + "State": "Louisiana", + "StateAbbreviation": "LA", + "DisplayName": "Alexandria, Louisiana", + "Latitude": 31.3112936, + "Longitude": -92.4451371 + }, + { + "Id": 776, + "City": "Olympia", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Olympia, Washington", + "Latitude": 47.0378741, + "Longitude": -122.9006951 + }, + { + "Id": 777, + "City": "Euclid", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Euclid, Ohio", + "Latitude": 41.5931049, + "Longitude": -81.5267873 + }, + { + "Id": 778, + "City": "Mishawaka", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Mishawaka, Indiana", + "Latitude": 41.6619927, + "Longitude": -86.15861559999999 + }, + { + "Id": 779, + "City": "Salina", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Salina, Kansas", + "Latitude": 38.8402805, + "Longitude": -97.611423699999989 + }, + { + "Id": 780, + "City": "Azusa", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Azusa, California", + "Latitude": 34.1336186, + "Longitude": -117.9075627 + }, + { + "Id": 781, + "City": "Newark", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Newark, Ohio", + "Latitude": 40.0581205, + "Longitude": -82.4012642 + }, + { + "Id": 782, + "City": "Chesterfield", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Chesterfield, Missouri", + "Latitude": 38.6631083, + "Longitude": -90.5770675 + }, + { + "Id": 783, + "City": "Leesburg", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Leesburg, Virginia", + "Latitude": 39.1156615, + "Longitude": -77.56360149999999 + }, + { + "Id": 784, + "City": "Dunwoody", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Dunwoody, Georgia", + "Latitude": 33.9462125, + "Longitude": -84.3346473 + }, + { + "Id": 785, + "City": "Hattiesburg", + "State": "Mississippi", + "StateAbbreviation": "MS", + "DisplayName": "Hattiesburg, Mississippi", + "Latitude": 31.3271189, + "Longitude": -89.290339199999991 + }, + { + "Id": 786, + "City": "Roseville", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Roseville, Michigan", + "Latitude": 42.4972583, + "Longitude": -82.9371409 + }, + { + "Id": 787, + "City": "Bonita Springs", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Bonita Springs, Florida", + "Latitude": 26.339806, + "Longitude": -81.7786972 + }, + { + "Id": 788, + "City": "Portage", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Portage, Michigan", + "Latitude": 42.2011538, + "Longitude": -85.5800022 + }, + { + "Id": 789, + "City": "St. Louis Park", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "St. Louis Park, Minnesota", + "Latitude": 44.9597376, + "Longitude": -93.3702186 + }, + { + "Id": 790, + "City": "Collierville", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Collierville, Tennessee", + "Latitude": 35.042036, + "Longitude": -89.6645266 + }, + { + "Id": 791, + "City": "Middletown", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Middletown, Connecticut", + "Latitude": 41.5623209, + "Longitude": -72.6506488 + }, + { + "Id": 792, + "City": "Stillwater", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Stillwater, Oklahoma", + "Latitude": 36.1156071, + "Longitude": -97.0583681 + }, + { + "Id": 793, + "City": "East Providence", + "State": "Rhode Island", + "StateAbbreviation": "RI", + "DisplayName": "East Providence, Rhode Island", + "Latitude": 41.8137116, + "Longitude": -71.3700545 + }, + { + "Id": 794, + "City": "Lawrence", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Lawrence, Indiana", + "Latitude": 39.8386516, + "Longitude": -86.0252612 + }, + { + "Id": 795, + "City": "Wauwatosa", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Wauwatosa, Wisconsin", + "Latitude": 43.0494572, + "Longitude": -88.0075875 + }, + { + "Id": 796, + "City": "Mentor", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Mentor, Ohio", + "Latitude": 41.6661573, + "Longitude": -81.339552 + }, + { + "Id": 797, + "City": "Ceres", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Ceres, California", + "Latitude": 37.5949316, + "Longitude": -120.9577098 + }, + { + "Id": 798, + "City": "Cedar Hill", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Cedar Hill, Texas", + "Latitude": 32.5884689, + "Longitude": -96.9561152 + }, + { + "Id": 799, + "City": "Mansfield", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Mansfield, Ohio", + "Latitude": 40.75839, + "Longitude": -82.5154471 + }, + { + "Id": 800, + "City": "Binghamton", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Binghamton, New York", + "Latitude": 42.098686699999988, + "Longitude": -75.917973800000013 + }, + { + "Id": 801, + "City": "Coeur d'Alene", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Coeur d'Alene, Idaho", + "Latitude": 47.6776832, + "Longitude": -116.7804664 + }, + { + "Id": 802, + "City": "San Luis Obispo", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Luis Obispo, California", + "Latitude": 35.2827524, + "Longitude": -120.6596156 + }, + { + "Id": 803, + "City": "Minot", + "State": "North Dakota", + "StateAbbreviation": "ND", + "DisplayName": "Minot, North Dakota", + "Latitude": 48.2329668, + "Longitude": -101.2922906 + }, + { + "Id": 804, + "City": "Palm Springs", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Palm Springs, California", + "Latitude": 33.8302961, + "Longitude": -116.5452921 + }, + { + "Id": 805, + "City": "Pine Bluff", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Pine Bluff, Arkansas", + "Latitude": 34.2284312, + "Longitude": -92.00319549999999 + }, + { + "Id": 806, + "City": "Texas City", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Texas City, Texas", + "Latitude": 29.383845, + "Longitude": -94.9027002 + }, + { + "Id": 807, + "City": "Summerville", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Summerville, South Carolina", + "Latitude": 33.0185039, + "Longitude": -80.175648099999989 + }, + { + "Id": 808, + "City": "Twin Falls", + "State": "Idaho", + "StateAbbreviation": "ID", + "DisplayName": "Twin Falls, Idaho", + "Latitude": 42.5629668, + "Longitude": -114.4608711 + }, + { + "Id": 809, + "City": "Jeffersonville", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Jeffersonville, Indiana", + "Latitude": 38.2775702, + "Longitude": -85.7371847 + }, + { + "Id": 810, + "City": "San Jacinto", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Jacinto, California", + "Latitude": 33.7839084, + "Longitude": -116.958635 + }, + { + "Id": 811, + "City": "Madison", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Madison, Alabama", + "Latitude": 34.6992579, + "Longitude": -86.748331800000017 + }, + { + "Id": 812, + "City": "Altoona", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Altoona, Pennsylvania", + "Latitude": 40.5186809, + "Longitude": -78.3947359 + }, + { + "Id": 813, + "City": "Columbus", + "State": "Indiana", + "StateAbbreviation": "IN", + "DisplayName": "Columbus, Indiana", + "Latitude": 39.2014404, + "Longitude": -85.9213796 + }, + { + "Id": 814, + "City": "Beavercreek", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Beavercreek, Ohio", + "Latitude": 39.7092262, + "Longitude": -84.063268499999992 + }, + { + "Id": 815, + "City": "Apopka", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Apopka, Florida", + "Latitude": 28.6934076, + "Longitude": -81.5322149 + }, + { + "Id": 816, + "City": "Elmhurst", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Elmhurst, Illinois", + "Latitude": 41.8994744, + "Longitude": -87.9403418 + }, + { + "Id": 817, + "City": "Maricopa", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Maricopa, Arizona", + "Latitude": 33.0581063, + "Longitude": -112.0476423 + }, + { + "Id": 818, + "City": "Farmington", + "State": "New Mexico", + "StateAbbreviation": "NM", + "DisplayName": "Farmington, New Mexico", + "Latitude": 36.728058300000008, + "Longitude": -108.2186856 + }, + { + "Id": 819, + "City": "Glenview", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Glenview, Illinois", + "Latitude": 42.0697509, + "Longitude": -87.7878408 + }, + { + "Id": 820, + "City": "Cleveland Heights", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Cleveland Heights, Ohio", + "Latitude": 41.5200518, + "Longitude": -81.556235 + }, + { + "Id": 821, + "City": "Draper", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Draper, Utah", + "Latitude": 40.5246711, + "Longitude": -111.8638226 + }, + { + "Id": 822, + "City": "Lincoln", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lincoln, California", + "Latitude": 38.891565, + "Longitude": -121.2930079 + }, + { + "Id": 823, + "City": "Sierra Vista", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Sierra Vista, Arizona", + "Latitude": 31.5455001, + "Longitude": -110.2772856 + }, + { + "Id": 824, + "City": "Lacey", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Lacey, Washington", + "Latitude": 47.034262899999987, + "Longitude": -122.8231915 + }, + { + "Id": 825, + "City": "Biloxi", + "State": "Mississippi", + "StateAbbreviation": "MS", + "DisplayName": "Biloxi, Mississippi", + "Latitude": 30.3960318, + "Longitude": -88.885307799999993 + }, + { + "Id": 826, + "City": "Strongsville", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Strongsville, Ohio", + "Latitude": 41.3144966, + "Longitude": -81.83569 + }, + { + "Id": 827, + "City": "Barnstable Town", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Barnstable Town, Massachusetts", + "Latitude": 41.7003208, + "Longitude": -70.3002024 + }, + { + "Id": 828, + "City": "Wylie", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Wylie, Texas", + "Latitude": 33.0151201, + "Longitude": -96.5388789 + }, + { + "Id": 829, + "City": "Sayreville", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Sayreville, New Jersey", + "Latitude": 40.459402100000013, + "Longitude": -74.360846 + }, + { + "Id": 830, + "City": "Kannapolis", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Kannapolis, North Carolina", + "Latitude": 35.4873613, + "Longitude": -80.6217341 + }, + { + "Id": 831, + "City": "Charlottesville", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Charlottesville, Virginia", + "Latitude": 38.0293059, + "Longitude": -78.476678100000015 + }, + { + "Id": 832, + "City": "Littleton", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Littleton, Colorado", + "Latitude": 39.613321, + "Longitude": -105.0166498 + }, + { + "Id": 833, + "City": "Titusville", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Titusville, Florida", + "Latitude": 28.6122187, + "Longitude": -80.8075537 + }, + { + "Id": 834, + "City": "Hackensack", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Hackensack, New Jersey", + "Latitude": 40.8859325, + "Longitude": -74.0434736 + }, + { + "Id": 835, + "City": "Newark", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Newark, California", + "Latitude": 37.5296593, + "Longitude": -122.0402399 + }, + { + "Id": 836, + "City": "Pittsfield", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Pittsfield, Massachusetts", + "Latitude": 42.4500845, + "Longitude": -73.2453824 + }, + { + "Id": 837, + "City": "York", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "York, Pennsylvania", + "Latitude": 39.9625984, + "Longitude": -76.727745 + }, + { + "Id": 838, + "City": "Lombard", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Lombard, Illinois", + "Latitude": 41.8800296, + "Longitude": -88.007843499999993 + }, + { + "Id": 839, + "City": "Attleboro", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Attleboro, Massachusetts", + "Latitude": 41.944544099999987, + "Longitude": -71.2856082 + }, + { + "Id": 840, + "City": "DeKalb", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "DeKalb, Illinois", + "Latitude": 41.9294736, + "Longitude": -88.750364699999992 + }, + { + "Id": 841, + "City": "Blacksburg", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Blacksburg, Virginia", + "Latitude": 37.2295733, + "Longitude": -80.4139393 + }, + { + "Id": 842, + "City": "Dublin", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Dublin, Ohio", + "Latitude": 40.0992294, + "Longitude": -83.1140771 + }, + { + "Id": 843, + "City": "Haltom City", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Haltom City, Texas", + "Latitude": 32.7995738, + "Longitude": -97.26918169999999 + }, + { + "Id": 844, + "City": "Lompoc", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Lompoc, California", + "Latitude": 34.6391501, + "Longitude": -120.4579409 + }, + { + "Id": 845, + "City": "El Centro", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "El Centro, California", + "Latitude": 32.792, + "Longitude": -115.5630514 + }, + { + "Id": 846, + "City": "Danville", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Danville, California", + "Latitude": 37.8215929, + "Longitude": -121.9999606 + }, + { + "Id": 847, + "City": "Jefferson City", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Jefferson City, Missouri", + "Latitude": 38.576701700000008, + "Longitude": -92.1735164 + }, + { + "Id": 848, + "City": "Cutler Bay", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Cutler Bay, Florida", + "Latitude": 25.5808323, + "Longitude": -80.346859299999991 + }, + { + "Id": 849, + "City": "Oakland Park", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Oakland Park, Florida", + "Latitude": 26.1723065, + "Longitude": -80.1319893 + }, + { + "Id": 850, + "City": "North Miami Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "North Miami Beach, Florida", + "Latitude": 25.9331488, + "Longitude": -80.1625463 + }, + { + "Id": 851, + "City": "Freeport", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Freeport, New York", + "Latitude": 40.6576022, + "Longitude": -73.58318349999999 + }, + { + "Id": 852, + "City": "Moline", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Moline, Illinois", + "Latitude": 41.5067003, + "Longitude": -90.515134199999991 + }, + { + "Id": 853, + "City": "Coachella", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Coachella, California", + "Latitude": 33.6803003, + "Longitude": -116.173894 + }, + { + "Id": 854, + "City": "Fort Pierce", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Fort Pierce, Florida", + "Latitude": 27.4467056, + "Longitude": -80.3256056 + }, + { + "Id": 855, + "City": "Smyrna", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Smyrna, Tennessee", + "Latitude": 35.9828412, + "Longitude": -86.5186045 + }, + { + "Id": 856, + "City": "Bountiful", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Bountiful, Utah", + "Latitude": 40.8893895, + "Longitude": -111.880771 + }, + { + "Id": 857, + "City": "Fond du Lac", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Fond du Lac, Wisconsin", + "Latitude": 43.7730448, + "Longitude": -88.4470508 + }, + { + "Id": 858, + "City": "Everett", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Everett, Massachusetts", + "Latitude": 42.40843, + "Longitude": -71.0536625 + }, + { + "Id": 859, + "City": "Danville", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Danville, Virginia", + "Latitude": 36.5859718, + "Longitude": -79.395022799999992 + }, + { + "Id": 860, + "City": "Keller", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Keller, Texas", + "Latitude": 32.9341893, + "Longitude": -97.229298 + }, + { + "Id": 861, + "City": "Belleville", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Belleville, Illinois", + "Latitude": 38.5200504, + "Longitude": -89.9839935 + }, + { + "Id": 862, + "City": "Bell Gardens", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Bell Gardens, California", + "Latitude": 33.9652918, + "Longitude": -118.1514588 + }, + { + "Id": 863, + "City": "Cleveland", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Cleveland, Tennessee", + "Latitude": 35.1595182, + "Longitude": -84.8766115 + }, + { + "Id": 864, + "City": "North Lauderdale", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "North Lauderdale, Florida", + "Latitude": 26.217305, + "Longitude": -80.2258811 + }, + { + "Id": 865, + "City": "Fairfield", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Fairfield, Ohio", + "Latitude": 39.3454673, + "Longitude": -84.5603187 + }, + { + "Id": 866, + "City": "Salem", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Salem, Massachusetts", + "Latitude": 42.51954, + "Longitude": -70.8967155 + }, + { + "Id": 867, + "City": "Rancho Palos Verdes", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rancho Palos Verdes, California", + "Latitude": 33.7444613, + "Longitude": -118.3870173 + }, + { + "Id": 868, + "City": "San Bruno", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Bruno, California", + "Latitude": 37.6304904, + "Longitude": -122.4110835 + }, + { + "Id": 869, + "City": "Concord", + "State": "New Hampshire", + "StateAbbreviation": "NH", + "DisplayName": "Concord, New Hampshire", + "Latitude": 43.2081366, + "Longitude": -71.5375718 + }, + { + "Id": 870, + "City": "Burlington", + "State": "Vermont", + "StateAbbreviation": "VT", + "DisplayName": "Burlington, Vermont", + "Latitude": 44.4758825, + "Longitude": -73.212071999999992 + }, + { + "Id": 871, + "City": "Apex", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Apex, North Carolina", + "Latitude": 35.732652, + "Longitude": -78.850285599999992 + }, + { + "Id": 872, + "City": "Midland", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Midland, Michigan", + "Latitude": 43.6155825, + "Longitude": -84.2472116 + }, + { + "Id": 873, + "City": "Altamonte Springs", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Altamonte Springs, Florida", + "Latitude": 28.6611089, + "Longitude": -81.3656242 + }, + { + "Id": 874, + "City": "Hutchinson", + "State": "Kansas", + "StateAbbreviation": "KS", + "DisplayName": "Hutchinson, Kansas", + "Latitude": 38.0608445, + "Longitude": -97.929774299999991 + }, + { + "Id": 875, + "City": "Buffalo Grove", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Buffalo Grove, Illinois", + "Latitude": 42.1662831, + "Longitude": -87.9631308 + }, + { + "Id": 876, + "City": "Urbandale", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Urbandale, Iowa", + "Latitude": 41.6266555, + "Longitude": -93.712165599999992 + }, + { + "Id": 877, + "City": "State College", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "State College, Pennsylvania", + "Latitude": 40.7933949, + "Longitude": -77.8600012 + }, + { + "Id": 878, + "City": "Urbana", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Urbana, Illinois", + "Latitude": 40.1105875, + "Longitude": -88.2072697 + }, + { + "Id": 879, + "City": "Plainfield", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Plainfield, Illinois", + "Latitude": 41.632223, + "Longitude": -88.2120315 + }, + { + "Id": 880, + "City": "Manassas", + "State": "Virginia", + "StateAbbreviation": "VA", + "DisplayName": "Manassas, Virginia", + "Latitude": 38.7509488, + "Longitude": -77.475266699999992 + }, + { + "Id": 881, + "City": "Bartlett", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Bartlett, Illinois", + "Latitude": 41.9950276, + "Longitude": -88.1856301 + }, + { + "Id": 882, + "City": "Kearny", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Kearny, New Jersey", + "Latitude": 40.7684342, + "Longitude": -74.1454214 + }, + { + "Id": 883, + "City": "Oro Valley", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Oro Valley, Arizona", + "Latitude": 32.3909071, + "Longitude": -110.966488 + }, + { + "Id": 884, + "City": "Findlay", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Findlay, Ohio", + "Latitude": 41.04422, + "Longitude": -83.6499321 + }, + { + "Id": 885, + "City": "Rohnert Park", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Rohnert Park, California", + "Latitude": 38.3396367, + "Longitude": -122.7010984 + }, + { + "Id": 887, + "City": "Westfield", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Westfield, Massachusetts", + "Latitude": 42.1250929, + "Longitude": -72.749538 + }, + { + "Id": 886, + "City": "Linden", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Linden, New Jersey", + "Latitude": 40.6220478, + "Longitude": -74.24459019999999 + }, + { + "Id": 888, + "City": "Sumter", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Sumter, South Carolina", + "Latitude": 33.9204354, + "Longitude": -80.3414693 + }, + { + "Id": 889, + "City": "Wilkes-Barre", + "State": "Pennsylvania", + "StateAbbreviation": "PA", + "DisplayName": "Wilkes-Barre, Pennsylvania", + "Latitude": 41.2459149, + "Longitude": -75.881307499999991 + }, + { + "Id": 890, + "City": "Woonsocket", + "State": "Rhode Island", + "StateAbbreviation": "RI", + "DisplayName": "Woonsocket, Rhode Island", + "Latitude": 42.002876099999988, + "Longitude": -71.514783900000012 + }, + { + "Id": 891, + "City": "Leominster", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Leominster, Massachusetts", + "Latitude": 42.5250906, + "Longitude": -71.759794 + }, + { + "Id": 892, + "City": "Shelton", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Shelton, Connecticut", + "Latitude": 41.3164856, + "Longitude": -73.0931641 + }, + { + "Id": 893, + "City": "Brea", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Brea, California", + "Latitude": 33.9166805, + "Longitude": -117.9000604 + }, + { + "Id": 894, + "City": "Covington", + "State": "Kentucky", + "StateAbbreviation": "KY", + "DisplayName": "Covington, Kentucky", + "Latitude": 39.0836712, + "Longitude": -84.5085536 + }, + { + "Id": 895, + "City": "Rockwall", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Rockwall, Texas", + "Latitude": 32.931233600000013, + "Longitude": -96.4597089 + }, + { + "Id": 896, + "City": "Meridian", + "State": "Mississippi", + "StateAbbreviation": "MS", + "DisplayName": "Meridian, Mississippi", + "Latitude": 32.3643098, + "Longitude": -88.703656 + }, + { + "Id": 897, + "City": "Riverton", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Riverton, Utah", + "Latitude": 40.521893, + "Longitude": -111.9391023 + }, + { + "Id": 898, + "City": "St. Cloud", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "St. Cloud, Florida", + "Latitude": 28.2489016, + "Longitude": -81.2811801 + }, + { + "Id": 899, + "City": "Quincy", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Quincy, Illinois", + "Latitude": 39.9356016, + "Longitude": -91.4098726 + }, + { + "Id": 900, + "City": "Morgan Hill", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Morgan Hill, California", + "Latitude": 37.1305012, + "Longitude": -121.6543901 + }, + { + "Id": 901, + "City": "Warren", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Warren, Ohio", + "Latitude": 41.2375569, + "Longitude": -80.818416599999992 + }, + { + "Id": 902, + "City": "Edmonds", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Edmonds, Washington", + "Latitude": 47.8106521, + "Longitude": -122.3773552 + }, + { + "Id": 903, + "City": "Burleson", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Burleson, Texas", + "Latitude": 32.5420821, + "Longitude": -97.3208492 + }, + { + "Id": 904, + "City": "Beverly", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Beverly, Massachusetts", + "Latitude": 42.5584283, + "Longitude": -70.880049 + }, + { + "Id": 905, + "City": "Mankato", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Mankato, Minnesota", + "Latitude": 44.1635775, + "Longitude": -93.99939959999999 + }, + { + "Id": 906, + "City": "Hagerstown", + "State": "Maryland", + "StateAbbreviation": "MD", + "DisplayName": "Hagerstown, Maryland", + "Latitude": 39.6417629, + "Longitude": -77.71999319999999 + }, + { + "Id": 907, + "City": "Prescott", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Prescott, Arizona", + "Latitude": 34.5400242, + "Longitude": -112.4685025 + }, + { + "Id": 908, + "City": "Campbell", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Campbell, California", + "Latitude": 37.2871651, + "Longitude": -121.9499568 + }, + { + "Id": 909, + "City": "Cedar Falls", + "State": "Iowa", + "StateAbbreviation": "IA", + "DisplayName": "Cedar Falls, Iowa", + "Latitude": 42.5348993, + "Longitude": -92.4453161 + }, + { + "Id": 910, + "City": "Beaumont", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Beaumont, California", + "Latitude": 33.9294606, + "Longitude": -116.977248 + }, + { + "Id": 911, + "City": "La Puente", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "La Puente, California", + "Latitude": 34.0200114, + "Longitude": -117.9495083 + }, + { + "Id": 912, + "City": "Crystal Lake", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Crystal Lake, Illinois", + "Latitude": 42.2411344, + "Longitude": -88.31619649999999 + }, + { + "Id": 913, + "City": "Fitchburg", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Fitchburg, Massachusetts", + "Latitude": 42.5834228, + "Longitude": -71.8022955 + }, + { + "Id": 914, + "City": "Carol Stream", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Carol Stream, Illinois", + "Latitude": 41.912528599999987, + "Longitude": -88.134792699999991 + }, + { + "Id": 915, + "City": "Hickory", + "State": "North Carolina", + "StateAbbreviation": "NC", + "DisplayName": "Hickory, North Carolina", + "Latitude": 35.7344538, + "Longitude": -81.3444573 + }, + { + "Id": 916, + "City": "Streamwood", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Streamwood, Illinois", + "Latitude": 42.0255827, + "Longitude": -88.178408499999989 + }, + { + "Id": 917, + "City": "Norwich", + "State": "Connecticut", + "StateAbbreviation": "CT", + "DisplayName": "Norwich, Connecticut", + "Latitude": 41.5242649, + "Longitude": -72.075910499999992 + }, + { + "Id": 918, + "City": "Coppell", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Coppell, Texas", + "Latitude": 32.9545687, + "Longitude": -97.015007799999992 + }, + { + "Id": 919, + "City": "San Gabriel", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "San Gabriel, California", + "Latitude": 34.096111100000009, + "Longitude": -118.1058333 + }, + { + "Id": 920, + "City": "Holyoke", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Holyoke, Massachusetts", + "Latitude": 42.2042586, + "Longitude": -72.6162009 + }, + { + "Id": 921, + "City": "Bentonville", + "State": "Arkansas", + "StateAbbreviation": "AR", + "DisplayName": "Bentonville, Arkansas", + "Latitude": 36.3728538, + "Longitude": -94.2088172 + }, + { + "Id": 922, + "City": "Florence", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Florence, Alabama", + "Latitude": 34.79981, + "Longitude": -87.677251 + }, + { + "Id": 923, + "City": "Peachtree Corners", + "State": "Georgia", + "StateAbbreviation": "GA", + "DisplayName": "Peachtree Corners, Georgia", + "Latitude": 33.9698929, + "Longitude": -84.2214551 + }, + { + "Id": 924, + "City": "Brentwood", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Brentwood, Tennessee", + "Latitude": 36.0331164, + "Longitude": -86.782777200000012 + }, + { + "Id": 925, + "City": "Bozeman", + "State": "Montana", + "StateAbbreviation": "MT", + "DisplayName": "Bozeman, Montana", + "Latitude": 45.6769979, + "Longitude": -111.0429339 + }, + { + "Id": 926, + "City": "New Berlin", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "New Berlin, Wisconsin", + "Latitude": 42.9764027, + "Longitude": -88.1084224 + }, + { + "Id": 927, + "City": "Goose Creek", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Goose Creek, South Carolina", + "Latitude": 32.9810059, + "Longitude": -80.03258670000001 + }, + { + "Id": 928, + "City": "Huntsville", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Huntsville, Texas", + "Latitude": 30.7235263, + "Longitude": -95.550777099999991 + }, + { + "Id": 929, + "City": "Prescott Valley", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Prescott Valley, Arizona", + "Latitude": 34.6100243, + "Longitude": -112.315721 + }, + { + "Id": 930, + "City": "Maplewood", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Maplewood, Minnesota", + "Latitude": 44.9530215, + "Longitude": -92.9952153 + }, + { + "Id": 931, + "City": "Romeoville", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Romeoville, Illinois", + "Latitude": 41.6475306, + "Longitude": -88.0895061 + }, + { + "Id": 932, + "City": "Duncanville", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Duncanville, Texas", + "Latitude": 32.6518004, + "Longitude": -96.9083366 + }, + { + "Id": 933, + "City": "Atlantic City", + "State": "New Jersey", + "StateAbbreviation": "NJ", + "DisplayName": "Atlantic City, New Jersey", + "Latitude": 39.3642834, + "Longitude": -74.4229266 + }, + { + "Id": 934, + "City": "Clovis", + "State": "New Mexico", + "StateAbbreviation": "NM", + "DisplayName": "Clovis, New Mexico", + "Latitude": 34.4047987, + "Longitude": -103.2052272 + }, + { + "Id": 935, + "City": "The Colony", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "The Colony, Texas", + "Latitude": 33.0806083, + "Longitude": -96.892830899999993 + }, + { + "Id": 936, + "City": "Culver City", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Culver City, California", + "Latitude": 34.0211224, + "Longitude": -118.3964665 + }, + { + "Id": 937, + "City": "Marlborough", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Marlborough, Massachusetts", + "Latitude": 42.3459271, + "Longitude": -71.5522874 + }, + { + "Id": 938, + "City": "Hilton Head Island", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Hilton Head Island, South Carolina", + "Latitude": 32.216316, + "Longitude": -80.752608 + }, + { + "Id": 939, + "City": "Moorhead", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Moorhead, Minnesota", + "Latitude": 46.8737648, + "Longitude": -96.76780389999999 + }, + { + "Id": 940, + "City": "Calexico", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Calexico, California", + "Latitude": 32.6789476, + "Longitude": -115.4988834 + }, + { + "Id": 941, + "City": "Bullhead City", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Bullhead City, Arizona", + "Latitude": 35.1359386, + "Longitude": -114.5285981 + }, + { + "Id": 942, + "City": "Germantown", + "State": "Tennessee", + "StateAbbreviation": "TN", + "DisplayName": "Germantown, Tennessee", + "Latitude": 35.0867577, + "Longitude": -89.8100858 + }, + { + "Id": 943, + "City": "La Quinta", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "La Quinta, California", + "Latitude": 33.6633573, + "Longitude": -116.3100095 + }, + { + "Id": 944, + "City": "Lancaster", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Lancaster, Ohio", + "Latitude": 39.7136754, + "Longitude": -82.5993294 + }, + { + "Id": 945, + "City": "Wausau", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Wausau, Wisconsin", + "Latitude": 44.9591352, + "Longitude": -89.6301221 + }, + { + "Id": 946, + "City": "Sherman", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Sherman, Texas", + "Latitude": 33.6356618, + "Longitude": -96.6088805 + }, + { + "Id": 947, + "City": "Ocoee", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Ocoee, Florida", + "Latitude": 28.5691677, + "Longitude": -81.5439619 + }, + { + "Id": 948, + "City": "Shakopee", + "State": "Minnesota", + "StateAbbreviation": "MN", + "DisplayName": "Shakopee, Minnesota", + "Latitude": 44.7973962, + "Longitude": -93.5272861 + }, + { + "Id": 949, + "City": "Woburn", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Woburn, Massachusetts", + "Latitude": 42.4792618, + "Longitude": -71.1522765 + }, + { + "Id": 950, + "City": "Bremerton", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Bremerton, Washington", + "Latitude": 47.5673202, + "Longitude": -122.6329356 + }, + { + "Id": 951, + "City": "Rock Island", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Rock Island, Illinois", + "Latitude": 41.5094771, + "Longitude": -90.5787476 + }, + { + "Id": 952, + "City": "Muskogee", + "State": "Oklahoma", + "StateAbbreviation": "OK", + "DisplayName": "Muskogee, Oklahoma", + "Latitude": 35.7478769, + "Longitude": -95.3696909 + }, + { + "Id": 953, + "City": "Cape Girardeau", + "State": "Missouri", + "StateAbbreviation": "MO", + "DisplayName": "Cape Girardeau, Missouri", + "Latitude": 37.3058839, + "Longitude": -89.518147599999992 + }, + { + "Id": 954, + "City": "Annapolis", + "State": "Maryland", + "StateAbbreviation": "MD", + "DisplayName": "Annapolis, Maryland", + "Latitude": 38.9784453, + "Longitude": -76.4921829 + }, + { + "Id": 955, + "City": "Greenacres", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Greenacres, Florida", + "Latitude": 26.6276276, + "Longitude": -80.1353896 + }, + { + "Id": 956, + "City": "Ormond Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Ormond Beach, Florida", + "Latitude": 29.2858129, + "Longitude": -81.0558894 + }, + { + "Id": 957, + "City": "Hallandale Beach", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Hallandale Beach, Florida", + "Latitude": 25.9812024, + "Longitude": -80.148378999999991 + }, + { + "Id": 958, + "City": "Stanton", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Stanton, California", + "Latitude": 33.8025155, + "Longitude": -117.9931165 + }, + { + "Id": 959, + "City": "Puyallup", + "State": "Washington", + "StateAbbreviation": "WA", + "DisplayName": "Puyallup, Washington", + "Latitude": 47.1853785, + "Longitude": -122.2928974 + }, + { + "Id": 960, + "City": "Pacifica", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Pacifica, California", + "Latitude": 37.6138253, + "Longitude": -122.4869194 + }, + { + "Id": 961, + "City": "Hanover Park", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Hanover Park, Illinois", + "Latitude": 41.9994722, + "Longitude": -88.1450735 + }, + { + "Id": 962, + "City": "Hurst", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Hurst, Texas", + "Latitude": 32.8234621, + "Longitude": -97.1705678 + }, + { + "Id": 963, + "City": "Lima", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Lima, Ohio", + "Latitude": 40.742551, + "Longitude": -84.1052256 + }, + { + "Id": 964, + "City": "Marana", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Marana, Arizona", + "Latitude": 32.436381, + "Longitude": -111.2224422 + }, + { + "Id": 965, + "City": "Carpentersville", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Carpentersville, Illinois", + "Latitude": 42.1211364, + "Longitude": -88.2578582 + }, + { + "Id": 966, + "City": "Oakley", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Oakley, California", + "Latitude": 37.9974219, + "Longitude": -121.7124536 + }, + { + "Id": 967, + "City": "Huber Heights", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Huber Heights, Ohio", + "Latitude": 39.843947, + "Longitude": -84.124660800000015 + }, + { + "Id": 968, + "City": "Lancaster", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Lancaster, Texas", + "Latitude": 32.5920798, + "Longitude": -96.7561082 + }, + { + "Id": 969, + "City": "Montclair", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Montclair, California", + "Latitude": 34.0775104, + "Longitude": -117.6897776 + }, + { + "Id": 970, + "City": "Wheeling", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Wheeling, Illinois", + "Latitude": 42.1391927, + "Longitude": -87.9289591 + }, + { + "Id": 971, + "City": "Brookfield", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Brookfield, Wisconsin", + "Latitude": 43.0605671, + "Longitude": -88.1064787 + }, + { + "Id": 972, + "City": "Park Ridge", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Park Ridge, Illinois", + "Latitude": 42.0111412, + "Longitude": -87.840619199999992 + }, + { + "Id": 973, + "City": "Florence", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Florence, South Carolina", + "Latitude": 34.1954331, + "Longitude": -79.7625625 + }, + { + "Id": 974, + "City": "Roy", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Roy, Utah", + "Latitude": 41.1616108, + "Longitude": -112.0263313 + }, + { + "Id": 975, + "City": "Winter Garden", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Winter Garden, Florida", + "Latitude": 28.5652787, + "Longitude": -81.58618469999999 + }, + { + "Id": 976, + "City": "Chelsea", + "State": "Massachusetts", + "StateAbbreviation": "MA", + "DisplayName": "Chelsea, Massachusetts", + "Latitude": 42.3917638, + "Longitude": -71.0328284 + }, + { + "Id": 977, + "City": "Valley Stream", + "State": "New York", + "StateAbbreviation": "NY", + "DisplayName": "Valley Stream, New York", + "Latitude": 40.6642699, + "Longitude": -73.708464499999991 + }, + { + "Id": 978, + "City": "Spartanburg", + "State": "South Carolina", + "StateAbbreviation": "SC", + "DisplayName": "Spartanburg, South Carolina", + "Latitude": 34.9495672, + "Longitude": -81.9320482 + }, + { + "Id": 979, + "City": "Lake Oswego", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Lake Oswego, Oregon", + "Latitude": 45.420674899999987, + "Longitude": -122.6706498 + }, + { + "Id": 980, + "City": "Friendswood", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Friendswood, Texas", + "Latitude": 29.5293998, + "Longitude": -95.2010447 + }, + { + "Id": 981, + "City": "Westerville", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Westerville, Ohio", + "Latitude": 40.1261743, + "Longitude": -82.929069599999991 + }, + { + "Id": 982, + "City": "Northglenn", + "State": "Colorado", + "StateAbbreviation": "CO", + "DisplayName": "Northglenn, Colorado", + "Latitude": 39.8961821, + "Longitude": -104.9811468 + }, + { + "Id": 983, + "City": "Phenix City", + "State": "Alabama", + "StateAbbreviation": "AL", + "DisplayName": "Phenix City, Alabama", + "Latitude": 32.4709761, + "Longitude": -85.0007653 + }, + { + "Id": 984, + "City": "Grove City", + "State": "Ohio", + "StateAbbreviation": "OH", + "DisplayName": "Grove City, Ohio", + "Latitude": 39.881451899999988, + "Longitude": -83.0929644 + }, + { + "Id": 985, + "City": "Texarkana", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Texarkana, Texas", + "Latitude": 33.425125, + "Longitude": -94.04768820000001 + }, + { + "Id": 986, + "City": "Addison", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Addison, Illinois", + "Latitude": 41.931696, + "Longitude": -87.9889556 + }, + { + "Id": 987, + "City": "Dover", + "State": "Delaware", + "StateAbbreviation": "DE", + "DisplayName": "Dover, Delaware", + "Latitude": 39.158168, + "Longitude": -75.5243682 + }, + { + "Id": 988, + "City": "Lincoln Park", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Lincoln Park, Michigan", + "Latitude": 42.2505943, + "Longitude": -83.1785361 + }, + { + "Id": 989, + "City": "Calumet City", + "State": "Illinois", + "StateAbbreviation": "IL", + "DisplayName": "Calumet City, Illinois", + "Latitude": 41.6155909, + "Longitude": -87.5294871 + }, + { + "Id": 990, + "City": "Muskegon", + "State": "Michigan", + "StateAbbreviation": "MI", + "DisplayName": "Muskegon, Michigan", + "Latitude": 43.2341813, + "Longitude": -86.24839209999999 + }, + { + "Id": 991, + "City": "Aventura", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Aventura, Florida", + "Latitude": 25.9564812, + "Longitude": -80.1392121 + }, + { + "Id": 992, + "City": "Martinez", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Martinez, California", + "Latitude": 38.0193657, + "Longitude": -122.1341321 + }, + { + "Id": 993, + "City": "Greenfield", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Greenfield, Wisconsin", + "Latitude": 42.9614039, + "Longitude": -88.0125865 + }, + { + "Id": 994, + "City": "Apache Junction", + "State": "Arizona", + "StateAbbreviation": "AZ", + "DisplayName": "Apache Junction, Arizona", + "Latitude": 33.4150485, + "Longitude": -111.5495777 + }, + { + "Id": 995, + "City": "Monrovia", + "State": "California", + "StateAbbreviation": "CA", + "DisplayName": "Monrovia, California", + "Latitude": 34.1442616, + "Longitude": -118.0019482 + }, + { + "Id": 996, + "City": "Weslaco", + "State": "Texas", + "StateAbbreviation": "TX", + "DisplayName": "Weslaco, Texas", + "Latitude": 26.1595194, + "Longitude": -97.9908366 + }, + { + "Id": 997, + "City": "Keizer", + "State": "Oregon", + "StateAbbreviation": "OR", + "DisplayName": "Keizer, Oregon", + "Latitude": 44.9901194, + "Longitude": -123.0262077 + }, + { + "Id": 998, + "City": "Spanish Fork", + "State": "Utah", + "StateAbbreviation": "UT", + "DisplayName": "Spanish Fork, Utah", + "Latitude": 40.114955, + "Longitude": -111.654923 + }, + { + "Id": 999, + "City": "Beloit", + "State": "Wisconsin", + "StateAbbreviation": "WI", + "DisplayName": "Beloit, Wisconsin", + "Latitude": 42.5083482, + "Longitude": -89.031776499999992 + }, + { + "Id": 1000, + "City": "Panama City", + "State": "Florida", + "StateAbbreviation": "FL", + "DisplayName": "Panama City, Florida", + "Latitude": 30.1588129, + "Longitude": -85.6602058 + } +] \ No newline at end of file diff --git a/SlackBotPrototype/README.md b/SlackBotPrototype/README.md new file mode 100644 index 0000000..861daa6 --- /dev/null +++ b/SlackBotPrototype/README.md @@ -0,0 +1,103 @@ +# Weather Slack Bot + +## Overview + +Slack weather bot that uses DarkSky API to get forecasts. The bot supports location based weather requests () +To support location based weather requests, we need to persist user locations. + +It currently only supports small set of locations from demonstration purposes, 1000 cities in the United States only. Data source for cities from this Gist: https://gist.github.com/Miserlou/c5cd8364bf9b2420bb29 + +## Features + +* Responds to `weather now`, `weather tomorrow`, and `what should I wear?` +* Responds to `weather now `, `weather tomorrow ` + * needs to be a city state pair, where state is a two letter abbreviation e.g. New York, NY +* User can set location with `set me to ` + +## Development Setup + +* Visual Studio 2017 +* Windows 10 (.NET 4.5.2) +* Ensure that app.config files are present in both `DBPreparer` and `SlackBotPropertype` + +### DBPreparer App.config + +``` + + + + + + + + + + + +``` + +### SlackBotPrototype App.config + +``` + + + + + + + + + + + + + + + + + + +``` + +## External Dependencies + +* DarkSky API -- provides the weather info +* Slack API -- uses RTM inferface +* SQLite database + +## Setup Instructions + +1. Create app.config file in deploy folder +``` + + + + + + + + + + + + + + + + + + +``` +1. Set token for DarkSky API `DARK_SKY_TOKEN` to DarkSky secret in App.config +1. Set token for Slack API bot user `SLACK_API_TOKEN` to Slack bot user secret in App.config +1. Run executable `./DBPreparer.exe`, this creates a `SlackBotDb.db` file that is required for persistence. +1. Copy DB file to deploy folder. +1. Run executable via commandline `./SlackBotPrototype.exe` + +## Troubleshooting + +* `SQLite.dll` is not found -- quirk with library means that sometimes a full `rebuid solution` is required + + + + diff --git a/SlackBotPrototype/SlackBotPrototype.sln b/SlackBotPrototype/SlackBotPrototype.sln new file mode 100644 index 0000000..477a2a5 --- /dev/null +++ b/SlackBotPrototype/SlackBotPrototype.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.15 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlackBotPrototype", "SlackBotPrototype\SlackBotPrototype.csproj", "{84E25C64-267B-4A86-9EF9-52A550D8B228}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API", "API\API.csproj", "{A234D7B8-EAB9-497F-84E7-354DC066BCB5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API.Tests", "API.Tests\API.Tests.csproj", "{BEAB33E8-9F1E-4D39-B741-2069E95834DD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBPreparer", "DBPreparer\DBPreparer.csproj", "{41D05933-278A-45E7-A64D-933527E27883}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {84E25C64-267B-4A86-9EF9-52A550D8B228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {84E25C64-267B-4A86-9EF9-52A550D8B228}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84E25C64-267B-4A86-9EF9-52A550D8B228}.Release|Any CPU.ActiveCfg = Release|Any CPU + {84E25C64-267B-4A86-9EF9-52A550D8B228}.Release|Any CPU.Build.0 = Release|Any CPU + {A234D7B8-EAB9-497F-84E7-354DC066BCB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A234D7B8-EAB9-497F-84E7-354DC066BCB5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A234D7B8-EAB9-497F-84E7-354DC066BCB5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A234D7B8-EAB9-497F-84E7-354DC066BCB5}.Release|Any CPU.Build.0 = Release|Any CPU + {BEAB33E8-9F1E-4D39-B741-2069E95834DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEAB33E8-9F1E-4D39-B741-2069E95834DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEAB33E8-9F1E-4D39-B741-2069E95834DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEAB33E8-9F1E-4D39-B741-2069E95834DD}.Release|Any CPU.Build.0 = Release|Any CPU + {41D05933-278A-45E7-A64D-933527E27883}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41D05933-278A-45E7-A64D-933527E27883}.Debug|Any CPU.Build.0 = Debug|Any CPU + {41D05933-278A-45E7-A64D-933527E27883}.Release|Any CPU.ActiveCfg = Release|Any CPU + {41D05933-278A-45E7-A64D-933527E27883}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/SlackBotPrototype/SlackBotPrototype/Program.cs b/SlackBotPrototype/SlackBotPrototype/Program.cs new file mode 100644 index 0000000..8c9c0e2 --- /dev/null +++ b/SlackBotPrototype/SlackBotPrototype/Program.cs @@ -0,0 +1,83 @@ +using System; +using System.Linq; +using System.Threading; +using API; +using SlackAPI; +using SlackAPI.WebSocketMessages; + +namespace SlackBotPrototype +{ + internal static class Program + { + private static SlackSocketClient _client; + private static IMessageToCommandConverter _messageToCommandConverter; + private static IWeatherProvider _weatherProvider; + + private static void Main(string[] args) + { + var clientReady = new ManualResetEventSlim(false); + var slackToken = ConfigConstants.SlackApiSecret; + var darkSkyToken = ConfigConstants.DarkSkyApiSecret; + + if (string.IsNullOrWhiteSpace(slackToken)) + { + // SHORTCUT: Normally would use logging library instead so that we can have a robust, and standardized logs + Console.WriteLine("Slack token not found in environment var name = `{SLACK_API_TOKEN}`"); + return; + } + + if (string.IsNullOrWhiteSpace(darkSkyToken)) + { + Console.WriteLine("Dark sky API token not available var name = `{DARK_SKY_TOKEN}`"); + return; + } + + // SHORTCUT: We'd normally wrap the slack client library so that we can + // switch implementations or libraries with less fuss + _client = new SlackSocketClient(slackToken); + _weatherProvider = new DarkSkyWeatherProvider(darkSkyToken, new RestClientHttpProvider(ConfigConstants.DarkSkyBaseUrl)); + _messageToCommandConverter = new MessageToCommandConverter(_weatherProvider, new SqLitePersistence()); + + _client.Connect((connected) => { + // This is called once the client has emitted the RTM start command + Console.WriteLine($"RTM started -- {string.Join(",", connected.channels.Select(c => c.name))}"); + clientReady.Set(); + + }, () => { + // This is called once the RTM client has connected to the end point + Console.WriteLine("RTM connected"); + }); + + _client.GetUserList((ulr) => + { + Console.WriteLine("Got users"); + }); + + _client.OnMessageReceived += OnClientOnOnMessageReceived; + + clientReady.Wait(); + Console.Read(); + } + + private static void OnClientOnOnMessageReceived(NewMessage message) + { + Console.WriteLine(_client.MyData.name); + Console.WriteLine(message.type + " " + message.text); + + if (message.text.Contains($"@{_client.MyData.id}")) + { + Console.WriteLine($"Mentioned by {message.user}:{message.id}"); + var resp = _messageToCommandConverter.HandleRequest(message.user, message.text); + var msg = resp.Command.Invoke(); + + _client.PostMessage((response) => { }, message.channel, !string.IsNullOrWhiteSpace(msg) ? msg : "Huh?"); + } + else + { + Console.WriteLine("Not mentioned"); + } + } + } + + +} diff --git a/SlackBotPrototype/SlackBotPrototype/Properties/AssemblyInfo.cs b/SlackBotPrototype/SlackBotPrototype/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f8458bb --- /dev/null +++ b/SlackBotPrototype/SlackBotPrototype/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SlackBotPrototype")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SlackBotPrototype")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("84e25c64-267b-4a86-9ef9-52a550d8b228")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SlackBotPrototype/SlackBotPrototype/SlackBotPrototype.csproj b/SlackBotPrototype/SlackBotPrototype/SlackBotPrototype.csproj new file mode 100644 index 0000000..8cab2a5 --- /dev/null +++ b/SlackBotPrototype/SlackBotPrototype/SlackBotPrototype.csproj @@ -0,0 +1,157 @@ + + + + + Debug + AnyCPU + {84E25C64-267B-4A86-9EF9-52A550D8B228} + Exe + SlackBotPrototype + SlackBotPrototype + v4.5.2 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\FluentScheduler.5.3.0\lib\net40\FluentScheduler.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.AWT.WinForms.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Beans.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Charsets.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Cldrdata.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Corba.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Core.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Jdbc.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Localedata.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Management.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Media.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Misc.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Naming.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Nashorn.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Remoting.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Security.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.SwingAWT.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Text.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Tools.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.Util.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.API.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Bind.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Crypto.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Parse.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.Transform.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.WebServices.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.OpenJDK.XML.XPath.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.Runtime.dll + + + ..\packages\IKVM.8.1.5717.0\lib\IKVM.Runtime.JNI.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\SlackAPI.1.0.5.93\lib\net45\SlackAPI.dll + + + ..\packages\Stanford.NLP.POSTagger.3.7.0.1\lib\stanford-postagger-3.7.0.dll + + + + + + + + + + + + + + + + + Designer + + + + + + {A234D7B8-EAB9-497F-84E7-354DC066BCB5} + API + + + + \ No newline at end of file diff --git a/SlackBotPrototype/SlackBotPrototype/packages.config b/SlackBotPrototype/SlackBotPrototype/packages.config new file mode 100644 index 0000000..133d274 --- /dev/null +++ b/SlackBotPrototype/SlackBotPrototype/packages.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file