android+高德地图教程,Android高德地图开发(三)地图简单操作

一、概述

上一节中我们了解到地图的定位,图层切换,离线地图等基础操作,接下来学习地图的基本操作。

二、本章内容

--- 地图交互设置

--- 地图绘制

1.地图交互设置

在使用地图的时候,不可避免的会涉及到与地图交互问题,如滑动手势,地图缩放,地图旋转,地图logo位置等。我们可以根据需要来决定是否开启某些交互功能。主要用到的就是高德地图API中的 UiSettings 类。通过AMap实例可以获取到UiSettings的实例 uiSettings = aMap.getUiSettings();

①手势设置

//开启放缩手势

uiSettings.setZoomGesturesEnabled(true);

//开启滑动手势

uiSettings.setScrollGesturesEnabled(true);

//开启旋转手势

uiSettings.setRotateGesturesEnabled(true);

//开启双指倾斜手势

uiSettings.setTiltGesturesEnabled(true);

//开启全部手势

uiSettings.setAllGesturesEnabled(true);

//指定手势中心点

//aMap.setPointToCenter(100,100);

//开启中心为手势中心

uiSettings.setGestureScaleByMapCenter(true);

上面这些功能在一般情况下,默认是开启的。当我们有特殊的需求时可以适当的关闭某些手势。

②地图缩放

//是否允许显示地图缩放按钮

uiSettings.setZoomControlsEnabled(true);

//是否允许收拾手势缩放地图

uiSettings.setZoomGesturesEnabled(true);

//设置双击地图放大在地图中心位置放大,false则是在点击位置放大

uiSettings.setZoomInByScreenCenter(true);

//地图缩放按钮的位置

uiSettings.setZoomPosition(AMapOptions.ZOOM_POSITION_RIGHT_BUTTOM);

//AMapOptions.ZOOM_POSITION_RIGHT_CENTER

//AMapOptions.ZOOM_POSITION_RIGHT_BUTTOM

//获取地图缩放按钮位置

Log.e(TAG, "settingZoom: " + uiSettings.getZoomPosition());

③将屏幕中心移动到指定经纬度

//这个类就是设置地图移动的参数,CameraPosition,参数1---要移动到的经纬度,

//参数2---地图的放缩级别zoom,参数3---地图倾斜度,参数4---地图的旋转角度

CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(

new CameraPosition(new LatLng(30.67, 104.07), 10, 0, 0));

//带动画的移动,aMap添加动画监听时,会有动画效果。不添加不会开启动画

aMap.animateCamera(mCameraUpdate, 5000, new AMap.CancelableCallback() {

@Override

public void onFinish() {

}

@Override

public void onCancel() {

}

});

//不带动画的移动

aMap.moveCamera(mCameraUpdate);

④其他设置

//是否显示指南针

uiSettings.setCompassEnabled(true);

//开启比例尺

uiSettings.setScaleControlsEnabled(true);

// 设置logo位置

uiSettings.setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_CENTER);

//AMapOptions.LOGO_POSITION_BOTTOM_LEFTLOGO(左边)

//AMapOptions.LOGO_MARGIN_BOTTOMLOGO(底部)

//AMapOptions.LOGO_MARGIN_RIGHTLOGO(右边)

//AMapOptions.LOGO_POSITION_BOTTOM_CENTER(地图底部居中)

//AMapOptions.LOGO_POSITION_BOTTOM_LEFT(地图左下角)

//AMapOptions.LOGO_POSITION_BOTTOM_RIGHT (地图右下角)

//显示默认的定位按钮

uiSettings.setMyLocationButtonEnabled(true);

// 可触发定位并显示当前位置

aMap.setMyLocationEnabled(true);

//这里设置定位为了在点击定位按钮后,显示地图定位的位置方便查看

//注意这里有个坑,在点击定位后发现定位到了默认的位置(海里面),造成这种情况并不是权限和代码的问题,

//遇到这种情况时,需要手动将GPS定位打开就OK了

MyLocationStyle mls = new MyLocationStyle();

mls.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);

aMap.setMyLocationEnabled(true);

aMap.setMyLocationStyle(mls);

代码

public class InteractiveMapActivity extends BaseActivity {

@BindView(R.id.a_map_view)

MapView aMapView;

@BindView(R.id.button)

Button button;

@BindView(R.id.button2)

Button button2;

@BindView(R.id.button3)

Button button3;

@BindView(R.id.button4)

Button button4;

private Unbinder binder;

private UiSettings uiSettings;

private AMap aMap;

private static final String TAG = "CF";

@Override

public void setContentView(@Nullable Bundle savedInstanceState) {

setContentView(R.layout.acticity_interactive);

binder = ButterKnife.bind(this);

aMapView.onCreate(savedInstanceState);

}

@Override

public void initData() {

aMap = aMapView.getMap();

uiSettings = aMap.getUiSettings();

//设置地图缩放

settingZoom();

//是否显示指南针

uiSettings.setCompassEnabled(true);

//开启比例尺

uiSettings.setScaleControlsEnabled(true);

// 设置logo位置

uiSettings.setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_CENTER);

//AMapOptions.LOGO_POSITION_BOTTOM_LEFTLOGO(左边)

//AMapOptions.LOGO_MARGIN_BOTTOMLOGO(底部)

//AMapOptions.LOGO_MARGIN_RIGHTLOGO(右边)

//AMapOptions.LOGO_POSITION_BOTTOM_CENTER(地图底部居中)

//AMapOptions.LOGO_POSITION_BOTTOM_LEFT(地图左下角)

//AMapOptions.LOGO_POSITION_BOTTOM_RIGHT (地图右下角)

//显示默认的定位按钮

uiSettings.setMyLocationButtonEnabled(true);

// 可触发定位并显示当前位置

aMap.setMyLocationEnabled(true);

//这里设置定位为了在点击定位按钮后,显示地图定位的位置方便查看

//注意这里有个坑,在点击定位后发现定位到了默认的位置(海里面),造成这种情况并不是权限和代码的问题,

//遇到这种情况时,需要手动将GPS定位打开就OK了

MyLocationStyle mls = new MyLocationStyle();

mls.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);

