mapbox的基本原理和核心差异

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mapbox的基本原理和核心差异相关的知识,希望对你有一定的参考价值。

参考技术A 首先来科普一下什么是webgl

webgl 全拼 Web Graphics Library 是一种3D绘图协议,可以为html5 Canvas 提供硬件3D加速渲染,web开发人员可以借助系统显卡在浏览器里更流畅地展示3D场景和模型,还能创建复杂的导航和数据视觉化

核心差异

1.渲染差异

Mapbox GL JS (mapbox graphics library javascript

的 核心特点 是 客户端渲染

在Mapbox GL JS中创建web应用时,通过Javascript和WebGL把地图作为 vector tiles(矢量瓦片)进行渲染

相比将服务器的一系列切片图片组合起来再显示,Mapbox GL JS 渲染可以快速改变样式,使得地图的呈现更加多样化

2. 图层(layers)

传统的 JavaScript 地图库有两种完全不同的 " 图层 ":

基础图层(baselayers) :构成地图基础的 图像切片 。通常包含大量数据——街道地图包括标注、建筑、图标等细节,在浏览器上渲染的话效果不会太好。可参考 Mapbox.js 中的 L.mapbox.tileLayer 和 Leaflet 中的 L.TileLayer。

叠加图层(overlays):通常包括 GeoJSON 之类的矢量数据,参考 Mapbox.js 中的L.mapbox.featureLayer 和 Leaflet 中的 L.geoJson。和基础图层相比,叠加图层包含的信息更少,但交互性更强:可在 JavaScript 中进行修改,并且点击的时候会触发弹窗。

Mapbox GL JS 中的图层是对矢量数据或者  raster data 的风格化呈现。每个图层都将规定特定数据在浏览器中该如何绘制,渲染器(renderer)会通过这些图层把地图渲染到屏幕上。

如下图所示,随着缩放级别的改变,地图细节也会变化。地形、建筑、公共交通站台和位置信息都作为其相应的图层来渲染。

由于通过Mapbox GL JS,浏览器中的所有地图内容均以矢量数据的形式加载,Mapbox GL JS 对基础图层和叠加图层不作区分。因此标签、图标等地图要素节都可以通过 JavaScript 进行修改,与以前的地图库中的叠加图层类似。当然,这也意味着更改图层样式的函数和方法会更细化一点

片段上的 Mapbox 膨胀视图

【中文标题】片段上的 Mapbox 膨胀视图【英文标题】:Mapbox Inflate View on Fragment 【发布时间】:2016-04-12 12:36:18 【问题描述】:

我在为 Android 片段上的 Mapbox MapView 充气时遇到问题。当我在 Activity 上使用相同的代码时(除了 Activity 和 Fragment 之间的标准差异),我可以让 MapView 正确加载,但不能在 Fragment 上。

Mapbox 也有一个 MapFragment 类here,但我不确定如何在 Fragment 中正确使用它(示例仍在 Activity 中);借助 Google Maps API,我可以毫无问题地在 Fragment 上使用 MapView。

以下 logcat 行:

at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)

指的是Java行:

fragmentLayout = inflater.inflate(R.layout.fragment_map, container, false);

这里是这个问题的相关代码以及日志:

fragment_map.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_ >

    <com.mapbox.mapboxsdk.views.MapView
        android:id="@+id/mapview"
        android:layout_
        android:layout_
        mapbox:access_token="@string/access_token"/>

    <android.support.v7.widget.CardView
        android:id="@+id/map_card"
        android:layout_
        android:layout_
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp">
        <com.mapbox.mapboxsdk.views.MapView
            android:layout_
            android:layout_
            android:id="@+id/mini_map"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            mapbox:access_token="@string/access_token"/>
    </android.support.v7.widget.CardView>

FragmentMap.java:

