需要用到的类

package com.jwuwb.library.service.nav.core;

import java.util.ArrayList;
import java.util.Arrays;


public class GisPoint {
    //坐标
    private Vector3 coordinate;

    //父节点
    private GisPoint parent;

    //ID 连接信息
    private String[] idConnections;

    //ID
    private String id;

    //F
    private double F;

    //G
    private double G;

    //H
    private double H;

    //是否可用
    private boolean isValidate;

    //连接点
    private ArrayList<GisPoint> connections;

    //构造函数
    public GisPoint() {
        coordinate = new Vector3(0, 0, 0);
        parent = null;
        F = 0;
        G = 0;
        H = 0;
        isValidate = true;
        connections = new ArrayList<GisPoint>();
    }

    //构造函数
    public GisPoint(double x, double y, double z) {
        coordinate = new Vector3(x, y, z);
        parent = null;
        F = 0;
        G = 0;
        H = 0;
        isValidate = true;
        connections = new ArrayList<GisPoint>();
    }

    //添加连接
    public void addConnection(GisPoint point) {
        connections.add(point);
    }

    //获取F
    public double getF() {
        return getG() + getH();
    }

    //获取坐标
    public Vector3 getCoordinate() {
        return coordinate;
    }

    //设置坐标
    public void setCoordinate(Vector3 coordinate) {
        this.coordinate = coordinate;
    }

    //获取父
    public GisPoint getParent() {
        return parent;
    }

    //设置父
    public void setParent(GisPoint parent) {
        this.parent = parent;
    }

    //获取 G
    public double getG() {
        return G;
    }

    //设置G
    public void setG(double g) {
        G = g;
    }

    //获取 H
    public double getH() {
        return H;
    }

    //设置 H
    public void setH(double h) {
        H = h;
    }

    //是否可用
    public boolean isValidate() {
        return isValidate;
    }

    //设置是否可用
    public void setValidate(boolean validate) {
        isValidate = validate;
    }

    //获取连接数量
    public int connectionCount() {
        return connections.size();
    }

    //获取连接点
    public GisPoint getConnectionPoint(int i) {
        return connections.get(i);
    }

    //获取ID连接
    public String[] getIdConnections() {
        return idConnections;
    }

    //设置ID连接
    public void setIdConnections(String[] idConnections) {
        this.idConnections = idConnections;
    }

    //获取ID
    public String getId() {
        return id;
    }

    //设置ID
    public void setId(String id) {
        this.id = id;
    }

    //克隆
    @Override
    public GisPoint clone() {
        GisPoint ret = new GisPoint();
        ret.setCoordinate(getCoordinate());
        ret.setValidate(true);
        ret.setParent(null);
        ret.setId(getId());
        ret.idConnections = getIdConnections();
        return ret;
    }


}
package com.jwuwb.library.service.nav.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class GisSpace {
    /**
     * 本类唯一对象
     */
    private static GisSpace gisSpace = null;
    /**
     * gis 点信息
     */
    private Map<String, ArrayList<GisPoint>> mGisPoints;

    /**
     * 构造函数
     */
    private GisSpace() {
        mGisPoints = new ConcurrentHashMap<>(new HashMap<>());
    }

    /**
     * 获取本类唯一对象
     *
     * @return
     */
    public static GisSpace getRef() {
        if (gisSpace == null)
            gisSpace = new GisSpace();
        return gisSpace;
    }

    /**
     * 构建gis连接
     *
     * @param gisSet
     */
    public static void connectionGis(ArrayList<GisPoint> gisSet) {
        for (GisPoint gp : gisSet) {
            for (String conId : gp.getIdConnections()) {
                for (GisPoint toGp : gisSet) {
                    if (conId.equals(toGp.getId())) {
                        gp.addConnection(toGp);
                        break;
                    }
                }
            }
        }
    }

    /**
     * 添加GIS信息点
     *
     * @param mapUniqueKey 地图UID
     * @param point        点坐标
     */
    public void addGisPoint(String mapUniqueKey, ArrayList<GisPoint> point) {
        mGisPoints.put(mapUniqueKey, point);
    }

    /**
     * 拷贝一个GIS列表
     *
     * @return
     */
    public ArrayList<GisPoint> cloneGisPoints() {
        ArrayList<GisPoint> ret = new ArrayList<GisPoint>();

        ArrayList<GisPoint> forMapGis = mGisPoints.get("map");
        if (forMapGis != null) {
            for (int i = 0; i < forMapGis.size(); i++) {
                GisPoint oldGP = mGisPoints.get("map").get(i);
                ret.add(oldGP.clone());
            }
        }

        //建立 GIS 连接
        connectionGis(ret);

        return ret;
    }

    /**
     * 清除所有GIS点
     */
    public void clearGisPoint() {
        mGisPoints.clear();
    }


}
package com.jwuwb.library.service.nav.core;

