私は、パッケージ旅行のための旅程マッパーのような作業をしています。私はこれまで行ってきたことに本当に満足しています。私は道案内APIをカスタムレンダラで実装しているので、運転の道順を取ることができ、経路に沿ったGoogleのひどいものではない方向矢印で自分のポリラインをプロットすることができます。私は正確に数学の専門家ではない、私は別のパスに平行してパスを作る方法を理解しようとしている。たとえば、旅程は都市1から都市2に、都市1に戻ります。Googleマップapiパラレルパスライン
都市1のポリラインに戻り、パスを鏡映して平行移動します。理想的には、パスを作成し、他のパスの交差点をチェックし、見つかった場合はそれらのポイントだけのパスをオフセットすることが理想的です。たとえば、短時間だけ別のパスに出会った場合など、別のパスと交差する場所でのみパスをパラレルにすることができるので、これはより優れた実装になります。
私は法案のチャドウィック
リンクからAPI2のため、このコードはここにあるが見つかりました:http://wtp2.appspot.com/ParallelLines.htm
更新:どういうわけか、それはv3の中で働いて得るために、この古いv2のスクリプトを変換するために管理が、私はいくつかを経験しています問題...
元のポイント数を2倍以上にしてパスに従いますが、実際にランダムに投げています。ここにスクリーンショット:私は変換
クラスはここにある:これはポイントに取り組んでいる
function BDCCParallelLines(points, color, weight, opacity, opts, gapPx) {
console.log('Pllel COnstructor Initialized');
this.gapPx = gapPx;
this.points = points;
this.color = color;
this.weight = weight;
this.opacity = opacity;
this.opts = opts;
this.line1 = null;
this.line2 = null;
this.lstnZoom = null;
}
BDCCParallelLines.prototype = new google.maps.OverlayView();
BDCCParallelLines.prototype.onAdd = function() {
console.log('Pllel Initialized');
this.prj = map.getProjection();
var self = this;
this.lstnZoom = google.maps.event.addListener(map, "zoom_changed", function() {
self.recalc();
});
this.recalc();//first draw
}
BDCCParallelLines.prototype.onRemove = function() {
if(this.line2)
this.line2.setMap(null);
if(this.line1)
this.line1.setMap(null);
if(this.lstnZoom != null)
google.maps.event.removeListener(this.lstnZoom);
}
BDCCParallelLines.prototype.copy = function() {
return new BDCCParallelLines(this.points,this.color,this.weight,this.opacity,this.opts,this.gapPx);
}
BDCCParallelLines.prototype.draw = function(force) {
return; //do nothing
}
/**
* @param {google.maps.Map} map
* @param {google.maps.LatLng} latlng
* @param {int} z
* @return {google.maps.Point}
*/
BDCCParallelLines.prototype.latLngToPoint = function(latlng, z){
var normalizedPoint = map.getProjection().fromLatLngToPoint(latlng); // returns x,y normalized to 0~255
var scale = Math.pow(2, z);
var pixelCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale);
return pixelCoordinate;
};
/**
* @param {google.maps.Map} map
* @param {google.maps.Point} point
* @param {int} z
* @return {google.maps.LatLng}
*/
BDCCParallelLines.prototype.pointToLatlng = function(point, z){
var scale = Math.pow(2, z);
var normalizedPoint = new google.maps.Point(point.x/scale, point.y/scale);
var latlng = map.getProjection().fromPointToLatLng(normalizedPoint);
return latlng;
};
BDCCParallelLines.prototype.recalc = function() {
var distallowance;
console.log('recalc called');
var zoom = map.getZoom();
distallowance = 1.6;
if(zoom > 6){
distallowance = 1.3;
if(zoom > 9){
distallowance = .7;
if(zoom > 13){
distallowance = .2;
if(zoom > 15){
distallowance = .0001;
}
}
}
}
console.log('Zoom Level: ' + zoom);
console.log('Allowance = ' + distallowance);
var pts1 = new Array();//left side of center
//shift the pts array away from the centre-line by half the gap + half the line width
var o = (this.gapPx + this.weight)/2;
var p2l,p2r;
for (var i=1; i<this.points.length; i++){
var p1lm1;
var p1rm1;
var p2lm1;
var p2rm1;
var thetam1;
var p1 = this.latLngToPoint(this.points[i-1], zoom)
var p2 = this.latLngToPoint(this.points[i], zoom)
var theta = Math.atan2(p1.x-p2.x,p1.y-p2.y);
theta = theta + (Math.PI/2);
var dl = Math.sqrt(((p1.x-p2.x)*(p1.x-p2.x))+((p1.y-p2.y)*(p1.y-p2.y)));
if(theta > Math.PI)
theta -= Math.PI*2;
var dx = Math.round(o * Math.sin(theta));
var dy = Math.round(o * Math.cos(theta));
var p1l = new google.maps.Point(p1.x+dx,p1.y+dy);
var p1r = new google.maps.Point(p1.x-dx,p1.y-dy);
p2l = new google.maps.Point(p2.x+dx,p2.y+dy);
p2r = new google.maps.Point(p2.x-dx,p2.y-dy);
if(i==1){ //first point
pts1.push(this.pointToLatlng(p1l,zoom));
}
else{ // mid this.points
if(distbetweentwo(this.points[i-1], this.points[i]) > distallowance){
if(theta == thetam1){
// adjacent segments in a straight line
pts1.push(this.pointToLatlng(p1l,zoom));
}
else{
var pli = this.intersect(p1lm1,p2lm1,p1l,p2l);
var pri = this.intersect(p1rm1,p2rm1,p1r,p2r);
var dlxi = (pli.x-p1.x);
var dlyi = (pli.y-p1.y);
var drxi = (pri.x-p1.x);
var dryi = (pri.y-p1.y);
var di = Math.sqrt((drxi*drxi)+(dryi*dryi));
var s = o/di;
var dTheta = theta - thetam1;
if(dTheta < (Math.PI*2))
dTheta += Math.PI*2;
if(dTheta > (Math.PI*2))
dTheta -= Math.PI*2;
if(dTheta < Math.PI){
//intersect point on outside bend
pts1.push(this.pointToLatlng(p2lm1,zoom));
pts1.push(this.pointToLatlng(new google.maps.Point(p1.x+(s*dlxi),p1.y+(s*dlyi)),zoom));
pts1.push(this.pointToLatlng(p1l,zoom));
}
else if (di < dl){
pts1.push(this.pointToLatlng(pli,zoom));
}
else{
pts1.push(this.pointToLatlng(p2lm1,zoom));
pts1.push(this.pointToLatlng(p1l,zoom));
}
}
}
else{
//console.log(distbetweentwo(this.points[i-1], this.points[i]));
}
}
p1lm1 = p1l;
p1rm1 = p1r;
p2lm1 = p2l;
p2rm1 = p2r;
thetam1 = theta;
//end loop
}
pts1.push(this.pointToLatlng(p2l,zoom));//final point
// console.log(pts1);
if(this.line1)
this.line1.setMap(null);
this.line1 = new google.maps.Polyline({
strokeColor: this.color,
strokeOpacity: this.opacity,
strokeWeight: this.weight,
map: map,
path: pts1 });
this.line1.setMap(map);
}
BDCCParallelLines.prototype.intersect = function(p0,p1,p2,p3)
{
// this function computes the intersection of the sent lines p0-p1 and p2-p3
// and returns the intersection point,
var a1,b1,c1, // constants of linear equations
a2,b2,c2,
det_inv, // the inverse of the determinant of the coefficient matrix
m1,m2; // the slopes of each line
var x0 = p0.x;
var y0 = p0.y;
var x1 = p1.x;
var y1 = p1.y;
var x2 = p2.x;
var y2 = p2.y;
var x3 = p3.x;
var y3 = p3.y;
// compute slopes, note the cludge for infinity, however, this will
// be close enough
if ((x1-x0)!=0)
m1 = (y1-y0)/(x1-x0);
else
m1 = 1e+10; // close enough to infinity
if ((x3-x2)!=0)
m2 = (y3-y2)/(x3-x2);
else
m2 = 1e+10; // close enough to infinity
// compute constants
a1 = m1;
a2 = m2;
b1 = -1;
b2 = -1;
c1 = (y0-m1*x0);
c2 = (y2-m2*x2);
// compute the inverse of the determinate
det_inv = 1/(a1*b2 - a2*b1);
// use Kramers rule to compute xi and yi
var xi=((b1*c2 - b2*c1)*det_inv);
var yi=((a2*c1 - a1*c2)*det_inv);
return new google.maps.Point(Math.round(xi),Math.round(yi));
}
...それは元の実装としてうまく機能しています。パス全体がズームベースで再計算されていますが、ズームレベルが高いほど非常に短いパス(奇妙な角度)をスキップする機能をハックしましたが、ズームしたほうがパスに近づきます。
ちょうどそれはかなり集中しているので、再計算されていない固定された距離のオフセットを持っている...この偉業、rhino3d、オートキャド、イラストレーターを達成する多くのプログラムがあります...私はそれがグーグルマップ自身、あなたが帰り旅行と元の旅行を区別することができるようにパスの相殺。
Googleのマップではないにしても、誰かがJSに似たようなことをしてくれたら、私はそれを見たいと思うでしょう。私が調査していますリンク:一般的に
http://processingjs.nihongoresources.com/bezierinfo/
http://www.groupsrv.com/computers/about21532.html
あなたは問題を解決しましたか?ありがとう – SERG