Migrate to v10 | Maps SDK | Android | Mapbox

文章推薦指數: 80 %
投票人數:10人

Upgrade your application from the Mapbox Maps SDK for Android v9 to v10. ... Read more about OfflineManager in the Offline guide. Youareusinganoutdatedbrowserandwillencountersomeproblemswithourwebsite.Pleaseconsiderupgrading.UpgradeNowMapsSDKforAndroidSearchGuidesExamplesAPIReferenceTutorialsTroubleshootingAlldocsMapsSDKforAndroidGuidesMigratetov10Migratetov10OnthispageRequirementsUpgradingtouseOkHttp/Okio4.+PackagenamechangesSimplifiedlifecyclemanagementLifecyclePluginModulararchitectureExample:ReplacemodularHTTPstackDefaultResourceOptionsconfiguration(includingaccesstoken)MapstylesSynchronizedgetMapboxMap()StyleloadingfunctionsStyleDSLStylesparitywithpre-v10MapsSDKRetrievestylepropertiesfromthemapAnnotationsMapeventsTraditionallistener-basedeventAPIObservableeventAPIMapeventslifecycleNewfeaturesandimprovementsPlatform-drivenanimationsystemLocationcomponentpluginwithpuckandcameradecoupledScalebarplugin3DmodelcapabilitiesAsynchronousqueryrenderedfeaturesNewOfflineManagerLocalizationextensionRendercacheDeprecationsandremovalsPropertyFactoryStringDefannotationsPointandLatLngRenamingtilttopitchCameraUpdateFactoryCameraPositiongetVisibleRegionLegacyOfflineManagerLocationPluginShareyourfeedbackTheMapboxMapsSDKv10introducesimprovementstohowMapboxworksontheAndroidplatform,aswellaschangestohowdevelopersusetheSDK.ThisdocumentsummarizesthemostimportantchangesandwalksyouthroughhowtoupgradeanapplicationusingapreviousversionoftheMapboxMapsSDKtov10.RequirementsMinimumAndroidSDKversionisnow21(formerly16).Kotlinversion1.4.x.Java8languagefeaturessupportshouldbedeclaredinapp-levelbuild.gradlefile.android{ ... compileOptions{ sourceCompatibilityJavaVersion.VERSION_1_8 targetCompatibilityJavaVersion.VERSION_1_8 } kotlinOptions{ jvmTarget="1.8" } } UpgradingtouseOkHttp/Okio4.+TheMapboxMapsSDKv10isusingOkHttpv4.9.0bydefaultunderthehood.ItisimportanttousecompatibleversionsofallrelatedSquarelibrarieslikeRetrofit,Okioetcotherwiseruntimecrashesmayhappen.Moreovermakesuretovalidatedependenciesbyrunning./gradlew:app:dependenciesbecausesomeotherprojectlibrariesmaysilentlybringindependenciesthatyouarenotawareof,e.g.usingcom.squareup.okhttp3:logging-interceptor:3.12.7aspartofsomeother3d-partylibrarycanbreakrequestsdonewithcom.squareup.retrofit2:retrofit:2.9.0andcom.squareup.okhttp3:okhttp:4.9.0andresultinunexpectederrors.PackagenamechangesPackagepre-v10v10MavengroupIDformapcom.mapbox.mapboxsdkcom.mapbox.mapsMavenartifactIDformapmapbox-android-sdkandroidMavengroupIDforpluginscom.mapbox.mapboxsdkcom.mapbox.pluginMavengroupIDforpluginscom.mapbox.mapboxsdkcom.mapbox.extensionMavenartifactIDforpluginsmapbox-android-plugin-PLUGINNAMEmaps-PLUGINNAMEPackagenameformapscom.mapbox.mapboxsdk.mapscom.mapbox.mapsMapViewclassinthelayoutcom.mapbox.mapboxsdk.maps.MapViewcom.mapbox.maps.MapViewForcommonexamples,refertotheExampleApp.SimplifiedlifecyclemanagementWiththeMapsSDKv10,managingactivitylifecyclemethodshasbeenreducedbyafactoroffour.ItisnolongerrequiredtohookintoActivity#onCreate,Activity#onPause,Activity#onResumeandActivity#onSaveInstanceState.Belowisanexampleimplementationoflifecyclemanagement:classSimpleMapActivity:AppCompatActivity(){ overridefunonCreate(savedInstanceState:Bundle?){ super.onCreate(savedInstanceState) setContentView(R.layout.activity_simple_map) //WillloadStyle.MAPBOX_STREETSbydefaultifnostyleisprovided.Userscanloadotherstylesifneed. //mapView.getMapboxMap().loadStyleUri(Style.SATELLITE) } overridefunonStart(){ super.onStart() mapView.onStart() } overridefunonStop(){ super.onStop() mapView.onStop() } overridefunonLowMemory(){ super.onLowMemory() mapView.onLowMemory() } overridefunonDestroy(){ super.onDestroy() mapView.onDestroy() } } LifecyclePluginBeginningwithv10.0.0-rc.5,thelifecyclepluginisincludedasastandardpartoftheMapsSDK.Thepluginsimplifieshandlingyouractivityorfragment'slifecycleevents(onStart/onStop/onDestroy/onLowMemory).Bydefault,thelifecyclepluginwillautomaticallyhookintothelifecycleeventsofthehostActivityorFragment,sothatdevelopersdon'tneedtomanuallyinvokethecorrespondinglifecyclemethodsoftheMapView.Note:Tobeabletofunctionproperly,thelifecyclepluginrequirestheapplicationtouseappcompatv1.3.0+andabove.Otherwise,thelifecycleevents(onStart/onStop/onDestroy/onLowMemory)mustbemanuallyhandled.ModulararchitectureTheMapsSDKv10hasamodulararchitecturetosetthefoundationforaplugin-basedarchitecturethatcanbeminimizedorextended.Becauseofthisarchitecturalchange,theSDKemploysextensionfunctionswidelyusedtoaugmentthemap’scontrolclass,MapboxMap.Theseextensionfunctionsmustbeimported.TheywilltypicallyappearintheAndroidStudioautocompletesuggestions,butwithlowerprioritiesthanthenativefunctionsinsidetheclass.ImporttheMapsSDK,includingallpackagedpluginsas:implementation"com.mapbox.maps:android:10.5.0" Example:ReplacemodularHTTPstackTheSDKallowsforswappingcertaincomponentsforacustomizedimplementation.Forexample,theHTTPstackcanbeswappedoutby:RemovingthedefaultHTTPstackbundledwiththeSDKandincludeMapboxAnnotationprocessordependency:plugins{ ... kotlin("kapt") } dependencies{ ... implementation('com.mapbox.maps:android:10.5.0'){ excludegroup:'com.mapbox.common',module:'okhttp' } implementation('androidx.annotation:annotation:${version.androidX}') compileOnly('com.mapbox.base:annotations:${version.mapboxBaseAndroid}') kapt('com.mapbox.base:annotations-processor:${versions.mapboxBaseAndroid}') } ProvideacustomHTTPClientclassandletitimplementcom.mapbox.common.HttpServiceInterfaceandannotatetheclasswith@MapboxModule(type=MapboxModuleType.CommonHttpClient):@MapboxModule(type=MapboxModuleType.CommonHttpClient) classCustomizedHttpService:HttpServiceInterface(){ ... overridefunsetMaxRequestsPerHost(max:Byte){ TODO("Notyetimplemented") } overridefunrequest(request:HttpRequest,callback:HttpResponseCallback):Long{ TODO("Notyetimplemented") } overridefuncancelRequest(id:Long,callback:ResultCallback){ TODO("Notyetimplemented") } overridefunsupportsKeepCompression():Boolean{ TODO("Notyetimplemented") } overridefundownload(options:DownloadOptions,callback:DownloadStatusCallback):Long{ TODO("Notyetimplemented") } } Implementtheabstractfunctions.DefaultResourceOptionsconfiguration(includingaccesstoken)Thepre-v10requiredconfigurationoftheaccesstokenthroughtheMapbox.getInstanceAPI.Withv10,thesingletonMapboxobjecthasbeenremovedandResourceOptionsManagerisintroducedtomanagetheapplication-scopedResourceOptions,includingthedefaultMapboxaccesstoken.Thepriorityofaccesstokensis:TokenthatissetinaMapViewXMLattribute(mapbox_resourcesAccessToken)TokenthatisprogrammaticallysettoResourceOptionsManager.getDefault(context:Context,defaultToken:String?=null)Tokenthatwithpredefinedstringidentifierresourcenamedmapbox_access_tokenAunifiedconfigurationcanbeimplementedbyupdatingthedefaultsettingsusingResourceOptionsManager.getDefault(context:Context,defaultToken:String?=null).update{}API://Settheapplication-scopedResourceOptionsManagerwithcustomisedtokenandtilestoreusagemode //sothatallMapViewscreatedwithdefaultconfigwillapplythesesettings. ResourceOptionsManager.getDefault(this,getString(R.string.mapbox_access_token)).update{ tileStoreUsageMode(TileStoreUsageMode.READ_ONLY) } AcustomconfigurationforcreatingaMapViewprogrammaticallycanbeimplementedlikethis://setmapoptions valmapOptions=MapOptions.Builder().applyDefaultParams(this) .constrainMode(ConstrainMode.HEIGHT_ONLY) .glyphsRasterizationOptions( GlyphsRasterizationOptions.Builder() .rasterizationMode(GlyphsRasterizationMode.IDEOGRAPHS_RASTERIZED_LOCALLY) //FontfamilyisrequiredwhentheGlyphsRasterizationModeissettoIDEOGRAPHS_RASTERIZED_LOCALLYorALL_GLYPHS_RASTERIZED_LOCALLY .fontFamily("sans-serif") .build() ) .build() //pluginsthatwillbeloadedaspartofMapViewinitialisation valplugins=listOf( PLUGIN_LOGO_CLASS_NAME, PLUGIN_ATTRIBUTION_CLASS_NAME ) //settokenandtilestoreusagemodeforthisparticularmapview,thesesettingswilloverwritethedefaultvalue. valresourceOptions=ResourceOptions.Builder().applyDefaultParams(this) .accessToken(getString(R.string.mapbox_access_token)) .tileStoreUsageMode(TileStoreUsageMode.DISABLED) .build() //setinitialcameraposition valinitialCameraOptions=CameraOptions.Builder() .center(Point.fromLngLat(-122.4194,37.7749)) .zoom(9.0) .bearing(120.0) .build() valmapInitOptions= MapInitOptions(this,resourceOptions,mapOptions,plugins,initialCameraOptions,true) //createviewprogrammatically customMapView=MapView(this,mapboxMapOptions) MapstylesSynchronizedgetMapboxMap()IntheMapsSDKv10,youcansafelyaccessMapboxMapfromtheMapViewinasynchronizedmanner.YouarenolongerrequiredtowaitforthemaptobecomereadybeforecallingfunctionsontheMapboxMap:pre-v10:mapView.getMapAsync{mapboxMap-> mapboxMap.setStyle(Style.MAPBOX_STREETS){style-> //Mapissetupandthestylehasloaded.Nowyoucanadddataormakeothermapadjustments. } } v10:mapView.getMapboxMap().loadStyleUri(Style.MAPBOX_STREETS){style-> //Mapissetupandthestylehasloaded.Nowyoucanadddataormakeothermapadjustments. } StyleloadingfunctionsThesetStyleAPIhasbeensplitintomultiplefunctionswithmoredescriptivenames:FunctionDescriptionloadStyleUri(styleUri:String)LoadanewmapstyleasynchronousfromthespecifiedURI.loadStyleJson(styleJson:String)LoadstylefromaJSONstring.loadStyle(style:StyleExtension)LoadthestylefromthestyleextensionprovidedDSL.StyleDSLTheStyledomain-specificlanguage(DSL)isacollectionoffunctionsthatallowscompositionofastyleinablockthatisappliedtoareceiverclass.IntheMapsSDKv10,thestyleAPImorecloselymatchestheMapboxStyleSpecification.Inv10,DSLfunctionsforlayers,sources,light,andexpressionsareprovidedtoconstructtheinstances.TheDSLfunctionnamesmatchtheclassnamebeingcreated,butthefirstcharacterinthenameislowercase.Incaseswheretherearemandatoryconstructorparametersoftheclass,assignthemandatoryconstructorparametersbeforethecodeblock.InsidetheDSLblock,usecodecompletioninAndroidStudiotofindallavailablereceiverfunctions.WiththeStyleDSL,authoringorupdatingmapstylesismorelikewritingstyleJSONdirectly.ThehigherlevelstyleAPIisexposedasDSL,allowingconstructionofaStyleExtensionobjectusingthesameparadigmandusingtheoverloadedoperator+insidetheStyleDSLclosuretoaddlayers,sources,orlighttotheStyleExtension.BelowisanexampleusingtheStyleDSLtoaddaGeoJsonSourceandacirclelayer:mapView.getMapboxMap().loadStyle( style(styleUri=Style.TRAFFIC_DAY){ +geoJsonSource(id="earthquakes"){ url(GEOJSON_URL) cluster(false) } +circleLayer(layerId="earthquakeCircle",sourceId="earthquakes"){ circleRadius(get{literal("mag")}) circleColor(Color.RED) circleOpacity(0.3) circleStrokeColor(Color.WHITE) } }, object:Style.OnStyleLoaded{ overridefunonStyleLoaded(style:Style){ //Mapissetupandthestylehasloaded.Nowyoucanadddataormakeothermapadjustments. } }, object:OnMapLoadErrorListener{ overridefunonMapLoadError(mapViewLoadError:MapLoadError,msg:String){ //Erroroccurredwhenloadingthemap,trytohandleitgracefullyhere } } ) Stylesparitywithpre-v10MapsSDKTheAPIsforlayer,source,andlightareflattened,meaningyoucanfindalltheoperationsandpropertiesdirectlyundertheLayer,SourceandLightclassesthemselves.TherearenomorenestedoptionslikeLayer.setProperties()andGeoJsonOptions.ThismakestheAPIssafebecauseyoucannotassignapropertythatisn’tsupportedbythelayerwiththenewstyleAPI.Belowisacomparisonofv10andpre-v10styleAPIsinspecificusecases.PropertyFactorydeprecationInsteadofPropertyFactory,compatiblepropertiesareexposeddirectlyinsidethelayerasfunctionswithstronglytypedvalueparameters.pre-v10:SymbolLayerstretchLayer=newSymbolLayer(STRETCH_LAYER,STRETCH_SOURCE) .withProperties( textField(get("name")), iconImage(get("image-name")), iconAllowOverlap(true), textAllowOverlap(true), iconTextFit(ICON_TEXT_FIT_BOTH)); v10:valstretchLayer=symbolLayer(STRETCH_LAYER,STRETCH_SOURCE){ textField(get{literal("name")}) iconImage(get{literal("image-name")}) iconAllowOverlap(true) textAllowOverlap(true) iconTextFit(IconTextFit.BOTH) } StringDefdeprecationTheStringDefstaticpropertyvalueshavebeenreplacedbyenumclass.UseDoubleinsteadofFloatTheFloattypepropertiesinthestyleAPIsarereplacedwiththemoreprecisetype,Double.UseexpressionsTobetterutilizetheStyleDSLandtobeabletousethenestedexpressionDSL,allconstantvaluesinsidetheexpressionsaretreatedasliteralexpressionsandhavetobewrappedinsidetheliteralexpression.ExpressionscanbeconstructedusingDSLaswell:pre-v10:heatmapWeight( interpolate( linear(),get("mag"), stop(0,0), stop(6,1) ) ) v10:heatmapWeight( interpolate{ linear() get{literal("mag")} stop{ literal(0) literal(0) } stop{ literal(6) literal(1) } } ) UpdateasinglestylepropertyAfteralayer,source,andlightisaddedtothestyle,anychangetothelayer’spropertywillbepassedthroughstyleandbeshownontheMap.pre-v10:circleLayer.setProperties( circleColor(Color.RED) ); v10:circleLayer.circleColor(Color.RED) RetrievestylepropertiesfromthemapAfterthelayer,source,andlightisaddedtothestyle,getthecurrentstylepropertiesusingthegetterfunctiondirectlyexposedtotheLayer,Source,andLightclasses.Inmostcases,therewillbetwogetterfunctionsoftheproperty:get{PropertyName}:{PropertyType}?andget{PropertyName}AsExpression:Expression?.Thefirstwillreturnthepropertyinitsowntype,andthesecondwillreturnapropertyasanExpression(constantvalueswillbewrappedintoaliteralexpression).FloattypesarereplacedwithDoubleinthev10styleAPIs.pre-v10:valradiusPropertyValue:PropertyValue=circleLayer.getCircleRadius() valradius:Float=radius.getValue() v10:valradius:Double=circleLayer.circleRadius!! ChangestosourcesSourcessharethesameAPIstructure:allsourcepropertiesmutatorsareavailableontheSourceclass.Afterasourceisaddedtothestyle,changestothesourcepropertiesarepassedtothestyleandreflectedonthemapdirectly.Settingthesourcepropertiescanbedonethroughmethodssuchasurl(),geometry(),feature(),orfeatureCollection()anddataisparsedontheworkerthreadnotblockingUI.valgeoJsonSource=geoJsonSource(id="earthquakes"){ featureCollection(FEATURE_COLLECTION) cluster(false) clusterRadius(50L) } AnnotationsWiththeMapsSDKv10,thelegacyannotationshavebeenreplacedwiththepluginannotationofv9.x.x.MostofthepluginAPIsinv10arethesameasthoseinpre-v10,themaindifferenceisthewayofgettingAnnotationManagers.InsteadofcreatinganAnnotationManagerdirectlylikeyoudidinpre-v10,inv10anAnnotationplugininstancemustbecreatedfirst.pre-v10:valcircleManager=newCircleManager(mapView,mapboxMap,style); v10:valannotationPlugin=mapView.annotations valcircleManager=annotationPlugin.createCircleAnnotationManager(mapView) Inpre-v10,AnnotationManagerneededtoberecycledintheonDestroymethodofthehostactivity.Inv10,thereisnoneedtodoitmanuallybecauseAnnotationManagerwillbecleanedautomaticallyalongwiththehost,AnnotationPlugin.Inv10,alltheLatLngrelatedmethodsandparametersarereplacedwithPoint.RememberthatthelatitudeandlongitudeparametersarereversedbetweenLatLngandPoint.pre-v10:CircleOptionscircleOptions=newCircleOptions() .withLatLng(newLatLng(6.687337,0.381457)) v10:valcircleOptions:CircleOptions=CircleOptions() .withPoint(Point.fromLngLat(0.381457,6.687337)) Viewannotationsavailableinv10.2.0andhigherInv9,viewannotationswereincludedintheMapboxAnnotationPlugin.Inpre-v9versions,thisfunctionalitywasincludedintheMapboxMarkerViewPlugin.TheMapsSDKv10andhighercomeswithviewannotationfunctionalitybuiltin,andviewannotationsareavailableinv10.2.0andhigher.FormoredetailsseetheViewannotationsguide.MapeventsInv10,therearetwowaystomonitorthemap'sevent:thetraditionallistener-basedeventAPIandtheobservableeventAPI.Traditionallistener-basedeventAPIInv10,twolistener-basedeventAPIsareprovided.UseMapboxMap#addEVENTListener()andMapboxMap#removeEVENTListener()toaddorremovetheeventlistenerrespectively.Findalistofsupportedlistenersthedocumentation.ObservableeventAPIInadditionaltothetraditionallistener-basedeventAPIs,theSDKprovidestwoobservableeventAPIs.UsetheMapboxMap#subscribeAPIandtheMapboxMap#unsubscribeAPItosubscribetoandunsubscribefromoneormultipleeventsfromtheobservablerespectively.TheavailableeventsandtheirdocumentationcanbefoundintheMapEventsclassasfollows:publicfinalclassMapEvents{ /** *Thestylehasbeenfullyloaded,andthe`map`hasrenderedallvisibletiles. * *```text *Eventdataformat(Object). *``` */ publicstaticfinalStringMAP_LOADED="map-loaded"; /** *DescribesanerrorthathasoccuredwhileloadingtheMap.The`type`propertydefineswhatresourcecould *notbeloadedandthe`message`propertywillcontainadescriptiveerrormessage. *Incaseof`source`or`tile`loadingerrors,`source-id`willcontaintheidofthesourcefailing. *Incaseof`tile`loadingerrors,`tile-id`willcontaintheidofthetile * *```text *Eventdataformat(Object): *. *├──type-String("style"|"sprite"|"source"|"tile"|"glyphs") *├──message-String *├──source-id-optionalString *└──tile-id-optionalObject *├──zNumber(zoomlevel) *├──xNumber(xcoorinate) *└──yNumber(ycoorinate) *``` */ publicstaticfinalStringMAP_LOADING_ERROR="map-loading-error"; /** *The`map`hasenteredtheidlestate.The`map`isintheidlestatewhentherearenoongoingtransitions *andthe`map`hasrenderedallrequestednon-volatiletiles.Theeventwillnotbeemittedif`setUserAnimationInProgress` *and/or`setGestureInProgress`issetto`true`. * *```text *Eventdataformat(Object). *``` */ publicstaticfinalStringMAP_IDLE="map-idle"; /** *Therequestedstyledatahasbeenloaded.The`type`propertydefineswhatkindofstyledatahasbeenloaded. *Eventmaybeemittedsynchronously,forexample,when`setStyleJSON`isusedtoloadstyle. * *Basedonaneventdata`type`propertyvalue,followinguse-casesmaybeimplemented: *-`style`:Styleisparsed,stylelayerpropertiescouldbereadandmodified,stylelayersandsourcescouldbe *addedorremovedbeforerenderingisstarted. *-`sprite`:Style'sspritesheetisparsedanditispossibletoaddorupdateimages. *-`sources`:Allsourcesdefinedbythestyleareloadedandtheirpropertiescouldbereadandupdatedifneeded. * *```text *Eventdataformat(Object): *. *└──type-String("style"|"sprite"|"sources") *``` */ publicstaticfinalStringSTYLE_DATA_LOADED="style-data-loaded"; /** *Therequestedstylehasbeenfullyloaded,includingthestyle,specifiedspriteandsources'metadata. * *```text *Eventdataformat(Object). *``` * *Note:Thestylespecifiedspritewouldbemarkedasloadedevenwithspriteloadingerror(Anerrorwillbeemittedvia`MapLoadingError`). *Spriteloadingerrorisnotfatalandwedon'twantittoblockthemaprendering,thusthiseventwillstillbeemittedifstyleandsourcesarefullyloaded. * */ publicstaticfinalStringSTYLE_LOADED="style-loaded"; /** *Astylehasamissingimage.Thiseventisemittedwhenthe`map`rendersvisibletilesand *oneoftherequiredimagesismissinginthespritesheet.Subscriberhastoprovidethemissingimage *bycalling`addStyleImage`method. * *```text *Eventdataformat(Object): *. *└──id-String *``` */ publicstaticfinalStringSTYLE_IMAGE_MISSING="style-image-missing"; /** *Animageaddedtothestyleisnolongerneededandcanberemovedusing`removeStyleImage`method. * *```text *Eventdataformat(Object): *. *└──id-String *``` */ publicstaticfinalStringSTYLE_IMAGE_REMOVE_UNUSED="style-image-remove-unused"; /** *Asourcedatahasbeenloaded. *Eventmaybeemittedsynchronouslyincaseswhensource'smetadataisavailablewhensourceisaddedtothestyle. * *The`id`propertydefinesthesourceid. * *The`type`propertydefinesifsource'smetadata(e.g.,TileJSON)ortilehasbeenloaded.Thepropertyof`metadata` *valuemightbeusefultoidentifywhenparticularsource'smetadataisloaded,thusallsource'spropertiesare *readableandcanbeupdatedbefore`map`willstartrequestingdatatoberendered. * *The`loaded`propertywillbesetto`true`ifallsource'sdatarequiredforvisibleviewportofthe`map`,areloaded. *The`tile-id`propertydefinesthetileidifthe`type`fieldequals`tile`. * *```text *Eventdataformat(Object): *. *├──id-String *├──type-String("metadata"|"tile") *├──loaded-optionalBoolean *└──tile-id-optionalObject *├──zNumber(zoomlevel) *├──xNumber(xcoorinate) *└──yNumber(ycoorinate) *``` */ publicstaticfinalStringSOURCE_DATA_LOADED="source-data-loaded"; /** *Thesourcehasbeenaddedwith`addStyleSource`method. *Theeventisemittedsynchronously,therefore,itispossibletoimmediately *readaddedsource'sproperties. * *```text *Eventdataformat(Object): *. *└──id-String *``` */ publicstaticfinalStringSOURCE_ADDED="source-added"; /** *Thesourcehasbeenremovedwith`removeStyleSource`method. *Theeventisemittedsynchronously,thus,`getStyleSources`willbe *insyncwhenthe`observer`receivesthenotification. * *```text *Eventdataformat(Object): *. *└──id-String *``` */ publicstaticfinalStringSOURCE_REMOVED="source-removed"; /** *The`map`startedrenderingaframe. * *Eventdataformat(Object). */ publicstaticfinalStringRENDER_FRAME_STARTED="render-frame-started"; /** *The`map`finishedrenderingaframe. *The`render-mode`propertytellswhetherthe`map`hasalldata(`full`)requiredtorenderthevisibleviewport. *The`needs-repaint`propertyprovidesinformationaboutongoingtransitionsthattrigger`map`repaint. *The`placement-changed`propertytellsifthesymbolplacementhasbeenchangedinthevisibleviewport. * *```text *Eventdataformat(Object): *. *├──render-mode-String("partial"|"full") *├──needs-repaint-Boolean *└──placement-changed-Boolean *``` */ publicstaticfinalStringRENDER_FRAME_FINISHED="render-frame-finished"; /** *Thecamerahaschanged.Thiseventisemittedwheneverthevisibleviewport *changesduetotheinvocationof`setSize`,`setBounds`methodsorwhenthecamera *ismodifiedbycallingcameramethods.Theeventisemittedsynchronously, *sothatanupdatedcamerastatecanbefetchedimmediately. * *```text *Eventdataformat(Object). *``` */ publicstaticfinalStringCAMERA_CHANGED="camera-changed"; /** *The`ResourceRequest`eventallowsclienttoobserveresourcerequestsmadebya *`map`or`mapsnapshotter`objects. * *```text *Eventdataformat(Object): *. *├──data-source-String("resource-loader"|"network"|"database"|"asset"|"file-system") *├──request-Object *│├──url-String *│├──kind-String("unknown"|"style"|"source"|"tile"|"glyphs"|"sprite-image"|"sprite-json"|"image") *│├──priority-String("regular"|"low") *│└──loading-method-Array["cache"|"network"] *├──response-optionalObject *│├──no-content-Boolean *│├──not-modified-Boolean *│├──must-revalidate-Boolean *│├──source-String("network"|"cache"|"tile-store"|"local-file") *│├──size-Number(sizeinbytes) *│├──modified-optionalString,rfc1123timestamp *│├──expires-optionalString,rfc1123timestamp *│├──etag-optionalString *│└──error-optionalObject *│├──reason-String("success"|"not-found"|"server"|"connection"|"rate-limit"|"other") *│└──message-String *└──cancelled-Boolean *``` */ publicstaticfinalStringRESOURCE_REQUEST="resource-request"; } Theconvenientextensionfunctionsarealsoprovidedtohelpsubscribetoorunsubscribefromasingleeventtype,andparsetheeventdatafromtheobservedeventstostrong-typedKotlinclasses.MapeventslifecycleTheclosestequivalentofpre-v10'sOnStyleLoadedlisteneristheOnStyleDataLoadedlistenerwhenitsassociatedtypeisstyle,butwerecommendedusingthenewOnStyleLoadedlistenerinstead.Thefollowingsimplifieddiagramhelpsexplaintheeventlifecycle:*┌─────────────┐┌─────────┐┌──────────────┐ *│Application││Map││ResourceLoader│ *└──────┬──────┘└────┬────┘└───────┬──────┘ *│││ *├───────setStyleURI────────▶││ *│├───────────getstyle───────────▶│ *│││ *││◀─────────styledata────────────┤ *│││ *│├─parsestyle─┐│ *││││ *│StyleDataLoaded◀─────────────┘│ *│◀────{"type":"style"}─────┤│ *│├─────────getsprite────────────▶│ *│││ *││◀────────spritedata────────────┤ *│││ *│├──────parsesprite───────┐│ *││││ *│StyleDataLoaded◀─────────────────────────┘│ *│◀───{"type":"sprite"}─────┤│ *│├─────getsourceTileJSON(s)────▶│ *│││ *│SourceDataLoaded│◀─────parseTileJSONdata───────┤ *│◀──{"type":"metadata"}────┤│ *│││ *│││ *│StyleDataLoaded││ *│◀───{"type":"sources"}────┤│ *│├──────────gettiles────────────▶│ *│││ *│◀───────StyleLoaded────────┤│ *│││ *│SourceDataLoaded│◀─────────tiledata─────────────┤ *│◀────{"type":"tile"}──────┤│ *│││ *│││ *│◀────RenderFrameStarted────┤│ *│├─────render─────┐│ *││││ *│◀────────────────┘│ *│◀───RenderFrameFinished────┤│ *│├──render,alltilesloaded──┐│ *││││ *│◀────────────────────────────┘│ *│◀────────MapLoaded─────────┤│ *│││ *│││ *│◀─────────MapIdle──────────┤│ *│┌────┴────┐│ *││offline││ *│└────┬────┘│ *│││ *├─────────setCamera────────▶││ *│├───────────gettiles───────────▶│ *│││ *││┌──────────────│ *│◀─────────MapIdle──────────┤waitingforconnectivity││ *│││Maprenderscacheddata│ *││──────────────┘│ NewfeaturesandimprovementsPlatform-drivenanimationsystemAnewcameraanimationsystemleveragestheAndroidanimatorframeworkandprovidestwosetsofcameraAPIs:high-levelanimataionAPIsandlow-levelanimationAPIs.High-levelanimationAPIsHigh-levelAPIsprovideparitywithpre-v10animationsandcatertomosttypicalusecases.Inv10,customizationoptionshavebeenexpanded.TheMapsSDKv10alsoleveragesAndroidSDKlistenersandtimeinterpolators,deliveringresultsthataremoreperformantandimplementationsthataremoreconvenienttouseandenhance.ImportantAPIchanges:flyToreplacesanimateCamera.easeToreplaceseaseCamera.pre-v10:publicfinalvoideaseCamera( @NonNullCameraUpdateupdate, intdurationMs, @NullablefinalMapboxMap.CancelableCallbackcallback ) publicfinalvoidanimateCamera( @NonNullCameraUpdateupdate, finalintdurationMs @NullableMapboxMap.CancelableCallbackcallback ) v10:MapboxMap.flyTo( cameraOptions:CameraOptions, animationOptions:MapAnimationOptions?=null ):Cancelable MapboxMap.easeTo( cameraOptions:CameraOptions, animationOptions:MapAnimationOptions?=null ):Cancelable //additionalcamerafunctions MapboxMap.rotateBy( first:ScreenCoordinate, second:ScreenCoordinate, animationOptions:MapAnimationOptions?=null ):Cancelable MapboxMap.pitchBy( pitch:Double, animationOptions:MapAnimationOptions?=null ):Cancelable MapboxMap.scaleBy( amount:Double, screenCoordinate:ScreenCoordinate?, animationOptions:MapAnimationOptions?=null ):Cancelable MapboxMap.moveBy( screenCoordinate:ScreenCoordinate, animationOptions:MapAnimationOptions?=null ):Cancelable //MapAnimationOptionsclassdefinition classMapAnimationOptions( valowner:String?, valduration:Long?, valinterpolator:TimeInterpolator?, valanimatorListener:Animator.AnimatorListener? ) Low-levelanimationAPIsTheMapsSDKv10alsointroducesanewsetoflower-levelanimationAPIs.EachcamerapropertycanbeanimatedindependentlythroughtheAndroidSDKanimatorframework.Thefollowingexampleconstructsthreeindependentanimations(bearing,zoom,andpitch)andcreatesananimationsetsotheyexecutesimultaneously.Theanimationcanbecustomizedbyutilizingtheflexiblelow-levelAPIs.importcom.mapbox.maps.plugin.animation.CameraAnimatorOptions.Companion.cameraAnimatorOptions importcom.mapbox.maps.plugin.animation.camera valplugin=mapView.camera valbearing=plugin.createBearingAnimator(cameraAnimatorOptions(0.0,160.0)){ duration=8500 interpolator=AnticipateOvershootInterpolator() } valzoom=plugin.createZoomAnimator( cameraAnimatorOptions(18.0){ startValue=15.0 } ){ duration=5000 interpolator=AccelerateDecelerateInterpolator() } valpitch=plugin.createPitchAnimator( cameraAnimatorOptions(55.0){ startValue=0.0 } ){ duration=7000 interpolator=BounceInterpolator() } plugin.registerAnimators(bearing,zoom,pitch) valanimatorSet=AnimatorSet() animatorSet.startDelay=5000 animatorSet.playTogether(bearing,zoom,pitch) animatorSet.addListener(object:AnimatorListenerAdapter(){ overridefunonAnimationEnd(animation:Animator?){ super.onAnimationEnd(animation) plugin.unregisterAnimators(bearing,pitch,zoom) } }) animatorSet.start() LocationcomponentpluginwithpuckandcameradecoupledWithv10,wehaveintroducedtheMapboxLocationComponentPluginformanagingthelocationindicatordecoupledfromcameraupdates.v9trackingmodeshavebeenreplacedbytheMapboxViewportPlugin(availablestartinginv10.3).Besidesfollowingobjectsonamap,itcanbeextendedwithcustomstatesandtransitions.Formoredetails,seetheUserlocationguide.ScalebarpluginYoucanaccesspluginsfrompre-v10directlyintheMapsSDKv10.pre-v10:dependencies{ implementation'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.5.0' } v10:IfyouinstalltheMapsSDKinfull,pluginswillbeincludedandyoudonotneedtospecifypluginsseparatelyinyourbuild.gradlefile.YoucanalsousepluginsindependentofotherMapsSDKfeaturesbyinstallingthepluginonly(asseenbelow).dependencies{ implementation'com.mapbox.plugin:maps-scalebar:10.0.0' } Formoredetails,seetheMapboxMapsScaleBarPlugin'sREADME.3DmodelcapabilitiesThenewlocationcomponentpluginsupportsanewAPItousea3Dmodeltovisualizetheenduser’slocationonthemap.3Dpucksupportswidevarietyofpropertiesforcustomization.mapView.location.enabled=true mapView.location.locationPuck=LocationPuck3D( modelUri="asset://sportcar.glb", modelScale=listOf(0.1f,0.1f,0.1f) ) TheLocationModelLayeroptionscanbeconfiguredby: dataclassLocationPuck3D( /** *AnURLforthemodelfileingltfformat. */ varmodelUri:String, /** *Thescaleofthemodel. */ varposition:List=listOf(0f,0f), /** *Theopacityofthemodel. */ varmodelOpacity:Float=1f, /** *Thescaleofthemodel. */ varmodelScale:List=listOf(1f,1f,1f), /** *Thescaleexpressionofthemodel,whichwilloverwritethedefaultscaleexpressionthatkeepsthemodelsizeconstantduringzoom. */ varmodelScaleExpression:String?=null, /** *Therotationofthemodel. */ varmodelRotation:List=listOf(0f,0f,90f), ):LocationPuck() 3DterrainandskylayersIntheMapsSDKv10,youcanshowdramaticelevationchangesagainstanatmosphericbackdropbyenabling3Dterrainandusingthenewskylayer.3DTerraincanbeappliedtoaDEMdatasource.BelowisacodesnippetofenablingterrainusingStyleDSL.mapboxMap.loadStyle( styleExtension=style(Style.SATELLITE_STREETS){ +rasterDemSource("TERRAIN_SOURCE"){ url("mapbox://mapbox.mapbox-terrain-dem-v1") } +terrain("TERRAIN_SOURCE"){ exaggeration(1.1) } ) Note3Dterrainisstillinanexperimentalstate.Itmightnotworkasexpectedwiththemapcameraanimationsystem.3DglobeIntheMapsSDKv10,youcouldswitchtoglobeprojectiontoshowmapasthe3Dglobe.Switchingprojectionsisavailableinruntime.mapboxMap.setMapProjection(MapProjection.Globe) Note3Dglobeisstillinanexperimentalstate.Notalllayertypesaresupportedforglobeprojection.AsynchronousqueryrenderedfeaturesGettingalistofmapfeaturesisnowperformedasynchronouslyanddoesnotblocktheexecutingthread.pre-v10:publicListqueryRenderedFeatures(@NonNullPointFcoordinates,@NullableString...layerIds) v10:voidqueryRenderedFeatures(@NonNullListshape,@NonNullRenderedQueryOptionsoptions,@NonNullQueryFeaturesCallbackcallback); //wherecallbackisexecutedonbackgroundthread publicinterfaceQueryFeaturesCallback{ voidrun(@NonNullExpected>features); } NewOfflineManagerv10introducesanewOfflineManagerAPIthatmanagesstylepacksandproducestilesetdescriptorsforthetilestore.ReadmoreaboutOfflineManagerintheOfflineguide.Localizationextensionv10providesanabilitytochangestylelanguagebasedonlocalegiven.Itcouldbeachievedwithfollowingcode://Getcurrentdevicelocale vallocale=resources.configuration.locale //Applythislocaletogivenstyle mapView.getMapboxMap().loadStyleUri(nextStyle){ it.localizeLabels(locale) } RendercacheRendercacheisanexperimentalfeatureaimingtoreducemaprenderingresourceusagebycachingintermediaterenderingresultsoftilesintospecificcachetexturesforreusebetweenframes.Theperformancebenefitofthecachedependsonthemapstyleyouareusingbecausenotalllayersarecacheable(forexample,whenusingviewportalignedfeatures).Rendercachealwaysprefersqualityoverperformance.ThemaximumsizeallocatedfortherendercacheinmegabytescanbesetusingtheMapboxMap#setRenderCacheOptions(RenderCacheOptions)API.Therecommendedstartingvaluesforthecachesizesare64and128fordeviceswithpixelratio1.0and>1.0respectively.Settingtherendercachesizeto0willeffectivelydisabletherendercache.AnexampleusingthisAPIispresentedinthefollowingsnippet(pseudocode):valmapboxMap=mapView.getMapboxMap() //Setthelarge(128MB)rendercachesize. mapboxMap.setRenderCacheOptions(RenderCacheOptions.Builder().setSmallSize().build()) //Or,disabletherendercache. mapboxMap.setRenderCacheOptions(RenderCacheOptions.Builder().setDisabled().build()) DeprecationsandremovalsPropertyFactoryPropertyFactoryhasbeendeprecatedinfavorofdirectpropertysetterandgetterAPIsinsidelayers.StringDefannotationsStringDefannotationshavebeenreplacedbyenumclasses.PointandLatLngLatLngBoundsandLatLnghasbeenremovedinfavorofcoordinateboundsandpointgeometry.Renamingtilttopitchtilthasbeenrenamedtopitchthroughoutourcodebase.Forexample,Camera#tiltisreplacedbyCameraOptions#Pitch.CameraUpdateFactoryCameraUpdateFactoryhasbeenremovedinfavorofthenewplatform-drivencameraanimationsystem.CameraPositionCameraPositionhasbeenreplacedwithCameraOptionsifsettingcameratoMapboxMap.WhenobtainingcurrentMapboxMapcamera,immutableCameraStatewithnon-nullpropertieswillbereturned.getVisibleRegionThefunctiongetVisibleRegion()isnotavailable,butwehaveanequivalentimplementationthatcangettheCoordinateBoundsforthevisibleregion.valcameraState=mapView.getMapboxMap().cameraState valbounds=mapView.getMapboxMap().coordinateBoundsForCamera(cameraState.toCameraOptions()) LegacyOfflineManagerThelegacypre-v10OfflineManagerhasbeendeprecatedandrenamedtoOfflineRegionManager.LocationPluginThelegacyLocationPluginhasbeenremoved.Shareyourfeedback



請為這篇文章評分?