import java.util.ArrayList;


public class Navigation {

    //GIS信息点
    private ArrayList<GisPoint> mGISPoints = null;

    //可用的GIS信息列表
    private ArrayList<GisPoint> mAvaliableGisPoint = null;

    public Navigation() {
        mAvaliableGisPoint = new ArrayList<GisPoint>();
        mGISPoints = GisSpace.getRef().cloneGisPoints();
    }

    //导航
    public ArrayList<Point> doNav(Point start, Point end) {
        //如果 gisPoints 没有则返回空
        if (mGISPoints.size() == 0) {
            return new ArrayList<Point>();
        }

        //获取未知点到起点最近的一个 GIS 点
        GisPoint startGP = getClosestGisPoint(start);

        //获取未知点到结束点最近的一个 GIS 点
        GisPoint endGP = getClosestGisPoint(end);

        //起点等于终点
        if (startGP == endGP) {
            ArrayList<Point> retV = new ArrayList<>();
            retV.add(start);
            retV.add(startGP.getCoordinate());
            retV.add(end);
            return retV;
        }

        //添加起点
        mAvaliableGisPoint.add(startGP);

        //初始化 H 值
        for (int i = 0; i < mGISPoints.size(); i++) {
            GisPoint igp = mGISPoints.get(i);
            initGisPointH(igp, endGP);
            igp.setValidate(true);
            igp.setParent(null);
        }

        //获取 F 值最小的 GIS 点
        GisPoint curGP = getMinFGisPoint();

        //标注搜索是否结束
        boolean skip = false;

        //开始搜索
        do {
            //搜索列表为空则退出
            if (mAvaliableGisPoint.size() == 0) {
                break;
            }

            //从可用列表中移除
            removeGisPointFromAvaliableList(curGP);
            curGP.setValidate(false);

            //搜索当前点的连接点
            for (int i = 0; i < curGP.connectionCount(); i++) {
                //获取连接点
                GisPoint newGP = curGP.getConnectionPoint(i);

                //如果搜索已经到了结束点则跳出
                if (newGP == endGP) {
                    skip = true;
                    endGP.setParent(curGP);
                    break;
                }

                //计算新的G值
                double tempG = curGP.getCoordinate().distance(newGP.getCoordinate());
                double newG = tempG + curGP.getG();

                //如果当前点已经失效,则继续下一个点
                if (newGP.isValidate() == false) {
                    continue;
                }

                //当前点已经在可用列表中
                if (isGisPointInAvaliableList(newGP) == true) {
                    if (newGP.getG() < newG) {
                    } else {
                        newGP.setParent(curGP);
                        newGP.setG(newG);
                    }
                } else {
                    newGP.setParent(curGP);
                    newGP.setG(newG);
                    mAvaliableGisPoint.add(newGP);
                }
            }

            //选择 F 值最小的一个 GIS 点,继续搜索
            curGP = getMinFGisPoint();

        }
        while (skip == false);

        //取出点信息
        ArrayList<Point> ret = new ArrayList<Point>();
        getNavPathPoint(endGP, ret);
        return ret;
    }

    //取出 路径的 gis 点
    void getNavPathPoint(GisPoint parent, ArrayList<Point> ret) {
        if (parent == null) return;
        ret.add(parent.getCoordinate());
        if (parent != null) {
            getNavPathPoint(parent.getParent(), ret);
        }

    }