aMap.setMyLocationEnabled(true);

aMap.setMyLocationStyle(mls);

setGestures();

}

private void setGestures() {

//开启放缩手势

uiSettings.setZoomGesturesEnabled(true);

//开启滑动手势

uiSettings.setScrollGesturesEnabled(true);

//开启旋转手势

uiSettings.setRotateGesturesEnabled(true);

//开启双指倾斜手势

uiSettings.setTiltGesturesEnabled(true);

//开启全部手势

uiSettings.setAllGesturesEnabled(true);

//指定手势中心点

// aMap.setPointToCenter(100,100);

//开启中心为手势中心

uiSettings.setGestureScaleByMapCenter(true);

}

private void settingZoom() {

//是否允许显示地图缩放按钮

uiSettings.setZoomControlsEnabled(true);

//是否允许收拾手势缩放地图

uiSettings.setZoomGesturesEnabled(true);

//设置双击地图放大在地图中心位置放大,false则是在点击位置放大

uiSettings.setZoomInByScreenCenter(true);

//地图缩放按钮的位置

uiSettings.setZoomPosition(AMapOptions.ZOOM_POSITION_RIGHT_BUTTOM);

// AMapOptions.ZOOM_POSITION_RIGHT_CENTER

// AMapOptions.ZOOM_POSITION_RIGHT_BUTTOM

//获取地图缩放按钮位置

Log.e(TAG, "settingZoom: " + uiSettings.getZoomPosition());

}

@Override

protected void onStart() {

super.onStart();

}

@Override

protected void onResume() {

super.onResume();

aMapView.onResume();

}

@Override

protected void onPause() {

super.onPause();

aMapView.onPause();

}

@Override

protected void onStop() {

super.onStop();

}

@Override

protected void onDestroy() {

aMapView.onDestroy();

binder.unbind();

super.onDestroy();

}

@Override

protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

aMapView.onSaveInstanceState(outState);

}

private void moveToTargetPosition() {

//这个类就是设置地图移动的参数,CameraPosition,参数1---要移动到的经纬度,参数2---地图的放缩级别zoom,参数3---地图倾斜度,参数4---地图的旋转角度

CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(

new CameraPosition(new LatLng(30.67, 104.07), 10, 0, 0));

//带动画的移动

aMap.animateCamera(mCameraUpdate, 5000, new AMap.CancelableCallback() {

@Override

public void onFinish() {

}

@Override

public void onCancel() {

}

});

//不带动画的移动

aMap.moveCamera(mCameraUpdate);

}

@OnClick({R.id.button, R.id.button2, R.id.button3, R.id.button4})

public void onViewClicked(View view) {

switch (view.getId()) {

case R.id.button:

moveToTargetPosition();

break;

case R.id.button2:

showCustomMapBounds(true);

break;

case R.id.button3:

showCustomMapBounds(false);

break;

case R.id.button4:

screenCapture();

break;

}

}

private void showCustomMapBounds(boolean enable) {

if (enable) {

LatLng southwestLatLng = new LatLng(30.67, 104.07);

LatLng northeastLatLng = new LatLng(30.77, 104.17);

LatLngBounds latLngBounds = new LatLngBounds(southwestLatLng, northeastLatLng);

aMap.setMapStatusLimits(latLngBounds);

} else {

aMap.setMapStatusLimits(null);

}

}

/** 地图截屏 */

private void screenCapture() {

aMap.getMapScreenShot(new AMap.OnMapScreenShotListener() {

@Override

public void onMapScreenShot(Bitmap bitmap) {

}

@Override

public void onMapScreenShot(Bitmap bitmap, int i) {

if (null == bitmap) {

return;

}

try {

FileOutputStream fos = new FileOutputStream(

Environment.getExternalStorageDirectory() + "/MyMap/"

+ "test" + ".png");

boolean b = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

try {

fos.flush();

} catch (IOException e) {

e.printStackTrace();

}

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

StringBuffer buffer = new StringBuffer();

if (b)

buffer.append("截屏成功 ");

else {

buffer.append("截屏失败 ");

}

if (i != 0)

buffer.append("地图渲染完成,截屏无网格");

else {

buffer.append("地图未渲染完成,截屏有网格");

}

Toast.makeText(InteractiveMapActivity.this, buffer.toString(), Toast.LENGTH_SHORT).show();

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

});

}

}

2.地图绘制

①绘制marker

//添加一个默认的marker

LatLng latLng = new LatLng(30.67, 104.07);

MarkerOptions markerOptions = new MarkerOptions()

//必须,设置经纬度

.position(latLng)

//设置title

.title("成都")

//设置内容

.snippet("marker内容");

aMap.addMarker(markerOptions);

//添加一个自定义的marker

LatLng latLng1 = new LatLng(30.67, 104.07);

MarkerOptions mo = new MarkerOptions();

mo.position(latLng1)

//设置透明度

.alpha(0.6f)

//设置title

.title("自定义标题")

//设置内容

.snippet("自定义内容")

//设置锚点,锚点是marker图标的位置,(0,0)-(1,1)

.anchor(0.5f, 1.0f)

//是否可见

.visible(true)

//是否可拖动,注意这里需要长按marker后,才可以拖动

.draggable(true)

//添加自定义marker图标

.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(

getResources(), R.drawable.location)))

