安卓智能地图开发与实施十三:空间查询与展示 - ArcGIS Runtime SDK for Android(Version 100.0.0)

0
分享 2017-08-21
空间查询与展示
空间查询需要入口(屏幕触摸、文字输入,甚至绘制个Geometry进行查询),也需要展示容器,如果查询仅仅返回一条记录,在地图中弹出窗口展示信息足矣。当返回多条记录,特别是多个图层的多条记录便需要类似AnimatedExpandableListView的容器来放置查询结果。 查询效果(脖子不好时):

写在开头

源程序请自行下载: 链接:http://pan.baidu.com/s/1qXJ6LxM 密码:uh2d 
若失效,可发邮件给韩源萌(polyline@126.com)索要。

后面的都是废话(代码解释)



搜索菜单
空间查询的入口可以是个按钮,找一个类似ArcMap中的Identify图标的图片作为菜单的icon 即可。SearchView是Android原生的搜索框控件,它提供了一个用户界面,用于用户搜索查询。

main_activity_header_menu.xml


 
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<!--搜索菜单-->
<item android:id="@+id/action_identify" android:orderInCategory="50" android:title="空间查询" app:showAsAction="always" android:icon="@drawable/ic_action_search_identity"/>
<item android:id="@+id/action_search" android:icon="@drawable/ic_action_search" android:orderInCategory="50" android:title="属性搜索" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="always"/>
</menu>

处理空间查询


 
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_identify) {
//this.OpenBottomPanelFunction();
mainConfigurations.ChangeMapViewOnTouchFunction(Configurations.MapTouchType.TOTALIDENTIFY);

return true;
}
return super.onOptionsItemSelected(item);
}

处理文本查询


 
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_activity_header_menu, menu);
MenuItem menuItemSearch = menu.findItem(R.id.action_search);//在菜单中找到对应控件的item
mainSearchView = (SearchView) MenuItemCompat.getActionView(menuItemSearch);
mainSearchView.setQueryHint("查找...");
mainSearchView.setSubmitButtonEnabled(false);
mainSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
final MapQueryClass mapQueryClass = new MapQueryClass();
mapQueryClass.Search(mainConfigurations.getMainReadOperationsFL(),
query,
new IQueryResult() {
@Override
public void getQuery() {
List<MapQueryClass.MapQueryResult> mapQueryResults= mapQueryClass.getMapQueryResult();
for (MapQueryClass.MapQueryResult mapQueryResult:mapQueryResults
) {
mapQueryResult.labelField =
mainConfigurations.GetLayerLabelFieldName(mapQueryResult.featureLayer.getName());
}

mainSearchView.onActionViewCollapsed();
mainSearchView.clearFocus();
ShowSearchResultFunction(mapQueryResults);

}
});
return false;
}

@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
MenuItem menuItemidentify = menu.findItem(R.id.action_identify);//在菜单中找到对应控件的item
return true;
}

MapView的触摸事件
MapView的setOnTouchListener没有对应的移除机制。
public void ChangeMapViewOnTouchFunction(MapTouchType type) {
ChangeMapViewOnTouchFunction(type, null);
}

public void ChangeMapViewOnTouchFunction(MapTouchType type, FeatureLayer featureLayer) {
if (mainCallout.isShowing()) {
mainCallout.dismiss();
}
switch (type) {
case SKETCH:
mainSketchGraphicsOverlay.mCanMapTouch = true;
canLayerTouchidentity = false;
canMapTouchidentity = false;
break;
case LAYERIDENTIFY:
mainSketchGraphicsOverlay.mCanMapTouch = false;
canLayerTouchidentity = true;
canMapTouchidentity = false;
StartLayerTouchFunction(featureLayer);
break;
case TOTALIDENTIFY:
mainSketchGraphicsOverlay.mCanMapTouch = false;
canLayerTouchidentity = false;
canMapTouchidentity = true;
StartMapTouchFunction();
break;
case CLEAR:
mainSketchGraphicsOverlay.mCanMapTouch = false;
canLayerTouchidentity = false;
canMapTouchidentity = false;
break;
}
}


这里的代码处理的比较乱,合适的方式是定义一个枚举的变量,没必要弄这么多Boolean。

StartLayerTouchFunction


 
protected void StartLayerTouchFunction(FeatureLayer featureLayer) {
if(featureLayer == null)
{
return;
}
ClearLayerFunction();
final FeatureLayer mainFeatureLayer = featureLayer;
mainMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mainMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// remove any existing callouts
if (canLayerTouchidentity == false) {
return super.onSingleTapConfirmed(e);
}
android.graphics.Point screenPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()));
final Point clickPoint = MapViewMethodsClass.GetMapPointFromScreenPointFunction(mainMapView,screenPoint);
Envelope mapEnvelope = MapViewMethodsClass.GetEnvelopeFromMapPointFunction(
mainMapView,screenPoint,10);
final MapQueryClass mapQueryClass = new MapQueryClass();
mapQueryClass.Select(
mainFeatureLayer,
mapEnvelope,
new IQueryResult() {
@Override
public void getQuery() {
List<MapQueryClass.MapQueryResult> mapQueryResults= mapQueryClass.getMapQueryResult();
for (MapQueryClass.MapQueryResult mapQueryResult:mapQueryResults
) {
mapQueryResult.labelField =
GetLayerLabelFieldName(mapQueryResult.featureLayer.getName());
//mapQueryResult.setFeatureLayerSelected(true);
}
HymnActivity.mainHymnActivity.ShowSearchResultFunction(mapQueryResults);
}
}
);

return super.onSingleTapConfirmed(e);
}
});
}

StartMapTouchFunction


 
protected void StartMapTouchFunction(){
mainMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this,mainMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (canMapTouchidentity == false) {
return super.onSingleTapConfirmed(e);
}
ClearLayerFunction();
android.graphics.Point screenPoint =
new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()));
Envelope mapEnvelope =
MapViewMethodsClass.GetEnvelopeFromMapPointFunction(mainMapView,screenPoint,10);
final MapQueryClass mapQueryClass = new MapQueryClass();
mapQueryClass.Select(
mainReadOperationsFL,
mapEnvelope,
new IQueryResult() {
@Override
public void getQuery() {
List<MapQueryClass.MapQueryResult> mapQueryResults= mapQueryClass.getMapQueryResult();
for (MapQueryClass.MapQueryResult mapQueryResult:mapQueryResults
) {
mapQueryResult.labelField =
GetLayerLabelFieldName(mapQueryResult.featureLayer.getName());
//mapQueryResult.setFeatureLayerSelected(true);
}
HymnActivity.mainHymnActivity.ShowSearchResultFunction(mapQueryResults);
}
}
);
return super.onSingleTapConfirmed(e);
}
});
}

ShowMapCallOutFunction


 
public void ShowMapCallOutFunction(Feature feature){
TextView calloutContent = new TextView(getApplicationContext());
calloutContent.setTextColor(Color.BLACK);
calloutContent.setSingleLine(false);
calloutContent.setVerticalScrollBarEnabled(true);
calloutContent.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
calloutContent.setMovementMethod(new ScrollingMovementMethod());
calloutContent.setMaxWidth(600);
calloutContent.setLines(5);
calloutContent.setText(
AttributeMethodsClass.GetCalloutStringByAttributeFunction(
feature.getAttributes()));
mainCallout.setLocation(GeometryMethodsClass.GetFeatureCenterFunction(feature));
mainCallout.setContent(calloutContent);
mainCallout.show();
}

查询结果的承载 - AnimatedExpandableListView

对AnimatedExpandableListView感兴趣的可参考 <a href="https://github.com/idunnololz/ ... tView

main_search_result_group_item.xml


 
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingRight="10dp" android:paddingLeft="40dp">
<TextView android:paddingTop="10dp" android:paddingBottom="10dp" android:id="@+id/resultGroupContainer" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:layout_editor_absoluteY="0dp" android:layout_marginLeft="0dp" app:layout_constraintLeft_toLeftOf="parent" />
<TextView android:paddingTop="10dp" android:paddingBottom="10dp" android:text="10" android:id="@+id/resultGroupCountContainer" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:layout_editor_absoluteY="0dp" android:layout_marginRight="8dp" app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>

