Close
Angular React Web Components Blazor WinUI Uno Platform Angular
Premium

Angular 地理的データ モデルのバインディング

Ignite UI for Angular マップ コンポーネントは、シェイプ ファイルからの地理空間データやデータ モデルからの地理的位置を地理的画像マップに表示するように設計されています。地理的シリーズの dataSource プロパティは、データ モデルへのバインディングのために使用されます。このプロパティは、カスタム オブジェクトの配列にバインドできます。

Angular 地理的データ モデルのバインディングの例

以下の表で、地理的シリーズのタイプごとに必要となるデータ構造を簡単に説明します。

Geographic シリーズ プロパティ 概要
IgxGeographicSymbolSeriesComponent longitudeMemberPath、latitudeMemberPath 2 つの数値の経度と緯度座標の名前を指定します。
IgxGeographicHighDensityScatterSeriesComponent longitudeMemberPath、latitudeMemberPath 2 つの数値の経度と緯度座標の名前を指定します。
IgxGeographicProportionalSymbolSeriesComponent longitudeMemberPath、latitudeMemberPath、radiusMemberPath 2 つの経度座標と緯度座標の名前と、シンボルのサイズ/半径の数字列を 1 列指定します。
IgxGeographicScatterAreaSeriesComponent longitudeMemberPath、latitudeMemberPath、colorMemberPath 数値の三角測量のために、2 つの経度と緯度座標および数値列を 1 列指定します。
IgxGeographicContourLineSeriesComponent longitudeMemberPath、latitudeMemberPath、valueMemberPath 数値の三角測量のために、2 つの経度と緯度座標および数値列を 1 列指定します。
IgxGeographicShapeSeriesComponent shapeMemberPath 図形の地理的ポイントを含む dataSource 項目のデータ列の名前を指定します。このプロパティは、x プロパティと y プロパティを持つオブジェクトの配列の配列にマップする必要があります。
IgxGeographicPolylineSeriesComponent shapeMemberPath 線の地理的座標を含む dataSource 項目のデータ列の名前を指定します。このプロパティは、x プロパティと y プロパティを持つオブジェクトの配列の配列にマップする必要があります。

コード スニペット

以下のコードは、IgxGeographicSymbolSeriesComponent を、経度と緯度の座標を使用して格納された世界の一部の都市の地理的位置を含むカスタム データ モデルにバインドする方法を示します。また、以下のコードで全体を示す MapGeodesics の大円距離の計算を使用してこれらの場所間の最短の地理的経路をプロットするために IgxGeographicPolylineSeriesComponent を使用します。

<igx-geographic-map
    #geoMap
    height="100%"
    width="100%"
    zoomable="true">
</igx-geographic-map>
import { IgxGeographicMapComponent, IgxGeographicPolylineSeriesComponent, IgxGeographicSymbolSeriesComponent } from 'igniteui-angular-maps';
import { MarkerType } from 'igniteui-angular-charts';
// ...
/**
 * Great circle maths for a map: the path between two locations, and how far apart they are.
 */
export class MapGeodesics {

    // calculate geo-paths between two locations using great circle formula
    public calcPaths(origin: any, dest: any): any[] {
        let interval = 200;
        let paths: any[] = [[]];
        let pathID = 0;
        let 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 });

                let bearing = this.calcBearing(current, dest);
                current = this.calcDestination(current, bearing, interval);
                // ensure geo-path wrap around the world through the new date-line
                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;
    }

    // calculate bearing angle between two locations
    public calcBearing(origin: any, dest: any): number
    {
        origin = this.toRadianLocation(origin);
        dest = this.toRadianLocation(dest);
        let range = (dest.lon - origin.lon);
        let y = Math.sin(range) * Math.cos(dest.lat);
        let x = Math.cos(origin.lat) * Math.sin(dest.lat) -
                Math.sin(origin.lat) * Math.cos(dest.lat) * Math.cos(range);
        let angle = Math.atan2(y, x);
        return this.toDegreesNormalized(angle);
    }

    // calculate destination for origin location and travel distance
    public calcDestination(origin: any, bearing: number, distance: number): any {
        let radius = 6371.0;
        origin = this.toRadianLocation(origin);
        bearing = this.toRadians(bearing);
        distance = distance / radius; // angular distance in radians

        let lat = Math.asin(Math.sin(origin.lat) * Math.cos(distance) +
                       Math.cos(origin.lat) * Math.sin(distance) * Math.cos(bearing));
        let x = Math.sin(bearing) * Math.sin(distance) * Math.cos(origin.lat);
        let y = Math.cos(distance) - Math.sin(origin.lat) * Math.sin(origin.lat);
        let lon = origin.lon + Math.atan2(x, y);
        // normalize lon to coordinate between -180º and +180º
        lon = (lon + 3 * Math.PI) % (2 * Math.PI) - Math.PI;

        lon = this.toDegrees(lon);
        lat = this.toDegrees(lat);

        return { lon: lon, lat: lat };
    }

    // calculate distance between two locations
    public calcDistance(origin: any, dest: any): number {
        origin = this.toRadianLocation(origin);
        dest = this.toRadianLocation(dest);
        let sinProd = Math.sin(origin.lat) * Math.sin(dest.lat);
        let cosProd = Math.cos(origin.lat) * Math.cos(dest.lat);
        let lonDelta = (dest.lon - origin.lon);

        let angle = Math.acos(sinProd + cosProd * Math.cos(lonDelta));
        let distance = angle * 6371.0;
        return distance; // * 6371.0; // in km
    }

    public toRadianLocation(geoPoint: any): any {
        let x = this.toRadians(geoPoint.lon);
        let y = this.toRadians(geoPoint.lat);
        return { lon: x, lat: y };
    }

    public toRadians(degrees: number): number
    {
        return degrees * Math.PI / 180;
    }

    public toDegrees(radians: number): number {
        return (radians * 180.0 / Math.PI);
    }

    public toDegreesNormalized(radians: number): number
    {
        let degrees = this.toDegrees(radians);
        degrees = (degrees + 360) % 360;
        return degrees;
    }
}
// ...
private mapGeodesics: MapGeodesics = new MapGeodesics();

