简介:
通过源码,我们来一步步分析Mapbox地图引擎如何进行不同数据源的地图渲染的,这里是基于5.3.0的版本.
首先,我们找到地图的核心类,MapView,这个view就是用来显示地图的,它是在mapbox.mapboxsdk.maps包下,看到它的初始化之后,发现它有这么一个方法,叫做initialiseDrawingSurface(),从名字上看可以看出这是一个初始化画布的方法,我们看下它的实现.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| private void initialiseDrawingSurface(MapboxMapOptions options) { if (options.getTextureMode()) { TextureView textureView = new TextureView(getContext()); mapRenderer = new TextureViewMapRenderer(getContext(), textureView) { @Override protected void onSurfaceCreated(GL10 gl, EGLConfig config) { MapView.this.post(new Runnable() { @Override public void run() { if (mapboxMap == null) { initialiseMap(); mapboxMap.onStart(); } } }); super.onSurfaceCreated(gl, config); } }; addView(textureView, 0); } else { GLSurfaceView glSurfaceView = (GLSurfaceView) findViewById(R.id.surfaceView); glSurfaceView.setZOrderMediaOverlay(mapboxMapOptions.getRenderSurfaceOnTop()); mapRenderer = new GLSurfaceViewMapRenderer(getContext(), glSurfaceView) { @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { MapView.this.post(new Runnable() { @Override public void run() { if (mapboxMap == null) { initialiseMap(); mapboxMap.onStart(); } } }); super.onSurfaceCreated(gl, config); } }; glSurfaceView.setVisibility(View.VISIBLE); } nativeMapView = new NativeMapView(this, mapRenderer); nativeMapView.resizeView(getMeasuredWidth(), getMeasuredHeight()); }
|
这里我们可以看出来,它首先根据选项区分使用TextureView作为view载体,还是GLSurfaceView作为view载体,然后分别讲TextureView和GLSurfaceView通过自定义的两个渲染器TextureViewMapRenderer和GLSurfaceViewMapRenderer的构造方法传递进去进行绑定.这里我们看GLSurfaceViewMapRenderer这个类.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| public class GLSurfaceViewMapRenderer extends MapRenderer implements GLSurfaceView.Renderer { private final GLSurfaceView glSurfaceView; public GLSurfaceViewMapRenderer(Context context, GLSurfaceView glSurfaceView) { super(context); this.glSurfaceView = glSurfaceView; glSurfaceView.setEGLContextClientVersion(2); glSurfaceView.setEGLConfigChooser(new EGLConfigChooser()); glSurfaceView.setRenderer(this); glSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY); } @Override public void onStop() { glSurfaceView.onPause(); } @Override public void onStart() { glSurfaceView.onResume(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { super.onSurfaceCreated(gl, config); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { super.onSurfaceChanged(gl, width, height); } @Override public void onDrawFrame(GL10 gl) { super.onDrawFrame(gl); } @Override public void requestRender() { glSurfaceView.requestRender(); } @Override public void queueEvent(Runnable runnable) { glSurfaceView.queueEvent(runnable); }}
|
从这个源码我们可以看出来它并未做什么工作,只是在构造方法里做了一些基础配置,和绑定了GLSurfaceView.Renderer渲染器.其它都丢到TextureViewMapRenderer和GLSurfaceViewMapRenderer共同的父类MapRenderer里了,这里我们看下MapRenderer又做了什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @CallSuper protected void onSurfaceCreated(GL10 gl, EGLConfig config) { nativeOnSurfaceCreated(); } @CallSuper protected void onSurfaceChanged(GL10 gl, int width, int height) { if (width < 0) { throw new IllegalArgumentException("fbWidth cannot be negative."); } if (height < 0) { throw new IllegalArgumentException("fbHeight cannot be negative."); } if (width > 65535) { throw new IllegalArgumentException( "fbWidth cannot be greater than 65535."); } if (height > 65535) { throw new IllegalArgumentException( "fbHeight cannot be greater than 65535."); } gl.glViewport(0, 0, width, height); nativeOnSurfaceChanged(width, height); } @CallSuper protected void onDrawFrame(GL10 gl) { nativeRender(); if (onFpsChangedListener != null) { updateFps(); } }
|
我们看到MapRenderer也声明了onSurfaceCreated(),onSurfaceChanged(),onDrawFrame()方法,并加上@CallSuper注解用于子类必须调用父类这三个方法,但是我们看到他们也并未做什么,而是分别调用了native*()将实现放入底层,这样性能会更好一些,一般onSurfaceCreated()是进行一些初始化配置的工作,onSurfaceChanged()执行画面有改变的时候,onDrawFrame()执行绘制的工作.这里我们跟踪onDrawFrame()内调用的nativeRender()方法
这里我们看到与MapRenderer对应的实现底层文件map_renderer.cpp,这里我们看到它的registerNative()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void MapRenderer::registerNative(jni::JNIEnv& env) { MapRenderer::javaClass = *jni::Class<MapRenderer>::Find(env).NewGlobalRef(env).release(); #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) jni::RegisterNativePeer<MapRenderer>(env, MapRenderer::javaClass, "nativePtr", std::make_unique<MapRenderer, JNIEnv&, jni::Object<MapRenderer>, jni::Object<FileSource>, jni::jfloat, jni::String>, "nativeInitialize", "finalize", METHOD(&MapRenderer::render, "nativeRender"), METHOD(&MapRenderer::onSurfaceCreated, "nativeOnSurfaceCreated"), METHOD(&MapRenderer::onSurfaceChanged, "nativeOnSurfaceChanged")); }
|
这里我们看到它将上层的nativeRender()方法和自己的render()方法进行绑定,我们接着看它的render()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| void MapRenderer::render(JNIEnv&) { assert (renderer); std::shared_ptr<UpdateParameters> params; { std::unique_lock<std::mutex> lock(updateMutex); if (!updateParameters) return; params = updateParameters; } BackendScope backendGuard { *backend }; Scheduler::SetCurrent(this); if (framebufferSizeChanged) { backend->updateViewPort(); framebufferSizeChanged = false; } renderer->render(*params); if (snapshotCallback) { snapshotCallback->operator()(backend->readFramebuffer()); snapshotCallback.reset(); } }
|
这里我们看到了这么一行代码renderer->render(*params);它将有关更新数据传入底层Renderer类中的render()方法,继续往下看
1 2 3
| void Renderer::render(const UpdateParameters& updateParameters) { impl->render(updateParameters); }
|
这里我们看到它将实现都放到它的Impl实现类,即renderer_impl文件里.这里我们看到render()方法中这行代码
1 2 3 4 5
| for (const auto& entry : renderSources) { if (entry.second->isEnabled()) { entry.second->startRender(parameters); } }
|
这里通过RenderSource.startRender()方法开始渲染,其startRender()方法是虚函数,其子类RenderAnnotationSource,RenderGeoJSONSource,RenderRasterSource,RenderVectorSource,RenderImageSource分别继承并实现了它.