//是否平贴地图,倾斜地图,感觉marker不是竖直而是粘贴在地面上

.setFlat(false)

//是否允许显示infoWindow

.infoWindowEnable(true)

//z轴方向的值,重叠

.zIndex(10)

//设置marker图片旋转角度,正北开始逆时针方向计算

.rotateAngle(30.0f)

//设置infoWindow的偏移位置

.setInfoWindowOffset(0, 0);

aMap.addMarker(mo);

//添加一个动画marker

LatLng latLng2 = new LatLng(30.68, 104.07);

MarkerOptions mo1 = new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(

BitmapFactory.decodeResource(getResources(), R.drawable.location)))

.title("动画").snippet("生长动画").position(latLng2);

Marker m = aMap.addMarker(mo1);

final Animation animation = new ScaleAnimation(0, 1, 0, 1);

animation.setDuration(2000);

animation.setInterpolator(new AccelerateInterpolator());

m.setAnimation(animation);

m.startAnimation();

//添加一个marker的点击事件

aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {

@Override

public boolean onMarkerClick(Marker marker) {

//当点击的时候添加生长动画

marker.setAnimation(animation);

marker.startAnimation();

//这里在添加点击监听事件后,原来的InfoWindow被取消了,可以在回调方法中手动实现

if (marker.isInfoWindowShown()) {

marker.hideInfoWindow();

} else {

marker.showInfoWindow();

}

return true;

}

});

//添加拖拽事件,注意此回调方法只对设置了可拖拽的marker生效

aMap.setOnMarkerDragListener(new AMap.OnMarkerDragListener() {

@Override

public void onMarkerDragStart(Marker marker) {

Log.e(TAG, "onMarkerDragStart: 被拖拽的Marker标题为->" + marker.getTitle());

}

@Override

public void onMarkerDrag(Marker marker) {

}

@Override

public void onMarkerDragEnd(Marker marker) {

Log.e(TAG, "onMarkerDragEnd: 拖拽完后Maker的经纬度-> lat="

+marker.getPosition().latitude + " lng=" + marker.getPosition().longitude);

}

});

//自定义infoWindow

aMap.setInfoWindowAdapter(new AMap.InfoWindowAdapter() {

View view;

@Override

public View getInfoWindow(Marker marker) {

if (view == null) {

view = LayoutInflater.from(DrawActivity.this).inflate(R.layout.custom_info_window, null);

}

findViews(marker, view);

return view;

}

@Override

public View getInfoContents(Marker marker) {

return null;

}

});

aMap.setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {

@Override

public void onInfoWindowClick(Marker marker) {

Log.e(TAG, "onInfoWindowClick: 标题为:" + marker.getTitle() + " 的InfoWindow被点击了");

}

});

/**

* 在点击marker显示infoWindow是,找到相应的控件,修改显示

*/

private void findViews(Marker marker, View view) {

TextView name = view.findViewById(R.id.name);

TextView address = view.findViewById(R.id.address);

name.setText(marker.getTitle());

address.setText(marker.getSnippet());

}

②绘制线

ArrayList points = new ArrayList<>();

points.add(new LatLng(30.66, 104.06));

points.add(new LatLng(30.66, 104.07));

points.add(new LatLng(30.67, 104.07));

points.add(new LatLng(30.67, 104.06));

points.add(new LatLng(30.66, 104.06));

aMap.addPolyline(new PolylineOptions().addAll(points).width(10).color(Color.argb(255, 1, 1, 1)));

ArrayList latlngs = new ArrayList<>();

latlngs.add(new LatLng(30.6595, 104.0595));

latlngs.add(new LatLng(30.6595, 104.0705));

latlngs.add(new LatLng(30.6705, 104.0705));

latlngs.add(new LatLng(30.6705, 104.0595));

latlngs.add(new LatLng(30.6595, 104.0595));

ArrayList a = new ArrayList<>();

a.add(0);

a.add(1);

a.add(2);

a.add(3);

//为每条线段添加纹理

ArrayList b = new ArrayList<>();

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bb)));

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.aa)));

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bb)));

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.aa)));