main_search_result_list_item.xml


 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingRight="10dp" android:paddingLeft="50dp">
<TextView android:paddingTop="10dp" android:paddingBottom="10dp" android:id="@+id/resultListContainer" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>

SearchResultAdapter.java


 
package esrichina.hymn.usingmappingbyhymnlocal.Adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.layers.FeatureLayer;

import java.util.ArrayList;
import java.util.List;

import esrichina.hymn.ListView.AnimatedExpandableListView;
import esrichina.hymn.MapQuery.MapQueryClass;
import esrichina.hymn.usingmappingbyhymnlocal.R;

/** * Created by HymnHan on 2017/5/17. */

public class SearchResultAdapter extends AnimatedExpandableListView.AnimatedExpandableListAdapter {
private LayoutInflater inflater;

private List<MapQueryClass.MapQueryResult> items = new ArrayList<>();

public SearchResultAdapter(Context context) {
inflater = LayoutInflater.from(context);
}

public void setData(List<MapQueryClass.MapQueryResult> items) {
this.items = items;
}

@Override
public Feature getChild(int groupPosition, int childPosition) {
return items.get(groupPosition).features.get(childPosition);
}

@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}

@Override
public View getRealChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder holder;
MapQueryClass.MapQueryResult mapQueryResult = getGroup(groupPosition);
if (convertView == null) {
holder = new ChildHolder();
convertView = inflater.inflate(R.layout.main_search_result_list_item, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.resultListContainer);
convertView.setTag(holder);
} else {
holder = (ChildHolder) convertView.getTag();
}

holder.title.setText(mapQueryResult.getTitle(childPosition));
holder.mapQueryResult = mapQueryResult;
//holder.hint.setText(item.hint);

return convertView;
}

@Override
public int getRealChildrenCount(int groupPosition) {
return items.get(groupPosition).features.size();
}

@Override
public MapQueryClass.MapQueryResult getGroup(int groupPosition) {
return items.get(groupPosition);
}

@Override
public int getGroupCount() {
return items.size();
}

@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder holder;
MapQueryClass.MapQueryResult mapQueryResult = getGroup(groupPosition);
if (convertView == null) {
holder = new GroupHolder();
convertView = inflater.inflate(R.layout.main_search_result_group_item, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.resultGroupContainer);
holder.count = (TextView) convertView.findViewById(R.id.resultGroupCountContainer);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}

holder.title.setText(mapQueryResult.getLayerTitle());
holder.count.setText("共 " + String.valueOf(mapQueryResult.getFeatureCount()) + " 条");
holder.mapQueryResult = mapQueryResult;
return convertView;
}

@Override
public boolean hasStableIds() {
return true;
}

@Override
public boolean isChildSelectable(int arg0, int arg1) {
return true;
}

public static class ChildHolder {
public TextView title;
public MapQueryClass.MapQueryResult mapQueryResult;
}

public static class GroupHolder {
public TextView title;
public TextView count;
public MapQueryClass.MapQueryResult mapQueryResult;
}
}

SearchResultComponent.java


 
package esrichina.hymn.usingmappingbyhymnlocal.Components;

import android.view.View;
import android.widget.ExpandableListView;

import com.esri.arcgisruntime.data.Feature;

import java.util.ArrayList;
import java.util.List;

import esrichina.hymn.ListView.AnimatedExpandableListView;
import esrichina.hymn.MapQuery.MapQueryClass;
import esrichina.hymn.Methods.MapViewMethodsClass;
import esrichina.hymn.usingmappingbyhymnlocal.Adapters.SearchResultAdapter;
import esrichina.hymn.usingmappingbyhymnlocal.R;

/** * Created by HymnHan on 2017/5/19. */

