Angular 地理的データ モデルのバインディング
Ignite UI for Angular マップ コンポーネントは、シェイプ ファイルからの地理空間データやデータ モデルからの地理的位置を地理的画像マップに表示するように設計されています。地理的シリーズの ItemsSource
プロパティは、データ モデルへのバインディングのために使用されます。このプロパティは、カスタム オブジェクトの配列にバインドできます。
Angular 地理的データ モデルのバインディングの例
EXAMPLE
DATA
MODULES
TS
HTML
SCSS
export class WorldUtility {
public static calcPaths(origin: any, dest: any): any[] {
const interval = 200;
const paths: any[] = [[]];
let pathID = 0;
const distance = this.calcDistance(origin, dest);
if (distance <= interval) {
paths[pathID].push({ x: origin.lon, y: origin.lat });
paths[pathID].push({ x: dest.lon, y: dest.lat });
} else {
let current = origin;
let previous = origin;
for (let dist = interval; dist <= distance; dist += interval) {
previous = current;
paths[pathID].push({ x: current.lon, y: current.lat });
const bearing = this.calcBearing(current, dest);
current = this.calcDestination(current, bearing, interval);
if (previous.lon > 150 && current.lon < -150) {
paths[pathID].push({ x: 180, y: current.lat });
paths.push([]);
pathID++;
current = { lon: -180, lat: current.lat };
} else if (previous.lon < -150 && current.lon > 150) {
paths[pathID].push({ x: -180, y: current.lat });
paths.push([]);
pathID++;
current = { lon: 180, lat: current.lat };
}
}
paths[pathID].push({ x: dest.lon, y: dest.lat });
}
return paths;
}
public static calcBearing(origin: any, dest: any): number {
origin = this.toRadianLocation(origin);
dest = this.toRadianLocation(dest);
const range = (dest.lon - origin.lon);
const y = Math.sin(range) * Math.cos(dest.lat);
const x = Math.cos(origin.lat) * Math.sin(dest.lat) -
Math.sin(origin.lat) * Math.cos(dest.lat) * Math.cos(range);
const angle = Math.atan2(y, x);
return this.toDegreesNormalized(angle);
}
public static calcDestination(origin: any, bearing: number, distance: number): any {
const radius = 6371.0;
origin = this.toRadianLocation(origin);
bearing = this.toRadians(bearing);
distance = distance / radius;
let lat = Math.asin(Math.sin(origin.lat) * Math.cos(distance) +
Math.cos(origin.lat) * Math.sin(distance) * Math.cos(bearing));
const x = Math.sin(bearing) * Math.sin(distance) * Math.cos(origin.lat);
const y = Math.cos(distance) - Math.sin(origin.lat) * Math.sin(origin.lat);
let lon = origin.lon + Math.atan2(x, y);
lon = (lon + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
lon = this.toDegrees(lon);
lat = this.toDegrees(lat);
return { lon, lat };
}
public static calcDistance(origin: any, dest: any): number {
origin = this.toRadianLocation(origin);
dest = this.toRadianLocation(dest);
const sinProd = Math.sin(origin.lat) * Math.sin(dest.lat);
const cosProd = Math.cos(origin.lat) * Math.cos(dest.lat);
const lonDelta = (dest.lon - origin.lon);
const angle = Math.acos(sinProd + cosProd * Math.cos(lonDelta));
const distance = angle * 6371.0;
return distance;
}
public static toRadianLocation(geoPoint: any): any {
const x = this.toRadians(geoPoint.lon);
const y = this.toRadians(geoPoint.lat);
return { lon: x, lat: y };
}
public static toRadians(degrees: number): number {
return degrees * Math.PI / 180;
}
public static toDegrees(radians: number): number {
return (radians * 180.0 / Math.PI);
}
public static toDegreesNormalized(radians: number): number {
let degrees = this.toDegrees(radians);
degrees = (degrees + 360) % 360;
return degrees;
}
public static toStringLat(latitude: number): string {
const str = Math.abs(latitude).toFixed(1) + "°";
return latitude > 0 ? str + "N" : str + "S";
}
public static toStringLon(coordinate: number): string {
const val = Math.abs(coordinate);
const str = val < 100 ? val.toFixed(1) : val.toFixed(0);
return coordinate > 0 ? str + "°E" : str + "°W";
}
public static toStringAbbr(value: number): string {
if (value > 1000000000000) {
return (value / 1000000000000).toFixed(1) + " T";
} else if (value > 1000000000) {
return (value / 1000000000).toFixed(1) + " B";
} else if (value > 1000000) {
return (value / 1000000).toFixed(1) + " M";
} else if (value > 1000) {
return (value / 1000).toFixed(1) + " K";
}
return value.toFixed(0);
}
public static getLongitude(location: any): number {
if (location.x) { return location.x; }
if (location.lon) { return location.lon; }
if (location.longitude) { return location.longitude; }
return Number.NaN;
}
public static getLatitude(location: any): number {
if (location.y) { return location.y; }
if (location.lat) { return location.lat; }
if (location.latitude) { return location.latitude; }
return Number.NaN;
}
public static getBounds(locations: any[]): any {
let minLat = 90;
let maxLat = -90;
let minLon = 180;
let maxLon = -180;
for (const location of locations) {
const crrLon = this.getLongitude(location);
if (!Number.isNaN(crrLon)) {
minLon = Math.min(minLon, crrLon);
maxLon = Math.max(maxLon, crrLon);
}
const crrLat = this.getLatitude(location);
if (!Number.isNaN(crrLat)) {
minLat = Math.min(minLat, crrLat);
maxLat = Math.max(maxLat, crrLat);
}
}
const geoBounds = {
left: minLon,
top: minLat,
width: Math.abs(maxLon - minLon),
height: Math.abs(maxLat - minLat)
};
return geoBounds;
}
}
ts
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { CommonModule } from "@angular/common";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { IgxGeographicMapModule } from "igniteui-angular-maps";
import { IgxDataChartInteractivityModule } from "igniteui-angular-charts";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
CommonModule,
FormsModule,
IgxGeographicMapModule,
IgxDataChartInteractivityModule
],
providers: [],
schemas: []
})
export class AppModule {}
ts
import { AfterViewInit, Component, TemplateRef, ViewChild } from "@angular/core";
import { MarkerType } from "igniteui-angular-charts";
import { IgxGeographicMapComponent } from "igniteui-angular-maps";
import { IgxGeographicPolylineSeriesComponent } from "igniteui-angular-maps";
import { IgxGeographicSymbolSeriesComponent } from "igniteui-angular-maps";
import { WorldUtility } from "./WorldUtility";
@Component({
standalone: false,
selector: "app-root",
styleUrls: ["./app.component.scss"],
templateUrl: "./app.component.html"
})
export class AppComponent implements AfterViewInit {
@ViewChild("map", { static: true })
public map: IgxGeographicMapComponent;
@ViewChild("pointSeriesTooltipTemplate", { static: true })
public pointSeriesTooltipTemplate: TemplateRef<object>;
@ViewChild("polylineSeriesTooltipTemplate", { static: true })
public polylineSeriesTooltipTemplate: TemplateRef<object>;
public flights: any[];
constructor() {
}
public ngAfterViewInit(): void {
const cityDAL = { lat: 32.763, lon: -96.663, country: "US", name: "Dallas" };
const citySYD = { lat: -33.889, lon: 151.028, country: "Australia", name: "Sydney" };
const cityNZL = { lat: -36.848, lon: 174.763, country: "New Zealand", name: "Auckland" };
const cityQTR = { lat: 25.285, lon: 51.531, country: "Qatar", name: "Doha" };
const cityPAN = { lat: 8.949, lon: -79.400, country: "Panama", name: "Panama" };
const cityCHL = { lat: -33.475, lon: -70.647, country: "Chile", name: "Santiago" };
const cityJAP = { lat: 35.683, lon: 139.809, country: "Japan", name: "Tokyo" };
const cityALT = { lat: 33.795, lon: -84.349, country: "US", name: "Atlanta" };
const cityJOH = { lat: -26.178, lon: 28.004, country: "South Africa", name: "Johannesburg" };
const cityNYC = { lat: 40.750, lon: -74.0999, country: "US", name: "New York" };
const citySNG = { lat: 1.229, lon: 104.177, country: "Singapore", name: "Singapore" };
const cityMOS = { lat: 55.750, lon: 37.700, country: "Russia", name: "Moscow" };
const cityROM = { lat: 41.880, lon: 12.520, country: "Italy", name: "Rome" };
const cityLAX = { lat: 34.000, lon: -118.25, country: "US", name: "Los Angeles" };
this.flights = [
{ origin: cityDAL, dest: citySNG, color: "Green" },
{ origin: cityMOS, dest: cityNZL, color: "Red" },
{ origin: cityCHL, dest: cityJAP, color: "Blue" },
{ origin: cityPAN, dest: cityROM, color: "Orange" },
{ origin: cityALT, dest: cityJOH, color: "Black" },
{ origin: cityNYC, dest: cityQTR, color: "Purple" },
{ origin: cityLAX, dest: citySYD, color: "Gray" }
];
for (const flight of this.flights) {
this.createPolylineSeries(flight);
this.createSymbolSeries(flight);
}
}
public createSymbolSeries(flight: any) {
const geoLocations = [flight.origin, flight.dest ];
const symbolSeries = new IgxGeographicSymbolSeriesComponent ();
symbolSeries.dataSource = geoLocations;
symbolSeries.markerType = MarkerType.Circle;
symbolSeries.latitudeMemberPath = "lat";
symbolSeries.longitudeMemberPath = "lon";
symbolSeries.markerBrush = "White";
symbolSeries.markerOutline = flight.color;
symbolSeries.thickness = 1;
symbolSeries.tooltipTemplate = this.pointSeriesTooltipTemplate;
this.map.series.add(symbolSeries);
}
public createPolylineSeries(flight: any) {
const geoPath = WorldUtility.calcPaths(flight.origin, flight.dest);
const geoDistance = WorldUtility.calcDistance(flight.origin, flight.dest);
const geoRoutes = [
{
dest: flight.dest,
distance: geoDistance,
origin: flight.origin,
points: geoPath,
time: geoDistance / 850
}];
const lineSeries = new IgxGeographicPolylineSeriesComponent ();
lineSeries.dataSource = geoRoutes;
lineSeries.shapeMemberPath = "points";
lineSeries.shapeStrokeThickness = 9;
lineSeries.shapeOpacity = 0.5;
lineSeries.shapeStroke = flight.color;
lineSeries.tooltipTemplate = this.polylineSeriesTooltipTemplate;
this.map.series.add(lineSeries);
}
}
ts
<div class="container vertical">
<igx-geographic-map #map
width="100%"
height="100%"
zoomable="true" >
</igx-geographic-map>
<ng-template let-series="series" let-item="item" #pointSeriesTooltipTemplate>
<div>
<span [style.color]="series.brush">{{item.country}}</span>
</div>
</ng-template>
<ng-template let-series="series" let-item="item" #polylineSeriesTooltipTemplate>
<div>
<span [style.color]="series.brush">Departure: {{item.origin.country}}</span><br/>
<span [style.color]="series.brush">Arrival: {{item.dest.country}}</span>
</div>
</ng-template>
</div>
html
このサンプルが気に入りましたか? 完全な Ignite UI for Angularツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
以下の表で、地理的シリーズのタイプごとに必要となるデータ構造を簡単に説明します。
コード スニペット
以下のコードは、IgxGeographicSymbolSeriesComponent
を、経度と緯度の座標を使用して格納された世界の一部の都市の地理的位置を含むカスタム データ モデルにバインドする方法を示します。また、WorldUtility を使用してこれらの場所間の最短の地理的経路をプロットするために IgxGeographicPolylineSeriesComponent
を使用します。
<div className="sampleRoot" >
<igx-geographic-map #map
width="700px"
height="500px"
zoomable="true" >
</igx-geographic-map>
</div>
<ng-template let-series="series" let-item="item" #pointSeriesTemplate>
<div>
<span [style.color]="series.brush">
{{item.country}}
</span>
</div>
</ng-template>
<ng-template let-series="series" let-item="item" #polylineSeriesTooltipTemplate>
<div>
<span [style.color]="series.brush">
Departure: {{item.origin.country}}
</span>
<br/>
<span [style.color]="series.brush">
Arrival: {{item.dest.country}}
</span>
</div>
</ng-template>
html
import { AfterViewInit, Component, TemplateRef, ViewChild } from "@angular/core";
import { MarkerType } from 'igniteui-angular-charts';
import { IgxGeographicMapComponent } from 'igniteui-angular-maps';
import { IgxGeographicPolylineSeriesComponent } from "igniteui-angular-maps";
import { IgxGeographicSymbolSeriesComponent } from 'igniteui-angular-maps';
import { WorldUtils } from "../../utilities/WorldUtils";
@Component({
selector: "app-map-binding-geographic-data-models",
styleUrls: ["./map-binding-geographic-data-models.component.scss"],
templateUrl: "./map-binding-geographic-data-models.component.html"
})
export class MapBindingDataModelComponent implements AfterViewInit {
@ViewChild ("map")
public map: IgxGeographicMapComponent;
@ViewChild("pointSeriesTemplate")
public pointSeriesTemplate: TemplateRef<object>;
@ViewChild("polylineSeriesTooltipTemplate")
public polylineSeriesTooltipTemplate: TemplateRef<object>;
public flights: any[];
constructor() {
}
public ngAfterViewInit(): void {
const cityDAL = { lat: 32.763, lon: -96.663, country: "US", name: "Dallas" };
const citySYD = { lat: -33.889, lon: 151.028, country: "Australia", name: "Sydney" };
const cityNZL = { lat: -36.848, lon: 174.763, country: "New Zealand", name: "Auckland" };
const cityQTR = { lat: 25.285, lon: 51.531, country: "Qatar", name: "Doha" };
const cityPAN = { lat: 8.949, lon: -79.400, country: "Panama", name: "Panama" };
const cityCHL = { lat: -33.475, lon: -70.647, country: "Chile", name: "Santiago" };
const cityJAP = { lat: 35.683, lon: 139.809, country: "Japan", name: "Tokyo" };
const cityALT = { lat: 33.795, lon: -84.349, country: "US", name: "Atlanta" };
const cityJOH = { lat: -26.178, lon: 28.004, country: "South Africa", name: "Johannesburg" };
const cityNYC = { lat: 40.750, lon: -74.0999, country: "US", name: "New York" };
const citySNG = { lat: 1.229, lon: 104.177, country: "Singapore", name: "Singapore" };
const cityMOS = { lat: 55.750, lon: 37.700, country: "Russia", name: "Moscow" };
const cityROM = { lat: 41.880, lon: 12.520, country: "Italy", name: "Roma" };
const cityLAX = { lat: 34.000, lon: -118.25, country: "US", name: "Los Angeles" };
this.flights = [
{ origin: cityDAL, dest: citySNG, color: "Green" },
{ origin: cityMOS, dest: cityNZL, color: "Red" },
{ origin: cityCHL, dest: cityJAP, color: "Blue" },
{ origin: cityPAN, dest: cityROM, color: "Orange" },
{ origin: cityALT, dest: cityJOH, color: "Black" },
{ origin: cityNYC, dest: cityQTR, color: "Purple" },
{ origin: cityLAX, dest: citySYD, color: "Gray" }
];
for (const flight of this.flights) {
this.createPolylineSeries(flight);
this.createSymbolSeries(flight);
}
}
public createSymbolSeries(flight: any) {
const geoLocations = [flight.origin, flight.dest ];
const symbolSeries = new IgxGeographicSymbolSeriesComponent ();
symbolSeries.dataSource = geoLocations;
symbolSeries.markerType = MarkerType.Circle;
symbolSeries.latitudeMemberPath = "lat";
symbolSeries.longitudeMemberPath = "lon";
symbolSeries.markerBrush = "White";
symbolSeries.markerOutline = flight.color;
symbolSeries.thickness = 1;
symbolSeries.tooltipTemplate = this.pointSeriesTemplate;
this.map.series.add(symbolSeries);
}
public createPolylineSeries(flight: any) {
const geoPath = WorldUtils.calcPaths(flight.origin, flight.dest);
const geoDistance = WorldUtils.calcDistance(flight.origin, flight.dest);
const geoRoutes = [
{
dest: flight.dest,
distance: geoDistance,
origin: flight.origin,
points: geoPath,
time: geoDistance / 850
}];
const lineSeries = new IgxGeographicPolylineSeriesComponent ();
lineSeries.dataSource = geoRoutes;
lineSeries.shapeMemberPath = "points";
lineSeries.shapeStrokeThickness = 9;
lineSeries.shapeOpacity = 0.5;
lineSeries.shapeStroke = flight.color;
lineSeries.tooltipTemplate = this.polylineSeriesTooltipTemplate;
this.map.series.add(lineSeries);
}
}
ts
API リファレンス