public class FragmentMap extends Fragment 
    private MapView mv, miniMap;
        View fragmentLayout;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        fragmentLayout = inflater.inflate(R.layout.fragment_map, container, false);

    mv = (MapView) fragmentLayout.findViewById(R.id.mapview);
    mv.onCreate(savedInstanceState);

    miniMap = (MapView) fragmentLayout.findViewById(R.id.mini_map);
    miniMap.onCreate(savedInstanceState);

    return fragmentLayout;



@Override
public void onStart() 
    super.onStart();
    mv.onStart();
    miniMap.onStart();

@Override
public void onStop() 
    super.onStop();
    mv.onStop();
    miniMap.onStop();



@Override
public void onDestroy() 
    super.onDestroy();
    mv.onDestroy();
    miniMap.onDestroy();


@Override
public void onResume() 
    super.onResume();
    mv.onResume();
    miniMap.onResume();


@Override
public void onPause() 
    super.onPause();
    mv.onPause();
    miniMap.onPause();

@Override
public void onLowMemory() 
    super.onLowMemory();
    mv.onLowMemory();
    miniMap.onLowMemory();


@Override
public void onSaveInstanceState(Bundle outState) 
    super.onSaveInstanceState(outState);
    mv.onSaveInstanceState(outState);
    miniMap.onSaveInstanceState(outState);

日志猫:

01-07 08:07:00.548 710-710/com.example.exampleapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.exampleapp, PID: 710
android.view.InflateException: Binary XML file line #13: Error inflating class com.mapbox.mapboxsdk.views.MapView
at android.view.LayoutInflater.createView(LayoutInflater.java:633)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:552)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:1778)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:871)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:841)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1115)
at android.support.design.widget.TabLayout$1.onClick(TabLayout.java:665)
at android.view.View.performClick(View.java:4785)
at android.view.View$PerformClick.run(View.java:19884)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:552)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:1778)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:871)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:841)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1115)
at android.support.design.widget.TabLayout$1.onClick(TabLayout.java:665)
at android.view.View.performClick(View.java:4785)
at android.view.View$PerformClick.run(View.java:19884)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
Caused by: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.exampleapp-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libmapbox-gl.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at com.mapbox.mapboxsdk.views.NativeMapView.<clinit>(NativeMapView.java:42)
at com.mapbox.mapboxsdk.views.MapView.initialize(MapView.java:680)
at com.mapbox.mapboxsdk.views.MapView.<init>(MapView.java:621)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:552)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:1778)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:871)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:841)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1115)
at android.support.design.widget.TabLayout$1.onClick(TabLayout.java:665)
at android.view.View.performClick(View.java:4785)
at android.view.View$PerformClick.run(View.java:19884)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

应用分级:

buildscript 
    repositories 
        mavenCentral()
    
    dependencies 
        classpath 'com.android.tools.build:gradle:1.3.0'
    


apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

repositories 
    mavenCentral()
    jcenter()


android 
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig 
        applicationId "com.example.exampleapp"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    
    useLibrary 'org.apache.http.legacy'

    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        
    


dependencies 
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:cardview-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile 'com.google.android.exoplayer:exoplayer:r1.5.2'
    compile 'com.google.android.gms:play-services-auth:8.3.0'
    compile 'com.google.android.gms:play-services-maps:8.3.0'
    compile('com.mapbox.mapboxsdk:mapbox-android-sdk:2.3.0@aar') 
        transitive = true
    
    compile files('libs/commons-lang3-3.3.2.jar')

项目结构:

【问题讨论】:

你能附上你的项目文件夹结构的截图吗?问题可能在于错误放置libmapbox-gl.so 刚刚添加的app gradle 是的,你可能是对的,但我之前使用过 Mapbox 没有问题,根本不需要处理这个问题。事实上,我可以在 Activity 中获得一个 Mapbox 视图来处理这个应用程序,而无需更改任何其他内容。 我会尽快截取截图 检查您在android/java/lib/src/main/jniLibs/armeabi-v7a/android/java/lib/src/main/libs/armeabi-v7a/android/java/lib/src/main/jni/armeabi-v7a/ 中是否有libmapbox-gl.so - 这些位置之一应该可以工作(不确定哪一个) 【参考方案1】:

