我是采用html5来处理如何在一张图片上画线,比如一张google static map在上面画路况信息
首先在html上建立容器
然后执行如下js方法
function drawRect() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var pic = new Image();
pic.src = "${url}";
if(pic.complete){
context.drawImage(pic, 0, 0);
${coorddinates};
}else{
pic.onload = function(){
pic = new Image();
pic.src = "${url}";
context.drawImage(pic, 0, 0);
${coorddinates};
};
}
}
其中coorddinates包含了画线所执行的语句,在后台准备;
现在开始说后台程式的编写,
首先我们会有一段经纬度坐标,我们假设显示的图片大小为320*480的图片上
那么我们就需要赛选哪些经纬度会出现在这个图片上
public static List<DeviceCCTV> getDeviceCCTVInPicture(int zoom,double x,double y,List<DeviceCCTV> list){
List<DeviceCCTV> decList = new ArrayList<DeviceCCTV>();
double zoomLevel0 = 1.40625;
while(zoom!=0){
zoomLevel0 = zoomLevel0/2;
zoom--;
}
double Sgx = x+zoomLevel0*240;
double Egx = x-zoomLevel0*240;
double Sgy = y+zoomLevel0*160;
double Egy = y-zoomLevel0*160;
for(DeviceCCTV dc:list){
if(Double.parseDouble(dc.getWgsy())>Egx&&Double.parseDouble(dc.getWgsy())<Sgx){
if(Double.parseDouble(dc.getWgsx())>Egy&&Double.parseDouble(dc.getWgsx())<Sgy){
decList.add(dc);
}
}
}
return decList;
}
其中参数x Y 为这个google static map中心点的坐标
其中zoomLevel10为map缩放比例为10时,一个像素点转化为1.4625的经纬度差距
故来筛选这张在一定缩放比例上,所能显示的经纬度范围。
这样经纬度准备完毕以后,开始拼接html5所要画图语句:
String coorddinates = "";
for (Coordinate c : coorddinateList) {
List<String> pathList = c.getCoordinate();
coorddinates += "context.beginPath();";
for (int i = 0; i < pathList.size(); i++) {
String[] str = pathList.get(i).split(",");
double y = 240
+ DeviceUtil.latToPixel(
Double.parseDouble(str[0]), 13)
- DeviceUtil.latToPixel(
Double.parseDouble(positionArray[0]), 13);
double x = 160
+ DeviceUtil.lngToPixel(
Double.parseDouble(str[1]), 13)
- DeviceUtil.lngToPixel(
Double.parseDouble(positionArray[1]), 13);
if(i==0){
coorddinates += "context.moveTo("+(x)+", "+(y)+");";
}
coorddinates += "context.lineTo("+(x)+", "+(y)+");";
}
if(c.getColor().equals("#style0")){
coorddinates += "context.strokeStyle = '#00ff00';";
}else if(c.getColor().equals("#style1")){
coorddinates += "context.strokeStyle = '#f79708';";
}else if(c.getColor().equals("#style2")){
coorddinates += "context.strokeStyle = '#ff0000';";
}else if(c.getColor().equals("#style3")){
coorddinates += "context.strokeStyle = '##5a5a5a';";
}
coorddinates += "context.stroke();";
}
url = url + "format=jpg&sensor=false&mobile=true";
其中需要使用到的 将经度和纬度坐标转换成象数坐标,一这张图片上的中心点(160,240)做计算
那么我是通过计算要画的点与中心点的经纬度差距得到的象数差,得到的象数差再加上中心点的象数值,来得到这个点应该在这个图片上的象数点位置。
那么最后提供的就是将经纬度计算成象数的方法:
/**
* 经度到象数点
* @param lng
* @param zoom
* @return
*/
public static double lngToPixel(double lng, int zoom) {
return (lng + 180) * (256L << zoom) / 360;
}
/**
* 纬度到象数点
* @param lat
* @param zoom
* @return
*/
public static double latToPixel(double lat, int zoom) {
double siny = Math.sin(lat * Math.PI / 180);
double y = Math.log((1 + siny) / (1 - siny));
return (128 << zoom) * (1 - y / (2 * Math.PI));
}
需要注意的是纬度是横的,经度是竖的,在地球仪上。而在google static map的图片上横向距离为经度差,而纵向距离为纬度差。
最后这样将拼接好的html5语句传给前面所写的js方法里,就可以显示了。