aMap.addPolyline(new PolylineOptions()

//添加多有的经纬度点

.addAll(latlngs)

//绘制线宽

.width(20)

//是否开启纹理贴图

.setUseTexture(true)

//纹理贴图段的index数组

.setCustomTextureIndex(a)

//纹理贴图每段对应的纹理资源图

.setCustomTextureList(b)

//是否虚线,纹理贴图时无效

.setDottedLine(false)

//绘制成大地线

.geodesic(false)

//设置纹理样式

.setCustomTexture(BitmapDescriptorFactory.fromBitmap(

BitmapFactory.decodeResource(getResources(), R.drawable.aa)))

//设置画线的颜色

.color(Color.argb(255, 1, 1, 1))

);

③绘制面

LatLng latLng = new LatLng(30.665, 104.065);

//绘制一个圆

Circle circle = aMap.addCircle(new CircleOptions()

.center(latLng)

.radius(500)

.fillColor(Color.argb(30, 1, 1, 1))

.strokeColor(Color.argb(255, 1, 1, 1))

.strokeWidth(10)

);

circle.setStrokeDottedLineType(0);

// //绘制一个矩形,多边形跟这个一样的

// aMap.addPolygon(new PolygonOptions()

// .addAll(createRectangle(new LatLng(30.665, 104.065), 0.01, 0.01))

// .fillColor(Color.LTGRAY).strokeColor(Color.RED).strokeWidth(5));

//

// // 绘制一个椭圆

// PolygonOptions options = new PolygonOptions();

// int numPoints = 400;

// float semiHorizontalAxis = 2f;

// float semiVerticalAxis = 0.5f;

// double phase = 2 * Math.PI / numPoints;

// for (int i = 0; i <= numPoints; i++) {

// options.add(new LatLng(

// 30.665 + semiVerticalAxis * Math.sin(i * phase),

// 104.065 + semiHorizontalAxis * Math.cos(i * phase)

// ));

// }

//

// Polygon polygon = aMap.addPolygon(options

// .strokeWidth(25)

// .strokeColor(Color.argb(50, 1, 1, 1))

// .fillColor(Color.argb(50, 1, 1, 1))

// );

/**

* 生成一个长方形的四个坐标点

*/

private List createRectangle(LatLng center, double halfWidth,

double halfHeight) {

List latLngs = new ArrayList();

latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude - halfWidth));

latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude + halfWidth));

latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude + halfWidth));

latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude - halfWidth));

return latLngs;

}

④绘制热力图

LatLng center = new LatLng(30.665, 104.065);

//第一步准备数据

LatLng[] data = new LatLng[100];

for (int i = 0; i < data.length; i++) {

double offsetLat = Math.random();

offsetLat /= 10;

double offsetLng = Math.random();

offsetLng /= 10;

LatLng one = new LatLng(center.latitude + offsetLat, center.longitude + offsetLng);

data[i] = one;

}

int[] colors = {Color.rgb(0, 255, 0), Color.rgb(255, 0, 0)};

float[] startPoints = {0.0f, 1.0f};

Gradient gradient = new Gradient(colors, startPoints);

//初始化热力图

HeatmapTileProvider.Builder builder = new HeatmapTileProvider.Builder();

builder.data(Arrays.asList(data))

// .gradient(gradient)

;

HeatmapTileProvider provider = builder.build();

// 初始化 TileOverlayOptions

TileOverlayOptions tileOverlayOptions = new TileOverlayOptions();

// 设置瓦片图层的提供者

tileOverlayOptions.tileProvider(provider);

// 向地图上添加 TileOverlayOptions 类对象

aMap.addTileOverlay(tileOverlayOptions);

⑤绘制长方体

/**------------------------------------地图上绘制3D图形------------------------------*/

aMap.showMapText(false);

aMap.showBuildings(false);

aMap.setCustomRenderer(new CubeMapRender(aMap));

/**------------------------------------地图上绘制3D图形-----------------------------*/

public class CubeMapRender implements CustomRenderer {

private float[] translate_vector = new float[4];

public static float SCALE = 0.005F;// 缩放暂时使用这个

private LatLng center = new LatLng(30.665, 104.065);// 北京市经纬度

private Cube cube ;

private AMap aMap;

float width, height;

public CubeMapRender(AMap aMap) {

this.aMap = aMap;

aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center,15));

}

float[] mvp = new float[16];

@Override

public void onDrawFrame(GL10 gl) {

if(cube != null) {

Matrix.setIdentityM(mvp, 0);

//偏移

PointF pointF = aMap.getProjection().toOpenGLLocation(center);

Matrix.multiplyMM(mvp,0, aMap.getProjectionMatrix(),0,aMap.getViewMatrix(),0);

Matrix.translateM(mvp, 0 , pointF.x , pointF.y , 0);

int scale = 1;

Matrix.scaleM(mvp, 0 , scale, scale, scale);

cube.drawES20(mvp);

}

}

@Override

public void onSurfaceChanged(GL10 gl, int width, int height) {

this.width = width;

this.height = height;

}

@Override

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

//创建cube

cube = new Cube(0.2f,0.2f,0.2f);

cube.initShader();

}

@Override

public void OnMapReferencechanged() {

}

}