您正在谈论通货膨胀,但请查看堆栈跟踪:

引起:java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip 文件 "/data/app/com.example.exampleapp-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] 找不到“libmapbox-gl.so” java.lang.Runtime.loadLibrary(Runtime.java:366) 在 java.lang.System.loadLibrary(System.java:988) 在 com.mapbox.mapboxsdk.views.NativeMapView.(NativeMapView.java:42) 在 com.mapbox.mapboxsdk.views.MapView.initialize(MapView.java:680) 在 com.mapbox.mapboxsdk.views.MapView.(MapView.java:621)

顺便说一句:

第一

你需要决定是每次都膨胀视图局部变量)还是重用它(全局变量)

示例:

if(_view==null) 
   _view = inflater.inflate(..);
return _view;

秒:

不要手动调用onCreate onPause之类的activity或者fragment方法(os用来维护生命周期的方法)

第三个:

如果你使用 viewpager 和嵌套片段,你需要创建带有子片段管理器的适配器

更多和更多:

请记住,在子片段 viewpager 片段中设置一些数据和属性需要布局

“第一:我每次都在膨胀它,这通常不是问题(我的标签可以与我创建的任何其他片段一起使用,包括谷歌地图,但不是 Mapbox)第二:是的,你确实调用了活动手动生命周期方法。您必须使用 onCreate 来膨胀视图。第三:我有一个适配器,我只是没有在此处包含它。这不是问题,我的选项卡可以与我创建的任何其他片段一起正常工作。最后:我'不知道你在说什么,但我的片段在我的其他标签中工作正常。

请关注手头的问题...将 Mapbox 视图放在片段中,> 无论该片段在哪里(标签页查看器与否).. – TangoJLabs"

/**
 * Called to do initial creation of a fragment.  This is called after
 * @link #onAttach(Activity) and before
 * @link #onCreateView(LayoutInflater, ViewGroup, Bundle).
 *
 * <p>Note that this can be called while the fragment's activity is
 * still in the process of being created.  As such, you can not rely
 * on things like the activity's content view hierarchy being initialized
 * at this point.  If you want to do work once the activity itself is
 * created, see @link #onActivityCreated(Bundle).
 *
 * @param savedInstanceState If the fragment is being re-created from
 * a previous saved state, this is the state.
 */
public void onCreate(@Nullable Bundle savedInstanceState) 
    mCalled = true;

将它从片段的 onCreate 移动到 onViewCreated(View,Bundle)

mv = (MapView) fragmentLayout.findViewById(R.id.mapview);
mv.onCreate(savedInstanceState);

miniMap = (MapView) fragmentLayout.findViewById(R.id.mini_map);
miniMap.onCreate(savedInstanceState);


/**
 * Called immediately after @link #onCreateView(LayoutInflater, ViewGroup, Bundle)
 * has returned, but before any saved state has been restored in to the view.
 * This gives subclasses a chance to initialize themselves once
 * they know their view hierarchy has been completely created.  The fragment's
 * view hierarchy is not however attached to its parent at this point.
 * @param view The View returned by @link #onCreateView(LayoutInflater, ViewGroup, Bundle).
 * @param savedInstanceState If non-null, this fragment is being re-constructed
 * from a previous saved state as given here.
 */
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) 

最后一句话:gradle 文件

我不知道您的文件内容是否同时包含 gradle 文件或仅包含应用程序文件,但这些行不应该在应用程序 gradle 文件中 - 这些是*** gradle:

buildscript 
    repositories 
        mavenCentral()
    
    dependencies 
        classpath 'com.android.tools.build:gradle:1.3.0'
    


repositories 
    mavenCentral()
    jcenter()

你应该考虑迁移到最新的 android 应用插件 - 但我看到你正在使用 gms 服务 - 所以你的*** gradle 文件包含其他插件,上面的那些被省略了

我无法按照您的编辑逻辑进行操作。我没有可以从中移动任何东西的 onCreate

