我是采用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方法里,就可以显示了。