public mapBindingDataModelOnViewInit(): void {
    var geoMap = this.geoMap;
    geoMap.updateZoomWindow({ left: 0.2, top: 0.1, width: 0.6, height: 0.6 });

    var cityDAL = { lat: 32.763, lon: -96.663, country: "US", name: "Dallas" };
    var citySYD = { lat: -33.889, lon: 151.028, country: "Australia", name: "Sydney" };
    var cityNZL = { lat: -36.848, lon: 174.763, country: "New Zealand", name: "Auckland" };
    var cityQTR = { lat: 25.285, lon: 51.531, country: "Qatar", name: "Doha" };
    var cityPAN = { lat: 8.949, lon: -79.4, country: "Panama", name: "Panama" };
    var cityCHL = { lat: -33.475, lon: -70.647, country: "Chile", name: "Santiago" };
    var cityJAP = { lat: 35.683, lon: 139.809, country: "Japan", name: "Tokyo" };
    var cityALT = { lat: 33.795, lon: -84.349, country: "US", name: "Atlanta" };
    var cityJOH = { lat: -26.178, lon: 28.004, country: "South Africa", name: "Johannesburg" };
    var cityNYC = { lat: 40.75, lon: -74.0999, country: "US", name: "New York" };
    var citySNG = { lat: 1.229, lon: 104.177, country: "Singapore", name: "Singapore" };
    var cityMOS = { lat: 55.75, lon: 37.7, country: "Russia", name: "Moscow" };
    var cityROM = { lat: 41.88, lon: 12.52, country: "Italy", name: "Roma" };
    var cityLAX = { lat: 34.0, lon: -118.25, country: "US", name: "Los Angeles" };

    var 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" }
    ];

    // the route first, so that the cities at either end of it draw on top
    for (var i = 0; i < flights.length; i++) {
        this.addFlightRoute(geoMap, flights[i]);
        this.addFlightCities(geoMap, flights[i]);
    }
}

/** the flight itself, as a great circle path between its two cities */
public addFlightRoute(geoMap: any, flight: any): void {
    var geodesics = this.mapGeodesics;
    var geoPath = geodesics.calcPaths(flight.origin, flight.dest);
    var geoDistance = geodesics.calcDistance(flight.origin, flight.dest);
    var geoRoutes = [{
        points: geoPath,
        origin: flight.origin,
        dest: flight.dest,
        distance: geoDistance,
        time: geoDistance / 850
    }];

    var lineSeries = new IgxGeographicPolylineSeriesComponent();
    lineSeries.dataSource = geoRoutes;
    lineSeries.shapeMemberPath = "points";
    lineSeries.shapeStrokeThickness = 9;
    lineSeries.shapeOpacity = 0.5;
    lineSeries.shapeStroke = flight.color;
    geoMap.series.add(lineSeries);
}

/** the cities at either end, in the flight's own colour */
public addFlightCities(geoMap: any, flight: any): void {
    var geoLocations = [flight.origin, flight.dest];

    var 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;
    geoMap.series.add(symbolSeries);
}

API リファレンス

IgxGeographicContourLineSeriesComponent
IgxGeographicHighDensityScatterSeriesComponent
IgxGeographicPolylineSeriesComponent
IgxGeographicProportionalSymbolSeriesComponent
IgxGeographicScatterAreaSeriesComponent
IgxGeographicSymbolSeriesComponent