前面说过了加载天地图,这篇文章是另一种加载方式:
- 页面:
<com.example.arcgisopen.uiview.SpotMapView android:id="@+id/smvMap" android:visibility="visible" android:layout_width="match_parent" android:layout_height="match_parent"> </com.example.arcgisopen.uiview.SpotMapView>
2、 activity页面;
package com.example.arcgisopen.uiview; import android.annotation.SuppressLint; import android.content.Context; import android.util.AttributeSet; import android.widget.Toast; import com.example.arcgisopen.base.BaseApp; import com.esri.android.map.MapView; import com.esri.android.map.event.OnPinchListener; import com.esri.android.map.event.OnSingleTapListener; import com.esri.android.map.event.OnStatusChangedListener; import com.esri.android.map.event.OnZoomListener; public class SpotMapView extends MapView implements OnZoomListener,OnSingleTapListener,OnStatusChangedListener{ private double[] mPresetScale = new double[]{2256.994353,4513.988705,9027.977411,18055.954822,36111.909643,72223.819286,144447.638572,288895.277144,577790.554289,1155581.108577,2311162.217155,4622324.434309,9244648.868618,1.8489297737236E7,3.6978595474472E7,7.3957190948944E7,1.47914381897889E8,2.95828763795777E8,5.91657527591555E8}; //初始的比例尺 private int mScaleLevel; //比例尺视图 private MapScaleView mScaleView; //指北针视图 private CompassView mCompassView; private SpotMapView.MapListener mMapListener; public void setMapListener(SpotMapView.MapListener listener){this.mMapListener = listener;} public interface MapListener{ /** * 地图加载完毕后的回调函数 * */ void onMapLoaded(); /** * 地图点击回调 * @param var1 屏幕x * @param var2 屏幕y */ void onSingleTap(float var1, float var2); /** * 地图缩放变化 * @param scale 缩放 */ void scaleChanged(double scale); } @SuppressLint("ResourceType") public SpotMapView(Context context, AttributeSet attrs) { super(context, attrs); setOnZoomListener(this); setOnSingleTapListener(this); setOnStatusChangedListener(this); // //地图指北针事件 // setAllowRotationByPinch(true); setOnPinchListener(new OnPinchListener() { @Override public void prePointersMove(float v, float v1, float v2, float v3, double v4) {} @Override public void postPointersMove(float v, float v1, float v2, float v3, double v4) { float rotationAngle = Double.valueOf(getRotationAngle()).floatValue(); mCompassView.updateDirection(-rotationAngle); } @Override public void prePointersDown(float v, float v1, float v2, float v3, double v4) {} @Override public void postPointersDown(float v, float v1, float v2, float v3, double v4) {} @Override public void prePointersUp(float v, float v1, float v2, float v3, double v4) {} @Override public void postPointersUp(float v, float v1, float v2, float v3, double v4) {} }); } //缩放至大一个级别 public void zoomUpper(){ if (mScaleLevel<mPresetScale.length-2) { mScaleLevel++; setScaleLevel(mScaleLevel); }else { Toast.makeText(BaseApp.getContext(),"已缩放至最小级别!",Toast.LENGTH_LONG).show(); } } //缩放至小一个级别 public void zoomLower(){ if (mScaleLevel>0) { mScaleLevel--; setScaleLevel(mScaleLevel); }else { Toast.makeText(BaseApp.getContext(),"已缩放至最大级别!",Toast.LENGTH_LONG).show(); } } //设置缩放级别 public void setScaleLevel(int level){ if (level<0||level>=mPresetScale.length){ return; } mScaleLevel = level; setScale(mPresetScale[level],true); } @Override public void setScale(double scale, boolean animated) { super.setScale(scale, animated); notifyScaleChanged(); } //地图缩放事件1 @Override public void preAction(float v, float v1, double v2) { // Log.d("数据测试","缩放开始"); } //地图缩放事件2 @Override public void postAction(float v, float v1, double v2) { /**通知地图的缩放改变了及时更新地图的一些其他部件信息*/ mScaleLevel = cacScaleLevel(getScale()); notifyScaleChanged(); } //比例尺显示功能1 public int cacScaleLevel(double curScale){ int left = 0, right = mPresetScale.length-1,mid; while(left<right){ mid = (right+left)/2; if (compare(mPresetScale[mid],curScale)==0){ return mid; } else if (compare(mPresetScale[mid],curScale)>0){ right = mid - 1; } else if (compare(mPresetScale[mid],curScale)<0){ left = mid + 1; } } return left; } //比例尺显示功能2 private void notifyScaleChanged() { if (mScaleView!=null){ mScaleView.refreshScaleView(); } if (mMapListener!=null){ mMapListener.scaleChanged(getScale()); } // Log.i("数据测试",mScaleLevel+""); } //比例尺显示辅助函数 private int compare(double d1, double d2){ double accuracy = 0.001; if (d1-d2<0){ return -1; }else if (d1-d2>accuracy){ return 1; }else { return 0; } } //需在MainActivity中调用该方法给mScaleView赋值 public void setScaleView(MapScaleView mScaleView) { mScaleView.setMapView(this); this.mScaleView = mScaleView; } //需在MainActivity中调用该方法给mCompassView赋值 public void setCompassView(CompassView compassView) { this.mCompassView = compassView; } @Override public void onStatusChanged(Object o, STATUS status) { if (status.equals(STATUS.INITIALIZED)){ mMapListener.onMapLoaded(); } } @Override public void onSingleTap(float v, float v1) { if (mMapListener!=null){ mMapListener.onSingleTap(v,v1); } } }
3、 天地图文件TDTMapLayer
package com.example.arcgisopen.tianditu;
import com.esri.android.map.MapView;
public class TDTMapLayer {
private static TDTTiledMapServiceLayer t_vec=new TDTTiledMapServiceLayer(TDTTiledMapServiceType.VEC_C);
private static TDTTiledMapServiceLayer t_cva=new TDTTiledMapServiceLayer(TDTTiledMapServiceType.CVA_C);
private static TDTTiledMapServiceLayer t_img= new TDTTiledMapServiceLayer(TDTTiledMapServiceType.IMG_C);
private static TDTTiledMapServiceLayer t_cia= new TDTTiledMapServiceLayer(TDTTiledMapServiceType.CIA_C);
private static boolean Layervisible=true;
public static boolean isLayervisible() {
return Layervisible;
}
public static void addToMap(MapView map){
t_vec=new TDTTiledMapServiceLayer(TDTTiledMapServiceType.VEC_C);
t_cva=new TDTTiledMapServiceLayer(TDTTiledMapServiceType.CVA_C);
t_img= new TDTTiledMapServiceLayer(TDTTiledMapServiceType.IMG_C);
t_cia= new TDTTiledMapServiceLayer(TDTTiledMapServiceType.CIA_C);
map.addLayer(t_vec);
map.addLayer(t_cva);
map.addLayer(t_img);
map.addLayer(t_cia);
setTDTMapLayerVisible(Layervisible);
}
public static void changeTDTMapLayerVisible(){
Layervisible = !Layervisible;
if(Layervisible==false){
t_img.setVisible(true);
t_cia.setVisible(true);
t_cva.setVisible(false);
t_vec.setVisible(false);
}else {
t_img.setVisible(false);
t_cia.setVisible(false);
t_cva.setVisible(true);
t_vec.setVisible(true);
}
}
public static void setTDTMapLayerVisible(Boolean isvisible){
Layervisible = isvisible;
if(isvisible==false){
t_img.setVisible(true);
t_cia.setVisible(true);
t_cva.setVisible(false);
t_vec.setVisible(false);
}else{
t_img.setVisible(false);
t_cia.setVisible(false);
t_cva.setVisible(true);
t_vec.setVisible(true);
}
}
}
4、天地图文件二:TDTTiledMapServiceLayer
package com.example.arcgisopen.tianditu;
import android.util.Log;
import com.esri.android.map.TiledServiceLayer;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.io.UserCredentials;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.RejectedExecutionException;
public class TDTTiledMapServiceLayer extends TiledServiceLayer {
private TDTTiledMapServiceType _mapType;
private TileInfo tiandituTileInfo;
public TDTTiledMapServiceLayer() {
this(null, null, true);
}
public TDTTiledMapServiceLayer(TDTTiledMapServiceType mapType) {
this(mapType, null, true);
}
public TDTTiledMapServiceLayer(TDTTiledMapServiceType mapType, UserCredentials usercredentials) {
this(mapType, usercredentials, true);
}
public TDTTiledMapServiceLayer(TDTTiledMapServiceType mapType, UserCredentials usercredentials, boolean flag) {
super("");
this._mapType = mapType;
setCredentials(usercredentials);
if (flag)
try {
getServiceExecutor().submit(new Runnable() {
public final void run() {
a.initLayer();
}
final TDTTiledMapServiceLayer a;
{
a = TDTTiledMapServiceLayer.this;
}
});
return;
} catch (RejectedExecutionException _ex) {
}
}
public TDTTiledMapServiceType getMapType() {
return this._mapType;
}
protected void initLayer() {
this.buildTileInfo();
this.setFullExtent(new Envelope(103.36, 24.37, 109.35, 29.13));
this.setDefaultSpatialReference(SpatialReference.create(4490)); //CGCS2000
// //this.setDefaultSpatialReference(SpatialReference.create(4326));
// //this.setInitialExtent(new Envelope(115.40,39.33,117.50,41.10));
this.setInitialExtent(new Envelope(103.36, 24.37, 109.35, 29.13));
super.initLayer();
}
public void refresh() {
try {
getServiceExecutor().submit(new Runnable() {
public final void run() {
if (a.isInitialized())
try {
a.b();
a.clearTiles();
return;
} catch (Exception exception) {
Log.e("ArcGIS", "Re-initialization of the layer failed.", exception);
}
}
final TDTTiledMapServiceLayer a;
{
a = TDTTiledMapServiceLayer.this;
//super();
}
});
return;
} catch (RejectedExecutionException _ex) {
return;
}
}
final void b() throws Exception {
}
@Override
protected byte[] getTile(int level, int col, int row) throws Exception {
byte[] result = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
URL sjwurl = new URL(this.getTianDiMapUrl(level, col, row));
HttpURLConnection httpUrl = null;
BufferedInputStream bis = null;
byte[] buf = new byte[1024];
httpUrl = (HttpURLConnection) sjwurl.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
while (true) {
int bytes_read = bis.read(buf);
if (bytes_read > 0) {
bos.write(buf, 0, bytes_read);
} else {
break;
}
}
bis.close();
httpUrl.disconnect();
result = bos.toByteArray();
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
@Override
public TileInfo getTileInfo() {
return this.tiandituTileInfo;
}
private String getTianDiMapUrl(int level, int col, int row) {
String url = new TDTUrl(level, col, row, this._mapType).generatUrl();
return url;
}
private void buildTileInfo() {
Point originalPoint = new Point(-180, 90);
double[] res = {
1.40625,
0.703125,
0.3515625,
0.17578125,
0.087890625,
0.0439453125,
0.02197265625,
0.010986328125,
0.0054931640625,
0.00274658203125,
0.001373291015625,
0.0006866455078125,
0.00034332275390625,
0.000171661376953125,
8.58306884765629E-05,
4.29153442382814E-05,
2.14576721191407E-05,
1.07288360595703E-05,
5.36441802978515E-06,
2.68220901489258E-06,
1.34110450744629E-06
};
double[] scale = {
400000000,
295497598.5708346,
147748799.285417,
73874399.6427087,
36937199.8213544,
18468599.9106772,
9234299.95533859,
4617149.97766929,
2308574.98883465,
1154287.49441732,
577143.747208662,
288571.873604331,
144285.936802165,
72142.9684010827,
36071.4842005414,
18035.7421002707,
9017.87105013534,
4508.93552506767,
2254.467762533835,
1127.2338812669175,
563.616940
};
int levels = 19;
int dpi = 96;
int tileWidth = 256;
int tileHeight = 256;
this.tiandituTileInfo = new TileInfo(originalPoint, scale, res, levels, dpi, tileWidth, tileHeight);
this.setTileInfo(this.tiandituTileInfo);
}
}
5、天地图文件三:TDTTiledMapServiceType
package com.example.arcgisopen.tianditu;
public enum TDTTiledMapServiceType {
/**
* 天地图矢量
* */
VEC_C,
/**
* 天地图影像
* */
IMG_C,
/**
* 天地图矢量标注
* */
CVA_C,
/**
* 天地图影像标注
* */
CIA_C
}
6、天地图文件四:TDTUrl
package com.example.arcgisopen.tianditu;
import java.util.Random;
/**
* Created by Fly on 2016/9/6.
*/
public class TDTUrl {
private TDTTiledMapServiceType _tiandituMapServiceType;
private int _level;
private int _col;
private int _row;
public TDTUrl(int level, int col, int row,TDTTiledMapServiceType tiandituMapServiceType){
this._level=level;
this._col=col;
this._row=row;
this._tiandituMapServiceType=tiandituMapServiceType;
}
public String generatUrl(){
/**
* 天地图矢量、影像
* */
StringBuilder url=new StringBuilder("http://t");
Random random=new Random();
int subdomain = (random.nextInt(6) + 1);
url.append(subdomain);
switch(this._tiandituMapServiceType){
case VEC_C:
url.append(".tianditu.com/DataServer?T=vec_c&X=").append(this._col).append("&Y=").append(this._row).append("&L=").append(this._level).append("&tk=a4edecc3a1040656f20e39976c1f357b");;
break;
case CVA_C:
url.append(".tianditu.com/DataServer?T=cva_c&X=").append(this._col).append("&Y=").append(this._row).append("&L=").append(this._level).append("&tk=a4edecc3a1040656f20e39976c1f357b");;
break;
case CIA_C:
url.append(".tianditu.com/DataServer?T=cia_c&X=").append(this._col).append("&Y=").append(this._row).append("&L=").append(this._level).append("&tk=a4edecc3a1040656f20e39976c1f357b");;
break;
case IMG_C:
url.append(".tianditu.com/DataServer?T=img_c&X=").append(this._col).append("&Y=").append(this._row).append("&L=").append(this._level).append("&tk=a4edecc3a1040656f20e39976c1f357b");;
break;
default:
return null;
}
return url.toString();
}
}
7、MainActivity.class
1、
@BindView(R.id.smvMap)
SpotMapView mMapView;
2、TDTMapLayer.addToMap(mMapView);在初始化的时候加载天地图
3、定位:定位通过Location获取当经度纬度就可以了,不需要转换,直接用,百度上还是很多的,这里就不介绍怎么去获取了。
Point p = new Point(经度, 纬度);
mMapView.zoomToScale(p, 9000);
```
4、显示定位图标,在activity,ocreate()中使用或初始化activity的时候使用此方法就可以了。
private void position() {
LocationDisplayManager ldm = mMapView.getLocationDisplayManager();
ldm.setLocationListener(new LocationListener() {
boolean locationChanged = false;
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
//GPS开启时触发
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (!locationChanged) {
locationChanged = true;
}
}
});
ldm.start();
}