一、加载mmpk
MMPK不仅可是生产基础底图(Basemap)还可以生产业务图层(OperationalLayers),当然两者不能同时包含在一个MMPK文件中。
与Geodatabase文件相比,MobileMapPackage(MMPK)文件的优势在于对要素量较大的数据来说加载效果和效率好。从各自内部包含的图层来看,MMPK明显做过了调优,考虑了图层索引顺序问题,也就是说MMPK中的业务图层的图层索引编号是倒置过的。而Geodatabase文件中获取的图层,往ArcGISMap中添加时,为了保证和生产该文件的图层顺序相同,需要从末位倒序加入。
final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/data/cssj/ff.mmpk";
File file = new File(path);
if (!file.exists()) {
Toast.makeText(MainActivity.this, "文件不存在!", Toast.LENGTH_LONG).show();
}
final MobileMapPackage mainMobileMapPackage = new MobileMapPackage(path);
String v = mainMobileMapPackage.getVersion(); //获取mmpk的版本
mainMobileMapPackage.loadAsync();
mainMobileMapPackage.addDoneLoadingListener(new Runnable() {
/**
*
*/
@Override
public void run() {
LoadStatus mainLoadStatus = mainMobileMapPackage.getLoadStatus();
if (mainLoadStatus == LoadStatus.LOADED) {
List<ArcGISMap> mainArcGISMapL = mainMobileMapPackage.getMaps();
ArcGISMap arcGISMap = mainArcGISMapL.get(0);
list = arcGISMap.getOperationalLayers(); // 可取出这里面的所有图层
mMapView.setMap(arcGISMap);
} else {
Exception e = mainMobileMapPackage.getLoadError();
e.printStackTrace();
Toast.makeText(MainActivity.this, "加载失败!", Toast.LENGTH_LONG).show();
}
}
});
二、读取属性
对于移动地图包,它的另一个特点就是保存了所有的feature要素,因此也可以进行空间查询。以空间查询举个例子:
mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
android.graphics.Point screenPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()));
final Point mapPoint = mMapView.screenToLocation(new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY())));
// QueryParameters parameters = new QueryParameters();
// parameters.setGeometry(mapPoint);
// FeatureLayer featureLayer = (FeatureLayer) mMapView.getMap().getOperationalLayers().get(0);
// FeatureTable featureTable = featureLayer.getFeatureTable();
// final ListenableFuture<FeatureQueryResult> future =
featureTable.queryFeaturesAsync(parameters);
final ListenableFuture<List<IdentifyLayerResult>> future = mMapView.identifyLayersAsync(
screenPoint, 20, false, 10);
future.addDoneListener(new Runnable() {
@Override
public void run() {
try {
//IdentifyLayerResult:每个图层的返回结果
List<IdentifyLayerResult> identifyLayerResults = future.get();
List<Content> contents = new ArrayList<>();
Content content = null;
int type = -1;
// for (IdentifyLayerResult identifyLayerResult : identifyLayerResults) {
for (int i = 0; i<identifyLayerResults.size(); i++) {
IdentifyLayerResult identifyLayerResult = identifyLayerResults.get(i);
String name = identifyLayerResult.getLayerContent().getName();
type = i;
featureLayerList.put(String.valueOf(type), (FeatureLayer) mMapView.getMap().getOperationalLayers().get(i));
List<GeoElement> elements = identifyLayerResult.getElements();
for (GeoElement element : elements) {
Map<String, Object> attributes = element.getAttributes();
Geometry geometry = element.getGeometry();
for (String key : attributes.keySet()) {
content = new Content(-1, key, String.valueOf(attributes.get(key)), geometry, type);
contents.add(content);
}
//单个图斑高亮显示操作
SimpleMarkerSymbol markSymbolTemp = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.YELLOW, 10);
SimpleLineSymbol lineSymbolTemp = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.YELLOW, 3);
SimpleFillSymbol fillSymbolTemp = new SimpleFillSymbol(SimpleFillSymbol.Style.NULL, Color.YELLOW, lineSymbolTemp);
//存在点线面三种类型
GeometryType geometryType = geometry.getGeometryType();
Graphic graphic = null;
if (geometryType == GeometryType.POINT) {
graphic = new Graphic(geometry, markSymbolTemp);
} else if (geometryType == GeometryType.POLYLINE) {
graphic = new Graphic(geometry, lineSymbolTemp);
} else if (geometryType == GeometryType.POLYGON) {
graphic = new Graphic(geometry, fillSymbolTemp);
}
mHighlightGraphicsOverlay.getGraphics().add(graphic);
}
//点击哪里就缩放到哪里
mMapView.setViewpointGeometryAsync(mapPoint.getExtent());
//插图显示
showCallout(contents, mapPoint);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (ExecutionException e1) {
e1.printStackTrace();
}
}
});
return true;
}
});
提供一个插图,Callout气泡的显示:
public void showCallout(List<Content> cotents, Point clickPoint){
if(cotents==null || cotents.size()==0)
return;
View calloutView = View.inflate(this, R.layout.callout_view, null);
ListView listView = calloutView.findViewById(R.id.listview);
SiteSelectionContentAdapter contentAdapter = new SiteSelectionContentAdapter(this, R.layout.content_item, cotents,this);
listView.setAdapter(contentAdapter);
mCallout = mMapView.getCallout();
//设置Callout样式
Callout.Style style = new Callout.Style(this);
style.setMaxWidth(320); //设置最大宽度
style.setMaxHeight(220); //设置最大高度
style.setBorderWidth(2); //设置边框宽度
style.setCornerRadius(8); //设置圆角半径
style.setLeaderPosition(Callout.Style.LeaderPosition.LOWER_MIDDLE); //设置指示性位置
mCallout.setStyle(style);
mCallout.setContent(calloutView);
//通过在地图坐标中指定Point来设置Callout的位置。
mCallout.setLocation(clickPoint);
mCallout.show();
}
效果图如下: