├── .github └── workflows │ ├── dotnet.yml │ └── nuget.yml ├── .gitignore ├── .nuspec ├── GoogleMapsApi.Test ├── GoogleMapsApi.Test.csproj ├── IntegrationTests │ ├── BaseTestIntegration.cs │ ├── DirectionsTests.cs │ ├── DistanceMatrixTests.cs │ ├── ElevationTests.cs │ ├── GeocodingTests.cs │ ├── PlaceAutocompleteTests.cs │ ├── PlacesDetailsTests.cs │ ├── PlacesFindTests.cs │ ├── PlacesNearByTests.cs │ ├── PlacesSearchTests.cs │ ├── PlacesTextTests.cs │ └── TimeZoneTests.cs ├── LocationToStringTest.cs ├── StaticMaps.cs ├── UnixTimeConverterTest.cs ├── Utils │ ├── AppSettings.cs │ └── AssertInconclusive.cs └── appsettings.template.json ├── GoogleMapsApi.sln ├── GoogleMapsApi ├── Engine │ ├── MapsAPIGenericEngine.cs │ └── UnixTimeConverter.cs ├── EngineFacade.cs ├── Entities │ ├── Common │ │ ├── AddressLocation.cs │ │ ├── ILocationString.cs │ │ ├── IResponseFor.cs │ │ ├── Location.cs │ │ ├── MapsBaseRequest.cs │ │ ├── Photo.cs │ │ ├── SignableRequest.cs │ │ └── Type.cs │ ├── Directions │ │ ├── Request │ │ │ ├── AvoidWay.cs │ │ │ ├── DirectionsRequest.cs │ │ │ └── TravelMode.cs │ │ ├── Response │ │ │ ├── DirectionsResponse.cs │ │ │ ├── Distance.cs │ │ │ ├── Duration.cs │ │ │ ├── Leg.cs │ │ │ ├── Line.cs │ │ │ ├── OverviewPolyline.cs │ │ │ ├── PointsDecodingException.cs │ │ │ ├── Route.cs │ │ │ ├── StatusCodes.cs │ │ │ ├── Step.cs │ │ │ ├── Stop.cs │ │ │ ├── TransitAgency.cs │ │ │ ├── TransitDetails.cs │ │ │ ├── Vehicle.cs │ │ │ └── VehicleType.cs │ │ └── The Google Directions API - Google Maps API Web Services - Google Code.htm │ ├── DistanceMatrix │ │ ├── Request │ │ │ ├── DistanceMatrixRequest.cs │ │ │ ├── Restrictions.cs │ │ │ ├── Time.cs │ │ │ ├── TrafficModel.cs │ │ │ ├── TransitMode.cs │ │ │ ├── TransitRoutingPreference.cs │ │ │ ├── TravelMode.cs │ │ │ └── UnitSystem.cs │ │ └── Response │ │ │ ├── Distance.cs │ │ │ ├── DistanceMatrixResponse.cs │ │ │ ├── Duration.cs │ │ │ ├── Element.cs │ │ │ ├── ElementStatusCodes.cs │ │ │ ├── Row.cs │ │ │ └── StatusCodes.cs │ ├── Elevation │ │ ├── Request │ │ │ └── ElevationRequest.cs │ │ └── Response │ │ │ ├── ElevationResponse.cs │ │ │ ├── Result.cs │ │ │ └── Status.cs │ ├── Geocoding │ │ ├── Request │ │ │ ├── GeocodingComponents.cs │ │ │ └── GeocodingRequest.cs │ │ └── Response │ │ │ ├── AddressComponent.cs │ │ │ ├── FramedLocation.cs │ │ │ ├── GeocodingResponse.cs │ │ │ ├── Geometry.cs │ │ │ ├── LocationType.cs │ │ │ ├── Result.cs │ │ │ └── Status.cs │ ├── PlaceAutocomplete │ │ ├── Request │ │ │ └── PlaceAutocompleteRequest.cs │ │ └── Response │ │ │ ├── MatchedSubstring.cs │ │ │ ├── PlaceAutocompleteResponse.cs │ │ │ ├── Prediction.cs │ │ │ ├── Status.cs │ │ │ └── Term.cs │ ├── Places │ │ ├── Request │ │ │ ├── PlacesRequest.cs │ │ │ └── RankBy.cs │ │ └── Response │ │ │ ├── Geometry.cs │ │ │ ├── PlacesResponse.cs │ │ │ ├── Result.cs │ │ │ └── Status.cs │ ├── PlacesDetails │ │ ├── Request │ │ │ └── PlacesDetailsRequest.cs │ │ └── Response │ │ │ ├── Aspect.cs │ │ │ ├── Events.cs │ │ │ ├── Geometry.cs │ │ │ ├── OpeningHours.cs │ │ │ ├── Period.cs │ │ │ ├── PlacesDetailsResponse.cs │ │ │ ├── Result.cs │ │ │ ├── Review.cs │ │ │ ├── Status.cs │ │ │ └── TimeOfWeek.cs │ ├── PlacesFind │ │ ├── Request │ │ │ ├── InputType.cs │ │ │ └── PlacesFindRequest.cs │ │ └── Response │ │ │ ├── Candidate.cs │ │ │ ├── Geometry.cs │ │ │ ├── OpeningHours.cs │ │ │ ├── PlacesFindResponse.cs │ │ │ └── Status.cs │ ├── PlacesNearBy │ │ ├── Request │ │ │ ├── PlacesNearByRequest.cs │ │ │ └── RankBy.cs │ │ └── Response │ │ │ ├── Geometry.cs │ │ │ ├── PlacesNearByResponse.cs │ │ │ ├── Result.cs │ │ │ └── Status.cs │ ├── PlacesRadar │ │ ├── Request │ │ │ └── PlacesRadarRequest.cs │ │ └── Response │ │ │ ├── Geometry.cs │ │ │ ├── PlacesRadarResponse.cs │ │ │ ├── Result.cs │ │ │ └── Status.cs │ ├── PlacesText │ │ ├── Request │ │ │ └── PlacesTextRequest.cs │ │ └── Response │ │ │ ├── Geometry.cs │ │ │ ├── PlacesTextResponse.cs │ │ │ ├── Result.cs │ │ │ └── Status.cs │ └── TimeZone │ │ ├── Request │ │ └── TimeZoneRequest.cs │ │ └── Response │ │ ├── Status.cs │ │ └── TimeZoneResponse.cs ├── GoogleMaps.cs ├── GoogleMapsApi.csproj ├── HttpClientExtensions.cs ├── IEngineFacade.cs ├── QueryStringParametersList.cs ├── ReleaseNotes.md └── StaticMaps │ ├── Entities │ ├── ImageSize.cs │ ├── MapStyle.cs │ ├── Marker.cs │ ├── MarkerStyle.cs │ ├── Path.cs │ ├── PathStyle.cs │ └── StaticMapRequest.cs │ ├── Enums │ ├── ImageFormat.cs │ ├── MapElement.cs │ ├── MapFeatures.cs │ ├── MapType.cs │ ├── MapVisibility.cs │ └── MarkerSize.cs │ └── StaticMapsEngine.cs ├── LICENSE.md ├── README.md └── SECURITY.md /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | name: .NET 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Setup .NET 16 | uses: actions/setup-dotnet@v4 17 | with: 18 | dotnet-version: 7.0.x 19 | - name: Restore dependencies 20 | run: dotnet restore 21 | - name: Build 22 | run: dotnet build --no-restore 23 | - name: Test 24 | run: dotnet test --no-build --verbosity normal 25 | env: 26 | GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} 27 | -------------------------------------------------------------------------------- /.github/workflows/nuget.yml: -------------------------------------------------------------------------------- 1 | name: Publish Nuget 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | 15 | - name: Setup .NET 16 | uses: actions/setup-dotnet@v4 17 | with: 18 | dotnet-version: | 19 | 6.0.x 20 | 7.0.x 21 | 8.0.x 22 | 23 | - name: Get version from tag 24 | id: get_version 25 | run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT 26 | 27 | - name: Update version in project file 28 | run: | 29 | sed -i 's/0.0.0<\/Version>/${{ steps.get_version.outputs.VERSION }}<\/Version>/' GoogleMapsApi/GoogleMapsApi.csproj 30 | 31 | - name: Restore dependencies 32 | run: dotnet restore 33 | 34 | - name: Build 35 | run: dotnet build --configuration Release --no-restore 36 | 37 | - name: Pack 38 | run: dotnet pack --configuration Release --no-build --output . 39 | 40 | - name: Publish NuGet 41 | run: dotnet nuget push *.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Dd]ebug*/ 3 | [Bb]in 4 | obj/ 5 | *.suo 6 | *.user 7 | _ReSharper*/ 8 | packages 9 | 10 | # mstest test results 11 | [Tt]est[Rr]esult* 12 | \.vs/ 13 | 14 | GoogleMapsApi/project\.lock\.json 15 | 16 | **/appsettings.json 17 | -------------------------------------------------------------------------------- /.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GoogleMapsApi 5 | $version$ 6 | Google Maps Web Services API wrapper for .NET 7 | Maxim Novak 8 | Maxim Novak 9 | https://github.com/maximn/google-maps/blob/master/LICENSE.md 10 | https://github.com/maximn/google-maps/ 11 | https://code.google.com/p/google-maps/logo?cct=1335784301 12 | false 13 | 14 | This library wraps Google maps API. 15 | You can easily query Google maps for Geocoding, Directions, Elevation, and Places. 16 | You can easily show the results on a Static Google Map! 17 | This Library is well documented and easy to use. 18 | 19 | 20 | 21 | Map Geo Places Elevation Geocode Directions Maps 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/GoogleMapsApi.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0;net6.0;net4.8 4 | latest 5 | Library 6 | false 7 | enable 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | all 22 | runtime; build; native; contentfiles; analyzers; buildtransitive 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | PreserveNewest 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/BaseTestIntegration.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Test.Utils; 2 | using System.IO; 3 | 4 | namespace GoogleMapsApi.Test.IntegrationTests 5 | { 6 | // Note: The integration tests run against the real Google API web 7 | // servers and count towards your query limit. Also, the tests 8 | // require a working internet connection in order to pass. 9 | // Their run time may vary depending on your connection, 10 | // network congestion and the current load on Google's servers. 11 | 12 | public class BaseTestIntegration 13 | { 14 | const string ApiKeyEnvironmentVariable = "GOOGLE_API_KEY"; 15 | 16 | public BaseTestIntegration() 17 | { 18 | } 19 | 20 | protected string ApiKey => AppSettings.Load()?.GoogleApiKey 21 | ?? Environment.GetEnvironmentVariable(ApiKeyEnvironmentVariable) 22 | ?? throw new InvalidOperationException($"API key is not configured. Please set the {ApiKeyEnvironmentVariable} environment variable."); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/ElevationTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using GoogleMapsApi.Entities.Common; 3 | using GoogleMapsApi.Entities.Elevation.Request; 4 | using NUnit.Framework; 5 | using GoogleMapsApi.Test.Utils; 6 | using System.Threading.Tasks; 7 | 8 | namespace GoogleMapsApi.Test.IntegrationTests 9 | { 10 | [TestFixture] 11 | public class ElevationTests : BaseTestIntegration 12 | { 13 | [Test] 14 | public async Task Elevation_ReturnsCorrectElevation() 15 | { 16 | var request = new ElevationRequest 17 | { 18 | ApiKey = ApiKey, 19 | Locations = new[] { new Location(40.7141289, -73.9614074) } 20 | }; 21 | 22 | var result = await GoogleMaps.Elevation.QueryAsync(request); 23 | 24 | AssertInconclusive.NotExceedQuota(result); 25 | Assert.That(result.Status, Is.EqualTo(Entities.Elevation.Response.Status.OK)); 26 | Assert.That(result.Results.First().Elevation, Is.EqualTo(16.92).Within(1.0)); 27 | Assert.That(result.Results.First().Resolution, Is.EqualTo(75.0).Within(10.0)); 28 | } 29 | 30 | [Test] 31 | public void ElevationAsync_ReturnsCorrectElevation() 32 | { 33 | var request = new ElevationRequest 34 | { 35 | ApiKey = ApiKey, 36 | Locations = new[] { new Location(40.7141289, -73.9614074) } 37 | }; 38 | 39 | var result = GoogleMaps.Elevation.QueryAsync(request).Result; 40 | 41 | AssertInconclusive.NotExceedQuota(result); 42 | Assert.That(result.Status, Is.EqualTo(Entities.Elevation.Response.Status.OK)); 43 | Assert.That(result.Results.First().Elevation, Is.EqualTo(16.92).Within(1.0)); 44 | Assert.That(result.Results.First().Resolution, Is.EqualTo(75.0).Within(10.0)); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/PlacesDetailsTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using GoogleMapsApi.Entities.Common; 3 | using GoogleMapsApi.Entities.PlacesDetails.Request; 4 | using GoogleMapsApi.Entities.PlacesDetails.Response; 5 | using NUnit.Framework; 6 | using GoogleMapsApi.Test.Utils; 7 | using System.Threading.Tasks; 8 | 9 | namespace GoogleMapsApi.Test.IntegrationTests 10 | { 11 | [TestFixture] 12 | public class PlacesDetailsTests : BaseTestIntegration 13 | { 14 | [Test] 15 | public async Task ReturnsPhotos() 16 | { 17 | var request = new PlacesDetailsRequest 18 | { 19 | ApiKey = ApiKey, 20 | PlaceId = "ChIJZ3VuVMQdLz4REP9PWpQ4SIY" 21 | }; 22 | 23 | PlacesDetailsResponse result = await GoogleMaps.PlacesDetails.QueryAsync(request); 24 | 25 | AssertInconclusive.NotExceedQuota(result); 26 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 27 | Assert.That(result.Result.Photos, Is.Not.Empty); 28 | } 29 | 30 | [Test] 31 | public async Task ReturnsNotFoundForWrongReferenceString() 32 | { 33 | var request = new PlacesDetailsRequest 34 | { 35 | ApiKey = base.ApiKey, 36 | // Needs to be a correct looking reference. 1 character too short or long and google will return INVALID_REQUEST instead. 37 | PlaceId = "ChIJbWWgrQAVkFQReAwrXXWzlYs" 38 | }; 39 | 40 | PlacesDetailsResponse result = await GoogleMaps.PlacesDetails.QueryAsync(request); 41 | 42 | AssertInconclusive.NotExceedQuota(result); 43 | Assert.That(result.Status, Is.EqualTo(Status.NOT_FOUND)); 44 | } 45 | 46 | readonly PriceLevel[] anyPriceLevel = new PriceLevel[] { PriceLevel.Free, PriceLevel.Inexpensive, PriceLevel.Moderate, PriceLevel.Expensive, PriceLevel.VeryExpensive }; 47 | 48 | [Test] 49 | public async Task ReturnsStronglyTypedPriceLevel() 50 | { 51 | var request = new PlacesDetailsRequest 52 | { 53 | ApiKey = ApiKey, 54 | PlaceId = await GetMyPlaceId(), 55 | }; 56 | 57 | PlacesDetailsResponse result = await GoogleMaps.PlacesDetails.QueryAsync(request); 58 | 59 | AssertInconclusive.NotExceedQuota(result); 60 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 61 | Assert.That(result.Result.PriceLevel, Is.Not.Null); 62 | Assert.That(new PriceLevel[] { result.Result.PriceLevel.Value }, Is.SubsetOf(anyPriceLevel)); 63 | } 64 | 65 | [Test] 66 | public async Task ReturnsOpeningTimes() 67 | { 68 | var request = new PlacesDetailsRequest 69 | { 70 | ApiKey = ApiKey, 71 | PlaceId = await GetMyPlaceId(), 72 | }; 73 | 74 | PlacesDetailsResponse result = await GoogleMaps.PlacesDetails.QueryAsync(request); 75 | 76 | AssertInconclusive.NotExceedQuota(result); 77 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 78 | 79 | // commented out because seems like google doesn't have opening hours for this place anymore 80 | /* 81 | Assert.AreEqual(7, result.Result.OpeningHours.Periods.Count()); 82 | var sundayPeriod = result.Result.OpeningHours.Periods.First(); 83 | Assert.That(sundayPeriod.OpenTime.Day, Is.EqualTo(DayOfWeek.Sunday)); 84 | Assert.That(sundayPeriod.OpenTime.Time, Is.GreaterThanOrEqualTo(0)); 85 | Assert.That(sundayPeriod.OpenTime.Time, Is.LessThanOrEqualTo(2359)); 86 | Assert.That(sundayPeriod.CloseTime.Time, Is.GreaterThanOrEqualTo(0)); 87 | Assert.That(sundayPeriod.CloseTime.Time, Is.LessThanOrEqualTo(2359)); 88 | */ 89 | } 90 | 91 | private string? cachedMyPlaceId; 92 | private async Task GetMyPlaceId() 93 | { 94 | if (cachedMyPlaceId == null) 95 | { 96 | var request = new Entities.Places.Request.PlacesRequest() 97 | { 98 | ApiKey = ApiKey, 99 | Name = "My Place Bar & Restaurant", 100 | Location = new Location(-31.954453, 115.862717), 101 | RankBy = Entities.Places.Request.RankBy.Distance, 102 | }; 103 | var result = await GoogleMaps.Places.QueryAsync(request); 104 | AssertInconclusive.NotExceedQuota(result); 105 | cachedMyPlaceId = result.Results.First().PlaceId; 106 | } 107 | return cachedMyPlaceId; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/PlacesFindTests.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.PlacesFind.Request; 2 | using GoogleMapsApi.Entities.PlacesFind.Response; 3 | using GoogleMapsApi.Test.Utils; 4 | using NUnit.Framework; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace GoogleMapsApi.Test.IntegrationTests 12 | { 13 | [TestFixture] 14 | public class PlacesFindTests : BaseTestIntegration 15 | { 16 | [Test] 17 | public async Task ReturnsResults() 18 | { 19 | var request = new PlacesFindRequest 20 | { 21 | ApiKey = ApiKey, 22 | Input = "pizza chicago il", 23 | InputType = InputType.TextQuery 24 | }; 25 | 26 | PlacesFindResponse result = await GoogleMaps.PlacesFind.QueryAsync(request); 27 | 28 | AssertInconclusive.NotExceedQuota(result); 29 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 30 | Assert.That(result.Candidates, Is.Not.Empty); 31 | } 32 | 33 | [Test] 34 | public async Task DoesNotReturnFieldsWhenNotRequested() 35 | { 36 | var request = new PlacesFindRequest 37 | { 38 | ApiKey = ApiKey, 39 | Input = "pizza chicago il", 40 | InputType = InputType.TextQuery, 41 | Fields = "place_id" 42 | }; 43 | 44 | PlacesFindResponse result = await GoogleMaps.PlacesFind.QueryAsync(request); 45 | 46 | //FormattedAddress should be null since it wasn't requested 47 | Assert.That(result.Candidates, Is.Not.Empty); 48 | Assert.That(result.Candidates.FirstOrDefault()?.FormattedAddress, Is.Null); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/PlacesNearByTests.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using GoogleMapsApi.Entities.PlacesNearBy.Request; 3 | using GoogleMapsApi.Entities.PlacesNearBy.Response; 4 | using GoogleMapsApi.Test.Utils; 5 | using NUnit.Framework; 6 | using System; 7 | using System.Linq; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | namespace GoogleMapsApi.Test.IntegrationTests 12 | { 13 | [TestFixture] 14 | public class PlacesNearByTests : BaseTestIntegration 15 | { 16 | [Test] 17 | public async Task ReturnsNearbySearchRequest() 18 | { 19 | var request = new PlacesNearByRequest 20 | { 21 | ApiKey = ApiKey, 22 | Keyword = "pizza", 23 | Radius = 10000, 24 | Location = new Location(47.611162, -122.337644), //Seattle, Washington, USA 25 | }; 26 | 27 | PlacesNearByResponse result = await GoogleMaps.PlacesNearBy.QueryAsync(request); 28 | 29 | AssertInconclusive.NotExceedQuota(result); 30 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 31 | Assert.That(result.Results.Count(), Is.GreaterThan(5)); 32 | } 33 | 34 | [Test] 35 | [Ignore("Need to fix it")] 36 | public async Task TestNearbySearchType() 37 | { 38 | var request = new PlacesNearByRequest 39 | { 40 | ApiKey = ApiKey, 41 | Radius = 10000, 42 | Location = new Location(40.6782552, -73.8671761), // New York 43 | Type = "airport", 44 | }; 45 | 46 | PlacesNearByResponse result = await GoogleMaps.PlacesNearBy.QueryAsync(request); 47 | 48 | AssertInconclusive.NotExceedQuota(result); 49 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 50 | Assert.That(result.Results.Any(), Is.True); 51 | Assert.That(result.Results.Any(t => t.Name.Contains("John F. Kennedy")), Is.True); 52 | } 53 | 54 | [Test] 55 | public async Task TestNearbySearchPagination() 56 | { 57 | var request = new PlacesNearByRequest 58 | { 59 | ApiKey = ApiKey, 60 | Keyword = "pizza", 61 | Radius = 10000, 62 | Location = new Location(47.611162, -122.337644), //Seattle, Washington, USA 63 | }; 64 | 65 | PlacesNearByResponse result = await GoogleMaps.PlacesNearBy.QueryAsync(request); 66 | 67 | AssertInconclusive.NotExceedQuota(result); 68 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 69 | //we should have more than one page of pizza results from the NearBy Search 70 | Assert.That(!String.IsNullOrEmpty(result.NextPage), Is.True); 71 | //a full page of results is always 20 72 | Assert.That(result.Results.Count(), Is.EqualTo(20)); 73 | var resultFromFirstPage = result.Results.FirstOrDefault(); //hold onto this 74 | 75 | //get the second page of results. Delay request by 2 seconds 76 | //Google API requires a short processing window to develop the second page. See Google API docs for more info on delay. 77 | 78 | Thread.Sleep(2000); 79 | request = new PlacesNearByRequest 80 | { 81 | ApiKey = ApiKey, 82 | Keyword = "pizza", 83 | Radius = 10000, 84 | Location = new Location(47.611162, -122.337644), //Seattle, Washington, USA 85 | PageToken = result.NextPage 86 | }; 87 | result = await GoogleMaps.PlacesNearBy.QueryAsync(request); 88 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 89 | //make sure the second page has some results 90 | Assert.That(result.Results != null && result.Results.Any(), Is.True); 91 | //make sure the result from the first page isn't on the second page to confirm we actually got a second page with new results 92 | Assert.That(result.Results, Is.Not.Null); 93 | Assert.That(resultFromFirstPage, Is.Not.Null); 94 | Assert.That(result.Results.Any(t => t.PlaceId == resultFromFirstPage.PlaceId), Is.False); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/PlacesSearchTests.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using GoogleMapsApi.Entities.Places.Request; 3 | using GoogleMapsApi.Entities.Places.Response; 4 | using GoogleMapsApi.Test.Utils; 5 | using NUnit.Framework; 6 | using System; 7 | using System.Linq; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | namespace GoogleMapsApi.Test.IntegrationTests 12 | { 13 | [TestFixture] 14 | public class PlacesSearchTests : BaseTestIntegration 15 | { 16 | [Test] 17 | public async Task ReturnsNearbySearchRequest() 18 | { 19 | var request = new PlacesRequest 20 | { 21 | ApiKey = ApiKey, 22 | Keyword = "pizza", 23 | Radius = 10000, 24 | Location = new Location(47.611162, -122.337644), //Seattle, Washington, USA 25 | }; 26 | 27 | PlacesResponse result = await GoogleMaps.Places.QueryAsync(request); 28 | 29 | AssertInconclusive.NotExceedQuota(result); 30 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 31 | Assert.That(result.Results.Count(), Is.GreaterThan(5)); 32 | } 33 | 34 | [Test] 35 | [Ignore("Need to fix it")] 36 | public async Task TestNearbySearchType() 37 | { 38 | var request = new PlacesRequest 39 | { 40 | ApiKey = ApiKey, 41 | Radius = 10000, 42 | Location = new Location(40.6782552, -73.8671761), // New York 43 | Type = "airport" 44 | }; 45 | 46 | PlacesResponse result = await GoogleMaps.Places.QueryAsync(request); 47 | 48 | AssertInconclusive.NotExceedQuota(result); 49 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 50 | Assert.That(result.Results.Any(), Is.True); 51 | Assert.That(result.Results.Any(t => t.Name.Contains("John F. Kennedy")), Is.True); 52 | } 53 | 54 | [Test] 55 | public async Task TestNearbySearchPagination() 56 | { 57 | var request = new PlacesRequest 58 | { 59 | ApiKey = ApiKey, 60 | Keyword = "pizza", 61 | Radius = 10000, 62 | Location = new Location(47.611162, -122.337644), //Seattle, Washington, USA 63 | }; 64 | 65 | PlacesResponse result = await GoogleMaps.Places.QueryAsync(request); 66 | 67 | AssertInconclusive.NotExceedQuota(result); 68 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 69 | //we should have more than one page of pizza results from the NearBy Search 70 | Assert.That(!String.IsNullOrEmpty(result.NextPage), Is.True); 71 | //a full page of results is always 20 72 | Assert.That(result.Results.Count(), Is.EqualTo(20)); 73 | var resultFromFirstPage = result.Results.FirstOrDefault(); //hold onto this 74 | 75 | //get the second page of results. Delay request by 2 seconds 76 | //Google API requires a short processing window to develop the second page. See Google API docs for more info on delay. 77 | 78 | Thread.Sleep(2000); 79 | request = new PlacesRequest 80 | { 81 | ApiKey = ApiKey, 82 | Keyword = "pizza", 83 | Radius = 10000, 84 | Location = new Location(47.611162, -122.337644), //Seattle, Washington, USA 85 | PageToken = result.NextPage 86 | }; 87 | result = await GoogleMaps.Places.QueryAsync(request); 88 | 89 | AssertInconclusive.NotExceedQuota(result); 90 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 91 | //make sure the second page has some results 92 | Assert.That(result.Results != null && result.Results.Any(), Is.True); 93 | //make sure the result from the first page isn't on the second page to confirm we actually got a second page with new results 94 | Assert.That(result.Results, Is.Not.Null); 95 | Assert.That(resultFromFirstPage, Is.Not.Null); 96 | Assert.That(result.Results.Any(t => t.PlaceId == resultFromFirstPage.PlaceId), Is.False); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/PlacesTextTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using GoogleMapsApi.Entities.PlacesText.Request; 3 | using GoogleMapsApi.Entities.PlacesText.Response; 4 | using NUnit.Framework; 5 | using GoogleMapsApi.Test.Utils; 6 | using System.Threading.Tasks; 7 | 8 | namespace GoogleMapsApi.Test.IntegrationTests 9 | { 10 | [TestFixture] 11 | public class PlacesTextTests : BaseTestIntegration 12 | { 13 | [Test] 14 | public async Task ReturnsFormattedAddress() 15 | { 16 | var request = new PlacesTextRequest 17 | { 18 | ApiKey = ApiKey, 19 | Query = "1 smith st parramatta", 20 | Types = "address" 21 | }; 22 | 23 | PlacesTextResponse result = await GoogleMaps.PlacesText.QueryAsync(request); 24 | 25 | AssertInconclusive.NotExceedQuota(result); 26 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 27 | Assert.That(result.Results.First().FormattedAddress, Is.EqualTo("1 Smith St, Parramatta NSW 2150, Australia")); 28 | } 29 | 30 | [Test] 31 | public async Task ReturnsPhotos() 32 | { 33 | var request = new PlacesTextRequest 34 | { 35 | ApiKey = ApiKey, 36 | Query = "1600 Pennsylvania Ave NW", 37 | Types = "address" 38 | }; 39 | 40 | PlacesTextResponse result = await GoogleMaps.PlacesText.QueryAsync(request); 41 | 42 | AssertInconclusive.NotExceedQuota(result); 43 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 44 | Assert.That(result.Results, Is.Not.Null.And.Not.Empty); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/IntegrationTests/TimeZoneTests.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using GoogleMapsApi.Entities.TimeZone.Request; 3 | using GoogleMapsApi.Entities.TimeZone.Response; 4 | using GoogleMapsApi.Test.Utils; 5 | using NUnit.Framework; 6 | using System.Threading.Tasks; 7 | 8 | namespace GoogleMapsApi.Test.IntegrationTests 9 | { 10 | [TestFixture] 11 | public class TimeZoneTests : BaseTestIntegration 12 | { 13 | [Test] 14 | [Ignore("Need to fix it")] 15 | public async Task TimeZone_Correct_OverviewPath() 16 | { 17 | var request = new TimeZoneRequest 18 | { 19 | ApiKey = ApiKey, 20 | Location = new Location(55.866413, 12.501063), 21 | Language = "en" 22 | }; 23 | 24 | TimeZoneResponse result = await GoogleMaps.TimeZone.QueryAsync(request); 25 | 26 | AssertInconclusive.NotExceedQuota(result); 27 | Assert.That(result.Status, Is.EqualTo(Status.OK)); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /GoogleMapsApi.Test/LocationToStringTest.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using NUnit.Framework; 3 | 4 | namespace GoogleMapsApi.Test 5 | { 6 | [TestFixture] 7 | public class LocationToStringTest 8 | { 9 | [Test] 10 | public void WhenNearZeroLongitude_ExpectCorrectToString() 11 | { 12 | // Longitude of 0.000009 is converted to 9E-06 using Invariant ToString, but we need 0.000009 13 | var location = new Location(57.231d, 0.000009d); 14 | Assert.That(location.ToString(), Is.EqualTo("57.231,0.000009")); 15 | } 16 | 17 | [Test] 18 | public void WhenZeroLongitude_ExpectCorrectToString() 19 | { 20 | // Longitude of 0.000009 is converted to 9E-06 using Invariant ToString, but we need 0.000009 21 | var location = new Location(52.123123d, 0.0d); 22 | Assert.That(location.ToString(), Is.EqualTo("52.123123,0.0")); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/StaticMaps.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using GoogleMapsApi.Entities.Common; 3 | using GoogleMapsApi.StaticMaps; 4 | using GoogleMapsApi.StaticMaps.Entities; 5 | using GoogleMapsApi.StaticMaps.Enums; 6 | using NUnit.Framework; 7 | 8 | namespace GoogleMapsApi.Test 9 | { 10 | /// 11 | /// Tests examples from - http://code.google.com/apis/maps/documentation/staticmaps/ 12 | /// 13 | [TestFixture] 14 | public class StaticMaps 15 | { 16 | [Test(Description = "First basic example")] 17 | public void BasicTest() 18 | { 19 | // downtown New York City 20 | StaticMapRequest request = new( 21 | new AddressLocation("Brooklyn Bridge,New York,NY"), 14, new ImageSize(512, 512)) 22 | { 23 | MapType = MapType.Roadmap, 24 | Markers = 25 | new List 26 | { 27 | new Marker 28 | { 29 | Style = new MarkerStyle { Color = "blue", Label = "S" }, 30 | Locations = new List { new Location(40.702147, -74.015794) } 31 | }, 32 | new Marker 33 | { 34 | Style = new MarkerStyle { Color = "green", Label = "G" }, 35 | Locations = new List { new Location(40.711614, -74.012318) } 36 | }, 37 | new Marker 38 | { 39 | Style = new MarkerStyle { Color = "red", Label = "C" }, 40 | Locations = new List { new Location(40.718217, -73.998284) } 41 | } 42 | } 43 | }; 44 | string expectedResult = "http://maps.google.com/maps/api/staticmap" + 45 | "?center=Brooklyn%20Bridge%2CNew%20York%2CNY&zoom=14&size=512x512&maptype=roadmap" + 46 | "&markers=color%3Ablue%7Clabel%3AS%7C40.702147%2C-74.015794&markers=color%3Agreen%7Clabel%3AG%7C40.711614%2C-74.012318" + 47 | "&markers=color%3Ared%7Clabel%3AC%7C40.718217%2C-73.998284"; 48 | 49 | string generateStaticMapURL = new StaticMapsEngine().GenerateStaticMapURL(request); 50 | 51 | // Updated Assertion 52 | Assert.That(generateStaticMapURL, Is.EqualTo(expectedResult)); 53 | } 54 | 55 | [Test] 56 | public void AddressTest() 57 | { 58 | var request = new StaticMapRequest(new AddressLocation("Berkeley,CA"), 14, new ImageSize(400, 400)); 59 | string expectedResult = "http://maps.google.com/maps/api/staticmap" + 60 | "?center=Berkeley%2CCA&zoom=14&size=400x400"; 61 | 62 | string generateStaticMapURL = new StaticMapsEngine().GenerateStaticMapURL(request); 63 | 64 | // Updated Assertion 65 | Assert.That(generateStaticMapURL, Is.EqualTo(expectedResult)); 66 | } 67 | 68 | [Test] 69 | public void ZoomLevels() 70 | { 71 | var request = new StaticMapRequest(new Location(40.714728, -73.998672), 12, new ImageSize(400, 400)); 72 | string expectedResult = "http://maps.google.com/maps/api/staticmap" + 73 | "?center=40.714728%2C-73.998672&zoom=12&size=400x400"; 74 | 75 | string generateStaticMapURL = new StaticMapsEngine().GenerateStaticMapURL(request); 76 | 77 | // Updated Assertion 78 | Assert.That(generateStaticMapURL, Is.EqualTo(expectedResult)); 79 | } 80 | 81 | [Test] 82 | public void ImageSize() 83 | { 84 | var request = new StaticMapRequest(new Location(0, 0), 1, new ImageSize(400, 50)); 85 | string expectedResult = "http://maps.google.com/maps/api/staticmap" + 86 | "?center=0.0%2C0.0&zoom=1&size=400x50"; 87 | 88 | string generateStaticMapURL = new StaticMapsEngine().GenerateStaticMapURL(request); 89 | 90 | // Updated Assertion 91 | Assert.That(generateStaticMapURL, Is.EqualTo(expectedResult)); 92 | } 93 | 94 | 95 | [Test] 96 | public void MapTypes() 97 | { 98 | var request = new StaticMapRequest(new Location(40.714728, -73.998672), 12, new ImageSize(400, 400)) 99 | { 100 | MapType = MapType.Terrain 101 | }; 102 | 103 | string expectedResult = @"http://maps.google.com/maps/api/staticmap" + 104 | @"?center=40.714728%2C-73.998672&zoom=12&size=400x400&maptype=terrain"; 105 | 106 | string actualResult = new StaticMapsEngine().GenerateStaticMapURL(request); 107 | 108 | // Updated Assertion 109 | Assert.That(actualResult, Is.EqualTo(expectedResult)); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/UnixTimeConverterTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using GoogleMapsApi.Engine; 4 | 5 | namespace GoogleMapsApi.Test 6 | { 7 | [TestFixture] 8 | public class UnixTimeConverterTest 9 | { 10 | [Test] 11 | public void DateTimeToUnixTimestamp_Zero_ExpectedResult() 12 | { 13 | var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 14 | const int expected = 0; 15 | 16 | // Updated Assertions 17 | Assert.That(UnixTimeConverter.DateTimeToUnixTimestamp(epoch), Is.EqualTo(expected)); 18 | Assert.That(UnixTimeConverter.DateTimeToUnixTimestamp(epoch.ToLocalTime()), Is.EqualTo(expected)); 19 | } 20 | 21 | [Test] 22 | public void DateTimeToUnixTimestamp_DST_ExpectedResult() 23 | { 24 | var dst = new DateTime(2016, 4, 4, 10, 0, 0, DateTimeKind.Utc); 25 | const int expected = 1459764000; 26 | 27 | // Updated Assertions 28 | Assert.That(UnixTimeConverter.DateTimeToUnixTimestamp(dst), Is.EqualTo(expected)); 29 | Assert.That(UnixTimeConverter.DateTimeToUnixTimestamp(dst.ToLocalTime()), Is.EqualTo(expected)); 30 | } 31 | 32 | [Test] 33 | public void DateTimeToUnixTimestamp_NonDST_ExpectedResult() 34 | { 35 | var nonDst = new DateTime(2016, 3, 1, 11, 0, 0, DateTimeKind.Utc); 36 | const int expected = 1456830000; 37 | 38 | // Updated Assertions 39 | Assert.That(UnixTimeConverter.DateTimeToUnixTimestamp(nonDst), Is.EqualTo(expected)); 40 | Assert.That(UnixTimeConverter.DateTimeToUnixTimestamp(nonDst.ToLocalTime()), Is.EqualTo(expected)); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /GoogleMapsApi.Test/Utils/AppSettings.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GoogleMapsApi.Test.Utils 9 | { 10 | internal class AppSettings 11 | { 12 | [JsonProperty(PropertyName ="GOOGLE_API_KEY")] 13 | public string? GoogleApiKey { get; set; } 14 | 15 | public static AppSettings? Load() 16 | { 17 | var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"); 18 | if (!File.Exists(path)) return null; 19 | return JsonConvert.DeserializeObject(File.ReadAllText(path)); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /GoogleMapsApi.Test/appsettings.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "GOOGLE_API_KEY": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 3 | } -------------------------------------------------------------------------------- /GoogleMapsApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31808.319 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GoogleMapsApi.Test", "GoogleMapsApi.Test\GoogleMapsApi.Test.csproj", "{AD9AD8E9-0E2C-470E-9004-373679F9D954}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{950E065F-B61E-4C05-8C74-5F03946AD7E2}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{9D09CCCC-6AFA-41EA-BFB3-4698FC5830E6}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "artifacts", "artifacts", "{2A90AB7E-F3EC-48BD-974E-41F34A80E714}" 13 | ProjectSection(SolutionItems) = preProject 14 | LICENSE.md = LICENSE.md 15 | README.md = README.md 16 | EndProjectSection 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GoogleMapsApi", "GoogleMapsApi\GoogleMapsApi.csproj", "{61E9FC82-47B0-43C3-8749-95D3A9967060}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Debug|Mixed Platforms = Debug|Mixed Platforms 24 | Debug|x86 = Debug|x86 25 | Release|Any CPU = Release|Any CPU 26 | Release|Mixed Platforms = Release|Mixed Platforms 27 | Release|x86 = Release|x86 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 33 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 34 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU 35 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Debug|x86.ActiveCfg = Debug|Any CPU 36 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 39 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Release|Mixed Platforms.Build.0 = Release|Any CPU 40 | {AD9AD8E9-0E2C-470E-9004-373679F9D954}.Release|x86.ActiveCfg = Release|Any CPU 41 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 44 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 45 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Debug|x86.ActiveCfg = Debug|Any CPU 46 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Debug|x86.Build.0 = Debug|Any CPU 47 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 50 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Release|Mixed Platforms.Build.0 = Release|Any CPU 51 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Release|x86.ActiveCfg = Release|Any CPU 52 | {61E9FC82-47B0-43C3-8749-95D3A9967060}.Release|x86.Build.0 = Release|Any CPU 53 | EndGlobalSection 54 | GlobalSection(SolutionProperties) = preSolution 55 | HideSolutionNode = FALSE 56 | EndGlobalSection 57 | GlobalSection(NestedProjects) = preSolution 58 | {AD9AD8E9-0E2C-470E-9004-373679F9D954} = {9D09CCCC-6AFA-41EA-BFB3-4698FC5830E6} 59 | {61E9FC82-47B0-43C3-8749-95D3A9967060} = {950E065F-B61E-4C05-8C74-5F03946AD7E2} 60 | EndGlobalSection 61 | GlobalSection(ExtensibilityGlobals) = postSolution 62 | SolutionGuid = {061AA237-7231-49DE-835A-296ED94715C4} 63 | EndGlobalSection 64 | EndGlobal 65 | -------------------------------------------------------------------------------- /GoogleMapsApi/Engine/MapsAPIGenericEngine.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.IO; 5 | using System.Net; 6 | using System.Net.Http; 7 | using System.Runtime.Serialization.Json; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using System.Text; 11 | 12 | namespace GoogleMapsApi.Engine 13 | { 14 | public delegate Uri UriCreatedDelegate(Uri uri); 15 | public delegate void RawResponseReceivedDelegate(byte[] data); 16 | 17 | public abstract class MapsAPIGenericEngine 18 | where TRequest : MapsBaseRequest, new() 19 | where TResponse : IResponseFor 20 | { 21 | internal static event UriCreatedDelegate OnUriCreated; 22 | internal static event RawResponseReceivedDelegate OnRawResponseReceived; 23 | 24 | private static readonly HttpClient client = new HttpClient(); 25 | 26 | protected internal static async Task QueryGoogleAPIAsync(TRequest request, TimeSpan timeout, CancellationToken token = default) 27 | { 28 | if (request == null) 29 | throw new ArgumentNullException(nameof(request)); 30 | 31 | var requstUri = request.GetUri(); 32 | var uri = OnUriCreated?.Invoke(requstUri) ?? requstUri; 33 | 34 | var response = await client.DownloadDataTaskAsyncAsString(uri, timeout, token).ConfigureAwait(false); 35 | 36 | OnRawResponseReceived?.Invoke(Encoding.UTF8.GetBytes(response)); 37 | 38 | return JsonConvert.DeserializeObject(response); 39 | } 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Engine/UnixTimeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GoogleMapsApi.Engine 4 | { 5 | public static class UnixTimeConverter 6 | { 7 | private static DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 8 | 9 | /// 10 | /// Converts a DateTime to a Unix timestamp 11 | /// 12 | public static int DateTimeToUnixTimestamp(DateTime dateTime) 13 | { 14 | return (int)(dateTime.ToUniversalTime() - epoch).TotalSeconds; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/AddressLocation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GoogleMapsApi.Entities.Common 4 | { 5 | public class AddressLocation : ILocationString 6 | { 7 | public string Address { get; private set; } 8 | 9 | public AddressLocation(string address) 10 | { 11 | Address = address; 12 | } 13 | 14 | public string LocationString 15 | { 16 | get { return Address; } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/ILocationString.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.Common 2 | { 3 | public interface ILocationString 4 | { 5 | string LocationString { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/IResponseFor.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.Common 2 | { 3 | public interface IResponseFor where T : MapsBaseRequest { } 4 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/Location.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Common 5 | { 6 | [DataContract] 7 | public class Location : ILocationString 8 | { 9 | [DataMember(Name = "lat")] 10 | public double Latitude { get; set; } 11 | 12 | [DataMember(Name = "lng")] 13 | public double Longitude { get; set; } 14 | 15 | public Location(double lat, double lng) 16 | { 17 | Latitude = lat; 18 | Longitude = lng; 19 | } 20 | 21 | public string LocationString 22 | { 23 | get 24 | { 25 | return ToNonScientificString(Latitude) + "," + ToNonScientificString(Longitude); 26 | } 27 | } 28 | 29 | public override string ToString() 30 | { 31 | return LocationString; 32 | } 33 | 34 | private static string ToNonScientificString(double d) 35 | { 36 | var s = d.ToString(DoubleFormat, CultureInfo.InvariantCulture).TrimEnd('0'); 37 | return s.Length == 0 ? "0.0" : s; 38 | } 39 | 40 | private static readonly string DoubleFormat = "0." + new string('#', 339); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/MapsBaseRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | using System.Net; 5 | using System.Linq; 6 | 7 | namespace GoogleMapsApi.Entities.Common 8 | { 9 | public abstract class MapsBaseRequest 10 | { 11 | public MapsBaseRequest() 12 | { 13 | this.isSsl = true; 14 | ApiKey = null; 15 | } 16 | 17 | 18 | /// 19 | /// True to indicate that request comes from a device with a location sensor, otherwise false. 20 | /// 21 | /// 22 | /// The Google Maps API previously required that you include the sensor parameter to indicate whether your application used a sensor to determine the user's location. 23 | /// This parameter is no longer required. 24 | /// See the geocoding API reference at https://developers.google.com/maps/documentation/geocoding/. 25 | /// 26 | [Obsolete] 27 | public bool Sensor { get; set; } 28 | 29 | /// 30 | /// True to use use the https protocol; false to use http. The default is false. 31 | /// 32 | public virtual bool IsSSL 33 | { 34 | get { return isSsl; } 35 | set { isSsl = value; } 36 | } 37 | private bool isSsl; 38 | 39 | 40 | protected internal virtual string BaseUrl 41 | { 42 | get 43 | { 44 | return "maps.googleapis.com/maps/api/"; 45 | } 46 | } 47 | 48 | /// 49 | /// Your application's API key. This key identifies your application for purposes of quota management and so that Places 50 | /// added from your application are made immediately available to your app. Visit the APIs Console to create an API Project and obtain your key. 51 | /// 52 | public string ApiKey { get; set; } 53 | 54 | protected virtual QueryStringParametersList GetQueryStringParameters() 55 | { 56 | QueryStringParametersList parametersList = new QueryStringParametersList(); 57 | 58 | if (!string.IsNullOrWhiteSpace(ApiKey)) 59 | { 60 | if (!this.IsSSL) 61 | { 62 | throw new ArgumentException("When using an ApiKey MUST send the request over SSL [IsSSL = true]"); 63 | } 64 | parametersList.Add("key", ApiKey); 65 | } 66 | 67 | return parametersList; 68 | } 69 | 70 | public virtual Uri GetUri() 71 | { 72 | string scheme = IsSSL ? "https://" : "http://"; 73 | 74 | var queryString = GetQueryStringParameters().GetQueryStringPostfix(); 75 | return new Uri(scheme + BaseUrl + "json?" + queryString); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/Photo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Common 5 | { 6 | /// 7 | /// Place Photo. 8 | /// 9 | [DataContract] 10 | public class Photo 11 | { 12 | /// 13 | /// PhotoReference — a string used to identify the photo when you perform a Photo request. 14 | /// 15 | [DataMember(Name = "photo_reference")] 16 | public virtual string PhotoReference { get; set; } 17 | 18 | /// 19 | /// Height — the maximum height of the image. 20 | /// 21 | [DataMember(Name = "height")] 22 | public virtual int Height { get; set; } 23 | 24 | /// 25 | /// Width — the maximum width of the image. 26 | /// 27 | [DataMember(Name = "width")] 28 | public virtual int Width { get; set; } 29 | 30 | /// 31 | /// HtmlAttributions — contains any required attributions. This field will always be present, but may be empty. 32 | /// 33 | [DataMember(Name = "html_attributions")] 34 | public virtual IEnumerable HtmlAttributions { get; set; } 35 | } 36 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/SignableRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | 8 | namespace GoogleMapsApi.Entities.Common 9 | { 10 | /// 11 | /// An abstract base class for requests that can be authenticated via URL signing. 12 | /// 13 | /// 14 | /// See https://developers.google.com/maps/documentation/business/webservices for details about signing. 15 | /// 16 | public abstract class SignableRequest : MapsBaseRequest 17 | { 18 | /// 19 | /// The client ID provided to you by Google Enterprise Support, or null to disable URL signing. All client IDs begin with a "gme-" prefix. 20 | /// 21 | public string ClientID { get; set; } 22 | 23 | /// 24 | /// A cryptographic signing key (secret shared key), in base64url format, provided to you by Google Enterprise Support. 25 | /// The key will only be used if the ClientID property is set, otherwise it will be ignored. 26 | /// 27 | /// 28 | /// This cryptographic signing key is not the same as the (freely available) Maps API key (typically beginning with 'ABQ..') 29 | /// that developers without a Maps API for Business license are required to use when loading the Maps JavaScript API V2 and 30 | /// Maps API for Flash, or the keys issued by the Google APIs Console for use with the Google Places API. 31 | /// 32 | public string SigningKey { get; set; } 33 | 34 | /// 35 | /// Add the channel parameter to requests so you can view more detailed usage reports when using a Premium Plan 36 | /// 37 | public string Channel { get; set; } 38 | 39 | public override Uri GetUri() 40 | { 41 | if (ClientID != null) 42 | return Sign(base.GetUri()); 43 | 44 | return base.GetUri(); 45 | } 46 | 47 | /// 48 | /// Based on the C# sample from: https://developers.google.com/maps/documentation/business/webservices 49 | /// 50 | internal Uri Sign(Uri uri) 51 | { 52 | if (uri == null) 53 | throw new ArgumentNullException("uri"); 54 | if (ClientID == null) 55 | throw new ArgumentNullException("userID"); 56 | if (string.IsNullOrWhiteSpace(SigningKey)) 57 | throw new ArgumentException("Invalid signing key."); 58 | if (!ClientID.StartsWith("gme-")) 59 | throw new ArgumentException("A user ID must start with 'gme-'."); 60 | 61 | var urlSegmentToSign = uri.LocalPath + uri.Query + "&client=" + ClientID; 62 | 63 | if (!string.IsNullOrWhiteSpace(Channel)) 64 | urlSegmentToSign += "&channel=" + Channel; 65 | 66 | byte[] privateKey = FromBase64UrlString(SigningKey); 67 | byte[] signature; 68 | 69 | using (var algorithm = new HMACSHA1(privateKey)) 70 | { 71 | signature = algorithm.ComputeHash(Encoding.ASCII.GetBytes(urlSegmentToSign)); 72 | } 73 | 74 | return new Uri(uri.Scheme + "://" + uri.Host + urlSegmentToSign + "&signature=" + ToBase64UrlString(signature)); 75 | } 76 | 77 | private static byte[] FromBase64UrlString(string base64UrlString) 78 | { 79 | return Convert.FromBase64String(base64UrlString.Replace("-", "+").Replace("_", "/")); 80 | } 81 | 82 | private static string ToBase64UrlString(byte[] data) 83 | { 84 | return Convert.ToBase64String(data).Replace("+", "-").Replace("/", "_"); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Common/Type.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Common 4 | { 5 | [DataContract] 6 | public enum LocationType 7 | { 8 | [EnumMember(Value = "street_address")] 9 | StreetAddress,// indicates a precise street address. 10 | [EnumMember(Value = "route")] 11 | Route,// indicates a named route (such as "US 101"). 12 | [EnumMember(Value = "intersection")] 13 | Intersection,// indicates a major intersection, usually of two major roads. 14 | [EnumMember(Value = "political")] 15 | Political,// indicates a political entity. Usually, this type indicates a polygon of some civil administration. 16 | [EnumMember(Value = "country")] 17 | Country,// indicates the national political entity, and is typically the highest order type returned by the Geocoder. 18 | [EnumMember(Value = "administrative_area_level_1")] 19 | AdministrativeAreaLevel1,// indicates a first-order civil entity below the country level. Within the United States, these administrative levels are states. Not all nations exhibit these administrative levels. 20 | [EnumMember(Value = "administrative_area_level_2")] 21 | AdministrativeAreaLevel2, // indicates a second-order civil entity below the country level. Within the United States, these administrative levels are counties. Not all nations exhibit these administrative levels. 22 | [EnumMember(Value = "administrative_area_level_3")] 23 | AdministrativeAreaLevel3, // indicates a third-order civil entity below the country level. This type indicates a minor civil division. Not all nations exhibit these administrative levels. 24 | [EnumMember(Value = "colloquial_area")] 25 | ColloquialArea, // indicates a commonly-used alternative name for the entity. 26 | [EnumMember(Value = "locality")] 27 | Locality, // indicates an incorporated city or town political entity. 28 | [EnumMember(Value = "sublocality")] 29 | Sublocality, // indicates an first-order civil entity below a locality 30 | [EnumMember(Value = "neighborhood")] 31 | Neighborhood, // indicates a named neighborhood 32 | [EnumMember(Value = "premise")] 33 | Premise, // indicates a named location, usually a building or collection of buildings with a common name 34 | [EnumMember(Value = "subpremise")] 35 | Subpremise, // indicates a first-order entity below a named location, usually a singular building within a collection of buildings with a common name 36 | [EnumMember(Value = "postal_code")] 37 | PostalCode, // indicates a postal code as used to address postal mail within the country. 38 | [EnumMember(Value = "natural_feature")] 39 | NaturalFeature, // indicates a prominent natural feature. 40 | [EnumMember(Value = "airport")] 41 | Airport, // indicates an airport. 42 | [EnumMember(Value = "park")] 43 | Park, // indicates a named park. 44 | [EnumMember(Value = "point_of_interest")] 45 | PointOfInterest, // indicates a named point of interest. Typically, these "POI"s are prominent local entities that don't easily fit in another category such as "Empire State Building" or "Statue of Liberty." 46 | //In addition to the above, address components may exhibit the following types: 47 | [EnumMember(Value = "post_box")] 48 | PostBox,// indicates a specific postal box. 49 | [EnumMember(Value = "street_number")] 50 | StreetNumber, // indicates the precise street number. 51 | [EnumMember(Value = "floor")] 52 | Floor, // indicates the floor of a building address. 53 | [EnumMember(Value = "room")] 54 | Room // indicates the room of a building address. 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Request/AvoidWay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GoogleMapsApi.Entities.Directions.Request 4 | { 5 | [Flags] 6 | public enum AvoidWay 7 | { 8 | Nothing = 0x0, 9 | Tolls = 0x1, 10 | Highways = 0x2, 11 | Ferries = 0x3, 12 | Indoor = 0x4 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Request/TravelMode.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.Directions.Request 2 | { 3 | public enum TravelMode 4 | { 5 | Driving, 6 | Walking, 7 | Bicycling, 8 | Transit 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/DirectionsResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using GoogleMapsApi.Entities.Common; 6 | using GoogleMapsApi.Entities.Directions.Request; 7 | 8 | namespace GoogleMapsApi.Entities.Directions.Response 9 | { 10 | [DataContract(Name = "DirectionsResponse")] 11 | public class DirectionsResponse : IResponseFor 12 | { 13 | /// 14 | /// Error message received from the server when the call fails 15 | /// 16 | /// Error message 17 | [DataMember(Name = "error_message")] 18 | public string ErrorMessage { get; set; } 19 | 20 | [DataMember(Name = "status")] 21 | public string StatusStr 22 | { 23 | get 24 | { 25 | return Status.ToString(); 26 | } 27 | set 28 | { 29 | Status = (DirectionsStatusCodes)Enum.Parse(typeof(DirectionsStatusCodes), value); 30 | } 31 | } 32 | 33 | /// 34 | /// "status" contains metadata on the request. See Status Codes below. 35 | /// 36 | public DirectionsStatusCodes Status { get; set; } 37 | 38 | /// 39 | /// "routes" contains an array of routes from the origin to the destination. See Routes below. 40 | /// 41 | [DataMember(Name = "routes")] 42 | public IEnumerable Routes { get; set; } 43 | 44 | 45 | public override string ToString() 46 | { 47 | return string.Format("DirectionsResponse - Status: {0}, Results count: {1}", Status, Routes != null ? Routes.Count() : 0); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Distance.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Directions.Response 4 | { 5 | [DataContract(Name = "distance")] 6 | public class Distance 7 | { 8 | /// 9 | /// value indicates the distance in meters 10 | /// 11 | [DataMember(Name = "value")] 12 | public int Value { get; set; } 13 | 14 | /// 15 | /// text contains a human-readable representation of the distance, displayed in units as used at the origin, in the language specified in the request. (For example, miles and feet will be used for any origin within the United States.) Note that regardless of what unit system is displayed as text, the distance.value field always contains a value expressed in meters. 16 | /// 17 | [DataMember(Name = "text")] 18 | public string Text { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Duration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Directions.Response 5 | { 6 | /// 7 | /// duration indicates the total duration of this leg 8 | /// These fields may be absent if the duration is unknown. 9 | /// 10 | [DataContract(Name = "duration")] 11 | public class Duration 12 | { 13 | [DataMember(Name = "value")] 14 | internal int ValueInSec 15 | { 16 | get 17 | { 18 | return (int)Math.Round(Value.TotalSeconds); 19 | } 20 | set 21 | { 22 | Value = TimeSpan.FromSeconds(value); 23 | } 24 | } 25 | 26 | /// 27 | /// value indicates the duration in seconds. 28 | /// 29 | public TimeSpan Value { get; set; } 30 | 31 | /// 32 | /// text contains a human-readable representation of the duration. 33 | /// 34 | [DataMember(Name = "text")] 35 | public string Text { get; set; } 36 | 37 | [DataMember(Name = "time_zone")] 38 | public string TimeZone { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Leg.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | using GoogleMapsApi.Entities.Common; 4 | 5 | namespace GoogleMapsApi.Entities.Directions.Response 6 | { 7 | /// 8 | /// Each element in the legs array specifies a single leg of the journey from the origin to the destination in the calculated route. For routes that contain no waypoints, the route will consist of a single "leg," but for routes that define one or more waypoints, the route will consist of one or more legs, corresponding to the specific legs of the journey. 9 | /// 10 | [DataContract(Name = "leg")] 11 | public class Leg 12 | { 13 | /// 14 | /// steps[] contains an array of steps denoting information about each separate step of the leg of the journey. (See Directions Steps below.) 15 | /// 16 | [DataMember(Name = "steps")] 17 | public IEnumerable Steps { get; set; } 18 | 19 | /// 20 | /// distance indicates the total distance covered by this leg 21 | /// 22 | [DataMember(Name = "distance")] 23 | public Distance Distance { get; set; } 24 | 25 | /// 26 | /// duration indicates the total duration of this leg, 27 | /// 28 | [DataMember(Name = "duration")] 29 | public Duration Duration { get; set; } 30 | 31 | /// 32 | /// duration_in_traffic indicates the total duration of this leg. This value is an estimate of the time in traffic based on current and historical traffic conditions. 33 | /// 34 | [DataMember(Name = "duration_in_traffic")] 35 | public Duration DurationInTraffic { get; set; } 36 | 37 | /// 38 | /// start_location contains the latitude/longitude coordinates of the origin of this leg. Because the Directions API calculates directions between locations by using the nearest transportation option (usually a road) at the start and end points, start_location may be different than the provided origin of this leg if, for example, a road is not near the origin. 39 | /// 40 | [DataMember(Name = "start_location")] 41 | public Location StartLocation { get; set; } 42 | 43 | /// 44 | /// end_location contains the latitude/longitude coordinates of the given destination of this leg. Because the Directions API calculates directions between locations by using the nearest transportation option (usually a road) at the start and end points, end_location may be different than the provided destination of this leg if, for example, a road is not near the destination. 45 | /// 46 | [DataMember(Name = "end_location")] 47 | public Location EndLocation { get; set; } 48 | 49 | /// 50 | /// start_address contains the human-readable address (typically a street address) reflecting the start_location of this leg. 51 | /// 52 | [DataMember(Name = "start_address")] 53 | public string StartAddress { get; set; } 54 | 55 | /// 56 | /// end_addresss contains the human-readable address (typically a street address) reflecting the end_location of this leg. 57 | /// 58 | [DataMember(Name = "end_address")] 59 | public string EndAddress { get; set; } 60 | 61 | /// 62 | /// The time of arrival. Only avaliable when using TravelMode = Transit 63 | /// 64 | [DataMember(Name = "arrival_time")] 65 | public Duration ArrivalTime { get; set; } 66 | 67 | /// 68 | /// The time of departure. Only avaliable when using TravelMode = Transit 69 | /// 70 | [DataMember(Name = "departure_time")] 71 | public Duration DepartureTime { get; set; } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Line.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Directions.Response 5 | { 6 | [DataContract(Name = "line")] 7 | public class Line 8 | { 9 | /// 10 | /// Contains the full name of this transit line. eg. "7 Avenue Express". 11 | /// 12 | [DataMember(Name = "name")] 13 | public string Name { get; set; } 14 | 15 | /// 16 | /// Contains the short name of this transit line. This will normally be a line number, such as "M7" or "355". 17 | /// 18 | [DataMember(Name = "short_name")] 19 | public string ShortName { get; set; } 20 | 21 | /// 22 | /// Contains the color commonly used in signage for this transit line. The color will be specified as a hex string such as: #FF0033. 23 | /// 24 | [DataMember(Name = "color")] 25 | public string Color { get; set; } 26 | 27 | /// 28 | /// Contains a List of TransitAgency objects that each provide information about the operator of the line. 29 | /// 30 | [DataMember(Name = "agencies")] 31 | public List Agencies { get; set; } 32 | 33 | /// 34 | /// Contains the URL for this transit line as provided by the transit agency. 35 | /// 36 | [DataMember(Name = "url")] 37 | public string Url { get; set; } 38 | 39 | /// 40 | /// Contains the URL for the icon associated with this line. 41 | /// 42 | [DataMember(Name = "icon")] 43 | public string Icon { get; set; } 44 | 45 | /// 46 | /// Contains the color of text commonly used for signage of this line. The color will be specified as a hex string. 47 | /// 48 | [DataMember(Name = "text_color")] 49 | public string TextColor { get; set; } 50 | 51 | /// 52 | /// Contains the type of vehicle used on this line. 53 | /// 54 | [DataMember(Name = "vehicle")] 55 | public Vehicle Vehicle { get; set; } 56 | } 57 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/OverviewPolyline.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | 6 | namespace GoogleMapsApi.Entities.Directions.Response 7 | { 8 | /// 9 | /// Contains the encoded and decoded data returned in the overview_polyline field. 10 | /// 11 | [DataContract] 12 | public class OverviewPolyline 13 | { 14 | /// 15 | /// The encoded string containing the overview path points as they were received. 16 | /// 17 | [DataMember(Name = "points")] 18 | internal string EncodedPoints { get; set; } 19 | 20 | private Lazy> pointsLazy; 21 | 22 | /// 23 | /// An array of Location objects representing the points in the overview path, decoded from the string contained in the EncodedPoints property. 24 | /// 25 | /// Unexpectedly couldn't decode points 26 | public IEnumerable Points { get { return pointsLazy.Value; } } 27 | 28 | public OverviewPolyline() 29 | { 30 | InitLazyPoints(default); 31 | } 32 | 33 | //NOTE that the CTOR isn't called when Deserialized so we use the Attribute 34 | [OnDeserializing] 35 | private void InitLazyPoints(StreamingContext contex) 36 | { 37 | pointsLazy = new Lazy>(DecodePoints); 38 | } 39 | 40 | // Adapted from http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java 41 | // The algorithm explained here - https://developers.google.com/maps/documentation/utilities/polylinealgorithm 42 | /// 43 | /// 44 | /// 45 | /// 46 | /// Unexpectedly couldn't decode points 47 | private IEnumerable DecodePoints() 48 | { 49 | IEnumerable points; 50 | 51 | try 52 | { 53 | var poly = new List(); 54 | int index = 0; 55 | int lat = 0; 56 | int lng = 0; 57 | 58 | while (index < EncodedPoints.Length) 59 | { 60 | int b, shift = 0, result = 0; 61 | do 62 | { 63 | b = EncodedPoints[index++] - 63; 64 | result |= (b & 0x1f) << shift; 65 | shift += 5; 66 | } while (b >= 0x20); 67 | int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 68 | lat += dlat; 69 | 70 | shift = 0; 71 | result = 0; 72 | do 73 | { 74 | b = EncodedPoints[index++] - 63; 75 | result |= (b & 0x1f) << shift; 76 | shift += 5; 77 | } while (b >= 0x20); 78 | int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 79 | lng += dlng; 80 | 81 | poly.Add(new Location(lat / 1E5, lng / 1E5)); 82 | } 83 | 84 | points = poly.ToArray(); 85 | } 86 | catch (Exception ex) 87 | { 88 | throw new PointsDecodingException("Couldn't decode points", EncodedPoints, ex); 89 | } 90 | 91 | return points; 92 | } 93 | 94 | /// 95 | /// The RAW data of points from Google 96 | /// 97 | /// 98 | public string GetRawPointsData() 99 | { 100 | return this.EncodedPoints; 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/PointsDecodingException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GoogleMapsApi.Entities.Directions.Response 4 | { 5 | public class PointsDecodingException : Exception 6 | { 7 | public string EncodedString { get; set; } 8 | 9 | public PointsDecodingException() 10 | { 11 | } 12 | 13 | public PointsDecodingException(string message) : base(message) 14 | { 15 | } 16 | 17 | public PointsDecodingException(string message, string encodedString, Exception inner) : base(message, inner) 18 | { 19 | EncodedString = encodedString; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Route.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | using GoogleMapsApi.Entities.Geocoding.Response; 4 | 5 | namespace GoogleMapsApi.Entities.Directions.Response 6 | { 7 | /// 8 | /// When the Directions API returns results, it places them within a (JSON) routes array. Even if the service returns no results (such as if the origin and/or destination doesn't exist) it still returns an empty routes array. (XML responses consist of zero or more route elements.) 9 | /// Each element of the routes array contains a single result from the specified origin and destination. This route may consist of one or more legs depending on whether any waypoints were specified. As well, the route also contains copyright and warning information which must be displayed to the user in addition to the routing information. 10 | /// 11 | [DataContract(Name = "route")] 12 | public class Route 13 | { 14 | /// 15 | /// summary contains a short textual description for the route, suitable for naming and disambiguating the route from alternatives. 16 | /// 17 | [DataMember(Name = "summary")] 18 | public string Summary { get; set; } 19 | 20 | /// 21 | /// bounds (optionally returned) contains the viewport bounding box of the overview_polyline. 22 | /// 23 | [DataMember(Name = "bounds")] 24 | public FramedLocation Bounds { get; set; } 25 | 26 | /// 27 | /// legs[] contains an array which contains information about a leg of the route, between two locations within the given route. A separate leg will be present for each waypoint or destination specified. (A route with no waypoints will contain exactly one leg within the legs array.) Each leg consists of a series of steps. (See Directions Legs below.) 28 | /// 29 | [DataMember(Name = "legs")] 30 | public IEnumerable Legs { get; set; } 31 | 32 | /// 33 | /// waypoint_order contains an array indicating the order of any waypoints in the calculated route. This waypoints may be reordered if the request was passed optimize:true within its waypoints parameter. 34 | /// 35 | [DataMember(Name = "waypoint_order")] 36 | public int[] WaypointOrder { get; set; } 37 | 38 | /// 39 | /// overview_path contains an object holding an array of encoded points and levels that represent an approximate (smoothed) path of the resulting directions. 40 | /// 41 | [DataMember(Name = "overview_polyline")] 42 | public OverviewPolyline OverviewPath { get; set; } 43 | 44 | /// 45 | /// copyrights contains the copyrights text to be displayed for this route. You must handle and display this information yourself. 46 | /// 47 | [DataMember(Name = "copyrights")] 48 | public string Copyrights { get; set; } 49 | 50 | /// 51 | /// warnings[] contains an array of warnings to be displayed when showing these directions. You must handle and display these warnings yourself. 52 | /// 53 | [DataMember(Name = "warnings")] 54 | public string[] Warnings { get; set; } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/StatusCodes.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Directions.Response 4 | { 5 | [DataContract] 6 | public enum DirectionsStatusCodes 7 | { 8 | [EnumMember] 9 | OK, // indicates the response contains a valid result. 10 | [EnumMember] 11 | NOT_FOUND, // indicates at least one of the locations specified in the requests's origin, destination, or waypoints could not be geocoded. 12 | [EnumMember] 13 | ZERO_RESULTS, // indicates no route could be found between the origin and destination. 14 | [EnumMember] 15 | MAX_WAYPOINTS_EXCEEDED, // indicates that too many waypointss were provided in the request The maximum allowed waypoints is 8, plus the origin, and destination. ( Google Maps Premier customers may contain requests with up to 23 waypoints.) 16 | [EnumMember] 17 | MAX_ROUTE_LENGTH_EXCEEDED, // indicates the requested route is too long and cannot be processed. 18 | [EnumMember] 19 | INVALID_REQUEST, // indicates that the provided request was invalid. 20 | [EnumMember] 21 | OVER_QUERY_LIMIT, // indicates the service has received too many requests from your application within the allowed time period. 22 | [EnumMember] 23 | REQUEST_DENIED, // indicates that the service denied use of the directions service by your application. 24 | [EnumMember] 25 | UNKNOWN_ERROR, // indicates a directions request could not be processed due to a server error. The request may succeed if you try again 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Step.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | using GoogleMapsApi.Entities.Directions.Request; 6 | 7 | namespace GoogleMapsApi.Entities.Directions.Response 8 | { 9 | /// 10 | /// Each element in the steps array defines a single step of the calculated directions. A step is the most atomic unit of a direction's route, containing a single step describing a specific, single instruction on the journey. E.g. "Turn left at W. 4th St." The step not only describes the instruction but also contains distance and duration information relating to how this step relates to the following step. For example, a step denoted as "Merge onto I-80 West" may contain a duration of "37 miles" and "40 minutes," indicating that the next step is 37 miles/40 minutes from this step. 11 | /// 12 | [DataContract(Name = "step")] 13 | public class Step 14 | { 15 | /// 16 | /// html_instructions contains formatted instructions for this step, presented as an HTML text string. 17 | /// 18 | [DataMember(Name = "html_instructions")] 19 | public string HtmlInstructions { get; set; } 20 | 21 | /// 22 | /// Contains an object holding an array of encoded points that represent an approximate (smoothed) path of the resulting directions. 23 | /// 24 | [DataMember(Name = "polyline")] 25 | public OverviewPolyline PolyLine { get; set; } 26 | 27 | /// 28 | /// distance contains the distance covered by this step until the next step. (See the discussion of this field in Directions Legs above.) This field may be undefined if the distance is unknown. 29 | /// 30 | [DataMember(Name = "distance")] 31 | public Distance Distance { get; set; } 32 | 33 | /// 34 | /// duration contains the typical time required to perform the step, until the next step (See the description in Directions Legs above.) This field may be undefined if the duration is unknown. 35 | /// 36 | [DataMember(Name = "duration")] 37 | public Duration Duration { get; set; } 38 | 39 | /// 40 | /// start_location contains the location of the starting point of this step, as a single set of lat and lng fields. 41 | /// 42 | [DataMember(Name = "start_location")] 43 | public Location StartLocation { get; set; } 44 | 45 | /// 46 | /// end_location contains the location of the starting point of this step, as a single set of lat and lng fields. 47 | /// 48 | [DataMember(Name = "end_location")] 49 | public Location EndLocation { get; set; } 50 | 51 | /// 52 | /// More information about the step. Only avaliable when TravelMode = Transit 53 | /// 54 | [DataMember(Name = "transit_details")] 55 | public TransitDetails TransitDetails { get; set; } 56 | 57 | /// 58 | /// Contains detailed directions for walking or driving steps in transit directions. Substeps are only available when TravelMode is set to Transit. 59 | /// * NOTE : Google documentations states that it should be 'sub_steps' but implemented as 'steps' so we use the actual implementation 60 | /// 61 | [DataMember(Name = "steps")] 62 | public IEnumerable SubSteps { get; set; } 63 | 64 | /// 65 | /// Gets the mode of transportation used in this step 66 | /// 67 | public TravelMode TravelMode { get; set; } 68 | 69 | /// 70 | /// Gets the mode of transportation used in this step 71 | /// 72 | [DataMember(Name = "travel_mode")] 73 | internal string TravelModeString 74 | { 75 | get { return TravelMode.ToString(); } 76 | set 77 | { 78 | TravelMode travelMode; 79 | if (Enum.TryParse(value, true, out travelMode)) 80 | { 81 | TravelMode = travelMode; 82 | } 83 | } 84 | } 85 | 86 | /// 87 | /// Gets the action to take for the current step (turn left, merge, straight, etc.) - Values in this list are subject to change. See documentation. 88 | /// 89 | [DataMember(Name = "maneuver")] 90 | public string Maneuver { get; set; } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Stop.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.Directions.Response 5 | { 6 | /// 7 | /// Contains information about the stop/station for this part of the trip 8 | /// 9 | [DataContract(Name = "stop")] 10 | public class Stop 11 | { 12 | /// 13 | /// The name of the transit station/stop. eg. "Union Square". 14 | /// 15 | [DataMember(Name = "name")] 16 | public string Name { get; set; } 17 | 18 | /// 19 | /// The location of the transit station/stop, represented as lattitude and longitude. 20 | /// 21 | [DataMember(Name = "location")] 22 | public Location Location { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/TransitAgency.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Directions.Response 4 | { 5 | /// 6 | /// Information about the transit agency. 7 | /// Note: You must display the names and URLs of the transit agencies servicing the trip results. 8 | /// 9 | [DataContract(Name = "TransitAgency")] 10 | public class TransitAgency 11 | { 12 | /// 13 | /// Contains the name of the transit agency. 14 | /// 15 | [DataMember(Name = "name")] 16 | public string Name { get; set; } 17 | 18 | /// 19 | /// Contains the URL for the transit agency. 20 | /// 21 | [DataMember(Name = "url")] 22 | public string Url { get; set; } 23 | 24 | /// 25 | /// Contains the phone number of the transit agency. 26 | /// 27 | [DataMember(Name = "phone")] 28 | public string Phone { get; set; } 29 | } 30 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/TransitDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Directions.Response 4 | { 5 | [DataContract(Name = "transit_details")] 6 | public class TransitDetails 7 | { 8 | /// 9 | /// Contains information about the stop/station for this part of the trip 10 | /// 11 | [DataMember(Name = "arrival_stop")] 12 | public Stop ArrivalStop { get; set; } 13 | 14 | /// 15 | /// Contains information about the stop/station for this part of the trip. 16 | /// 17 | [DataMember(Name = "departure_stop")] 18 | public Stop DepartureStop { get; set; } 19 | 20 | /// 21 | /// Contain the arrival times for this leg of the journey 22 | /// 23 | [DataMember(Name = "arrival_time")] 24 | public Duration ArrivalTime { get; set; } 25 | 26 | /// 27 | /// Contain the departure times for this leg of the journey 28 | /// 29 | [DataMember(Name = "departure_time")] 30 | public Duration DepartureTime { get; set; } 31 | 32 | /// 33 | /// Specifies the direction in which to travel on this line, as it is marked on the vehicle or at the departure stop. This will often be the terminus station. 34 | /// 35 | [DataMember(Name = "headsign")] 36 | public string Headsign { get; set; } 37 | 38 | /// 39 | /// Specifies the expected number of seconds between departures from the same stop at this time. For example, with a headway value of 600, you would expect a ten minute wait if you should miss your bus. 40 | /// 41 | [DataMember(Name = "headway")] 42 | public int Headway { get; set; } 43 | 44 | /// 45 | /// Contains the number of stops in this step, counting the arrival stop, but not the departure stop. For example, if your directions involve leaving from Stop A, passing through stops B and C, and arriving at stop D, num_stops will return 3. 46 | /// 47 | [DataMember(Name = "num_stops")] 48 | public int NumberOfStops { get; set; } 49 | 50 | /// 51 | /// Contains information about the transit line used in this step. 52 | /// 53 | [DataMember(Name = "line")] 54 | public Line Lines { get; set; } 55 | } 56 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/Vehicle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Directions.Response 5 | { 6 | [DataContract(Name = "vehicle")] 7 | public class Vehicle 8 | { 9 | /// 10 | /// Contains the name of the vehicle on this line. eg. "Subway." 11 | /// 12 | [DataMember(Name = "name")] 13 | public string Name { get; set; } 14 | 15 | /// 16 | /// Contains the type of vehicle that runs on this line. 17 | /// 18 | [DataMember(Name = "type")] 19 | public string VehicleTypeString 20 | { 21 | get => VehicleType.ToString(); 22 | set => VehicleType = Enum.TryParse(value, out VehicleType vehicleType) ? vehicleType : VehicleType.OTHER; 23 | } 24 | 25 | /// 26 | /// Contains the type of vehicle that runs on this line. 27 | /// 28 | public VehicleType VehicleType { get; set; } 29 | 30 | /// 31 | /// Contains the URL for an icon associated with this vehicle type. 32 | /// 33 | [DataMember(Name = "icon")] 34 | public string Icon { get; set; } 35 | 36 | /// 37 | /// Contains the URL for a localized icon associated with this vehicle type. 38 | /// 39 | [DataMember(Name = "local_icon")] 40 | public string LocalIcon { get; set; } 41 | } 42 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Directions/Response/VehicleType.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.Directions.Response 2 | { 3 | public enum VehicleType 4 | { 5 | /// 6 | /// All other vehicles will return this type. 7 | /// 8 | OTHER, 9 | 10 | /// 11 | /// Rail. 12 | /// 13 | RAIL, 14 | 15 | /// 16 | /// Light rail transit. 17 | /// 18 | METRO_RAIL, 19 | 20 | /// 21 | /// Underground light rail. 22 | /// 23 | SUBWAY, 24 | 25 | /// 26 | /// Above ground light rail. 27 | /// 28 | TRAM, 29 | 30 | /// 31 | /// Monorail. 32 | /// 33 | MONORAIL, 34 | 35 | /// 36 | /// Heavy rail. 37 | /// 38 | HEAVY_RAIL, 39 | 40 | /// 41 | /// Commuter rail. 42 | /// 43 | COMMUTER_TRAIN, 44 | 45 | /// 46 | /// High speed train. 47 | /// 48 | HIGH_SPEED_TRAIN, 49 | 50 | /// 51 | /// Bus. 52 | /// 53 | BUS, 54 | 55 | /// 56 | /// Intercity bus. 57 | /// 58 | INTERCITY_BUS, 59 | 60 | /// 61 | /// Trolleybus. 62 | /// 63 | TROLLEYBUS, 64 | 65 | /// 66 | /// Share taxi is a kind of bus with the ability to drop off and pick up passengers anywhere on its route. 67 | /// 68 | SHARE_TAXI, 69 | 70 | /// 71 | /// Ferry. 72 | /// 73 | FERRY, 74 | 75 | /// 76 | /// A vehicle that operates on a cable, usually on the ground. Aerial cable cars may be of the type GONDOLA_LIFT. 77 | /// 78 | CABLE_CAR, 79 | 80 | /// 81 | /// An aerial cable car. 82 | /// 83 | GONDOLA_LIFT, 84 | 85 | /// 86 | /// A vehicle that is pulled up a steep incline by a cable. A Funicular typically consists of two cars, with each car acting as a counterweight for the other. 87 | /// 88 | FUNICULAR, 89 | 90 | /// 91 | /// Not by google documented vehicle type. But returned by e.g. following directions API call: 92 | /// https://maps.googleapis.com/maps/api/directions/json?&mode=transit&origin=zurich+airport&destination=brig&departure_time=1534606200 93 | /// 94 | LONG_DISTANCE_TRAIN 95 | } 96 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Request/Restrictions.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Request 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixRestrictions 7 | { 8 | [EnumMember] 9 | tolls, 10 | [EnumMember] 11 | highways, 12 | [EnumMember] 13 | ferries, 14 | [EnumMember] 15 | indoor, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Request/Time.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace GoogleMapsApi.Entities.DistanceMatrix.Request 3 | { 4 | using System; 5 | using System.Globalization; 6 | 7 | using GoogleMapsApi.Engine; 8 | 9 | public class Time 10 | { 11 | public DateTime Value { get; set; } 12 | 13 | public bool IsNow { get; set; } 14 | 15 | public Time() 16 | { 17 | IsNow = true; 18 | } 19 | 20 | public override string ToString() 21 | { 22 | return IsNow ? "now" : UnixTimeConverter.DateTimeToUnixTimestamp(Value).ToString(CultureInfo.InvariantCulture); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Request/TrafficModel.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Request 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixTrafficModels 7 | { 8 | // To be used for 'driving' travel mode only 9 | [EnumMember] 10 | best_guess, // uses historical trafic conditions. live traffic weighted more significantly for departure times closer to now. 11 | [EnumMember] 12 | pessimistic, // returned duration in traffic should be longer than actual travel on most days. 13 | [EnumMember] 14 | optimistic, // returned duration in traffic should be shorter than actual travel on most days. 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Request/TransitMode.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Request 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixTransitModes 7 | { 8 | // To be used for 'transit' travel mode only 9 | [EnumMember] 10 | bus, // route should prefer travel by bus 11 | [EnumMember] 12 | subway, // route should prefer travel by subway 13 | [EnumMember] 14 | train, // route should prefer travel by train 15 | [EnumMember] 16 | tram, // route should prefer travel by tram or light rail 17 | [EnumMember] 18 | rail, // route should prefer travel by train, tram, light rail and subway 19 | } 20 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Request/TransitRoutingPreference.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Request 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixTransitRoutingPreferences 7 | { 8 | // To be used for 'transit' travel mode only 9 | [EnumMember] 10 | less_walking, // route should prefer limited amounts of walking 11 | [EnumMember] 12 | fewer_transfers, // route should prefer limited numbers of transfers 13 | } 14 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Request/TravelMode.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Request 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixTravelModes { 7 | [EnumMember] 8 | driving, // uses road network. 9 | [EnumMember] 10 | walking, // uses pedestrian paths (where available). 11 | [EnumMember] 12 | bicycling, // uses bicycle paths and preferred streets (where available). 13 | [EnumMember] 14 | transit, // uses public transit routes (where available). 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Request/UnitSystem.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Request 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixUnitSystems 7 | { 8 | [EnumMember] 9 | metric, // kilometers an meters. 10 | [EnumMember] 11 | imperial, // miles and feet. 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Response/Distance.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Response 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract(Name = "distance")] 6 | public class Distance 7 | { 8 | /// 9 | /// value indicates the distance in meters 10 | /// 11 | [DataMember(Name = "value")] 12 | public int Value { get; set; } 13 | 14 | /// 15 | /// text contains a human-readable representation of the distance, displayed in units as used at the origin, in the language specified in the request. (For example, miles and feet will be used for any origin within the United States.) Note that regardless of what unit system is displayed as text, the distance.value field always contains a value expressed in meters. 16 | /// 17 | [DataMember(Name = "text")] 18 | public string Text { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Response/DistanceMatrixResponse.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Response 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Runtime.Serialization; 6 | 7 | using GoogleMapsApi.Entities.Common; 8 | using GoogleMapsApi.Entities.Directions.Response; 9 | using GoogleMapsApi.Entities.DistanceMatrix.Request; 10 | 11 | [DataContract(Name = "DistanceMatrixResponse")] 12 | public class DistanceMatrixResponse: IResponseFor 13 | { 14 | [DataMember(Name = "status")] 15 | public string StatusStr 16 | { 17 | get 18 | { 19 | return Status.ToString(); 20 | } 21 | set 22 | { 23 | Status = (DistanceMatrixStatusCodes)Enum.Parse(typeof(DistanceMatrixStatusCodes), value); 24 | } 25 | } 26 | 27 | /// 28 | /// "status" contains metadata on the request. See Status Codes below. 29 | /// 30 | public DistanceMatrixStatusCodes Status { get; set; } 31 | 32 | [DataMember(Name = "rows")] 33 | public IEnumerable Rows { get; set; } 34 | 35 | [DataMember(Name = "destination_addresses")] 36 | public IEnumerable DestinationAddresses { get; set; } 37 | 38 | 39 | [DataMember(Name = "origin_addresses")] 40 | public IEnumerable OriginAddresses { get; set; } 41 | 42 | [DataMember(Name = "error_message")] 43 | public string ErrorMessage { get; set; } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Response/Duration.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Response 2 | { 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | /// 7 | /// duration indicates the total duration of this leg 8 | /// These fields may be absent if the duration is unknown. 9 | /// 10 | [DataContract(Name = "duration")] 11 | public class Duration 12 | { 13 | [DataMember(Name = "value")] 14 | internal int ValueInSec 15 | { 16 | get 17 | { 18 | return (int)Math.Round(this.Value.TotalSeconds); 19 | } 20 | set 21 | { 22 | this.Value = TimeSpan.FromSeconds(value); 23 | } 24 | } 25 | 26 | /// 27 | /// value indicates the duration in seconds. 28 | /// 29 | public TimeSpan Value { get; set; } 30 | 31 | /// 32 | /// text contains a human-readable representation of the duration. 33 | /// 34 | [DataMember(Name = "text")] 35 | public string Text { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Response/Element.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Response 2 | { 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | using GoogleMapsApi.Entities.Directions.Response; 7 | 8 | [DataContract(Name = "element")] 9 | public class Element 10 | { 11 | [DataMember(Name = "status")] 12 | public string StatusStr 13 | { 14 | get 15 | { 16 | return Status.ToString(); 17 | } 18 | set 19 | { 20 | Status = (DistanceMatrixElementStatusCodes)Enum.Parse(typeof(DistanceMatrixElementStatusCodes), value); 21 | } 22 | } 23 | 24 | /// 25 | /// "status" See Status Codes for a list of possible status codes. 26 | /// 27 | public DistanceMatrixElementStatusCodes Status { get; set; } 28 | 29 | /// 30 | /// distance: The total distance of this route, expressed in meters (value) and as text 31 | /// 32 | [DataMember(Name = "distance")] 33 | public Distance Distance { get; set; } 34 | 35 | /// 36 | /// duration: The length of time it takes to travel this route 37 | /// 38 | [DataMember(Name = "duration")] 39 | public Duration Duration { get; set; } 40 | 41 | /// 42 | /// duration_in_traffic The length of time it takes to travel this route, based on current and historical traffic conditions. 43 | /// See the traffic_model request parameter for the options you can use to request that the returned value is optimistic, pessimistic, or a best-guess estimate. 44 | /// 45 | [DataMember(Name = "duration_in_traffic")] 46 | public Duration DurationInTraffic { get; set; } 47 | 48 | 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Response/ElementStatusCodes.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Response 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixElementStatusCodes 7 | { 8 | [EnumMember] 9 | OK, // indicates the response contains a valid result. 10 | [EnumMember] 11 | NOT_FOUND, // indicates that the origin and/or destination of this pairing could not be geocoded. 12 | [EnumMember] 13 | ZERO_RESULTS, // indicates no route could be found between the origin and destination. 14 | [EnumMember] 15 | MAX_ROUTE_LENGTH_EXCEEDED // indicates the requested route is too long and cannot be processed. 16 | } 17 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Response/Row.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Response 2 | { 3 | using System.Collections.Generic; 4 | using System.Runtime.Serialization; 5 | 6 | [DataContract(Name = "row")] 7 | public class Row 8 | { 9 | /// 10 | /// element[] The information about each origin-destination pairing is returned in an element entry 11 | /// 12 | [DataMember(Name = "elements")] 13 | public IEnumerable Elements { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/DistanceMatrix/Response/StatusCodes.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.DistanceMatrix.Response 2 | { 3 | using System.Runtime.Serialization; 4 | 5 | [DataContract] 6 | public enum DistanceMatrixStatusCodes 7 | { 8 | [EnumMember] 9 | OK, // indicates the response contains a valid result. 10 | [EnumMember] 11 | NOT_FOUND,//indicates at least one of the locations specified in the request's origin, destination, or waypoints could not be geocoded. 12 | [EnumMember] 13 | ZERO_RESULTS,// indicates no route could be found between the origin and destination. 14 | [EnumMember] 15 | MAX_WAYPOINTS_EXCEEDED, // 16 | [EnumMember] 17 | MAX_ROUTE_LENGTH_EXCEEDED, // indicates the requested route is too long and cannot be processed. 18 | [EnumMember] 19 | INVALID_REQUEST, // indicates that the provided request was invalid. 20 | [EnumMember] 21 | MAX_ELEMENTS_EXCEEDED, // indicates that the product of origins and destinations exceeds the per-query limit. 22 | [EnumMember] 23 | OVER_QUERY_LIMIT, // indicates the service has received too many requests from your application within the allowed time period. 24 | [EnumMember] 25 | REQUEST_DENIED, // indicates that the service denied use of the directions service by your application. 26 | [EnumMember] 27 | UNKNOWN_ERROR, // indicates a directions request could not be processed due to a server error. The request may succeed if you try again 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Elevation/Request/ElevationRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using GoogleMapsApi.Entities.Common; 4 | using System.Linq; 5 | 6 | namespace GoogleMapsApi.Entities.Elevation.Request 7 | { 8 | //http://code.google.com/apis/maps/documentation/elevation/ 9 | 10 | /// 11 | /// The Elevation API provides elevation data for all locations on the surface of the earth, including depth locations on the ocean floor (which return negative values). In those cases where Google does not possess exact elevation measurements at the precise location you request, the service will interpolate and return an averaged value using the four nearest locations. 12 | /// With the Elevation API, you can develop hiking and biking applications, mobile positioning applications, or low resolution surveying applications. 13 | /// You access the Elevation API through an HTTP interface Users of the Google JavaScript API V3 may also access this API directly by using the ElevationService() object. (See Elevation Service for more information.) 14 | /// The Elevation API is a new service; we encourage you to join the Maps API discussion group to give us feedback. 15 | /// 16 | public class ElevationRequest : SignableRequest 17 | { 18 | protected internal override string BaseUrl 19 | { 20 | get 21 | { 22 | return base.BaseUrl + "elevation/"; 23 | } 24 | } 25 | /// 26 | /// locations (required) defines the location(s) on the earth from which to return elevation data. This parameter takes either a single location as a comma-separated {latitude,longitude} pair (e.g. "40.714728,-73.998672") or multiple latitude/longitude pairs passed as an array or as an encoded polyline. For more information, see Specifying Locations below. 27 | /// 28 | public IEnumerable Locations { get; set; } 29 | 30 | /// 31 | /// 32 | /// 33 | public IEnumerable Path { get; set; } 34 | 35 | protected override QueryStringParametersList GetQueryStringParameters() 36 | { 37 | if ((Locations == null) == (Path == null)) 38 | throw new ArgumentException("Either Locations or Path must be specified, and both cannot be specified."); 39 | 40 | var parameters = base.GetQueryStringParameters(); 41 | parameters.Add(Locations != null ? "locations" : "path", string.Join("|", Locations ?? Path)); 42 | 43 | return parameters; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Elevation/Response/ElevationResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using GoogleMapsApi.Entities.Common; 6 | using GoogleMapsApi.Entities.Elevation.Request; 7 | 8 | namespace GoogleMapsApi.Entities.Elevation.Response 9 | { 10 | [DataContract] 11 | public class ElevationResponse : IResponseFor 12 | { 13 | [DataMember(Name = "status")] 14 | internal string StatusStr 15 | { 16 | get 17 | { 18 | return Status.ToString(); 19 | } 20 | set 21 | { 22 | Status = (Status)Enum.Parse(typeof(Status), value); 23 | } 24 | } 25 | 26 | public Status Status { get; set; } 27 | 28 | [DataMember(Name = "results")] 29 | public IEnumerable Results { get; set; } 30 | 31 | 32 | public override string ToString() 33 | { 34 | return string.Format("ElevationResponse - Status: {0}, Results count: {1}", Status, Results != null ? Results.Count() : 0); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Elevation/Response/Result.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.Elevation.Response 5 | { 6 | [DataContract] 7 | public class Result 8 | { 9 | /// 10 | /// A location element (containing lat and lng elements) of the position for which elevation data is being computed. Note that for path requests, the set of location elements will contain the sampled points along the path. 11 | /// 12 | [DataMember(Name = "location")] 13 | public Location Location { get; set; } 14 | 15 | /// 16 | /// An elevation element indicating the elevation of the location in meters. 17 | /// 18 | [DataMember(Name = "elevation")] 19 | public double Elevation { get; set; } 20 | 21 | /// 22 | /// The value indicating the maximum distance between data points from which the elevation was interpolated, in meters. 23 | /// This property will be missing if the resolution is not known. 24 | /// Note that elevation data becomes more coarse (larger resolution values) when multiple points are passed. 25 | /// To obtain the most accurate elevation value for a point, it should be queried independently. 26 | /// 27 | [DataMember(Name = "resolution")] 28 | public double Resolution { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Elevation/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Elevation.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | [EnumMember] 9 | OK, // indicating the API request was successful 10 | [EnumMember] 11 | INVALID_REQUEST, // indicating the API request was malformed 12 | [EnumMember] 13 | OVER_QUERY_LIMIT, // indicating the requestor has exceeded quota 14 | [EnumMember] 15 | REQUEST_DENIED, // indicating the API did not complete the request 16 | [EnumMember] 17 | UNKNOWN_ERROR //indicating an unknown error 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Request/GeocodingComponents.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace GoogleMapsApi.Entities.Geocoding.Request 5 | { 6 | public class GeocodingComponents 7 | { 8 | private readonly Dictionary components = new Dictionary(); 9 | 10 | /// 11 | /// matches long or short name of a route. 12 | /// 13 | public string Route { get { return components[RouteComponent]; } set { components[RouteComponent] = value; } } 14 | /// 15 | /// matches against both locality and sublocality types. 16 | /// 17 | public string Locality { get { return components[LocalityComponent]; } set { components[LocalityComponent] = value; } } 18 | /// 19 | /// matches all the administrative_area levels. 20 | /// 21 | public string AdministrativeArea { get { return components[AdministrativeAreaComponent]; } set { components[AdministrativeAreaComponent] = value; } } 22 | /// 23 | /// matches postal_code and postal_code_prefix. 24 | /// 25 | public string PostalCode { get { return components[PostalCodeComponent]; } set { components[PostalCodeComponent] = value; } } 26 | /// 27 | /// matches a country name or a two letter ISO 3166-1 country code. 28 | /// 29 | public string Country { get { return components[CountryComponent]; } set { components[CountryComponent] = value; } } 30 | public bool Exists { get { return components.Count > 0; } } 31 | public override string ToString() 32 | { 33 | return Build(); 34 | } 35 | public string Build() 36 | { 37 | return string.Join("|", components.Select(x => x.Key + ":" + x.Value)); 38 | } 39 | 40 | private const string RouteComponent = "route"; 41 | private const string LocalityComponent = "locality"; 42 | private const string AdministrativeAreaComponent = "administrative_area"; 43 | private const string PostalCodeComponent = "postal_code"; 44 | private const string CountryComponent = "country"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Request/GeocodingRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using GoogleMapsApi.Entities.Common; 5 | 6 | namespace GoogleMapsApi.Entities.Geocoding.Request 7 | { 8 | public class GeocodingRequest : SignableRequest 9 | { 10 | protected internal override string BaseUrl 11 | { 12 | get 13 | { 14 | return base.BaseUrl + "geocode/"; 15 | } 16 | } 17 | 18 | /// 19 | /// address (required) — The address that you want to geocode.* 20 | /// 21 | public string Address { get; set; } //Required *or Location or PlaceId 22 | 23 | /// 24 | /// latlng (required) — The textual latitude/longitude value for which you wish to obtain the closest, human-readable address.* 25 | /// If you pass a latlng, the geocoder performs what is known as a reverse geocode. See Reverse Geocoding for more information. 26 | /// 27 | public Location Location { get; set; } //Required *or Address or PlaceId 28 | 29 | /// 30 | /// placeId (required) — The place ID of the place for which you wish to obtain the closest, human-readable address.* 31 | /// 32 | public string PlaceId { get; set; } //Required *or Address or Location 33 | 34 | /// 35 | /// bounds (optional) — The bounding box of the viewport within which to bias geocode results more prominently. (For more information see Viewport Biasing below.) 36 | /// The bounds and region parameters will only influence, not fully restrict, results from the geocoder. 37 | /// 38 | public Location[] Bounds { get; set; } 39 | 40 | /// 41 | /// region (optional) — The region code, specified as a ccTLD ("top-level domain") two-character value. (For more information see Region Biasing below.) 42 | /// The bounds and region parameters will only influence, not fully restrict, results from the geocoder. 43 | /// 44 | public string Region { get; set; } 45 | 46 | /// 47 | /// language (optional) — The language in which to return results. See the supported list of domain languages. Note that we often update supported languages so this list may not be exhaustive. If language is not supplied, the geocoder will attempt to use the native language of the domain from which the request is sent wherever possible. 48 | /// 49 | public string Language { get; set; } 50 | 51 | /// 52 | /// A component filter for which you wish to obtain a geocode. The components filter will also be accepted as an optional parameter if an address is provided. 53 | /// See more info: https://developers.google.com/maps/documentation/geocoding/intro#ComponentFiltering 54 | /// 55 | public GeocodingComponents Components { get; set; } = new GeocodingComponents(); 56 | 57 | protected override QueryStringParametersList GetQueryStringParameters() 58 | { 59 | bool hasPlaceId = !string.IsNullOrWhiteSpace(PlaceId); 60 | bool hasLocation = Location is not null; 61 | bool hasAddress = !string.IsNullOrWhiteSpace(Address); 62 | 63 | if (!(hasPlaceId || hasLocation || hasAddress || Components.Exists)) 64 | throw new ArgumentException("PlaceId, Location, Address or Components is required"); 65 | 66 | var parameters = base.GetQueryStringParameters(); 67 | 68 | if (hasPlaceId) 69 | { 70 | parameters.Add(_placeId, PlaceId); 71 | } 72 | else if (hasLocation) 73 | { 74 | parameters.Add(_latlng, Location.ToString()); 75 | } 76 | else if (hasAddress) 77 | { 78 | parameters.Add(_address, Address); 79 | } 80 | 81 | if (Components.Exists && !hasPlaceId) 82 | { 83 | string components = Components.Build(); 84 | parameters.Add(_components, components); 85 | } 86 | 87 | if (Bounds != null && Bounds.Any() && !hasPlaceId) 88 | parameters.Add(_bounds, string.Join("|", Bounds.AsEnumerable())); 89 | 90 | if (!string.IsNullOrWhiteSpace(Region) && !hasPlaceId) 91 | parameters.Add(_region, Region); 92 | 93 | if (!string.IsNullOrWhiteSpace(Language)) 94 | parameters.Add(_language, Language); 95 | 96 | return parameters; 97 | } 98 | 99 | private const string _latlng = "latlng"; 100 | private const string _address = "address"; 101 | private const string _placeId = "place_id"; 102 | private const string _bounds = "bounds"; 103 | private const string _region = "region"; 104 | private const string _language = "language"; 105 | private const string _components = "components"; 106 | } 107 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Response/AddressComponent.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Geocoding.Response 5 | { 6 | [DataContract] 7 | public class AddressComponent 8 | { 9 | /// 10 | /// types[] is an array indicating the type of the address component. 11 | /// 12 | [DataMember(Name = "types")] 13 | public IEnumerable Types { get; set; } 14 | /// 15 | /// short_name is an abbreviated textual name for the address component, if available. For example, an address component for the state of Alaska may have a long_name of "Alaska" and a short_name of "AK" using the 2-letter postal abbreviation. 16 | /// 17 | [DataMember(Name = "short_name")] 18 | public string ShortName { get; set; } 19 | /// 20 | /// long_name is the full text description or name of the address component as returned by the Geocoder. 21 | /// 22 | [DataMember(Name = "long_name")] 23 | public string LongName { get; set; } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Response/FramedLocation.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.Geocoding.Response 5 | { 6 | [DataContract] 7 | public class FramedLocation 8 | { 9 | [DataMember(Name = "southwest")] 10 | public Location SouthWest { get; set; } 11 | 12 | [DataMember(Name = "northeast")] 13 | public Location NorthEast { get; set; } 14 | 15 | public Location Center 16 | { 17 | get 18 | { 19 | if (SouthWest == null || NorthEast == null) 20 | return null; 21 | return new Location((SouthWest.Latitude + NorthEast.Latitude) / 2, (SouthWest.Longitude + NorthEast.Longitude) / 2); 22 | } 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Response/GeocodingResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using GoogleMapsApi.Entities.Common; 6 | using GoogleMapsApi.Entities.Geocoding.Request; 7 | 8 | namespace GoogleMapsApi.Entities.Geocoding.Response 9 | { 10 | [DataContract] 11 | public class GeocodingResponse : IResponseFor 12 | { 13 | [DataMember(Name = "status")] 14 | internal string StatusStr 15 | { 16 | get 17 | { 18 | return Status.ToString(); 19 | } 20 | set 21 | { 22 | Status = (Status)Enum.Parse(typeof(Status), value); 23 | } 24 | } 25 | 26 | public Status Status { get; set; } 27 | 28 | [DataMember(Name = "results")] 29 | public IEnumerable Results { get; set; } 30 | 31 | public override string ToString() 32 | { 33 | return string.Format("GeocodingResponse - Status: {0}, Results count: {1}", Status, Results != null ? Results.Count() : 0); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Response/Geometry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using GoogleMapsApi.Entities.Common; 4 | 5 | namespace GoogleMapsApi.Entities.Geocoding.Response 6 | { 7 | [DataContract] 8 | public class Geometry 9 | { 10 | /// 11 | /// location contains the geocoded latitude,longitude value. For normal address lookups, this field is typically the most important. 12 | /// 13 | [DataMember(Name = "location")] 14 | public Location Location { get; set; } 15 | 16 | /// 17 | /// location_type stores additional data about the specified location. 18 | /// 19 | public GeocodeLocationType LocationType { get; set; } 20 | 21 | /// 22 | /// viewport contains the recommended viewport for displaying the returned result, specified as two latitude,longitude values defining the southwest and northeast corner of the viewport bounding box. Generally the viewport is used to frame a result when displaying it to a user. 23 | /// 24 | [DataMember(Name = "viewport")] 25 | public FramedLocation ViewPort { get; set; } 26 | 27 | /// 28 | /// bounds (optionally returned) stores the bounding box which can fully contain the returned result. Note that these bounds may not match the recommended viewport. (For example, San Francisco includes the Farallon islands, which are technically part of the city, but probably should not be returned in the viewport.) 29 | /// 30 | [DataMember(Name = "bounds")] 31 | public FramedLocation Bounds { get; set; } 32 | 33 | 34 | [DataMember(Name = "location_type")] 35 | internal string LocationTypeStr 36 | { 37 | get 38 | { 39 | return LocationType.ToString(); 40 | } 41 | set 42 | { 43 | LocationType = (GeocodeLocationType)Enum.Parse(typeof(GeocodeLocationType), value); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Response/LocationType.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Geocoding.Response 4 | { 5 | [DataContract] 6 | public enum GeocodeLocationType 7 | { 8 | /// 9 | /// Indicates that the returned result is a precise geocode for which we have location information accurate down to street address precision. 10 | /// 11 | [EnumMember] 12 | ROOFTOP, 13 | 14 | /// 15 | /// Indicates that the returned result reflects an approximation (usually on a road) interpolated between two precise points (such as intersections). Interpolated results are generally returned when rooftop geocodes are unavailable for a street address. 16 | /// 17 | [EnumMember] 18 | RANGE_INTERPOLATED, 19 | 20 | /// 21 | /// Indicates that the returned result is the geometric center of a result such as a polyline (for example, a street) or polygon (region). 22 | /// 23 | [EnumMember] 24 | GEOMETRIC_CENTER, 25 | 26 | /// 27 | /// Indicates that the returned result is approximate. 28 | /// 29 | [EnumMember] 30 | APPROXIMATE 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Response/Result.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Geocoding.Response 5 | { 6 | /// 7 | /// When the geocoder returns results, it places them within a (JSON) results array. Even if the geocoder returns no results (such as if the address doesn't exist) it still returns an empty results array. (XML responses consist of zero or more result elements.) 8 | /// 9 | [DataContract] 10 | public class Result 11 | { 12 | /// 13 | /// The types[] array indicates the type of the returned result. This array contains a set of one or more tags identifying the type of feature returned in the result. For example, a geocode of "Chicago" returns "locality" which indicates that "Chicago" is a city, and also returns "political" which indicates it is a political entity. 14 | /// 15 | [DataMember(Name = "types")] 16 | public IEnumerable Types { get; set; } 17 | 18 | /// 19 | /// formatted_address is a string containing the human-readable address of this location. Often this address is equivalent to the "postal address," which sometimes differs from country to country. (Note that some countries, such as the United Kingdom, do not allow distribution of true postal addresses due to licensing restrictions.) This address is generally composed of one or more address components. For example, the address "111 8th Avenue, New York, NY" contains separate address components for "111" (the street number, "8th Avenue" (the route), "New York" (the city) and "NY" (the US state). These address components contain additional information as noted below. 20 | /// 21 | [DataMember(Name = "formatted_address")] 22 | public string FormattedAddress { get; set; } 23 | 24 | /// 25 | /// address_components[] is an array containing the separate address components 26 | /// 27 | [DataMember(Name = "address_components")] 28 | public IEnumerable AddressComponents { get; set; } 29 | 30 | /// 31 | /// geometry contains information such as latitude, longitude, location_type, viewport, bounds 32 | /// 33 | [DataMember(Name = "geometry")] 34 | public Geometry Geometry { get; set; } 35 | 36 | /// 37 | /// indicates that the geocoder did not return an exact match for the original request, though it did match part of the requested address. You may wish to examine the original request for misspellings and/or an incomplete address. Partial matches most often occur for street addresses that do not exist within the locality you pass in the request. 38 | /// 39 | [DataMember(Name = "partial_match")] 40 | public bool PartialMatch { get; set; } 41 | 42 | /// 43 | /// provides the Google PlaceId 44 | /// 45 | [DataMember(Name = "place_id")] 46 | public string PlaceId { get; set; } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Geocoding/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Geocoding.Response 4 | { 5 | /// 6 | /// The "status" field within the Geocoding response object contains the status of the request, and may contain debugging information to help you track down why Geocoding is not working. The "status" field may contain the following values: 7 | /// 8 | [DataContract] 9 | public enum Status 10 | { 11 | /// 12 | /// Indicates that no errors occurred; the address was successfully parsed and at least one geocode was returned. 13 | /// 14 | [EnumMember] 15 | OK, 16 | 17 | /// 18 | /// Indicates that the geocode was successful but returned no results. This may occur if the geocode was passed a non-existent address or a latlng in a remote location. 19 | /// 20 | [EnumMember] 21 | ZERO_RESULTS, 22 | 23 | /// 24 | /// Indicates that you are over your quota. 25 | /// 26 | [EnumMember] 27 | OVER_QUERY_LIMIT, 28 | 29 | /// 30 | /// Indicates that your request was denied. 31 | /// 32 | [EnumMember] 33 | REQUEST_DENIED, 34 | 35 | /// 36 | /// Generally indicates that the query (address or latlng) is missing. 37 | /// 38 | [EnumMember] 39 | INVALID_REQUEST 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlaceAutocomplete/Response/MatchedSubstring.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.PlaceAutocomplete.Response 5 | { 6 | /// 7 | /// Describes the location of the entered term in the PlaceAutocomplete result text, so that the term can be highlighted if desired 8 | /// 9 | [DataContract] 10 | public class MatchedSubstring 11 | { 12 | /// 13 | /// The start position of this term in the description, measured in Unicode characters 14 | /// 15 | [DataMember(Name = "offset")] 16 | public int Offset { get; set; } 17 | 18 | /// 19 | /// The length of this term in the description, measured in Unicode characters 20 | /// 21 | [DataMember(Name = "length")] 22 | public int Length { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlaceAutocomplete/Response/PlaceAutocompleteResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | using GoogleMapsApi.Entities.PlaceAutocomplete.Request; 6 | 7 | namespace GoogleMapsApi.Entities.PlaceAutocomplete.Response 8 | { 9 | [DataContract] 10 | public class PlaceAutocompleteResponse : IResponseFor 11 | { 12 | /// 13 | /// "status" contains metadata on the request. 14 | /// 15 | public Status Status { get; set; } 16 | 17 | [DataMember(Name = "status")] 18 | internal string StatusStr 19 | { 20 | get 21 | { 22 | return Status.ToString(); 23 | } 24 | set 25 | { 26 | Status = (Status)Enum.Parse(typeof(Status), value); 27 | } 28 | } 29 | 30 | /// 31 | /// "results" contains an array of predictions rather than full results, each including a description and a reference which can be queried further 32 | /// to get the full place details 33 | /// 34 | [DataMember(Name = "predictions")] 35 | public IEnumerable Results { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlaceAutocomplete/Response/Prediction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using GoogleMapsApi.Entities.Common; 4 | 5 | namespace GoogleMapsApi.Entities.PlaceAutocomplete.Response 6 | { 7 | /// 8 | /// When the PlaceAutocomplete service returns results from a search, it places them within a predictions array. 9 | /// Even if the service returns no results (such as if the location is remote) it still returns an empty predictions array. 10 | /// 11 | [DataContract] 12 | public class Prediction 13 | { 14 | /// 15 | /// Contains the human-readable name for the returned result. For establishment results, this is usually the business name. 16 | /// 17 | [DataMember(Name = "description")] 18 | public string Description { get; set; } 19 | 20 | /// 21 | /// Contains a unique identifier for this place. To retrieve information about this place, pass this identifier in the placeId field of 22 | /// a Places API request. 23 | /// 24 | [DataMember( Name = "place_id" )] 25 | public string PlaceId { get; set; } 26 | 27 | /// 28 | /// Contains a unique token that you can use to retrieve additional information about this place in a Place Details request. 29 | /// You can store this token and use it at any time in future to refresh cached data about this place, but the same token is 30 | /// not guaranteed to be returned for any given place across different searches. 31 | /// 32 | [DataMember(Name = "reference")] 33 | [Obsolete( "Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information." )] 34 | public string Reference { get; set; } 35 | 36 | /// 37 | /// Contains a unique stable identifier denoting this place. This identifier may not be used to retrieve information about this 38 | /// place, but can be used to consolidate data about this place, and to verify the identity of a place across separate searches. 39 | /// 40 | [DataMember(Name = "id")] 41 | [Obsolete( "Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information." )] 42 | public string ID { get; set; } 43 | 44 | /// 45 | /// Contains an array of terms identifying each section of the returned description (a section of the description is generally 46 | /// terminated with a comma). Each entry in the array has a value field, containing the text of the term, and an offset field, 47 | /// defining the start position of this term in the description, measured in Unicode characters. 48 | /// 49 | [DataMember(Name = "terms")] 50 | public Term[] Terms { get; set; } 51 | 52 | /// 53 | /// Contains an array of types that apply to this place. For example: [ "political", "locality" ] or [ "establishment", "geocode" ]. 54 | /// 55 | [DataMember(Name = "types")] 56 | public string[] Types { get; set; } 57 | 58 | /// 59 | /// Contains an offset value and a length. These describe the location of the entered term in the prediction result text, so that 60 | /// the term can be highlighted if desired. 61 | /// 62 | [DataMember(Name = "matched_substrings")] 63 | public MatchedSubstring[] MatchedSubstrings { get; set; } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlaceAutocomplete/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.PlaceAutocomplete.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | [EnumMember(Value = "OK")] 9 | OK, // indicates that no errors occurred; the place was successfully detected and at least one result was returned. 10 | [EnumMember(Value = "ZERO_RESULTS")] 11 | ZERO_RESULTS, // indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 12 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 13 | OVER_QUERY_LIMIT, // indicates that you are over your quota. 14 | [EnumMember(Value = "REQUEST_DENIED")] 15 | REQUEST_DENIED, // indicates that your request was denied. 16 | [EnumMember(Value = "INVALID_REQUEST")] 17 | INVALID_REQUEST // generally indicates that the input parameter is missing. 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlaceAutocomplete/Response/Term.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.PlaceAutocomplete.Response 5 | { 6 | /// 7 | /// Identifies a section of description in a PlaceAutocomplete search result 8 | /// 9 | [DataContract] 10 | public class Term 11 | { 12 | /// 13 | /// The text of the term 14 | /// 15 | [DataMember(Name = "value")] 16 | public string Value { get; set; } 17 | 18 | /// 19 | /// The start position of this term in the description, measured in Unicode characters 20 | /// 21 | [DataMember(Name = "offset")] 22 | public int Offset { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Places/Request/RankBy.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.Places.Request 2 | { 3 | /// 4 | /// Specifies the order in which results are listed 5 | /// 6 | public enum RankBy 7 | { 8 | /// 9 | /// This option sorts results based on their importance. Ranking will favor prominent places within the specified area. Prominence can be affected by a Place's ranking in Google's index, the number of check-ins from your application, global popularity, and other factors. 10 | /// 11 | Prominence, 12 | /// 13 | /// This option sorts results in ascending order by their distance from the specified location. A radius should not be supplied, and bounds is not supported. One or more of keyword, name, or types is required. 14 | /// 15 | Distance 16 | } 17 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Places/Response/Geometry.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.Places.Response 5 | { 6 | /// 7 | /// Contains the location 8 | /// 9 | [DataContract] 10 | public class Geometry 11 | { 12 | [DataMember(Name = "location")] 13 | public Location Location { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Places/Response/PlacesResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | using GoogleMapsApi.Entities.Places.Request; 6 | 7 | namespace GoogleMapsApi.Entities.Places.Response 8 | { 9 | [DataContract] 10 | public class PlacesResponse : IResponseFor 11 | { 12 | /// 13 | /// "status" contains metadata on the request. 14 | /// 15 | public Status Status { get; set; } 16 | 17 | [DataMember(Name = "status")] 18 | internal string StatusStr 19 | { 20 | get 21 | { 22 | return Status.ToString(); 23 | } 24 | set 25 | { 26 | Status = (Status)Enum.Parse(typeof(Status), value); 27 | } 28 | } 29 | 30 | /// 31 | /// If there is a next page of results, the token will be supplied by Google. Token should be set on the next PlacesRequest object to get the next page of results from Google. 32 | /// If null is returned, there is no next page of results. 33 | /// 34 | [DataMember(Name = "next_page_token")] 35 | public string NextPage 36 | { 37 | get; 38 | set; 39 | } 40 | 41 | /// 42 | /// "results" contains an array of places, with information about the place. See Place Search Results for information about these results. The Places API returns up to 20 establishment results. Additionally, political results may be returned which serve to identify the area of the request. 43 | /// 44 | [DataMember(Name = "results")] 45 | public IEnumerable Results { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Places/Response/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.Places.Response 5 | { 6 | [DataContract] 7 | public class Result 8 | { 9 | /// 10 | /// name contains the human-readable name for the returned result. For establishment results, this is usually the canonicalized business name. 11 | /// 12 | [DataMember(Name = "name")] 13 | public string Name { get; set; } 14 | 15 | [DataMember(Name = "rating")] 16 | public double Rating { get; set; } 17 | 18 | [DataMember(Name = "icon")] 19 | public string Icon { get; set; } 20 | 21 | [DataMember(Name = "id")] 22 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 23 | public string ID { get; set; } 24 | 25 | [DataMember(Name = "reference")] 26 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 27 | public string Reference { get; set; } 28 | 29 | [DataMember(Name = "vicinity")] 30 | public string Vicinity { get; set; } 31 | 32 | [DataMember(Name = "types")] 33 | public string[] Types { get; set; } 34 | 35 | [DataMember( Name = "geometry" )] 36 | public Geometry Geometry { get; set; } 37 | 38 | [DataMember(Name = "place_id")] 39 | public string PlaceId { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/Places/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.Places.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | [EnumMember(Value = "OK")] 9 | OK, // indicates that no errors occurred; the place was successfully detected and at least one result was returned. 10 | [EnumMember(Value = "ZERO_RESULTS")] 11 | ZERO_RESULTS, // indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 12 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 13 | OVER_QUERY_LIMIT, // indicates that you are over your quota. 14 | [EnumMember(Value = "REQUEST_DENIED")] 15 | REQUEST_DENIED, // indicates that your request was denied. 16 | [EnumMember(Value = "INVALID_REQUEST")] 17 | INVALID_REQUEST // generally indicates that the query parameter (location or radius) is missing. 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Request/PlacesDetailsRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesDetails.Request 5 | { 6 | public class PlacesDetailsRequest : MapsBaseRequest 7 | { 8 | protected internal override string BaseUrl 9 | { 10 | get { return "maps.googleapis.com/maps/api/place/details/"; } 11 | } 12 | 13 | public string PlaceId { get; set; } // required 14 | 15 | public string Language { get; set; } // optional 16 | 17 | public override bool IsSSL 18 | { 19 | get { return true; } 20 | set { throw new NotSupportedException("This operation is not supported, PlacesRequest must use SSL"); } 21 | } 22 | 23 | /// 24 | /// A random string which identifies an autocomplete session for billing purposes. 25 | /// If this parameter is omitted from an autocomplete request, the request is billed independently. 26 | /// 27 | public string SessionToken { get; set; } 28 | 29 | protected override QueryStringParametersList GetQueryStringParameters() 30 | { 31 | if (string.IsNullOrWhiteSpace(PlaceId)) 32 | throw new ArgumentException("PlaceId must be provided."); 33 | 34 | if (string.IsNullOrWhiteSpace(ApiKey)) 35 | throw new ArgumentException("ApiKey must be provided"); 36 | 37 | QueryStringParametersList parameters = base.GetQueryStringParameters(); 38 | 39 | parameters.Add("placeid", PlaceId); 40 | 41 | if (!string.IsNullOrWhiteSpace(Language)) parameters.Add("language", Language); 42 | 43 | if (!string.IsNullOrWhiteSpace(SessionToken)) 44 | parameters.Add("sessiontoken", SessionToken); 45 | 46 | return parameters; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/Aspect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 5 | { 6 | [DataContract] 7 | public class Aspect 8 | { 9 | /// 10 | /// Event id. 11 | /// 12 | [DataMember(Name = "rating")] 13 | public int Rating { get; set; } 14 | 15 | [DataMember(Name = "type")] 16 | public string Type { get; set; } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/Events.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 5 | { 6 | [DataContract] 7 | public class Event 8 | { 9 | 10 | 11 | /// 12 | /// Event id. 13 | /// 14 | [DataMember(Name = "event_id")] 15 | public string EventId { get; set; } 16 | 17 | public DateTime StartTime; 18 | 19 | [DataMember(Name = "start_time")] 20 | internal int int_StartTime 21 | { 22 | get 23 | { 24 | return GoogleMapsApi.Engine.UnixTimeConverter.DateTimeToUnixTimestamp(StartTime); 25 | } 26 | set 27 | { 28 | DateTime epoch = new DateTime(1970, 1, 1); 29 | StartTime = epoch.AddSeconds(value); 30 | } 31 | } 32 | 33 | [DataMember(Name = "summary")] 34 | public string Summary { get; set; } 35 | 36 | [DataMember(Name = "url")] 37 | public string Url { get; set; } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/Geometry.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 5 | { 6 | /// 7 | /// Contains the location 8 | /// 9 | [DataContract] 10 | public class Geometry 11 | { 12 | [DataMember(Name = "location")] 13 | public Location Location { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/OpeningHours.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 5 | { 6 | [DataContract] 7 | public class OpeningHours 8 | { 9 | /// 10 | /// is a boolean value indicating if the Place is open at the current time. 11 | /// 12 | [DataMember(Name = "open_now")] 13 | public bool OpenNow { get; set; } 14 | 15 | 16 | /// 17 | /// periods[] is an array of opening periods covering seven days, starting from Sunday, in chronological order. Each period contains: 18 | /// open contains a pair of day and time objects describing when the Place opens 19 | /// 20 | [DataMember(Name = "periods")] 21 | public IEnumerable Periods { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/Period.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 4 | { 5 | /// 6 | /// periods[] is an array of opening periods covering seven days, starting from Sunday, in chronological order. Each period contains: 7 | /// open contains a pair of day and time objects describing when the Place opens: 8 | /// day a number from 0–6, corresponding to the days of the week, starting on Sunday. For example, 2 means Tuesday. 9 | /// time may contain a time of day in 24-hour hhmm format. Values are in the range 0000–2359. The time will be reported in the Place’s time zone. 10 | /// close may contain a pair of day and time objects describing when the Place closes. Note: If a Place is always open, the close section will be missing from the response. Clients can rely on always-open being represented as an open period containing day with value 0 and time with value 0000, and no close. 11 | /// 12 | [DataContract] 13 | public class Period 14 | { 15 | [DataMember(Name = "open")] 16 | public TimeOfWeek OpenTime { get; set; } 17 | 18 | [DataMember(Name = "close")] 19 | public TimeOfWeek CloseTime { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/PlacesDetailsResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | using GoogleMapsApi.Entities.PlacesDetails.Request; 6 | 7 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 8 | { 9 | [DataContract] 10 | public class PlacesDetailsResponse : IResponseFor 11 | { 12 | /// 13 | /// "status" contains metadata on the request. 14 | /// 15 | public Status Status { get; set; } 16 | 17 | [DataMember(Name = "status")] 18 | internal string StatusStr 19 | { 20 | get 21 | { 22 | return Status.ToString(); 23 | } 24 | set 25 | { 26 | Status = (Status)Enum.Parse(typeof(Status), value); 27 | } 28 | } 29 | 30 | /// 31 | /// "results" contains an array of places, with information about the place. See Place Search Results for information about these results. The Places API returns up to 20 establishment results. Additionally, political results may be returned which serve to identify the area of the request. 32 | /// 33 | [DataMember(Name = "result")] 34 | public Result Result { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Runtime.Serialization; 4 | using System.Collections.Generic; 5 | using GoogleMapsApi.Entities.Common; 6 | 7 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 8 | { 9 | [DataContract] 10 | public class Result 11 | { 12 | /// 13 | /// name contains the human-readable name for the returned result. For establishment results, this is usually the canonicalized business name. 14 | /// 15 | 16 | [DataMember(Name="address_components")] 17 | public IEnumerable AddressComponent { get; set; } 18 | 19 | 20 | [DataMember(Name = "events")] 21 | public IEnumerable Event { get; set; } 22 | 23 | [DataMember(Name = "formatted_address")] 24 | public string FormattedAddress { get; set; } 25 | 26 | [DataMember(Name = "formatted_phone_number")] 27 | public string FormattedPhoneNumber { get; set; } 28 | 29 | [DataMember(Name = "geometry")] 30 | public Geometry Geometry { get; set; } 31 | 32 | [DataMember(Name = "icon")] 33 | public string Icon { get; set; } 34 | 35 | [DataMember(Name = "id")] 36 | public string ID { get; set; } 37 | 38 | [DataMember(Name = "international_phone_number")] 39 | public string InternationalPhoneNumber { get; set; } 40 | 41 | [DataMember(Name = "name")] 42 | public string Name { get; set; } 43 | 44 | /// 45 | /// Opening hours information 46 | /// 47 | [DataMember(Name = "opening_hours")] 48 | public OpeningHours OpeningHours { get; set; } 49 | 50 | [DataMember(Name = "permanently_closed")] 51 | public bool PermanentlyClosed { get; set; } 52 | 53 | [DataMember(Name = "photos")] 54 | public IEnumerable Photos { get; set; } 55 | 56 | public PriceLevel? PriceLevel; 57 | 58 | [DataMember(Name = "price_level")] 59 | internal string string_PriceLevel 60 | { 61 | get { return PriceLevel.HasValue ? ((int) PriceLevel).ToString(CultureInfo.InvariantCulture) : null; } 62 | set 63 | { 64 | if (value == null) 65 | PriceLevel = null; 66 | else 67 | { 68 | int priceLevelInt; 69 | if (int.TryParse(value, out priceLevelInt)) 70 | PriceLevel = (PriceLevel) priceLevelInt; 71 | else 72 | PriceLevel = null; 73 | } 74 | } 75 | } 76 | 77 | [DataMember(Name = "rating")] 78 | public double Rating { get; set; } 79 | 80 | [DataMember(Name = "reference")] 81 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 82 | public string Reference { get; set; } 83 | 84 | [DataMember(Name = "reviews")] 85 | public IEnumerable Review { get; set; } 86 | 87 | [DataMember(Name = "types")] 88 | public string[] Types { get; set; } 89 | 90 | [DataMember(Name = "url")] 91 | public string URL { get; set; } 92 | 93 | [DataMember(Name = "utc_offset")] 94 | public string UTCOffset { get; set; } 95 | 96 | [DataMember(Name = "vicinity")] 97 | public string Vicinity { get; set; } 98 | 99 | [DataMember(Name = "website")] 100 | public string Website { get; set; } 101 | 102 | [DataMember(Name = "place_id")] 103 | public string PlaceId { get; set; } 104 | } 105 | 106 | public enum PriceLevel 107 | { 108 | Free = 0, 109 | Inexpensive = 1, 110 | Moderate = 2, 111 | Expensive = 3, 112 | VeryExpensive = 4, 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/Review.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 5 | { 6 | [DataContract] 7 | public class Review 8 | { 9 | /// 10 | /// Event id. 11 | /// 12 | [DataMember(Name = "aspect")] 13 | public Aspect Aspect { get; set; } 14 | 15 | [DataMember(Name = "author_name")] 16 | public string AuthorName { get; set; } 17 | 18 | [DataMember(Name = "author_url")] 19 | public string AuthorUrl { get; set; } 20 | 21 | public DateTime Time; 22 | 23 | [DataMember(Name = "time")] 24 | internal int int_StartTime 25 | { 26 | get 27 | { 28 | return GoogleMapsApi.Engine.UnixTimeConverter.DateTimeToUnixTimestamp(Time); 29 | } 30 | set 31 | { 32 | DateTime epoch = new DateTime(1970, 1, 1); 33 | Time = epoch.AddSeconds(value); 34 | } 35 | } 36 | 37 | [DataMember(Name = "text")] 38 | public string Text { get; set; } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | /// 9 | /// Indicates that no errors occurred; the place was successfully detected and at least one result was returned. 10 | /// 11 | [EnumMember(Value = "OK")] 12 | OK, 13 | 14 | /// 15 | /// Indicates a server-side error; trying again may be successful. 16 | /// 17 | [EnumMember(Value = "UNKNOWN_ERROR")] 18 | UNKNOWN_ERROR, 19 | 20 | /// 21 | /// Indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 22 | /// 23 | [EnumMember(Value = "ZERO_RESULTS")] 24 | ZERO_RESULTS, 25 | 26 | /// 27 | /// Indicates that you are over your quota. 28 | /// 29 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 30 | OVER_QUERY_LIMIT, 31 | 32 | /// 33 | /// Indicates that your request was denied. 34 | /// 35 | [EnumMember(Value = "REQUEST_DENIED")] 36 | REQUEST_DENIED, 37 | 38 | /// 39 | /// Generally indicates that the query parameter (location or radius) is missing. 40 | /// 41 | [EnumMember(Value = "INVALID_REQUEST")] 42 | INVALID_REQUEST, 43 | 44 | /// 45 | /// Indicates that the referenced location was not found in the Places database. 46 | /// 47 | [EnumMember(Value = "NOT_FOUND")] 48 | NOT_FOUND, 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesDetails/Response/TimeOfWeek.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesDetails.Response 5 | { 6 | [DataContract] 7 | public class TimeOfWeek 8 | { 9 | /// 10 | /// .net's DayOfWeek follows the same numbering as google (Sunday == 0) therefor a specific 11 | /// conversion step is not needed, the deserializer's direct casting will work. 12 | /// http://msdn.microsoft.com/en-us/library/system.dayofweek.aspx 13 | /// 14 | [DataMember(Name = "day")] 15 | public DayOfWeek Day { get; set; } 16 | 17 | /// 18 | /// May contain a time of day in 24-hour hhmm format (values are in the range 0000–2359). The time will 19 | /// be reported in the Place’s timezone. 20 | /// 21 | /// 22 | /// Didn't make this stronly typed due to .net's lack of an explicit 'Time' class. 23 | /// http://noda-time.blogspot.com.au/2011/08/what-wrong-with-datetime-anyway.html 24 | /// 25 | [DataMember(Name = "time")] 26 | public int Time { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesFind/Request/InputType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GoogleMapsApi.Entities.PlacesFind.Request 9 | { 10 | public enum InputType 11 | { 12 | [EnumMember(Value = "textquery")] 13 | TextQuery, 14 | [EnumMember(Value = "phonenumber")] 15 | PhoneNumber 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesFind/Request/PlacesFindRequest.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using System; 3 | using System.Globalization; 4 | 5 | namespace GoogleMapsApi.Entities.PlacesFind.Request 6 | { 7 | /// 8 | /// A Find Place request takes a text input, and returns a place. The text input can be any kind of Places data, for example, a name, address, or phone number. 9 | /// 10 | public class PlacesFindRequest : MapsBaseRequest 11 | { 12 | protected internal override string BaseUrl 13 | { 14 | get 15 | { 16 | return "maps.googleapis.com/maps/api/place/findplacefromtext/"; 17 | } 18 | } 19 | 20 | /// 21 | /// Required. The text input specifying which place to search for (for example, a name, address, or phone number). 22 | /// 23 | public string Input { get; set; } 24 | 25 | /// 26 | /// Required. The type of input. This can be one of either textquery or phonenumber. Phone numbers must be in international format (prefixed by a plus sign ("+"), followed by the country code, then the phone number itself). See E.164 ITU recommendation for more information. 27 | /// 28 | public InputType? InputType { get; set; } 29 | 30 | /// 31 | /// Optional. The language code, indicating in which language the results should be returned, if possible. Searches are also biased to the selected language; results in the selected language may be given a higher ranking. See the list of supported languages and their codes. Note that we often update supported languages so this list may not be exhaustive. 32 | /// 33 | public string Language { get; set; } 34 | 35 | /// 36 | /// Optional. The fields specifying the types of place data to return, separated by a comma. If you omit the fields parameter from a Find Place request, only the place_id for the result will be returned. See docs for more information on 37 | /// 38 | public string Fields { get; set; } 39 | 40 | /// 41 | /// Prefer results in a specified area, by specifying either a radius plus lat/lng, or two lat/lng pairs representing the points of a rectangle. If this parameter is not specified, the API uses IP address biasing by default. See docs for more information on how to format value. 42 | /// 43 | public string LocationBias { get; set; } 44 | 45 | public override bool IsSSL 46 | { 47 | get 48 | { 49 | return true; 50 | } 51 | set 52 | { 53 | throw new NotSupportedException("This operation is not supported, PlacesFindRequest must use SSL"); 54 | } 55 | } 56 | 57 | protected override QueryStringParametersList GetQueryStringParameters() 58 | { 59 | if (Input == null) 60 | throw new ArgumentException("Input must be provided."); 61 | if (InputType == null) 62 | throw new ArgumentException("InputType must be provided."); 63 | if (string.IsNullOrWhiteSpace(ApiKey)) 64 | throw new ArgumentException("ApiKey must be provided"); 65 | 66 | var parameters = base.GetQueryStringParameters(); 67 | parameters.Add("key", ApiKey); 68 | parameters.Add("input", Input); 69 | parameters.Add("inputtype", InputType == Request.InputType.PhoneNumber ? "phonenumber" : "textquery"); 70 | 71 | // optional parameters 72 | if (!string.IsNullOrWhiteSpace(Language)) 73 | parameters.Add("language", Language); 74 | if (!string.IsNullOrWhiteSpace(Fields)) 75 | parameters.Add("fields", Fields); 76 | if (!string.IsNullOrWhiteSpace(LocationBias)) 77 | parameters.Add("locationbias", LocationBias); 78 | 79 | return parameters; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesFind/Response/Candidate.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Runtime.Serialization; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace GoogleMapsApi.Entities.PlacesFind.Response 10 | { 11 | [DataContract] 12 | public class Candidate 13 | { 14 | // basic fields 15 | [DataMember(Name = "formatted_address")] 16 | public string FormattedAddress { get; set; } 17 | 18 | [DataMember(Name = "geometry")] 19 | public Geometry Geometry { get; set; } 20 | 21 | [DataMember(Name = "icon")] 22 | public string Icon { get; set; } 23 | 24 | [DataMember(Name = "id")] 25 | public string ID { get; set; } 26 | 27 | [DataMember(Name = "name")] 28 | public string Name { get; set; } 29 | 30 | [DataMember(Name = "permanently_closed")] 31 | public bool? PermanentlyClosed { get; set; } 32 | 33 | [DataMember(Name = "photos")] 34 | public IEnumerable Photos { get; set; } 35 | 36 | [DataMember(Name = "place_id")] 37 | public string PlaceId { get; set; } 38 | 39 | [DataMember(Name = "plus_code")] 40 | public string PlusCode { get; set; } 41 | 42 | [DataMember(Name = "scope")] 43 | public string Scope { get; set; } 44 | 45 | [DataMember(Name = "types")] 46 | public string[] Types { get; set; } 47 | 48 | // contact fields 49 | /// 50 | /// Place Search returns only open_now; use a Place Details request to get the full opening_hours results. 51 | /// 52 | [DataMember(Name = "opening_hours")] 53 | public OpeningHours OpeningHours { get; set; } 54 | 55 | // atmosphere fields 56 | [DataMember(Name = "price_level")] 57 | public int? PriceLevel { get; set; } 58 | 59 | [DataMember(Name = "rating")] 60 | public double? Rating { get; set; } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesFind/Response/Geometry.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Runtime.Serialization; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace GoogleMapsApi.Entities.PlacesFind.Response 10 | { 11 | /// 12 | /// Contains the location 13 | /// 14 | [DataContract] 15 | public class Geometry 16 | { 17 | [DataMember(Name = "location")] 18 | public Location Location { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesFind/Response/OpeningHours.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GoogleMapsApi.Entities.PlacesFind.Response 9 | { 10 | [DataContract] 11 | public class OpeningHours 12 | { 13 | /// 14 | /// is a boolean value indicating if the Place is open at the current time. 15 | /// 16 | [DataMember(Name = "open_now")] 17 | public bool OpenNow { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesFind/Response/PlacesFindResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | using GoogleMapsApi.Entities.PlacesFind.Request; 6 | 7 | namespace GoogleMapsApi.Entities.PlacesFind.Response 8 | { 9 | [DataContract] 10 | public class PlacesFindResponse : IResponseFor 11 | { 12 | public Status Status { get; set; } 13 | 14 | [DataMember(Name = "status")] 15 | internal string StatusStr 16 | { 17 | get 18 | { 19 | return Status.ToString(); 20 | } 21 | set 22 | { 23 | Status = (Status)Enum.Parse(typeof(Status), value); 24 | } 25 | } 26 | 27 | /// 28 | /// Collection of places. Each result contains only the data types that were specified using the fields parameter, plus html_attributions. 29 | /// 30 | [DataMember(Name = "candidates")] 31 | public IEnumerable Candidates { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesFind/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GoogleMapsApi.Entities.PlacesFind.Response 9 | { 10 | [DataContract] 11 | public enum Status 12 | { 13 | [EnumMember(Value = "OK")] 14 | OK, // indicates that no errors occurred; the place was successfully detected and at least one result was returned. 15 | [EnumMember(Value = "ZERO_RESULTS")] 16 | ZERO_RESULTS, // indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 17 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 18 | OVER_QUERY_LIMIT, // indicates that you are over your quota. 19 | [EnumMember(Value = "REQUEST_DENIED")] 20 | REQUEST_DENIED, // indicates that your request was denied. 21 | [EnumMember(Value = "INVALID_REQUEST")] 22 | INVALID_REQUEST, // generally indicates that the query parameter (location or radius) is missing. 23 | [EnumMember(Value = "UNKNOWN_ERROR ")] 24 | UNKNOWN_ERROR // indicates a server-side error; trying again may be successful. 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesNearBy/Request/PlacesNearByRequest.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using System; 3 | using System.Globalization; 4 | 5 | namespace GoogleMapsApi.Entities.PlacesNearBy.Request 6 | { 7 | /// 8 | /// The Google Places API is a service that returns information about a "place" (hereafter referred to as a Place) — defined within this API as an establishment, a geographic location, or prominent point of interest — using an HTTP request. Place requests specify locations as latitude/longitude coordinates. 9 | /// Two basic Place requests are available: a Place Search request and a Place Details request. Generally, a Place Search request is used to return candidate matches, while a Place Details request returns more specific information about a Place. 10 | /// This service is designed for processing place requests generated by a user for placement of application content on a map; this service is not designed to respond to batch of offline queries, which are a violation of its terms of use. 11 | /// 12 | public class PlacesNearByRequest : MapsBaseRequest 13 | { 14 | protected internal override string BaseUrl 15 | { 16 | get 17 | { 18 | return "maps.googleapis.com/maps/api/place/nearbysearch/"; 19 | } 20 | } 21 | 22 | /// 23 | /// location (required) — The textual latitude/longitude value from which you wish to retrieve place information. 24 | /// 25 | public Location Location { get; set; } //Required 26 | 27 | /// 28 | /// Defines the distance (in meters) within which to return Place results. The maximum allowed radius is 50 000 meters. 29 | /// Note that radius must not be included if rankby=distance (described under Optional parameters below) is specified. 30 | /// 31 | public double? Radius { get; set; } 32 | 33 | /// 34 | /// A term to be matched against all content that Google has indexed for this Place, 35 | /// including but not limited to name, type, and address, as well as customer reviews and other third-party content. 36 | /// 37 | public string Keyword { get; set; } 38 | 39 | /// 40 | /// The language code, indicating in which language the results should be returned, if possible. See the list of supported languages and their codes. 41 | /// Note that we often update supported languages so this list may not be exhaustive. 42 | /// 43 | public string Language { get; set; } 44 | 45 | /// 46 | /// A term to be matched against the names of Places. Results will be restricted to those containing the passed name value. 47 | /// 48 | public string Name { get; set; } 49 | 50 | /// 51 | /// Specifies the order in which results are listed 52 | /// 53 | public RankBy RankBy { get; set; } 54 | 55 | /// 56 | /// Restricts the results to Places matching the specified type. 57 | /// See the list of supported types - https://developers.google.com/maps/documentation/places/supported_types 58 | /// 59 | /// 60 | public string Type { get; set; } 61 | 62 | /// 63 | /// If there is a next page of results, this token will be supplied by Google in a previous PlacesResponse. PageToken should be set to the previous response value to get the next page of results from Google. 64 | /// When PageToken is set, all other Request parameters are ignored. 65 | /// 66 | public string PageToken { get; set; } 67 | 68 | public override bool IsSSL 69 | { 70 | get 71 | { 72 | return true; 73 | } 74 | set 75 | { 76 | throw new NotSupportedException("This operation is not supported, PlacesRequest must use SSL"); 77 | } 78 | } 79 | 80 | protected override QueryStringParametersList GetQueryStringParameters() 81 | { 82 | if (Location == null) 83 | throw new ArgumentException("Location must be provided."); 84 | if (Radius.HasValue && (Radius > 50000 || Radius < 1)) 85 | throw new ArgumentException("Radius must be greater than or equal to 1 and less than or equal to 50000."); 86 | if (!Radius.HasValue && RankBy != RankBy.Distance) 87 | throw new ArgumentException("Radius must be specified unless RankBy is 'Distance'."); 88 | if (!Enum.IsDefined(typeof(RankBy), RankBy)) 89 | throw new ArgumentException("Invalid RankBy value."); 90 | if (string.IsNullOrWhiteSpace(ApiKey)) 91 | throw new ArgumentException("ApiKey must be provided"); 92 | 93 | var parameters = base.GetQueryStringParameters(); 94 | parameters.Add("location", Location.ToString()); 95 | parameters.Add("key", ApiKey); 96 | 97 | if (Radius.HasValue) 98 | parameters.Add("radius", Radius.Value.ToString(CultureInfo.InvariantCulture)); 99 | if (!string.IsNullOrWhiteSpace(Keyword)) 100 | parameters.Add("keyword", Keyword); 101 | if (!string.IsNullOrWhiteSpace(Language)) 102 | parameters.Add("language", Language); 103 | if (!string.IsNullOrWhiteSpace(Type)) 104 | parameters.Add("type", Type); 105 | if (!string.IsNullOrWhiteSpace(Name)) 106 | parameters.Add("name", Name); 107 | if (RankBy == RankBy.Distance) 108 | parameters.Add("rankby", "distance"); 109 | if (!string.IsNullOrWhiteSpace(PageToken)) 110 | parameters.Add("pagetoken", PageToken); 111 | 112 | return parameters; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesNearBy/Request/RankBy.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.Entities.PlacesNearBy.Request 2 | { 3 | /// 4 | /// Specifies the order in which results are listed 5 | /// 6 | public enum RankBy 7 | { 8 | /// 9 | /// This option sorts results based on their importance. Ranking will favor prominent places within the specified area. Prominence can be affected by a Place's ranking in Google's index, the number of check-ins from your application, global popularity, and other factors. 10 | /// 11 | Prominence, 12 | /// 13 | /// This option sorts results in ascending order by their distance from the specified location. A radius should not be supplied, and bounds is not supported. One or more of keyword, name, or types is required. 14 | /// 15 | Distance 16 | } 17 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesNearBy/Response/Geometry.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesNearBy.Response 5 | { 6 | /// 7 | /// Contains the location 8 | /// 9 | [DataContract] 10 | public class Geometry 11 | { 12 | [DataMember(Name = "location")] 13 | public Location Location { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesNearBy/Response/PlacesNearByResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | using GoogleMapsApi.Entities.PlacesNearBy.Request; 6 | 7 | namespace GoogleMapsApi.Entities.PlacesNearBy.Response 8 | { 9 | [DataContract] 10 | public class PlacesNearByResponse : IResponseFor 11 | { 12 | /// 13 | /// "status" contains metadata on the request. 14 | /// 15 | public Status Status { get; set; } 16 | 17 | [DataMember(Name = "status")] 18 | internal string StatusStr 19 | { 20 | get 21 | { 22 | return Status.ToString(); 23 | } 24 | set 25 | { 26 | Status = (Status)Enum.Parse(typeof(Status), value); 27 | } 28 | } 29 | 30 | /// 31 | /// If there is a next page of results, the token will be supplied by Google. Token should be set on the next PlacesRequest object to get the next page of results from Google. 32 | /// If null is returned, there is no next page of results. 33 | /// 34 | [DataMember(Name = "next_page_token")] 35 | public string NextPage 36 | { 37 | get; 38 | set; 39 | } 40 | 41 | /// 42 | /// "results" contains an array of places, with information about the place. See Place Search Results for information about these results. The Places API returns up to 20 establishment results. Additionally, political results may be returned which serve to identify the area of the request. 43 | /// 44 | [DataMember(Name = "results")] 45 | public IEnumerable Results { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesNearBy/Response/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesNearBy.Response 5 | { 6 | [DataContract] 7 | public class Result 8 | { 9 | /// 10 | /// name contains the human-readable name for the returned result. For establishment results, this is usually the canonicalized business name. 11 | /// 12 | [DataMember(Name = "name")] 13 | public string Name { get; set; } 14 | 15 | [DataMember(Name = "rating")] 16 | public double Rating { get; set; } 17 | 18 | [DataMember(Name = "icon")] 19 | public string Icon { get; set; } 20 | 21 | [DataMember(Name = "id")] 22 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 23 | public string ID { get; set; } 24 | 25 | [DataMember(Name = "reference")] 26 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 27 | public string Reference { get; set; } 28 | 29 | [DataMember(Name = "vicinity")] 30 | public string Vicinity { get; set; } 31 | 32 | [DataMember(Name = "types")] 33 | public string[] Types { get; set; } 34 | 35 | [DataMember( Name = "geometry" )] 36 | public Geometry Geometry { get; set; } 37 | 38 | [DataMember(Name = "place_id")] 39 | public string PlaceId { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesNearBy/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.PlacesNearBy.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | [EnumMember(Value = "OK")] 9 | OK, // indicates that no errors occurred; the place was successfully detected and at least one result was returned. 10 | [EnumMember(Value = "ZERO_RESULTS")] 11 | ZERO_RESULTS, // indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 12 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 13 | OVER_QUERY_LIMIT, // indicates that you are over your quota. 14 | [EnumMember(Value = "REQUEST_DENIED")] 15 | REQUEST_DENIED, // indicates that your request was denied. 16 | [EnumMember(Value = "INVALID_REQUEST")] 17 | INVALID_REQUEST // generally indicates that the query parameter (location or radius) is missing. 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesRadar/Request/PlacesRadarRequest.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using System; 3 | using System.Globalization; 4 | 5 | namespace GoogleMapsApi.Entities.PlacesRadar.Request 6 | { 7 | /// 8 | /// Find out how to replace it - 9 | /// https://cloud.google.com/blog/products/maps-platform/announcing-deprecation-of-place-add 10 | /// 11 | [Obsolete("Radar search is deprecated since June 30 2018", true)] 12 | public class PlacesRadarRequest : MapsBaseRequest 13 | { 14 | protected internal override string BaseUrl 15 | { 16 | get 17 | { 18 | return "maps.googleapis.com/maps/api/place/radarsearch/"; 19 | } 20 | } 21 | 22 | /// 23 | /// Required. The latitude/longitude around which to retrieve place information. This must be specified as latitude,longitude. 24 | /// 25 | public Location Location { get; set; } //Required 26 | 27 | /// 28 | /// Required. Defines the distance (in meters) within which to return place results. The maximum allowed radius is 50 000 meters. 29 | /// 30 | public double Radius { get; set; } 31 | 32 | /// 33 | /// Optional. A term to be matched against all content that Google has indexed for this place, including but not limited to name, type, and address, as well as customer reviews and other third-party content. 34 | /// 35 | public string Keyword { get; set; } 36 | 37 | /// 38 | /// Optional. Restricts results to only those places within the specified price level. Valid values are in the range from 0 (most affordable) to 4 (most expensive), inclusive. The exact amount indicated by a specific value will vary from region to region. 39 | /// 40 | public int? MinPrice { get; set; } 41 | 42 | /// 43 | /// Optional. Restricts results to only those places within the specified price level. Valid values are in the range from 0 (most affordable) to 4 (most expensive), inclusive. The exact amount indicated by a specific value will vary from region to region. 44 | /// 45 | public int? MaxPrice { get; set; } 46 | 47 | /// 48 | /// Optional. One or more terms to be matched against the names of places, separated by a space character. Results will be restricted to those containing the passed name values. Note that a place may have additional names associated with it, beyond its listed name. The API will try to match the passed name value against all of these names. As a result, places may be returned in the results whose listed names do not match the search term, but whose associated names do. 49 | /// 50 | public string Name { get; set; } 51 | 52 | /// 53 | /// Optional. Set to true to only return those places that are open for business at the time the query is sent. Places that do not specify opening hours in the Google Places database will not be returned if you include this parameter in your query. 54 | /// 55 | public bool OpenNow { get; set; } 56 | 57 | /// 58 | /// Optional. Restricts the results to Places matching the specified type. 59 | /// See the list of supported types - https://developers.google.com/maps/documentation/places/supported_types 60 | /// 61 | public string Type { get; set; } 62 | 63 | public override bool IsSSL 64 | { 65 | get 66 | { 67 | return true; 68 | } 69 | set 70 | { 71 | throw new NotSupportedException("This operation is not supported, PlacesRequest must use SSL"); 72 | } 73 | } 74 | 75 | protected override QueryStringParametersList GetQueryStringParameters() 76 | { 77 | if (Location == null) 78 | throw new ArgumentException("Location must be provided."); 79 | if ((Radius > 50000 || Radius < 1)) 80 | throw new ArgumentException("Radius must be greater than or equal to 1 and less than or equal to 50000."); 81 | if (string.IsNullOrWhiteSpace(ApiKey)) 82 | throw new ArgumentException("ApiKey must be provided"); 83 | 84 | var parameters = base.GetQueryStringParameters(); 85 | parameters.Add("location", Location.ToString()); 86 | parameters.Add("key", ApiKey); 87 | parameters.Add("radius", Radius.ToString(CultureInfo.InvariantCulture)); 88 | 89 | if (!string.IsNullOrWhiteSpace(Keyword)) 90 | parameters.Add("keyword", Keyword); 91 | if (MinPrice.HasValue) 92 | parameters.Add("minprice", MinPrice.Value.ToString(CultureInfo.InvariantCulture)); 93 | if (MaxPrice.HasValue) 94 | parameters.Add("maxprice", MaxPrice.Value.ToString(CultureInfo.InvariantCulture)); 95 | if (!string.IsNullOrWhiteSpace(Name)) 96 | parameters.Add("name", Name); 97 | if (OpenNow) 98 | parameters.Add("opennow", "true"); 99 | if (!string.IsNullOrWhiteSpace(Type)) 100 | parameters.Add("type", Type); 101 | 102 | return parameters; 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesRadar/Response/Geometry.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesRadar.Response 5 | { 6 | /// 7 | /// Contains the location 8 | /// 9 | [DataContract] 10 | public class Geometry 11 | { 12 | [DataMember(Name = "location")] 13 | public Location Location { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesRadar/Response/PlacesRadarResponse.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using GoogleMapsApi.Entities.PlacesRadar.Request; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Runtime.Serialization; 6 | 7 | namespace GoogleMapsApi.Entities.PlacesRadar.Response 8 | { 9 | [DataContract] 10 | [Obsolete("Radar search is deprecated since June 30 2018", true)] 11 | public class PlacesRadarResponse : IResponseFor 12 | { 13 | /// 14 | /// "status" contains metadata on the request. 15 | /// 16 | public Status Status { get; set; } 17 | 18 | [DataMember(Name = "status")] 19 | internal string StatusStr 20 | { 21 | get 22 | { 23 | return Status.ToString(); 24 | } 25 | set 26 | { 27 | Status = (Status)Enum.Parse(typeof(Status), value); 28 | } 29 | } 30 | 31 | /// 32 | /// "results" contains an array of places, with information about the place. See Place Search Results for information about these results. The Places API returns up to 20 establishment results. Additionally, political results may be returned which serve to identify the area of the request. 33 | /// 34 | [DataMember(Name = "results")] 35 | public IEnumerable Results { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesRadar/Response/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesRadar.Response 5 | { 6 | [DataContract] 7 | public class Result 8 | { 9 | [DataMember(Name = "id")] 10 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 11 | public string ID { get; set; } 12 | 13 | [DataMember(Name = "reference")] 14 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 15 | public string Reference { get; set; } 16 | 17 | [DataMember( Name = "geometry" )] 18 | public Geometry Geometry { get; set; } 19 | 20 | [DataMember(Name = "place_id")] 21 | public string PlaceId { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesRadar/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.PlacesRadar.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | [EnumMember(Value = "OK")] 9 | OK, // indicates that no errors occurred; the place was successfully detected and at least one result was returned. 10 | [EnumMember(Value = "ZERO_RESULTS")] 11 | ZERO_RESULTS, // indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 12 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 13 | OVER_QUERY_LIMIT, // indicates that you are over your quota. 14 | [EnumMember(Value = "REQUEST_DENIED")] 15 | REQUEST_DENIED, // indicates that your request was denied. 16 | [EnumMember(Value = "INVALID_REQUEST")] 17 | INVALID_REQUEST // generally indicates that the query parameter (location or radius) is missing. 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesText/Request/PlacesTextRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using GoogleMapsApi.Entities.Common; 4 | 5 | namespace GoogleMapsApi.Entities.PlacesText.Request 6 | { 7 | public class PlacesTextRequest : MapsBaseRequest 8 | { 9 | protected internal override string BaseUrl 10 | { 11 | get { return "maps.googleapis.com/maps/api/place/textsearch/"; } 12 | } 13 | 14 | public string Query { get; set; } // required 15 | 16 | public Location Location { get; set; } // optional 17 | public double? Radius { get; set; } // optional 18 | public string Language { get; set; } // optional 19 | public string Types { get; set; } // optional 20 | 21 | public override bool IsSSL 22 | { 23 | get { return true; } 24 | set { throw new NotSupportedException("This operation is not supported, PlacesRequest must use SSL"); } 25 | } 26 | 27 | protected override QueryStringParametersList GetQueryStringParameters() 28 | { 29 | if (string.IsNullOrWhiteSpace(Query)) 30 | throw new ArgumentException("Query must be provided."); 31 | 32 | if (string.IsNullOrWhiteSpace(ApiKey)) 33 | throw new ArgumentException("ApiKey must be provided"); 34 | 35 | QueryStringParametersList parameters = base.GetQueryStringParameters(); 36 | 37 | parameters.Add("query", Query); 38 | 39 | 40 | if (Location != null) parameters.Add("location", Location.ToString()); 41 | if (Radius != null) parameters.Add("radius", Radius.Value.ToString(CultureInfo.InvariantCulture)); 42 | if (!string.IsNullOrWhiteSpace(Language)) parameters.Add("language", Language); 43 | if (!string.IsNullOrWhiteSpace(Types)) parameters.Add("types", Types); 44 | 45 | return parameters; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesText/Response/Geometry.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.Entities.PlacesText.Response 5 | { 6 | /// 7 | /// Contains the location 8 | /// 9 | [DataContract] 10 | public class Geometry 11 | { 12 | [DataMember(Name = "location")] 13 | public Location Location { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesText/Response/PlacesTextResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | using GoogleMapsApi.Entities.PlacesText.Request; 6 | 7 | namespace GoogleMapsApi.Entities.PlacesText.Response 8 | { 9 | [DataContract] 10 | public class PlacesTextResponse : IResponseFor 11 | { 12 | /// 13 | /// "status" contains metadata on the request. 14 | /// 15 | public Status Status { get; set; } 16 | 17 | [DataMember(Name = "status")] 18 | internal string StatusStr 19 | { 20 | get 21 | { 22 | return Status.ToString(); 23 | } 24 | set 25 | { 26 | Status = (Status)Enum.Parse(typeof(Status), value); 27 | } 28 | } 29 | 30 | /// 31 | /// "results" contains an array of places, with information about the place. See Place Search Results for information about these results. The Places API returns up to 20 establishment results. Additionally, political results may be returned which serve to identify the area of the request. 32 | /// 33 | [DataMember(Name = "results")] 34 | public IEnumerable Results { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesText/Response/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using GoogleMapsApi.Entities.Common; 5 | 6 | namespace GoogleMapsApi.Entities.PlacesText.Response 7 | { 8 | [DataContract] 9 | public class Result 10 | { 11 | /// 12 | /// name contains the human-readable name for the returned result. For establishment results, this is usually the canonicalized business name. 13 | /// 14 | [DataMember(Name = "name")] 15 | public string Name { get; set; } 16 | 17 | [DataMember(Name = "rating")] 18 | public double Rating { get; set; } 19 | 20 | [DataMember(Name = "icon")] 21 | public string Icon { get; set; } 22 | 23 | [DataMember(Name = "id")] 24 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 25 | public string ID { get; set; } 26 | 27 | [DataMember(Name = "reference")] 28 | [Obsolete("Use place_id instead. See https://developers.google.com/places/documentation/search#deprecation for more information.")] 29 | public string Reference { get; set; } 30 | 31 | [DataMember(Name = "formatted_address")] 32 | public string FormattedAddress { get; set; } 33 | 34 | [DataMember(Name = "types")] 35 | public string[] Types { get; set; } 36 | 37 | [DataMember(Name = "geometry")] 38 | public Geometry Geometry { get; set; } 39 | 40 | [DataMember(Name = "place_id")] 41 | public string PlaceId { get; set; } 42 | 43 | [DataMember(Name = "photos")] 44 | public IEnumerable Photos { get; set; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/PlacesText/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.PlacesText.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | [EnumMember(Value = "OK")] 9 | OK, // indicates that no errors occurred; the place was successfully detected and at least one result was returned. 10 | [EnumMember(Value = "ZERO_RESULTS")] 11 | ZERO_RESULTS, // indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 12 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 13 | OVER_QUERY_LIMIT, // indicates that you are over your quota. 14 | [EnumMember(Value = "REQUEST_DENIED")] 15 | REQUEST_DENIED, // indicates that your request was denied. 16 | [EnumMember(Value = "INVALID_REQUEST")] 17 | INVALID_REQUEST // generally indicates that the query parameter (location or radius) is missing. 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/TimeZone/Request/TimeZoneRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using GoogleMapsApi.Engine; 3 | using GoogleMapsApi.Entities.Common; 4 | 5 | namespace GoogleMapsApi.Entities.TimeZone.Request 6 | { 7 | public class TimeZoneRequest : SignableRequest 8 | { 9 | protected internal override string BaseUrl 10 | { 11 | get { return base.BaseUrl + "timezone/"; } 12 | } 13 | 14 | /// 15 | /// location: a comma-separated lat,lng tuple (eg. location=-33.86,151.20), representing the location to look up 16 | /// 17 | public Location Location { get; set; } // required 18 | 19 | /// 20 | /// Timestamp specifies the desired time as seconds since midnight, January 1, 1970 UTC. The Time Zone API uses the timestamp to determine whether or not Daylight Savings should be applied. Times before 1970 can be expressed as negative values. 21 | /// 22 | public DateTime TimeStamp { get; set; } // required 23 | 24 | /// 25 | /// The language in which to return results. See the list of supported domain languages. Note that we often update supported languages so this list may not be exhaustive. Defaults to en 26 | /// 27 | public string Language { get; set; } // optional 28 | 29 | /// 30 | /// The language in which to return results. See the list of supported domain languages. Note that we often update supported languages so this list may not be exhaustive. Defaults to en. 31 | /// 32 | public override bool IsSSL 33 | { 34 | get { return true; } 35 | set { throw new NotSupportedException("This operation is not supported, TimeZoneRequest must use SSL"); } 36 | } 37 | 38 | protected override QueryStringParametersList GetQueryStringParameters() 39 | { 40 | if (Location == null) 41 | throw new ArgumentException("Location is required"); 42 | 43 | var parameters = base.GetQueryStringParameters(); 44 | 45 | parameters.Add("location", this.Location.LocationString); 46 | parameters.Add("timestamp", UnixTimeConverter.DateTimeToUnixTimestamp(this.TimeStamp).ToString()); 47 | 48 | if (!string.IsNullOrWhiteSpace(Language)) parameters.Add("language", Language); 49 | 50 | return parameters; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/TimeZone/Response/Status.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace GoogleMapsApi.Entities.TimeZone.Response 4 | { 5 | [DataContract] 6 | public enum Status 7 | { 8 | [EnumMember(Value = "OK")] 9 | OK, // indicates that no errors occurred; the place was successfully detected and at least one result was returned. 10 | [EnumMember(Value = "ZERO_RESULTS")] 11 | ZERO_RESULTS, // indicates that the search was successful but returned no results. This may occur if the search was passed a latlng in a remote location. 12 | [EnumMember(Value = "OVER_QUERY_LIMIT")] 13 | OVER_QUERY_LIMIT, // indicates that you are over your quota. 14 | [EnumMember(Value = "REQUEST_DENIED")] 15 | REQUEST_DENIED, // indicates that your request was denied. 16 | [EnumMember(Value = "INVALID_REQUEST")] 17 | INVALID_REQUEST, // generally indicates that the query parameter (location or radius) is missing. 18 | [EnumMember(Value = "UNKNOWN_ERROR")] 19 | UNKNOWN_ERROR // indicates an unknown error 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /GoogleMapsApi/Entities/TimeZone/Response/TimeZoneResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using GoogleMapsApi.Entities.Common; 4 | using GoogleMapsApi.Entities.TimeZone.Request; 5 | 6 | namespace GoogleMapsApi.Entities.TimeZone.Response 7 | { 8 | [DataContract] 9 | public class TimeZoneResponse : IResponseFor 10 | { 11 | /// 12 | /// "status" contains metadata on the request. 13 | /// 14 | public Status Status { get; set; } 15 | 16 | [DataMember(Name = "status")] 17 | internal string StatusStr 18 | { 19 | get 20 | { 21 | return Status.ToString(); 22 | } 23 | set 24 | { 25 | Status = (Status)Enum.Parse(typeof(Status), value); 26 | } 27 | } 28 | 29 | /// 30 | /// DstOffset: the offset for daylight-savings time in seconds. This will be zero if the time zone is not in Daylight Savings Time during the specified timestamp. 31 | /// 32 | [DataMember(Name = "dstOffset")] 33 | public double DstOffSet { get; set; } 34 | 35 | [Obsolete("Use DstOffSet instead.")] 36 | public double OffSet { get { return DstOffSet; } } 37 | 38 | /// 39 | /// RawOffset: the offset from UTC (in seconds) for the given location. This does not take into effect daylight savings. 40 | /// 41 | [DataMember(Name = "rawOffset")] 42 | public double RawOffSet { get; set; } 43 | 44 | /// 45 | /// TimeZoneId: a string containing the ID of the time zone, such as "America/Los_Angeles" or "Australia/Sydney". 46 | /// 47 | [DataMember(Name = "timeZoneId")] 48 | public string TimeZoneId { get; set; } 49 | 50 | /// 51 | /// TimeZoneName: a string containing the long form name of the time zone. This field will be localized if the language parameter is set. eg. "Pacific Daylight Time" or "Australian. 52 | /// 53 | [DataMember(Name = "timeZoneName")] 54 | public string TimeZoneName { get; set; } 55 | } 56 | } 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /GoogleMapsApi/GoogleMapsApi.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0;net7.0;net6.0;netstandard2.0 4 | latest 5 | 0.0.0 6 | True 7 | True 8 | GoogleMapsApi 9 | Maxim Novak 10 | BSD-2-Clause 11 | Google Maps Web Services API wrapper for .NET 12 | Copyright © 2010-$([System.DateTime]::Now.Year) 13 | Google;Maps;API;Geo;Places;Elevation;Geocode;Directions 14 | git 15 | https://github.com/maximn/google-maps 16 | https://github.com/maximn/google-maps 17 | README.md 18 | true 19 | true 20 | true 21 | snupkg 22 | disable 23 | 24 | 25 | 26 | true 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /GoogleMapsApi/IEngineFacade.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.Entities.Common; 2 | using System; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace GoogleMapsApi 7 | { 8 | using Engine; 9 | 10 | public interface IEngineFacade 11 | where TRequest : MapsBaseRequest, new() 12 | where TResponse : IResponseFor 13 | { 14 | /// 15 | /// Occurs when the Url created. Can be used for override the Url. 16 | /// 17 | public event UriCreatedDelegate OnUriCreated; 18 | 19 | /// 20 | /// Occurs when raw data from Google API received. 21 | /// 22 | public event RawResponseReceivedDelegate OnRawResponseReceived; 23 | 24 | /// 25 | /// Asynchronously query the Google Maps API using the provided request. 26 | /// 27 | /// The request that will be sent. 28 | /// A Task with the future value of the response. 29 | /// Thrown when a null value is passed to the request parameter. 30 | Task QueryAsync(TRequest request); 31 | 32 | /// 33 | /// Asynchronously query the Google Maps API using the provided request. 34 | /// 35 | /// The request that will be sent. 36 | /// A TimeSpan specifying the amount of time to wait for a response before aborting the request. 37 | /// The specify an infinite timeout, pass a TimeSpan with a TotalMillisecond value of Timeout.Infinite. 38 | /// When a request is aborted due to a timeout the returned task will transition to the Faulted state with a TimeoutException. 39 | /// A Task with the future value of the response. 40 | /// Thrown when a null value is passed to the request parameter. 41 | /// Thrown when the value of timeout is neither a positive value or infinite. 42 | Task QueryAsync(TRequest request, TimeSpan timeout); 43 | 44 | /// 45 | /// Asynchronously query the Google Maps API using the provided request. 46 | /// 47 | /// The request that will be sent. 48 | /// A cancellation token that can be used to cancel the pending asynchronous task. 49 | /// A Task with the future value of the response. 50 | /// Thrown when a null value is passed to the request parameter. 51 | Task QueryAsync(TRequest request, CancellationToken token); 52 | 53 | /// 54 | /// Asynchronously query the Google Maps API using the provided request. 55 | /// 56 | /// The request that will be sent. 57 | /// A TimeSpan specifying the amount of time to wait for a response before aborting the request. 58 | /// The specify an infinite timeout, pass a TimeSpan with a TotalMillisecond value of Timeout.Infinite. 59 | /// When a request is aborted due to a timeout the returned task will transition to the Faulted state with a TimeoutException. 60 | /// A cancellation token that can be used to cancel the pending asynchronous task. 61 | /// A Task with the future value of the response. 62 | /// Thrown when a null value is passed to the request parameter. 63 | /// Thrown when the value of timeout is neither a positive value or infinite. 64 | Task QueryAsync(TRequest request, TimeSpan timeout, CancellationToken token); 65 | } 66 | } -------------------------------------------------------------------------------- /GoogleMapsApi/QueryStringParametersList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace GoogleMapsApi 7 | { 8 | public class QueryStringParametersList 9 | { 10 | private List> list { get; set; } 11 | 12 | public QueryStringParametersList() 13 | { 14 | list = new List>(); 15 | } 16 | 17 | public void Add(string key, string value) 18 | { 19 | list.Add(new KeyValuePair(key, value)); 20 | } 21 | 22 | public string GetQueryStringPostfix() 23 | { 24 | return string.Join("&", list.Select(p => Uri.EscapeDataString(p.Key) + "=" + Uri.EscapeDataString(p.Value))); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /GoogleMapsApi/ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | # Release notes 2 | 3 | ## V 0.41 4 | * Fixed sub steps for directions (9712e572b89ee2eb552728109e616547ed085b52) 5 | * Added PlaceId (b23882eaba698d049ad4707593de24a127bf3bea) 6 | * The Id and References fields are being deprecated in favor of PlaceId. I've added the PlaceId field. (3162e9acfa821cb2a5ee835a608693faf81e7e47) 7 | * Autocomplete APIs (f57ff14dc4e32f06f917b5b7bf0ce447ad00047a) -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Entities/ImageSize.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Entities 2 | { 3 | /// 4 | /// Images may be retrieved in sizes up to 640 by 640 pixels. The size parameter takes a string with two values separated by the x character. 640x640 is the largest image size allowed. Note that the center parameter, combined with the size parameter implicitly defines the coverage area of the map image. 5 | /// 6 | public struct ImageSize 7 | { 8 | public readonly int Width; 9 | public readonly int Height; 10 | 11 | public ImageSize(int width, int height) 12 | { 13 | Width = width; 14 | Height = height; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Entities/MapStyle.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.StaticMaps.Enums; 2 | 3 | namespace GoogleMapsApi.StaticMaps.Entities 4 | { 5 | /// 6 | /// Styled maps allow you to customize the presentation of the standard Google map styles, changing the visual display of such elements as roads, parks, and built-up areas to reflect a different style than that used in the default map type. These components are known as features and a styled map allows you to select these features and apply visual styles to their display (including hiding them entirely). With these changes, the map can be made to emphasize particular components or complement content within the surrounding page. 7 | /// A customized "styled" map consists of one or more specified styles, each indicated through a style parameter within the Static Map request URL. Additional styles are specified by passing additional style parameters. A style consists of a selection(s) and a set of rules to apply to that selection. The rules indicate what visual modification to make to the selection. 8 | /// 9 | public class MapStyle 10 | { 11 | /// 12 | /// (optional) indicates what features to select for this style modification. (See Map Features below.) If no feature argument is passed, all features will be selected. 13 | /// 14 | public MapFeature MapFeature { get; set; } 15 | 16 | /// 17 | /// (optional) indicates what sub-set of the selected features to select. (See Map Elements below.) If no element argument is passed, all elements of the given feature will be selected. 18 | /// 19 | public MapElement MapElement { get; set; } 20 | 21 | /// 22 | /// (an RGB hex string of format 0xRRGGBB) indicates the basic color to apply to the selection. 23 | /// 24 | public string HUE { get; set; } 25 | 26 | /// 27 | /// (a floating point value between -100 and 100) indicates the percentage change in brightness of the element. Negative values increase darkness (where -100 specifies black) while positive values increase brightness (where +100 specifies white). 28 | /// 29 | public float? Lightness { get; set; } 30 | 31 | /// 32 | /// (a floating point value between -100 and 100) indicates the percentage change in intensity of the basic color to apply to the element. 33 | /// 34 | public float? Saturation { get; set; } 35 | 36 | /// 37 | /// (a floating point value between 0.01 and 10.0, where 1.0 applies no correction) indicates the amount of gamma correction to apply to the element. Gammas modify the lightness of hues in a non-linear fashion, while unaffecting white or black values. Gammas are typically used to modify the contrast of multiple elements. For example, you could modify the gamma to increase or decrease the contrast between the edges and interiors of elements. Low gamma values (less than 1) increase contrast, while high values (> 1) decrease contrast. 38 | /// 39 | public float? Gamma { get; set; } 40 | 41 | /// 42 | /// simply inverts the existing lightness. 43 | /// 44 | public bool InverseLightness { get; set; } 45 | 46 | /// 47 | /// indicates whether and how the element appears on the map. visibility:simplified indicates that the map should simplify the presentation of those elements as it sees fit. (A simplified road structure may show fewer roads, for example.) 48 | /// 49 | public MapVisibility MapVisibility { get; set; } 50 | } 51 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Entities/Marker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.StaticMaps.Entities 5 | { 6 | /// 7 | /// The markers parameter defines a set of one or more markers at a set of locations. Each marker defined within a single markers declaration must exhibit the same visual style; if you wish to display markers with different styles, you will need to supply multiple markers parameters with separate style information. 8 | /// 9 | public class Marker 10 | { 11 | /// 12 | /// Marker's style 13 | /// 14 | public MarkerStyle Style { get; set; } 15 | 16 | public IList Locations { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Entities/MarkerStyle.cs: -------------------------------------------------------------------------------- 1 | using GoogleMapsApi.StaticMaps.Enums; 2 | 3 | namespace GoogleMapsApi.StaticMaps.Entities 4 | { 5 | public class MarkerStyle 6 | { 7 | /// 8 | /// (optional) specifies the size of marker from the set {tiny, mid, small}. If no size parameter is set, the marker will appear in its default (normal) size. 9 | /// 10 | public MarkerSize Size { get; set; } 11 | 12 | /// 13 | /// optional) specifies a 24-bit color (example: color=0xFFFFCC) or a predefined color from the set {black, brown, green, purple, yellow, blue, gray, orange, red, white}. 14 | /// Note that transparencies (specified using 32-bit hex color values) are not supported in markers, though they are supported for paths. 15 | /// 16 | public string Color { get; set; } 17 | 18 | /// 19 | /// (optional) specifies a single uppercase alphanumeric character from the set {A-Z, 0-9}. 20 | /// (The requirement for uppercase characters is new to this version of the API.) 21 | /// Note that default and mid sized markers are the only markers capable of displaying an alphanumeric-character parameter. 22 | /// tiny and small markers are not capable of displaying an alphanumeric-character. 23 | /// 24 | public string Label { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Entities/Path.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using GoogleMapsApi.Entities.Common; 3 | 4 | namespace GoogleMapsApi.StaticMaps.Entities 5 | { 6 | public class Path 7 | { 8 | public PathStyle Style { get; set; } 9 | 10 | public IList Locations { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Entities/PathStyle.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Entities 2 | { 3 | public class PathStyle 4 | { 5 | /// 6 | /// (optional) specifies the thickness of the path in pixels. If no weight parameter is set, the path will appear in its default thickness (5 pixels). 7 | /// 8 | public int Weight { get; set; } 9 | 10 | /// 11 | /// (optional) specifies a color either as a 24-bit (example: color=0xFFFFCC) or 32-bit hexadecimal value (example: color=0xFFFFCCFF), or from the set {black, brown, green, purple, yellow, blue, gray, orange, red, white}. 12 | /// When a 32-bit hex value is specified, the last two characters specify the 8-bit alpha transparency value. This value varies between 00 (completely transparent) and FF (completely opaque). Note that transparencies are supported in paths, though they are not supported for markers. 13 | /// 14 | public string Color { get; set; } 15 | 16 | /// 17 | /// (optional) indicates both that the path marks off a polygonal area and specifies the fill color to use as an overlay within that area. The set of locations following need not be a "closed" loop; the Static Map server will automatically join the first and last points. Note, however, that any stroke on the exterior of the filled area will not be closed unless you specifically provide the same beginning and end location. 18 | /// 19 | public string FillColor { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Enums/ImageFormat.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Enums 2 | { 3 | /// 4 | /// Images may be returned in several common web graphics formats: GIF, JPEG and PNG. The format parameter takes one of the following values: 5 | /// png8 or png (default) specifies the 8-bit PNG format. 6 | /// png32 specifies the 32-bit PNG format. 7 | /// gif specifies the GIF format. 8 | /// jpg specifies the JPEG compression format. 9 | /// jpg-baseline specifies a non-progressive JPEG compression format. 10 | /// jpg and jpg-baseline typically provide the smallest image size, though they do so through "lossy" compression which may degrade the image. gif, png8 and png32 provide lossless compression. 11 | /// Most JPEG images are progressive, meaning that they load a coarser image earlier and refine the image resolution as more data arrives. This allows images to be loaded quickly in webpages and is the most widespread use of JPEG currently. However, some uses of JPEG (especially printing) require non-progressive (baseline) images. In such cases, you may want to use the jpg-baseline format, which is non-progressive. 12 | /// 13 | public enum ImageFormat 14 | { 15 | /// 16 | /// (default) specifies the 8-bit PNG format. 17 | /// 18 | PNG8, 19 | /// 20 | /// specifies the 32-bit PNG format. 21 | /// 22 | PNG32, 23 | /// 24 | /// specifies the GIF format. 25 | /// 26 | GIF, 27 | /// 28 | /// specifies the JPEG compression format. 29 | /// 30 | JPG, 31 | /// 32 | /// specifies a non-progressive JPEG compression format. 33 | /// 34 | JPG_baseline 35 | } 36 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Enums/MapElement.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Enums 2 | { 3 | /// 4 | /// Additionally, some features on a map typically consist of different elements. A road, for example, consists of not only the graphical line (geometry) on the map, but the text denoting its name (labels) attached the map. Elements within features are selected by declaring an element argument 5 | /// 6 | public enum MapElement 7 | { 8 | All, 9 | Geometry, 10 | Labels 11 | } 12 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Enums/MapFeatures.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Enums 2 | { 3 | /// 4 | /// A map consists of a set of features, such as roads or parks. The feature types form a category tree, with feature:all as the root. 5 | /// 6 | public enum MapFeature 7 | { 8 | All, 9 | Road, 10 | Landscape 11 | } 12 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Enums/MapType.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Enums 2 | { 3 | public enum MapType 4 | { 5 | /// 6 | /// (default) specifies a standard roadmap image, as is normally shown on the Google Maps website. If no maptype value is specified, the Static Maps API serves roadmap tiles by default. 7 | /// 8 | Roadmap, 9 | /// 10 | /// specifies a satellite image. 11 | /// 12 | Satellite, 13 | /// 14 | /// specifies a physical relief map image, showing terrain and vegetation. 15 | /// 16 | Terrain, 17 | /// 18 | /// specifies a hybrid of the satellite and roadmap image, showing a transparent layer of major streets and place names on the satellite image. 19 | /// 20 | Hybrid 21 | } 22 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Enums/MapVisibility.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Enums 2 | { 3 | public enum MapVisibility 4 | { 5 | On, 6 | Off, 7 | Simplified 8 | } 9 | } -------------------------------------------------------------------------------- /GoogleMapsApi/StaticMaps/Enums/MarkerSize.cs: -------------------------------------------------------------------------------- 1 | namespace GoogleMapsApi.StaticMaps.Enums 2 | { 3 | public enum MarkerSize 4 | { 5 | Mid, 6 | Tiny, 7 | Small 8 | } 9 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012, Maxim Novak 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/maximn/google-maps/actions/workflows/dotnet.yml/badge.svg)](https://github.com/maximn/google-maps/actions/workflows/dotnet.yml) 2 | [![NuGet Status](https://img.shields.io/nuget/v/GoogleMapsApi.svg)](https://www.nuget.org/packages/GoogleMapsApi/) 3 | 4 | google-maps 5 | =========== 6 | 7 | Google Maps Web Services API wrapper for .NET 8 | 9 | For Quickstart and more info read the wiki pages (https://github.com/maximn/google-maps/wiki) 10 | 11 | The web page - http://maximn.github.com/google-maps 12 | 13 | NuGet page - https://www.nuget.org/packages/GoogleMapsApi/ 14 | 15 | 16 | **Check out my blog at http://maxondev.com** 17 | 18 | # Quickstart 19 | 20 | This library wraps Google maps API. 21 | 22 | You can easily query Google maps for Geocoding, Directions, Elevation, and Places. 23 | 24 | NEW! Now you can easily show the results on a Static Google Map! 25 | 26 | This Library is well documented and easy to use. 27 | 28 | Code sample - 29 | ``` C# 30 | using GoogleMapsApi; 31 | using GoogleMapsApi.Entities.Common; 32 | using GoogleMapsApi.Entities.Directions.Request; 33 | using GoogleMapsApi.Entities.Directions.Response; 34 | using GoogleMapsApi.Entities.Geocoding.Request; 35 | using GoogleMapsApi.Entities.Geocoding.Response; 36 | using GoogleMapsApi.StaticMaps; 37 | using GoogleMapsApi.StaticMaps.Entities; 38 | 39 | //Static class use (Directions) (Can be made from static/instance class) 40 | DirectionsRequest directionsRequest = new DirectionsRequest() 41 | { 42 | Origin = "NYC, 5th and 39", 43 | Destination = "Philladephia, Chesnut and Wallnut", 44 | }; 45 | 46 | DirectionsResponse directions = GoogleMaps.Directions.Query(directionsRequest); 47 | Console.WriteLine(directions); 48 | 49 | //Instance class use (Geocode) (Can be made from static/instance class) 50 | GeocodingRequest geocodeRequest = new GeocodingRequest() 51 | { 52 | Address = "new york city", 53 | }; 54 | var geocodingEngine = GoogleMaps.Geocode; 55 | GeocodingResponse geocode = geocodingEngine.Query(geocodeRequest); 56 | Console.WriteLine(geocode); 57 | 58 | // Static maps API - get static map of with the path of the directions request 59 | StaticMapsEngine staticMapGenerator = new StaticMapsEngine(); 60 | 61 | //Path from previos directions request 62 | IEnumerable steps = directions.Routes.First().Legs.First().Steps; 63 | // All start locations 64 | IList path = steps.Select(step => step.StartLocation).ToList(); 65 | // also the end location of the last step 66 | path.Add(steps.Last().EndLocation); 67 | 68 | string url = staticMapGenerator.GenerateStaticMapURL(new StaticMapRequest(new Location(40.38742, -74.55366), 9, new ImageSize(800, 400)) 69 | { 70 | Pathes = new List(){ new GoogleMapsApi.StaticMaps.Entities.Path() 71 | { 72 | Style = new PathStyle() 73 | { 74 | Color = "red" 75 | }, 76 | Locations = path 77 | }} 78 | }); 79 | Console.WriteLine("Map with path: " + url); 80 | ``` 81 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | --------------------------------------------------------------------------------