JAVA实现百度地图上绘制离散点等值线——离散点插值+等值线算法+BaiduMap绘制

最近希望在android上实现在百度地图绘制重力异常图(地形图),查了一下官方提供了一个热力图绘制方法,效果很好,但只能显示官方提供的人员流量数据,所以退一步试着实现简单的等值线图绘制,不难,着急的朋友完全可以仿照下例修改使用:

主要方法:

①对离散点构造矩形区域并插值:
insertValue(List longitude,List latitude ,List value,int row ,int col);
参数含义:longitude/latitdue/value测点经、纬度和测值列表,顺序依次对应,row/col目标插值矩阵行列数;

对插值矩阵实现等值线算法 :
createContour(float[ ][ ] data,int ilb,int iub, int jlb, int jub,float[ ] insert_longitude,float[ ] insert_latitude,int n ,float[ ] z);
参数含义:data经插值后得到的矩阵,ilb/iub/jlb/jub很多时候我们仅需要对一部分区域绘制等值线,这四个参数决定了取data矩阵中哪部分计算等值线,取值0~(row-1)或者0~(col-1),insert_longitude/latitude插值后对应矩阵点横纵坐标值(经纬度),n测线的数量,越大等值线越密,z的长度与n对应,指示每段等值线间要间隔的数值;

③在BaiduMap上绘制等值线:

drawCoutour(float longitude1,float latitude1,float longitude2,float latitude2,Baidumap);

前四个参数指示了要绘制直线的起始位置,并传入一个发生绘制的地图组件;


public  void insertValue(List longitude,List latitude,List value,int row_latitude,int col_longitude,int n) {

    		float max_longitude,min_longitude,max_latitude,min_latitude,add_longitude,add_latitude;
    		float insert_longitude[]=new float[col_longitude];
    		float insert_latitude[]=new float[row_latitude];  
    		float insert_value[][]=new float[row_latitude][col_longitude]; 
    		max_longitude=Collections.max(longitude);
    		min_longitude=Collections.min(longitude);
    		max_latitude=Collections.max(latitude);
    		min_latitude=Collections.min(latitude);
    		add_longitude=(max_longitude-min_longitude)/col_longitude;
    		add_latitude=(max_latitude-min_latitude)/row_latitude;
    		
    		for(int i=0;i public void createContour(float[][] data, int ilb, int iub, int jlb, int jub, float [] x, float [] y, int nc, float [] z){
double x1 = 0.0;
    	double x2 = 0.0;
    	double y1 = 0.0;
    	double y2 = 0.0;
    	int i,j,k,m;
    	int [] im = {0,1,1,0};
    	int [] jm = {0,0,1,1};
    	int [][][] castab=
    	{
    	{
    	{0,0,8},{0,2,5},{7,6,9}
    	},
    	{
    	{0,3,4},{1,3,1},{4,3,0}
    	},
    	{
    	{9,6,7},{5,2,0},{8,0,0}
    	}
    	};
    	
    	for (j=(jub-1);j>=jlb;j--) {
    	for (i=ilb;i<=iub-1;i++) {
    	double temp1,temp2;
    	temp1 = Math.min(d[i][j],d[i][j+1]);
    	temp2 = Math.min(d[i+1][j],d[i+1][j+1]);
    	dmin= Math.min(temp1,temp2);
    	temp1 = Math.max(d[i][j],d[i][j+1]);
    	temp2 = Math.max(d[i+1][j],d[i+1][j+1]);
    	dmax= Math.max(temp1,temp2);
    	if (dmax>=z[0]&&dmin<=z[nc-1]) {
    	for (k=0;k=dmin&&z[k]<=dmax) {
    	for (m=4;m>=0;m--) {
    	if (m>0) {
    	h[m] = d[i+im[m-1]][j+jm[m-1]]-z[k];
    	xh[m] = x[i+im[m-1]];
    	yh[m] = y[j+jm[m-1]];
    	} else {
    	h[0] = 0.25*(h[1]+h[2]+h[3]+h[4]);
    	xh[0]=0.5*(x[i]+x[i+1]);
    	yh[0]=0.5*(y[j]+y[j+1]);
    	}
    	if (h[m]>0.0) {
    	sh[m] = 1;
    	} else if (h[m]<0.0) {
    	sh[m] = -1;
    	} else
    	sh[m] = 0;
    	}
    	for (m=1;m<=4;m++) {
    	m1 = m;
    	m2 = 0;
    	if (m!=4) {
    	m3 = m+1;
    	} else {
    	m3 = 1;
    	}
    	case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1];
    	if (case_value!=0) {
    	switch (case_value) {
    	case 1: // Line between vertices 1 and 2
    	x1=xh[m1];
    	y1=yh[m1];
    	x2=xh[m2];
    	y2=yh[m2];
    	break;
    	case 2: // Line between vertices 2 and 3
    	x1=xh[m2];
    	y1=yh[m2];
    	x2=xh[m3];
    	y2=yh[m3];
    	break;
    	case 3: // Line between vertices 3 and 1
    	x1=xh[m3];
    	y1=yh[m3];
    	x2=xh[m1];
    	y2=yh[m1];
    	break;
    	case 4: // Line between vertex 1 and side 2-3
    	x1=xh[m1];
    	y1=yh[m1];
    	x2=xsect(m2,m3);
    	y2=ysect(m2,m3);
    	break;
    	case 5: // Line between vertex 2 and side 3-1
    	x1=xh[m2];
    	y1=yh[m2];
    	x2=xsect(m3,m1);
    	y2=ysect(m3,m1);
    	break;
    	case 6: //Line between vertex 3 and side 1-2
    	x1=xh[m3];
    	y1=yh[m3];
    	x2=xsect(m1,m2);
    	y2=ysect(m1,m2);
    	break;
    	case 7: // Line between sides 1-2 and 2-3
    	x1=xsect(m1,m2);
    	y1=ysect(m1,m2);
    	x2=xsect(m2,m3);
    	y2=ysect(m2,m3);
    	break;
    	case 8: // Line between sides 2-3 and 3-1
    	x1=xsect(m2,m3);
    	y1=ysect(m2,m3);
    	x2=xsect(m3,m1);
    	y2=ysect(m3,m1);
    	break;
    	case 9: // Line between sides 3-1 and 1-2
    	x1=xsect(m3,m1);
    	y1=ysect(m3,m1);
    	x2=xsect(m1,m2);
    	y2=ysect(m1,m2);
    	break;
    	default:
    	break;
    	}
    	this.drawContour((float)x1, (float)y1, (float)x2, (float)y2, baidumap);//注意在此调用drawContour绘制等值线
    	//System.out.println("绘制线段,从点("+x1+","+y1+")到("+x2+","+y2+")");
    	}}}}}}}}

