Using Angular To Travel To The Other Side Of The World
With Angular, a tiny bit of math, Google Maps, and the OpenWeatherMap api, you can discover what it’s like on the exact other side of the globe.
Antipode
You can also enter custom coordinates for your starting position so you can discover the antipode for any place in the world!
NOTE: An antipode map. If you’re standing on a blue country, your antipode is the same country in yellow
Spoiler Alert:
Creating the app through StackBlitz
Remove the “Hello” Component
This is how you remove the “Hello” component:
- Delete the
hello.component.ts
file.
- Delete the “HelloComponent” references in app.module.ts
- Delete the
<hello>
element in app.component.html
- Refresh is necessary. Your app should have removed the “Hello Angular 12” at the top.
Add new Weather component
- Right click on the “app” directory and select Angular Generator, then Component.
2. When it asks for a name, enter “Weather”
3. You’ll see that a new directory has been made with 3 files:
- weather.component.css,
- weather.component.html,
- weather.component.ts.
These files make up your Weather component.
This new Weather component will display the weather information about your current location and your antipode.
Add Weather component to module
- In app.module.ts, add WeatherComponent to declarations array next to AppComponent. Don’t forget to import it!
- In app.component.html, add an
element.
Retrieve Current Location
Retrieving your current location is surprisingly easy with the built-in navigator object in standard JavaScript.
export class AppComponent {
lat: number;
long: number;
constructor() {
this.getLocation();
}
getLocation(keepCoords?: boolean): void {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
this.lat = position.coords.latitude;
this.long = position.coords.longitude;
});
} else {
console.log('No support for geolocation');
}
}
}
Bind class properties to UI inputs
There’s a chance the user won’t allow the code to retrieve its local position, or maybe the user wants to enter a custom location. We’ll give them the option by placing two inputs in the UI so they can enter whatever latitude and longitude they want, but default to their current location.
1. In app.component.html, remove the <p>…</p>
element at the top and add these elements at the top instead:
Latitude:
<input [(ngModel)]="lat" />
Longitude:
<input [(ngModel)]="long" />
2. You should now be able to see your default coordinates!
Add parameters to weather app and display Google maps image
We’ve retrieved our local coordinates, but now we need to be able to use them to display something useful. We’re going to update our Weather component so it takes the latitude and longitude as parameters, pass those parameters to a Google maps url, and then embed that url into an iframe to display to the user.
1. Replace the code in weather.component.ts with this code which populates a property called “src” which we use to populate the iframe:
import { Component, Input, OnChanges } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
@Component({
selector: 'app-weather',
templateUrl: './weather.component.html',
styleUrls: ['./weather.component.css'],
})
export class WeatherComponent implements OnChanges {
@Input() lat: string;
@Input() long: string;
src: SafeResourceUrl;
constructor(private sanitizer: DomSanitizer) {}
ngOnChanges() {
this.updateWeatherData();
}
updateWeatherData(): void {
this.src = this.sanitizer.bypassSecurityTrustResourceUrl(
`https://www.google.com/maps/embed?pb=!1m10!1m8!1m3!1d106203.97188628554!2d${this.long}00000002!3d${this.lat}!3m2!1i1024!2i768!4f13.1!5e0!3m2!1sen!2sus!4v1635881545400!5m2!1sen!2sus`
);
}
}
2. In app.component.html, add the lat and long parameters to the app-weather component. These will be populated with the values in the input fields:
<app-weather lat="{{ lat }}" long="{{ long }}"></app-weather>
<iframe
[src]="src"
width="300"
height="225"
style="border:0;"
allowfullscreen=""
loading="lazy"
></iframe>
4. Now you should see the map centered on the location of your coordinates!
Calculate and Display Antipode
Now that we’re displaying a slick google docs image of our current location, let’s take our coordinates and determine the antipode. The math is very simple: simply take the latitude and multiply it by -1, and then take the absolute value of the longitude and subtract it from 180:
New Latitude = Original Latitude * -1;
New Longitude = 180 – abs (Original Longitude);
The New Latitude and New Longitude give you the coordinates of your antipode!
anti_lat: number;
anti_long: number;
- a. Add a new method for computing the antipode:
computeAntipode(): void {
this.anti_lat = this.lat * -1;
this.anti_long = 180 - Math.abs(this.long);
}
- b. Add a call to computeAntipode after retrieving and set the lat and long:
this.lat = position.coords.latitude;
this.long = position.coords.longitude;
this.computeAntipode();
- c. Add an onChange method that will recompute the antinode. The goal is tie this method to the change events in the original lat and long inputs:
onChange(e: any): void {
this.computeAntipode();
}
<input [(ngModel)]="lat" (ngModelChange)="onChange($event)" />
…
<input [(ngModel)]="long" (ngModelChange)="onChange($event)" />
<app-weather lat="{{ anti_lat }}" long="{{ anti_long }}"></app-weather>
The antipode for anywhere in the United States will be in the Indian Ocean
Displaying Weather Information
To display weather, I made a free account at https://openweathermap.org to use their simple one-call API. It returns data in this format:
Example of the JSON that will be returned when making a call to the OpenWeatherMap one-call-api.
1. In weather.component.ts immediately after the import statements, add a new Weather interface that is to contain the shape of the data we’ll be receiving from the api:
interface Weather {
timezone: string;
timezone_offset: number;
current: {
temp: number;
feels_like: number;
dt: number;
currentTime: string;
sunriseText: string;
sunsetText: string;
sunrise: number;
sunset: number;
wind_speed: number;
weather: { main: string; description: string }[];
};
}
Notice the addition of 3 new properties: currentTime, sunriseText, and sunsetText. This is because dt, sunrise, and sunset are all stored in number format when coming from the open weather api. We want to transform them into new, human-readable strings.
2. Then add a new weather property under the existing src property. This property will store the JSON data we receive from the open weather api:
src: SafeResourceUrl;
weather: Weather;
…
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [BrowserModule, FormsModule, HttpClientModule],
…
import { HttpClient } from '@angular/common/http';
…
…
constructor(private sanitizer: DomSanitizer, private http: HttpClient) {}
- a. Because certain dates will come in UNIX format and we’ll want to convert them to human-readable code, lets add a method in the class to do that:
convertDate(unixDate: number): string {
const date = new Date(unixDate * 1000);
return date.toLocaleString();
}
- b. Then at the end of the updateWeatherData function, add this bit of code which calls the open weather api and transfers the data to the local weather property:
if (this.lat && this.long)
this.http
.get<Weather>(
`https://api.openweathermap.org/data/2.5/onecall?lat=${this.lat}&lon=${this.long}&exclude=hourly,daily&appid=1a30e79ce8715662d0b2ddd6c6212fa6&units=imperial`
)
.subscribe((x) => {
this.weather = {
...x,
current: {
...x.current,
sunriseText: this.convertDate(x.current.sunrise),
sunsetText: this.convertDate(x.current.sunset),
currentTime: this.convertDate(x.current.dt),
},
};
});
<p>Temperature: {{ weather?.current?.temp }} F</p>
<p>Feels Like: {{ weather?.current?.feels_like }} F</p>
<p>Sunrise: {{ weather?.current?.sunriseText }}</p>
<p>Sunset: {{ weather?.current?.sunsetText }}</p>
<p>Time zone: {{ weather?.timezone }}</p>
<p>Weather: {{ weather?.current?.weather[0]?.main }}</p>
And that’s it! Here’s a final version here: https://angular-ivy-lqwdux.stackblitz.io
Conclusion
If you’d like to see the coordinates for some popular places, please take a look at the list below. As you update the latitude and longitude, the Google Maps iframe and open weather api should automatically update:
City |
Latitude |
Longitude |
Minneapolis, MN |
45 |
-95 |
New York City, NY |
40 |
-75 |
Asuncion, Paraguay |
-25 |
-60 |
Rio De Janeiro, Brazil |
-25 |
-45 |
Honolulu, HI |
20 |
-160 |
Rome, Italy |
40 |
10 |
London, England |
50 |
0 |
Beijing, China |
40 |
115 |
Index
Author
by Luis Camacho III – Intertech, Inc. Consultant
Three Great Reasons To Let Intertech Build Your Software “Right” The First Time!
To understand why so many companies rely on Intertech for their software consulting and software education needs, you must understand the importance we place on staying up-to-date with the most current technologies and methodologies.
“When an outside firm asked over 4000 of our customers these questions, we immediately understood why they trusted Intertech!”
Say “Yes” To Intertech!
- Would you use Intertech again? 99.55%
99.55% of customers answered YES!
- Are you happy with Intertech? 99.55%
99.55% of customers answered YES!
- Would you refer Intertech to others? 99.70%
99.70% of customers answered YES!
Clients Testimonials
“We look forward to working with Intertech on future projects to drive even more value from our data.”
99.55% Of Our Past Clients Said “Yes, They Would Work With Us Again!”
“Intertech’s SQL expertise was invaluable in improving our database server performance. Thanks to the guidance and work from Intertech consultants, we’ve reduced runtime on common queries, modernized our technology stack, created a platform for real-time sales feedback, and enabled more comprehensive strategic planning for our company. We look forward to working with Intertech on future projects to drive even more value from our data.” — Tom B
“Intertech eliminated hundreds of hours in manual work…”
“Working with Intertech has been a great experience. Converting a manual process of entering data into spreadsheets to a new online system gives us access to real-time results. We have modernized our business like no one else in the market. Eliminating hundreds of hours in manual work, while giving our customers a tool to quickly manage their business and improve profits is a great benefit we can now offer.” — Jay W
“It was a pleasure working with everyone at Intertech.”
“Thanks everyone for all of your hard work on another successful portal project! As always, it has been a pleasure working with everyone at Intertech.” — Sandra K
“A credit to their hard work…”
“It’s great to hear about the positive responses to eCharging and the enthusiasm shown by those involved. These remarks are a credit to the hard work that you and the rest of the eCharging team have put into the project. These comments remind us of the important impact our daily work has on improving the criminal justice system across the state. Good work and congratulations!” — Robert H