/** inflate fragment  - this will create view */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    return inflater.inflate(R.layout.fragment_map, container, false);


/** after view is created - set map view */
@Override
public void onViewCreated(View view, Bundle savedInstanceState) 
    super.onViewCreated(view, savedInstanceState);

    if(view!=null) 
       MapView mv = (MapView) view.findViewById(R.id.mapview);
       mv.onCreate(savedInstanceState);
    

顺便说一句,我对其余的生命周期方法有更多的担忧——片段可以或不保留状态,所以简单地将活动生命周期方法放在片段方法中可能会产生更多问题:)

我不使用 & 不知道 MapView 的源实现,所以我不能告诉你如何实现这个,但我可以给你一个提示,在你调用任何 mapview 方法之前检查片段是否附加到活动

@ceph3us -1 这里提到的一切都是错误的,你的语法 可以改进。我没有答案,我在这里 同样的问题。第一个根视图不应该是一个字段,它应该是 每次调用 onCreateView 时都会膨胀,第二个是正确的调用,第三个 其余的都是题外话,对主题没有帮助。 ——海登凯

@海登凯

    首先请指定来源供您审议 为什么要重新创建视图?目的 ?浪费资源(比如你编写代码和用户 CPU 和 MEM 的时间)? - 在那里你可以负担得起或需要一个新的然后没关系,但在其他情况下 REUSE !!! 视图根本不需要膨胀,它可以正常创建,例如通过返回 new LinearLayout(Context) 或 FrameLayout 或任何其他复杂视图 - 这是使用 xml 或 java 的开发人员选择 - 我不喜欢使用 xml - 我喜欢纯 JAVA :) 所以最后我可以说你的 -1 对我来说是空的

【讨论】:

第一:我每次都在充气,这通常不是问题(我的标签可以与我创建的任何其他片段一起使用,包括谷歌地图,但不是 Mapbox)第二:是的,你确实打电话活动生命周期方法手动。您必须使用 onCreate 来膨胀视图。第三:我有一个适配器,我只是没有在这里包含它。这不是问题,我的选项卡可以与我创建的任何其他片段一起正常工作。最后:我不确定你在说什么,但我的片段在我的其他标签中工作正常。 请关注手头的问题...将 Mapbox 视图放入片段中,无论该片段在哪里(标签页查看器与否)... 我无法按照您的编辑逻辑进行操作。我没有可以从中移动任何东西的 onCreate。 @HaydenKai 对你很友好 - 顺便说一句,你值得特别编辑 :)【参考方案2】:

这个库看起来处于繁重的开发状态,可能存在一些问题,这些问题在 GitHub 上有所提及,尤其是在您运行 2.2.0 版本时。

尝试将版本更改为最新的稳定版:

compile 'com.mapbox.mapboxsdk:mapbox-android-sdk:3.0.0'

【讨论】:

很遗憾,Mapbox 3.0.0 没有解决这个特定的错误,但 Damian 是对的,Mapbox Android SDK 显然正在大力开发。希望 Mapbox 能在不久的将来提供在 Fragment 中使用的文档。 我遇到了同样的问题。您是说 Mapbox MapView 不能用于片段吗?那将是一个真正的耻辱。 @jmc34 在有问题的 cmets 中存在聊天链接。你可以阅读我与 Tango 的讨论。 我已经设法在 Fragment 中使用 Mapbox 3.2 视图,但是一旦引入 ViewPager,我就会收到类似的膨胀错误,但没有“找不到”/unsatsfiedLinkError。可以在这里查看我的问题:***.com/questions/35557857/…

以上是关于mapbox的基本原理和核心差异的主要内容,如果未能解决你的问题,请参考以下文章

云计算的基本原理是什么?核心技术有哪些?

Quartz基本原理

[转帖]「白帽黑客成长记」Windows提权基本原理(上)

固态硬盘SSD基本原理

线程池基本使用和ThreadPoolExecutor核心原理讲解

TiDB基本原理学习