分類: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】下面的注釋。
運行觀察效果。