由于项目经常遇到这些业务需求,索性总结出来小写一篇文章加深记忆。
本文的前置条件是已知ArcGis map上两个点坐标,暂且假设为startPoint,endPoint。即通过这两个坐标就可以在map上划出一条直线。
以endPoint为端点,计算其左右两边箭头点的位置坐标,
①计算长度
fun getLength(endPoint: Point, startPoint: Point?): Double {
var changdu = 0.005
var xPyl = endPoint.x - startPoint!!.x
var yPyl = endPoint.y - startPoint!!.y
if (xPyl < 0) xPyl = 0 - xPyl
if (yPyl < 0) yPyl = 0 - yPyl
if (xPyl > yPyl) {
if (xPyl < 0) {
changdu = 0 - xPyl
} else {
changdu = xPyl
}
} else {
if (yPyl < 0) {
changdu = 0 - yPyl
} else {
changdu = yPyl
}
}
changdu /= 6 //箭头长度取两点间长度的六分之一 自行修改
return changdu
}
②获取方位角 eg 两点的线段可能是这样 / | \ 等等不确定 ,所以要判断直线的方位角 方便计算箭头两个端点的方位
fun getAzimuth(startPoint: Point, endPoint: Point):Double{
val angle = asin(Math.abs(endPoint.y - startPoint.y) / (Math.sqrt(Math.pow(startPoint.x - endPoint.x, 2.0) + Math.pow(startPoint.y - endPoint.y, 2.0))))
var azimuth = 0.0
if (endPoint.x > startPoint.x && endPoint.y > startPoint.y) {//右上
azimuth = angle + Math.PI
} else if (endPoint.x > startPoint.x && endPoint.y < startPoint.y) {//右下
azimuth = Math.PI - angle
} else if (endPoint.x < startPoint.x && endPoint.y < startPoint.y) {//左下
azimuth = angle
} else if (endPoint.x < startPoint.x && endPoint.y > startPoint.y) {//左上
azimuth = Math.PI * 2 - angle
}
return azimuth
}
③计算点 angle 是箭头与直线的夹角, distance 就是①计算的长度, clockWise 直线左边 直线右边 这个方法调用两次即可得到对应的两个点
fun getThirdPoint(startPoint: Point, endPoint: Point, angle:Double,distance:Double,clockWise:Boolean):Point{
val azimuth = getAzimuth(startPoint,endPoint)
val alpha = if(clockWise) (azimuth + angle) else (azimuth - angle)
val dx = distance * Math.cos(alpha)
val dy = distance * Math.sin(alpha)
return Point(endPoint.x + dx, endPoint.y + dy)
}
至于其他的样式自己根据需求修改angle就好。
如有不对的地方希望指正。
欢迎交流