gpt4 book ai didi

javascript - Google maps api 平行路径线

转载 作者:行者123 更新时间:2023-11-29 10:22:47 26 4
gpt4 key购买 nike

我正在为打包假期开发一种行程映射器,我对目前所做的工作非常满意;我有使用自定义渲染器实现的方向 api,因此我可以获取行车路线,并绘制我自己的多段线,其中包含方向箭头,这些方向箭头不是谷歌沿路径间隔的糟糕方向。我算不上数学专家,我想弄清楚如何让一条路径与另一条路径平行。比如行程从1市到2市,再回到1市。

我想将行程偏移回城市 1 的多段线,以便它镜像路径,但平行于它行进。理想情况下,我希望在创建路径时检查其他路径中的交叉点,如果找到任何交叉点,则仅在这些点处偏移路径。这将是一个更好的实现方式,因为例如您可以仅在恰好与另一条​​路径相交的地方平行路径,例如当它仅在短时间内与另一条路径相遇时。

我从 bill chadwick 那里找到了 API2 的代码

链接在这里:http://wtp2.appspot.com/ParallelLines.htm

更新:以某种方式设法转换这个旧的 v2 脚本以使其在 v3 中工作,但我遇到了一些麻烦...

比原来的点数翻了一倍还多,跟着路径走,但真的是随机扔进去的。截图在这里:

Google maps screenshot

我转换的类在这里:

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));

}

这在某种程度上是有效的...它与原始实现一样有效。整个路径是在缩放的基础上重新计算的,我有点破解了在更高的缩放级别跳过非常短的路径(奇怪的 Angular )的功能,你放大得越多,它就越接近路径。

我宁愿只有一个不重新计算的固定距离偏移,因为它非常密集......有很多程序可以实现这一壮举,rhino3d,autocad,illustrator......我觉得这对谷歌地图本身的行车路线,路径的偏移,因此您可以区分回程和原始行程。

如果有人在 JS 中做过类似的事情,即使它不是专门针对谷歌地图的,我也很乐意看到它。我正在调查的链接:

http://processingjs.nihongoresources.com/bezierinfo/

http://www.groupsrv.com/computers/about21532.html

最佳答案

偏移路径通常是一项非常棘手的业务。 This paper (scientific paper alert) 很好地描述了“专业”偏移算法所采取的步骤。

http://cgcad.thss.tsinghua.edu.cn/~yongjh/papers/CiI2007V58N03P0240.pdf

关于javascript - Google maps api 平行路径线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8140988/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com