├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── debug.jks ├── libs │ ├── AMap3DMap_5.0.0_AMapNavi_5.0.1_AMapSearch_5.0.0_AMapLocation_3.3.0_20170410.jar │ └── armeabi │ │ ├── libGNaviData.so │ │ ├── libGNaviGuide.so │ │ ├── libGNaviMap.so │ │ ├── libGNaviMapex.so │ │ ├── libGNaviPos.so │ │ ├── libGNaviRoute.so │ │ ├── libGNaviSearch.so │ │ ├── libGNaviUtils.so │ │ ├── libRoadLineRebuildAPI.so │ │ ├── librtbt800.so │ │ └── libwtbt800.so ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── marker │ │ └── mo │ │ └── amapsmoothmarker │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── marker │ │ │ └── mo │ │ │ └── amapsmoothmarker │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable │ │ └── car_up.png │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── marker │ └── mo │ └── amapsmoothmarker │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AmapSmoothMarker 2 | To achieve the smooth moving effect of multiple vehicles~ 3 | 4 | Tech solve link:http://blog.csdn.net/zyktojo/article/details/62891606 5 | 6 | 博客详解链接:http://blog.csdn.net/zyktojo/article/details/62891606 7 | 8 | 打开滴滴打车APP,会发现地图上的车辆显示的十分形象,车辆会在路上平滑的加减速,转向停车~ 9 | 10 | 有种即时战略的感觉,看起来挺有趣: 11 | 12 | 为了研究这个效果如何实现,我开始了探索之旅~~ 13 | 14 | 实现效果如图: 15 | 16 | 17 | ![](http://img.blog.csdn.net/20170421102917096?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenlrdG9qbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.marker.mo.amapsmoothmarker" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | sourceSets { 21 | main { 22 | jniLibs.srcDirs = ['libs'] 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | compile fileTree(include: ['*.jar'], dir: 'libs') 29 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 30 | exclude group: 'com.android.support', module: 'support-annotations' 31 | }) 32 | compile 'com.android.support:appcompat-v7:25.3.1' 33 | testCompile 'junit:junit:4.12' 34 | compile files('libs/AMap3DMap_5.0.0_AMapNavi_5.0.1_AMapSearch_5.0.0_AMapLocation_3.3.0_20170410.jar') 35 | } 36 | -------------------------------------------------------------------------------- /app/debug.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/debug.jks -------------------------------------------------------------------------------- /app/libs/AMap3DMap_5.0.0_AMapNavi_5.0.1_AMapSearch_5.0.0_AMapLocation_3.3.0_20170410.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/AMap3DMap_5.0.0_AMapNavi_5.0.1_AMapSearch_5.0.0_AMapLocation_3.3.0_20170410.jar -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviData.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviData.so -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviGuide.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviGuide.so -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviMap.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviMap.so -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviMapex.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviMapex.so -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviPos.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviPos.so -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviRoute.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviRoute.so -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviSearch.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviSearch.so -------------------------------------------------------------------------------- /app/libs/armeabi/libGNaviUtils.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libGNaviUtils.so -------------------------------------------------------------------------------- /app/libs/armeabi/libRoadLineRebuildAPI.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libRoadLineRebuildAPI.so -------------------------------------------------------------------------------- /app/libs/armeabi/librtbt800.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/librtbt800.so -------------------------------------------------------------------------------- /app/libs/armeabi/libwtbt800.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/libs/armeabi/libwtbt800.so -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in F:\SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/marker/mo/amapsmoothmarker/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.marker.mo.amapsmoothmarker; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.marker.mo.amapsmoothmarker", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/marker/mo/amapsmoothmarker/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.marker.mo.amapsmoothmarker; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.util.Pair; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | import com.amap.api.maps.AMap; 10 | import com.amap.api.maps.CameraUpdateFactory; 11 | import com.amap.api.maps.MapView; 12 | import com.amap.api.maps.model.BitmapDescriptor; 13 | import com.amap.api.maps.model.BitmapDescriptorFactory; 14 | import com.amap.api.maps.model.LatLng; 15 | import com.amap.api.maps.model.LatLngBounds; 16 | import com.amap.api.maps.model.Marker; 17 | import com.amap.api.maps.model.MarkerOptions; 18 | import com.amap.api.maps.model.animation.AlphaAnimation; 19 | import com.amap.api.maps.model.animation.Animation; 20 | import com.amap.api.maps.utils.SpatialRelationUtil; 21 | import com.amap.api.maps.utils.overlay.SmoothMoveMarker; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import java.util.Random; 26 | 27 | /** 28 | * author: Ivan Zhang 29 | * 高德地图,图标平滑移动功能Demo 30 | */ 31 | public class MainActivity extends AppCompatActivity { 32 | 33 | MapView mMapView = null; 34 | AMap aMap; 35 | 36 | private double[] coords;//路线坐标点数据,不断清空复用 37 | private List carsLatLng;//静态车辆的数据 38 | private List goLatLng; 39 | private List showMarks;//静态车辆图标 40 | private List smoothMarkers;//平滑移动图标集合 41 | //经度 42 | private double lng = 0.0; 43 | //纬度 44 | private double lat = 0.0; 45 | 46 | @Override 47 | protected void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | setContentView(R.layout.activity_main); 50 | //获取地图控件引用 51 | mMapView = (MapView) findViewById(R.id.map); 52 | //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图 53 | mMapView.onCreate(savedInstanceState); 54 | if (aMap == null) { 55 | aMap = mMapView.getMap(); 56 | } 57 | initView(); 58 | initData(); 59 | } 60 | 61 | private void initView() { 62 | Button put = (Button) findViewById(R.id.put); 63 | Button run = (Button) findViewById(R.id.run); 64 | 65 | //放入静态车辆 66 | put.setOnClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | //清空地图覆盖物 70 | if (smoothMarkers != null) {//清空动态marker 71 | for (int i = 0; i < smoothMarkers.size(); i++) { 72 | smoothMarkers.get(i).destroy(); 73 | } 74 | } 75 | //清除旧集合 76 | if (showMarks == null) { 77 | showMarks = new ArrayList(); 78 | } 79 | for (int j = 0; j < showMarks.size(); j++) { 80 | showMarks.get(j).remove(); 81 | } 82 | //依次放入静态图标 83 | for (int i = 0; i < carsLatLng.size(); i++) { 84 | BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.car_up); 85 | lng = Double.valueOf(carsLatLng.get(i).longitude); 86 | lat = Double.valueOf(carsLatLng.get(i).latitude); 87 | MarkerOptions markerOptions = new MarkerOptions(); 88 | markerOptions.position(new LatLng(lat, lng)) 89 | .icon(icon); 90 | showMarks.add(aMap.addMarker(markerOptions)); 91 | Animation startAnimation = new AlphaAnimation(0, 1); 92 | startAnimation.setDuration(600); 93 | //设置所有静止车的角度 94 | // showMarks.get(i).setRotateAngle(Float.valueOf(listBaseBean.datas.get(i).angle)); 95 | showMarks.get(i).setAnimation(startAnimation); 96 | showMarks.get(i).setRotateAngle(new Random().nextInt(359)); 97 | showMarks.get(i).startAnimation(); 98 | } 99 | } 100 | }); 101 | 102 | /** 103 | * 展示平滑移动车辆 104 | */ 105 | run.setOnClickListener(new View.OnClickListener() { 106 | @Override 107 | public void onClick(View v) { 108 | if (smoothMarkers != null) {//清空动态marker 109 | for (int i = 0; i < smoothMarkers.size(); i++) { 110 | smoothMarkers.get(i).destroy(); 111 | } 112 | } 113 | //清除旧集合 114 | if (showMarks == null) { 115 | showMarks = new ArrayList(); 116 | } 117 | //清除静态marker 118 | for (int j = 0; j < showMarks.size(); j++) { 119 | showMarks.get(j).remove(); 120 | } 121 | smoothMarkers = null;//清空旧数据 122 | smoothMarkers = new ArrayList(); 123 | BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.car_up); 124 | //循环 125 | for (int i = 0; i < carsLatLng.size(); i++) { 126 | //放入路线 127 | double[] newoords = {Double.valueOf(carsLatLng.get(i).longitude), Double.valueOf(carsLatLng.get(i).latitude), 128 | Double.valueOf(goLatLng.get(i).longitude), Double.valueOf(goLatLng.get(i).latitude)}; 129 | coords = newoords; 130 | //移动车辆 131 | movePoint(icon); 132 | } 133 | } 134 | }); 135 | } 136 | 137 | private void initData() { 138 | //出发地 139 | LatLng car1 = new LatLng(39.902138, 116.391415); 140 | LatLng car2 = new LatLng(39.935184, 116.328587); 141 | LatLng car3 = new LatLng(39.987814, 116.488232); 142 | //出发地坐标集合 143 | carsLatLng = new ArrayList<>(); 144 | carsLatLng.add(car1); 145 | carsLatLng.add(car2); 146 | carsLatLng.add(car3); 147 | 148 | //目的地 149 | LatLng go1 = new LatLng(39.96782, 116.403775); 150 | LatLng go2 = new LatLng(39.891225, 116.322235); 151 | LatLng go3 = new LatLng(39.883322, 116.415619); 152 | //目的地坐标集合 153 | goLatLng = new ArrayList<>(); 154 | goLatLng.add(go1); 155 | goLatLng.add(go2); 156 | goLatLng.add(go3); 157 | } 158 | 159 | @Override 160 | protected void onDestroy() { 161 | super.onDestroy(); 162 | //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图 163 | mMapView.onDestroy(); 164 | } 165 | 166 | @Override 167 | protected void onResume() { 168 | super.onResume(); 169 | //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图 170 | mMapView.onResume(); 171 | } 172 | 173 | @Override 174 | protected void onPause() { 175 | super.onPause(); 176 | //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制 177 | mMapView.onPause(); 178 | } 179 | 180 | @Override 181 | protected void onSaveInstanceState(Bundle outState) { 182 | super.onSaveInstanceState(outState); 183 | //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态 184 | mMapView.onSaveInstanceState(outState); 185 | } 186 | 187 | //平滑移动 188 | public void movePoint(BitmapDescriptor bitmap) { 189 | // 获取轨迹坐标点 190 | List points = readLatLngs(); 191 | // LatLngBounds bounds = new LatLngBounds(points.get(0), points.get(points.size() - 2)); 192 | // aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); 193 | 194 | // SparseArrayCompat sparseArrayCompat = new SparseArrayCompat();//谷歌新集合,替代hashmap 195 | SmoothMoveMarker smoothMarker = new SmoothMoveMarker(aMap); 196 | smoothMarkers.add(smoothMarker); 197 | int num = smoothMarkers.size() - 1; 198 | // 设置滑动的图标 199 | smoothMarkers.get(num).setDescriptor(bitmap); 200 | LatLng drivePoint = points.get(0); 201 | Pair pair = SpatialRelationUtil.calShortestDistancePoint(points, drivePoint); 202 | points.set(pair.first, drivePoint); 203 | List subList = points.subList(pair.first, points.size()); 204 | 205 | // 设置滑动的轨迹左边点 206 | smoothMarkers.get(num).setPoints(subList); 207 | // 设置滑动的总时间 208 | smoothMarkers.get(num).setTotalDuration(10); 209 | // 开始滑动 210 | smoothMarkers.get(num).startSmoothMove(); 211 | } 212 | 213 | //获取路线 214 | private List readLatLngs() { 215 | List points = new ArrayList(); 216 | for (int i = 0; i < coords.length; i += 2) { 217 | points.add(new LatLng(coords[i + 1], coords[i])); 218 | } 219 | return points; 220 | } 221 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/car_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zyktojo/AmapSmoothMarker/6aaa22b0d3d31aa704ccfd2a5c1fb459e06227b6/app/src/main/res/drawable/car_up.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 |