0

複数の「ゾーン」で構成されるマップがあり、それぞれがポリゴン オーバーレイとして作成されます。また、ユーザーがルートを定義できるようにし、DirectionsService を使用して、ルートを同じマップhttp://i.stack.imgur.com/DDZI1.png上のポリラインとしてレンダリングします。緑と青の 2 つのゾーンと赤のルートが表示されます。最終バージョンでは、最大 30 のゾーンが定義されます。

私がする必要があるのは、各ゾーンでポリライン (ルート) が費やす距離を計算することです。ルートは、道路のねじれや曲がり方によってはゾーンに何度も出入りする可能性があり、ゾーンの境界と交差せずにルート全体がゾーン内に存在する可能性もあります。

これについてどうすればよいですか?

これは私が現在持っているコードで、マップに 2 つのゾーンを追加して線をプロットするだけです。また、ゾーン「a」にあるセグメントのマップ上に新しいポリラインを描画するために使用するポリゴン内に座標があるかどうかを判断できる「contains」メソッドも追加しました。ただし、これは、頂点間で発生する可能性があるゾーンに最初に入る時期を知るほど具体的ではありません。

// Functions ===============
// =========================

var calcRoute = function (start, end) {

var request = {
    origin: start,
    destination: end,
    travelMode: google.maps.TravelMode.DRIVING,
    provideRouteAlternatives: false,
    avoidHighways: false,
    avoidTolls: false,
    optimizeWaypoints: false
};

// Load directions
directions.service.route(request, function (result, status) {

    if (status == google.maps.DirectionsStatus.OK) {

        // Iterate through each route, adding it to th map
        $(result.routes).each(function onEach(index, route) {

            // Create a new Polyline, set its path to the route path
            var line = new google.maps.Polyline({
                path: route.overview_path,
                strokeColor: "#FF0000",
                strokeOpacity: 1,
                strokeWeight: 2
            });

            // Add line to the map
            line.setMap(map);

            // Find individual line segments
            var inside = [];
            var vertices = line.getPath();
            for (var i = 0; i < vertices.length; i++) {

                var vertix = vertices.getAt(i);

                // Check to see if the vertix exists within a specified Polygon
                if (zones.a.polygon.contains(vertix)) {
                    inside.push(vertix);
                }

            }

            // Add another Polyline for the segments inside the polygon
            var line = new google.maps.Polyline({
                path: inside,
                strokeColor: "#000000",
                strokeOpacity: 1,
                strokeWeight: 4
            });

            // Add line to the map
            line.setMap(map);

        });

    }

});

}

// ray casting alogrithm http://rosettacode.org/wiki/Ray-casting_algorithm
google.maps.Polygon.prototype.contains = function(point) {

var crossings = 0,
    path = this.getPath();

// for each edge
for (var i=0; i < path.getLength(); i++) {
    var a = path.getAt(i),
        j = i + 1;
    if (j >= path.getLength()) {
        j = 0;
    }
    var b = path.getAt(j);
    if (rayCrossesSegment(point, a, b)) {
        crossings++;
    }
}

// odd number of crossings?
return (crossings % 2 == 1);

function rayCrossesSegment(point, a, b) {
    var px = point.lng(),
        py = point.lat(),
        ax = a.lng(),
        ay = a.lat(),
        bx = b.lng(),
        by = b.lat();
    if (ay > by) {
        ax = b.lng();
        ay = b.lat();
        bx = a.lng();
        by = a.lat();
    }
    // alter longitude to cater for 180 degree crossings
    if (px < 0) { px += 360 };
    if (ax < 0) { ax += 360 };
    if (bx < 0) { bx += 360 };

    if (py == ay || py == by) py += 0.00000001;
    if ((py > by || py < ay) || (px > Math.max(ax, bx))) return false;
    if (px < Math.min(ax, bx)) return true;

    var red = (ax != bx) ? ((by - ay) / (bx - ax)) : Infinity;
    var blue = (ax != px) ? ((py - ay) / (px - ax)) : Infinity;
    return (blue >= red);

}

};