    //获取离某点最近的GIS点
    private GisPoint getClosestGisPoint(Point p) {
        double minDis = 99999999999.0;
        GisPoint ret = null;
        for (int i = 0; i < mGISPoints.size(); i++) {
            GisPoint gp = mGISPoints.get(i);
            double dis = gp.getCoordinate().distance(p);
            if (dis < minDis) {
                minDis = dis;
                ret = gp;
            }
        }
        return ret;
    }

    //点是否在可用列表中
    private boolean isGisPointInAvaliableList(GisPoint p) {
        for (int i = 0; i < mAvaliableGisPoint.size(); i++) {
            GisPoint gp = mAvaliableGisPoint.get(i);
            if (gp == p) {
                return true;
            }
        }
        return false;
    }

    //获取 G 值最小的一个点
    private GisPoint getMinGGisPoint() {
        double minG = 9999999999999.0;
        GisPoint ret = null;
        for (int i = 0; i < mAvaliableGisPoint.size(); i++) {
            GisPoint gp = mAvaliableGisPoint.get(i);
            if (gp.getG() < minG) {
                minG = gp.getG();
                ret = gp;
            }
        }
        return ret;
    }

    //获取 F 值最小的一个点
    private GisPoint getMinFGisPoint() {
        double minF = 9999999999999.0;
        GisPoint ret = null;
        for (int i = 0; i < mAvaliableGisPoint.size(); i++) {
            GisPoint gp = mAvaliableGisPoint.get(i);
            if (gp.getF() < minF) {
                minF = gp.getF();
                ret = gp;
            }
        }
        return ret;
    }

    //从可用列表中移除
    private void removeGisPointFromAvaliableList(GisPoint p) {
        for (int i = 0; i < mAvaliableGisPoint.size(); i++) {
            GisPoint gp = mAvaliableGisPoint.get(i);
            if (gp == p) {
                mAvaliableGisPoint.remove(p);
                return;
            }
        }
    }

    //初始化 H 值
    private void initGisPointH(GisPoint cur, GisPoint endP) {
        double dis = cur.getCoordinate().distance(endP.getCoordinate());
        cur.setH(dis);
    }

}
package com.jwuwb.library.service.nav.core;

public class Point{

    private double x;
    private double y;
    private double z;

    //构造函数
    public Point() {
        x = 0;
        y = 0;
        z = 0;
    }

    //构造函数
    public Point(double _x, double _y, double _z) {
        x = _x;
        y = _y;
        z = _z;
    }

    //计算2线段是否相交
    public static boolean IsSegmentsCross(Point a, Point b, Point c, Point d) {
        // 三角形abc 面积的2倍
        double area_abc = (a.x - c.x) * (b.z - c.z) - (a.z - c.z) * (b.x - c.x);

        // 三角形abd 面积的2倍
        double area_abd = (a.x - d.x) * (b.z - d.z) - (a.z - d.z) * (b.x - d.x);

        // 面积符号相同则两点在线段同侧,不相交
        if (area_abc * area_abd >= 0) {
            return false;
        }

        // 三角形cda 面积的2倍
        double area_cda = (c.x - a.x) * (d.z - a.z) - (c.z - a.z) * (d.x - a.x);
        // 三角形cdb 面积的2倍
        double area_cdb = area_cda + area_abc - area_abd;
        if (area_cda * area_cdb >= 0) {
            return false;
        }

        //计算交点坐标
        double t = area_cda / (area_abd - area_abc);
        double dx = t * (b.x - a.x),
                dy = t * (b.z - a.z);
        // x: a.x + dx
        //z: a.z + dy
        return true;
    }

    //从字符串获取Point类型
    public static Point FromString(String str, String splitStr) {
        Point ret = new Point(0, 0, 0);
        String[] sourceStrArray = str.split(splitStr);
        if (sourceStrArray.length == 3) {
            double x = Double.parseDouble(sourceStrArray[0]);
            double y = Double.parseDouble(sourceStrArray[1]);
            double z = Double.parseDouble(sourceStrArray[2]);

            ret.x = x;
            ret.y = y;
            ret.z = z;

        }
        return ret;
    }