class Cube {

ArrayList verticesList = new ArrayList();

short indices[] = {

0, 4, 5,

0, 5, 1,

1, 5, 6,

1, 6, 2,

2, 6, 7,

2, 7, 3,

3, 7, 4,

3, 4, 0,

4, 7, 6,

4, 6, 5,

3, 0, 1,

3, 1, 2,

};

//

float[] colors = {

1f, 0f, 0f, 1f, // vertex 0 red

0f, 1f, 0f, 1f, // vertex 1 green

0f, 0f, 1f, 1f, // vertex 2 blue

1f, 1f, 0f, 1f, // vertex 3

0f, 1f, 1f, 1f, // vertex 4

1f, 0f, 1f, 1f, // vertex 5

0f, 0f, 0f, 1f, // vertex 6

1f, 1f, 1f, 1f, // vertex 7

};

public Cube(float width, float height, float depth) {

// 地图坐标系比较大,将值放大以免太小看不见

width *= 10000;

height *= 10000;

depth *= 10000;

width /= 2;

height /= 2;

depth /= 2;

//尽量不要让z轴有负数出现

float vertices1[] = {

-width, -height, -0,

width, -height, -0,

width, height, -0,

-width, height, -0,

-width, -height, depth,

width, -height, depth,

width, height, depth,

-width, height, depth,

};

for (int i = 0; i < vertices1.length; i++) {

verticesList.add(vertices1[i]);

}

//index

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(indices.length * 4);

byteBuffer.order(ByteOrder.nativeOrder());

indexBuffer = byteBuffer.asShortBuffer();

indexBuffer.put(indices);

indexBuffer.position(0);

//color

ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(colors.length * 4);

byteBuffer1.order(ByteOrder.nativeOrder());

colorBuffer = byteBuffer1.asFloatBuffer();

colorBuffer.put(colors);

colorBuffer.position(0);

init();

}

private FloatBuffer vertextBuffer;

private ShortBuffer indexBuffer;

private FloatBuffer colorBuffer;

private void init() {

if (vertextBuffer == null) {

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verticesList.size() * 4);

byteBuffer.order(ByteOrder.nativeOrder());

vertextBuffer = byteBuffer.asFloatBuffer();

}

vertextBuffer.clear();

for (Float f : verticesList) {

vertextBuffer.put(f);

}

vertextBuffer.position(0);

}

class MyShader {

String vertexShader = "precision highp float;\n" +

" attribute vec3 aVertex;//顶点数组,三维坐标\n" +

" attribute vec4 aColor;//颜色数组,三维坐标\n" +

" uniform mat4 aMVPMatrix;//mvp矩阵\n" +

" varying vec4 color;//\n" +

" void main(){\n" +

" gl_Position = aMVPMatrix * vec4(aVertex, 1.0);\n" +

" color = aColor;\n" +

" }";

String fragmentShader = "//有颜色 没有纹理\n" +

" precision highp float;\n" +

" varying vec4 color;//\n" +

" void main(){\n" +

" gl_FragColor = color;\n" +

" }";

int aVertex,aMVPMatrix,aColor;

int program;

public void create() {

int vertexLocation = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);

int fragmentLocation = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);

GLES20.glShaderSource(vertexLocation,vertexShader);

GLES20.glCompileShader(vertexLocation);

GLES20.glShaderSource(fragmentLocation,fragmentShader);

GLES20.glCompileShader(fragmentLocation);

program = GLES20.glCreateProgram();

GLES20.glAttachShader(program,vertexLocation);

GLES20.glAttachShader(program,fragmentLocation);

GLES20.glLinkProgram(program);

aVertex = GLES20.glGetAttribLocation(program, "aVertex");

aMVPMatrix = GLES20.glGetUniformLocation(program,"aMVPMatrix");

aColor = GLES20.glGetAttribLocation(program,"aColor");

}

}

MyShader shader;

public void initShader() {

shader = new MyShader();

shader.create();

}

public void drawES20(float[] mvp) {

GLES20.glUseProgram(shader.program);

GLES20.glEnable(GLES20.GL_DEPTH_TEST);

GLES20.glEnableVertexAttribArray(shader.aVertex);

//顶点指针

GLES20.glVertexAttribPointer(shader.aVertex, 3, GLES20.GL_FLOAT, false, 0, vertextBuffer);

//颜色指针

GLES20.glEnableVertexAttribArray(shader.aColor);

GLES20.glVertexAttribPointer(shader.aColor,4, GLES20.GL_FLOAT,false,0,colorBuffer);

GLES20.glUniformMatrix4fv(shader.aMVPMatrix,1,false,mvp,0);

//开始画

GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);

GLES20.glDisableVertexAttribArray(shader.aVertex);

GLES20.glDisable(GLES20.GL_DEPTH_TEST);

}

}

⑥绘制平滑移动的物体

//这里选择一个公交站,获取经过改公交站的一路公交车的路线

//让小车再这个路线上移动

BusStationQuery bsq;

BusStationSearch bss;

bsq = new BusStationQuery("天华一路", "成都");

bss = new BusStationSearch(this, bsq);