// Variables ===============
// =========================
var $map = document.getElementById('map_canvas'),
defaultLocation = new google.maps.LatLng(-37.813553, 144.96341899999993), // Melbourne CBD
directions = {
    display: new google.maps.DirectionsRenderer(),
    service: new google.maps.DirectionsService()
},
initialLocation = defaultLocation,
map = null,
options = {
    center: initialLocation,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    zoom: 13
},
zones = {
    a: {
        options: {
            path: [
                new google.maps.LatLng(-37.839848,144.916192),
                new google.maps.LatLng(-37.831374,144.911557),
                new google.maps.LatLng(-37.822358,144.911128),
                new google.maps.LatLng(-37.806627,144.908038),
                new google.maps.LatLng(-37.794148,144.914218),
                new google.maps.LatLng(-37.787636,144.924518),
                new google.maps.LatLng(-37.788586,144.947520),
                new google.maps.LatLng(-37.787365,144.950953),
                new google.maps.LatLng(-37.789536,144.958507),
                new google.maps.LatLng(-37.793063,144.966060),
                new google.maps.LatLng(-37.792656,144.975501),
                new google.maps.LatLng(-37.807983,144.972239),
                new google.maps.LatLng(-37.815035,144.975158),
                new google.maps.LatLng(-37.833069,144.971210),
                new google.maps.LatLng(-37.836594,144.968463),
                new google.maps.LatLng(-37.849066,144.950438),
                new google.maps.LatLng(-37.839848,144.916192)
            ],
            fillColor: "#00FF00",
            fillOpacity: 0.35,
            strokeColor: "#00FF00",
            strokeOpacity: 1,
            strokeWeight: 2
        },
        polygon: null
    }, // End zone a
    b: {
        options: {
            path: [
                new google.maps.LatLng(-37.840119,144.915591),
                new google.maps.LatLng(-37.865465,144.914561),
                new google.maps.LatLng(-37.867905,144.908467),
                new google.maps.LatLng(-37.871970,144.902974),
                new google.maps.LatLng(-37.859096,144.873277),
                new google.maps.LatLng(-37.867498,144.843064),
                new google.maps.LatLng(-37.870208,144.838944),
                new google.maps.LatLng(-37.815984,144.849587),
                new google.maps.LatLng(-37.812187,144.860230),
                new google.maps.LatLng(-37.781531,144.864350),
                new google.maps.LatLng(-37.770134,144.865724),
                new google.maps.LatLng(-37.757378,144.859544),
                new google.maps.LatLng(-37.728872,144.867097),
                new google.maps.LatLng(-37.734574,144.904176),
                new google.maps.LatLng(-37.732673,144.920999),
                new google.maps.LatLng(-37.746791,145.022622),
                new google.maps.LatLng(-37.764706,145.020562),
                new google.maps.LatLng(-37.764435,145.027085),
                new google.maps.LatLng(-37.790485,145.027429),
                new google.maps.LatLng(-37.792927,145.031205),
                new google.maps.LatLng(-37.826561,145.025369),
                new google.maps.LatLng(-37.837136,145.026742),
                new google.maps.LatLng(-37.836865,145.037042),
                new google.maps.LatLng(-37.845812,145.039445),
                new google.maps.LatLng(-37.847710,145.042535),
                new google.maps.LatLng(-37.871292,145.038415),
                new google.maps.LatLng(-37.879693,145.034295),
                new google.maps.LatLng(-37.884571,145.038758),
                new google.maps.LatLng(-37.903807,145.035325),
                new google.maps.LatLng(-37.927371,145.029145),
                new google.maps.LatLng(-37.931433,145.025712),
                new google.maps.LatLng(-37.975560,145.015412),
                new google.maps.LatLng(-37.969606,145.008546),
                new google.maps.LatLng(-37.961485,145.011292),
                new google.maps.LatLng(-37.944701,144.995843),
                new google.maps.LatLng(-37.937932,144.996873),
                new google.maps.LatLng(-37.925476,144.984857),
                new google.maps.LatLng(-37.911392,144.984857),
                new google.maps.LatLng(-37.894054,144.985200),
                new google.maps.LatLng(-37.881861,144.977647),
                new google.maps.LatLng(-37.856927,144.966660),
                new google.maps.LatLng(-37.849066,144.951554),
                new google.maps.LatLng(-37.837136,144.969064),
                new google.maps.LatLng(-37.833340,144.971810),
                new google.maps.LatLng(-37.814899,144.976274),
                new google.maps.LatLng(-37.807847,144.973527),
                new google.maps.LatLng(-37.792384,144.976274),
                new google.maps.LatLng(-37.791299,144.967004),
                new google.maps.LatLng(-37.785873,144.952584),
                new google.maps.LatLng(-37.786958,144.947434),
                new google.maps.LatLng(-37.786144,144.924088),
                new google.maps.LatLng(-37.791842,144.915162),
                new google.maps.LatLng(-37.805135,144.906236),
                new google.maps.LatLng(-37.820052,144.908982),
                new google.maps.LatLng(-37.831171,144.910012),
                new google.maps.LatLng(-37.840119,144.915591)
            ],
            fillColor: "#0000FF",
            fillOpacity: 0.35,
            strokeColor: "#0000FF",
            strokeOpacity: 1,
            strokeWeight: 2
        }
    } // End zone b
};


// Load reference to map
map = new google.maps.Map($map, options);

// Load zones
zones.a.polygon = new google.maps.Polygon(zones.a.options);
zones.a.polygon.setMap(map);

zones.b.polygon = new google.maps.Polygon(zones.b.options);
zones.b.polygon.setMap(map);

// Load route
calcRoute(
    'Dandenong',
    'South Melbourne'
);
4

2 に答える 2

0

使用している距離単位 (フィート、メートル、km、マイル) に応じて、次のようにします...

var increment = 0;
var zone = initial_zone;

//loop structure
if(current zone == zone){
   increment = increment + 1;
}
else{
    zone = zone_2;
}

など...など

于 2012-07-10T01:01:24.380 に答える
0
  • ライン ポリゴンの交点を検索
  • 理解しているアルゴリズムを選択するか、API に移植できる JavaScript の実装を見つけます
  • それを使用して、ルートとポリゴンの交差点を見つけます
  • ジオメトリ ライブラリを使用して、各ポリゴン内のセグメントの長さを決定します
于 2012-07-10T04:19:34.953 に答える