分類:C#、Android、百度地圖應用; 日期:2016-02-04
百度地圖SDK為廣大開發者開放了OpenGL繪制接口,幫助開發者在地圖上實現更靈活的樣式繪制,豐富地圖使用效果體驗。
簡介:介紹如何使用OpenGL在地圖上實現自定義繪制。
詳述:
(1)利用OpenGL繪制基本折線;
(2)利用OpenGL在地圖上進行紋理繪制;
本示例運行截圖如下:
1、添加demo24_opengl.xml文件
在layout文件夾下添加該文件,然後將代碼改為下面的內容:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.baidu.mapapi.map.TextureMapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
2、添加Demo24OpenGL.cs文件
在SrcSdkDemos文件夾下添加該文件,然後將代碼改為下面的內容:
using Android.App;
using Android.OS;
using Com.Baidu.Mapapi.Map;
using Com.Baidu.Mapapi.Model;
using Android.Graphics;
using Android.Util;
using System.Collections.Generic;
using Javax.Microedition.Khronos.Opengles;
using Java.Nio;
using Android.Opengl;
namespace BdMapV371Demos.SrcSdkDemos
{
/// <summary>
/// 此demo用來展示如何在地圖繪制的每幀中再額外繪制一些用戶自己的內容
/// </summary>
[Activity(Label = "@string/demo_name_opengl")]
public class Demo24OpenGL : Activity, BaiduMap.IOnMapDrawFrameCallback
{
// 地圖相關
private TextureMapView mMapView;
private BaiduMap mBaiduMap;
private Bitmap bitmap;
private LatLng latlng1 = new LatLng(39.97923, 116.357428);
private LatLng latlng2 = new LatLng(39.94923, 116.397428);
private LatLng latlng3 = new LatLng(39.96923, 116.437428);
private IList<LatLng> latLngPolygon;
private float[] vertexs;
private FloatBuffer vertexBuffer;
private int textureId = -1;
private readonly string LTAG = "Demo24OpenGL";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.demo24_opengl);
mMapView = FindViewById<TextureMapView>(Resource.Id.bmapView);
mBaiduMap = mMapView.Map;
latLngPolygon = new List<LatLng>()
{
latlng1,latlng2,latlng3
};
mBaiduMap.SetOnMapDrawFrameCallback(this);
bitmap = BitmapFactory.DecodeResource(Resources,
Resource.Drawable.ground_overlay);
}
protected override void OnPause()
{
mMapView.OnPause();
base.OnPause();
}
protected override void OnResume()
{
mMapView.OnResume();
textureId = -1;
base.OnResume();
}
protected override void OnDestroy()
{
mMapView.OnDestroy();
base.OnDestroy();
}
public void OnMapDrawFrame(IGL10 gl, MapStatus drawingMapStatus)
{
if (mBaiduMap.Projection != null)
{
calPolylinePoint(drawingMapStatus);
drawPolyline(gl, Color.Argb(255, 255, 0, 0), vertexBuffer, 10, 3,
drawingMapStatus);
drawTexture(gl, bitmap, drawingMapStatus);
}
}
public void calPolylinePoint(MapStatus mspStatus)
{
PointF[] polyPoints = new PointF[latLngPolygon.Count];
vertexs = new float[3 * latLngPolygon.Count];
int i = 0;
foreach (LatLng xy in latLngPolygon)
{
polyPoints[i] = mBaiduMap.Projection.ToOpenGLLocation(xy, mspStatus);
vertexs[i * 3] = polyPoints[i].X;
vertexs[i * 3 + 1] = polyPoints[i].Y;
vertexs[i * 3 + 2] = 0.0f;
i++;
}
for (int j = 0; j < vertexs.Length; j++)
{
Log.Debug(LTAG, "vertexs[" + j + "]: " + vertexs[j]);
}
vertexBuffer = makeFloatBuffer(vertexs);
}
private FloatBuffer makeFloatBuffer(float[] fs)
{
ByteBuffer bb = ByteBuffer.AllocateDirect(fs.Length * 4);
bb.Order(ByteOrder.NativeOrder());
FloatBuffer fb = bb.AsFloatBuffer();
fb.Put(fs);
fb.Position(0);
return fb;
}
private void drawPolyline(IGL10 gl, int color, FloatBuffer lineVertexBuffer,
float lineWidth, int pointSize, MapStatus drawingMapStatus)
{
gl.GlEnable(GL10.GlBlend);
gl.GlEnableClientState(GL10.GlVertexArray);
gl.GlBlendFunc(GL10.GlSrcAlpha, GL10.GlOneMinusSrcAlpha);
float colorA = Color.GetAlphaComponent(color) / 255f;
float colorR = Color.GetRedComponent(color) / 255f;
float colorG = Color.GetGreenComponent(color) / 255f;
float colorB = Color.GetBlueComponent(color) / 255f;
gl.GlVertexPointer(3, GL10.GlFloat, 0, lineVertexBuffer);
gl.GlColor4f(colorR, colorG, colorB, colorA);
gl.GlLineWidth(lineWidth);
gl.GlDrawArrays(GL10.GlLineStrip, 0, pointSize);
gl.GlDisable(GL10.GlBlend);
gl.GlDisableClientState(GL10.GlVertexArray);
}
/// <summary>
/// 使用opengl坐標繪制
/// </summary>
/// <param name="gl"></param>
/// <param name="bitmap"></param>
/// <param name="drawingMapStatus"></param>
public void drawTexture(IGL10 gl, Bitmap bitmap, MapStatus drawingMapStatus)
{
PointF p1 = mBaiduMap.Projection.ToOpenGLLocation(latlng2,
drawingMapStatus);
PointF p2 = mBaiduMap.Projection.ToOpenGLLocation(latlng3,
drawingMapStatus);
ByteBuffer byteBuffer = ByteBuffer.AllocateDirect(4 * 3 * 4);
byteBuffer.Order(ByteOrder.NativeOrder());
FloatBuffer vertices = byteBuffer.AsFloatBuffer();
vertices.Put(new float[] { p1.X, p1.Y, 0.0f, p2.X, p1.Y, 0.0f, p1.X,
p2.Y, 0.0f, p2.X, p2.Y, 0.0f });
ByteBuffer indicesBuffer = ByteBuffer.AllocateDirect(6 * 2);
indicesBuffer.Order(ByteOrder.NativeOrder());
ShortBuffer indices = indicesBuffer.AsShortBuffer();
indices.Put(new short[] { 0, 1, 2, 1, 2, 3 });
ByteBuffer textureBuffer = ByteBuffer.AllocateDirect(4 * 2 * 4);
textureBuffer.Order(ByteOrder.NativeOrder());
FloatBuffer texture = textureBuffer.AsFloatBuffer();
texture.Put(new float[] { 0, 1f, 1f, 1f, 0f, 0f, 1f, 0f });
indices.Position(0);
vertices.Position(0);
texture.Position(0);
// 生成紋理
if (textureId == -1)
{
int[] textureIds = new int[1];
gl.GlGenTextures(1, textureIds, 0);
textureId = textureIds[0];
Log.Debug(LTAG, "textureId: " + textureId);
gl.GlBindTexture(GL10.GlTexture2d, textureId);
GLUtils.TexImage2D(GL10.GlTexture2d, 0, bitmap, 0);
gl.GlTexParameterf(GL10.GlTexture2d, GL10.GlTextureMinFilter, GL10.GlNearest);
gl.GlTexParameterf(GL10.GlTexture2d, GL10.GlTextureMagFilter, GL10.GlNearest);
gl.GlBindTexture(GL10.GlTexture2d, 0);
}
gl.GlEnable(GL10.GlTexture2d);
gl.GlEnableClientState(GL10.GlVertexArray);
gl.GlEnableClientState(GL10.GlTextureCoordArray);
gl.GlEnable(GL10.GlBlend);
gl.GlBlendFunc(GL10.GlSrcAlpha, GL10.GlOneMinusSrcAlpha);
gl.GlColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// 綁定紋理ID
gl.GlBindTexture(GL10.GlTexture2d, textureId);
gl.GlVertexPointer(3, GL10.GlFloat, 0, vertices);
gl.GlTexCoordPointer(2, GL10.GlFloat, 0, texture);
gl.GlDrawElements(GL10.GlTriangleStrip, 6, GL10.GlUnsignedShort, indices);
gl.GlDisable(GL10.GlTexture2d);
gl.GlDisableClientState(GL10.GlVertexArray);
gl.GlDisableClientState(GL10.GlTextureCoordArray);
gl.GlDisable(GL10.GlBlend);
}
}
}
3、修改MainActivity.cs文件
在MainActivity.cs文件的demos字段定義中,去掉【示例24】下面的注釋。
運行觀察效果。