bss.setOnBusStationSearchListener(new BusStationSearch.OnBusStationSearchListener() {

@Override

public void onBusStationSearched(BusStationResult busStationResult, int i) {

List data = busStationResult.getBusStations();

if (data != null && data.size() > 0) {

final LatLonPoint busStationPoint = data.get(0).getLatLonPoint();

List dataBus = data.get(0).getBusLineItems();

if (dataBus != null && dataBus.size() > 0) {

BusLineItem bli = dataBus.get(0);

BusLineQuery blq = new BusLineQuery(

bli.getBusLineId(), BusLineQuery.SearchType.BY_LINE_ID, bli.getCityCode());

blq.setPageSize(10);

blq.setPageNumber(1);

BusLineSearch busLineSearch = new BusLineSearch(getApplicationContext(), blq);

busLineSearch.setOnBusLineSearchListener(new BusLineSearch.OnBusLineSearchListener() {

@Override

public void onBusLineSearched(BusLineResult busLineResult, int i) {

List d = busLineResult.getBusLines().get(0).getDirectionsCoordinates();

List driverPath = new ArrayList<>();

for (LatLonPoint one : d) {

driverPath.add(new LatLng(one.getLatitude(), one.getLongitude()));

}

moveToPosition(busStationPoint.getLatitude(), busStationPoint.getLongitude());

aMap.addPolyline(new PolylineOptions()

.addAll(driverPath)

.width(20)

//是否开启纹理贴图

.setUseTexture(true)

//绘制成大地线

.geodesic(false)

//设置纹理样式

.setCustomTexture(BitmapDescriptorFactory.fromBitmap(

BitmapFactory.decodeResource(getResources(),

R.drawable.custtexture)))

//设置画线的颜色

.color(Color.argb(200, 0, 0, 0)));

final SmoothMoveMarker smoothMarker = new SmoothMoveMarker(aMap);

// 设置滑动的图标

smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(

R.mipmap.icon_car));

// 设置滑动的轨迹左边点

smoothMarker.setPoints(driverPath);

// 设置滑动的总时间

smoothMarker.setTotalDuration(30);

// 开始滑动

smoothMarker.startSmoothMove();

}

});

busLineSearch.searchBusLineAsyn();

}

} else {

Log.e(TAG, "onBusStationSearched: no data");

}

Log.e(TAG, "onBusStationSearched: " + i);

}

});

bss.searchBusStationAsyn();

绘制的代码

public class DrawActivity extends BaseActivity {

private static final String TAG = "CF";

@BindView(R.id.draw_map_view)

MapView drawMapView;

private Unbinder binder;

private AMap aMap;

@Override

public void setContentView(@Nullable Bundle savedInstanceState) {

setContentView(R.layout.activity_draw_map);

binder = ButterKnife.bind(this);

drawMapView.onCreate(savedInstanceState);

aMap = drawMapView.getMap();

}

@Override

public void initData() {

//绘制Marker

// drawMarker();

//绘制线段

// drawLine();

//绘制面

// drawSurface();

//绘制热力图

drawThermodynamic();

//绘制3D模型

draw3DModel();

// drawSmoothMove();

}

//绘制平滑移动

private void drawSmoothMove() {

//这里选择一个公交站,获取经过改公交站的一路公交车的路线

//让小车再这个路线上移动

BusStationQuery bsq;

BusStationSearch bss;

bsq = new BusStationQuery("天华一路", "成都");

bss = new BusStationSearch(this, bsq);

bss.setOnBusStationSearchListener(new BusStationSearch.OnBusStationSearchListener() {

@Override

public void onBusStationSearched(BusStationResult busStationResult, int i) {

List data = busStationResult.getBusStations();

if (data != null && data.size() > 0) {

final LatLonPoint busStationPoint = data.get(0).getLatLonPoint();

List dataBus = data.get(0).getBusLineItems();

if (dataBus != null && dataBus.size() > 0) {

BusLineItem bli = dataBus.get(0);

BusLineQuery blq = new BusLineQuery(bli.getBusLineId(), BusLineQuery.SearchType.BY_LINE_ID, bli.getCityCode());

blq.setPageSize(10);

blq.setPageNumber(1);

BusLineSearch busLineSearch = new BusLineSearch(getApplicationContext(), blq);

busLineSearch.setOnBusLineSearchListener(new BusLineSearch.OnBusLineSearchListener() {

@Override

public void onBusLineSearched(BusLineResult busLineResult, int i) {

List d = busLineResult.getBusLines().get(0).getDirectionsCoordinates();

List driverPath = new ArrayList<>();

for (LatLonPoint one : d) {

driverPath.add(new LatLng(one.getLatitude(), one.getLongitude()));

}

moveToPosition(busStationPoint.getLatitude(), busStationPoint.getLongitude());

aMap.addPolyline(new PolylineOptions()

.addAll(driverPath)

.width(20)

//是否开启纹理贴图

.setUseTexture(true)

//绘制成大地线

.geodesic(false)

//设置纹理样式

.setCustomTexture(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture)))

//设置画线的颜色

.color(Color.argb(200, 0, 0, 0)));

final SmoothMoveMarker smoothMarker = new SmoothMoveMarker(aMap);

// 设置滑动的图标

smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.mipmap.icon_car));

// 设置滑动的轨迹左边点

smoothMarker.setPoints(driverPath);

// 设置滑动的总时间

smoothMarker.setTotalDuration(30);

// 开始滑动

smoothMarker.startSmoothMove();

}

});

busLineSearch.searchBusLineAsyn();

}

} else {

Log.e(TAG, "onBusStationSearched: no data");

}

Log.e(TAG, "onBusStationSearched: " + i);

}

});

bss.searchBusStationAsyn();

}