public class SearchResultComponent extends BaseComponent {
private AnimatedExpandableListView searchResultContainer;
private SearchResultAdapter searchResultAdapter;
public SearchResultComponent() {
searchResultAdapter = new SearchResultAdapter(mainHymnActivity);
searchResultContainer = (AnimatedExpandableListView) mainHymnActivity.findViewById(R.id.searchResultContainer);
searchResultContainer.setAdapter(searchResultAdapter);
searchResultContainer.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
SearchResultAdapter.ChildHolder childHolder =
(SearchResultAdapter.ChildHolder) v.getTag();
Feature feature = childHolder.mapQueryResult.features.get(childPosition);
MapViewMethodsClass.CenterMapViewByGeometryFunction(
mainHymnActivity.getMainMapView(),
feature,
10);
childHolder.mapQueryResult.selectFeature(feature);
mainConfigurations.ShowMapCallOutFunction(feature);
return false;
}
});
}
public void ClearSearchResultFunction()
{
searchResultAdapter.setData(new ArrayList<MapQueryClass.MapQueryResult>());
searchResultAdapter.notifyDataSetChanged();
}
public void ShowSearchResultFunction(List<MapQueryClass.MapQueryResult> mapQueryResults)
{
searchResultAdapter.setData(mapQueryResults);
searchResultAdapter.notifyDataSetChanged();
searchResultContainer.expandGroupWithAnimation(0);
}
}

查询结果的承载 - SlidingUpPanelLayout

对SlidingUpPanelLayout感兴趣的可参考 <a href="https://github.com/umano/Andro ... Panel
<esrichina.hymn.DragUpPanel.SlidingUpPanelLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainSliding"
android:gravity="bottom"
app:umanoPanelHeight="20dp"
app:umanoShadowHeight="4dp"
app:umanoParallaxOffset="100dp"
app:umanoDragView="@+id/dragView"
app:umanoOverlay="false"
app:umanoScrollableView="@+id/searchResultContainer"
app:umanoAnchorPoint="0.565"
app:umanoFadeColor="@color/geometry_swatch_background"
app:umanoInitialState="hidden">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/main_map_container"/>
<include layout="@layout/main_activity_header_container"/>
</android.support.design.widget.CoordinatorLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical"
android:clickable="true"
android:focusable="false"
android:id="@+id/dragView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_panel_header"
android:orientation="horizontal"
android:background="@color/bootstrap_brand_info">
</LinearLayout>
<include layout="@layout/main_search_result_container"/>
</LinearLayout>
</esrichina.hymn.DragUpPanel.SlidingUpPanelLayout>

查询结果的清除

 
 安卓智能地图开发与实施一:配置离线SDK - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3304
 安卓智能地图开发与实施二:开发环境准备 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3303
 安卓智能地图开发与实施三:创建第一个地图程序 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3302
 安卓智能地图开发与实施四:二维地图的MapView与Layers - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3305
 安卓智能地图开发与实施五:在线基础底图 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3309
 安卓智能地图开发与实施六:离线基础底图 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3299
 安卓智能地图开发与实施七:在线业务图层(浏览查询) - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3298
 安卓智能地图开发与实施八:离线业务图层(浏览查询) - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3297
 安卓智能地图开发与实施九:地图缩放与旋转 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3296
 安卓智能地图开发与实施十:图层管理 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3295
 安卓智能地图开发与实施十一:业务数据查询 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3294
 安卓智能地图开发与实施十二:空间查询与模糊搜索 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3293
 安卓智能地图开发与实施十三:空间查询与展示 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3308
 安卓智能地图开发与实施十四:业务数据编辑 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3307
 安卓智能地图开发与实施十五:离线与同步 - ArcGIS Runtime SDK for Android(Version 100.0.0) :http://zhihu.esrichina.com.cn/article/3306
 安卓智能地图开发与实施十六:三维地图 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3289
 安卓智能地图开发与实施十七:使用天地图 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3288
 安卓智能地图开发与实施十八:空间要素绘制 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3287
 安卓智能地图开发与实施十九:符号与渲染器 - ArcGIS Runtime SDK for Android(Version 100.1.0) :http://zhihu.esrichina.com.cn/article/3286
文章来源:http://blog.csdn.net/allenlu2008/article/details/72818545

0 个评论

要回复文章请先登录注册