public void drawContour(float long1,float lat1,float long2,float lat2,BaiduMap baodumap) {
    	
        LatLng p1 = new LatLng(long1, lat1);
        LatLng p2 = new LatLng(long2, lat2);
        List points = new ArrayList();
        points.add(p1);
        points.add(p2);
    //绘制折线
        OverlayOptions ooPolyline = new PolylineOptions().width(10)
                .color(0xAAFF0000).points(points);
        Polyline mPolyline = (Polyline)baidumap.addOverlay(ooPolyline);
    }
//几个辅助方法
public float distance2(float insert_longitude,float insert_latitude,float longitude,float latitude) {
    	return (float) (Math.pow((float) Math.pow((longitude-insert_longitude),2)+Math.pow((latitude-insert_latitude),2),1))       ;}

private double xsect(int p1, int p2){
    	return(h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]);
    	}
    	
private double ysect(int p1, int p2){
    	return (h[p2]*yh[p1]-h[p1]*yh[p2])/(h[p2]-h[p1]);
    	}

1.以下是不同测线数量的显示效果(用java graphics简单绘制),可以看到在要求精度不高的情况下可以有效实现等值线的绘制:

JAVA实现百度地图上绘制离散点等值线——离散点插值+等值线算法+BaiduMap绘制_第1张图片

JAVA实现百度地图上绘制离散点等值线——离散点插值+等值线算法+BaiduMap绘制_第2张图片

2.第一个方法中List的使用例子:
        List longitude=new ArrayList<>();
List latitude=new ArrayList<>();
List value=new ArrayList<>();

longitude.add((float) 100);//继续添加坐标值...
latitude.add((float) 110);   //继续添加坐标值...
        value.add((float) 50);        //继续添加测点值...

希望能帮到有需要的人。




你可能感兴趣的:(JAVA实现百度地图上绘制离散点等值线——离散点插值+等值线算法+BaiduMap绘制)