    //获取X
    public double getX() {
        return x;
    }

    //设置X
    public void setX(double x) {
        this.x = x;
    }

    //获取Y
    public double getY() {
        return y;
    }

    //设置Y
    public void setY(double y) {
        this.y = y;
    }

    //获取Z
    public double getZ() {
        return z;
    }

    //设置z
    public void setZ(double z) {
        this.z = z;
    }

    //加
    public Point add(Point v) {
        Point ret = new Point();
        ret.x = x + v.x;
        ret.y = y + v.y;
        ret.z = z + v.z;
        return ret;
    }

    //减
    public Point sub(Point v) {
        Point ret = new Point();
        ret.x = x - v.x;
        ret.y = y - v.y;
        ret.z = z - v.z;
        return ret;
    }

    //乘
    public Point mul(Point v) {
        Point ret = new Point ();
        ret.x = x * v.x;
        ret.y = y * v.y;
        ret.z = z * v.z;
        return ret;
    }

    //乘
    public Point mul(double v) {
        Point ret = new Point ();
        ret.x = x * v;
        ret.y = y * v;
        ret.z = z * v;
        return ret;
    }

    //除
    public Point div(Point v) {
        Point ret = new Point ();
        ret.x = x / v.x;
        ret.y = y / v.y;
        ret.z = z / v.z;
        return ret;
    }

    //点积
    public double dot(Point v) {
        double ret = 0;
        ret = x * v.x + y * v.y + z * v.z;
        return ret;
    }

    //叉乘
    public Point cross(Point v) {
        Point ret = new Point ();
        ret.x = y * v.z - z * v.y;
        ret.y = z * v.x - x * v.z;
        ret.z = x * v.y - y * v.x;
        return ret;
    }

    //长度
    public double length() {
        return Math.sqrt(x * x + y * y + z * z);
    }

    //距离
    public double distance(Point v) {
        double x1 = x - v.x;
        double y1 = y - v.y;
        double z1 = z - v.z;
        return Math.sqrt(x1 * x1 + y1 * y1 + z1 * z1);
    }

    //归一化
    public Point normalize() {
        double len = length();
        return new Point (x / len, y / len, z / len);
    }

    @Override
    public String toString() {
        return "Point {" +
                "x=" + x +
                ", y=" + y +
                ", z=" + z +
                '}';
    }
}
package com.jwuwb.library.service.nav;

import java.util.ArrayList;
import java.util.List;

public class AStar {

    public static final int[][] NODES = {
            {0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0},
    };

    public static final int STEP = 10;

    private ArrayList<Node> openList = new ArrayList<Node>();
    private ArrayList<Node> closeList = new ArrayList<Node>();

    public Node findMinFNodeInOpneList() {
        Node tempNode = openList.get(0);
        for (Node node : openList) {
            if (node.F < tempNode.F) {
                tempNode = node;
            }
        }
        return tempNode;
    }

    public ArrayList<Node> findNeighborNodes(Node currentNode) {
        ArrayList<Node> arrayList = new ArrayList<Node>();
        // 只考虑上下左右,不考虑斜对角
        int topX = currentNode.x;
        int topY = currentNode.y - 1;
        if (canReach(topX, topY) && !exists(closeList, topX, topY)) {
            arrayList.add(new Node(topX, topY));
        }
        int bottomX = currentNode.x;
        int bottomY = currentNode.y + 1;
        if (canReach(bottomX, bottomY) && !exists(closeList, bottomX, bottomY)) {
            arrayList.add(new Node(bottomX, bottomY));
        }
        int leftX = currentNode.x - 1;
        int leftY = currentNode.y;
        if (canReach(leftX, leftY) && !exists(closeList, leftX, leftY)) {
            arrayList.add(new Node(leftX, leftY));
        }
        int rightX = currentNode.x + 1;
        int rightY = currentNode.y;
        if (canReach(rightX, rightY) && !exists(closeList, rightX, rightY)) {
            arrayList.add(new Node(rightX, rightY));
        }
        return arrayList;
    }