private void draw3DModel() {

moveToDefaultPosition();

aMap.showMapText(false);

aMap.showBuildings(false);

aMap.setCustomRenderer(new CubeMapRender(aMap));

}

/**

* ----------------------------------------热力图---------------------------------------------------------

*/

private void drawThermodynamic() {

moveToDefaultPosition();

LatLng center = new LatLng(30.665, 104.065);

//第一步准备数据

LatLng[] data = new LatLng[100];

for (int i = 0; i < data.length; i++) {

double offsetLat = Math.random();

offsetLat /= 10;

double offsetLng = Math.random();

offsetLng /= 10;

LatLng one = new LatLng(center.latitude + offsetLat, center.longitude + offsetLng);

data[i] = one;

}

int[] colors = {Color.rgb(0, 255, 0), Color.rgb(255, 0, 0)};

float[] startPoints = {0.0f, 1.0f};

Gradient gradient = new Gradient(colors, startPoints);

//初始化热力图

HeatmapTileProvider.Builder builder = new HeatmapTileProvider.Builder();

builder.data(Arrays.asList(data))

// .gradient(gradient)

;

HeatmapTileProvider provider = builder.build();

// 初始化 TileOverlayOptions

TileOverlayOptions tileOverlayOptions = new TileOverlayOptions();

// 设置瓦片图层的提供者

tileOverlayOptions.tileProvider(provider);

// 向地图上添加 TileOverlayOptions 类对象

aMap.addTileOverlay(tileOverlayOptions);

}

/**

* ----------------------------------------热力图---------------------------------------------------------

* */

/**

* -----------------------------------------Marker相关----------------------------------------------------

* */

/**

* 地图上marker相关

*/

private void drawMarker() {

//添加一个默认的marker

LatLng latLng = new LatLng(30.67, 104.07);

MarkerOptions markerOptions = new MarkerOptions()

//必须,设置经纬度

.position(latLng)

//设置title

.title("成都")

//设置内容

.snippet("marker内容");

aMap.addMarker(markerOptions);

//添加一个自定义的marker

LatLng latLng1 = new LatLng(30.67, 104.07);

MarkerOptions mo = new MarkerOptions();

mo.position(latLng1)

//设置透明度

.alpha(0.6f)

//设置title

.title("自定义标题")

//设置内容

.snippet("自定义内容")

//设置锚点,锚点是marker图标的位置,(0,0)-(1,1)

.anchor(0.5f, 1.0f)

//是否可见

.visible(true)

//是否可拖动,注意这里需要长按marker后,才可以拖动

.draggable(true)

//添加自定义marker图标

.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.location)))

//是否平贴地图,倾斜地图,感觉marker不是竖直而是粘贴在地面上

.setFlat(false)

//是否允许显示infoWindow

.infoWindowEnable(true)

//z轴方向的值,重叠

.zIndex(10)

//设置marker图片旋转角度,正北开始逆时针方向计算

.rotateAngle(30.0f)

//设置infoWindow的偏移位置

.setInfoWindowOffset(0, 0);

aMap.addMarker(mo);

//添加一个动画marker

LatLng latLng2 = new LatLng(30.68, 104.07);

MarkerOptions mo1 = new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.location)))

.title("动画").snippet("生长动画").position(latLng2);

Marker m = aMap.addMarker(mo1);

final Animation animation = new ScaleAnimation(0, 1, 0, 1);

animation.setDuration(2000);

animation.setInterpolator(new AccelerateInterpolator());

m.setAnimation(animation);

m.startAnimation();

//添加一个marker的点击事件

aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {

@Override

public boolean onMarkerClick(Marker marker) {

//当点击的时候添加生长动画

marker.setAnimation(animation);

marker.startAnimation();

//这里在添加点击监听事件后,原来的InfoWindow被取消了,可以在回调方法中手动实现

if (marker.isInfoWindowShown()) {

marker.hideInfoWindow();

} else {

marker.showInfoWindow();

}

return true;

}

});

//添加拖拽事件,注意此回调方法只对设置了可拖拽的marker生效

aMap.setOnMarkerDragListener(new AMap.OnMarkerDragListener() {

@Override

public void onMarkerDragStart(Marker marker) {

Log.e(TAG, "onMarkerDragStart: 被拖拽的Marker标题为->" + marker.getTitle());

}

@Override

public void onMarkerDrag(Marker marker) {

}

@Override

public void onMarkerDragEnd(Marker marker) {

Log.e(TAG, "onMarkerDragEnd: 拖拽完后Maker的经纬度-> lat=" + marker.getPosition().latitude + " lng=" + marker.getPosition().longitude);

}

});

//自定义infoWindow

aMap.setInfoWindowAdapter(new AMap.InfoWindowAdapter() {

View view;

@Override

public View getInfoWindow(Marker marker) {

if (view == null) {

view = LayoutInflater.from(DrawActivity.this).inflate(R.layout.custom_info_window, null);

}

findViews(marker, view);

return view;

}

@Override

public View getInfoContents(Marker marker) {

return null;

}

});

aMap.setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {

@Override

public void onInfoWindowClick(Marker marker) {

Log.e(TAG, "onInfoWindowClick: 标题为:" + marker.getTitle() + " 的InfoWindow被点击了");

}

});

moveToDefaultPosition();

}

