在B/S端的矢量地图中,道路都是一条条的线要素,而线要素是由点要素连接而成。这个过程被封装在地图服务器中如arcgis server或supermap iserver,其中连接为线要素的点要素是可以通过请求来获取的。
若要获取两条线要素的交点坐标,需要先将组成线要素的各个相邻的点坐标存储成一个数组var ptt1=[{x1,y1},{x2,y2},{x3,y3},.........],然后计算两个线要素上各自相邻的两个点组成的两个直线的交点,最后判断这个交点在不在这四个点各自组成的两条线段某一个上。(注意线段与直线的区别)
判断方法为:交点坐标是否在以两条线段为对角线的两个矩形区域内,当满足同时在两个矩形区域时,此交点即所求。
具体代码如下:
//* @param {geometry} geometry_r1 第一条道路的图形
//* @param {geometry} geometry_r2 第二条道路的图形(列表中的)
function point(geometry_r1, geometry_r2) {
//道路 pt1 未排序 点 数组 ptt1 排序点数组
var pt1 = new Array(); //先声明一维
for (var i = 0; i < geometry_r1.geometry.components.length; i++) { //一维长度为i,i为变量,可以根据实际情况改变
pt1[i] = new Array(); //声明二维,每一个一维数组里面的一个元素都是一个数组;
pt1[i][0] = geometry_r1.geometry.components[i].x; //这里将变量初始化,我这边统一初始化为空,后面在用所需的值覆盖里面的值
pt1[i][1] = geometry_r1.geometry.components[i].y;
}
var mapped = pt1.map(function (ar, i) {
return {
value: ar[0],
index: i
} //输出一个object对象,value为排序的数字的值,index为数字所在的数组在一维数组中的索引值
})
mapped.sort(function (a, b) {
return a.value - b.value;
})
ptt1 = mapped.map(function (ar) {
return pt1[ar.index];
})
//道路 pt2 未排序 点 数组 ptt2 排序点数组
var pt2 = new Array(); //先声明一维
for (var i = 0; i < geometry_r2.geometry.components.length; i++) { //一维长度为i,i为变量,可以根据实际情况改变
pt2[i] = new Array(); //声明二维,每一个一维数组里面的一个元素都是一个数组;
pt2[i][0] = geometry_r2.geometry.components[i].x; //这里将变量初始化,我这边统一初始化为空,后面在用所需的值覆盖里面的值
pt2[i][1] = geometry_r2.geometry.components[i].y;
}
console.log(pt2)
var mapped2 = pt2.map(function (ar, i) {
return {
value: ar[0],
index: i
} //输出一个object对象,value为排序的数字的值,index为数字所在的数组在一维数组中的索引值
})
mapped2.sort(function (a, b) {
return a.value - b.value;
})
ptt2 = mapped2.map(function (ar) {
return pt2[ar.index];
})
}
计算两条线交点
//参数seg1、seg2{x1,x2,y1,y2}(x1<x2);options{pOrl:Boolean,tolerance:number}
function pointxy(ptt1, ptt2) {
for (var i = 0; i < ptt1.length-1; i++) {
for (var j = 0; j < ptt2.length-1; j++) {
var a1 = ptt1[i][1] - ptt1[i + 1][1];
var b1 = ptt1[i + 1][0] - ptt1[i][0];
var c1 = a1 * ptt1[i + 1][0] + b1 * ptt1[i + 1][1];
//转换成一般式: Ax+By = C
var a2 = ptt2[j][1] - ptt2[j + 1][1];
var b2 = ptt2[j + 1][0] - ptt2[j][0];
var c2 = a2 * ptt2[j + 1][0] + b2 * ptt2[j + 1][1];
// 计算交点
var d = a1 * b2 - a2 * b1;
// 当d==0时,两线平行
if (d == 0) {
return false;
} else {
var x = (b2 * c1 - b1 * c2) / d;
var y = (a1 * c2 - a2 * c1) / d;
// 检测交点是否在两条线段上
if ((isInBetween(ptt1[i + 1][0], x, ptt1[i][0]) || isInBetween(ptt1[i + 1][1], y, ptt1[i][1])) &&
(isInBetween(ptt2[j + 1][0], x, ptt2[j][0]) || isInBetween(ptt2[j + 1][1], y, ptt2[j][1]))) {
map.setCenter(new top.SuperMap.LonLat(x, y), 7)
}
}
}
//如果b在a和c之间,返回true
//当a==b或者b==c时排除结果,返回false
function isInBetween(a, b, c) {
// 如果b几乎等于a或c,返回false.为了避免浮点运行时两值几乎相等,但存在相差0.00000...0001的这种情况出现使用下面方式进行避免
if ((Math.abs(a - b) > 0.000001 || Math.abs(b - c) > 0.000001) && ((b > a && b < c) || (b < a && b > c)) || (a==b||b==c)) {
return true;
} else {
return false;
}
}
}
}