    public boolean canReach(int x, int y) {
        if (x >= 0 && x < NODES.length && y >= 0 && y < NODES[0].length) {
            return NODES[x][y] == 0;
        }
        return false;
    }

    public Node findPath(Node startNode, Node endNode) {

        // 把起点加入 open list
        openList.add(startNode);

        while (openList.size() > 0) {
            // 遍历 open list ,查找 F值最小的节点,把它作为当前要处理的节点
            Node currentNode = findMinFNodeInOpneList();
            // 从open list中移除
            openList.remove(currentNode);
            // 把这个节点移到 close list
            closeList.add(currentNode);

            ArrayList<Node> neighborNodes = findNeighborNodes(currentNode);
            for (Node node : neighborNodes) {
                if (exists(openList, node)) {
                    foundPoint(currentNode, node);
                } else {
                    notFoundPoint(currentNode, endNode, node);
                }
            }
            if (find(openList, endNode) != null) {
                return find(openList, endNode);
            }
        }

        return find(openList, endNode);
    }

    private void foundPoint(Node tempStart, Node node) {
        int G = calcG(tempStart, node);
        if (G < node.G) {
            node.parent = tempStart;
            node.G = G;
            node.calcF();
        }
    }

    private void notFoundPoint(Node tempStart, Node end, Node node) {
        node.parent = tempStart;
        node.G = calcG(tempStart, node);
        node.H = calcH(end, node);
        node.calcF();
        openList.add(node);
    }

    private int calcG(Node start, Node node) {
        int G = STEP;
        int parentG = node.parent != null ? node.parent.G : 0;
        return G + parentG;
    }

    private int calcH(Node end, Node node) {
        int step = Math.abs(node.x - end.x) + Math.abs(node.y - end.y);
        return step * STEP;
    }

    public static void main(String[] args) {
        Node startNode = new Node(5, 1);
        Node endNode = new Node(5, 5);
        Node parent = new AStar().findPath(startNode, endNode);

        for (int i = 0; i < NODES.length; i++) {
            for (int j = 0; j < NODES[0].length; j++) {
                System.out.print(NODES[i][j] + ", ");
            }
            System.out.println();
        }
        ArrayList<Node> arrayList = new ArrayList<>();

        while (parent != null) {
            arrayList.add(new Node(parent.x, parent.y));
            parent = parent.parent;
        }
        System.out.println("\n");

        for (int i = 0; i < NODES.length; i++) {
            for (int j = 0; j < NODES[0].length; j++) {
                if (exists(arrayList, i, j)) {
                    System.out.print("@, ");
                } else {
                    System.out.print(NODES[i][j] + ", ");
                }

            }
            System.out.println();
        }

    }

    public static Node find(List<Node> nodes, Node point) {
        for (Node n : nodes)
            if ((n.x == point.x) && (n.y == point.y)) {
                return n;
            }
        return null;
    }

    public static boolean exists(List<Node> nodes, Node node) {
        for (Node n : nodes) {
            if ((n.x == node.x) && (n.y == node.y)) {
                return true;
            }
        }
        return false;
    }

    public static boolean exists(List<Node> nodes, int x, int y) {
        for (Node n : nodes) {
            if ((n.x == x) && (n.y == y)) {
                return true;
            }
        }
        return false;
    }

    public static class Node {
        public Node(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int x;
        public int y;

        public int F;
        public int G;
        public int H;

        public void calcF() {
            this.F = this.G + this.H;
        }

        public Node parent;
    }
}
public JSONArray calculate(String startPos, String endPos) throws Exception {

        Point startPoint = Point.FromString(startPos, ",");
        Point endPoint = Point.FromString(endPos, ",");

        //获取导航数据
        Navigation nav = new Navigation();
        List<Point> resultPoints = nav.doNav(startPoint, endPoint);
        JSONArray array = new JSONArray();
        array.add(startPoint);
        for (int i = resultPoints.size() - 1; i >= 0; i--) {
            array.add(resultPoints.get(i));
        }
        array.add(endPoint);
        return array;
    }

最后是怎么使用,初始化可以将我们的x,y,z坐标点集合按照规则放入,直接调用返回点的顺序集合