diff --git a/library/src/main/java/com/onlylemi/mapview/library/MapView.java b/library/src/main/java/com/onlylemi/mapview/library/MapView.java index a2feaeb..caba176 100644 --- a/library/src/main/java/com/onlylemi/mapview/library/MapView.java +++ b/library/src/main/java/com/onlylemi/mapview/library/MapView.java @@ -6,6 +6,7 @@ import android.graphics.Matrix; import android.graphics.Picture; import android.graphics.PointF; +import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; @@ -350,8 +351,19 @@ public void translate(float x, float y) { currentMatrix.postTranslate(x, y); } - public PointF mapCenter() { - return new PointF(mapLayer.getImage().getWidth() / 2, mapLayer.getImage().getHeight() / 2); + /** + * set point to map center + * + * @param x + * @param y + */ + public void mapCenterWithPoint(float x, float y) { + float[] goal = {x, y}; + currentMatrix.mapPoints(goal); + + float deltaX = getWidth() / 2 - goal[0]; + float deltaY = getHeight() / 2 - goal[1]; + currentMatrix.postTranslate(deltaX, deltaY); } public float getCurrentRotateDegrees() { @@ -364,7 +376,8 @@ public float getCurrentRotateDegrees() { * @param degrees */ public void setCurrentRotateDegrees(float degrees) { - setCurrentRotateDegrees(degrees, getMapWidth() / 2, getMapHeight() / 2); + mapCenterWithPoint(getMapWidth() / 2, getMapHeight() / 2); + setCurrentRotateDegrees(degrees, getWidth() / 2, getHeight() / 2); } /** diff --git a/library/src/main/java/com/onlylemi/mapview/library/MapViewListener.java b/library/src/main/java/com/onlylemi/mapview/library/MapViewListener.java index 295c149..15091f8 100644 --- a/library/src/main/java/com/onlylemi/mapview/library/MapViewListener.java +++ b/library/src/main/java/com/onlylemi/mapview/library/MapViewListener.java @@ -1,7 +1,5 @@ package com.onlylemi.mapview.library; -import android.graphics.Bitmap; - /** * MapViewListener * @@ -18,9 +16,4 @@ public interface MapViewListener { * when mapview load error to callback */ void onMapLoadFail(); - - /** - * @param bitmap - */ - void onGetCurrentMap(Bitmap bitmap); } diff --git a/library/src/main/java/com/onlylemi/mapview/library/utils/MapMath.java b/library/src/main/java/com/onlylemi/mapview/library/utils/MapMath.java index c3b9f0b..58daca1 100644 --- a/library/src/main/java/com/onlylemi/mapview/library/utils/MapMath.java +++ b/library/src/main/java/com/onlylemi/mapview/library/utils/MapMath.java @@ -19,7 +19,7 @@ public final class MapMath { /** - * 得到两点之间的距离 + * the distance between two points * * @param x1 * @param y1 @@ -33,7 +33,7 @@ public static float getDistanceBetweenTwoPoints(float x1, float y1, } /** - * 得到两点之间的距离 + * the distance between two points * * @param start * @param end @@ -46,40 +46,35 @@ public static float getDistanceBetweenTwoPoints(PointF start, PointF end) { /** - * 得到地图中两点间的最短路径点集list (FloydAlgorithm) + * the shortest path between two points (FloydAlgorithm) * - * @param begin 起点 - * @param end 终点 - * @param matrix 点集之间的关系矩阵 + * @param begin + * @param end + * @param matrix adjacency matrix * @return */ public static List getShortestPathBetweenTwoPoints(int begin, int end, float[][] matrix) { - return FloydAlgorithm.getInstance().findCheapestPath(begin, end, matrix); } /** - * 任意点间最优路径 (邻近点) + * the best path between some points (NearestNeighbour tsp) * - * @param matrix + * @param matrix adjacency matrix * @return */ - public static List getShortestPathBetweenPoints(float[][] matrix) { - // TSP 计算最优路线 - List result = new TSPNearestNeighbour().tsp(matrix); - Log.i("MApMath:", result.toString()); - return result; + public static List getBestPathBetweenPointsByNearestNeighbour(float[][] matrix) { + return TSPNearestNeighbour.getInstance().tsp(matrix); } /** - * 任意点间最优路径 (遗传算法) + * the best path between some points (GeneticAlgorithm tsp) * * @param matrix * @return */ - public static List getBestPathByGeneticAlgorithm(float[][] matrix) { - // 遗传算法 tsp + public static List getBestPathBetweenPointsByGeneticAlgorithm(float[][] matrix) { GeneticAlgorithm ga = GeneticAlgorithm.getInstance(); ga.setAutoNextGeneration(true); ga.setMaxGeneration(200); @@ -94,7 +89,7 @@ public static List getBestPathByGeneticAlgorithm(float[][] matrix) { /** - * 得到两点连线与水平面所成夹角 + * get the angle between two points and the horizontal plane * * @param start * @param end @@ -121,7 +116,7 @@ public static float getDegreeBetweenTwoPointsWithHorizontal(PointF start, PointF } /** - * 得到两点连线与垂直面所成夹角 + * get the angle between two points and the vertical plane * * @param start * @param end @@ -148,7 +143,7 @@ public static float getDegreeBetweenTwoPointsWithVertical(PointF start, PointF e } /** - * 获取角度 + * get degree between two points * * @param x1 * @param y1 @@ -162,19 +157,18 @@ public static float getDegreeBetweenTwoPoints(float x1, float y1, float x2, floa } /** - * 获取角度 + * get degree between two points * * @param start * @param end * @return */ public static float getDegreeBetweenTwoPoints(PointF start, PointF end) { - double radians = Math.atan2(start.x - end.x, start.y - end.y); - return (float) Math.toDegrees(radians); + return getDegreeBetweenTwoPoints(start.x, start.y, end.x, end.y); } /** - * 得到两点间中点的坐标 + * The coordinates of the midpoint between two points are obtained * * @param x1 * @param y1 @@ -187,18 +181,18 @@ public static PointF getMidPointBetweenTwoPoints(float x1, float y1, float x2, f } /** - * 得到两点间中点的坐标 + * The coordinates of the midpoint between two points are obtained * * @param start * @param end * @return */ public static PointF getMidPointBetweenTwoPoints(PointF start, PointF end) { - return getEveryPointBetweenTwoPoints(start, end, 0.5f); + return getMidPointBetweenTwoPoints(start.x, start.y, end.x, end.y); } /** - * 得到两点间任意一点的坐标 + * Get the coordinates of any point between two points * * @param start * @param end @@ -206,9 +200,9 @@ public static PointF getMidPointBetweenTwoPoints(PointF start, PointF end) { * @return */ public static PointF getEveryPointBetweenTwoPoints(PointF start, PointF end, float value) { - //坐标系 y=kx+b + // y=kx+b float x, y; - //有斜率 + // with slope if (start.x != end.x) { float k = (end.y - start.y) / (end.x - start.x); float b = end.y - k * end.x; @@ -219,7 +213,7 @@ public static PointF getEveryPointBetweenTwoPoints(PointF start, PointF end, flo x = Math.max(end.x, start.x) + (end.x - start.x) * value; } y = k * x + b; - } else { //无斜率 + } else { // no slope x = start.x; if (end.y > start.y) { y = Math.min(end.y, start.y) + (end.y - start.y) * value; @@ -232,44 +226,44 @@ public static PointF getEveryPointBetweenTwoPoints(PointF start, PointF end, flo /** - * 得到一个点到直线最短距离 + * Get a shortest distance from point to line * - * @param point 已知点 - * @param linePoint1 确定直线的1点 - * @param linePoint2 确定直线的2点 + * @param point + * @param linePoint1 Determine the first point of a straight line + * @param linePoint2 Determine the second point of a straight line * @return */ - public static float getDistancePointToLine(PointF point, PointF linePoint1, PointF linePoint2) { + public static float getDistanceFromPointToLine(PointF point, PointF linePoint1, PointF + linePoint2) { // y = kx + b; // d = |kx-y+b| / √(k^2+1) float d; - if (linePoint1.x != linePoint2.x) { //有斜率 + if (linePoint1.x != linePoint2.x) { // with slope float k = (linePoint2.y - linePoint1.y) / (linePoint2.x - linePoint1.x); float b = linePoint2.y - k * linePoint2.x; d = Math.abs(k * point.x - point.y + b) / (float) Math.sqrt(k * k + 1); - } else { //无斜率 + } else { // no slope d = Math.abs(point.x - linePoint1.x); } return d; } /** - * 得到一个点到直线最短距离的交点坐标 + * get intersection coordinates from a point to a line * * @param point * @param linePoint1 * @param linePoint2 * @return */ - public static PointF getIntersectionPointToLine(PointF point, PointF linePoint1, PointF + public static PointF getIntersectionCoordinatesFromPointToLine(PointF point, PointF linePoint1, PointF linePoint2) { - // y = kx + b; float x, y; - if (linePoint1.x != linePoint2.x) { //有斜率 + if (linePoint1.x != linePoint2.x) { // with slope float k = (linePoint2.y - linePoint1.y) / (linePoint2.x - linePoint1.x); float b = linePoint2.y - k * linePoint2.x; - //过point的垂线方程 + // The equation of point if (k != 0) { float kV = -1 / k; float bV = point.y - kV * point.x; @@ -279,7 +273,7 @@ public static PointF getIntersectionPointToLine(PointF point, PointF linePoint1, x = point.x; y = linePoint1.y; } - } else { //无斜率 + } else { // no slope x = linePoint1.x; y = point.y; } @@ -287,14 +281,14 @@ public static PointF getIntersectionPointToLine(PointF point, PointF linePoint1, } /** - * 判断一个点与一条线段顶点连线的夹角 + * is/not obtuse angle between a point and a line * * @param point * @param linePoint1 * @param linePoint2 * @return */ - public static boolean isObtuseAngleBetweenPointToLine(PointF point, PointF linePoint1, PointF + public static boolean isObtuseAnglePointAndLine(PointF point, PointF linePoint1, PointF linePoint2) { // A*A + B*B < C*C float p_l1, p_l2, l1_l2; diff --git a/library/src/main/java/com/onlylemi/mapview/library/utils/MapUtils.java b/library/src/main/java/com/onlylemi/mapview/library/utils/MapUtils.java index 409b337..542ee04 100644 --- a/library/src/main/java/com/onlylemi/mapview/library/utils/MapUtils.java +++ b/library/src/main/java/com/onlylemi/mapview/library/utils/MapUtils.java @@ -1,16 +1,12 @@ package com.onlylemi.mapview.library.utils; -import android.content.res.AssetManager; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Picture; import android.graphics.PointF; import android.graphics.RectF; import android.util.Log; -import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -19,7 +15,7 @@ * * @author onlylemi */ -public class MapUtils { +public final class MapUtils { private static final String TAG = "MapUtils: "; @@ -27,17 +23,13 @@ public class MapUtils { private static int nodesSize; private static int nodesContactSize; - public static void init(List nodes, List nodesContact) { - if (nodes != null) { - nodesSize = nodes.size(); - } - if (nodesContact != null) { - nodesContactSize = nodesContact.size(); - } + public static void init(int nodessize, int nodescontactsize) { + nodesSize = nodessize; + nodesContactSize = nodescontactsize; } /** - * 得到list点集间的距离 + * Get the distance between points * * @param nodes * @param list @@ -54,7 +46,7 @@ public static float getDistanceBetweenList(List nodes, } /** - * 得到list表中 两点间与水平线所成的夹角集 + * get degrees between two points(list) with horizontal plane * * @param routeList * @param nodes @@ -72,7 +64,7 @@ public static List getDegreeBetweenTwoPointsWithHorizontal(List } /** - * 得到list表中 两点间与垂直线所成的夹角集 + * get degrees between two points(list) with vertical plane * * @param routeList * @param nodes @@ -90,12 +82,12 @@ public static List getDegreeBetweenTwoPointsWithVertical(List ro } /** - * 得到地图中两点间的最短路径点集list + * get shortest path between two points * - * @param start 起点 - * @param end 终点 - * @param nodes 点集list - * @param nodesContact 点集之间的关系list + * @param start start point + * @param end end point + * @param nodes nodes list + * @param nodesContact nodesContact list * @return */ public static List getShortestPathBetweenTwoPoints(int start, @@ -107,17 +99,16 @@ public static List getShortestPathBetweenTwoPoints(int start, } /** - * 得到任意多个点集间的最优路径 + * get best path between points * * @param points * @param nodes * @param nodesContact * @return */ - public static List getShortestPathBetweenPoints(int[] points, - List nodes, List - nodesContact) { - // 关系矩阵 + public static List getBestPathBetweenPoints(int[] points, List nodes, + List nodesContact) { + // adjacency matrix float[][] matrix = new float[points.length][points.length]; for (int i = 0; i < matrix.length; i++) { for (int j = i; j < matrix[i].length; j++) { @@ -132,10 +123,9 @@ nodes, getShortestPathBetweenTwoPoints(points[i], } } - // TSP 计算最优路线 + // TSP to get best path List routeList = new ArrayList<>(); - List result = MapMath.getBestPathByGeneticAlgorithm(matrix); -// Log.i(TAG, result.toString()); + List result = MapMath.getBestPathBetweenPointsByGeneticAlgorithm(matrix); for (int i = 0; i < result.size() - 1; i++) { int size = routeList.size(); routeList.addAll(getShortestPathBetweenTwoPoints( @@ -150,16 +140,16 @@ nodes, getShortestPathBetweenTwoPoints(points[i], /** - * 得到地图上任意多个点集间的最优路径 + * get best path between points * * @param pointList * @param nodes * @param nodesContact * @return */ - public static List getShortestPathBetweenPoints(List pointList, - List nodes, List - nodesContact) { + public static List getBestPathBetweenPoints(List pointList, + List nodes, List + nodesContact) { if (nodesSize != nodes.size()) { int value = nodes.size() - nodesSize; for (int i = 0; i < value; i++) { @@ -171,19 +161,18 @@ public static List getShortestPathBetweenPoints(List pointList, } } - //找到目标点 距离 最近的路线上的点 + //find the point on the nearest route int[] points = new int[pointList.size()]; for (int i = 0; i < pointList.size(); i++) { addPointToList(pointList.get(i), nodes, nodesContact); points[i] = nodes.size() - 1; } - - return getShortestPathBetweenPoints(points, nodes, nodesContact); + return getBestPathBetweenPoints(points, nodes, nodesContact); } /** - * 得到两点间的最短距离 + * get shortest distance between two points * * @param start * @param end @@ -200,7 +189,7 @@ public static float getShortestDistanceBetweenTwoPoints(int start, int end, } /** - * 得到节点集之间的关系矩阵 + * adjacency matrix with points * * @param nodes * @param nodesContact @@ -208,7 +197,7 @@ public static float getShortestDistanceBetweenTwoPoints(int start, int end, */ public static float[][] getMatrixBetweenFloorPlanNodes(List nodes, List nodesContact) { - // 设初始值为无穷大 + // set default is INF float[][] matrix = new float[nodes.size()][nodes.size()]; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { @@ -216,7 +205,7 @@ public static float[][] getMatrixBetweenFloorPlanNodes(List nodes, List< } } - // 给矩阵赋路径权值 + // set value for matrix for (int i = 0; i < nodesContact.size(); i++) { matrix[(int) nodesContact.get(i).x][(int) nodesContact.get(i).y] = MapMath .getDistanceBetweenTwoPoints(nodes.get((int) nodesContact.get(i).x), @@ -231,7 +220,7 @@ public static float[][] getMatrixBetweenFloorPlanNodes(List nodes, List< } /** - * 得到地图中任意两点间的最短路径 + * get shortest distance between two points * * @param start * @param end @@ -242,8 +231,6 @@ public static float[][] getMatrixBetweenFloorPlanNodes(List nodes, List< public static List getShortestDistanceBetweenTwoPoints(PointF start, PointF end, List nodes, List nodesContact) { - Log.i(TAG, "getShortestDistanceBetweenTwoPoints"); - if (nodesSize != nodes.size()) { int value = nodes.size() - nodesSize; for (int i = 0; i < value; i++) { @@ -263,7 +250,7 @@ public static List getShortestDistanceBetweenTwoPoints(PointF start, Po } /** - * 得到地图中目标点到定位点的最短路径 + * get the shortest path from the position point to the target point in the map * * @param position * @param target @@ -291,7 +278,7 @@ public static List getShortestDistanceBetweenTwoPoints(PointF position, } /** - * 添加点到list中去 + * add point to list * * @param point * @param nodes @@ -306,24 +293,30 @@ private static void addPointToList(PointF point, List nodes, List minDis) { - pV = MapMath.getIntersectionPointToLine(point, p1, p2); + pV = MapMath.getIntersectionCoordinatesFromPointToLine(point, p1, p2); min1 = minDis; po1 = (int) nodesContact.get(i).x; po2 = (int) nodesContact.get(i).y; } } } - //得到交点 + // get intersection nodes.add(pV); - Log.i(TAG, "node=" + (nodes.size() - 1) + ", po1=" + po1 + ", po2=" + po2); + //Log.i(TAG, "node=" + (nodes.size() - 1) + ", po1=" + po1 + ", po2=" + po2); nodesContact.add(new PointF(po1, nodes.size() - 1)); nodesContact.add(new PointF(po2, nodes.size() - 1)); } } + /** + * bitmap to picture + * + * @param bitmap + * @return + */ public static Picture getPictureFromBitmap(Bitmap bitmap) { Picture picture = new Picture(); Canvas canvas = picture.beginRecording(bitmap.getWidth(), diff --git a/library/src/main/java/com/onlylemi/mapview/library/utils/math/FloydAlgorithm.java b/library/src/main/java/com/onlylemi/mapview/library/utils/math/FloydAlgorithm.java index 8171ddf..122c9fe 100644 --- a/library/src/main/java/com/onlylemi/mapview/library/utils/math/FloydAlgorithm.java +++ b/library/src/main/java/com/onlylemi/mapview/library/utils/math/FloydAlgorithm.java @@ -10,10 +10,10 @@ */ public final class FloydAlgorithm { - private static final int INF = Integer.MAX_VALUE; // 无边 + private static final int INF = Integer.MAX_VALUE; private float[][] dist; - // 顶点i 到 j的最短路径长度,初值是i到j的边的权重 + // the shortest path from i to j private int[][] path; private List result; @@ -35,7 +35,7 @@ private void init(float[][] matrix) { } /** - * 求两点间的最短路径 + * the shortest between begin to end * * @param begin * @param end @@ -56,7 +56,7 @@ private void findPath(int i, int j) { int k = path[i][j]; if (k == -1) return; - findPath(i, k); // 递归 + findPath(i, k); // recursion result.add(k); findPath(k, j); } diff --git a/library/src/main/java/com/onlylemi/mapview/library/utils/math/TSPNearestNeighbour.java b/library/src/main/java/com/onlylemi/mapview/library/utils/math/TSPNearestNeighbour.java index 889ce4f..494f4a8 100644 --- a/library/src/main/java/com/onlylemi/mapview/library/utils/math/TSPNearestNeighbour.java +++ b/library/src/main/java/com/onlylemi/mapview/library/utils/math/TSPNearestNeighbour.java @@ -1,17 +1,26 @@ package com.onlylemi.mapview.library.utils.math; +import java.net.FileNameMap; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class TSPNearestNeighbour { - private static final float INF = Float.MAX_VALUE; // 无边 + private static final float INF = Float.MAX_VALUE; private int numberOfNodes; private Stack stack; private List list; + public static TSPNearestNeighbour getInstance() { + return TSPNearestNeighbourHolder.instance; + } + + private static class TSPNearestNeighbourHolder { + private static TSPNearestNeighbour instance = new TSPNearestNeighbour(); + } + public TSPNearestNeighbour() { stack = new Stack<>(); list = new ArrayList<>();