问题描述:使用成百上千个GPS坐标画路线,在android上的Google Map显示出来
之前我实现过一次,将每个点都遍历一边,然后在Google Map上画出来,但是由于
数据过多导致Google地图移动位置变得不流畅,每次移动Google地图都会调用draw
方法,那么程序一直遍历一直画图,花费大且不流畅。这次做了下优化,对只在屏幕内
的坐标画线。Google地图比之前流畅多了。
之前实现是画蓝色的线,这次实现只画红色的线。
临界条件是上一个点在屏幕内,下一个点在屏幕外。
运行环境:android版本2.3
package com.ui;import java.util.ArrayList;import java.util.List;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.Path;import android.util.Log;import com.google.android.maps.GeoPoint;import com.google.android.maps.MapView;import com.google.android.maps.Overlay;import com.google.android.maps.Projection;import com.model.Point;public class RouteOverlay extends Overlay{ final static String TAG = "DrawRoutePath"; private List<Point> points = new ArrayList<Point>(); private final Projection projection; private final Paint paint; public RouteOverlay(Projection projection) { this.projection = projection; // 设置画笔 paint = new Paint(); paint.setColor(Color.RED); // 画笔的粗细 paint.setStrokeWidth(3); paint.setAntiAlias(true); paint.setStrokeMiter(3); paint.setStyle(Style.STROKE); } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { super.draw(canvas, mapView, shadow); if(shadow) { return; } // 这里使用系统提供的Path,Point来画图 Path drawingPath = new Path(); android.graphics.Point pixelPoint = new android.graphics.Point(); // 得到当前屏幕的高*宽 int width = canvas.getWidth(); int height = canvas.getHeight(); GeoPoint bottomRight = projection.fromPixels(width, height); GeoPoint topLeft = projection.fromPixels(0, 0); int maxLat = topLeft.getLatitudeE6(); int minLat = bottomRight.getLatitudeE6(); int minLon = topLeft.getLongitudeE6(); int maxLon = bottomRight.getLongitudeE6(); int pointsSize = points.size(); // 之前的布点是否在屏幕中 boolean preOutOfBounds = true; // 之前的布点是否是新的一段路线的开始 boolean preWasMoveTo = true; int moveToLat = Integer.MAX_VALUE; int moveToLon = Integer.MIN_VALUE; for(int i=0; i<pointsSize; i++) { double pointLat = points.get(i).getLat(); int pointLatInt = (int)(pointLat * 1E6); double pointLon = points.get(i).getLon(); int pointLonInt = (int)(pointLon * 1E6); // 判断该点有没有超出屏幕显示的范围 boolean currentOutOfBounds = pointLatInt < minLat || pointLatInt > maxLat || pointLonInt < minLon || pointLonInt > maxLon; // 起点或者先前节点和当前节点都在屏幕之外,将preWasMoveTo设为true‘ // 当前坐标在屏幕外,并且之前坐标也在屏幕外,则设置preWasMoveTo为true if(i == 0 || (preOutOfBounds && currentOutOfBounds)) { moveToLat = pointLatInt; moveToLon = pointLonInt; preWasMoveTo = true; } else { if(preWasMoveTo) { GeoPoint geoPoint = new GeoPoint(moveToLat, moveToLon); // 将经纬度转换为屏幕画布像素上的点(称之为布点) projection.toPixels(geoPoint, pixelPoint); // 设置point.x, point.y为新一段路线的开始 drawingPath.moveTo(pixelPoint.x, pixelPoint.y); preWasMoveTo = false; } GeoPoint geoPoint = new GeoPoint(pointLatInt, pointLonInt); projection.toPixels(geoPoint, pixelPoint); // 将最后的布点与该布点之间画一条线 drawingPath.lineTo(pixelPoint.x, pixelPoint.y); } preOutOfBounds = currentOutOfBounds; } canvas.drawPath(drawingPath, paint); } public void setPoints(ArrayList<Point> points) { this.points = points; }}