private void moveToDefaultPosition() {

//移动到marker位置

CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(

new CameraPosition(

new LatLng(30.665, 104.065),

15,

0,

0

)

);

aMap.moveCamera(mCameraUpdate);

}

private void moveToPosition(double lat, double lng) {

//移动到marker位置

CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(

new CameraPosition(

new LatLng(lat, lng),

13,

0,

0

)

);

aMap.moveCamera(mCameraUpdate);

}

/**

* 在点击marker显示infoWindow是,找到相应的控件,修改显示

*/

private void findViews(Marker marker, View view) {

TextView name = view.findViewById(R.id.name);

TextView address = view.findViewById(R.id.address);

name.setText(marker.getTitle());

address.setText(marker.getSnippet());

}

/**

* -----------------------------------------Marker相关----------------------------------------------------

*/

/**

* -----------------------------------------Line相关------------------------------------------------------

*/

private void drawLine() {

moveToDefaultPosition();

ArrayList points = new ArrayList<>();

points.add(new LatLng(30.66, 104.06));

points.add(new LatLng(30.66, 104.07));

points.add(new LatLng(30.67, 104.07));

points.add(new LatLng(30.67, 104.06));

points.add(new LatLng(30.66, 104.06));

aMap.addPolyline(new PolylineOptions().addAll(points).width(10).color(Color.argb(255, 1, 1, 1)));

ArrayList latlngs = new ArrayList<>();

latlngs.add(new LatLng(30.6595, 104.0595));

latlngs.add(new LatLng(30.6595, 104.0705));

latlngs.add(new LatLng(30.6705, 104.0705));

latlngs.add(new LatLng(30.6705, 104.0595));

latlngs.add(new LatLng(30.6595, 104.0595));

ArrayList a = new ArrayList<>();

a.add(0);

a.add(1);

a.add(2);

a.add(3);

ArrayList b = new ArrayList<>();

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bb)));

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.aa)));

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bb)));

b.add(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.aa)));

aMap.addPolyline(new PolylineOptions()

//添加多有的经纬度点

.addAll(latlngs)

//绘制线宽

.width(20)

//是否开启纹理贴图

.setUseTexture(true)

//纹理贴图段的index数组

.setCustomTextureIndex(a)

//纹理贴图每段对应的纹理资源图

.setCustomTextureList(b)

//是否虚线,纹理贴图时无效

.setDottedLine(false)

//绘制成大地线

.geodesic(false)

//设置纹理样式

.setCustomTexture(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.aa)))

//设置画线的颜色

.color(Color.argb(255, 1, 1, 1))

);

}

/**

* -----------------------------------------Line相关------------------------------------------------------

*/

/**

* -----------------------------------------绘制几何图形相关------------------------------------------------------

*/

private void drawSurface() {

moveToDefaultPosition();

LatLng latLng = new LatLng(30.665, 104.065);

//绘制一个圆

Circle circle = aMap.addCircle(new CircleOptions()

.center(latLng)

.radius(500)

.fillColor(Color.argb(30, 1, 1, 1))

.strokeColor(Color.argb(255, 1, 1, 1))

.strokeWidth(10)

);

circle.setStrokeDottedLineType(0);

// //绘制一个矩形,多边形跟这个一样的

// aMap.addPolygon(new PolygonOptions()

// .addAll(createRectangle(new LatLng(30.665, 104.065), 0.01, 0.01))

// .fillColor(Color.LTGRAY).strokeColor(Color.RED).strokeWidth(5));

//

// // 绘制一个椭圆

// PolygonOptions options = new PolygonOptions();

// int numPoints = 400;

// float semiHorizontalAxis = 2f;

// float semiVerticalAxis = 0.5f;

// double phase = 2 * Math.PI / numPoints;

// for (int i = 0; i <= numPoints; i++) {

// options.add(new LatLng(

// 30.665 + semiVerticalAxis * Math.sin(i * phase),

// 104.065 + semiHorizontalAxis * Math.cos(i * phase)

// ));

// }

//

// Polygon polygon = aMap.addPolygon(options

// .strokeWidth(25)

// .strokeColor(Color.argb(50, 1, 1, 1))

// .fillColor(Color.argb(50, 1, 1, 1))

// );

}

/**

* 生成一个长方形的四个坐标点

*/

private List createRectangle(LatLng center, double halfWidth,

double halfHeight) {

List latLngs = new ArrayList();

latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude - halfWidth));

latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude + halfWidth));

latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude + halfWidth));

latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude - halfWidth));

return latLngs;

}

/**

* -----------------------------------------绘制几何图形相关------------------------------------------------------

*/

@Override

protected void onResume() {

super.onResume();

drawMapView.onResume();

}

@Override

protected void onPause() {

super.onPause();

drawMapView.onPause();

}

@Override

protected void onStop() {

super.onStop();

}

@Override

protected void onDestroy() {

List list = aMap.getMapScreenMarkers();

if (list != null && list.size() > 0) {

for (Marker one : list) {

one.destroy();

}

}

drawMapView.onDestroy();

//这里注意,butterknife注销一定要在所有销毁的最后,否则会出现空指针异常

binder.unbind();

super.onDestroy();

}

@Override

protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

drawMapView.onSaveInstanceState(outState);

}

}

你可能感兴趣的:(android+高德地图教程)